=> {
10 | try {
11 | const popularProducts = await prisma.products.findMany({
12 | take: 15,
13 | orderBy: {
14 | stockQuantity: "desc",
15 | },
16 | });
17 | const salesSummary = await prisma.salesSummary.findMany({
18 | take: 5,
19 | orderBy: {
20 | date: "desc",
21 | },
22 | });
23 | const purchaseSummary = await prisma.purchaseSummary.findMany({
24 | take: 5,
25 | orderBy: {
26 | date: "desc",
27 | },
28 | });
29 | const expenseSummary = await prisma.expenseSummary.findMany({
30 | take: 5,
31 | orderBy: {
32 | date: "desc",
33 | },
34 | });
35 | const expenseByCategorySummaryRaw = await prisma.expenseByCategory.findMany(
36 | {
37 | take: 5,
38 | orderBy: {
39 | date: "desc",
40 | },
41 | }
42 | );
43 | const expenseByCategorySummary = expenseByCategorySummaryRaw.map(
44 | (item) => ({
45 | ...item,
46 | amount: item.amount.toString(),
47 | })
48 | );
49 |
50 | res.json({
51 | popularProducts,
52 | salesSummary,
53 | purchaseSummary,
54 | expenseSummary,
55 | expenseByCategorySummary,
56 | });
57 | } catch (error) {
58 | res.status(500).json({ message: "Error retrieving dashboard metrics" });
59 | }
60 | };
61 |
--------------------------------------------------------------------------------
/client/src/app/inventory/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useGetProductsQuery } from "@/state/api";
4 | import Header from "@/app/(components)/Header";
5 | import { DataGrid, GridColDef } from "@mui/x-data-grid";
6 |
7 | const columns: GridColDef[] = [
8 | { field: "productId", headerName: "ID", width: 90 },
9 | { field: "name", headerName: "Product Name", width: 200 },
10 | {
11 | field: "price",
12 | headerName: "Price",
13 | width: 110,
14 | type: "number",
15 | valueGetter: (value, row) => `$${row.price}`,
16 | },
17 | {
18 | field: "rating",
19 | headerName: "Rating",
20 | width: 110,
21 | type: "number",
22 | valueGetter: (value, row) => (row.rating ? row.rating : "N/A"),
23 | },
24 | {
25 | field: "stockQuantity",
26 | headerName: "Stock Quantity",
27 | width: 150,
28 | type: "number",
29 | },
30 | ];
31 |
32 | const Inventory = () => {
33 | const { data: products, isError, isLoading } = useGetProductsQuery();
34 |
35 | if (isLoading) {
36 | return Loading...
;
37 | }
38 |
39 | if (isError || !products) {
40 | return (
41 |
42 | Failed to fetch products
43 |
44 | );
45 | }
46 |
47 | return (
48 |
49 |
50 | row.productId}
54 | checkboxSelection
55 | className="bg-white shadow rounded-lg border border-gray-200 mt-5 !text-gray-700"
56 | />
57 |
58 | );
59 | };
60 |
61 | export default Inventory;
62 |
--------------------------------------------------------------------------------
/client/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 | import { createThemes } from "tw-colors";
3 | import colors from "tailwindcss/colors";
4 |
5 | const baseColors = [
6 | "gray",
7 | "red",
8 | "yellow",
9 | "green",
10 | "blue",
11 | "indigo",
12 | "purple",
13 | "pink",
14 | ];
15 |
16 | const shadeMapping = {
17 | "50": "900",
18 | "100": "800",
19 | "200": "700",
20 | "300": "600",
21 | "400": "500",
22 | "500": "400",
23 | "600": "300",
24 | "700": "200",
25 | "800": "100",
26 | "900": "50",
27 | };
28 |
29 | const generateThemeObject = (colors: any, mapping: any, invert = false) => {
30 | const theme: any = {};
31 | baseColors.forEach((color) => {
32 | theme[color] = {};
33 | Object.entries(mapping).forEach(([key, value]: any) => {
34 | const shadeKey = invert ? value : key;
35 | theme[color][key] = colors[color][shadeKey];
36 | });
37 | });
38 | return theme;
39 | };
40 |
41 | const lightTheme = generateThemeObject(colors, shadeMapping);
42 | const darkTheme = generateThemeObject(colors, shadeMapping, true);
43 |
44 | const themes = {
45 | light: {
46 | ...lightTheme,
47 | white: "#ffffff",
48 | },
49 | dark: {
50 | ...darkTheme,
51 | white: colors.gray["950"],
52 | black: colors.gray["50"],
53 | },
54 | };
55 |
56 | const config: Config = {
57 | darkMode: "class",
58 | content: [
59 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
60 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
61 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
62 | ],
63 | theme: {
64 | extend: {
65 | backgroundImage: {
66 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
67 | "gradient-conic":
68 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
69 | },
70 | },
71 | },
72 | plugins: [createThemes(themes)],
73 | };
74 |
75 | export default config;
76 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Build a Fullstack Inventory Management Dashboard
2 |
3 | [](https://www.youtube.com/watch?v=ddKQ8sZo_v8)
4 |
5 | Link to related video: https://www.youtube.com/watch?v=ddKQ8sZo_v8
6 |
7 | ## Tutorial
8 |
9 | This repository contains the code corresponding to an in-depth tutorial available on my YouTube channel. It is highly suggested to watch the [tutorial video](https://www.youtube.com/watch?v=ddKQ8sZo_v8) as it includes detailed instructions on how to set up everything, including deploying AWS. This tutorial is designed for both beginners and experts.
10 |
11 | Join our [Discord community](https://discord.com/channels/1070200085440376872/1267499814678171698) for discussions about this specific app.
12 |
13 | ## Tech Stack
14 |
15 | - **Next JS**
16 | - **Tailwind**
17 | - **Redux Toolkit**
18 | - **Redux Toolkit Query**
19 | - **Material UI Data Grid**
20 | - **Node.js**
21 | - **Prisma**
22 | - **AWS EC2**
23 | - **AWS RDS**
24 | - **AWS API Gateway**
25 | - **AWS Amplify**
26 | - **AWS S3**
27 |
28 | ## Resources and Links
29 |
30 | ### Image Files
31 |
32 | - [Server assets to download](https://github.com/ed-roh/inventory-management/tree/master/server/assets)
33 |
34 | ### Configuration and Code
35 |
36 | - [tailwind.config.ts](https://github.com/ed-roh/inventory-management/blob/master/client/tailwind.config.ts) (to copy)
37 | - [Redux store file](https://github.com/ed-roh/inventory-management/blob/master/client/src/app/redux.tsx) (to copy)
38 | - [Seed files for database](https://github.com/ed-roh/inventory-management/blob/master/server/prisma/seed.ts) (to copy)
39 | - [Seed data files](https://github.com/ed-roh/inventory-management/tree/master/server/prisma/seedData) (to download)
40 |
41 | ### Additional Resources
42 |
43 | - [Data model diagram](https://drawsql.app/teams/team-3023/diagrams/56-inventorymanagement)
44 | - [Prisma schema file](https://github.com/ed-roh/inventory-management/blob/master/server/prisma/schema.prisma)
45 | - [AWS commands](https://github.com/ed-roh/inventory-management/blob/master/server/aws-ec2-instructions.md)
46 |
--------------------------------------------------------------------------------
/server/prisma/seed.ts:
--------------------------------------------------------------------------------
1 | import { PrismaClient } from "@prisma/client";
2 | import fs from "fs";
3 | import path from "path";
4 | const prisma = new PrismaClient();
5 |
6 | async function deleteAllData(orderedFileNames: string[]) {
7 | const modelNames = orderedFileNames.map((fileName) => {
8 | const modelName = path.basename(fileName, path.extname(fileName));
9 | return modelName.charAt(0).toUpperCase() + modelName.slice(1);
10 | });
11 |
12 | for (const modelName of modelNames) {
13 | const model: any = prisma[modelName as keyof typeof prisma];
14 | if (model) {
15 | await model.deleteMany({});
16 | console.log(`Cleared data from ${modelName}`);
17 | } else {
18 | console.error(
19 | `Model ${modelName} not found. Please ensure the model name is correctly specified.`
20 | );
21 | }
22 | }
23 | }
24 |
25 | async function main() {
26 | const dataDirectory = path.join(__dirname, "seedData");
27 |
28 | const orderedFileNames = [
29 | "products.json",
30 | "expenseSummary.json",
31 | "sales.json",
32 | "salesSummary.json",
33 | "purchases.json",
34 | "purchaseSummary.json",
35 | "users.json",
36 | "expenses.json",
37 | "expenseByCategory.json",
38 | ];
39 |
40 | await deleteAllData(orderedFileNames);
41 |
42 | for (const fileName of orderedFileNames) {
43 | const filePath = path.join(dataDirectory, fileName);
44 | const jsonData = JSON.parse(fs.readFileSync(filePath, "utf-8"));
45 | const modelName = path.basename(fileName, path.extname(fileName));
46 | const model: any = prisma[modelName as keyof typeof prisma];
47 |
48 | if (!model) {
49 | console.error(`No Prisma model matches the file name: ${fileName}`);
50 | continue;
51 | }
52 |
53 | for (const data of jsonData) {
54 | await model.create({
55 | data,
56 | });
57 | }
58 |
59 | console.log(`Seeded ${modelName} with data from ${fileName}`);
60 | }
61 | }
62 |
63 | main()
64 | .catch((e) => {
65 | console.error(e);
66 | })
67 | .finally(async () => {
68 | await prisma.$disconnect();
69 | });
70 |
--------------------------------------------------------------------------------
/server/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | // This is your Prisma schema file,
2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema
3 |
4 | // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
5 | // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
6 |
7 | generator client {
8 | provider = "prisma-client-js"
9 | }
10 |
11 | datasource db {
12 | provider = "postgresql"
13 | url = env("DATABASE_URL")
14 | }
15 |
16 | model Users {
17 | userId String @id
18 | name String
19 | email String
20 | }
21 |
22 | model Products {
23 | productId String @id
24 | name String
25 | price Float
26 | rating Float?
27 | stockQuantity Int
28 | Sales Sales[]
29 | Purchases Purchases[]
30 | }
31 |
32 | model Sales {
33 | saleId String @id
34 | productId String
35 | timestamp DateTime
36 | quantity Int
37 | unitPrice Float
38 | totalAmount Float
39 | product Products @relation(fields: [productId], references: [productId])
40 | }
41 |
42 | model Purchases {
43 | purchaseId String @id
44 | productId String
45 | timestamp DateTime
46 | quantity Int
47 | unitCost Float
48 | totalCost Float
49 | product Products @relation(fields: [productId], references: [productId])
50 | }
51 |
52 | model Expenses {
53 | expenseId String @id
54 | category String
55 | amount Float
56 | timestamp DateTime
57 | }
58 |
59 | model SalesSummary {
60 | salesSummaryId String @id
61 | totalValue Float
62 | changePercentage Float?
63 | date DateTime
64 | }
65 |
66 | model PurchaseSummary {
67 | purchaseSummaryId String @id
68 | totalPurchased Float
69 | changePercentage Float?
70 | date DateTime
71 | }
72 |
73 | model ExpenseSummary {
74 | expenseSummaryId String @id
75 | totalExpenses Float
76 | date DateTime
77 | ExpenseByCategory ExpenseByCategory[]
78 | }
79 |
80 | model ExpenseByCategory {
81 | expenseByCategoryId String @id
82 | expenseSummaryId String
83 | category String
84 | amount BigInt
85 | date DateTime
86 | expenseSummary ExpenseSummary @relation(fields: [expenseSummaryId], references: [expenseSummaryId])
87 | }
88 |
--------------------------------------------------------------------------------
/client/src/app/dashboard/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import {
4 | CheckCircle,
5 | Package,
6 | Tag,
7 | TrendingDown,
8 | TrendingUp,
9 | } from "lucide-react";
10 | import CardExpenseSummary from "./CardExpenseSummary";
11 | import CardPopularProducts from "./CardPopularProducts";
12 | import CardPurchaseSummary from "./CardPurchaseSummary";
13 | import CardSalesSummary from "./CardSalesSummary";
14 | import StatCard from "./StatCard";
15 |
16 | const Dashboard = () => {
17 | return (
18 |
19 |
20 |
21 |
22 |
23 | }
26 | dateRange="22 - 29 October 2023"
27 | details={[
28 | {
29 | title: "Customer Growth",
30 | amount: "175.00",
31 | changePercentage: 131,
32 | IconComponent: TrendingUp,
33 | },
34 | {
35 | title: "Expenses",
36 | amount: "10.00",
37 | changePercentage: -56,
38 | IconComponent: TrendingDown,
39 | },
40 | ]}
41 | />
42 | }
45 | dateRange="22 - 29 October 2023"
46 | details={[
47 | {
48 | title: "Dues",
49 | amount: "250.00",
50 | changePercentage: 131,
51 | IconComponent: TrendingUp,
52 | },
53 | {
54 | title: "Pending Orders",
55 | amount: "147",
56 | changePercentage: -56,
57 | IconComponent: TrendingDown,
58 | },
59 | ]}
60 | />
61 | }
64 | dateRange="22 - 29 October 2023"
65 | details={[
66 | {
67 | title: "Sales",
68 | amount: "1000.00",
69 | changePercentage: 20,
70 | IconComponent: TrendingUp,
71 | },
72 | {
73 | title: "Discount",
74 | amount: "200.00",
75 | changePercentage: -10,
76 | IconComponent: TrendingDown,
77 | },
78 | ]}
79 | />
80 |
81 | );
82 | };
83 |
84 | export default Dashboard;
85 |
--------------------------------------------------------------------------------
/server/aws-ec2-instructions.md:
--------------------------------------------------------------------------------
1 | # EC2 Setup Instructions
2 |
3 | ## 1. Connect to EC2 Instance via EC2 Instance Connect
4 |
5 | ## 2. Install Node Version Manager (nvm) and Node.js
6 |
7 | - **Switch to superuser and install nvm:**
8 |
9 | ```
10 | sudo su -
11 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
12 | ```
13 |
14 | - **Activate nvm:**
15 |
16 | ```
17 | . ~/.nvm/nvm.sh
18 | ```
19 |
20 | - **Install the latest version of Node.js using nvm:**
21 |
22 | ```
23 | nvm install node
24 | ```
25 |
26 | - **Verify that Node.js and npm are installed:**
27 |
28 | ```
29 | node -v
30 | npm -v
31 | ```
32 |
33 | ## 3. Install Git
34 |
35 | - **Update the system and install Git:**
36 |
37 | ```
38 | sudo yum update -y
39 | sudo yum install git -y
40 | ```
41 |
42 | - **Check Git version:**
43 |
44 | ```
45 | git --version
46 | ```
47 |
48 | - **Clone your code repository from GitHub:**
49 |
50 | ```
51 | git clone [your-github-link]
52 | ```
53 |
54 | - **Navigate to the directory and install packages:**
55 |
56 | ```
57 | cd inventory-management
58 | npm i
59 | ```
60 |
61 | - **Create Env File and Port 80:**
62 |
63 | ```
64 | echo "PORT=80" > .env
65 | ```
66 |
67 | - **Start the application:**
68 |
69 | ```
70 | npm start
71 | ```
72 |
73 | ## 4. Install pm2 (Production Process Manager for Node.js)
74 |
75 | - **Install pm2 globally:**
76 |
77 | ```
78 | npm i pm2 -g
79 | ```
80 |
81 | - **Create a pm2 ecosystem configuration file (inside server directory):**
82 |
83 | ```
84 | module.exports = { apps : [{ name: 'inventory-management', script: 'npm', args: 'run dev', env: { NODE_ENV: 'development', ENV_VAR1: 'environment-variable', } }], };
85 | ```
86 |
87 | - **Modify the ecosystem file if necessary:**
88 |
89 | ```
90 | nano ecosystem.config.js
91 | ```
92 |
93 | - **Set pm2 to restart automatically on system reboot:**
94 |
95 | ```
96 | sudo env PATH=$PATH:$(which node) $(which pm2) startup systemd -u $USER --hp $(eval echo ~$USER)
97 | ```
98 |
99 | - **Start the application using the pm2 ecosystem configuration:**
100 |
101 | ```
102 | pm2 start ecosystem.config.js
103 | ```
104 |
105 | - **Useful pm2 commands:**
106 |
107 | - **Stop all processes:**
108 |
109 | ```
110 | pm2 stop all
111 | ```
112 |
113 | - **Delete all processes:**
114 |
115 | ```
116 | pm2 delete all
117 | ```
118 |
119 | - **Check status of processes:**
120 |
121 | ```
122 | pm2 status
123 | ```
124 |
125 | - **Monitor processes:**
126 |
127 | ```
128 | pm2 monit
129 | ```
130 |
--------------------------------------------------------------------------------
/client/src/app/dashboard/CardPopularProducts.tsx:
--------------------------------------------------------------------------------
1 | import { useGetDashboardMetricsQuery } from "@/state/api";
2 | import { ShoppingBag } from "lucide-react";
3 | import React from "react";
4 | import Rating from "../(components)/Rating";
5 | import Image from "next/image";
6 |
7 | const CardPopularProducts = () => {
8 | const { data: dashboardMetrics, isLoading } = useGetDashboardMetricsQuery();
9 |
10 | return (
11 |
12 | {isLoading ? (
13 |
Loading...
14 | ) : (
15 | <>
16 |
17 | Popular Products
18 |
19 |
20 |
21 | {dashboardMetrics?.popularProducts.map((product) => (
22 |
26 |
27 |
36 |
37 |
38 | {product.name}
39 |
40 |
41 |
42 | ${product.price}
43 |
44 | |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
54 | {Math.round(product.stockQuantity / 1000)}k Sold
55 |
56 |
57 | ))}
58 |
59 | >
60 | )}
61 |
62 | );
63 | };
64 |
65 | export default CardPopularProducts;
66 |
--------------------------------------------------------------------------------
/client/src/app/dashboard/StatCard.tsx:
--------------------------------------------------------------------------------
1 | import { LucideIcon } from "lucide-react";
2 | import React from "react";
3 |
4 | type StatDetail = {
5 | title: string;
6 | amount: string;
7 | changePercentage: number;
8 | IconComponent: LucideIcon;
9 | };
10 |
11 | type StatCardProps = {
12 | title: string;
13 | primaryIcon: JSX.Element;
14 | details: StatDetail[];
15 | dateRange: string;
16 | };
17 |
18 | const StatCard = ({
19 | title,
20 | primaryIcon,
21 | details,
22 | dateRange,
23 | }: StatCardProps) => {
24 | const formatPercentage = (value: number) => {
25 | const signal = value >= 0 ? "+" : "";
26 | return `${signal}${value.toFixed()}%`;
27 | };
28 |
29 | const getChangeColor = (value: number) =>
30 | value >= 0 ? "text-green-500" : "text-red-500";
31 |
32 | return (
33 |
34 | {/* HEADER */}
35 |
36 |
37 |
{title}
38 | {dateRange}
39 |
40 |
41 |
42 |
43 | {/* BODY */}
44 |
45 |
46 | {primaryIcon}
47 |
48 |
49 | {details.map((detail, index) => (
50 |
51 |
52 |
{detail.title}
53 |
{detail.amount}
54 |
55 |
60 |
61 |
66 | {formatPercentage(detail.changePercentage)}
67 |
68 |
69 |
70 | {index < details.length - 1 &&
}
71 |
72 | ))}
73 |
74 |
75 |
76 | );
77 | };
78 |
79 | export default StatCard;
80 |
--------------------------------------------------------------------------------
/server/prisma/seedData/expenses.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "expenseId": "5c1121d7-20c8-4890-81c0-949bd60523a3",
4 | "category": "Salaries",
5 | "amount": 1489153.5,
6 | "timestamp": "2022-08-27T18:35:57Z"
7 | },
8 | {
9 | "expenseId": "4529aaef-39d0-4188-9256-8c8fd5bad7ca",
10 | "category": "Office",
11 | "amount": 1579039.97,
12 | "timestamp": "2020-05-12T19:39:50Z"
13 | },
14 | {
15 | "expenseId": "fca4f2d0-c3d7-4246-a04e-626ab4045c40",
16 | "category": "Office",
17 | "amount": 607415.3,
18 | "timestamp": "2021-06-08T13:48:10Z"
19 | },
20 | {
21 | "expenseId": "34de9517-153e-4505-9af8-dc8440e28dd9",
22 | "category": "Salaries",
23 | "amount": 171044.25,
24 | "timestamp": "2022-10-03T22:21:20Z"
25 | },
26 | {
27 | "expenseId": "c21c08e8-51b9-40f1-be37-b5116cd8d174",
28 | "category": "Salaries",
29 | "amount": 303743.89,
30 | "timestamp": "2020-03-18T00:41:00Z"
31 | },
32 | {
33 | "expenseId": "fb2dba2d-c186-4165-ab7d-66ce276041a4",
34 | "category": "Salaries",
35 | "amount": 1707710.31,
36 | "timestamp": "2020-05-04T20:18:41Z"
37 | },
38 | {
39 | "expenseId": "ba5ded78-639c-46ce-80bf-7d50642a1438",
40 | "category": "Office",
41 | "amount": 1375535.38,
42 | "timestamp": "2021-11-04T02:56:56Z"
43 | },
44 | {
45 | "expenseId": "c2f642b5-399b-48d7-9deb-e6a4eed0b9fa",
46 | "category": "Office",
47 | "amount": 858502.63,
48 | "timestamp": "2020-09-04T19:49:29Z"
49 | },
50 | {
51 | "expenseId": "fc8b38d8-388a-4898-9ca5-b942bbbec035",
52 | "category": "Professional",
53 | "amount": 1557261.18,
54 | "timestamp": "2020-07-22T02:35:40Z"
55 | },
56 | {
57 | "expenseId": "36764f05-d204-4f71-bbd3-9d0263ea6863",
58 | "category": "Salaries",
59 | "amount": 586616.74,
60 | "timestamp": "2021-01-18T01:06:07Z"
61 | },
62 | {
63 | "expenseId": "39e86828-36f4-4282-9599-bc4c42bae3a1",
64 | "category": "Office",
65 | "amount": 1677605.54,
66 | "timestamp": "2022-07-12T16:33:04Z"
67 | },
68 | {
69 | "expenseId": "66a3d687-05b0-4796-9b09-14941aa73031",
70 | "category": "Salaries",
71 | "amount": 1280249.59,
72 | "timestamp": "2021-09-09T05:45:26Z"
73 | },
74 | {
75 | "expenseId": "cfbd98f2-c6ed-4bcc-b604-f3d330c5f31e",
76 | "category": "Professional",
77 | "amount": 1851906.49,
78 | "timestamp": "2021-12-24T09:18:27Z"
79 | },
80 | {
81 | "expenseId": "c68ccd7e-601c-4b09-b76f-c5a19308e526",
82 | "category": "Salaries",
83 | "amount": 1791685.13,
84 | "timestamp": "2022-08-05T03:18:23Z"
85 | },
86 | {
87 | "expenseId": "3f19431c-3403-468b-9421-c9f54d466052",
88 | "category": "Salaries",
89 | "amount": 589917.71,
90 | "timestamp": "2021-05-19T17:43:00Z"
91 | }
92 | ]
93 |
--------------------------------------------------------------------------------
/client/src/app/redux.tsx:
--------------------------------------------------------------------------------
1 | import { useRef } from "react";
2 | import { combineReducers, configureStore } from "@reduxjs/toolkit";
3 | import {
4 | TypedUseSelectorHook,
5 | useDispatch,
6 | useSelector,
7 | Provider,
8 | } from "react-redux";
9 | import globalReducer from "@/state";
10 | import { api } from "@/state/api";
11 | import { setupListeners } from "@reduxjs/toolkit/query";
12 |
13 | import {
14 | persistStore,
15 | persistReducer,
16 | FLUSH,
17 | REHYDRATE,
18 | PAUSE,
19 | PERSIST,
20 | PURGE,
21 | REGISTER,
22 | } from "redux-persist";
23 | import { PersistGate } from "redux-persist/integration/react";
24 | import createWebStorage from "redux-persist/lib/storage/createWebStorage";
25 |
26 | /* REDUX PERSISTENCE */
27 | const createNoopStorage = () => {
28 | return {
29 | getItem(_key: any) {
30 | return Promise.resolve(null);
31 | },
32 | setItem(_key: any, value: any) {
33 | return Promise.resolve(value);
34 | },
35 | removeItem(_key: any) {
36 | return Promise.resolve();
37 | },
38 | };
39 | };
40 |
41 | const storage =
42 | typeof window === "undefined"
43 | ? createNoopStorage()
44 | : createWebStorage("local");
45 |
46 | const persistConfig = {
47 | key: "root",
48 | storage,
49 | whitelist: ["global"],
50 | };
51 | const rootReducer = combineReducers({
52 | global: globalReducer,
53 | [api.reducerPath]: api.reducer,
54 | });
55 | const persistedReducer = persistReducer(persistConfig, rootReducer);
56 |
57 | /* REDUX STORE */
58 | export const makeStore = () => {
59 | return configureStore({
60 | reducer: persistedReducer,
61 | middleware: (getDefaultMiddleware) =>
62 | getDefaultMiddleware({
63 | serializableCheck: {
64 | ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
65 | },
66 | }).concat(api.middleware),
67 | });
68 | };
69 |
70 | /* REDUX TYPES */
71 | export type AppStore = ReturnType;
72 | export type RootState = ReturnType;
73 | export type AppDispatch = AppStore["dispatch"];
74 | export const useAppDispatch = () => useDispatch();
75 | export const useAppSelector: TypedUseSelectorHook = useSelector;
76 |
77 | /* PROVIDER */
78 | export default function StoreProvider({
79 | children,
80 | }: {
81 | children: React.ReactNode;
82 | }) {
83 | const storeRef = useRef();
84 | if (!storeRef.current) {
85 | storeRef.current = makeStore();
86 | setupListeners(storeRef.current.dispatch);
87 | }
88 | const persistor = persistStore(storeRef.current);
89 |
90 | return (
91 |
92 |
93 | {children}
94 |
95 |
96 | );
97 | }
98 |
--------------------------------------------------------------------------------
/client/src/state/api.ts:
--------------------------------------------------------------------------------
1 | import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
2 |
3 | export interface Product {
4 | productId: string;
5 | name: string;
6 | price: number;
7 | rating?: number;
8 | stockQuantity: number;
9 | }
10 |
11 | export interface NewProduct {
12 | name: string;
13 | price: number;
14 | rating?: number;
15 | stockQuantity: number;
16 | }
17 |
18 | export interface SalesSummary {
19 | salesSummaryId: string;
20 | totalValue: number;
21 | changePercentage?: number;
22 | date: string;
23 | }
24 |
25 | export interface PurchaseSummary {
26 | purchaseSummaryId: string;
27 | totalPurchased: number;
28 | changePercentage?: number;
29 | date: string;
30 | }
31 |
32 | export interface ExpenseSummary {
33 | expenseSummarId: string;
34 | totalExpenses: number;
35 | date: string;
36 | }
37 |
38 | export interface ExpenseByCategorySummary {
39 | expenseByCategorySummaryId: string;
40 | category: string;
41 | amount: string;
42 | date: string;
43 | }
44 |
45 | export interface DashboardMetrics {
46 | popularProducts: Product[];
47 | salesSummary: SalesSummary[];
48 | purchaseSummary: PurchaseSummary[];
49 | expenseSummary: ExpenseSummary[];
50 | expenseByCategorySummary: ExpenseByCategorySummary[];
51 | }
52 |
53 | export interface User {
54 | userId: string;
55 | name: string;
56 | email: string;
57 | }
58 |
59 | export const api = createApi({
60 | baseQuery: fetchBaseQuery({ baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL }),
61 | reducerPath: "api",
62 | tagTypes: ["DashboardMetrics", "Products", "Users", "Expenses"],
63 | endpoints: (build) => ({
64 | getDashboardMetrics: build.query({
65 | query: () => "/dashboard",
66 | providesTags: ["DashboardMetrics"],
67 | }),
68 | getProducts: build.query({
69 | query: (search) => ({
70 | url: "/products",
71 | params: search ? { search } : {},
72 | }),
73 | providesTags: ["Products"],
74 | }),
75 | createProduct: build.mutation({
76 | query: (newProduct) => ({
77 | url: "/products",
78 | method: "POST",
79 | body: newProduct,
80 | }),
81 | invalidatesTags: ["Products"],
82 | }),
83 | getUsers: build.query({
84 | query: () => "/users",
85 | providesTags: ["Users"],
86 | }),
87 | getExpensesByCategory: build.query({
88 | query: () => "/expenses",
89 | providesTags: ["Expenses"],
90 | }),
91 | }),
92 | });
93 |
94 | export const {
95 | useGetDashboardMetricsQuery,
96 | useGetProductsQuery,
97 | useCreateProductMutation,
98 | useGetUsersQuery,
99 | useGetExpensesByCategoryQuery,
100 | } = api;
101 |
--------------------------------------------------------------------------------
/client/src/app/(components)/Navbar/index.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useAppDispatch, useAppSelector } from "@/app/redux";
4 | import { setIsDarkMode, setIsSidebarCollapsed } from "@/state";
5 | import { Bell, Menu, Moon, Settings, Sun } from "lucide-react";
6 | import Image from "next/image";
7 | import Link from "next/link";
8 | import React from "react";
9 |
10 | const Navbar = () => {
11 | const dispatch = useAppDispatch();
12 | const isSidebarCollapsed = useAppSelector(
13 | (state) => state.global.isSidebarCollapsed
14 | );
15 | const isDarkMode = useAppSelector((state) => state.global.isDarkMode);
16 |
17 | const toggleSidebar = () => {
18 | dispatch(setIsSidebarCollapsed(!isSidebarCollapsed));
19 | };
20 |
21 | const toggleDarkMode = () => {
22 | dispatch(setIsDarkMode(!isDarkMode));
23 | };
24 |
25 | return (
26 |
27 | {/* LEFT SIDE */}
28 |
29 |
35 |
36 |
37 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | {/* RIGHT SIDE */}
50 |
51 |
52 |
53 |
60 |
61 |
62 |
63 |
64 | 3
65 |
66 |
67 |
68 |
69 |
76 | Ed Roh
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | );
85 | };
86 |
87 | export default Navbar;
88 |
--------------------------------------------------------------------------------
/server/prisma/migrations/20240711174419_init/migration.sql:
--------------------------------------------------------------------------------
1 | -- CreateTable
2 | CREATE TABLE "Users" (
3 | "userId" TEXT NOT NULL,
4 | "name" TEXT NOT NULL,
5 | "email" TEXT NOT NULL,
6 |
7 | CONSTRAINT "Users_pkey" PRIMARY KEY ("userId")
8 | );
9 |
10 | -- CreateTable
11 | CREATE TABLE "Products" (
12 | "productId" TEXT NOT NULL,
13 | "name" TEXT NOT NULL,
14 | "price" DOUBLE PRECISION NOT NULL,
15 | "rating" DOUBLE PRECISION,
16 | "stockQuantity" INTEGER NOT NULL,
17 |
18 | CONSTRAINT "Products_pkey" PRIMARY KEY ("productId")
19 | );
20 |
21 | -- CreateTable
22 | CREATE TABLE "Sales" (
23 | "saleId" TEXT NOT NULL,
24 | "productId" TEXT NOT NULL,
25 | "timestamp" TIMESTAMP(3) NOT NULL,
26 | "quantity" INTEGER NOT NULL,
27 | "unitPrice" DOUBLE PRECISION NOT NULL,
28 | "totalAmount" DOUBLE PRECISION NOT NULL,
29 |
30 | CONSTRAINT "Sales_pkey" PRIMARY KEY ("saleId")
31 | );
32 |
33 | -- CreateTable
34 | CREATE TABLE "Purchases" (
35 | "purchaseId" TEXT NOT NULL,
36 | "productId" TEXT NOT NULL,
37 | "timestamp" TIMESTAMP(3) NOT NULL,
38 | "quantity" INTEGER NOT NULL,
39 | "unitCost" DOUBLE PRECISION NOT NULL,
40 | "totalCost" DOUBLE PRECISION NOT NULL,
41 |
42 | CONSTRAINT "Purchases_pkey" PRIMARY KEY ("purchaseId")
43 | );
44 |
45 | -- CreateTable
46 | CREATE TABLE "Expenses" (
47 | "expenseId" TEXT NOT NULL,
48 | "category" TEXT NOT NULL,
49 | "amount" DOUBLE PRECISION NOT NULL,
50 | "timestamp" TIMESTAMP(3) NOT NULL,
51 |
52 | CONSTRAINT "Expenses_pkey" PRIMARY KEY ("expenseId")
53 | );
54 |
55 | -- CreateTable
56 | CREATE TABLE "SalesSummary" (
57 | "salesSummaryId" TEXT NOT NULL,
58 | "totalValue" DOUBLE PRECISION NOT NULL,
59 | "changePercentage" DOUBLE PRECISION,
60 | "date" TIMESTAMP(3) NOT NULL,
61 |
62 | CONSTRAINT "SalesSummary_pkey" PRIMARY KEY ("salesSummaryId")
63 | );
64 |
65 | -- CreateTable
66 | CREATE TABLE "PurchaseSummary" (
67 | "purchaseSummaryId" TEXT NOT NULL,
68 | "totalPurchased" DOUBLE PRECISION NOT NULL,
69 | "changePercentage" DOUBLE PRECISION,
70 | "date" TIMESTAMP(3) NOT NULL,
71 |
72 | CONSTRAINT "PurchaseSummary_pkey" PRIMARY KEY ("purchaseSummaryId")
73 | );
74 |
75 | -- CreateTable
76 | CREATE TABLE "ExpenseSummary" (
77 | "expenseSummaryId" TEXT NOT NULL,
78 | "totalExpenses" DOUBLE PRECISION NOT NULL,
79 | "date" TIMESTAMP(3) NOT NULL,
80 |
81 | CONSTRAINT "ExpenseSummary_pkey" PRIMARY KEY ("expenseSummaryId")
82 | );
83 |
84 | -- CreateTable
85 | CREATE TABLE "ExpenseByCategory" (
86 | "expenseByCategoryId" TEXT NOT NULL,
87 | "expenseSummaryId" TEXT NOT NULL,
88 | "category" TEXT NOT NULL,
89 | "amount" BIGINT NOT NULL,
90 | "date" TIMESTAMP(3) NOT NULL,
91 |
92 | CONSTRAINT "ExpenseByCategory_pkey" PRIMARY KEY ("expenseByCategoryId")
93 | );
94 |
95 | -- AddForeignKey
96 | ALTER TABLE "Sales" ADD CONSTRAINT "Sales_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Products"("productId") ON DELETE RESTRICT ON UPDATE CASCADE;
97 |
98 | -- AddForeignKey
99 | ALTER TABLE "Purchases" ADD CONSTRAINT "Purchases_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Products"("productId") ON DELETE RESTRICT ON UPDATE CASCADE;
100 |
101 | -- AddForeignKey
102 | ALTER TABLE "ExpenseByCategory" ADD CONSTRAINT "ExpenseByCategory_expenseSummaryId_fkey" FOREIGN KEY ("expenseSummaryId") REFERENCES "ExpenseSummary"("expenseSummaryId") ON DELETE RESTRICT ON UPDATE CASCADE;
103 |
--------------------------------------------------------------------------------
/client/src/app/settings/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React, { useState } from "react";
4 | import Header from "@/app/(components)/Header";
5 |
6 | type UserSetting = {
7 | label: string;
8 | value: string | boolean;
9 | type: "text" | "toggle";
10 | };
11 |
12 | const mockSettings: UserSetting[] = [
13 | { label: "Username", value: "john_doe", type: "text" },
14 | { label: "Email", value: "john.doe@example.com", type: "text" },
15 | { label: "Notification", value: true, type: "toggle" },
16 | { label: "Dark Mode", value: false, type: "toggle" },
17 | { label: "Language", value: "English", type: "text" },
18 | ];
19 |
20 | const Settings = () => {
21 | const [userSettings, setUserSettings] = useState(mockSettings);
22 |
23 | const handleToggleChange = (index: number) => {
24 | const settingsCopy = [...userSettings];
25 | settingsCopy[index].value = !settingsCopy[index].value as boolean;
26 | setUserSettings(settingsCopy);
27 | };
28 |
29 | return (
30 |
84 | );
85 | };
86 |
87 | export default Settings;
88 |
--------------------------------------------------------------------------------
/client/src/app/dashboard/CardPurchaseSummary.tsx:
--------------------------------------------------------------------------------
1 | import { useGetDashboardMetricsQuery } from "@/state/api";
2 | import { TrendingDown, TrendingUp } from "lucide-react";
3 | import numeral from "numeral";
4 | import React from "react";
5 | import {
6 | Area,
7 | AreaChart,
8 | ResponsiveContainer,
9 | Tooltip,
10 | XAxis,
11 | YAxis,
12 | } from "recharts";
13 |
14 | const CardPurchaseSummary = () => {
15 | const { data, isLoading } = useGetDashboardMetricsQuery();
16 | const purchaseData = data?.purchaseSummary || [];
17 |
18 | const lastDataPoint = purchaseData[purchaseData.length - 1] || null;
19 |
20 | return (
21 |
22 | {isLoading ? (
23 |
Loading...
24 | ) : (
25 | <>
26 | {/* HEADER */}
27 |
28 |
29 | Purchase Summary
30 |
31 |
32 |
33 |
34 | {/* BODY */}
35 |
36 | {/* BODY HEADER */}
37 |
38 |
Purchased
39 |
40 |
41 | {lastDataPoint
42 | ? numeral(lastDataPoint.totalPurchased).format("$0.00a")
43 | : "0"}
44 |
45 | {lastDataPoint && (
46 |
= 0
49 | ? "text-green-500"
50 | : "text-red-500"
51 | } flex ml-3`}
52 | >
53 | {lastDataPoint.changePercentage! >= 0 ? (
54 |
55 | ) : (
56 |
57 | )}
58 | {Math.abs(lastDataPoint.changePercentage!)}%
59 |
60 | )}
61 |
62 |
63 | {/* CHART */}
64 |
65 |
69 |
70 |
71 | [
73 | `$${value.toLocaleString("en")}`,
74 | ]}
75 | labelFormatter={(label) => {
76 | const date = new Date(label);
77 | return date.toLocaleDateString("en-US", {
78 | year: "numeric",
79 | month: "long",
80 | day: "numeric",
81 | });
82 | }}
83 | />
84 |
91 |
92 |
93 |
94 | >
95 | )}
96 |
97 | );
98 | };
99 |
100 | export default CardPurchaseSummary;
101 |
--------------------------------------------------------------------------------
/client/src/app/products/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useCreateProductMutation, useGetProductsQuery } from "@/state/api";
4 | import { PlusCircleIcon, SearchIcon } from "lucide-react";
5 | import { useState } from "react";
6 | import Header from "@/app/(components)/Header";
7 | import Rating from "@/app/(components)/Rating";
8 | import CreateProductModal from "./CreateProductModal";
9 | import Image from "next/image";
10 |
11 | type ProductFormData = {
12 | name: string;
13 | price: number;
14 | stockQuantity: number;
15 | rating: number;
16 | };
17 |
18 | const Products = () => {
19 | const [searchTerm, setSearchTerm] = useState("");
20 | const [isModalOpen, setIsModalOpen] = useState(false);
21 |
22 | const {
23 | data: products,
24 | isLoading,
25 | isError,
26 | } = useGetProductsQuery(searchTerm);
27 |
28 | const [createProduct] = useCreateProductMutation();
29 | const handleCreateProduct = async (productData: ProductFormData) => {
30 | await createProduct(productData);
31 | };
32 |
33 | if (isLoading) {
34 | return Loading...
;
35 | }
36 |
37 | if (isError || !products) {
38 | return (
39 |
40 | Failed to fetch products
41 |
42 | );
43 | }
44 |
45 | return (
46 |
47 | {/* SEARCH BAR */}
48 |
49 |
50 |
51 | setSearchTerm(e.target.value)}
56 | />
57 |
58 |
59 |
60 | {/* HEADER BAR */}
61 |
62 |
63 |
70 |
71 |
72 | {/* BODY PRODUCTS LIST */}
73 |
74 | {isLoading ? (
75 |
Loading...
76 | ) : (
77 | products?.map((product) => (
78 |
82 |
83 |
92 |
93 | {product.name}
94 |
95 |
${product.price.toFixed(2)}
96 |
97 | Stock: {product.stockQuantity}
98 |
99 | {product.rating && (
100 |
101 |
102 |
103 | )}
104 |
105 |
106 | ))
107 | )}
108 |
109 |
110 | {/* MODAL */}
111 |
setIsModalOpen(false)}
114 | onCreate={handleCreateProduct}
115 | />
116 |
117 | );
118 | };
119 |
120 | export default Products;
121 |
--------------------------------------------------------------------------------
/client/src/app/products/CreateProductModal.tsx:
--------------------------------------------------------------------------------
1 | import React, { ChangeEvent, FormEvent, useState } from "react";
2 | import { v4 } from "uuid";
3 | import Header from "@/app/(components)/Header";
4 |
5 | type ProductFormData = {
6 | name: string;
7 | price: number;
8 | stockQuantity: number;
9 | rating: number;
10 | };
11 |
12 | type CreateProductModalProps = {
13 | isOpen: boolean;
14 | onClose: () => void;
15 | onCreate: (formData: ProductFormData) => void;
16 | };
17 |
18 | const CreateProductModal = ({
19 | isOpen,
20 | onClose,
21 | onCreate,
22 | }: CreateProductModalProps) => {
23 | const [formData, setFormData] = useState({
24 | productId: v4(),
25 | name: "",
26 | price: 0,
27 | stockQuantity: 0,
28 | rating: 0,
29 | });
30 |
31 | const handleChange = (e: ChangeEvent) => {
32 | const { name, value } = e.target;
33 | setFormData({
34 | ...formData,
35 | [name]:
36 | name === "price" || name === "stockQuantity" || name === "rating"
37 | ? parseFloat(value)
38 | : value,
39 | });
40 | };
41 |
42 | const handleSubmit = (e: FormEvent) => {
43 | e.preventDefault();
44 | onCreate(formData);
45 | onClose();
46 | };
47 |
48 | if (!isOpen) return null;
49 |
50 | const labelCssStyles = "block text-sm font-medium text-gray-700";
51 | const inputCssStyles =
52 | "block w-full mb-2 p-2 border-gray-500 border-2 rounded-md";
53 |
54 | return (
55 |
56 |
57 |
58 |
130 |
131 |
132 | );
133 | };
134 |
135 | export default CreateProductModal;
136 |
--------------------------------------------------------------------------------
/server/prisma/seedData/users.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "userId": "3b0fd66b-a4d6-4d95-94e4-01940c99aedb",
4 | "name": "Carly",
5 | "email": "cvansalzberger0@cisco.com"
6 | },
7 | {
8 | "userId": "d9d323fa-5c98-4222-a352-120e1f5e2798",
9 | "name": "Inesita",
10 | "email": "imcconnachie1@oaic.gov.au"
11 | },
12 | {
13 | "userId": "9e2895ae-4afe-4ff2-b3b3-be15cf1c82d6",
14 | "name": "Tulley",
15 | "email": "tbridywater2@wikimedia.org"
16 | },
17 | {
18 | "userId": "c7072fb5-cd2b-4703-8a58-328e5b7ed95a",
19 | "name": "Amelia",
20 | "email": "atondeur3@posterous.com"
21 | },
22 | {
23 | "userId": "22c29051-d301-4cc2-86dd-c19695408adb",
24 | "name": "Bucky",
25 | "email": "btompkin4@moonfruit.com"
26 | },
27 | {
28 | "userId": "6ac28937-bc05-4c0a-be7e-1a332e2de312",
29 | "name": "Sherline",
30 | "email": "sinston5@issuu.com"
31 | },
32 | {
33 | "userId": "552c1c73-e324-47ee-bf7f-b0dfbeb59788",
34 | "name": "Leontine",
35 | "email": "lchartres6@edublogs.org"
36 | },
37 | {
38 | "userId": "962c8a6b-c914-4aa4-93bc-2b91188a1a58",
39 | "name": "Cloris",
40 | "email": "cmorrall7@un.org"
41 | },
42 | {
43 | "userId": "35393a7a-f41b-4fe9-8901-fc39a8f803d6",
44 | "name": "Tobiah",
45 | "email": "trubinchik8@time.com"
46 | },
47 | {
48 | "userId": "9cf146a9-3da9-47fe-bcc3-3abdeb3a375d",
49 | "name": "Colet",
50 | "email": "cmincini9@dell.com"
51 | },
52 | {
53 | "userId": "4a6efba9-61a2-4829-abe6-dfed18484737",
54 | "name": "Van",
55 | "email": "vswaitea@imdb.com"
56 | },
57 | {
58 | "userId": "6718765e-123c-42d4-b2b3-efc029ff854e",
59 | "name": "Mella",
60 | "email": "mheartyb@sphinn.com"
61 | },
62 | {
63 | "userId": "0880eb85-2a08-4898-8aae-3cf90c48b08b",
64 | "name": "Karyl",
65 | "email": "kmatteic@live.com"
66 | },
67 | {
68 | "userId": "2977c5fe-22be-454a-80e1-5b93db92a371",
69 | "name": "Berrie",
70 | "email": "bnortcliffed@linkedin.com"
71 | },
72 | {
73 | "userId": "bd909a0b-f665-451a-a052-8e8111e796e3",
74 | "name": "Giselle",
75 | "email": "gsollitte@weibo.com"
76 | },
77 | {
78 | "userId": "26409ed7-15ac-4695-9813-be2afb6dad26",
79 | "name": "Niall",
80 | "email": "nrebeirof@netvibes.com"
81 | },
82 | {
83 | "userId": "80697f6f-69bc-4b03-82c0-40f48884f716",
84 | "name": "Afton",
85 | "email": "ajozaitisg@craigslist.org"
86 | },
87 | {
88 | "userId": "15d25fd9-32da-4ac7-b1b6-589a90a41dbf",
89 | "name": "Letisha",
90 | "email": "lgrimsdykeh@blogger.com"
91 | },
92 | {
93 | "userId": "0bd8b2b2-d67f-47dc-9acc-d2311006852b",
94 | "name": "Julio",
95 | "email": "jcuniami@weibo.com"
96 | },
97 | {
98 | "userId": "e83bae68-8104-4847-9f08-98206f35d100",
99 | "name": "Dana",
100 | "email": "dstrugnellj@51.la"
101 | },
102 | {
103 | "userId": "a4cf8f1f-8c61-404d-834d-220202358f91",
104 | "name": "Gertie",
105 | "email": "gmacrok@networkadvertising.org"
106 | },
107 | {
108 | "userId": "e091dbc4-0fc5-4823-9fc4-1cdded1fc5f4",
109 | "name": "Vidovik",
110 | "email": "vriddettl@usgs.gov"
111 | },
112 | {
113 | "userId": "e9ceef74-fb81-41e0-b52e-0089b978b2f3",
114 | "name": "Yancey",
115 | "email": "yfentemm@51.la"
116 | },
117 | {
118 | "userId": "9d82ca0e-cb41-4fba-a73f-acb7388e9d12",
119 | "name": "Lyndell",
120 | "email": "ldurninn@sciencedirect.com"
121 | },
122 | {
123 | "userId": "ecea4d11-d41e-468a-85d3-e80a193a5620",
124 | "name": "Heidie",
125 | "email": "hrackhamo@craigslist.org"
126 | },
127 | {
128 | "userId": "29232f0d-2423-406f-956b-00ddf9540ac8",
129 | "name": "Clem",
130 | "email": "cthorbonp@smugmug.com"
131 | },
132 | {
133 | "userId": "afd4a67e-83ba-4a62-9cdc-2fdc0c553b29",
134 | "name": "Paten",
135 | "email": "pblasdaleq@quantcast.com"
136 | },
137 | {
138 | "userId": "2a26982f-498f-4599-ab54-bc7469e2fbfd",
139 | "name": "Daisi",
140 | "email": "dsedgwickr@addthis.com"
141 | },
142 | {
143 | "userId": "c876a2cc-7528-4b61-837b-b7f7efc62cca",
144 | "name": "Sara-ann",
145 | "email": "sblundels@csmonitor.com"
146 | }
147 | ]
148 |
--------------------------------------------------------------------------------
/client/src/app/(components)/Sidebar/index.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useAppDispatch, useAppSelector } from "@/app/redux";
4 | import { setIsSidebarCollapsed } from "@/state";
5 | import {
6 | Archive,
7 | CircleDollarSign,
8 | Clipboard,
9 | Layout,
10 | LucideIcon,
11 | Menu,
12 | SlidersHorizontal,
13 | User,
14 | } from "lucide-react";
15 | import Image from "next/image";
16 | import Link from "next/link";
17 | import { usePathname } from "next/navigation";
18 | import React from "react";
19 |
20 | interface SidebarLinkProps {
21 | href: string;
22 | icon: LucideIcon;
23 | label: string;
24 | isCollapsed: boolean;
25 | }
26 |
27 | const SidebarLink = ({
28 | href,
29 | icon: Icon,
30 | label,
31 | isCollapsed,
32 | }: SidebarLinkProps) => {
33 | const pathname = usePathname();
34 | const isActive =
35 | pathname === href || (pathname === "/" && href === "/dashboard");
36 |
37 | return (
38 |
39 |
48 |
49 |
50 |
55 | {label}
56 |
57 |
58 |
59 | );
60 | };
61 |
62 | const Sidebar = () => {
63 | const dispatch = useAppDispatch();
64 | const isSidebarCollapsed = useAppSelector(
65 | (state) => state.global.isSidebarCollapsed
66 | );
67 |
68 | const toggleSidebar = () => {
69 | dispatch(setIsSidebarCollapsed(!isSidebarCollapsed));
70 | };
71 |
72 | const sidebarClassNames = `fixed flex flex-col ${
73 | isSidebarCollapsed ? "w-0 md:w-16" : "w-72 md:w-64"
74 | } bg-white transition-all duration-300 overflow-hidden h-full shadow-md z-40`;
75 |
76 | return (
77 |
78 | {/* TOP LOGO */}
79 |
84 |
91 |
96 | EDSTOCK
97 |
98 |
99 |
105 |
106 |
107 | {/* LINKS */}
108 |
109 |
115 |
121 |
127 |
133 |
139 |
145 |
146 |
147 | {/* FOOTER */}
148 |
149 |
© 2024 Edstock
150 |
151 |
152 | );
153 | };
154 |
155 | export default Sidebar;
156 |
--------------------------------------------------------------------------------
/client/src/app/dashboard/CardExpenseSummary.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | ExpenseByCategorySummary,
3 | useGetDashboardMetricsQuery,
4 | } from "@/state/api";
5 | import { TrendingUp } from "lucide-react";
6 | import { Cell, Pie, PieChart, ResponsiveContainer } from "recharts";
7 |
8 | type ExpenseSums = {
9 | [category: string]: number;
10 | };
11 |
12 | const colors = ["#00C49F", "#0088FE", "#FFBB28"];
13 |
14 | const CardExpenseSummary = () => {
15 | const { data: dashboardMetrics, isLoading } = useGetDashboardMetricsQuery();
16 |
17 | const expenseSummary = dashboardMetrics?.expenseSummary[0];
18 |
19 | const expenseByCategorySummary =
20 | dashboardMetrics?.expenseByCategorySummary || [];
21 |
22 | const expenseSums = expenseByCategorySummary.reduce(
23 | (acc: ExpenseSums, item: ExpenseByCategorySummary) => {
24 | const category = item.category + " Expenses";
25 | const amount = parseInt(item.amount, 10);
26 | if (!acc[category]) acc[category] = 0;
27 | acc[category] += amount;
28 | return acc;
29 | },
30 | {}
31 | );
32 |
33 | const expenseCategories = Object.entries(expenseSums).map(
34 | ([name, value]) => ({
35 | name,
36 | value,
37 | })
38 | );
39 |
40 | const totalExpenses = expenseCategories.reduce(
41 | (acc, category: { value: number }) => acc + category.value,
42 | 0
43 | );
44 | const formattedTotalExpenses = totalExpenses.toFixed(2);
45 |
46 | return (
47 |
48 | {isLoading ? (
49 |
Loading...
50 | ) : (
51 | <>
52 | {/* HEADER */}
53 |
54 |
55 | Expense Summary
56 |
57 |
58 |
59 | {/* BODY */}
60 |
61 | {/* CHART */}
62 |
63 |
64 |
65 |
75 | {expenseCategories.map((entry, index) => (
76 | |
80 | ))}
81 |
82 |
83 |
84 |
85 |
86 | ${formattedTotalExpenses}
87 |
88 |
89 |
90 | {/* LABELS */}
91 |
92 | {expenseCategories.map((entry, index) => (
93 | -
97 |
101 | {entry.name}
102 |
103 | ))}
104 |
105 |
106 | {/* FOOTER */}
107 |
108 |
109 | {expenseSummary && (
110 |
111 |
112 |
113 | Average:{" "}
114 |
115 | ${expenseSummary.totalExpenses.toFixed(2)}
116 |
117 |
118 |
119 |
120 |
121 | 30%
122 |
123 |
124 | )}
125 |
126 | >
127 | )}
128 |
129 | );
130 | };
131 |
132 | export default CardExpenseSummary;
133 |
--------------------------------------------------------------------------------
/client/src/app/dashboard/CardSalesSummary.tsx:
--------------------------------------------------------------------------------
1 | import { useGetDashboardMetricsQuery } from "@/state/api";
2 | import { TrendingUp } from "lucide-react";
3 | import React, { useState } from "react";
4 | import {
5 | Bar,
6 | BarChart,
7 | CartesianGrid,
8 | ResponsiveContainer,
9 | Tooltip,
10 | XAxis,
11 | YAxis,
12 | } from "recharts";
13 |
14 | const CardSalesSummary = () => {
15 | const { data, isLoading, isError } = useGetDashboardMetricsQuery();
16 | const salesData = data?.salesSummary || [];
17 |
18 | const [timeframe, setTimeframe] = useState("weekly");
19 |
20 | const totalValueSum =
21 | salesData.reduce((acc, curr) => acc + curr.totalValue, 0) || 0;
22 |
23 | const averageChangePercentage =
24 | salesData.reduce((acc, curr, _, array) => {
25 | return acc + curr.changePercentage! / array.length;
26 | }, 0) || 0;
27 |
28 | const highestValueData = salesData.reduce((acc, curr) => {
29 | return acc.totalValue > curr.totalValue ? acc : curr;
30 | }, salesData[0] || {});
31 |
32 | const highestValueDate = highestValueData.date
33 | ? new Date(highestValueData.date).toLocaleDateString("en-US", {
34 | month: "numeric",
35 | day: "numeric",
36 | year: "2-digit",
37 | })
38 | : "N/A";
39 |
40 | if (isError) {
41 | return Failed to fetch data
;
42 | }
43 |
44 | return (
45 |
46 | {isLoading ? (
47 |
Loading...
48 | ) : (
49 | <>
50 | {/* HEADER */}
51 |
52 |
53 | Sales Summary
54 |
55 |
56 |
57 |
58 | {/* BODY */}
59 |
60 | {/* BODY HEADER */}
61 |
62 |
63 |
Value
64 |
65 | $
66 | {(totalValueSum / 1000000).toLocaleString("en", {
67 | maximumFractionDigits: 2,
68 | })}
69 | m
70 |
71 |
72 |
73 | {averageChangePercentage.toFixed(2)}%
74 |
75 |
76 |
87 |
88 | {/* CHART */}
89 |
90 |
94 |
95 | {
98 | const date = new Date(value);
99 | return `${date.getMonth() + 1}/${date.getDate()}`;
100 | }}
101 | />
102 | {
104 | return `$${(value / 1000000).toFixed(0)}m`;
105 | }}
106 | tick={{ fontSize: 12, dx: -1 }}
107 | tickLine={false}
108 | axisLine={false}
109 | />
110 | [
112 | `$${value.toLocaleString("en")}`,
113 | ]}
114 | labelFormatter={(label) => {
115 | const date = new Date(label);
116 | return date.toLocaleDateString("en-US", {
117 | year: "numeric",
118 | month: "long",
119 | day: "numeric",
120 | });
121 | }}
122 | />
123 |
129 |
130 |
131 |
132 |
133 | {/* FOOTER */}
134 |
135 |
136 |
137 |
{salesData.length || 0} days
138 |
139 | Highest Sales Date:{" "}
140 | {highestValueDate}
141 |
142 |
143 |
144 | >
145 | )}
146 |
147 | );
148 | };
149 |
150 | export default CardSalesSummary;
151 |
--------------------------------------------------------------------------------
/server/prisma/seedData/purchaseSummary.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "purchaseSummaryId": "c452c304-0f7e-474f-b750-43c542df3412",
4 | "totalPurchased": 7599849.58,
5 | "changePercentage": -50.31,
6 | "date": "2023-05-27T05:20:14Z"
7 | },
8 | {
9 | "purchaseSummaryId": "1206e83e-0e1b-42e5-8ec5-35cd1080f09d",
10 | "totalPurchased": 5701783.0,
11 | "changePercentage": -89.63,
12 | "date": "2023-12-05T05:52:50Z"
13 | },
14 | {
15 | "purchaseSummaryId": "21491665-4761-4dea-b5f1-16b04d9f57bb",
16 | "totalPurchased": 2875081.56,
17 | "changePercentage": 97.28,
18 | "date": "2023-03-20T06:11:24Z"
19 | },
20 | {
21 | "purchaseSummaryId": "a8ae9a24-a851-4a75-be59-a16834827bb8",
22 | "totalPurchased": 5887134.05,
23 | "changePercentage": 84.43,
24 | "date": "2023-12-16T17:22:23Z"
25 | },
26 | {
27 | "purchaseSummaryId": "2de46932-fab9-41f6-87ca-8c06083a66f2",
28 | "totalPurchased": 6700381.67,
29 | "changePercentage": -15.4,
30 | "date": "2023-03-26T07:09:45Z"
31 | },
32 | {
33 | "purchaseSummaryId": "63409896-65aa-4f06-9bb6-fd0b6336eeb5",
34 | "totalPurchased": 3703183.4,
35 | "changePercentage": 93.36,
36 | "date": "2023-09-12T18:48:33Z"
37 | },
38 | {
39 | "purchaseSummaryId": "ab29178e-21a0-407f-8cef-8f99f5bd140c",
40 | "totalPurchased": 8183876.36,
41 | "changePercentage": 10.75,
42 | "date": "2023-07-13T19:13:53Z"
43 | },
44 | {
45 | "purchaseSummaryId": "1475b96b-0d32-4679-b8dc-050e446f8cf8",
46 | "totalPurchased": 6771390.73,
47 | "changePercentage": 8.17,
48 | "date": "2023-04-17T20:13:19Z"
49 | },
50 | {
51 | "purchaseSummaryId": "cd22c91d-af7a-4334-843c-0d9b3bd90bf8",
52 | "totalPurchased": 5362805.15,
53 | "changePercentage": -69.92,
54 | "date": "2023-12-30T11:00:31Z"
55 | },
56 | {
57 | "purchaseSummaryId": "b9952c34-ef74-41f8-9c44-76e0516dc7b9",
58 | "totalPurchased": 7901696.36,
59 | "changePercentage": -8.22,
60 | "date": "2024-01-02T01:46:59Z"
61 | },
62 | {
63 | "purchaseSummaryId": "677b220c-96b8-46b8-b367-be71b8a2fbb2",
64 | "totalPurchased": 592809.08,
65 | "changePercentage": -19.9,
66 | "date": "2023-07-07T19:23:16Z"
67 | },
68 | {
69 | "purchaseSummaryId": "584fec60-a573-4445-b23e-fd9d46eebcab",
70 | "totalPurchased": 787656.13,
71 | "changePercentage": -85.81,
72 | "date": "2023-07-10T16:48:15Z"
73 | },
74 | {
75 | "purchaseSummaryId": "124d1a24-3fd2-415d-9a6d-11737c319082",
76 | "totalPurchased": 1358410.16,
77 | "changePercentage": 81.52,
78 | "date": "2024-01-01T16:20:10Z"
79 | },
80 | {
81 | "purchaseSummaryId": "fd8bfb7f-a97c-4dd3-a3b3-d838c6dcc753",
82 | "totalPurchased": 9262819.3,
83 | "changePercentage": -13.2,
84 | "date": "2024-01-08T04:29:17Z"
85 | },
86 | {
87 | "purchaseSummaryId": "61d68449-e3ed-4fc7-b8f3-603c5c099ad0",
88 | "totalPurchased": 2892692.95,
89 | "changePercentage": 4.89,
90 | "date": "2023-07-24T18:44:29Z"
91 | },
92 | {
93 | "purchaseSummaryId": "a9c42568-3668-4750-93a4-b8798471acde",
94 | "totalPurchased": 8176245.28,
95 | "changePercentage": -80.84,
96 | "date": "2024-02-07T16:49:38Z"
97 | },
98 | {
99 | "purchaseSummaryId": "79d7b45a-ba98-437f-95b0-aa21c071709c",
100 | "totalPurchased": 6376329.63,
101 | "changePercentage": -17.35,
102 | "date": "2023-11-02T15:29:19Z"
103 | },
104 | {
105 | "purchaseSummaryId": "71fe4534-87fc-439f-b6c8-3022aa5e7d4b",
106 | "totalPurchased": 490177.73,
107 | "changePercentage": -65.94,
108 | "date": "2023-08-25T13:45:04Z"
109 | },
110 | {
111 | "purchaseSummaryId": "5c0a56c3-5140-447d-b992-a7d7c44d472d",
112 | "totalPurchased": 8033241.77,
113 | "changePercentage": -81.26,
114 | "date": "2023-11-16T18:22:18Z"
115 | },
116 | {
117 | "purchaseSummaryId": "bd1cf049-4f69-4180-a5d1-72f37beef632",
118 | "totalPurchased": 8113334.96,
119 | "changePercentage": 18.99,
120 | "date": "2023-07-17T01:23:37Z"
121 | },
122 | {
123 | "purchaseSummaryId": "6f24990f-336d-460e-84ad-810d159bad88",
124 | "totalPurchased": 2083304.59,
125 | "changePercentage": -80.93,
126 | "date": "2023-09-27T23:20:39Z"
127 | },
128 | {
129 | "purchaseSummaryId": "37e2ae04-638f-41cc-b838-4f7ebdd5f60b",
130 | "totalPurchased": 6278248.14,
131 | "changePercentage": 8.44,
132 | "date": "2023-11-29T20:52:03Z"
133 | },
134 | {
135 | "purchaseSummaryId": "a498409d-df59-46da-8065-ecaabc4e9225",
136 | "totalPurchased": 5013546.73,
137 | "changePercentage": -99.52,
138 | "date": "2023-08-01T12:30:43Z"
139 | },
140 | {
141 | "purchaseSummaryId": "b1972f5c-50d3-4c8e-b3d2-d2ad12c86277",
142 | "totalPurchased": 7883690.1,
143 | "changePercentage": -95.76,
144 | "date": "2024-01-17T21:08:06Z"
145 | },
146 | {
147 | "purchaseSummaryId": "d9d14c29-f07f-4cb5-8271-0330825e8159",
148 | "totalPurchased": 9402337.34,
149 | "changePercentage": 81.92,
150 | "date": "2024-01-21T00:14:36Z"
151 | },
152 | {
153 | "purchaseSummaryId": "4fc51811-2e51-4776-b9b5-181e5f422f6a",
154 | "totalPurchased": 4571470.93,
155 | "changePercentage": -19.34,
156 | "date": "2023-06-01T18:39:59Z"
157 | },
158 | {
159 | "purchaseSummaryId": "ccfd8bd5-c2a1-4d13-bec1-74157854773a",
160 | "totalPurchased": 4718798.68,
161 | "changePercentage": 95.35,
162 | "date": "2024-02-06T03:40:01Z"
163 | },
164 | {
165 | "purchaseSummaryId": "c2ecb47d-7b26-4e78-8b48-96a436c434bd",
166 | "totalPurchased": 1087744.03,
167 | "changePercentage": 24.69,
168 | "date": "2024-01-28T09:04:52Z"
169 | },
170 | {
171 | "purchaseSummaryId": "5fc29456-3bcc-4b2c-9096-3c36bcfae126",
172 | "totalPurchased": 3256718.55,
173 | "changePercentage": 68.1,
174 | "date": "2023-08-07T10:29:19Z"
175 | },
176 | {
177 | "purchaseSummaryId": "3b42e538-f6b8-4d8b-8778-9c052a581d58",
178 | "totalPurchased": 826579.41,
179 | "changePercentage": -87.81,
180 | "date": "2023-11-19T02:00:54Z"
181 | }
182 | ]
183 |
--------------------------------------------------------------------------------
/client/src/app/expenses/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import {
4 | ExpenseByCategorySummary,
5 | useGetExpensesByCategoryQuery,
6 | } from "@/state/api";
7 | import { useMemo, useState } from "react";
8 | import Header from "@/app/(components)/Header";
9 | import {
10 | Cell,
11 | Legend,
12 | Pie,
13 | PieChart,
14 | ResponsiveContainer,
15 | Tooltip,
16 | } from "recharts";
17 |
18 | type AggregatedDataItem = {
19 | name: string;
20 | color?: string;
21 | amount: number;
22 | };
23 |
24 | type AggregatedData = {
25 | [category: string]: AggregatedDataItem;
26 | };
27 |
28 | const Expenses = () => {
29 | const [activeIndex, setActiveIndex] = useState(0);
30 | const [selectedCategory, setSelectedCategory] = useState("All");
31 | const [startDate, setStartDate] = useState("");
32 | const [endDate, setEndDate] = useState("");
33 |
34 | const {
35 | data: expensesData,
36 | isLoading,
37 | isError,
38 | } = useGetExpensesByCategoryQuery();
39 | const expenses = useMemo(() => expensesData ?? [], [expensesData]);
40 |
41 | const parseDate = (dateString: string) => {
42 | const date = new Date(dateString);
43 | return date.toISOString().split("T")[0];
44 | };
45 |
46 | const aggregatedData: AggregatedDataItem[] = useMemo(() => {
47 | const filtered: AggregatedData = expenses
48 | .filter((data: ExpenseByCategorySummary) => {
49 | const matchesCategory =
50 | selectedCategory === "All" || data.category === selectedCategory;
51 | const dataDate = parseDate(data.date);
52 | const matchesDate =
53 | !startDate ||
54 | !endDate ||
55 | (dataDate >= startDate && dataDate <= endDate);
56 | return matchesCategory && matchesDate;
57 | })
58 | .reduce((acc: AggregatedData, data: ExpenseByCategorySummary) => {
59 | const amount = parseInt(data.amount);
60 | if (!acc[data.category]) {
61 | acc[data.category] = { name: data.category, amount: 0 };
62 | acc[data.category].color = `#${Math.floor(
63 | Math.random() * 16777215
64 | ).toString(16)}`;
65 | acc[data.category].amount += amount;
66 | }
67 | return acc;
68 | }, {});
69 |
70 | return Object.values(filtered);
71 | }, [expenses, selectedCategory, startDate, endDate]);
72 |
73 | const classNames = {
74 | label: "block text-sm font-medium text-gray-700",
75 | selectInput:
76 | "mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md",
77 | };
78 |
79 | if (isLoading) {
80 | return Loading...
;
81 | }
82 |
83 | if (isError || !expensesData) {
84 | return (
85 |
86 | Failed to fetch expenses
87 |
88 | );
89 | }
90 |
91 | return (
92 |
93 | {/* HEADER */}
94 |
95 |
96 |
97 | A visual representation of expenses over time.
98 |
99 |
100 |
101 | {/* FILTERS */}
102 |
103 |
104 |
105 | Filter by Category and Date
106 |
107 |
108 | {/* CATEGORY */}
109 |
110 |
113 |
125 |
126 | {/* START DATE */}
127 |
128 |
131 | setStartDate(e.target.value)}
137 | />
138 |
139 | {/* END DATE */}
140 |
141 |
144 | setEndDate(e.target.value)}
150 | />
151 |
152 |
153 |
154 | {/* PIE CHART */}
155 |
156 |
157 |
158 | setActiveIndex(index)}
167 | >
168 | {aggregatedData.map(
169 | (entry: AggregatedDataItem, index: number) => (
170 | |
176 | )
177 | )}
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 | );
187 | };
188 |
189 | export default Expenses;
190 |
--------------------------------------------------------------------------------
/server/prisma/seedData/products.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "productId": "d35623ee-bef6-42b2-8776-2f99f8bb4782",
4 | "name": "Pinkscale Blazing Star",
5 | "price": 456.04,
6 | "rating": 2.25,
7 | "stockQuantity": 124834
8 | },
9 | {
10 | "productId": "8ac1ac77-7358-425e-be16-0bdde9f02e59",
11 | "name": "Gila Milkvetch",
12 | "price": 899.05,
13 | "rating": 3.56,
14 | "stockQuantity": 799402
15 | },
16 | {
17 | "productId": "1afc136b-4d9f-4e8e-aace-8e1df908a404",
18 | "name": "Rocky Mountain Zinnia",
19 | "price": 264.37,
20 | "rating": 3.23,
21 | "stockQuantity": 842192
22 | },
23 | {
24 | "productId": "af84cc12-4fea-4f58-aece-f2ce92ca9580",
25 | "name": "Guadalupe Suncup",
26 | "price": 555.93,
27 | "rating": 4.09,
28 | "stockQuantity": 236333
29 | },
30 | {
31 | "productId": "86e3bb1c-2f5d-4774-98f3-4df7cddd0a0f",
32 | "name": "Saline Phlox",
33 | "price": 82.62,
34 | "rating": 4.8,
35 | "stockQuantity": 601208
36 | },
37 | {
38 | "productId": "26b017c6-06d8-443f-9b4a-d6b1cee6f4c0",
39 | "name": "Common Brighteyes",
40 | "price": 435.44,
41 | "rating": 0.27,
42 | "stockQuantity": 124068
43 | },
44 | {
45 | "productId": "440c9e80-6bf8-4eb3-b2d2-f81936d67de3",
46 | "name": "Vermejo Phlox",
47 | "price": 759.15,
48 | "rating": 2.46,
49 | "stockQuantity": 234525
50 | },
51 | {
52 | "productId": "98255f4e-40a6-470f-89a5-0792729f8947",
53 | "name": "Purple Marshlocks",
54 | "price": 974.99,
55 | "rating": 4.82,
56 | "stockQuantity": 739009
57 | },
58 | {
59 | "productId": "2a339fb2-f9f3-43bc-a85a-b217a0a38f12",
60 | "name": "Hamatocaulis Moss",
61 | "price": 639.9,
62 | "rating": 1.17,
63 | "stockQuantity": 754285
64 | },
65 | {
66 | "productId": "8a8391b2-b4ac-4847-b652-66ffd8d65875",
67 | "name": "Wax Myrtle",
68 | "price": 62.95,
69 | "rating": 4.6,
70 | "stockQuantity": 205240
71 | },
72 | {
73 | "productId": "be2157fb-7454-405e-9511-bf7ba81b7726",
74 | "name": "Thladiantha",
75 | "price": 699.0,
76 | "rating": 1.65,
77 | "stockQuantity": 399124
78 | },
79 | {
80 | "productId": "fdf1ba3d-fa06-4ce5-90ff-d081c5d37176",
81 | "name": "Common Tarweed",
82 | "price": 899.61,
83 | "rating": 2.39,
84 | "stockQuantity": 196884
85 | },
86 | {
87 | "productId": "afded6df-058f-477d-9878-e0e0b1d3dff3",
88 | "name": "Smooth Phlox",
89 | "price": 575.6,
90 | "rating": 4.38,
91 | "stockQuantity": 673658
92 | },
93 | {
94 | "productId": "daa29167-82a7-474b-9687-b8b903e7ec69",
95 | "name": "Lemmon's Beggarticks",
96 | "price": 492.35,
97 | "rating": 1.07,
98 | "stockQuantity": 205143
99 | },
100 | {
101 | "productId": "ccb83982-71f3-4497-bad8-7e64c6920dc6",
102 | "name": "Globe Fimbry",
103 | "price": 304.69,
104 | "rating": 2.62,
105 | "stockQuantity": 388596
106 | },
107 | {
108 | "productId": "1936d406-e89e-40e4-bff7-1827532269d4",
109 | "name": "Columbia Milkvetch",
110 | "price": 845.15,
111 | "rating": 2.21,
112 | "stockQuantity": 631658
113 | },
114 | {
115 | "productId": "c849a535-5f8b-47e3-889c-015693a644ac",
116 | "name": "Girdlepod",
117 | "price": 880.09,
118 | "rating": 1.49,
119 | "stockQuantity": 65457
120 | },
121 | {
122 | "productId": "0c3e80ee-59b3-4fc4-b760-8b07acc2d3ae",
123 | "name": "Lindley's Clerodendrum",
124 | "price": 51.66,
125 | "rating": 1.53,
126 | "stockQuantity": 263383
127 | },
128 | {
129 | "productId": "d8f5bee3-f3eb-4071-a124-6b857e0fd798",
130 | "name": "Arizonia Dry Rock Moss",
131 | "price": 746.88,
132 | "rating": 4.71,
133 | "stockQuantity": 616812
134 | },
135 | {
136 | "productId": "8d15de86-0e4a-4414-9166-7a33610202d3",
137 | "name": "Clamshell Orchid",
138 | "price": 17.1,
139 | "rating": 0.79,
140 | "stockQuantity": 604774
141 | },
142 | {
143 | "productId": "ea8fd0b9-c2d9-4d43-9c23-44cb99d079bb",
144 | "name": "Fourleaf Mare's-tail",
145 | "price": 905.04,
146 | "rating": 3.71,
147 | "stockQuantity": 909107
148 | },
149 | {
150 | "productId": "25d01c80-bca1-4a00-b1d0-0fbd39ff9e89",
151 | "name": "Simpson's Rosinweed",
152 | "price": 184.41,
153 | "rating": 1.98,
154 | "stockQuantity": 953695
155 | },
156 | {
157 | "productId": "1d6df6e3-b7ea-4507-9d66-87c6ee8ed5b9",
158 | "name": "Lobelia",
159 | "price": 163.6,
160 | "rating": 0.81,
161 | "stockQuantity": 341530
162 | },
163 | {
164 | "productId": "000a8c23-5bca-436c-a216-4e747a94c511",
165 | "name": "Yew Plum Pine",
166 | "price": 196.27,
167 | "rating": 1.6,
168 | "stockQuantity": 967173
169 | },
170 | {
171 | "productId": "c5b600dc-6bfb-492a-b335-c3cc8c707959",
172 | "name": "Thimbleberry",
173 | "price": 602.37,
174 | "rating": 0.13,
175 | "stockQuantity": 162208
176 | },
177 | {
178 | "productId": "9d5fafbc-312b-47e8-ada1-283918f0c3b5",
179 | "name": "Yellowturbans",
180 | "price": 564.82,
181 | "rating": 4.74,
182 | "stockQuantity": 33021
183 | },
184 | {
185 | "productId": "0114d5d4-ae48-46fa-b0ca-afe60eb88add",
186 | "name": "Field Brome",
187 | "price": 664.2,
188 | "rating": 0.13,
189 | "stockQuantity": 363992
190 | },
191 | {
192 | "productId": "e5b0da8c-148d-4680-b262-8609fb8a10da",
193 | "name": "Pentas",
194 | "price": 685.1,
195 | "rating": 1.5,
196 | "stockQuantity": 635092
197 | },
198 | {
199 | "productId": "2be5b024-2c96-4f29-912c-c6f36353f799",
200 | "name": "Strigose Beard Lichen",
201 | "price": 373.81,
202 | "rating": 1.06,
203 | "stockQuantity": 35383
204 | },
205 | {
206 | "productId": "fcf2e432-62a3-4b6f-a34d-36e42a12272e",
207 | "name": "Mad River Fleabane",
208 | "price": 669.97,
209 | "rating": 1.34,
210 | "stockQuantity": 880242
211 | },
212 | {
213 | "productId": "fc4c81e5-f1ac-40f5-8c6f-da3fbad5599d",
214 | "name": "Chickenthief",
215 | "price": 100.11,
216 | "rating": 0.49,
217 | "stockQuantity": 896782
218 | },
219 | {
220 | "productId": "07238d8e-0037-4972-87ca-0df206ee3e42",
221 | "name": "Palmleaf Poppymallow",
222 | "price": 22.99,
223 | "rating": 3.42,
224 | "stockQuantity": 635344
225 | },
226 | {
227 | "productId": "154b7860-23a2-4564-ad99-1745ab7122ef",
228 | "name": "Guayanan Waterclover",
229 | "price": 45.45,
230 | "rating": 0.34,
231 | "stockQuantity": 456487
232 | },
233 | {
234 | "productId": "8d4bf814-65d4-4df4-84cc-68911d925fdf",
235 | "name": "Emory's Acacia",
236 | "price": 847.6,
237 | "rating": 1.79,
238 | "stockQuantity": 638956
239 | },
240 | {
241 | "productId": "a52bf1bd-3d35-4cd2-849a-354e3952e2d2",
242 | "name": "American Century Plant",
243 | "price": 969.47,
244 | "rating": 3.66,
245 | "stockQuantity": 248630
246 | }
247 | ]
248 |
--------------------------------------------------------------------------------
/server/prisma/seedData/expenseSummary.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "expenseSummaryId": "5229a14b-443b-4551-9d01-4bc0dc820d05",
4 | "totalExpenses": 40749250.15,
5 | "date": "2022-08-23T23:59:13Z"
6 | },
7 | {
8 | "expenseSummaryId": "c17ff164-1ab4-41e7-91a8-8aab790dcd88",
9 | "totalExpenses": 82516685.25,
10 | "date": "2021-12-28T17:03:47Z"
11 | },
12 | {
13 | "expenseSummaryId": "45ecf33b-6c3b-4e55-84ec-fa30b88aa03f",
14 | "totalExpenses": 41860250.4,
15 | "date": "2021-09-18T23:26:30Z"
16 | },
17 | {
18 | "expenseSummaryId": "e495b850-cf2b-4b76-93c2-d4241c859cd0",
19 | "totalExpenses": 49456718.68,
20 | "date": "2022-01-08T04:26:56Z"
21 | },
22 | {
23 | "expenseSummaryId": "376f8d90-8b66-4cff-bd4e-2fcd14a42845",
24 | "totalExpenses": 35573786.54,
25 | "date": "2020-08-31T11:45:23Z"
26 | },
27 | {
28 | "expenseSummaryId": "744bb795-0f98-45cd-99ae-45dddb99c3e4",
29 | "totalExpenses": 43767088.74,
30 | "date": "2020-04-15T06:57:51Z"
31 | },
32 | {
33 | "expenseSummaryId": "4a6a10e5-4f44-4aef-a1bd-c57075f3c44f",
34 | "totalExpenses": 75311886.34,
35 | "date": "2021-11-05T16:10:48Z"
36 | },
37 | {
38 | "expenseSummaryId": "d62a1123-18b3-4784-bbdd-70a29f773f99",
39 | "totalExpenses": 25031430.77,
40 | "date": "2020-11-18T23:52:46Z"
41 | },
42 | {
43 | "expenseSummaryId": "ace2b05e-31de-48bd-a179-e59d16757456",
44 | "totalExpenses": 95066201.16,
45 | "date": "2020-05-10T17:55:37Z"
46 | },
47 | {
48 | "expenseSummaryId": "f24f6dd9-dd18-42f9-a76a-95d8198b7636",
49 | "totalExpenses": 43519955.41,
50 | "date": "2022-02-18T23:26:53Z"
51 | },
52 | {
53 | "expenseSummaryId": "2a2a88f0-0148-4667-8bab-7d129586bdf7",
54 | "totalExpenses": 11975718.82,
55 | "date": "2022-01-10T03:25:06Z"
56 | },
57 | {
58 | "expenseSummaryId": "560c166c-7093-4583-a007-5af2a88f1dab",
59 | "totalExpenses": 51372909.22,
60 | "date": "2022-04-24T18:53:13Z"
61 | },
62 | {
63 | "expenseSummaryId": "6faadd8d-5cdd-4b35-a3e8-cb0ada67de3a",
64 | "totalExpenses": 74722976.97,
65 | "date": "2022-01-14T09:36:38Z"
66 | },
67 | {
68 | "expenseSummaryId": "be4755fd-0f7c-4292-a0ad-539ad1371f6e",
69 | "totalExpenses": 75641467.74,
70 | "date": "2021-12-21T15:01:09Z"
71 | },
72 | {
73 | "expenseSummaryId": "46a33080-d239-49b2-9f0a-5d2d576a3966",
74 | "totalExpenses": 25500681.97,
75 | "date": "2022-04-01T15:50:39Z"
76 | },
77 | {
78 | "expenseSummaryId": "40dd45c1-b575-48d1-b1a0-2bf474c8b591",
79 | "totalExpenses": 539510.64,
80 | "date": "2020-01-13T13:28:34Z"
81 | },
82 | {
83 | "expenseSummaryId": "4d452c32-21fd-4891-a5fe-aa481861e0ad",
84 | "totalExpenses": 39145989.15,
85 | "date": "2022-04-13T22:53:06Z"
86 | },
87 | {
88 | "expenseSummaryId": "acd41481-9384-4ff1-8004-a3df027a0209",
89 | "totalExpenses": 21149322.36,
90 | "date": "2022-03-11T04:03:13Z"
91 | },
92 | {
93 | "expenseSummaryId": "9b523e04-fdae-4b0b-a6d9-58ef64c75431",
94 | "totalExpenses": 11169032.82,
95 | "date": "2021-08-06T01:20:04Z"
96 | },
97 | {
98 | "expenseSummaryId": "4ada8077-3799-4690-ae35-c552e4100b1a",
99 | "totalExpenses": 82993070.31,
100 | "date": "2021-08-03T10:58:02Z"
101 | },
102 | {
103 | "expenseSummaryId": "f6041c02-7b2a-4de3-8aed-81b82528ffe4",
104 | "totalExpenses": 66908936.55,
105 | "date": "2020-08-05T18:45:02Z"
106 | },
107 | {
108 | "expenseSummaryId": "d68b89d4-3332-4e29-8e5a-3c0483af6688",
109 | "totalExpenses": 33514872.87,
110 | "date": "2021-07-01T15:13:37Z"
111 | },
112 | {
113 | "expenseSummaryId": "9ef8296f-f2b3-4733-8664-7ef5e388734b",
114 | "totalExpenses": 63157720.91,
115 | "date": "2020-04-20T11:27:14Z"
116 | },
117 | {
118 | "expenseSummaryId": "c9a46c10-c426-4cbe-b805-83ab5d963e19",
119 | "totalExpenses": 58355575.44,
120 | "date": "2022-02-17T22:27:44Z"
121 | },
122 | {
123 | "expenseSummaryId": "8f70eaa2-fb78-4b32-bf2f-67c1e4988d2f",
124 | "totalExpenses": 84500652.59,
125 | "date": "2021-01-14T21:41:26Z"
126 | },
127 | {
128 | "expenseSummaryId": "f222583a-d003-44e1-920d-0f9743a873dc",
129 | "totalExpenses": 83208591.41,
130 | "date": "2021-05-23T02:25:54Z"
131 | },
132 | {
133 | "expenseSummaryId": "0675c624-1e11-4df8-821f-9a2d744dba09",
134 | "totalExpenses": 33465485.39,
135 | "date": "2022-10-29T12:01:44Z"
136 | },
137 | {
138 | "expenseSummaryId": "abe1d0e1-65bf-49dc-801d-ba669aae8e33",
139 | "totalExpenses": 27097402.85,
140 | "date": "2021-01-02T11:54:11Z"
141 | },
142 | {
143 | "expenseSummaryId": "6aef1c35-a1c4-4a58-9be0-b6488a622eaa",
144 | "totalExpenses": 60148771.5,
145 | "date": "2021-11-24T13:21:00Z"
146 | },
147 | {
148 | "expenseSummaryId": "43b606a2-45c6-4da4-85aa-f219aa6a2960",
149 | "totalExpenses": 39634053.67,
150 | "date": "2021-01-30T15:52:39Z"
151 | },
152 | {
153 | "expenseSummaryId": "db5b8de2-7dc0-4efe-a937-34e537a3f8ec",
154 | "totalExpenses": 63931774.54,
155 | "date": "2021-10-05T02:05:46Z"
156 | },
157 | {
158 | "expenseSummaryId": "b0760c67-c326-4f6d-9511-cb2b6896a11f",
159 | "totalExpenses": 61688809.89,
160 | "date": "2022-07-02T22:34:16Z"
161 | },
162 | {
163 | "expenseSummaryId": "8404fc43-72be-4a3a-bf55-313256b0e083",
164 | "totalExpenses": 70074829.75,
165 | "date": "2022-09-20T00:25:06Z"
166 | },
167 | {
168 | "expenseSummaryId": "b149ef3b-f9cc-4560-ab29-4f74ec138c71",
169 | "totalExpenses": 80265893.3,
170 | "date": "2022-12-21T05:58:49Z"
171 | },
172 | {
173 | "expenseSummaryId": "7e793e60-2edc-4adf-9d6f-bb6d09c93481",
174 | "totalExpenses": 10938282.95,
175 | "date": "2021-11-01T20:28:10Z"
176 | },
177 | {
178 | "expenseSummaryId": "e56345be-2ac9-4ca7-a9a2-1c59846381f7",
179 | "totalExpenses": 33591951.95,
180 | "date": "2021-11-23T16:52:43Z"
181 | },
182 | {
183 | "expenseSummaryId": "cdfd8bfd-1851-4cd1-ab5f-e66e7260ba92",
184 | "totalExpenses": 845358.59,
185 | "date": "2022-11-22T12:43:41Z"
186 | },
187 | {
188 | "expenseSummaryId": "eb8f9ea8-2cdb-4461-80fc-9dd571afb200",
189 | "totalExpenses": 66690967.68,
190 | "date": "2022-02-13T23:10:27Z"
191 | },
192 | {
193 | "expenseSummaryId": "1fe8f10b-24d0-4906-a66c-96ff7783671b",
194 | "totalExpenses": 43874777.57,
195 | "date": "2022-08-14T20:45:25Z"
196 | },
197 | {
198 | "expenseSummaryId": "6cd41a74-4084-4e91-b009-5ab41730d258",
199 | "totalExpenses": 40265520.46,
200 | "date": "2022-07-16T21:42:02Z"
201 | },
202 | {
203 | "expenseSummaryId": "d953877c-72d8-4189-8078-6ed4e46a23a4",
204 | "totalExpenses": 50581576.01,
205 | "date": "2020-07-23T13:00:44Z"
206 | },
207 | {
208 | "expenseSummaryId": "e328c686-7e18-41b3-92e2-e2ddaf3a4a31",
209 | "totalExpenses": 68186405.58,
210 | "date": "2021-03-10T22:55:10Z"
211 | },
212 | {
213 | "expenseSummaryId": "becde53e-60b5-40d1-be9c-27763057f3ac",
214 | "totalExpenses": 71676578.77,
215 | "date": "2022-10-17T04:27:37Z"
216 | },
217 | {
218 | "expenseSummaryId": "803d384f-69a9-450d-8ed3-96d202dbafcd",
219 | "totalExpenses": 44651450.2,
220 | "date": "2020-08-08T19:52:19Z"
221 | },
222 | {
223 | "expenseSummaryId": "4749833f-3eaa-452f-bb28-209988f7918d",
224 | "totalExpenses": 98571536.55,
225 | "date": "2022-06-18T07:04:03Z"
226 | },
227 | {
228 | "expenseSummaryId": "852af507-0551-41c8-9d95-a90ed9b1a07c",
229 | "totalExpenses": 31396413.25,
230 | "date": "2021-09-18T17:44:00Z"
231 | },
232 | {
233 | "expenseSummaryId": "45718dc4-41ef-4a92-b270-3f7eb445fbef",
234 | "totalExpenses": 30345484.18,
235 | "date": "2021-01-18T21:57:02Z"
236 | },
237 | {
238 | "expenseSummaryId": "5763fb5e-a9b1-41a7-b873-0ecfad5c749c",
239 | "totalExpenses": 78841883.13,
240 | "date": "2021-01-10T19:15:27Z"
241 | },
242 | {
243 | "expenseSummaryId": "87122213-3ad3-418a-8914-5a35e01bb69b",
244 | "totalExpenses": 1718619.1,
245 | "date": "2021-09-26T12:13:08Z"
246 | },
247 | {
248 | "expenseSummaryId": "10ec2f80-6da0-4909-b8fd-7c5cfdb7bef4",
249 | "totalExpenses": 97167385.15,
250 | "date": "2020-03-04T02:21:16Z"
251 | }
252 | ]
253 |
--------------------------------------------------------------------------------
/server/prisma/seedData/salesSummary.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "salesSummaryId": "9234a776-e6ac-46e2-bc24-c959ce216751",
4 | "totalValue": 4754106.83,
5 | "changePercentage": 61.51,
6 | "date": "2023-03-18T22:32:25Z"
7 | },
8 | {
9 | "salesSummaryId": "e5648831-7d0e-4ef5-8e04-f6e6a0eaafb1",
10 | "totalValue": 1512948.97,
11 | "changePercentage": -2.28,
12 | "date": "2023-09-03T13:50:20Z"
13 | },
14 | {
15 | "salesSummaryId": "785d33be-a1d8-47a6-b1d3-779942196b5c",
16 | "totalValue": 5545737.54,
17 | "changePercentage": -55.29,
18 | "date": "2023-07-28T13:16:27Z"
19 | },
20 | {
21 | "salesSummaryId": "0541d262-46aa-4961-b7c0-ce09143ccf34",
22 | "totalValue": 3260113.92,
23 | "changePercentage": -71.7,
24 | "date": "2023-05-16T08:32:38Z"
25 | },
26 | {
27 | "salesSummaryId": "185bb7e9-a9c0-4691-87d3-ca597a29e4d8",
28 | "totalValue": 849737.25,
29 | "changePercentage": 9.16,
30 | "date": "2023-08-26T05:41:40Z"
31 | },
32 | {
33 | "salesSummaryId": "6a1cb0f7-a4e1-4157-800d-86a59fb5fc16",
34 | "totalValue": 98903.57,
35 | "changePercentage": 36.24,
36 | "date": "2023-09-02T01:49:46Z"
37 | },
38 | {
39 | "salesSummaryId": "7d6d3e60-4687-40e3-9a77-452ea298df02",
40 | "totalValue": 973557.25,
41 | "changePercentage": 34.22,
42 | "date": "2023-03-31T15:20:53Z"
43 | },
44 | {
45 | "salesSummaryId": "7e071f0f-cff2-4699-bc67-3bee1114cb9e",
46 | "totalValue": 9761085.56,
47 | "changePercentage": -57.32,
48 | "date": "2023-06-25T12:21:04Z"
49 | },
50 | {
51 | "salesSummaryId": "6688c13c-758a-44c9-a291-d630d13dfd33",
52 | "totalValue": 9819343.72,
53 | "changePercentage": -49.57,
54 | "date": "2023-06-21T17:57:01Z"
55 | },
56 | {
57 | "salesSummaryId": "bce35149-3c37-4a0d-8963-c9f550b262f3",
58 | "totalValue": 2757578.95,
59 | "changePercentage": 73.95,
60 | "date": "2023-05-13T15:02:46Z"
61 | },
62 | {
63 | "salesSummaryId": "4d86c2df-d759-49df-9ecd-1eaf27a3d590",
64 | "totalValue": 8894817.67,
65 | "changePercentage": -25.81,
66 | "date": "2023-03-31T16:04:25Z"
67 | },
68 | {
69 | "salesSummaryId": "c85efa84-d294-4c2e-a9a5-8774d92af8bf",
70 | "totalValue": 2882180.14,
71 | "changePercentage": 57.29,
72 | "date": "2024-03-13T01:19:11Z"
73 | },
74 | {
75 | "salesSummaryId": "9257a2eb-d1ba-4cde-a0c2-cdf766c8c79c",
76 | "totalValue": 543716.99,
77 | "changePercentage": 8.85,
78 | "date": "2024-02-04T05:14:46Z"
79 | },
80 | {
81 | "salesSummaryId": "2f94d909-0f3a-45fb-8072-5054b6dba2d6",
82 | "totalValue": 1171786.52,
83 | "changePercentage": 79.4,
84 | "date": "2023-04-20T00:12:05Z"
85 | },
86 | {
87 | "salesSummaryId": "9bc6eca5-9f18-4e72-bed0-7a98bb759af3",
88 | "totalValue": 9574424.72,
89 | "changePercentage": 10.42,
90 | "date": "2023-04-04T22:57:17Z"
91 | },
92 | {
93 | "salesSummaryId": "a0979a0f-bbe2-4bd8-9639-e6c1d890c6e1",
94 | "totalValue": 1717855.75,
95 | "changePercentage": -76.77,
96 | "date": "2023-07-24T23:01:04Z"
97 | },
98 | {
99 | "salesSummaryId": "d2ff270c-63d9-4510-9524-91cb95494a9d",
100 | "totalValue": 1328587.6,
101 | "changePercentage": 62.35,
102 | "date": "2023-12-30T03:52:12Z"
103 | },
104 | {
105 | "salesSummaryId": "56693648-d829-4d6a-8ff1-379ed00187c0",
106 | "totalValue": 3363438.49,
107 | "changePercentage": -3.73,
108 | "date": "2023-06-16T12:55:40Z"
109 | },
110 | {
111 | "salesSummaryId": "22c58913-c4ad-44ac-bcf0-6309b6c61f26",
112 | "totalValue": 6253195.27,
113 | "changePercentage": -33.39,
114 | "date": "2023-05-12T13:22:28Z"
115 | },
116 | {
117 | "salesSummaryId": "e14f2cdc-28c8-4041-a5c3-444e32f4df96",
118 | "totalValue": 759235.03,
119 | "changePercentage": -70.16,
120 | "date": "2023-05-04T03:54:06Z"
121 | },
122 | {
123 | "salesSummaryId": "abb07538-994f-40df-9850-b93d758566d6",
124 | "totalValue": 8849902.08,
125 | "changePercentage": 49.99,
126 | "date": "2023-10-23T10:52:58Z"
127 | },
128 | {
129 | "salesSummaryId": "3c1be92e-86a4-4ba9-9cc4-0cd25cdd9b53",
130 | "totalValue": 6985354.53,
131 | "changePercentage": -45.28,
132 | "date": "2023-06-12T08:59:54Z"
133 | },
134 | {
135 | "salesSummaryId": "b6438519-cd43-49e4-a6ea-c1e97b6b9f4f",
136 | "totalValue": 1977818.88,
137 | "changePercentage": -1.73,
138 | "date": "2023-07-30T18:47:25Z"
139 | },
140 | {
141 | "salesSummaryId": "47d22ba7-a75b-4570-a0ee-5936af301dc0",
142 | "totalValue": 3051711.61,
143 | "changePercentage": 46.06,
144 | "date": "2023-06-21T19:26:53Z"
145 | },
146 | {
147 | "salesSummaryId": "75bf9bb7-67bf-4674-8d57-ef96c387bd5f",
148 | "totalValue": 1776483.92,
149 | "changePercentage": 5.92,
150 | "date": "2024-01-04T23:05:09Z"
151 | },
152 | {
153 | "salesSummaryId": "aa076cf0-2af4-42d1-a65a-e21048900cdc",
154 | "totalValue": 8008789.18,
155 | "changePercentage": -92.62,
156 | "date": "2023-07-11T05:46:12Z"
157 | },
158 | {
159 | "salesSummaryId": "0eabb55c-311b-4794-8621-684b8e3c6af3",
160 | "totalValue": 9939857.2,
161 | "changePercentage": 43.61,
162 | "date": "2023-11-03T17:55:50Z"
163 | },
164 | {
165 | "salesSummaryId": "02421d34-eab8-4c74-be90-29ae960217e0",
166 | "totalValue": 7378147.37,
167 | "changePercentage": -8.68,
168 | "date": "2023-06-02T21:55:25Z"
169 | },
170 | {
171 | "salesSummaryId": "dab41155-3b2c-4260-9b92-0fb36239e76a",
172 | "totalValue": 5903962.21,
173 | "changePercentage": 54.41,
174 | "date": "2023-04-15T12:08:49Z"
175 | },
176 | {
177 | "salesSummaryId": "777946fe-c45b-48c4-8009-dd34727a2d6e",
178 | "totalValue": 3995392.55,
179 | "changePercentage": -39.88,
180 | "date": "2023-06-04T10:27:19Z"
181 | },
182 | {
183 | "salesSummaryId": "0218422f-dff4-4b96-a485-ec81dfb52b1d",
184 | "totalValue": 2236665.35,
185 | "changePercentage": 62.25,
186 | "date": "2023-04-26T18:00:10Z"
187 | },
188 | {
189 | "salesSummaryId": "2cdc1dff-3f48-4223-b75d-6d40d5ebd70f",
190 | "totalValue": 4924895.6,
191 | "changePercentage": 91.7,
192 | "date": "2023-10-03T09:22:11Z"
193 | },
194 | {
195 | "salesSummaryId": "2876f4ae-7146-4144-a424-1050d3889af9",
196 | "totalValue": 8020749.83,
197 | "changePercentage": -53.71,
198 | "date": "2023-09-09T18:08:04Z"
199 | },
200 | {
201 | "salesSummaryId": "72d4764c-6438-43e8-9f5e-1e1392c49daa",
202 | "totalValue": 1401814.98,
203 | "changePercentage": -62.89,
204 | "date": "2024-01-23T21:18:15Z"
205 | },
206 | {
207 | "salesSummaryId": "0eb49bc9-7bb1-4593-b63c-623604b4d39e",
208 | "totalValue": 7075340.95,
209 | "changePercentage": 51.63,
210 | "date": "2023-04-12T18:35:19Z"
211 | },
212 | {
213 | "salesSummaryId": "a03badbe-ed85-4f67-8563-e70957d711f5",
214 | "totalValue": 6635158.49,
215 | "changePercentage": 1.55,
216 | "date": "2024-01-08T18:20:24Z"
217 | },
218 | {
219 | "salesSummaryId": "ef37f796-5792-48b5-947b-0861d1bcf1d2",
220 | "totalValue": 5438733.13,
221 | "changePercentage": 64.23,
222 | "date": "2023-06-04T03:34:31Z"
223 | },
224 | {
225 | "salesSummaryId": "38f4698c-f973-4118-a38f-0c772dc55993",
226 | "totalValue": 8733498.2,
227 | "changePercentage": -9.14,
228 | "date": "2023-06-18T12:45:24Z"
229 | },
230 | {
231 | "salesSummaryId": "bb7b3f86-95f6-414a-95c5-d6ad13a50e3b",
232 | "totalValue": 8834598.88,
233 | "changePercentage": -74.91,
234 | "date": "2023-09-18T22:57:29Z"
235 | },
236 | {
237 | "salesSummaryId": "6f673a1d-78e9-4ea8-91e2-d7a32836cd3a",
238 | "totalValue": 1518126.03,
239 | "changePercentage": 22.59,
240 | "date": "2024-02-17T06:29:57Z"
241 | },
242 | {
243 | "salesSummaryId": "ac08ecc4-f5e2-4f65-8f7d-3e9e02771657",
244 | "totalValue": 8916033.73,
245 | "changePercentage": -70.49,
246 | "date": "2023-11-23T06:52:42Z"
247 | },
248 | {
249 | "salesSummaryId": "3245bcab-7939-43ef-8f75-66bb2e092637",
250 | "totalValue": 8457395.47,
251 | "changePercentage": 58.85,
252 | "date": "2023-06-14T06:58:44Z"
253 | },
254 | {
255 | "salesSummaryId": "211ab48b-03e9-4e87-aff8-24723760c650",
256 | "totalValue": 2131348.79,
257 | "changePercentage": -46.72,
258 | "date": "2023-04-07T03:15:00Z"
259 | },
260 | {
261 | "salesSummaryId": "6bff1b90-9e27-493b-aead-d70b388c5058",
262 | "totalValue": 4439655.91,
263 | "changePercentage": -10.54,
264 | "date": "2023-08-08T00:53:14Z"
265 | },
266 | {
267 | "salesSummaryId": "b2cd84fc-8f66-477a-ad53-eb7826b89eae",
268 | "totalValue": 2253721.94,
269 | "changePercentage": -26.4,
270 | "date": "2023-12-04T03:33:12Z"
271 | },
272 | {
273 | "salesSummaryId": "db47a861-5062-49c5-92c1-0a8f13ec70b0",
274 | "totalValue": 3844322.3,
275 | "changePercentage": -23.92,
276 | "date": "2023-07-18T05:39:04Z"
277 | },
278 | {
279 | "salesSummaryId": "47ab518f-ec0e-4793-8d3b-53780452e472",
280 | "totalValue": 3145456.83,
281 | "changePercentage": -80.96,
282 | "date": "2023-05-18T14:04:36Z"
283 | },
284 | {
285 | "salesSummaryId": "2f255c3a-d024-4a49-9e3e-3ff4e529c362",
286 | "totalValue": 5041224.3,
287 | "changePercentage": 50.26,
288 | "date": "2023-08-15T23:43:31Z"
289 | },
290 | {
291 | "salesSummaryId": "1344c490-9f30-4a09-8379-e26dc551599e",
292 | "totalValue": 8409410.21,
293 | "changePercentage": 27.52,
294 | "date": "2024-01-01T14:21:37Z"
295 | },
296 | {
297 | "salesSummaryId": "f9e8bb8b-b267-49d9-b621-7f912b348e81",
298 | "totalValue": 4049054.53,
299 | "changePercentage": -9.75,
300 | "date": "2023-04-08T22:11:59Z"
301 | }
302 | ]
303 |
--------------------------------------------------------------------------------
/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
26 |
27 | /* Modules */
28 | "module": "nodenext" /* Specify what module code is generated. */,
29 | // "rootDir": "./", /* Specify the root folder within your source files. */
30 | "moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */,
31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
42 | "resolveJsonModule": true /* Enable importing .json files. */,
43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
45 |
46 | /* JavaScript Support */
47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
50 |
51 | /* Emit */
52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
58 | "outDir": "./dist" /* Specify an output folder for all emitted files. */,
59 | // "removeComments": true, /* Disable emitting comments. */
60 | // "noEmit": true, /* Disable emitting files from a compilation. */
61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
62 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
63 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
64 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
65 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
66 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
67 | // "newLine": "crlf", /* Set the newline character for emitting files. */
68 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
69 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
70 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
71 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
72 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
73 |
74 | /* Interop Constraints */
75 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
76 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
77 | // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
78 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
79 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
80 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
81 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
82 |
83 | /* Type Checking */
84 | "strict": true /* Enable all strict type-checking options. */,
85 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
86 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
87 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
88 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
89 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
90 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
91 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
92 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
93 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
94 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
95 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
96 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
97 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
98 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
99 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
100 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
101 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
102 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
103 |
104 | /* Completeness */
105 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
106 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/server/prisma/seedData/expenseByCategory.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "expenseByCategoryId": "0e980d1b-ae93-4a5a-b235-4dfea5f42860",
4 | "expenseSummaryId": "5229a14b-443b-4551-9d01-4bc0dc820d05",
5 | "date": "2023-11-23T11:54:21Z",
6 | "category": "Office",
7 | "amount": 48
8 | },
9 | {
10 | "expenseByCategoryId": "076a4956-60c2-4b73-b275-530359a91cba",
11 | "expenseSummaryId": "c17ff164-1ab4-41e7-91a8-8aab790dcd88",
12 | "date": "2023-08-13T09:49:33Z",
13 | "category": "Salaries",
14 | "amount": 66
15 | },
16 | {
17 | "expenseByCategoryId": "27d49b13-1a3a-4fc7-924c-07147e4d08bd",
18 | "expenseSummaryId": "45ecf33b-6c3b-4e55-84ec-fa30b88aa03f",
19 | "date": "2023-07-24T09:26:56Z",
20 | "category": "Salaries",
21 | "amount": 63
22 | },
23 | {
24 | "expenseByCategoryId": "037fce5f-2c74-4f7a-a863-8cdd4db8a56b",
25 | "expenseSummaryId": "e495b850-cf2b-4b76-93c2-d4241c859cd0",
26 | "date": "2023-05-24T05:24:15Z",
27 | "category": "Salaries",
28 | "amount": 77
29 | },
30 | {
31 | "expenseByCategoryId": "abdb6c33-81ff-45dd-a653-ceae0783729d",
32 | "expenseSummaryId": "376f8d90-8b66-4cff-bd4e-2fcd14a42845",
33 | "date": "2023-05-07T12:33:09Z",
34 | "category": "Office",
35 | "amount": 67
36 | },
37 | {
38 | "expenseByCategoryId": "246326ac-b8b2-44ee-9f14-f54086aa6a00",
39 | "expenseSummaryId": "744bb795-0f98-45cd-99ae-45dddb99c3e4",
40 | "date": "2024-01-08T22:08:30Z",
41 | "category": "Salaries",
42 | "amount": 12
43 | },
44 | {
45 | "expenseByCategoryId": "760beed5-a14b-4e4b-9951-3ebe6f5842a1",
46 | "expenseSummaryId": "4a6a10e5-4f44-4aef-a1bd-c57075f3c44f",
47 | "date": "2023-06-11T08:03:25Z",
48 | "category": "Office",
49 | "amount": 57
50 | },
51 | {
52 | "expenseByCategoryId": "6c653ab9-2b4b-49be-b891-944f5ff98b85",
53 | "expenseSummaryId": "d62a1123-18b3-4784-bbdd-70a29f773f99",
54 | "date": "2023-07-10T00:15:57Z",
55 | "category": "Office",
56 | "amount": 34
57 | },
58 | {
59 | "expenseByCategoryId": "0636f954-6ef8-40b4-819f-fbfe4511be56",
60 | "expenseSummaryId": "ace2b05e-31de-48bd-a179-e59d16757456",
61 | "date": "2023-12-16T19:29:15Z",
62 | "category": "Salaries",
63 | "amount": 43
64 | },
65 | {
66 | "expenseByCategoryId": "86f616b9-3d68-4a04-b8e8-966a11ce1a78",
67 | "expenseSummaryId": "f24f6dd9-dd18-42f9-a76a-95d8198b7636",
68 | "date": "2023-07-04T04:49:15Z",
69 | "category": "Salaries",
70 | "amount": 62
71 | },
72 | {
73 | "expenseByCategoryId": "0381f4e7-08dc-4e10-8d8d-be02a3d1c16b",
74 | "expenseSummaryId": "2a2a88f0-0148-4667-8bab-7d129586bdf7",
75 | "date": "2023-10-18T18:41:07Z",
76 | "category": "Professional",
77 | "amount": 28
78 | },
79 | {
80 | "expenseByCategoryId": "55628026-8104-4d95-91f8-8062df421036",
81 | "expenseSummaryId": "560c166c-7093-4583-a007-5af2a88f1dab",
82 | "date": "2024-01-01T03:49:45Z",
83 | "category": "Office",
84 | "amount": 65
85 | },
86 | {
87 | "expenseByCategoryId": "44e1e4bc-462a-4b41-a1d2-a9997fa38ff8",
88 | "expenseSummaryId": "6faadd8d-5cdd-4b35-a3e8-cb0ada67de3a",
89 | "date": "2023-12-23T19:25:39Z",
90 | "category": "Salaries",
91 | "amount": 54
92 | },
93 | {
94 | "expenseByCategoryId": "ab27a324-088c-4bdc-8ce4-c67a6fbff088",
95 | "expenseSummaryId": "be4755fd-0f7c-4292-a0ad-539ad1371f6e",
96 | "date": "2023-03-15T12:50:41Z",
97 | "category": "Salaries",
98 | "amount": 97
99 | },
100 | {
101 | "expenseByCategoryId": "2e335aef-bb2e-401d-bda9-2c123e3031ad",
102 | "expenseSummaryId": "46a33080-d239-49b2-9f0a-5d2d576a3966",
103 | "date": "2023-04-23T21:27:57Z",
104 | "category": "Professional",
105 | "amount": 94
106 | },
107 | {
108 | "expenseByCategoryId": "5cdabf88-3c50-4519-bcc3-f9eb2abcfdc9",
109 | "expenseSummaryId": "40dd45c1-b575-48d1-b1a0-2bf474c8b591",
110 | "date": "2023-05-11T09:55:13Z",
111 | "category": "Salaries",
112 | "amount": 24
113 | },
114 | {
115 | "expenseByCategoryId": "bf128fb0-7c2f-45af-916e-4210d0b2c737",
116 | "expenseSummaryId": "4d452c32-21fd-4891-a5fe-aa481861e0ad",
117 | "date": "2023-06-16T16:48:42Z",
118 | "category": "Office",
119 | "amount": 59
120 | },
121 | {
122 | "expenseByCategoryId": "70157f83-2d78-43b0-85c0-9c955abdbbcd",
123 | "expenseSummaryId": "acd41481-9384-4ff1-8004-a3df027a0209",
124 | "date": "2023-09-30T05:02:44Z",
125 | "category": "Office",
126 | "amount": 54
127 | },
128 | {
129 | "expenseByCategoryId": "2f0fc0ff-11d6-4fa2-b930-84c1503fc4b6",
130 | "expenseSummaryId": "9b523e04-fdae-4b0b-a6d9-58ef64c75431",
131 | "date": "2023-07-03T22:12:16Z",
132 | "category": "Office",
133 | "amount": 25
134 | },
135 | {
136 | "expenseByCategoryId": "ce4b9e25-25fa-49ed-8711-0ec432e913e3",
137 | "expenseSummaryId": "4ada8077-3799-4690-ae35-c552e4100b1a",
138 | "date": "2023-08-23T11:48:59Z",
139 | "category": "Professional",
140 | "amount": 54
141 | },
142 | {
143 | "expenseByCategoryId": "4bc92339-cf13-4da5-bfc5-d201b4bce01f",
144 | "expenseSummaryId": "f6041c02-7b2a-4de3-8aed-81b82528ffe4",
145 | "date": "2023-09-14T06:41:32Z",
146 | "category": "Professional",
147 | "amount": 37
148 | },
149 | {
150 | "expenseByCategoryId": "0cf47f96-e01f-443e-a864-9dd94aa0916b",
151 | "expenseSummaryId": "d68b89d4-3332-4e29-8e5a-3c0483af6688",
152 | "date": "2023-06-11T13:00:11Z",
153 | "category": "Office",
154 | "amount": 96
155 | },
156 | {
157 | "expenseByCategoryId": "1629525c-9e25-4252-a55a-708eae10d62c",
158 | "expenseSummaryId": "9ef8296f-f2b3-4733-8664-7ef5e388734b",
159 | "date": "2024-01-03T17:10:35Z",
160 | "category": "Office",
161 | "amount": 85
162 | },
163 | {
164 | "expenseByCategoryId": "33579bc1-739f-4489-9a5c-1fdea6e1dec2",
165 | "expenseSummaryId": "c9a46c10-c426-4cbe-b805-83ab5d963e19",
166 | "date": "2023-08-20T13:33:02Z",
167 | "category": "Salaries",
168 | "amount": 55
169 | },
170 | {
171 | "expenseByCategoryId": "baf43dac-2563-4847-b756-a6c02cc17500",
172 | "expenseSummaryId": "8f70eaa2-fb78-4b32-bf2f-67c1e4988d2f",
173 | "date": "2023-12-23T06:16:20Z",
174 | "category": "Salaries",
175 | "amount": 7
176 | },
177 | {
178 | "expenseByCategoryId": "c3784dc2-03aa-48c0-aaa7-54ab2d3fb049",
179 | "expenseSummaryId": "f222583a-d003-44e1-920d-0f9743a873dc",
180 | "date": "2023-09-20T10:01:41Z",
181 | "category": "Professional",
182 | "amount": 90
183 | },
184 | {
185 | "expenseByCategoryId": "6e0372f9-0dba-4152-91f0-1c14f977b7a0",
186 | "expenseSummaryId": "0675c624-1e11-4df8-821f-9a2d744dba09",
187 | "date": "2023-09-02T16:42:29Z",
188 | "category": "Office",
189 | "amount": 99
190 | },
191 | {
192 | "expenseByCategoryId": "c011c90e-ccfb-4dd8-b4b3-1daf483d9cba",
193 | "expenseSummaryId": "abe1d0e1-65bf-49dc-801d-ba669aae8e33",
194 | "date": "2023-07-05T08:02:52Z",
195 | "category": "Salaries",
196 | "amount": 52
197 | },
198 | {
199 | "expenseByCategoryId": "2956f7b0-0526-4175-a596-7a8c22c4a6e1",
200 | "expenseSummaryId": "6aef1c35-a1c4-4a58-9be0-b6488a622eaa",
201 | "date": "2023-12-01T05:58:17Z",
202 | "category": "Professional",
203 | "amount": 71
204 | },
205 | {
206 | "expenseByCategoryId": "2fc8c8c4-e1b3-4bc3-86af-ec2d83ed8511",
207 | "expenseSummaryId": "43b606a2-45c6-4da4-85aa-f219aa6a2960",
208 | "date": "2023-08-29T13:03:56Z",
209 | "category": "Salaries",
210 | "amount": 4
211 | },
212 | {
213 | "expenseByCategoryId": "a4d61feb-528b-4314-8648-eb7c34c2303c",
214 | "expenseSummaryId": "db5b8de2-7dc0-4efe-a937-34e537a3f8ec",
215 | "date": "2023-09-24T19:24:50Z",
216 | "category": "Salaries",
217 | "amount": 7
218 | },
219 | {
220 | "expenseByCategoryId": "b2a808b4-bba5-4091-a6b4-ce0f7b917807",
221 | "expenseSummaryId": "b0760c67-c326-4f6d-9511-cb2b6896a11f",
222 | "date": "2023-03-29T09:33:35Z",
223 | "category": "Office",
224 | "amount": 48
225 | },
226 | {
227 | "expenseByCategoryId": "fcb238ba-dabc-4d93-9c34-aee8e305f866",
228 | "expenseSummaryId": "8404fc43-72be-4a3a-bf55-313256b0e083",
229 | "date": "2024-01-08T08:48:51Z",
230 | "category": "Professional",
231 | "amount": 15
232 | },
233 | {
234 | "expenseByCategoryId": "4cfa1c7f-b18a-41d9-9e79-55854f1269bf",
235 | "expenseSummaryId": "b149ef3b-f9cc-4560-ab29-4f74ec138c71",
236 | "date": "2024-03-08T11:57:57Z",
237 | "category": "Professional",
238 | "amount": 94
239 | },
240 | {
241 | "expenseByCategoryId": "a9f613be-6d9b-4ff0-8f26-37b71ed47274",
242 | "expenseSummaryId": "7e793e60-2edc-4adf-9d6f-bb6d09c93481",
243 | "date": "2024-02-15T10:50:32Z",
244 | "category": "Office",
245 | "amount": 94
246 | },
247 | {
248 | "expenseByCategoryId": "198e6bd4-9586-47fd-903d-aac56f99b61d",
249 | "expenseSummaryId": "e56345be-2ac9-4ca7-a9a2-1c59846381f7",
250 | "date": "2023-08-13T13:25:33Z",
251 | "category": "Salaries",
252 | "amount": 10
253 | },
254 | {
255 | "expenseByCategoryId": "9a86fea1-8b89-4f2f-829f-4406e530934d",
256 | "expenseSummaryId": "cdfd8bfd-1851-4cd1-ab5f-e66e7260ba92",
257 | "date": "2024-03-11T08:04:25Z",
258 | "category": "Office",
259 | "amount": 18
260 | },
261 | {
262 | "expenseByCategoryId": "3ad489e8-ce80-4ace-b5e8-732d226affd2",
263 | "expenseSummaryId": "eb8f9ea8-2cdb-4461-80fc-9dd571afb200",
264 | "date": "2023-08-26T01:40:17Z",
265 | "category": "Salaries",
266 | "amount": 82
267 | },
268 | {
269 | "expenseByCategoryId": "c8122a8a-498f-4504-97ed-e6361169099f",
270 | "expenseSummaryId": "1fe8f10b-24d0-4906-a66c-96ff7783671b",
271 | "date": "2024-02-03T20:08:28Z",
272 | "category": "Salaries",
273 | "amount": 95
274 | },
275 | {
276 | "expenseByCategoryId": "fc7e618a-c26c-42e3-8e38-e87469127c7e",
277 | "expenseSummaryId": "6cd41a74-4084-4e91-b009-5ab41730d258",
278 | "date": "2023-10-07T22:01:48Z",
279 | "category": "Office",
280 | "amount": 91
281 | },
282 | {
283 | "expenseByCategoryId": "a81be162-da70-43f0-a5d5-279f63bb1183",
284 | "expenseSummaryId": "d953877c-72d8-4189-8078-6ed4e46a23a4",
285 | "date": "2024-01-27T17:00:00Z",
286 | "category": "Salaries",
287 | "amount": 77
288 | },
289 | {
290 | "expenseByCategoryId": "dac98685-6d90-41ed-80ba-dded515cc3f0",
291 | "expenseSummaryId": "e328c686-7e18-41b3-92e2-e2ddaf3a4a31",
292 | "date": "2023-07-03T02:00:59Z",
293 | "category": "Professional",
294 | "amount": 62
295 | },
296 | {
297 | "expenseByCategoryId": "1241f3cf-99d8-4b84-b734-d60c3b53caad",
298 | "expenseSummaryId": "becde53e-60b5-40d1-be9c-27763057f3ac",
299 | "date": "2023-12-20T22:03:05Z",
300 | "category": "Salaries",
301 | "amount": 34
302 | },
303 | {
304 | "expenseByCategoryId": "c8f652dd-e8a6-4eb5-bc17-993d58ea1e10",
305 | "expenseSummaryId": "803d384f-69a9-450d-8ed3-96d202dbafcd",
306 | "date": "2023-08-05T04:51:45Z",
307 | "category": "Salaries",
308 | "amount": 87
309 | },
310 | {
311 | "expenseByCategoryId": "381c5e38-daae-473d-b32a-b1414106771a",
312 | "expenseSummaryId": "4749833f-3eaa-452f-bb28-209988f7918d",
313 | "date": "2024-01-15T07:35:22Z",
314 | "category": "Salaries",
315 | "amount": 12
316 | },
317 | {
318 | "expenseByCategoryId": "96e7aac8-5c4e-4a14-9106-a31913e601d0",
319 | "expenseSummaryId": "852af507-0551-41c8-9d95-a90ed9b1a07c",
320 | "date": "2023-03-15T14:01:06Z",
321 | "category": "Salaries",
322 | "amount": 88
323 | },
324 | {
325 | "expenseByCategoryId": "98ef7cce-68d9-4dee-bca0-804955502b83",
326 | "expenseSummaryId": "45718dc4-41ef-4a92-b270-3f7eb445fbef",
327 | "date": "2024-01-30T18:16:56Z",
328 | "category": "Salaries",
329 | "amount": 100
330 | },
331 | {
332 | "expenseByCategoryId": "a8fbd7bf-b3f0-4f75-8b5d-6f0a078bef37",
333 | "expenseSummaryId": "5763fb5e-a9b1-41a7-b873-0ecfad5c749c",
334 | "date": "2023-12-20T11:34:30Z",
335 | "category": "Office",
336 | "amount": 98
337 | },
338 | {
339 | "expenseByCategoryId": "5a34add7-30f1-4878-a0cc-e45556f5bfe9",
340 | "expenseSummaryId": "87122213-3ad3-418a-8914-5a35e01bb69b",
341 | "date": "2023-08-18T16:03:36Z",
342 | "category": "Professional",
343 | "amount": 78
344 | },
345 | {
346 | "expenseByCategoryId": "1dac299c-9b5a-4fb4-8ab5-fcdf6f9f0298",
347 | "expenseSummaryId": "10ec2f80-6da0-4909-b8fd-7c5cfdb7bef4",
348 | "date": "2023-08-06T08:45:27Z",
349 | "category": "Office",
350 | "amount": 12
351 | }
352 | ]
353 |
--------------------------------------------------------------------------------
/server/prisma/seedData/sales.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "saleId": "df8a03fa-c69c-4ffe-9e28-5febfb7a5ca9",
4 | "productId": "d35623ee-bef6-42b2-8776-2f99f8bb4782",
5 | "timestamp": "2023-11-02T04:03:00Z",
6 | "quantity": 229,
7 | "unitPrice": 221.1,
8 | "totalAmount": 8012.55
9 | },
10 | {
11 | "saleId": "8d008094-bbb7-4b6f-a38c-0e2a9905322d",
12 | "productId": "8ac1ac77-7358-425e-be16-0bdde9f02e59",
13 | "timestamp": "2023-08-17T19:53:36Z",
14 | "quantity": 241,
15 | "unitPrice": 414.68,
16 | "totalAmount": 5661.25
17 | },
18 | {
19 | "saleId": "4fca2797-3e88-40c5-88d3-fd4df8744958",
20 | "productId": "1afc136b-4d9f-4e8e-aace-8e1df908a404",
21 | "timestamp": "2023-11-21T15:03:18Z",
22 | "quantity": 699,
23 | "unitPrice": 550.22,
24 | "totalAmount": 4708.54
25 | },
26 | {
27 | "saleId": "ae6a3d09-fdf8-407b-9e55-07a347c87efa",
28 | "productId": "af84cc12-4fea-4f58-aece-f2ce92ca9580",
29 | "timestamp": "2023-05-17T20:20:03Z",
30 | "quantity": 182,
31 | "unitPrice": 113.69,
32 | "totalAmount": 9419.4
33 | },
34 | {
35 | "saleId": "f4dced2f-4446-450b-9778-fd32fe4dc583",
36 | "productId": "86e3bb1c-2f5d-4774-98f3-4df7cddd0a0f",
37 | "timestamp": "2023-06-14T15:17:34Z",
38 | "quantity": 863,
39 | "unitPrice": 214.01,
40 | "totalAmount": 8942.2
41 | },
42 | {
43 | "saleId": "b9c0856c-d10f-47a1-bf05-2f2c400aff69",
44 | "productId": "26b017c6-06d8-443f-9b4a-d6b1cee6f4c0",
45 | "timestamp": "2023-10-27T18:59:51Z",
46 | "quantity": 985,
47 | "unitPrice": 506.74,
48 | "totalAmount": 1790.08
49 | },
50 | {
51 | "saleId": "4411942c-1d3e-42b1-89bd-a692c43185b4",
52 | "productId": "440c9e80-6bf8-4eb3-b2d2-f81936d67de3",
53 | "timestamp": "2023-06-17T19:16:31Z",
54 | "quantity": 607,
55 | "unitPrice": 100.77,
56 | "totalAmount": 3293.73
57 | },
58 | {
59 | "saleId": "85460f0a-83d5-45b5-8db0-42506e0c5739",
60 | "productId": "98255f4e-40a6-470f-89a5-0792729f8947",
61 | "timestamp": "2024-01-12T16:37:28Z",
62 | "quantity": 93,
63 | "unitPrice": 310.09,
64 | "totalAmount": 5531.81
65 | },
66 | {
67 | "saleId": "1d9c4316-ed1a-49c5-a9ed-71a9fc8aff1c",
68 | "productId": "2a339fb2-f9f3-43bc-a85a-b217a0a38f12",
69 | "timestamp": "2023-11-08T18:16:52Z",
70 | "quantity": 482,
71 | "unitPrice": 83.62,
72 | "totalAmount": 894.41
73 | },
74 | {
75 | "saleId": "94a6ad98-8efe-4aef-bf19-742a542cf790",
76 | "productId": "8a8391b2-b4ac-4847-b652-66ffd8d65875",
77 | "timestamp": "2023-12-21T22:49:11Z",
78 | "quantity": 285,
79 | "unitPrice": 76.09,
80 | "totalAmount": 3738.87
81 | },
82 | {
83 | "saleId": "cff83ef4-6b2c-4ad4-b550-929e0eb3fa93",
84 | "productId": "be2157fb-7454-405e-9511-bf7ba81b7726",
85 | "timestamp": "2023-11-21T15:03:43Z",
86 | "quantity": 219,
87 | "unitPrice": 606.43,
88 | "totalAmount": 8773.57
89 | },
90 | {
91 | "saleId": "bc6fbde5-325d-4918-b8d9-36d8a7be769f",
92 | "productId": "fdf1ba3d-fa06-4ce5-90ff-d081c5d37176",
93 | "timestamp": "2024-03-01T17:35:27Z",
94 | "quantity": 286,
95 | "unitPrice": 246.58,
96 | "totalAmount": 3328.18
97 | },
98 | {
99 | "saleId": "022fe7a7-3938-4f41-9f56-f9e0a797f00f",
100 | "productId": "afded6df-058f-477d-9878-e0e0b1d3dff3",
101 | "timestamp": "2023-06-27T12:09:45Z",
102 | "quantity": 107,
103 | "unitPrice": 891.26,
104 | "totalAmount": 3915.37
105 | },
106 | {
107 | "saleId": "e6fc26ef-50e8-4983-a7e0-f2cbf32d32ef",
108 | "productId": "daa29167-82a7-474b-9687-b8b903e7ec69",
109 | "timestamp": "2023-07-06T02:50:19Z",
110 | "quantity": 195,
111 | "unitPrice": 809.59,
112 | "totalAmount": 725.11
113 | },
114 | {
115 | "saleId": "5ab2a0f1-2248-4804-9bf0-219d8a30b076",
116 | "productId": "ccb83982-71f3-4497-bad8-7e64c6920dc6",
117 | "timestamp": "2023-03-18T01:14:42Z",
118 | "quantity": 339,
119 | "unitPrice": 662.74,
120 | "totalAmount": 3694.96
121 | },
122 | {
123 | "saleId": "a3659c0d-ccc6-4903-b035-6f13e7778253",
124 | "productId": "1936d406-e89e-40e4-bff7-1827532269d4",
125 | "timestamp": "2023-11-05T00:17:48Z",
126 | "quantity": 71,
127 | "unitPrice": 529.95,
128 | "totalAmount": 2535.36
129 | },
130 | {
131 | "saleId": "169eacd5-c2e3-4510-a102-12d4b8351401",
132 | "productId": "c849a535-5f8b-47e3-889c-015693a644ac",
133 | "timestamp": "2023-11-03T18:34:59Z",
134 | "quantity": 235,
135 | "unitPrice": 769.19,
136 | "totalAmount": 7007.95
137 | },
138 | {
139 | "saleId": "a2241026-9fbb-438d-8f74-186bfa7c3174",
140 | "productId": "0c3e80ee-59b3-4fc4-b760-8b07acc2d3ae",
141 | "timestamp": "2024-01-04T00:19:37Z",
142 | "quantity": 489,
143 | "unitPrice": 965.72,
144 | "totalAmount": 8759.91
145 | },
146 | {
147 | "saleId": "6e1ef31f-9990-43d3-a8ba-54f535d450e9",
148 | "productId": "d8f5bee3-f3eb-4071-a124-6b857e0fd798",
149 | "timestamp": "2023-07-29T03:12:53Z",
150 | "quantity": 967,
151 | "unitPrice": 486.31,
152 | "totalAmount": 3167.8
153 | },
154 | {
155 | "saleId": "ec369281-eefe-4a41-bcfc-f1f003ab8144",
156 | "productId": "8d15de86-0e4a-4414-9166-7a33610202d3",
157 | "timestamp": "2023-06-16T03:56:50Z",
158 | "quantity": 371,
159 | "unitPrice": 413.88,
160 | "totalAmount": 668.91
161 | },
162 | {
163 | "saleId": "7f455867-3226-43c8-9838-091356e52573",
164 | "productId": "ea8fd0b9-c2d9-4d43-9c23-44cb99d079bb",
165 | "timestamp": "2023-12-03T20:33:41Z",
166 | "quantity": 435,
167 | "unitPrice": 477.74,
168 | "totalAmount": 9592.66
169 | },
170 | {
171 | "saleId": "a3ee350e-5dee-4ce3-831f-710da0067756",
172 | "productId": "25d01c80-bca1-4a00-b1d0-0fbd39ff9e89",
173 | "timestamp": "2023-12-27T16:34:21Z",
174 | "quantity": 699,
175 | "unitPrice": 336.99,
176 | "totalAmount": 8316.35
177 | },
178 | {
179 | "saleId": "c535a63e-376a-404e-b81e-4b448a06ac0e",
180 | "productId": "1d6df6e3-b7ea-4507-9d66-87c6ee8ed5b9",
181 | "timestamp": "2024-03-14T02:16:17Z",
182 | "quantity": 540,
183 | "unitPrice": 656.63,
184 | "totalAmount": 9777.17
185 | },
186 | {
187 | "saleId": "b7d157e1-0931-4ebe-8ca3-571cee3b597c",
188 | "productId": "000a8c23-5bca-436c-a216-4e747a94c511",
189 | "timestamp": "2024-02-13T07:28:00Z",
190 | "quantity": 884,
191 | "unitPrice": 899.96,
192 | "totalAmount": 579.95
193 | },
194 | {
195 | "saleId": "04ec2c14-ee2f-4485-9946-b154ed2df29a",
196 | "productId": "c5b600dc-6bfb-492a-b335-c3cc8c707959",
197 | "timestamp": "2023-09-04T23:51:27Z",
198 | "quantity": 106,
199 | "unitPrice": 272.72,
200 | "totalAmount": 8699.14
201 | },
202 | {
203 | "saleId": "ca9f6794-b55e-4fb6-b76e-2e2e4d79d8f8",
204 | "productId": "9d5fafbc-312b-47e8-ada1-283918f0c3b5",
205 | "timestamp": "2023-06-27T17:57:01Z",
206 | "quantity": 543,
207 | "unitPrice": 15.84,
208 | "totalAmount": 304.87
209 | },
210 | {
211 | "saleId": "2fc702a0-8959-4794-9847-c99da26a83c2",
212 | "productId": "0114d5d4-ae48-46fa-b0ca-afe60eb88add",
213 | "timestamp": "2023-03-27T00:06:48Z",
214 | "quantity": 262,
215 | "unitPrice": 838.85,
216 | "totalAmount": 5265.29
217 | },
218 | {
219 | "saleId": "4d7f8590-2db0-4e05-9215-a5225eb99c1d",
220 | "productId": "e5b0da8c-148d-4680-b262-8609fb8a10da",
221 | "timestamp": "2023-09-25T03:45:29Z",
222 | "quantity": 485,
223 | "unitPrice": 268.43,
224 | "totalAmount": 5710.52
225 | },
226 | {
227 | "saleId": "b3fb5092-8991-4f6d-8b01-05cc2fe624e5",
228 | "productId": "2be5b024-2c96-4f29-912c-c6f36353f799",
229 | "timestamp": "2023-04-01T01:39:53Z",
230 | "quantity": 561,
231 | "unitPrice": 783.41,
232 | "totalAmount": 8189.57
233 | },
234 | {
235 | "saleId": "877c1b5b-d3d5-4f92-b640-f1d74e2207cd",
236 | "productId": "fcf2e432-62a3-4b6f-a34d-36e42a12272e",
237 | "timestamp": "2023-07-10T13:42:52Z",
238 | "quantity": 333,
239 | "unitPrice": 491.06,
240 | "totalAmount": 6152.84
241 | },
242 | {
243 | "saleId": "58de1711-bf0c-4a7e-9045-06e8dae2fb20",
244 | "productId": "fc4c81e5-f1ac-40f5-8c6f-da3fbad5599d",
245 | "timestamp": "2023-09-06T15:15:47Z",
246 | "quantity": 949,
247 | "unitPrice": 120.98,
248 | "totalAmount": 8873.08
249 | },
250 | {
251 | "saleId": "ee74af3c-ef81-45d2-a6e6-d883ff816992",
252 | "productId": "07238d8e-0037-4972-87ca-0df206ee3e42",
253 | "timestamp": "2024-03-05T13:54:29Z",
254 | "quantity": 2,
255 | "unitPrice": 234.17,
256 | "totalAmount": 7048.43
257 | },
258 | {
259 | "saleId": "9c7317c6-39fa-4ab6-adb0-cde1a11c2f47",
260 | "productId": "154b7860-23a2-4564-ad99-1745ab7122ef",
261 | "timestamp": "2023-03-22T06:46:16Z",
262 | "quantity": 292,
263 | "unitPrice": 707.73,
264 | "totalAmount": 2045.56
265 | },
266 | {
267 | "saleId": "5d5b341f-82c6-439a-8d59-44b38733cb7a",
268 | "productId": "8d4bf814-65d4-4df4-84cc-68911d925fdf",
269 | "timestamp": "2023-06-12T18:25:57Z",
270 | "quantity": 675,
271 | "unitPrice": 243.48,
272 | "totalAmount": 9259.03
273 | },
274 | {
275 | "saleId": "d47eb898-5413-4492-ac54-cebb2422ebcf",
276 | "productId": "a52bf1bd-3d35-4cd2-849a-354e3952e2d2",
277 | "timestamp": "2023-11-21T03:27:09Z",
278 | "quantity": 7,
279 | "unitPrice": 44.74,
280 | "totalAmount": 9210.79
281 | },
282 | {
283 | "saleId": "01ca19c0-c93a-464c-bc54-a14e9e80c55c",
284 | "productId": "d35623ee-bef6-42b2-8776-2f99f8bb4782",
285 | "timestamp": "2024-01-17T01:48:30Z",
286 | "quantity": 659,
287 | "unitPrice": 497.62,
288 | "totalAmount": 6661.77
289 | },
290 | {
291 | "saleId": "9c03ee38-1424-4d47-bf27-4ad1441e0391",
292 | "productId": "8ac1ac77-7358-425e-be16-0bdde9f02e59",
293 | "timestamp": "2024-02-28T00:43:12Z",
294 | "quantity": 818,
295 | "unitPrice": 685.08,
296 | "totalAmount": 8503.33
297 | },
298 | {
299 | "saleId": "55880ad4-1b25-4c67-a21a-9c2e480752af",
300 | "productId": "1afc136b-4d9f-4e8e-aace-8e1df908a404",
301 | "timestamp": "2023-09-05T17:54:43Z",
302 | "quantity": 578,
303 | "unitPrice": 817.99,
304 | "totalAmount": 1584.0
305 | },
306 | {
307 | "saleId": "76515f08-ff03-46a5-8435-af7345ff9bab",
308 | "productId": "af84cc12-4fea-4f58-aece-f2ce92ca9580",
309 | "timestamp": "2023-08-19T00:33:46Z",
310 | "quantity": 491,
311 | "unitPrice": 801.15,
312 | "totalAmount": 3758.2
313 | },
314 | {
315 | "saleId": "b84d883b-348a-4ea2-9f3b-7e9c6e841634",
316 | "productId": "86e3bb1c-2f5d-4774-98f3-4df7cddd0a0f",
317 | "timestamp": "2023-12-27T23:17:04Z",
318 | "quantity": 281,
319 | "unitPrice": 317.09,
320 | "totalAmount": 6151.55
321 | },
322 | {
323 | "saleId": "2be4ca15-1cfb-4b06-a87a-3494b02dacab",
324 | "productId": "26b017c6-06d8-443f-9b4a-d6b1cee6f4c0",
325 | "timestamp": "2023-11-18T12:30:37Z",
326 | "quantity": 666,
327 | "unitPrice": 690.3,
328 | "totalAmount": 1522.01
329 | },
330 | {
331 | "saleId": "3e1685c3-b8d1-49ac-8f00-15fb7f4e1a3d",
332 | "productId": "440c9e80-6bf8-4eb3-b2d2-f81936d67de3",
333 | "timestamp": "2024-01-22T17:28:27Z",
334 | "quantity": 113,
335 | "unitPrice": 54.35,
336 | "totalAmount": 8803.88
337 | },
338 | {
339 | "saleId": "446fca08-cdec-43c3-afe8-2c9b82016062",
340 | "productId": "98255f4e-40a6-470f-89a5-0792729f8947",
341 | "timestamp": "2023-03-29T14:37:25Z",
342 | "quantity": 574,
343 | "unitPrice": 605.86,
344 | "totalAmount": 749.81
345 | },
346 | {
347 | "saleId": "b84043c2-e60a-4c2f-9a10-6a56cedbb2a9",
348 | "productId": "2a339fb2-f9f3-43bc-a85a-b217a0a38f12",
349 | "timestamp": "2023-10-04T08:22:42Z",
350 | "quantity": 26,
351 | "unitPrice": 438.25,
352 | "totalAmount": 9407.62
353 | },
354 | {
355 | "saleId": "ca781bd3-fa61-4f5b-bdc2-3053531a9d2f",
356 | "productId": "8a8391b2-b4ac-4847-b652-66ffd8d65875",
357 | "timestamp": "2024-02-12T03:24:52Z",
358 | "quantity": 452,
359 | "unitPrice": 511.0,
360 | "totalAmount": 8734.61
361 | },
362 | {
363 | "saleId": "caa5f9b6-1458-4754-b0d1-19adebd562cf",
364 | "productId": "be2157fb-7454-405e-9511-bf7ba81b7726",
365 | "timestamp": "2023-12-25T10:27:27Z",
366 | "quantity": 484,
367 | "unitPrice": 280.73,
368 | "totalAmount": 5679.77
369 | },
370 | {
371 | "saleId": "36a183a7-7abb-4f74-938b-b21801aa4c22",
372 | "productId": "fdf1ba3d-fa06-4ce5-90ff-d081c5d37176",
373 | "timestamp": "2023-08-16T06:01:27Z",
374 | "quantity": 260,
375 | "unitPrice": 232.89,
376 | "totalAmount": 3765.82
377 | },
378 | {
379 | "saleId": "d62aaec8-35f2-44f2-ba46-5f024ddcb1c3",
380 | "productId": "afded6df-058f-477d-9878-e0e0b1d3dff3",
381 | "timestamp": "2023-10-02T16:42:02Z",
382 | "quantity": 718,
383 | "unitPrice": 685.31,
384 | "totalAmount": 6321.19
385 | },
386 | {
387 | "saleId": "253c02a9-decd-4d11-bf40-9cf6d8c12562",
388 | "productId": "daa29167-82a7-474b-9687-b8b903e7ec69",
389 | "timestamp": "2023-06-10T02:42:28Z",
390 | "quantity": 297,
391 | "unitPrice": 953.45,
392 | "totalAmount": 2757.43
393 | },
394 | {
395 | "saleId": "204bf1e8-c1ec-4c28-b209-4b3485983956",
396 | "productId": "ccb83982-71f3-4497-bad8-7e64c6920dc6",
397 | "timestamp": "2023-07-16T21:58:15Z",
398 | "quantity": 447,
399 | "unitPrice": 777.27,
400 | "totalAmount": 4574.02
401 | },
402 | {
403 | "saleId": "8f2cc66d-1cee-4bdb-8d71-124f27c5de48",
404 | "productId": "1936d406-e89e-40e4-bff7-1827532269d4",
405 | "timestamp": "2023-06-17T10:37:35Z",
406 | "quantity": 390,
407 | "unitPrice": 855.29,
408 | "totalAmount": 4044.96
409 | },
410 | {
411 | "saleId": "3a28dbfa-758c-4f0f-a086-0b04e7dd94a7",
412 | "productId": "c849a535-5f8b-47e3-889c-015693a644ac",
413 | "timestamp": "2024-01-31T06:04:28Z",
414 | "quantity": 851,
415 | "unitPrice": 170.23,
416 | "totalAmount": 9399.42
417 | },
418 | {
419 | "saleId": "12bd3ad4-b486-4515-9192-c2c2a33f97ff",
420 | "productId": "0c3e80ee-59b3-4fc4-b760-8b07acc2d3ae",
421 | "timestamp": "2023-05-03T13:57:12Z",
422 | "quantity": 882,
423 | "unitPrice": 973.95,
424 | "totalAmount": 4241.28
425 | },
426 | {
427 | "saleId": "d4fcfc21-9191-4419-a18d-a15282881274",
428 | "productId": "d8f5bee3-f3eb-4071-a124-6b857e0fd798",
429 | "timestamp": "2023-10-22T01:09:46Z",
430 | "quantity": 830,
431 | "unitPrice": 200.27,
432 | "totalAmount": 3059.84
433 | },
434 | {
435 | "saleId": "00680af4-e08f-4360-bcb0-e5702edec5f9",
436 | "productId": "8d15de86-0e4a-4414-9166-7a33610202d3",
437 | "timestamp": "2023-05-09T15:02:48Z",
438 | "quantity": 414,
439 | "unitPrice": 924.09,
440 | "totalAmount": 8604.22
441 | },
442 | {
443 | "saleId": "86b7e33b-e09e-4cdd-ac75-ad2d563936d9",
444 | "productId": "ea8fd0b9-c2d9-4d43-9c23-44cb99d079bb",
445 | "timestamp": "2023-03-23T16:14:23Z",
446 | "quantity": 390,
447 | "unitPrice": 792.89,
448 | "totalAmount": 6503.0
449 | },
450 | {
451 | "saleId": "baf92b24-73f7-45f8-8326-80c7d151472e",
452 | "productId": "25d01c80-bca1-4a00-b1d0-0fbd39ff9e89",
453 | "timestamp": "2024-02-22T07:16:30Z",
454 | "quantity": 391,
455 | "unitPrice": 685.29,
456 | "totalAmount": 9900.96
457 | },
458 | {
459 | "saleId": "dc8df228-0241-4cc0-95ee-3b5eda831524",
460 | "productId": "1d6df6e3-b7ea-4507-9d66-87c6ee8ed5b9",
461 | "timestamp": "2023-05-04T23:00:53Z",
462 | "quantity": 309,
463 | "unitPrice": 639.66,
464 | "totalAmount": 9964.61
465 | },
466 | {
467 | "saleId": "201e23c6-6ddc-4dc9-8e39-b6fb81404fcf",
468 | "productId": "000a8c23-5bca-436c-a216-4e747a94c511",
469 | "timestamp": "2023-08-23T17:23:35Z",
470 | "quantity": 325,
471 | "unitPrice": 471.59,
472 | "totalAmount": 7706.41
473 | },
474 | {
475 | "saleId": "603586d5-2f86-4c3e-9acf-cdffd433f702",
476 | "productId": "c5b600dc-6bfb-492a-b335-c3cc8c707959",
477 | "timestamp": "2024-02-22T06:16:55Z",
478 | "quantity": 857,
479 | "unitPrice": 197.36,
480 | "totalAmount": 760.65
481 | },
482 | {
483 | "saleId": "5253cf24-44e6-4f86-8abe-d827a088ee9b",
484 | "productId": "9d5fafbc-312b-47e8-ada1-283918f0c3b5",
485 | "timestamp": "2023-12-15T21:21:09Z",
486 | "quantity": 25,
487 | "unitPrice": 158.12,
488 | "totalAmount": 243.15
489 | },
490 | {
491 | "saleId": "31de695e-9c3d-433b-a5d5-3af401d2763e",
492 | "productId": "0114d5d4-ae48-46fa-b0ca-afe60eb88add",
493 | "timestamp": "2024-02-06T13:55:02Z",
494 | "quantity": 757,
495 | "unitPrice": 283.2,
496 | "totalAmount": 7420.27
497 | },
498 | {
499 | "saleId": "beffcc21-4fa2-4abf-9ddf-03a68651f751",
500 | "productId": "e5b0da8c-148d-4680-b262-8609fb8a10da",
501 | "timestamp": "2023-05-20T14:26:19Z",
502 | "quantity": 580,
503 | "unitPrice": 659.75,
504 | "totalAmount": 5018.42
505 | },
506 | {
507 | "saleId": "7c9389c3-87f0-454d-9ab3-f9c8fb28f082",
508 | "productId": "2be5b024-2c96-4f29-912c-c6f36353f799",
509 | "timestamp": "2023-07-01T04:46:47Z",
510 | "quantity": 948,
511 | "unitPrice": 620.57,
512 | "totalAmount": 7555.21
513 | },
514 | {
515 | "saleId": "ada3165e-5ce6-45b9-95d5-4665b223f221",
516 | "productId": "fcf2e432-62a3-4b6f-a34d-36e42a12272e",
517 | "timestamp": "2023-03-25T13:26:56Z",
518 | "quantity": 960,
519 | "unitPrice": 989.43,
520 | "totalAmount": 1188.7
521 | },
522 | {
523 | "saleId": "e8829f25-7ce4-44cd-bab9-277e1d2d170c",
524 | "productId": "fc4c81e5-f1ac-40f5-8c6f-da3fbad5599d",
525 | "timestamp": "2023-05-29T02:29:01Z",
526 | "quantity": 667,
527 | "unitPrice": 357.37,
528 | "totalAmount": 6196.09
529 | },
530 | {
531 | "saleId": "984b0d72-f6ea-49ac-960f-f4027d2ea67b",
532 | "productId": "07238d8e-0037-4972-87ca-0df206ee3e42",
533 | "timestamp": "2023-03-15T22:27:44Z",
534 | "quantity": 623,
535 | "unitPrice": 467.77,
536 | "totalAmount": 6657.9
537 | },
538 | {
539 | "saleId": "3027a79c-8583-4585-b618-a31344cb8acb",
540 | "productId": "154b7860-23a2-4564-ad99-1745ab7122ef",
541 | "timestamp": "2023-03-17T09:21:59Z",
542 | "quantity": 23,
543 | "unitPrice": 945.27,
544 | "totalAmount": 7870.76
545 | },
546 | {
547 | "saleId": "90f35bc0-3617-4cb6-9754-923c814991fd",
548 | "productId": "8d4bf814-65d4-4df4-84cc-68911d925fdf",
549 | "timestamp": "2024-01-29T09:24:28Z",
550 | "quantity": 140,
551 | "unitPrice": 664.0,
552 | "totalAmount": 7582.02
553 | },
554 | {
555 | "saleId": "5c86a794-9fac-4a1e-9c5a-01282a0b166e",
556 | "productId": "a52bf1bd-3d35-4cd2-849a-354e3952e2d2",
557 | "timestamp": "2023-05-25T21:06:21Z",
558 | "quantity": 127,
559 | "unitPrice": 185.81,
560 | "totalAmount": 4970.67
561 | },
562 | {
563 | "saleId": "ec033faa-a469-48d5-b5e1-108413f12d07",
564 | "productId": "d35623ee-bef6-42b2-8776-2f99f8bb4782",
565 | "timestamp": "2023-12-12T16:58:27Z",
566 | "quantity": 178,
567 | "unitPrice": 422.07,
568 | "totalAmount": 169.06
569 | },
570 | {
571 | "saleId": "0e8f8555-4af9-44a8-b32e-bc6d5d1b0de0",
572 | "productId": "8ac1ac77-7358-425e-be16-0bdde9f02e59",
573 | "timestamp": "2023-03-23T10:36:36Z",
574 | "quantity": 295,
575 | "unitPrice": 536.74,
576 | "totalAmount": 7652.54
577 | },
578 | {
579 | "saleId": "2ac5fd37-ad3e-4a22-b37b-70603a30d82e",
580 | "productId": "1afc136b-4d9f-4e8e-aace-8e1df908a404",
581 | "timestamp": "2023-08-28T07:08:56Z",
582 | "quantity": 338,
583 | "unitPrice": 304.83,
584 | "totalAmount": 137.98
585 | },
586 | {
587 | "saleId": "4ac03bce-3d3a-4d93-af99-9c7bc54e5168",
588 | "productId": "af84cc12-4fea-4f58-aece-f2ce92ca9580",
589 | "timestamp": "2024-02-15T09:35:47Z",
590 | "quantity": 65,
591 | "unitPrice": 951.61,
592 | "totalAmount": 7558.27
593 | },
594 | {
595 | "saleId": "e354821f-9808-487c-b466-3d3a1c7bc762",
596 | "productId": "86e3bb1c-2f5d-4774-98f3-4df7cddd0a0f",
597 | "timestamp": "2023-11-25T20:30:36Z",
598 | "quantity": 171,
599 | "unitPrice": 305.65,
600 | "totalAmount": 4647.58
601 | },
602 | {
603 | "saleId": "0ff9d397-db60-4281-8c51-73d6665003dd",
604 | "productId": "26b017c6-06d8-443f-9b4a-d6b1cee6f4c0",
605 | "timestamp": "2024-02-15T23:11:52Z",
606 | "quantity": 610,
607 | "unitPrice": 428.16,
608 | "totalAmount": 3294.23
609 | },
610 | {
611 | "saleId": "1a5873ef-8484-40b0-a9fd-d6c11e441e61",
612 | "productId": "440c9e80-6bf8-4eb3-b2d2-f81936d67de3",
613 | "timestamp": "2024-03-10T20:18:24Z",
614 | "quantity": 579,
615 | "unitPrice": 129.19,
616 | "totalAmount": 488.19
617 | },
618 | {
619 | "saleId": "d55ca8e1-ffff-439d-a55b-f0b9eb8f848e",
620 | "productId": "98255f4e-40a6-470f-89a5-0792729f8947",
621 | "timestamp": "2023-07-26T01:38:07Z",
622 | "quantity": 186,
623 | "unitPrice": 544.82,
624 | "totalAmount": 2989.5
625 | },
626 | {
627 | "saleId": "e90068e8-55c5-400d-a805-7dbab388138a",
628 | "productId": "2a339fb2-f9f3-43bc-a85a-b217a0a38f12",
629 | "timestamp": "2023-09-24T10:51:03Z",
630 | "quantity": 540,
631 | "unitPrice": 541.07,
632 | "totalAmount": 3861.48
633 | },
634 | {
635 | "saleId": "32eba028-2991-406a-90ca-600beb4f67db",
636 | "productId": "8a8391b2-b4ac-4847-b652-66ffd8d65875",
637 | "timestamp": "2023-06-29T10:24:41Z",
638 | "quantity": 661,
639 | "unitPrice": 78.07,
640 | "totalAmount": 2467.93
641 | },
642 | {
643 | "saleId": "7c17b19e-17ef-4d37-9233-6ad31bd85b23",
644 | "productId": "be2157fb-7454-405e-9511-bf7ba81b7726",
645 | "timestamp": "2023-12-02T12:10:55Z",
646 | "quantity": 635,
647 | "unitPrice": 52.5,
648 | "totalAmount": 4393.68
649 | },
650 | {
651 | "saleId": "729cfe78-6698-4a32-9c78-51ada37cfb36",
652 | "productId": "fdf1ba3d-fa06-4ce5-90ff-d081c5d37176",
653 | "timestamp": "2023-10-29T22:49:12Z",
654 | "quantity": 733,
655 | "unitPrice": 349.87,
656 | "totalAmount": 2736.72
657 | },
658 | {
659 | "saleId": "48afeac9-385d-4ff3-9e7f-0a6787ec1958",
660 | "productId": "afded6df-058f-477d-9878-e0e0b1d3dff3",
661 | "timestamp": "2023-11-07T08:57:27Z",
662 | "quantity": 268,
663 | "unitPrice": 700.99,
664 | "totalAmount": 7115.25
665 | },
666 | {
667 | "saleId": "0831a92f-4c18-4de6-a9d3-96ec3352603d",
668 | "productId": "daa29167-82a7-474b-9687-b8b903e7ec69",
669 | "timestamp": "2024-01-11T03:57:45Z",
670 | "quantity": 387,
671 | "unitPrice": 382.34,
672 | "totalAmount": 2575.24
673 | },
674 | {
675 | "saleId": "2888cfa2-b9ef-4e6d-8c62-014734591691",
676 | "productId": "ccb83982-71f3-4497-bad8-7e64c6920dc6",
677 | "timestamp": "2023-11-23T13:32:43Z",
678 | "quantity": 420,
679 | "unitPrice": 596.87,
680 | "totalAmount": 3294.5
681 | },
682 | {
683 | "saleId": "40bd92ec-084e-415e-ba4b-2d12d826ca36",
684 | "productId": "1936d406-e89e-40e4-bff7-1827532269d4",
685 | "timestamp": "2023-04-16T18:59:38Z",
686 | "quantity": 678,
687 | "unitPrice": 947.48,
688 | "totalAmount": 7363.69
689 | },
690 | {
691 | "saleId": "2ba6fdbb-81c8-4af2-8adb-0505033a3c98",
692 | "productId": "c849a535-5f8b-47e3-889c-015693a644ac",
693 | "timestamp": "2024-01-27T13:21:55Z",
694 | "quantity": 626,
695 | "unitPrice": 731.66,
696 | "totalAmount": 9487.24
697 | },
698 | {
699 | "saleId": "fc3006ad-f883-4f43-86ee-8c1a4f2c7248",
700 | "productId": "0c3e80ee-59b3-4fc4-b760-8b07acc2d3ae",
701 | "timestamp": "2023-11-02T09:32:22Z",
702 | "quantity": 732,
703 | "unitPrice": 366.09,
704 | "totalAmount": 4384.09
705 | },
706 | {
707 | "saleId": "8b6c8765-001c-4a54-91e2-761394f1a700",
708 | "productId": "d8f5bee3-f3eb-4071-a124-6b857e0fd798",
709 | "timestamp": "2023-04-21T22:19:20Z",
710 | "quantity": 368,
711 | "unitPrice": 37.27,
712 | "totalAmount": 5510.41
713 | },
714 | {
715 | "saleId": "b830c1e8-ed9a-4893-b6d2-68b87b991453",
716 | "productId": "8d15de86-0e4a-4414-9166-7a33610202d3",
717 | "timestamp": "2023-09-14T06:10:36Z",
718 | "quantity": 426,
719 | "unitPrice": 257.98,
720 | "totalAmount": 5241.93
721 | },
722 | {
723 | "saleId": "eeaa3b86-09ae-46aa-9b58-6354713c23cd",
724 | "productId": "ea8fd0b9-c2d9-4d43-9c23-44cb99d079bb",
725 | "timestamp": "2023-05-09T05:06:12Z",
726 | "quantity": 228,
727 | "unitPrice": 205.53,
728 | "totalAmount": 2448.67
729 | },
730 | {
731 | "saleId": "8579fa47-cd55-477e-9bc0-77f7975c91c6",
732 | "productId": "25d01c80-bca1-4a00-b1d0-0fbd39ff9e89",
733 | "timestamp": "2023-07-09T23:55:58Z",
734 | "quantity": 147,
735 | "unitPrice": 304.11,
736 | "totalAmount": 646.37
737 | },
738 | {
739 | "saleId": "d5436830-dc0a-4f7b-b96b-ca96c10f7b36",
740 | "productId": "1d6df6e3-b7ea-4507-9d66-87c6ee8ed5b9",
741 | "timestamp": "2023-06-25T14:57:39Z",
742 | "quantity": 700,
743 | "unitPrice": 574.25,
744 | "totalAmount": 6103.38
745 | },
746 | {
747 | "saleId": "477e5f5d-c44c-4f3a-b4c4-8a85924fe01b",
748 | "productId": "000a8c23-5bca-436c-a216-4e747a94c511",
749 | "timestamp": "2023-04-10T13:26:52Z",
750 | "quantity": 400,
751 | "unitPrice": 49.43,
752 | "totalAmount": 1860.5
753 | },
754 | {
755 | "saleId": "bfbe67c7-3d3b-471c-a999-d2ea8a9594d0",
756 | "productId": "c5b600dc-6bfb-492a-b335-c3cc8c707959",
757 | "timestamp": "2023-11-17T17:02:08Z",
758 | "quantity": 654,
759 | "unitPrice": 825.63,
760 | "totalAmount": 6998.87
761 | },
762 | {
763 | "saleId": "156a5c20-6338-41e2-b9ab-dbcb40905925",
764 | "productId": "9d5fafbc-312b-47e8-ada1-283918f0c3b5",
765 | "timestamp": "2023-03-20T16:53:47Z",
766 | "quantity": 125,
767 | "unitPrice": 237.24,
768 | "totalAmount": 6603.67
769 | },
770 | {
771 | "saleId": "6d4ab0ae-5d49-4731-b099-d8e155fb49d1",
772 | "productId": "0114d5d4-ae48-46fa-b0ca-afe60eb88add",
773 | "timestamp": "2023-06-14T08:48:03Z",
774 | "quantity": 677,
775 | "unitPrice": 479.94,
776 | "totalAmount": 7760.82
777 | },
778 | {
779 | "saleId": "81aa20f8-591f-47e6-8bad-7ad3e3003f81",
780 | "productId": "e5b0da8c-148d-4680-b262-8609fb8a10da",
781 | "timestamp": "2023-06-30T12:47:06Z",
782 | "quantity": 555,
783 | "unitPrice": 410.27,
784 | "totalAmount": 9330.17
785 | },
786 | {
787 | "saleId": "a93e6a0c-d178-4889-b2ae-ba0325d9051f",
788 | "productId": "2be5b024-2c96-4f29-912c-c6f36353f799",
789 | "timestamp": "2023-11-24T12:14:40Z",
790 | "quantity": 508,
791 | "unitPrice": 558.25,
792 | "totalAmount": 4006.69
793 | },
794 | {
795 | "saleId": "4a2575dd-8861-46ce-80ad-74f488d79a5a",
796 | "productId": "fcf2e432-62a3-4b6f-a34d-36e42a12272e",
797 | "timestamp": "2023-09-16T14:34:18Z",
798 | "quantity": 259,
799 | "unitPrice": 368.39,
800 | "totalAmount": 5611.94
801 | }
802 | ]
803 |
--------------------------------------------------------------------------------
/server/prisma/seedData/purchases.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "purchaseId": "5035f91e-4a29-411a-8779-17f6105675f1",
4 | "productId": "d35623ee-bef6-42b2-8776-2f99f8bb4782",
5 | "timestamp": "2007-09-28T13:56:51Z",
6 | "quantity": 875,
7 | "unitCost": 4163.31,
8 | "totalCost": 7871.43
9 | },
10 | {
11 | "purchaseId": "85841cb5-2132-40f2-b923-9769ee3c199b",
12 | "productId": "8ac1ac77-7358-425e-be16-0bdde9f02e59",
13 | "timestamp": "2015-02-01T13:04:43Z",
14 | "quantity": 471,
15 | "unitCost": 5673.17,
16 | "totalCost": 485.48
17 | },
18 | {
19 | "purchaseId": "de384851-f898-4495-99b8-73448bb470bf",
20 | "productId": "1afc136b-4d9f-4e8e-aace-8e1df908a404",
21 | "timestamp": "2010-10-22T19:38:20Z",
22 | "quantity": 37,
23 | "unitCost": 3835.06,
24 | "totalCost": 4202.25
25 | },
26 | {
27 | "purchaseId": "e0b0486c-6396-42b7-9a84-e21bd3a88600",
28 | "productId": "af84cc12-4fea-4f58-aece-f2ce92ca9580",
29 | "timestamp": "2020-01-25T13:30:58Z",
30 | "quantity": 201,
31 | "unitCost": 1822.27,
32 | "totalCost": 8028.29
33 | },
34 | {
35 | "purchaseId": "822e6025-e582-4e8c-b143-dc5ebad4c18c",
36 | "productId": "86e3bb1c-2f5d-4774-98f3-4df7cddd0a0f",
37 | "timestamp": "2011-12-30T12:54:41Z",
38 | "quantity": 789,
39 | "unitCost": 9238.02,
40 | "totalCost": 5086.57
41 | },
42 | {
43 | "purchaseId": "dd6d3a14-92d5-40f4-9bf4-92fb4043882c",
44 | "productId": "26b017c6-06d8-443f-9b4a-d6b1cee6f4c0",
45 | "timestamp": "2014-02-26T01:13:31Z",
46 | "quantity": 251,
47 | "unitCost": 2443.32,
48 | "totalCost": 9520.42
49 | },
50 | {
51 | "purchaseId": "434e5415-cb23-4170-b1e7-bc85737dc8c7",
52 | "productId": "440c9e80-6bf8-4eb3-b2d2-f81936d67de3",
53 | "timestamp": "2001-11-18T23:49:33Z",
54 | "quantity": 418,
55 | "unitCost": 5085.79,
56 | "totalCost": 5394.89
57 | },
58 | {
59 | "purchaseId": "963a92ab-e092-4f3d-8b6a-5ab803550d78",
60 | "productId": "98255f4e-40a6-470f-89a5-0792729f8947",
61 | "timestamp": "2020-04-27T08:53:44Z",
62 | "quantity": 926,
63 | "unitCost": 8626.52,
64 | "totalCost": 3526.35
65 | },
66 | {
67 | "purchaseId": "b4aebfdc-bce9-4e90-89fc-5098447d687a",
68 | "productId": "2a339fb2-f9f3-43bc-a85a-b217a0a38f12",
69 | "timestamp": "2020-02-05T13:02:55Z",
70 | "quantity": 754,
71 | "unitCost": 9052.79,
72 | "totalCost": 8035.97
73 | },
74 | {
75 | "purchaseId": "de2ba6a2-c291-4a60-aad1-23d5749c5847",
76 | "productId": "8a8391b2-b4ac-4847-b652-66ffd8d65875",
77 | "timestamp": "2020-05-07T16:41:13Z",
78 | "quantity": 365,
79 | "unitCost": 1105.02,
80 | "totalCost": 361.77
81 | },
82 | {
83 | "purchaseId": "78ea5f20-8fcc-4b6c-836f-e4b7a58d7479",
84 | "productId": "be2157fb-7454-405e-9511-bf7ba81b7726",
85 | "timestamp": "2014-08-12T16:37:41Z",
86 | "quantity": 975,
87 | "unitCost": 4783.47,
88 | "totalCost": 9517.85
89 | },
90 | {
91 | "purchaseId": "61ba57e9-81fe-4d04-85b5-6aab219ced9d",
92 | "productId": "fdf1ba3d-fa06-4ce5-90ff-d081c5d37176",
93 | "timestamp": "2008-12-07T16:18:59Z",
94 | "quantity": 286,
95 | "unitCost": 6910.82,
96 | "totalCost": 9006.07
97 | },
98 | {
99 | "purchaseId": "012d028b-4d6b-43bf-8d69-edf296133c9e",
100 | "productId": "afded6df-058f-477d-9878-e0e0b1d3dff3",
101 | "timestamp": "2005-12-29T10:50:55Z",
102 | "quantity": 71,
103 | "unitCost": 4058.81,
104 | "totalCost": 5983.42
105 | },
106 | {
107 | "purchaseId": "8155b76c-3da2-4fb4-ba18-68bf8a2cec1b",
108 | "productId": "daa29167-82a7-474b-9687-b8b903e7ec69",
109 | "timestamp": "2007-08-15T18:41:49Z",
110 | "quantity": 963,
111 | "unitCost": 2198.44,
112 | "totalCost": 4935.68
113 | },
114 | {
115 | "purchaseId": "4d449c76-ee8a-473e-8135-f74875a31964",
116 | "productId": "ccb83982-71f3-4497-bad8-7e64c6920dc6",
117 | "timestamp": "2014-12-05T06:28:48Z",
118 | "quantity": 614,
119 | "unitCost": 6565.99,
120 | "totalCost": 6406.98
121 | },
122 | {
123 | "purchaseId": "115c6e6c-e6d0-418f-990e-1730f9e4b02e",
124 | "productId": "1936d406-e89e-40e4-bff7-1827532269d4",
125 | "timestamp": "2003-12-17T12:52:02Z",
126 | "quantity": 193,
127 | "unitCost": 2562.72,
128 | "totalCost": 788.08
129 | },
130 | {
131 | "purchaseId": "7b898dfe-79e0-472c-a19e-d75d6a2719fd",
132 | "productId": "c849a535-5f8b-47e3-889c-015693a644ac",
133 | "timestamp": "2014-05-13T17:09:07Z",
134 | "quantity": 585,
135 | "unitCost": 1580.69,
136 | "totalCost": 2633.43
137 | },
138 | {
139 | "purchaseId": "cb3000e8-df2e-4e8b-99ed-4ceb35077404",
140 | "productId": "0c3e80ee-59b3-4fc4-b760-8b07acc2d3ae",
141 | "timestamp": "2006-10-21T15:28:13Z",
142 | "quantity": 938,
143 | "unitCost": 6197.05,
144 | "totalCost": 3487.61
145 | },
146 | {
147 | "purchaseId": "8b709837-e51b-493a-8720-89e64f9888e2",
148 | "productId": "d8f5bee3-f3eb-4071-a124-6b857e0fd798",
149 | "timestamp": "2002-08-23T21:20:02Z",
150 | "quantity": 388,
151 | "unitCost": 3280.29,
152 | "totalCost": 21.24
153 | },
154 | {
155 | "purchaseId": "8ee49368-1e96-41ed-bc53-7ba90ed537a4",
156 | "productId": "8d15de86-0e4a-4414-9166-7a33610202d3",
157 | "timestamp": "2022-09-09T02:34:59Z",
158 | "quantity": 463,
159 | "unitCost": 4646.46,
160 | "totalCost": 273.21
161 | },
162 | {
163 | "purchaseId": "a6d93761-366f-4e66-9a2f-2621d94896cb",
164 | "productId": "ea8fd0b9-c2d9-4d43-9c23-44cb99d079bb",
165 | "timestamp": "2013-04-06T06:29:40Z",
166 | "quantity": 893,
167 | "unitCost": 2857.95,
168 | "totalCost": 7423.21
169 | },
170 | {
171 | "purchaseId": "c6207ac3-3c64-49f4-9383-e47c32f11c28",
172 | "productId": "25d01c80-bca1-4a00-b1d0-0fbd39ff9e89",
173 | "timestamp": "2002-06-17T12:03:13Z",
174 | "quantity": 22,
175 | "unitCost": 3180.14,
176 | "totalCost": 9077.46
177 | },
178 | {
179 | "purchaseId": "02cb1517-154a-469e-88a1-33449be5b6de",
180 | "productId": "1d6df6e3-b7ea-4507-9d66-87c6ee8ed5b9",
181 | "timestamp": "2017-05-26T03:42:34Z",
182 | "quantity": 70,
183 | "unitCost": 4308.81,
184 | "totalCost": 1589.27
185 | },
186 | {
187 | "purchaseId": "6e468dfb-8cfc-4ad6-af0c-af0a1f6726ab",
188 | "productId": "000a8c23-5bca-436c-a216-4e747a94c511",
189 | "timestamp": "2013-02-03T13:03:56Z",
190 | "quantity": 208,
191 | "unitCost": 3424.81,
192 | "totalCost": 9545.07
193 | },
194 | {
195 | "purchaseId": "0f67af62-d82b-4986-ba91-0d7cc8261e21",
196 | "productId": "c5b600dc-6bfb-492a-b335-c3cc8c707959",
197 | "timestamp": "2020-03-16T04:44:49Z",
198 | "quantity": 309,
199 | "unitCost": 9757.04,
200 | "totalCost": 9843.24
201 | },
202 | {
203 | "purchaseId": "c7539c9a-06a1-4e1c-aba1-4b7c60354974",
204 | "productId": "9d5fafbc-312b-47e8-ada1-283918f0c3b5",
205 | "timestamp": "2011-08-01T04:44:36Z",
206 | "quantity": 97,
207 | "unitCost": 4437.3,
208 | "totalCost": 7227.92
209 | },
210 | {
211 | "purchaseId": "80e5fcca-73a3-4679-b27f-21328a77e077",
212 | "productId": "0114d5d4-ae48-46fa-b0ca-afe60eb88add",
213 | "timestamp": "2021-10-23T09:58:14Z",
214 | "quantity": 727,
215 | "unitCost": 6706.78,
216 | "totalCost": 3444.68
217 | },
218 | {
219 | "purchaseId": "33d99aae-0b34-4c3c-af34-dba1201fa025",
220 | "productId": "e5b0da8c-148d-4680-b262-8609fb8a10da",
221 | "timestamp": "2013-12-25T00:37:26Z",
222 | "quantity": 246,
223 | "unitCost": 7074.43,
224 | "totalCost": 1551.41
225 | },
226 | {
227 | "purchaseId": "0a05c7b9-01a2-48d2-b1ed-51e11dc50550",
228 | "productId": "2be5b024-2c96-4f29-912c-c6f36353f799",
229 | "timestamp": "2001-10-29T19:34:59Z",
230 | "quantity": 193,
231 | "unitCost": 1576.29,
232 | "totalCost": 5458.34
233 | },
234 | {
235 | "purchaseId": "4bbd5b44-51ea-40cb-b993-8c1c1f3d6146",
236 | "productId": "fcf2e432-62a3-4b6f-a34d-36e42a12272e",
237 | "timestamp": "2008-05-09T00:34:59Z",
238 | "quantity": 265,
239 | "unitCost": 9629.95,
240 | "totalCost": 9902.55
241 | },
242 | {
243 | "purchaseId": "1dc72d06-61c1-4606-b604-15fcd1a3943e",
244 | "productId": "fc4c81e5-f1ac-40f5-8c6f-da3fbad5599d",
245 | "timestamp": "2018-12-12T10:12:24Z",
246 | "quantity": 342,
247 | "unitCost": 9107.59,
248 | "totalCost": 9187.51
249 | },
250 | {
251 | "purchaseId": "51f66b06-f965-433c-9fca-35e344324b3f",
252 | "productId": "07238d8e-0037-4972-87ca-0df206ee3e42",
253 | "timestamp": "2022-11-23T16:45:20Z",
254 | "quantity": 623,
255 | "unitCost": 3511.85,
256 | "totalCost": 8448.84
257 | },
258 | {
259 | "purchaseId": "0669c359-14ad-488f-bf66-553cb4263a06",
260 | "productId": "154b7860-23a2-4564-ad99-1745ab7122ef",
261 | "timestamp": "2016-06-18T10:26:07Z",
262 | "quantity": 856,
263 | "unitCost": 584.88,
264 | "totalCost": 6455.21
265 | },
266 | {
267 | "purchaseId": "5e697ec5-7722-48b5-b682-c3752a11b62e",
268 | "productId": "8d4bf814-65d4-4df4-84cc-68911d925fdf",
269 | "timestamp": "2003-08-07T17:41:10Z",
270 | "quantity": 330,
271 | "unitCost": 9835.78,
272 | "totalCost": 311.95
273 | },
274 | {
275 | "purchaseId": "3e54b486-1044-46b6-82f9-2646d92d4afa",
276 | "productId": "a52bf1bd-3d35-4cd2-849a-354e3952e2d2",
277 | "timestamp": "2007-02-01T19:40:46Z",
278 | "quantity": 265,
279 | "unitCost": 6506.44,
280 | "totalCost": 6583.9
281 | },
282 | {
283 | "purchaseId": "3726ca7b-1f32-4cad-a21b-6112de7d73ad",
284 | "productId": "d35623ee-bef6-42b2-8776-2f99f8bb4782",
285 | "timestamp": "2012-07-16T01:03:33Z",
286 | "quantity": 395,
287 | "unitCost": 4122.4,
288 | "totalCost": 4838.66
289 | },
290 | {
291 | "purchaseId": "54e4ebc5-b083-42f3-a3ec-90dcd64923f3",
292 | "productId": "8ac1ac77-7358-425e-be16-0bdde9f02e59",
293 | "timestamp": "2002-02-19T15:33:07Z",
294 | "quantity": 230,
295 | "unitCost": 2500.44,
296 | "totalCost": 7003.48
297 | },
298 | {
299 | "purchaseId": "21af41db-67ee-42fb-ad12-8e53c9017a21",
300 | "productId": "1afc136b-4d9f-4e8e-aace-8e1df908a404",
301 | "timestamp": "2005-04-20T20:56:35Z",
302 | "quantity": 770,
303 | "unitCost": 3563.47,
304 | "totalCost": 2068.71
305 | },
306 | {
307 | "purchaseId": "6efcb79a-8db6-4271-b28b-cfb46441d6d8",
308 | "productId": "af84cc12-4fea-4f58-aece-f2ce92ca9580",
309 | "timestamp": "2013-01-08T17:38:44Z",
310 | "quantity": 903,
311 | "unitCost": 6854.34,
312 | "totalCost": 6894.18
313 | },
314 | {
315 | "purchaseId": "a5d27d65-6419-4741-94f0-9499151f9031",
316 | "productId": "86e3bb1c-2f5d-4774-98f3-4df7cddd0a0f",
317 | "timestamp": "2018-11-16T06:44:31Z",
318 | "quantity": 220,
319 | "unitCost": 170.61,
320 | "totalCost": 3140.28
321 | },
322 | {
323 | "purchaseId": "0ffb160a-c687-4155-bea3-fc3ecc7da237",
324 | "productId": "26b017c6-06d8-443f-9b4a-d6b1cee6f4c0",
325 | "timestamp": "2022-02-13T05:52:33Z",
326 | "quantity": 625,
327 | "unitCost": 5823.23,
328 | "totalCost": 4498.82
329 | },
330 | {
331 | "purchaseId": "f96e84fc-3b9c-4f96-b80c-0646752c2624",
332 | "productId": "440c9e80-6bf8-4eb3-b2d2-f81936d67de3",
333 | "timestamp": "2008-05-05T23:57:50Z",
334 | "quantity": 260,
335 | "unitCost": 1320.91,
336 | "totalCost": 6951.15
337 | },
338 | {
339 | "purchaseId": "65419b2f-d156-408b-bfb6-52846e3aca1d",
340 | "productId": "98255f4e-40a6-470f-89a5-0792729f8947",
341 | "timestamp": "2010-06-27T23:54:15Z",
342 | "quantity": 72,
343 | "unitCost": 6999.3,
344 | "totalCost": 4171.88
345 | },
346 | {
347 | "purchaseId": "cd59eb23-5b53-4a0c-a1a0-0950c5ea17f4",
348 | "productId": "2a339fb2-f9f3-43bc-a85a-b217a0a38f12",
349 | "timestamp": "2018-06-04T02:16:54Z",
350 | "quantity": 846,
351 | "unitCost": 1424.7,
352 | "totalCost": 604.87
353 | },
354 | {
355 | "purchaseId": "31b464d9-89a7-431e-9bf1-9d68ee05d549",
356 | "productId": "8a8391b2-b4ac-4847-b652-66ffd8d65875",
357 | "timestamp": "2019-12-08T22:05:22Z",
358 | "quantity": 998,
359 | "unitCost": 9289.05,
360 | "totalCost": 3108.03
361 | },
362 | {
363 | "purchaseId": "767fc135-43ca-4067-87bb-0ab503bbd4c3",
364 | "productId": "be2157fb-7454-405e-9511-bf7ba81b7726",
365 | "timestamp": "2005-01-25T15:21:10Z",
366 | "quantity": 311,
367 | "unitCost": 1386.68,
368 | "totalCost": 8924.26
369 | },
370 | {
371 | "purchaseId": "52ce8633-b4cc-455d-94ab-531a7fb5b720",
372 | "productId": "fdf1ba3d-fa06-4ce5-90ff-d081c5d37176",
373 | "timestamp": "2022-09-27T13:23:04Z",
374 | "quantity": 71,
375 | "unitCost": 6751.76,
376 | "totalCost": 2580.36
377 | },
378 | {
379 | "purchaseId": "e292f886-0f8d-4989-bc01-f43dfffde54e",
380 | "productId": "afded6df-058f-477d-9878-e0e0b1d3dff3",
381 | "timestamp": "2008-10-13T00:50:04Z",
382 | "quantity": 134,
383 | "unitCost": 4446.17,
384 | "totalCost": 1718.57
385 | },
386 | {
387 | "purchaseId": "42e2086e-6dda-4c8e-b635-4387d794d6a0",
388 | "productId": "daa29167-82a7-474b-9687-b8b903e7ec69",
389 | "timestamp": "2014-09-16T22:59:06Z",
390 | "quantity": 807,
391 | "unitCost": 9916.73,
392 | "totalCost": 6818.54
393 | },
394 | {
395 | "purchaseId": "c223c7fe-38d5-4291-b618-c44bd9f797a7",
396 | "productId": "ccb83982-71f3-4497-bad8-7e64c6920dc6",
397 | "timestamp": "2007-03-28T02:21:31Z",
398 | "quantity": 726,
399 | "unitCost": 2967.87,
400 | "totalCost": 5509.38
401 | },
402 | {
403 | "purchaseId": "e12f6fd6-af77-4556-8866-c724d88acc5d",
404 | "productId": "1936d406-e89e-40e4-bff7-1827532269d4",
405 | "timestamp": "2010-09-20T14:09:37Z",
406 | "quantity": 763,
407 | "unitCost": 2083.13,
408 | "totalCost": 9062.53
409 | },
410 | {
411 | "purchaseId": "503fbb6e-2c84-4293-ad1e-8ad1a4ea3c8f",
412 | "productId": "c849a535-5f8b-47e3-889c-015693a644ac",
413 | "timestamp": "2016-08-03T19:45:31Z",
414 | "quantity": 675,
415 | "unitCost": 6611.91,
416 | "totalCost": 2353.38
417 | },
418 | {
419 | "purchaseId": "418785b8-d434-4f1b-827b-52584eb91414",
420 | "productId": "0c3e80ee-59b3-4fc4-b760-8b07acc2d3ae",
421 | "timestamp": "2005-03-28T16:39:46Z",
422 | "quantity": 839,
423 | "unitCost": 1488.73,
424 | "totalCost": 403.2
425 | },
426 | {
427 | "purchaseId": "032f3bc6-1edf-45ee-8cdd-7a3dbd4ec6bd",
428 | "productId": "d8f5bee3-f3eb-4071-a124-6b857e0fd798",
429 | "timestamp": "2010-09-11T18:58:14Z",
430 | "quantity": 776,
431 | "unitCost": 9893.08,
432 | "totalCost": 2071.46
433 | },
434 | {
435 | "purchaseId": "f64f8bfd-7c71-4bb0-a74e-21907a8b2a71",
436 | "productId": "8d15de86-0e4a-4414-9166-7a33610202d3",
437 | "timestamp": "2011-06-19T11:19:53Z",
438 | "quantity": 720,
439 | "unitCost": 3132.2,
440 | "totalCost": 1104.45
441 | },
442 | {
443 | "purchaseId": "aa148601-a438-4c9a-ba20-6645945e750b",
444 | "productId": "ea8fd0b9-c2d9-4d43-9c23-44cb99d079bb",
445 | "timestamp": "2001-12-13T15:26:09Z",
446 | "quantity": 392,
447 | "unitCost": 4880.07,
448 | "totalCost": 7915.32
449 | },
450 | {
451 | "purchaseId": "feabf3d1-9727-4b03-bd5c-2c97d85fc91e",
452 | "productId": "25d01c80-bca1-4a00-b1d0-0fbd39ff9e89",
453 | "timestamp": "2019-07-06T09:30:09Z",
454 | "quantity": 265,
455 | "unitCost": 2609.83,
456 | "totalCost": 1980.18
457 | },
458 | {
459 | "purchaseId": "6f44cf51-39cf-46c6-8e7e-719347ec2124",
460 | "productId": "1d6df6e3-b7ea-4507-9d66-87c6ee8ed5b9",
461 | "timestamp": "2005-08-17T21:00:54Z",
462 | "quantity": 984,
463 | "unitCost": 8085.15,
464 | "totalCost": 8511.07
465 | },
466 | {
467 | "purchaseId": "e76ebddb-90a1-4916-a3bd-17b5c58855dd",
468 | "productId": "000a8c23-5bca-436c-a216-4e747a94c511",
469 | "timestamp": "2003-10-14T08:56:13Z",
470 | "quantity": 575,
471 | "unitCost": 6609.95,
472 | "totalCost": 3212.6
473 | },
474 | {
475 | "purchaseId": "00fb05b1-724d-4b82-8600-441d20127ecb",
476 | "productId": "c5b600dc-6bfb-492a-b335-c3cc8c707959",
477 | "timestamp": "2009-01-26T02:37:46Z",
478 | "quantity": 324,
479 | "unitCost": 5032.83,
480 | "totalCost": 6453.79
481 | },
482 | {
483 | "purchaseId": "2b5d452d-be4f-4fc0-a018-a156b0aa144a",
484 | "productId": "9d5fafbc-312b-47e8-ada1-283918f0c3b5",
485 | "timestamp": "2017-09-20T01:05:24Z",
486 | "quantity": 859,
487 | "unitCost": 9826.12,
488 | "totalCost": 4717.49
489 | },
490 | {
491 | "purchaseId": "8272d8dc-df85-455c-b2ec-7cc4611a570c",
492 | "productId": "0114d5d4-ae48-46fa-b0ca-afe60eb88add",
493 | "timestamp": "2014-11-05T03:06:06Z",
494 | "quantity": 713,
495 | "unitCost": 8238.67,
496 | "totalCost": 6012.29
497 | },
498 | {
499 | "purchaseId": "5d8b58d2-63b1-4419-ab46-16ed3664adfc",
500 | "productId": "e5b0da8c-148d-4680-b262-8609fb8a10da",
501 | "timestamp": "2008-11-29T17:59:44Z",
502 | "quantity": 230,
503 | "unitCost": 684.84,
504 | "totalCost": 202.1
505 | },
506 | {
507 | "purchaseId": "e33fabca-19cf-469b-b3e7-6e5f1f434a3e",
508 | "productId": "2be5b024-2c96-4f29-912c-c6f36353f799",
509 | "timestamp": "2018-03-14T04:27:34Z",
510 | "quantity": 247,
511 | "unitCost": 7781.32,
512 | "totalCost": 55.1
513 | },
514 | {
515 | "purchaseId": "17c90a13-0871-44a5-9dcf-9b46d756b780",
516 | "productId": "fcf2e432-62a3-4b6f-a34d-36e42a12272e",
517 | "timestamp": "2010-05-03T03:18:22Z",
518 | "quantity": 267,
519 | "unitCost": 5.18,
520 | "totalCost": 5559.82
521 | },
522 | {
523 | "purchaseId": "22be5e72-440c-4a02-8176-9eb50d9cdc99",
524 | "productId": "fc4c81e5-f1ac-40f5-8c6f-da3fbad5599d",
525 | "timestamp": "2001-09-14T20:35:26Z",
526 | "quantity": 298,
527 | "unitCost": 388.02,
528 | "totalCost": 364.51
529 | },
530 | {
531 | "purchaseId": "3b663fc6-e550-4513-9df4-ecd7399e3ad4",
532 | "productId": "07238d8e-0037-4972-87ca-0df206ee3e42",
533 | "timestamp": "2021-07-11T20:29:31Z",
534 | "quantity": 356,
535 | "unitCost": 3099.1,
536 | "totalCost": 9858.3
537 | },
538 | {
539 | "purchaseId": "a7cd1009-cca3-4dd0-a08e-519fbef15886",
540 | "productId": "154b7860-23a2-4564-ad99-1745ab7122ef",
541 | "timestamp": "2015-11-29T04:47:23Z",
542 | "quantity": 560,
543 | "unitCost": 8579.08,
544 | "totalCost": 6600.09
545 | },
546 | {
547 | "purchaseId": "08232378-99cf-4828-b36f-6d7a31baba64",
548 | "productId": "8d4bf814-65d4-4df4-84cc-68911d925fdf",
549 | "timestamp": "2016-09-15T07:58:08Z",
550 | "quantity": 843,
551 | "unitCost": 556.0,
552 | "totalCost": 6556.65
553 | },
554 | {
555 | "purchaseId": "d33fe221-fd05-4f75-a8cd-8540ab8e8ce6",
556 | "productId": "a52bf1bd-3d35-4cd2-849a-354e3952e2d2",
557 | "timestamp": "2016-03-27T16:52:42Z",
558 | "quantity": 288,
559 | "unitCost": 9563.81,
560 | "totalCost": 1649.02
561 | },
562 | {
563 | "purchaseId": "9cd56445-6055-450a-a992-e3ae14bb3338",
564 | "productId": "d35623ee-bef6-42b2-8776-2f99f8bb4782",
565 | "timestamp": "2000-03-20T02:42:32Z",
566 | "quantity": 725,
567 | "unitCost": 9495.08,
568 | "totalCost": 5749.92
569 | },
570 | {
571 | "purchaseId": "fd6d7c0a-5d02-4dbc-8217-1d826eb569ce",
572 | "productId": "8ac1ac77-7358-425e-be16-0bdde9f02e59",
573 | "timestamp": "2012-09-14T23:33:07Z",
574 | "quantity": 141,
575 | "unitCost": 4504.95,
576 | "totalCost": 1561.89
577 | },
578 | {
579 | "purchaseId": "fe28b71d-8883-4157-ac89-4a5105e8ff54",
580 | "productId": "1afc136b-4d9f-4e8e-aace-8e1df908a404",
581 | "timestamp": "2008-01-02T02:33:03Z",
582 | "quantity": 388,
583 | "unitCost": 6425.96,
584 | "totalCost": 837.03
585 | },
586 | {
587 | "purchaseId": "93a95d90-2d95-4e21-9d61-deb872b8ce23",
588 | "productId": "af84cc12-4fea-4f58-aece-f2ce92ca9580",
589 | "timestamp": "2018-06-18T17:24:06Z",
590 | "quantity": 194,
591 | "unitCost": 8925.08,
592 | "totalCost": 8644.66
593 | },
594 | {
595 | "purchaseId": "52a78535-b622-4c9e-834c-21ca705d07b5",
596 | "productId": "86e3bb1c-2f5d-4774-98f3-4df7cddd0a0f",
597 | "timestamp": "2022-11-06T03:27:35Z",
598 | "quantity": 873,
599 | "unitCost": 7537.82,
600 | "totalCost": 1841.36
601 | },
602 | {
603 | "purchaseId": "ed4adaea-bcd2-49e5-bc9e-84ed807fa04c",
604 | "productId": "26b017c6-06d8-443f-9b4a-d6b1cee6f4c0",
605 | "timestamp": "2022-04-20T14:20:15Z",
606 | "quantity": 70,
607 | "unitCost": 5186.13,
608 | "totalCost": 9731.04
609 | },
610 | {
611 | "purchaseId": "1ee44e30-7a8f-4e88-b6dd-01c11b26f6b9",
612 | "productId": "440c9e80-6bf8-4eb3-b2d2-f81936d67de3",
613 | "timestamp": "2008-04-18T13:02:07Z",
614 | "quantity": 10,
615 | "unitCost": 6835.47,
616 | "totalCost": 4138.19
617 | },
618 | {
619 | "purchaseId": "913bc6d9-6757-457c-a565-471396e4f5b5",
620 | "productId": "98255f4e-40a6-470f-89a5-0792729f8947",
621 | "timestamp": "2010-06-26T01:51:22Z",
622 | "quantity": 651,
623 | "unitCost": 1095.15,
624 | "totalCost": 503.43
625 | },
626 | {
627 | "purchaseId": "d33baec5-186c-428d-996d-6dbd12e20c10",
628 | "productId": "2a339fb2-f9f3-43bc-a85a-b217a0a38f12",
629 | "timestamp": "2015-06-01T00:52:08Z",
630 | "quantity": 638,
631 | "unitCost": 2282.03,
632 | "totalCost": 5722.0
633 | },
634 | {
635 | "purchaseId": "6eb61d25-4cf6-43f8-a52d-302cf0b29553",
636 | "productId": "8a8391b2-b4ac-4847-b652-66ffd8d65875",
637 | "timestamp": "2011-04-19T21:39:04Z",
638 | "quantity": 67,
639 | "unitCost": 5414.05,
640 | "totalCost": 1905.77
641 | },
642 | {
643 | "purchaseId": "37b1920b-5a4b-41c7-bbf0-a872e93f2ab3",
644 | "productId": "be2157fb-7454-405e-9511-bf7ba81b7726",
645 | "timestamp": "2008-12-12T12:16:22Z",
646 | "quantity": 775,
647 | "unitCost": 333.25,
648 | "totalCost": 2883.66
649 | },
650 | {
651 | "purchaseId": "9b4f68c8-2d1a-44c8-95e9-3b257a6c37e3",
652 | "productId": "fdf1ba3d-fa06-4ce5-90ff-d081c5d37176",
653 | "timestamp": "2020-12-29T16:46:08Z",
654 | "quantity": 513,
655 | "unitCost": 6781.28,
656 | "totalCost": 5454.83
657 | },
658 | {
659 | "purchaseId": "87c3172d-9ae8-4163-b8ef-ad638fa27c95",
660 | "productId": "afded6df-058f-477d-9878-e0e0b1d3dff3",
661 | "timestamp": "2019-04-05T05:20:27Z",
662 | "quantity": 13,
663 | "unitCost": 5414.02,
664 | "totalCost": 4540.62
665 | },
666 | {
667 | "purchaseId": "8aed5186-cb4a-4bbb-b8be-857ff8227289",
668 | "productId": "daa29167-82a7-474b-9687-b8b903e7ec69",
669 | "timestamp": "2019-05-19T23:47:06Z",
670 | "quantity": 522,
671 | "unitCost": 2047.88,
672 | "totalCost": 456.65
673 | },
674 | {
675 | "purchaseId": "a5e1bed8-ced3-41cd-af3b-d891e01e1c1d",
676 | "productId": "ccb83982-71f3-4497-bad8-7e64c6920dc6",
677 | "timestamp": "2018-12-19T05:41:28Z",
678 | "quantity": 20,
679 | "unitCost": 7741.5,
680 | "totalCost": 6205.14
681 | },
682 | {
683 | "purchaseId": "dcc30321-e243-4cce-808a-2e0c553eee94",
684 | "productId": "1936d406-e89e-40e4-bff7-1827532269d4",
685 | "timestamp": "2002-10-06T13:58:33Z",
686 | "quantity": 473,
687 | "unitCost": 8571.71,
688 | "totalCost": 3088.43
689 | },
690 | {
691 | "purchaseId": "d3462347-2e06-46ff-9088-ceb25ee3ed11",
692 | "productId": "c849a535-5f8b-47e3-889c-015693a644ac",
693 | "timestamp": "2008-10-07T18:13:43Z",
694 | "quantity": 621,
695 | "unitCost": 2592.95,
696 | "totalCost": 5944.58
697 | },
698 | {
699 | "purchaseId": "24bb1ac4-4d5c-4308-a6f9-a004bd819f5e",
700 | "productId": "0c3e80ee-59b3-4fc4-b760-8b07acc2d3ae",
701 | "timestamp": "2003-08-29T16:23:44Z",
702 | "quantity": 240,
703 | "unitCost": 7732.65,
704 | "totalCost": 4956.83
705 | },
706 | {
707 | "purchaseId": "42d5ade2-6b62-47f0-aaa4-0b065a0b73ff",
708 | "productId": "d8f5bee3-f3eb-4071-a124-6b857e0fd798",
709 | "timestamp": "2020-08-16T06:05:41Z",
710 | "quantity": 729,
711 | "unitCost": 9648.57,
712 | "totalCost": 9558.36
713 | },
714 | {
715 | "purchaseId": "394dd7bb-d9ca-4ded-87ca-6336ca68f06c",
716 | "productId": "8d15de86-0e4a-4414-9166-7a33610202d3",
717 | "timestamp": "2019-06-19T07:23:51Z",
718 | "quantity": 109,
719 | "unitCost": 6608.23,
720 | "totalCost": 8900.4
721 | },
722 | {
723 | "purchaseId": "312e3902-2aaa-4678-bafb-534ec5fc1c24",
724 | "productId": "ea8fd0b9-c2d9-4d43-9c23-44cb99d079bb",
725 | "timestamp": "2014-03-12T17:47:55Z",
726 | "quantity": 490,
727 | "unitCost": 4139.51,
728 | "totalCost": 428.37
729 | },
730 | {
731 | "purchaseId": "9685898d-0b3c-4500-98cf-101e4e5818cf",
732 | "productId": "25d01c80-bca1-4a00-b1d0-0fbd39ff9e89",
733 | "timestamp": "2002-12-27T20:19:43Z",
734 | "quantity": 926,
735 | "unitCost": 305.23,
736 | "totalCost": 326.1
737 | },
738 | {
739 | "purchaseId": "c67d1950-3c03-401e-9f4a-573cc919c3ff",
740 | "productId": "1d6df6e3-b7ea-4507-9d66-87c6ee8ed5b9",
741 | "timestamp": "2000-03-28T15:44:26Z",
742 | "quantity": 210,
743 | "unitCost": 838.57,
744 | "totalCost": 3004.31
745 | },
746 | {
747 | "purchaseId": "0d793046-8eff-412c-983e-c13196c331cf",
748 | "productId": "000a8c23-5bca-436c-a216-4e747a94c511",
749 | "timestamp": "2009-09-30T02:48:52Z",
750 | "quantity": 452,
751 | "unitCost": 6538.73,
752 | "totalCost": 9188.61
753 | },
754 | {
755 | "purchaseId": "b38af82a-d3fb-46ec-9f98-346faf95629f",
756 | "productId": "c5b600dc-6bfb-492a-b335-c3cc8c707959",
757 | "timestamp": "2018-01-17T10:45:44Z",
758 | "quantity": 418,
759 | "unitCost": 7846.58,
760 | "totalCost": 9258.71
761 | },
762 | {
763 | "purchaseId": "32e25004-21cf-44ab-b44e-e3580d0ef9ce",
764 | "productId": "9d5fafbc-312b-47e8-ada1-283918f0c3b5",
765 | "timestamp": "2004-07-18T14:25:34Z",
766 | "quantity": 902,
767 | "unitCost": 1056.47,
768 | "totalCost": 4319.07
769 | },
770 | {
771 | "purchaseId": "0bfea984-8cdd-45ee-9407-5c9da64f94b0",
772 | "productId": "0114d5d4-ae48-46fa-b0ca-afe60eb88add",
773 | "timestamp": "2017-01-24T20:41:03Z",
774 | "quantity": 757,
775 | "unitCost": 5163.91,
776 | "totalCost": 8653.39
777 | },
778 | {
779 | "purchaseId": "570950ee-9c94-4423-bc5d-546524adf1f3",
780 | "productId": "e5b0da8c-148d-4680-b262-8609fb8a10da",
781 | "timestamp": "2013-02-09T06:05:04Z",
782 | "quantity": 856,
783 | "unitCost": 9928.49,
784 | "totalCost": 3502.45
785 | },
786 | {
787 | "purchaseId": "5ad8b5f9-aaee-428e-aa11-3c1991e6d703",
788 | "productId": "2be5b024-2c96-4f29-912c-c6f36353f799",
789 | "timestamp": "2000-01-23T11:04:04Z",
790 | "quantity": 879,
791 | "unitCost": 4230.1,
792 | "totalCost": 7286.78
793 | },
794 | {
795 | "purchaseId": "6253b4e0-5089-4daa-ad09-6424516ff613",
796 | "productId": "fcf2e432-62a3-4b6f-a34d-36e42a12272e",
797 | "timestamp": "2004-07-08T16:20:29Z",
798 | "quantity": 762,
799 | "unitCost": 1296.53,
800 | "totalCost": 7583.95
801 | }
802 | ]
803 |
--------------------------------------------------------------------------------