From 7ae9cca86fe377b66eb6c84ec82d215002130158 Mon Sep 17 00:00:00 2001 From: minhtrannhat Date: Mon, 22 Jul 2024 12:18:06 -0400 Subject: [PATCH] Feat: All queries should work --- .idea/dataSources.xml | 4 +- .idea/misc.xml | 2 +- .idea/remote-targets.xml | 17 +++ src/main/sql/main.sql | 291 +++++++++++++++++++++++++++++++-------- 4 files changed, 251 insertions(+), 63 deletions(-) create mode 100644 .idea/remote-targets.xml diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml index 24fa632..424782f 100644 --- a/.idea/dataSources.xml +++ b/.idea/dataSources.xml @@ -1,11 +1,11 @@ - + mysql.8 true com.mysql.cj.jdbc.Driver - jdbc:mysql://localhost:32768 + jdbc:mysql://localhost:32770 diff --git a/.idea/misc.xml b/.idea/misc.xml index fdc35ea..532a8e6 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/.idea/remote-targets.xml b/.idea/remote-targets.xml new file mode 100644 index 0000000..7d73213 --- /dev/null +++ b/.idea/remote-targets.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/sql/main.sql b/src/main/sql/main.sql index 1f0400e..2870897 100644 --- a/src/main/sql/main.sql +++ b/src/main/sql/main.sql @@ -44,23 +44,26 @@ CREATE TABLE Products ); -- Create Sales table +-- +-- If DeliverToCity is NOT NULL, then this sale needs to be delivered CREATE TABLE Sales ( - SaleID INT PRIMARY KEY AUTO_INCREMENT, - SaleDate DATE NOT NULL, - TotalAmount DECIMAL(10, 2) NOT NULL, - ClientID INT, - DeliveryFee DECIMAL(10, 2), + SaleID INT PRIMARY KEY AUTO_INCREMENT, + SaleDate DATE NOT NULL, + TotalAmount DECIMAL(10, 2) DEFAULT 0, + ClientID INT, + DeliverToCity VARCHAR(50), + DeliveryFee DECIMAL(10, 2) DEFAULT 0, FOREIGN KEY (ClientID) REFERENCES Member (MemberID) ); -- Create SalesItems table +-- CREATE TABLE SalesItems ( SaleItemID INT PRIMARY KEY AUTO_INCREMENT, SaleID INT, ProductID INT, - Quantity INT, FOREIGN KEY (SaleID) REFERENCES Sales (SaleID), FOREIGN KEY (ProductID) REFERENCES Products (ProductID) ); @@ -88,6 +91,38 @@ CREATE TABLE Expenses -- Add constraints and triggers +-- Ensure Product is in stock before the Sale +CREATE TRIGGER chk_product_in_stock + BEFORE INSERT + ON SalesItems + FOR EACH ROW +BEGIN + DECLARE product_count INT; + DECLARE is_in_stock BOOLEAN; + + -- Check if product exists + SELECT COUNT(*) + INTO product_count + FROM Products + WHERE ProductID = NEW.ProductID; + + IF product_count = 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product does not exist. Failed to create SalesItems'; + ELSE + -- If product exists, check if it's in stock + SELECT InStock + INTO is_in_stock + FROM Products + WHERE ProductID = NEW.ProductID; + + IF NOT is_in_stock THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Product is not in stock. Failed to create SalesItems'; + END IF; + END IF; +END; + -- Ensure only presidents can approve expenses CREATE TRIGGER chk_president_approval_insert BEFORE INSERT @@ -104,11 +139,10 @@ BEGIN IF job_title != 'President' THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'ApprovedByID must refer to an employee with the job title President'; -END IF; + END IF; END; -- Trigger to update product stock status when sold -DELIMITER // CREATE TRIGGER update_product_stock AFTER INSERT ON SalesItems @@ -116,34 +150,70 @@ CREATE TRIGGER update_product_stock BEGIN UPDATE Products SET InStock = FALSE WHERE ProductID = NEW.ProductID; END; -// -DELIMITER ; --- Trigger to calculate and update delivery fee -DELIMITER // -CREATE TRIGGER calculate_delivery_fee +-- Create sale only for registered client +CREATE TRIGGER check_client_before_sale BEFORE INSERT ON Sales FOR EACH ROW BEGIN - DECLARE total_weight DECIMAL(10, 2); + DECLARE client_exists INT; - SELECT SUM(p.Weight * si.Quantity) - INTO total_weight + -- Check if the ClientID exists in the Member table + SELECT COUNT(*) + INTO client_exists + FROM Member + WHERE MemberID = NEW.ClientID; + + -- If the client doesn't exist, raise an error + IF client_exists = 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = 'Error: Cannot create sale for unregistered client.'; + END IF; +END; + +-- Calculate the delivery fees +CREATE TRIGGER calculate_delivery_fee_and_total + AFTER INSERT + ON SalesItems + FOR EACH ROW +BEGIN + DECLARE total_weight DECIMAL(10, 2); + DECLARE total_amount DECIMAL(10, 2); + DECLARE delivery_city VARCHAR(50); + DECLARE delivery_fee DECIMAL(10, 2); + + -- Calculate total weight and total amount of all items in the sale + SELECT SUM(p.Weight), SUM(p.SellingPrice), s.DeliverToCity + INTO total_weight, total_amount, delivery_city FROM SalesItems si JOIN Products p ON si.ProductID = p.ProductID - WHERE si.SaleID = NEW.SaleID; + JOIN Sales s ON si.SaleID = s.SaleID + WHERE si.SaleID = NEW.SaleID + GROUP BY si.SaleID; - SET NEW.DeliveryFee = total_weight * 6.50; - SET NEW.TotalAmount = NEW.TotalAmount + NEW.DeliveryFee; + IF delivery_city IS NOT NULL THEN + -- Calculate delivery fee + SET delivery_fee = total_weight * 6.50; + -- Update total amount to include delivery fee + SET total_amount = total_amount + delivery_fee; + ELSE + -- If not delivered, ensure DeliveryFee is 0 + SET delivery_fee = 0; + END IF; + + -- Update the Sales record + UPDATE Sales + SET TotalAmount = total_amount, + DeliveryFee = delivery_fee + WHERE SaleID = NEW.SaleID; END; -// -DELIMITER ; -- Insert data into Member table INSERT INTO Member (FirstName, LastName, MiddleInitial, DateOfBirth, Address, Gender, PhoneNumber, EmailAddress, SocialSecurityNumber, MembershipStartDate, MemberType) -VALUES ('John', 'Doe', 'A', '1980-05-15', '123 Main St, Anytown, USA', 'Male', '555-123-4567', 'john.doe@email.com', +VALUES ('John', 'Doe', 'A', '1980-05-15', '123 Main St, Anytown, USA', 'Male', '555-123-4567', + 'john.doe@email.com', '123-45-6789', '2022-01-01', 'Donor'), ('Jane', 'Smith', 'B', '1985-08-22', '456 Elm St, Somewhere, USA', 'Female', '555-987-6543', 'jane.smith@email.com', '987-65-4321', '2022-02-15', 'Client'), @@ -152,32 +222,50 @@ VALUES ('John', 'Doe', 'A', '1980-05-15', '123 Main St, Anytown, USA', 'Male', ' ('Darton', 'Johnson', 'C', '1972-11-11', '789 Oak St, Nowhere, USA', 'Male', '561-216-8835', 'darton.johnson@email.com', '148-46-2580', '2020-03-01', 'Employee'), ('Alice', 'Williams', 'D', '1990-11-30', '321 Pine St, Everywhere, USA', 'Female', '555-369-2580', - 'alice.williams@email.com', '369-25-8014', '2022-04-15', 'Donor'); + 'alice.williams@email.com', '369-25-8014', '2022-04-15', 'Donor'), + ('David', 'Williams', 'D', '1945-12-30', '311 Pine St, Everywhere, USA', 'Male', '565-109-2888', + 'david.williams@email.com', '379-25-8014', '2022-04-15', 'Client'), + ('Brenda', 'Williams', 'D', '1930-01-30', '331 Pine St, Everywhere, USA', 'Female', '556-201-1370', + 'brenda.williams@email.com', '269-25-8014', '2022-04-15', 'Client'); -- Insert data into Donations table INSERT INTO Donations (DonorID, DonationDate, DonationType, DonationAmount) VALUES (1, '2023-01-15', 'Money', 500.00), - (4, '2023-02-20', 'Products', NULL), + (2, '2023-02-20', 'Products', NULL), (1, '2023-03-10', 'Money', 250.00), - (4, '2023-04-05', 'Products', NULL); + (2, '2023-04-05', 'Products', NULL); -- Insert data into Products table INSERT INTO Products (Description, DonationDate, SellingPrice, Weight, InStock, DonationID) VALUES ('Laptop', '2023-02-20', 300.00, 2.5, TRUE, 2), ('Chair', '2023-02-20', 50.00, 5.0, TRUE, 2), ('Bookshelf', '2023-04-05', 100.00, 20.0, TRUE, 4), - ('Microwave', '2023-04-05', 75.00, 10.0, TRUE, 4); + ('Microwave', '2023-04-05', 75.00, 10.0, TRUE, 4), + ('TV', '2023-04-05', 55.00, 10.0, TRUE, 4), + ('Table', '2023-04-05', 50.00, 10.0, TRUE, 4), + ('OLED TV', '2021-04-05', 57.00, 10.0, TRUE, 4), + ('Table (Broken)', '2021-04-05', 58.00, 10.0, TRUE, 4); -- Insert data into Sales table -INSERT INTO Sales (SaleDate, TotalAmount, ClientID, DeliveryFee) -VALUES ('2023-05-01', 350.00, 2, NULL), - ('2023-05-15', 100.00, 2, NULL); +INSERT INTO Sales (SaleDate, ClientID, DeliverToCity) +VALUES ('2024-06-02', 2, 'Brossard'), + ('2024-06-15', 3, 'Saint Lambert'), + ('2023-07-15', 3, NULL), + ('2023-01-15', 6, NULL), + ('2023-01-15', 7, NULL), + ('2023-07-15', 6, NULL), + ('2023-07-15', 7, NULL); -- Insert data into SalesItems table -INSERT INTO SalesItems (SaleID, ProductID, Quantity) -VALUES (1, 1, 1), - (1, 2, 1), - (2, 3, 1); +INSERT INTO SalesItems (SaleID, ProductID) +VALUES (1, 1), + (1, 2), + (2, 3), + (3, 4), + (4, 5), + (5, 6), + (6, 7), + (7, 8); -- Insert data into Employees table INSERT INTO Employees (EmployeeID, JobTitle, Salary) @@ -186,36 +274,119 @@ VALUES (3, 'President', 100000.00), -- Insert data into Expenses table INSERT INTO Expenses (ApprovedByID, PaymentDate, Amount, ExpenseType, Description) -VALUES (3, '2023-06-01', 2000.00, 'Rent', 'Monthly office rent'), - (3, '2023-06-05', 500.00, 'Bill Payment', 'Electricity bill'), - (3, '2023-06-10', 1000.00, 'Charity Payment', 'Donation to local food bank'); +VALUES (3, '2024-01-02', 2000.00, 'Rent', 'Monthly office rent'), + (3, '2024-06-05', 500.00, 'Bill Payment', 'Electricity bill'), + (3, '2024-06-10', 1000.00, 'Charity Payment', 'Donation to local food bank'); -- Part 2 Question 1 # List the details of all the clients that are not volunteer employees and donors as well. # Details include client ID, first-name, last-name, middle-initial, date-of-birth, address, # gender, phone-number, email-address, social-security-number, job-title, and the start date # of membership -SELECT - m.MemberID AS ClientID, - m.FirstName, - m.LastName, - m.MiddleInitial, - m.DateOfBirth, - m.Address, - m.Gender, - m.PhoneNumber, - m.EmailAddress, - m.SocialSecurityNumber, - e.JobTitle, - m.MembershipStartDate -FROM - Member m - LEFT JOIN Employees e ON m.MemberID = e.EmployeeID -WHERE - m.MemberType = 'Client' - AND m.MemberID IN ( - SELECT DISTINCT DonorID - FROM Donations - WHERE DonorID IS NOT NULL -) - AND (e.EmployeeID IS NULL OR e.Salary > 0); +SELECT m.MemberID AS ClientID, + m.FirstName, + m.LastName, + m.MiddleInitial, + m.DateOfBirth, + m.Address, + m.Gender, + m.PhoneNumber, + m.EmailAddress, + m.SocialSecurityNumber, + e.JobTitle, + m.MembershipStartDate +FROM Member m + LEFT JOIN Employees e ON m.MemberID = e.EmployeeID +WHERE m.MemberType = 'Client' + OR m.MemberID IN (SELECT DISTINCT DonorID + FROM Donations + WHERE DonorID IS NOT NULL) + AND (e.EmployeeID IS NULL OR e.Salary > 0); + +-- Part 2: Question 2 +# List the details of all the expenses that are paid in the months of Jan to June of 2024. +# Details includes expense ID, first name and last name of the president who approved the +# expense, the date of the payment of the expense, the amount of the expense, the type of +# the expense, and the description of the expense +SELECT Expenses.ExpenseID, + Member.FirstName AS PresidentFirstName, + Member.LastName AS PresidentLastName, + Expenses.PaymentDate, + Expenses.Amount, + Expenses.ExpenseType, + Expenses.Description +FROM Expenses + INNER JOIN Member on Expenses.ApprovedByID = MemberID +WHERE Expenses.PaymentDate BETWEEN '2024-01-01' AND '2024-06-30'; + + +-- Part 2 Question 3 +# Give a report of the sales that have been delivered to the cities of Brossard and Saint +# Lambert in June 2024. Details include sale ID, date of the sale, client’s first name and last +# name, product description, price and weight of the product. Results should be displayed +# in ascending order by saleID, then by first name, then by last name, then by weight of the +# product. +SELECT s.SaleID, + s.SaleDate, + m.FirstName AS ClientFirstName, + m.LastName AS ClientLastName, + p.Description AS ProductDescription, + p.SellingPrice AS ProductPrice, + p.Weight AS ProductWeight +FROM Sales s + JOIN + Member m ON s.ClientID = m.MemberID + JOIN + SalesItems si ON s.SaleID = si.SaleID + JOIN + Products p ON si.ProductID = p.ProductID +WHERE s.SaleDate BETWEEN '2024-06-01' AND '2024-06-30' + AND (s.DeliverToCity = 'Brossard' + OR s.DeliverToCity = 'Saint Lambert') + AND s.DeliveryFee > 0 +ORDER BY s.SaleID ASC, + m.FirstName ASC, + m.LastName ASC, + p.Weight ASC; + +-- Question 2 part 4 +# Give a monthly report of the sales that have been picked up by the buyers in 2023. For +# every month of 2023, details include number of products sold, , average of price of all +# products sold, and average weight of the products sold. Results should be displayed in +# descending order by number of products sold +SELECT DATE_FORMAT(s.SaleDate, '%Y-%m') AS Month, + COUNT(si.ProductID) AS ProductsSold, + AVG(p.SellingPrice) AS AveragePrice, + AVG(p.Weight) AS AverageWeight +FROM Sales s + JOIN + SalesItems si ON s.SaleID = si.SaleID + JOIN + Products p ON si.ProductID = p.ProductID +WHERE YEAR(s.SaleDate) = 2023 + AND s.DeliveryFee = 0 +GROUP BY DATE_FORMAT(s.SaleDate, '%Y-%m') +ORDER BY ProductsSold DESC; + +-- Part 2 Question 5 +# For every client who is registered in the system and did not make any purchase since +# January 1st 2024, give a report of the sales she/he has done since her/his membership. The +# report should include the client’s first and last name, the date of the first sale she/he has +# made, the date of the last sale she/he has made, the total amount of sales she/he has made. +# The results should be displayed in decreasing order by total amount of sales. +SELECT m.FirstName, + m.LastName, + MIN(s.SaleDate) AS FirstSaleDate, + MAX(s.SaleDate) AS LastSaleDate, + SUM(s.TotalAmount) AS TotalSalesAmount +FROM Member m + LEFT JOIN + Sales s ON m.MemberID = s.ClientID +WHERE m.MemberType = 'Client' + AND m.MemberID NOT IN (SELECT DISTINCT ClientID + FROM Sales + WHERE SaleDate >= '2024-01-01') +GROUP BY m.MemberID +HAVING + COUNT(s.SaleID) > 0 +ORDER BY TotalSalesAmount DESC; \ No newline at end of file