Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 19

--DROP TABLE WALLET_LANDLORD

CREATE TABLE WALLET_LANDLORD


(
ID_w NVARCHAR(10) PRIMARY KEY,
Balance MONEY
)
-----

--DROP TABLE LANDLORD

CREATE TABLE LANDLORD


(
ID_l NVARCHAR(10) PRIMARY KEY,
Name NVARCHAR(50) NOT NULL,
PhoneNumber NVARCHAR(10) NOT NULL,
Birthday DATE NOT NULL,
ID_w NVARCHAR(10) NOT NULL,

FOREIGN KEY (ID_w) REFERENCES dbo.WALLET_LANDLORD(ID_w),

CONSTRAINT LL_CheckAge CHECK (DATEDIFF(year, Birthday, GETDATE()) >= 18),


CONSTRAINT LL_CheckPhoneNumber CHECK (PhoneNumber LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
);

---------

--DROP TABLE LOGIN_ACCOUNT

CREATE TABLE LOGIN_ACCOUNT (


ID_l NVARCHAR(10) ,
UserName NVARCHAR(255) PRIMARY KEY,
Password NVARCHAR(255) NOT NULL,

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


);
---------

--DROP TABLE TENANT

CREATE TABLE TENANT (


ID_t NVARCHAR(10) PRIMARY KEY,
Name NVARCHAR(50) NOT NULL,
PhoneNumber NVARCHAR(10) NOT NULL,
Job NVARCHAR(50),
Birthday DATE,
Balance MONEY NOT NULL,
ID_l NVARCHAR(10) NULL,

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


CONSTRAINT TN_CheckAge CHECK (DATEDIFF(year, Birthday, GETDATE()) >= 18),
CONSTRAINT TN_CheckPhoneNumber CHECK (PhoneNumber LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),
);
---------

--DROP TABLE BROKERAGECOMPANY

CREATE TABLE BROKERAGECOMPANY (


TaxCode NVARCHAR(10) PRIMARY KEY,
Name NVARCHAR(100) NOT NULL,
Address NVARCHAR(100) NOT NULL,
Wallet MONEY NOT NULL,
BonusPrice MONEY NOT NULL,
PriceperMonth MONEY NOT NULL,

);
---------

--DROP TABLE ROOM

CREATE TABLE ROOM (


RoomNumber NVARCHAR(10) PRIMARY KEY,
Area INT NOT NULL,
Interior INT NOT NULL,
State BIT NOT NULL,
PriceperMonth MONEY,
ElectricityPrice MONEY NOT NULL,
WaterPrice MONEY NOT NULL,
ID_l NVARCHAR(10),

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


);
---------

--DROP TABLE HIRED

CREATE TABLE HIRED (


ID_l NVARCHAR(10),
TaxCode NVARCHAR(10),
DayEnd DATE NOT NULL,
DayStart DATE NOT NULL,

CONSTRAINT Check_DayStartEnd_HIRED CHECK (DayEnd > DayStart),

PRIMARY KEY (ID_l,TaxCode),


FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),
FOREIGN KEY (TaxCode) REFERENCES dbo.BROKERAGECOMPANY(TaxCode)
);
---------

--DROP TABLE RENT

CREATE TABLE RENT (


ID_t NVARCHAR(10),
RoomNumber NVARCHAR(10),
TaxCode NVARCHAR(10) NULL,
DayEnd DATE NOT NULL,
DayStart DATE NOT NULL,

CONSTRAINT Check_DayStartEnd_RENT CHECK ( DayEnd > DayStart),

PRIMARY KEY (ID_t,RoomNumber),


FOREIGN KEY (ID_t) REFERENCES dbo.TENANT(ID_t),
FOREIGN KEY (TaxCode) REFERENCES dbo.BROKERAGECOMPANY(TaxCode),
FOREIGN KEY (RoomNumber) REFERENCES dbo.ROOM(RoomNumber)
);
---------

--DROP TABLE CONTRACT

CREATE TABLE CONTRACT (


Code NVARCHAR(10) PRIMARY KEY,
DayStart DATE,
Price MONEY,
Period INT,
RoomNumber NVARCHAR(10) NOT NULL,
ID_t NVARCHAR(10) NOT NULL,

FOREIGN KEY (RoomNumber) REFERENCES dbo.ROOM(RoomNumber),


FOREIGN KEY (ID_t) REFERENCES dbo.TENANT(ID_t)
);

