Index: database/Advanced Database Developement/Triggers/Automatic calculation of store rating from order reviews.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Automatic calculation of store rating from order reviews.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Automatic calculation of store rating from order reviews.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,55 @@
+CREATE OR REPLACE FUNCTION update_store_rating()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+DECLARE
+    v_order_num INT;
+    v_store_id INT;
+BEGIN
+    -- Determine which order was affected
+    IF TG_OP = 'DELETE' THEN
+        v_order_num := OLD.order_num;
+    ELSE
+        v_order_num := NEW.order_num;
+    END IF;
+
+    -- Find the store associated with the order
+    SELECT fs.store_id
+    INTO v_store_id
+    FROM for_store fs
+    JOIN "order" o
+        ON o.order_num = v_order_num
+    WHERE fs.request_num IS NOT NULL
+    LIMIT 1;
+
+    -- Update the store rating
+    IF v_store_id IS NOT NULL THEN
+        UPDATE store s
+        SET rating = (
+            SELECT COALESCE(AVG(r.rating), 0)
+            FROM review r
+            JOIN "order" o
+                ON o.order_num = r.order_num
+            -- The exact relationship between orders and stores
+            -- should be used here according to the final schema
+            WHERE o.order_num IN (
+                SELECT i.order_num
+                FROM includes i
+                JOIN sells sl
+                    ON sl.code = i.code
+                WHERE sl.store_id = v_store_id
+            )
+        )
+        WHERE s.store_id = v_store_id;
+    END IF;
+
+    RETURN NULL;
+END;
+$$;
+
+
+CREATE TRIGGER trg_update_store_rating
+AFTER INSERT OR UPDATE OR DELETE
+ON review
+FOR EACH ROW
+EXECUTE FUNCTION update_store_rating();
Index: database/Advanced Database Developement/Triggers/Automatic deletion of product changes when the product is deleted.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Automatic deletion of product changes when the product is deleted.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Automatic deletion of product changes when the product is deleted.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,19 @@
+CREATE OR REPLACE FUNCTION delete_product_changes()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+BEGIN
+    -- Delete all changes associated with the product
+    DELETE FROM change
+    WHERE product_code = OLD.code;
+
+    RETURN OLD;
+END;
+$$;
+
+
+CREATE TRIGGER trg_delete_product_changes
+BEFORE DELETE
+ON product
+FOR EACH ROW
+EXECUTE FUNCTION delete_product_changes();
Index: database/Advanced Database Developement/Triggers/Automatic setting of the last modified date for orders.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Automatic setting of the last modified date for orders.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Automatic setting of the last modified date for orders.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,15 @@
+CREATE OR REPLACE FUNCTION update_order_modified_date()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+BEGIN
+    NEW.last_modified_date := CURRENT_TIMESTAMP;
+    RETURN NEW;
+END;
+$$;
+
+CREATE TRIGGER trg_update_order_modified_date
+BEFORE UPDATE
+ON "order"
+FOR EACH ROW
+EXECUTE FUNCTION update_order_modified_date();
Index: database/Advanced Database Developement/Triggers/Automatic update of employee-store statistics after an employee is hired.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Automatic update of employee-store statistics after an employee is hired.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Automatic update of employee-store statistics after an employee is hired.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,30 @@
+CREATE OR REPLACE FUNCTION initialize_employee_statistics()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+BEGIN
+    /*
+    * The employee is created first.
+    * Work statistics can be initialized when
+    * the employee is assigned to a store.
+    * The actual store assignment should be handled
+    * through works_in_store. */
+    INSERT INTO worked (
+        employee_id,
+        total_working_hours,
+        total_wage
+    )
+    VALUES (
+        NEW.id,
+        0,
+        0
+    );
+    RETURN NEW;
+END;
+$$;
+
+CREATE TRIGGER trg_initialize_employee_statistics
+AFTER INSERT
+ON employees
+FOR EACH ROW
+EXECUTE FUNCTION initialize_employee_statistics();
Index: database/Advanced Database Developement/Triggers/Automatic update of product availability after an order.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Automatic update of product availability after an order.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Automatic update of product availability after an order.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,47 @@
+CREATE OR REPLACE FUNCTION update_product_availability()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+BEGIN
+    -- When a product is newly added to an order,
+    -- decrease the available quantity.
+    IF TG_OP = 'INSERT' THEN
+
+        UPDATE sells
+        SET quantity = quantity - (
+            SELECT o.quantity
+            FROM "order" o
+            WHERE o.order_num = NEW.order_num
+        )
+        WHERE code = NEW.code;
+
+    -- If the product/order entry is modified,
+    -- restore the old quantity and subtract the new quantity.
+    ELSIF TG_OP = 'UPDATE' THEN
+
+        UPDATE sells
+        SET quantity = quantity
+            + (
+                SELECT o.quantity
+                FROM "order" o
+                WHERE o.order_num = OLD.order_num
+            )
+            - (
+                SELECT o.quantity
+                FROM "order" o
+                WHERE o.order_num = NEW.order_num
+            )
+        WHERE code = NEW.code;
+
+    END IF;
+
+    RETURN NULL;
+END;
+$$;
+
+
+CREATE TRIGGER trg_update_product_availability
+AFTER INSERT OR UPDATE
+ON includes
+FOR EACH ROW
+EXECUTE FUNCTION update_product_availability();
Index: database/Advanced Database Developement/Triggers/Prevention of deleting stores with existing orders or reports.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Prevention of deleting stores with existing orders or reports.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Prevention of deleting stores with existing orders or reports.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,22 @@
+CREATE OR REPLACE FUNCTION prevent_store_deletion()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+BEGIN
+    -- Check whether the store has existing reports
+    IF EXISTS ( SELECT 1 FROM report WHERE store_id = OLD.store_id ) THEN
+        RAISE EXCEPTION 'Store % cannot be deleted because it has existing reports.', OLD.store_id;
+    END IF;
+    -- Check whether the store has products associated with it
+    IF EXISTS ( SELECT 1 FROM sells WHERE store_id = OLD.store_id ) THEN
+        RAISE EXCEPTION 'Store % cannot be deleted because it has existing product records.', OLD.store_id;
+    END IF;
+    RETURN OLD;
+END;
+$$;
+
+CREATE TRIGGER trg_prevent_store_deletion
+BEFORE DELETE
+ON store
+FOR EACH ROW
+EXECUTE FUNCTION prevent_store_deletion();
Index: database/Advanced Database Developement/Triggers/Prevention of ordering unavailable products.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Prevention of ordering unavailable products.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Prevention of ordering unavailable products.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,46 @@
+CREATE OR REPLACE FUNCTION check_product_availability()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+DECLARE
+    v_available_quantity INT;
+    v_order_quantity INT;
+BEGIN
+    -- Get the quantity requested by the order
+    SELECT quantity
+    INTO v_order_quantity
+    FROM "order"
+    WHERE order_num = NEW.order_num;
+
+    -- Get the currently available quantity of the product
+    SELECT quantity
+    INTO v_available_quantity
+    FROM sells
+    WHERE code = NEW.code;
+
+    -- Check whether the product exists
+    IF v_available_quantity IS NULL THEN
+        RAISE EXCEPTION
+            'Product % is not available in any store.',
+            NEW.code;
+    END IF;
+
+    -- Check whether there is enough stock
+    IF v_order_quantity > v_available_quantity THEN
+        RAISE EXCEPTION
+            'Insufficient stock for product %. Available: %, requested: %.',
+            NEW.code,
+            v_available_quantity,
+            v_order_quantity;
+    END IF;
+
+    RETURN NEW;
+END;
+$$;
+
+
+CREATE TRIGGER trg_check_product_availability
+BEFORE INSERT OR UPDATE
+ON includes
+FOR EACH ROW
+EXECUTE FUNCTION check_product_availability();
Index: database/Advanced Database Developement/Triggers/Validation of employee authorization before making a product change.txt
===================================================================
--- database/Advanced Database Developement/Triggers/Validation of employee authorization before making a product change.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Triggers/Validation of employee authorization before making a product change.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,29 @@
+CREATE OR REPLACE FUNCTION validate_employee_authorization()
+RETURNS TRIGGER
+LANGUAGE plpgsql
+AS $$
+DECLARE v_authorisation TEXT;
+BEGIN
+    -- Get the employee's authorization
+    SELECT authorisation
+    INTO v_authorisation
+    FROM personal
+    WHERE id = NEW.id;
+    -- Check whether the employee exists
+    IF v_authorisation IS NULL THEN
+        RAISE EXCEPTION 'Employee % does not have valid authorization.', NEW.id;
+    END IF;
+    -- Check whether the authorization matches
+    IF NEW.authorisation IS DISTINCT FROM v_authorisation THEN
+        RAISE EXCEPTION 'Employee % is not authorized to make this product change.', NEW.id;
+    END IF;
+    RETURN NEW;
+END;
+$$;
+
+
+CREATE TRIGGER trg_validate_employee_authorization
+BEFORE INSERT OR UPDATE
+ON makes_change
+FOR EACH ROW
+EXECUTE FUNCTION validate_employee_authorization();
Index: database/Advanced Database Developement/Views/Complete overview of customer orders.txt
===================================================================
--- database/Advanced Database Developement/Views/Complete overview of customer orders.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Complete overview of customer orders.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,23 @@
+CREATE OR REPLACE VIEW vw_customer_order_overview AS
+SELECT
+    o.order_num,
+    o.quantity,
+    o.status,
+    o.last_modified_date,
+    o.payment_method,
+    o.discount,
+    c.client_id,
+    c.first_name,
+    c.last_name,
+    c.email,
+    p.code AS product_code,
+    p.description AS product_description,
+    p.price FROM "order" o
+JOIN makes_order mo
+    ON mo.order_num = o.order_num
+JOIN client c
+    ON c.client_id = mo.client_id
+JOIN includes i
+    ON i.order_num = o.order_num
+JOIN product p
+    ON p.code = i.code;
Index: database/Advanced Database Developement/Views/Complete overview of products and stores.txt
===================================================================
--- database/Advanced Database Developement/Views/Complete overview of products and stores.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Complete overview of products and stores.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,19 @@
+CREATE OR REPLACE VIEW vw_product_store_overview AS
+SELECT
+    p.code AS product_code,
+    p.description,
+    p.price,
+    p.availability,
+    p.weight,
+    p.approx_production_time,
+    s.store_id,
+    s.name AS store_name,
+    s.physical_address,
+    s.rating,
+    sl.quantity,
+    sl.discount
+FROM product p
+JOIN sells sl
+    ON sl.code = p.code
+JOIN store s
+   ON s.store_id = sl.store_id;
Index: database/Advanced Database Developement/Views/Customer order history.txt
===================================================================
--- database/Advanced Database Developement/Views/Customer order history.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Customer order history.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,27 @@
+CREATE OR REPLACE VIEW vw_customer_order_history AS
+SELECT
+    c.client_id,
+    c.first_name,
+    c.last_name,
+    c.email,
+
+    o.order_num,
+    o.quantity,
+    o.status,
+    o.last_modified_date,
+    o.payment_method,
+    o.discount,
+
+    p.code AS product_code,
+    p.description AS product_description,
+    p.price
+
+FROM client c
+JOIN makes_order mo
+    ON mo.client_id = c.client_id
+JOIN "order" o
+    ON o.order_num = mo.order_num
+JOIN includes i
+    ON i.order_num = o.order_num
+JOIN product p
+    ON p.code = i.code;
Index: database/Advanced Database Developement/Views/Customer request and response overview.txt
===================================================================
--- database/Advanced Database Developement/Views/Customer request and response overview.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Customer request and response overview.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,26 @@
+CREATE OR REPLACE VIEW vw_customer_request_response AS
+SELECT
+    r.request_num,
+    r.date_and_time,
+    r.problem,
+    r.notes_of_communication,
+    r.customer_satisfaction,
+
+    c.client_id,
+    c.first_name AS client_first_name,
+    c.last_name AS client_last_name,
+    c.email AS client_email,
+
+    p.id AS employee_id,
+    p.first_name AS employee_first_name,
+    p.last_name AS employee_last_name
+
+FROM request r
+JOIN make_request mr
+    ON mr.request_num = r.request_num
+JOIN client c
+    ON c.client_id = mr.client_id
+LEFT JOIN answers a
+    ON a.request_num = r.request_num
+LEFT JOIN personal p
+    ON p.id = a.id;
Index: database/Advanced Database Developement/Views/Employee workload and salary report.txt
===================================================================
--- database/Advanced Database Developement/Views/Employee workload and salary report.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Employee workload and salary report.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,27 @@
+CREATE OR REPLACE VIEW vw_employee_workload_salary AS
+SELECT
+    e.id AS employee_id,
+    p.first_name,
+    p.last_name,
+    p.email,
+    e.date_of_hire,
+
+    s.store_id,
+    s.name AS store_name,
+
+    w.week,
+    w.total_week,
+    w.working_hours,
+    w.wage,
+    w.pay_method
+
+FROM employees e
+JOIN personal p
+    ON p.id = e.id
+JOIN works_in_store wis
+    ON wis.id = e.id
+JOIN store s
+    ON s.store_id = wis.store_id
+LEFT JOIN worked w
+    ON w.id = e.id
+    AND w.store_id = wis.store_id;
Index: database/Advanced Database Developement/Views/Monthly sales and profit per store.txt
===================================================================
--- database/Advanced Database Developement/Views/Monthly sales and profit per store.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Monthly sales and profit per store.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,18 @@
+CREATE OR REPLACE VIEW vw_monthly_sales_profit AS
+SELECT
+    s.store_id,
+    s.name AS store_name,
+    r.date,
+    r.month_and_year,
+    r.profit,
+    r.overall_profit,
+    ed.monthly_profit,
+    ed.sales,
+    ed.damages
+
+FROM store s
+JOIN report r
+    ON r.store_id = s.store_id
+LEFT JOIN exchanges_data ed
+    ON ed.store_id = r.store_id
+    AND ed.date = r.date;
Index: database/Advanced Database Developement/Views/Store inventory overview.txt
===================================================================
--- database/Advanced Database Developement/Views/Store inventory overview.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Store inventory overview.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,19 @@
+CREATE OR REPLACE VIEW vw_store_inventory AS
+SELECT
+    s.store_id,
+    s.name AS store_name,
+
+    p.code AS product_code,
+    p.description,
+    p.price,
+    p.availability,
+    p.approx_production_time,
+
+    sl.quantity,
+    sl.discount
+
+FROM store s
+JOIN sells sl
+    ON sl.store_id = s.store_id
+JOIN product p
+    ON p.code = sl.code;
Index: database/Advanced Database Developement/Views/Store performance overview.txt
===================================================================
--- database/Advanced Database Developement/Views/Store performance overview.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
+++ database/Advanced Database Developement/Views/Store performance overview.txt	(revision 62b296460f935ff5cc47a75f6567f97df5a244a7)
@@ -0,0 +1,27 @@
+CREATE OR REPLACE VIEW vw_store_performance AS
+SELECT
+    s.store_id,
+    s.name AS store_name,
+    s.date_of_founding,
+    s.rating,
+
+    COUNT(DISTINCT r.date) AS number_of_reports,
+    COALESCE(SUM(r.profit), 0) AS total_reported_profit,
+    COALESCE(MAX(r.overall_profit), 0) AS overall_profit,
+
+    COALESCE(SUM(ed.sales), 0) AS total_sales,
+    COALESCE(SUM(ed.damages), 0) AS total_damages,
+    COALESCE(SUM(ed.monthly_profit), 0) AS total_monthly_profit
+
+FROM store s
+LEFT JOIN report r
+    ON r.store_id = s.store_id
+LEFT JOIN exchanges_data ed
+    ON ed.store_id = r.store_id
+    AND ed.date = r.date
+
+GROUP BY
+    s.store_id,
+    s.name,
+    s.date_of_founding,
+    s.rating;