CREATE TABLE BILL (


Code NVARCHAR(10) PRIMARY KEY,
Price MONEY,
ElectricNumber FLOAT NOT NULL,
WaterNumber FLOAT NOT NULL,
Day DATE NULL,
ID_l NVARCHAR(10) NOT NULL,
RoomNumber NVARCHAR(10) NOT NULL,
ID_t NVARCHAR(10) NOT NULL,

FOREIGN KEY (ID_l) REFERENCES dbo.LANDLORD(ID_l),


FOREIGN KEY (RoomNumber) REFERENCES dbo.ROOM(RoomNumber),
FOREIGN KEY (ID_t) REFERENCES dbo.TENANT(ID_t)
);

--------------

----3.1 Quản lý ví tiền chung của Landlord


--insert
GO
CREATE PROCEDURE InsertWalletLandlord
@ID_w NVARCHAR(10),
@Balance MONEY
AS
BEGIN
BEGIN TRY
INSERT INTO WALLET_LANDLORD (ID_w, Balance)
VALUES (@ID_w, @Balance)

PRINT 'Đã thêm Wallet Landlord thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateWalletLandlord
@ID_w NVARCHAR(10),
@Balance MONEY
AS
BEGIN
BEGIN TRY
UPDATE WALLET_LANDLORD
SET Balance = @Balance
WHERE ID_w = @ID_w

PRINT 'Đã cập nhật Wallet Landlord thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteWalletLandlord
@ID_w NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM WALLET_LANDLORD
WHERE ID_w = @ID_w

PRINT 'Đã xóa Wallet Landlord thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

--------------3.1 Quản lý Tenant


--insert
GO
CREATE PROCEDURE InsertTenant
@ID_t NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Job NVARCHAR(50),
@Birthday DATE,
@Balance MONEY
AS
BEGIN
BEGIN TRY
-- Insert data
INSERT INTO TENANT (ID_t, Name, PhoneNumber, Job, Birthday, Balance)
VALUES (@ID_t, @Name, @PhoneNumber, @Job, @Birthday, @Balance)

PRINT 'Tenant inserted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateTenant
@ID_t NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Job NVARCHAR(50),
@Birthday DATE,
@Balance MONEY
AS
BEGIN
BEGIN TRY
-- Update data
UPDATE TENANT
SET Name = @Name,
PhoneNumber = @PhoneNumber,
Job = @Job,
Birthday = @Birthday,
Balance = @Balance
WHERE ID_t = @ID_t

PRINT 'Tenant updated successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteTenant
@ID_t NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Delete data
DELETE FROM TENANT
WHERE ID_t = @ID_t

PRINT 'Tenant deleted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--Tìm kiếm dựa vào ID_t
GO
CREATE FUNCTION FindTenantByID
(
@ID_t NVARCHAR(10)
)
RETURNS TABLE
AS
RETURN
(
SELECT *
FROM TENANT
WHERE ID_t = @ID_t
);
--trigger bắt lỗi khi insert/update/delete
GO
CREATE TRIGGER CheckTenant
ON TENANT
FOR INSERT, UPDATE, DELETE
AS
BEGIN
-- Kiểm tra tên của Tenant không được để trống
IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(Name) = '' OR Name IS NULL)
BEGIN
DECLARE @errMsg nvarchar(50)
SELECT @errMsg = N'Lỗi: Tên của Tenant không được để trống.'
RAISERROR(@errMsg, 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Tenant không được để trống


IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(PhoneNumber) = '' OR PhoneNumber IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Tenant không được để trống.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Tenant đã tồn tại (trong trường hợp INSERT hoặc UPDATE)
IF EXISTS (SELECT 1 FROM TENANT t INNER JOIN inserted i ON t.PhoneNumber = i.PhoneNumber WHERE i.ID_t IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Tenant đã tồn tại.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Tenant không được để trống (khi UPDATE)


IF EXISTS (SELECT 1 FROM inserted WHERE ID_t IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Tenant để chỉnh sửa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Tenant không được để trống (khi DELETE)


IF EXISTS (SELECT 1 FROM deleted WHERE ID_t IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Tenant để xóa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END
END

--------------------3.2 Quản lý Landlord


GO
CREATE PROCEDURE InsertLandlord
@ID_l NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Birthday DATE,
@ID_w NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Insert data
INSERT INTO LANDLORD (ID_l, Name, PhoneNumber, Birthday, ID_w)
VALUES (@ID_l, @Name, @PhoneNumber, @Birthday, @ID_w)

PRINT 'Landlord inserted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
GO
CREATE PROCEDURE UpdateLandlord
@ID_l NVARCHAR(10),
@Name NVARCHAR(50),
@PhoneNumber NVARCHAR(10),
@Birthday DATE,
@ID_w NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Update data
UPDATE LANDLORD
SET Name = @Name,
PhoneNumber = @PhoneNumber,
Birthday = @Birthday
WHERE ID_l = @ID_l

PRINT 'Landlord updated successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteLandlord
@ID_l NVARCHAR(10)
AS
BEGIN
BEGIN TRY
-- Delete data
DELETE FROM LANDLORD
WHERE ID_l = @ID_l

PRINT 'Landlord deleted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;

--Tìm kiếm dựa vào ID_l


GO
CREATE FUNCTION FindLandlordByID
(
@ID_l NVARCHAR(10)
)
RETURNS TABLE
AS
RETURN
(
SELECT *
FROM LANDLORD
WHERE ID_l = @ID_l
);
--trigger kiểm tra insert/update/delete
GO
CREATE TRIGGER CheckLandlord
ON LANDLORD
FOR INSERT, UPDATE, DELETE
AS
BEGIN
DECLARE @ID_l NVARCHAR(10), @UserName NVARCHAR(255), @Password NVARCHAR(255)

SELECT @ID_l = ID_l, @UserName = 'Landlord_' + ID_l, @Password = 'password' + ID_l -- Mặc định password là 'password'
FROM inserted

-- Thêm tài khoản đăng nhập vào bảng LOGIN_ACCOUNT


INSERT INTO LOGIN_ACCOUNT (ID_l, UserName, Password)
VALUES (@ID_l, @UserName, @Password)

-- Kiểm tra tên của Landlord không được để trống


IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(Name) = '' OR Name IS NULL)
BEGIN
DECLARE @errMsg nvarchar(50)
SELECT @errMsg = N'Lỗi: Tên của Landlord không được để trống.'
RAISERROR(@errMsg, 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Landlord không được để trống


IF EXISTS (SELECT 1 FROM inserted WHERE TRIM(PhoneNumber) = '' OR PhoneNumber IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Landlord không được để trống.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra số điện thoại của Landlord đã tồn tại (trong trường hợp INSERT hoặc UPDATE)
IF EXISTS (SELECT 1 FROM LANDLORD l INNER JOIN inserted i ON l.PhoneNumber = i.PhoneNumber WHERE i.ID_l IS NULL)
BEGIN
RAISERROR(N'Số điện thoại của Landlord đã tồn tại.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Landlord không được để trống (khi UPDATE)


IF EXISTS (SELECT 1 FROM inserted WHERE ID_l IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Landlord để chỉnh sửa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END

-- Kiểm tra ID của Landlord không được để trống (khi DELETE)


IF EXISTS (SELECT 1 FROM deleted WHERE ID_l IS NULL)
BEGIN
RAISERROR(N'Nhập ID của Landlord để xóa.', 16, 1)
ROLLBACK TRANSACTION
RETURN
END
END

--3.3 Quản lý company


--insert
GO
CREATE PROCEDURE InsertCompany
@TaxCode NVARCHAR(10),
@Name NVARCHAR(100),
@Address NVARCHAR(100),
@Wallet MONEY,
@BonusPrice MONEY,
@PriceperMonth MONEY
AS
BEGIN
BEGIN TRY
INSERT INTO BROKERAGECOMPANY (TaxCode, Name, Address, Wallet, BonusPrice, PriceperMonth)
VALUES (@TaxCode, @Name, @Address, @Wallet, @BonusPrice, @PriceperMonth)

PRINT 'Company inserted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateCompany
@TaxCode NVARCHAR(10),
@Name NVARCHAR(100),
@Address NVARCHAR(100),
@Wallet MONEY,
@BonusPrice MONEY,
@PriceperMonth MONEY
AS
BEGIN
BEGIN TRY
UPDATE BROKERAGECOMPANY
SET Name = @Name,
Address = @Address,
Wallet = @Wallet,
BonusPrice = @BonusPrice,
PriceperMonth = @PriceperMonth
WHERE TaxCode = @TaxCode

PRINT 'Company updated successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteCompany
@TaxCode NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM BROKERAGECOMPANY
WHERE TaxCode = @TaxCode

PRINT 'Company deleted successfully.'


END TRY
BEGIN CATCH
PRINT 'Error: ' + ERROR_MESSAGE();
END CATCH
END;

--3.3 Quản lý Room


--proc insert
GO
CREATE PROCEDURE InsertRoom
@RoomNumber NVARCHAR(10),
@Area INT,
@Interior INT,
@State BIT,
@ElectricityPrice MONEY,
@WaterPrice MONEY,
@ID_l NVARCHAR(10)
AS
BEGIN
DECLARE @PriceperMonth MONEY

-- Tính giá mới


SET @PriceperMonth = 1000000 + @Area * 50000 + @Interior * 50000
BEGIN TRY
INSERT INTO ROOM (RoomNumber, Area, Interior, State, PriceperMonth, ElectricityPrice, WaterPrice, ID_l)
VALUES (@RoomNumber, @Area, @Interior, @State, @PriceperMonth, @ElectricityPrice, @WaterPrice, @ID_l)
PRINT 'Phòng được thêm thành công.'
END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateRoom
@RoomNumber NVARCHAR(10),
@Area INT,
@Interior INT,
@State BIT,
@ElectricityPrice MONEY,
@WaterPrice MONEY,
@ID_l NVARCHAR(10)
AS
BEGIN
-- Khai báo biến để lưu giá trị mới của PriceperMonth
DECLARE @NewPriceperMonth MONEY

-- Tính toán giá trị mới cho PriceperMonth


SET @NewPriceperMonth = 1000000 + @Area * 50000 + @Interior * 50000

BEGIN TRY
-- Cập nhật thông tin của phòng
UPDATE ROOM
SET Area = @Area,
Interior = @Interior,
State = @State,
ElectricityPrice = @ElectricityPrice,
WaterPrice = @WaterPrice,
PriceperMonth = @NewPriceperMonth,
ID_l = @ID_l
WHERE RoomNumber = @RoomNumber;

PRINT 'Thông tin phòng đã được cập nhật thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--delete
GO
CREATE PROCEDURE DeleteRoom
@RoomNumber NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM ROOM
WHERE RoomNumber = @RoomNumber

PRINT 'Phòng đã được xóa thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--3.6 function
-- Hàm tính tháng dựa vào daystart và dayend
GO
CREATE FUNCTION dbo.CalculateMonth (@DayStart DATE, @DayEnd DATE)
RETURNS MONEY
AS
BEGIN
DECLARE @Month INT
SET @Month =
CASE WHEN (day(@DayStart) = day(@DayEnd)) THEN (DATEDIFF(month, @DayStart, @DayEnd))
WHEN (day(@DayStart) < day(@DayEnd)) THEN (DATEDIFF(month, @DayStart, @DayEnd) + 1)
ELSE DATEDIFF(month, @DayStart, @DayEnd)
END
RETURN @Month
END;

-- hàm tính Tiền dựa vào giá tiền hằng tháng và số tháng
GO
CREATE FUNCTION dbo.CalculatePrice (@PriceperMonth MONEY, @Month INT)
RETURNS MONEY
AS
BEGIN
DECLARE @Price MONEY
SET @Price = @Month * @PriceperMonth
RETURN @Price
END;

-- 3. Quản lý hợp đồng


GO
CREATE TRIGGER CalculateContractPriceAndPeriod
ON CONTRACT
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @ID_t NVARCHAR(10), @RoomNumber NVARCHAR(10), @Period INT, @Price MONEY, @DayStart DATE

-- Lấy ID_t, RoomNumber, và DayStart từ bảng RENT


SELECT @ID_t = i.ID_t, @RoomNumber = i.RoomNumber, @DayStart = i.DayStart
FROM inserted i

--Số tháng hợp đồng thuê


SELECT @Period = dbo.CalculateMonth(re.DayStart, re.DayEnd)
FROM RENT re
WHERE re.ID_t = @ID_t

-- Tính giá cho hợp đồng bằng cách sử dụng hàm CalculatePrice (= tiền hằng tháng * số tháng thuê)
-- Tiền phòng hằng tháng (PriceperMonth) được tính dựa trên thông tin của ROOM đó
-- Thời gian thuê (số tháng thuê) được tính dựa trên ngày bắt đầu&ngày kết thúc từ bảng RENT
SELECT @Price = dbo.CalculatePrice(r.PriceperMonth, dbo.CalculateMonth(re.DayStart, re.DayEnd))
FROM ROOM r
INNER JOIN RENT re ON r.RoomNumber = re.RoomNumber
WHERE re.ID_t = @ID_t

-- Cập nhật giá và thời gian thuê trong bảng CONTRACT


UPDATE CONTRACT
SET Price = @Price,
Period = @Period
WHERE ID_t = @ID_t AND RoomNumber = @RoomNumber

--Cập nhật trạng thái của Phòng thành đã có người thuê (State -> 1)
UPDATE ROOM
SET State = 1
WHERE RoomNumber = @RoomNumber
END;
--proc delêt contract
GO
CREATE PROCEDURE DeleteContract
@Code NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM CONTRACT
WHERE Code = @Code;

PRINT 'Hợp đồng đã được xoá thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

-- Trigger xóa contract -> xóa rent

GO
CREATE TRIGGER DeleteRentOnContractDelete
ON CONTRACT
AFTER DELETE
AS
BEGIN
DECLARE @DeletedContracts TABLE (Code NVARCHAR(10))

-- Lưu các hợp đồng bị xóa vào bảng tạm


INSERT INTO @DeletedContracts (Code)
SELECT Code FROM deleted

-- Xóa các bản ghi trong bảng RENT tương ứng với các hợp đồng bị xóa
DELETE FROM RENT
WHERE CONCAT(ID_t, RoomNumber) IN (SELECT Code FROM @DeletedContracts)

-- Cập nhật trạng thái của Room về false (0)


UPDATE ROOM
SET State = 0
WHERE RoomNumber IN (SELECT RoomNumber FROM deleted)
END;

--3.7 Quản lý Landlord thuê Company


--proc insert Hired
GO
CREATE PROCEDURE InsertHired
@ID_l NVARCHAR(10),
@TaxCode NVARCHAR(10),
@DayStart DATE,
@DayEnd DATE
AS
BEGIN
-- Kiểm tra xem thông tin thuê công ty môi giới đã tồn tại hay chưa
IF EXISTS (SELECT 1 FROM HIRED WHERE ID_l = @ID_l AND TaxCode = @TaxCode)
BEGIN
-- Nếu đã tồn tại, phát sinh lỗi và thông báo
RAISERROR(N'Thông tin thuê công ty môi giới đã tồn tại.', 16, 1);
RETURN; -- Kết thúc stored procedure
END

BEGIN TRY
-- Chèn thông tin thuê công ty môi giới vào bảng HIRED
INSERT INTO HIRED (ID_l, TaxCode, DayStart, DayEnd)
VALUES (@ID_l, @TaxCode, @DayStart, @DayEnd);

PRINT 'Thông tin thuê công ty môi giới đã được thêm thành công.'
END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

--trigger HIRED: Landlord trả tiền thuê cho COMPANY


GO
--DROP TRIGGER InsertHired
GO
CREATE TRIGGER TriggerInsertHired
ON HIRED
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @TaxCode NVARCHAR(10), @ID_l NVARCHAR(10), @Price MONEY

-- Lấy thông tin CompanyID và LandlordID từ bảng HIRED


SELECT @TaxCode = i.TaxCode, @ID_l = i.ID_l
FROM inserted i

-- Tính giá thuê dựa trên thông tin từ bảng BROKERAGECOMPANY, sử dụng hàm CalculatePrice (= tiền hằng tháng * số tháng
thuê)
-- Tiền Chủ thuê Công ty hằng tháng (PriceperMonth) được tính dựa trên Giá tiền Hằng thánng Công ty đó quy định
(BROKERAGECOMPANY.PriceperMonth)
-- Thời gian thuê (số tháng thuê) được tính dựa trên ngày bắt đầu&ngày kết thúc khi nhập HIRED
SELECT @Price = dbo.CalculatePrice(c.PriceperMonth, dbo.CalculateMonth(i.DayStart, i.DayEnd))
FROM BROKERAGECOMPANY c, inserted i

IF @Price > (SELECT Balance FROM WALLET_LANDLORD)


-- Trừ giá thuê từ tài khoản của chủ nhà (Landlord)
BEGIN
-- Nếu không đủ tiền thuê, phát sinh lỗi và thông báo
RAISERROR(N'Người chủ không đủ tiền để thuê Công ty môi giới!', 16, 1);
ROLLBACK TRANSACTION;
RETURN; -- Kết thúc trigger
END
ELSE
BEGIN
BEGIN TRANSACTION; -- Bắt đầu giao dịch
BEGIN TRY
UPDATE WALLET_LANDLORD
SET Balance = Balance - (@Price)

UPDATE BROKERAGECOMPANY
SET Wallet = Wallet + (@Price)

COMMIT TRANSACTION; -- Chấp nhận giao dịch


END TRY
BEGIN CATCH
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch nếu có lỗi
END CATCH
END
END;

--3.8 Quản lý Tenant thuê Room


--proc insert Rent
GO
CREATE PROCEDURE InsertRent
@ID_t NVARCHAR(10),
@RoomNumber NVARCHAR(10),
@DayStart DATE,
@DayEnd DATE,
@TaxCode NVARCHAR(10) = NULL -- Tham số TaxCode mặc định là NULL
AS
BEGIN
-- Kiểm tra xem phòng đã được thuê hay chưa
IF EXISTS (SELECT 1 FROM RENT WHERE RoomNumber = @RoomNumber AND DayEnd >= @DayStart)
BEGIN
-- Nếu phòng đã được thuê, phát sinh lỗi và thông báo
RAISERROR(N'Phòng đã được thuê trong thời gian này.', 16, 1);
RETURN; -- Kết thúc stored procedure
END

BEGIN TRY
-- Chèn thông tin thuê phòng vào bảng RENT
INSERT INTO RENT (ID_t, RoomNumber, TaxCode, DayStart, DayEnd)
VALUES (@ID_t, @RoomNumber, @TaxCode, @DayStart, @DayEnd);

PRINT 'Thông tin thuê phòng đã được thêm thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;

--trigger RENT, Code = "Roomnumber" + "Id_t", và check state của room phải = 0,
--kiểm tra Balance trong Tenant nếu đủ tiền thuê trọ thì được thuê (rent) --> Tạo Contract
--kiểm tra nếu Tenant có thuê Company thì WALLET_LANDLORD trừ tiền BonusPrice (Company)
GO
--DROP TRIGGER TriggerInsertRent
GO
CREATE TRIGGER TriggerInsertRent
ON RENT
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @ID_t NVARCHAR(10), @RoomNumber NVARCHAR(10), @Price MONEY, @TaxCode NVARCHAR(10), @DayStart DATE

-- Lấy thông tin ID_t, RoomNumber, TaxCode, DayStart từ bảng RENT


SELECT @ID_t = i.ID_t, @RoomNumber = i.RoomNumber, @TaxCode = i.TaxCode, @DayStart = i.DayStart
FROM inserted i

-- Kiểm tra trạng thái của phòng, trống thì được thuê (State = 0)
IF (SELECT State FROM ROOM WHERE RoomNumber = @RoomNumber) = 1
BEGIN
-- Nếu trạng thái của phòng là 0 (đã có người thuê, State = 0), phát sinh lỗi và thông báo
RAISERROR(N'Phòng đã được thuê. Vui lòng tìm phòng khác !', 16, 1);
ROLLBACK TRANSACTION;
RETURN; -- Kết thúc trigger
END

-- Kiểm tra xem ROOM có được thuê bởi một Company có TaxCode trùng khớp với TaxCode trong Rent không
IF @TaxCode IS NOT NULL
BEGIN
IF NOT EXISTS (
SELECT 1
FROM ROOM r
INNER JOIN HIRED h ON r.ID_l = h.ID_l
WHERE r.RoomNumber = @RoomNumber AND h.TaxCode = @TaxCode
)
BEGIN
-- Nếu không trùng, phát sinh lỗi và hủy bỏ giao dịch
RAISERROR(N'Phòng không thuộc sở hữu của Công ty môi giới này!', 16, 1);
ROLLBACK TRANSACTION;
RETURN;
END
END

-- Tính giá thuê dựa trên thông tin từ bảng ROOM, sử dụng hàm CalculatePrice (= tiền hằng tháng * số tháng thuê)
-- Tiền phòng hằng tháng (PriceperMonth) được tính dựa trên thông tin của ROOM đó
-- Thời gian thuê (số tháng thuê) được tính dựa trên ngày bắt đầu&ngày kết thúc khi nhập RENT
SELECT @Price = dbo.CalculatePrice(r.PriceperMonth, dbo.CalculateMonth(i.DayStart, i.DayEnd))
FROM ROOM r, inserted i
WHERE (r.RoomNumber = @RoomNumber)

IF @Price > (SELECT Balance FROM TENANT WHERE ID_t = @ID_t)


BEGIN
-- Nếu không đủ tiền thuê, phát sinh lỗi và thông báo
RAISERROR(N'Người thuê không đủ tiền để thuê phòng này!', 16, 1);
ROLLBACK TRANSACTION;
RETURN; -- Kết thúc trigger
END
ELSE
BEGIN TRANSACTION; -- Bắt đầu giao dịch
BEGIN TRY
-- Thêm hợp đồng vào bảng CONTRACT (Code = "ID_t"+"RoomNumber")
INSERT INTO CONTRACT (Code, DayStart, RoomNumber, ID_t)
VALUES ((CONCAT(@ID_t, @RoomNumber)), @DayStart, @RoomNumber, @ID_t);

UPDATE TENANT
SET ID_l = r.ID_l
FROM ROOM r
WHERE @ID_t = ID_t AND @RoomNumber = RoomNumber

IF @TaxCode IS NOT NULL


BEGIN
-- Kiểm tra xem TaxCode của Rent có trùng với TaxCode của Company mà Landlord thuê không
IF EXISTS (
SELECT 1
FROM HIRED h
INNER JOIN BROKERAGECOMPANY c ON h.TaxCode = c.TaxCode
WHERE h.TaxCode = @TaxCode
)
BEGIN
-- Nếu trùng, cập nhật WALLET_LANDLORD
UPDATE WALLET_LANDLORD
SET Balance = Balance - (SELECT BonusPrice FROM BROKERAGECOMPANY WHERE TaxCode = @TaxCode)

UPDATE BROKERAGECOMPANY
SET Wallet = Wallet + BonusPrice
WHERE TaxCode = @TaxCode

END
ELSE
BEGIN
--Nếu không trùng, phát sinh lỗi và hủy bỏ giao dịch
ROLLBACK TRANSACTION;
RETURN;
END
END

COMMIT TRANSACTION; -- Chấp nhận giao dịch


END TRY
BEGIN CATCH
RAISERROR(N'Lỗi!!!!!!!!!!!!!!!!!!!!!!!!!', 16, 1);
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch nếu có lỗi
END CATCH

END;

-----3.4 Quản lý hoá đơn (bill)


--insert
GO
CREATE PROCEDURE InsertBill
@Code NVARCHAR(10),
@ElectricNumber FLOAT,
@WaterNumber FLOAT,
@Day DATE,
@ID_l NVARCHAR(10),
@RoomNumber NVARCHAR(10),
@ID_t NVARCHAR(10)
AS
BEGIN
BEGIN TRY
INSERT INTO BILL (Code, ElectricNumber, WaterNumber, Day, ID_l, RoomNumber, ID_t)
VALUES (@Code, @ElectricNumber, @WaterNumber, @Day, @ID_l, @RoomNumber, @ID_t)

PRINT 'Đã thêm Bill thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--update
GO
CREATE PROCEDURE UpdateBill
@Code NVARCHAR(10),
@ElectricNumber FLOAT,
@WaterNumber FLOAT,
@Day DATE
AS
BEGIN
DECLARE @Price MONEY

-- Tính giá trị mới cho thuộc tính Price dựa trên các thuộc tính khác
SELECT @Price = ROOM.PriceperMonth + @ElectricNumber * ROOM.ElectricityPrice + @WaterNumber * ROOM.WaterPrice
FROM ROOM
INNER JOIN BILL ON ROOM.RoomNumber = BILL.RoomNumber
WHERE BILL.Code = @Code

-- Cập nhật giá trị mới cho thuộc tính Price


UPDATE BILL
SET Price = @Price,
ElectricNumber = @ElectricNumber,
WaterNumber = @WaterNumber
WHERE Code = @Code
END;
--delete
GO
CREATE PROCEDURE DeleteBill
@Code NVARCHAR(10)
AS
BEGIN
BEGIN TRY
DELETE FROM BILL
WHERE Code = @Code

PRINT 'Đã xóa Bill thành công.'


END TRY
BEGIN CATCH
PRINT 'Lỗi: ' + ERROR_MESSAGE();
END CATCH
END;
--proc tìm kiếm bill
GO
CREATE PROCEDURE FindBillByCode
@Code NVARCHAR(10)
AS
BEGIN
-- Kiểm tra xem hóa đơn có tồn tại không
IF EXISTS (SELECT * FROM BILL WHERE Code = @Code)
BEGIN
-- Nếu tồn tại, trả về thông tin của hóa đơn
SELECT *
FROM BILL
WHERE Code = @Code
END
ELSE
BEGIN
-- Nếu không tồn tại, thông báo rằng không tìm thấy hóa đơn
PRINT 'Không tìm thấy hóa đơn với mã ' + @Code
END
END;
--trigger
GO
CREATE TRIGGER TriggerInsertBill
ON BILL
AFTER INSERT
AS
BEGIN
DECLARE @Code NVARCHAR(10), @Price MONEY, @ElectricNumber FLOAT, @WaterNumber FLOAT, @Day DATE,
@RoomNumber NVARCHAR(10), @ID_t NVARCHAR(10), @DayStartContract DATE

-- Lấy thông tin từ bảng BILL


SELECT @Code = i.Code, @ElectricNumber = i.ElectricNumber, @WaterNumber = i.WaterNumber,
@Day = i.Day, @RoomNumber = i.RoomNumber, @ID_t = i.ID_t
FROM inserted i

-- Lấy ngày bắt đầu của hợp đồng từ bảng CONTRACT


SELECT @DayStartContract = DayStart
FROM CONTRACT
WHERE RoomNumber = @RoomNumber AND ID_t = @ID_t

-- Kiểm tra nếu ngày của BILL nằm trong 10 ngày sau khi bắt đầu hợp đồng
IF (@Day >= @DayStartContract)
BEGIN
-- Tính giá 1 tháng BILL
SELECT @Price = PriceperMonth + @ElectricNumber * ElectricityPrice + @WaterNumber * WaterPrice
FROM ROOM
WHERE RoomNumber = @RoomNumber

BEGIN TRANSACTION; -- Bắt đầu giao dịch


BEGIN TRY
-- Trừ tiền từ tài khoản của Tenant
UPDATE TENANT
SET Balance = Balance - @Price
WHERE ID_t = @ID_t

-- Cộng tiền vào tài khoản của Landlord


UPDATE WALLET_LANDLORD
SET Balance = Balance + @Price

-- Cập nhật giá vào bảng BILL


UPDATE BILL
SET Price = @Price
WHERE Code = @Code

COMMIT TRANSACTION; -- Chấp nhận giao dịch


END TRY
BEGIN CATCH
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch nếu có lỗi
END CATCH
END
ELSE
BEGIN
-- Nếu ngày của BILL không nằm trong 10 ngày sau khi bắt đầu hợp đồng, xoá hợp đồng
DELETE FROM CONTRACT
WHERE RoomNumber = @RoomNumber AND ID_t = @ID_t
-- Xoá bản ghi trong bảng RENT tương ứng với hợp đồng bị xoá
DELETE FROM RENT
WHERE ID_t = @ID_t AND RoomNumber = @RoomNumber
-- Huỷ việc chèn dữ liệu vào bảng BILL
RAISERROR(N'Ngày của BILL không nằm trong 10 ngày sau khi bắt đầu hợp đồng, xoá hợp đồng!', 16, 1);
ROLLBACK TRANSACTION; -- Hoàn lại giao dịch
END
END;

GO
--EXEC
EXEC InsertWalletLandlord 'WL1', 1000000000;

GO
EXEC InsertTenant 'TN1', 'John Doe', '1234567890', 'Engineer', '1990-01-01', 50000000;
GO
EXEC InsertLandlord 'LL1', 'Alice Smith', '9876543210', '1970-01-01', 'WL1';
GO
EXEC InsertRoom 'R1', 40, 2, 0, 5000, 5000, 'LL1';
GO
EXEC InsertCompany 'C1', 'Company1', 'VVN', 100000000, 1000000, 500000;
GO
-- Chủ thuê Công Ty môi giới 3 tháng
EXEC InsertHired 'LL1', 'C1', '2024-04-01', '2024-06-13';
GO
--Người thuê thuê phòng 2 tháng
EXEC InsertRent 'TN1', 'R1', '2024-04-01', '2024-06-01', 'C1' ;
GO
--Bill lần 1
EXEC InsertBill 'B1_1', 5, 5, '2024-04-06', 'LL1', 'R1', 'TN1';
--Bill lần 2
EXEC InsertBill 'B1_2', 5, 5, '2024-04-06', 'LL1', 'R1', 'TN1';

--EXEC2
GO
EXEC InsertTenant 'TN2', 'Tom', '2234567890', 'Engineer', '1990-01-01', 50000000;
GO
EXEC InsertLandlord 'LL2', 'Alice Smith', '9876543210', '1970-01-01', 'WL1';
GO
EXEC InsertRoom 'R2', 50, 5, 0, 5000, 5000, 'LL2';
GO
EXEC InsertCompany 'C2', 'Company2', 'VVN', 100000000, 1000000, 500000;
GO
-- Chủ thuê Công Ty môi giới 2 tháng
EXEC InsertHired 'LL2', 'C2', '2024-07-01', '2024-09-01';
GO
--Người thuê thuê phòng 3 tháng
EXEC InsertRent 'TN2', 'R2', '2024-07-01', '2024-10-01' ;
GO
--Bill lần 1
EXEC InsertBill 'B2_1', 11, 11, '2024-07-06', 'LL2', 'R2', 'TN2';

You might also like