 
															Hotel Reservation Project
Project Overview
The Easy Stay Hotel Management System is built on the Salesforce platform using Apex and custom objects. It automates hotel and reservation management by:
- Creating hotels and tracking room availability.
- Managing guest reservations.
- Generating unique confirmation codes for reservations.
- Automatically updating available room counts after booking.
2. Objects and Fields
Hotel Object (Hotel__c)
| Field Label | API Name | Data Type | Description | 
|---|---|---|---|
| 
													Hotel Name 												 | 
													Name 												 | 
													Text 												 | 
													The name of the hotel (e.g., “Grand Palace Hotel”). 												 | 
| 
													Total Rooms 												 | 
													Total_Rooms__c 												 | 
													Number 												 | 
													The total number of rooms available in the hotel when it is created. 												 | 
| 
													Available Rooms 												 | 
													Available_Rooms__c 												 | 
													Number 												 | 
													The current number of rooms available for booking. This field is automatically updated when reservations are made. 												 | 
 
															Reservation Object (Reservation__c)
| Field Label | API Name | Data Type | Description | 
|---|---|---|---|
| 
													Guest Name 												 | 
													Name 												 | 
													Text 												 | 
													The name of the guest making the reservation. 												 | 
| 
													Check-In Date 												 | 
													Check_In__c 												 | 
													Date 												 | 
													The date when the guest is scheduled to check into the hotel. 												 | 
| 
													Check-Out Date 												 | 
													Check_Out__c 												 | 
													Date 												 | 
													The date when the guest is scheduled to check out of the hotel.												 | 
| 
													Confirmation Code 												 | 
													
Confirmation_Code__c 
												 | 
													Text												 | 
													A unique system-generated code assigned to each reservation (e.g., CONF1234). 												 | 
| 
													Hotel 												 | 
													Hotel__c 												 | 
													Lookup												 | 
													A  lookup relationship to the Hotel__c object, linking the reservation to a specific hotel. 												 | 
 
															Room Service Object (Room_Service__c)
| Field Label | API Name | Data Type | Description | 
|---|---|---|---|
| 
													Service Name* 												 | 
													Service_Name__c												 | 
													Text 												 | 
													Name of the room service (e.g., Laundry, Meal). 												 | 
| 
													Reservation 												 | 
													Reservation__c 												 | 
													Lookup (Reservation__c) 												 | 
													Links the room service to a reservation. 												 | 
| 
													
Price 
Service Date 
												 | 
													
Price__c 
Service_Date__c 
												 | 
													
Currency 
Date 
												 | 
													
Cost of the service. 
Date when the service was provided. 
												 | 
 
															 
															CheckOut Object (CheckOut__c)
| Field Label | API Name | Data Type | Description | 
|---|---|---|---|
| 
													Reservation 												 | 
													Reservation__c 												 | 
													Lookup (Reservation__c) 												 | 
													Links the checkout to a specific reservation. 												 | 
| 
													Check-Out Date 												 | 
													Check_Out_Date__c												 | 
													Date 												 | 
													Date when the guest checked out. 												 | 
| 
													Status 
												 | 
													Status__c 
												 | 
													Picklist (e.g., Pending, Completed) 
												 | 
													Current status of the checkout. (When “Completed”, triggers billing creation.) 												 | 
Billing Object (Billing__c)
| Field Label | API Name | Data Type | Description | 
|---|---|---|---|
| 
													Invoice Number 												 | 
													Invoice_Number___c 												 | 
													Auto Number / Text 												 | 
													Unique invoice number. 												 | 
| 
													Reservation 												 | 
													Reservation__c 												 | 
													Lookup (Reservation__c) 												 | 
													Links the bill to a reservation.												 | 
| 
													Invoice Date 
												 | 
													Invoice_Date__c
												 | 
													Date 
												 | 
													Date the invoice is generated. 												 | 
| 
													Room Charges 												 | 
													Room_Charges__c 												 | 
													Currency 												 | 
													Charges for the room stay. 												 | 
| 
													Service Charges 												 | 
													Service_Charges__c 												 | 
													Currency 												 | 
													Charges for any room services used. 												 | 
| 
													CGST 												 | 
													CGST__c 												 | 
													Percent / Currency												 | 
													Central GST applied. 												 | 
| 
													SGST 												 | 
													SGST__c 												 | 
													Percent / Currency												 | 
													State GST applied.												 | 
| 
													Total Amount 												 | 
													Total_Amount__c 												 | 
													Currency 												 | 
													Total invoice amount. 												 | 
| 
													Payment Status 												 | 
													Payment_Status__c 												 | 
													Picklist (Pending, Paid, Cancelled) 												 | 
													Status of payment.												 | 
 
															3. Business Logic Implemented
- Auto-Generate Billing on CheckOut: 
 When a CheckOut__c record’s Status__c = “Completed”, a new Billing__c record is automatically created for the related reservation.
- Room charges are fetched from Reservation/Hotel.
- Service charges are summed from all related Room_Service__c records.
- CGST/SGST and Total Amount fields are calculated automatically.
- Payment Status defaults to “Pending.”
4. Apex Trigger
This trigger runs on the Reservation__c object and has before insert and after insert events.
 Navigate to Setup
- Click the ⚙️ Gear Icon in the top-right corner.
- Select Setup.
 Search for Apex Triggers
- In the Quick Find box, type Apex Triggers.
- Click on Apex Triggers under Custom Code.
 Click on “New”
- On the Apex Trigger page, click the New button.
 Select the Object
- Choose the object where the trigger should run.
- In this case: Reservation__c.
 Define Trigger Events
- Specify when the trigger should fire (e.g., before insert, after insert).
- Example:
Reservation Trigger trigger
trigger ReservationTrigger on Reservation__c (before insert, after insert) {
// Before Insert: Generate Confirmation Code
if (Trigger.isBefore && Trigger.isInsert) {
for (Reservation__c res : Trigger.new) {
String randomNum = String.valueOf(Math.abs(Crypto.getRandomInteger())).substring(0,4);
String code = ‘CONF’ + randomNum; // Example: CONF1234
res.Confirmation_Code__c = code;
}
}
// After Insert: Update Available Rooms in Hotel
if(Trigger.isAfter && Trigger.isInsert){
Map<Id, Integer> hotelReservationCount = new Map<Id, Integer>();
// Count reservations for each Hotel
for(Reservation__c res : Trigger.new){
if(res.Hotel__c != null){
if(hotelReservationCount.containsKey(res.Hotel__c)){
hotelReservationCount.put(res.Hotel__c, hotelReservationCount.get(res.Hotel__c) + 1);
} else {
hotelReservationCount.put(res.Hotel__c, 1);
}
}
}
// Fetch related Hotels
List<Hotel__c> hotelsToUpdate = [SELECT Id, Available_Rooms__c FROM Hotel__c WHERE Id IN :hotelReservationCount.keySet()];
for(Hotel__c hotel : hotelsToUpdate){
Integer count = hotelReservationCount.get(hotel.Id);
hotel.Available_Rooms__c = hotel.Available_Rooms__c – count;
}
update hotelsToUpdate;
}
}
Explanation:
- Trigger.isBefore && Trigger.isInsert → This block runs before the reservation is saved to the database.
- Loops through all new reservations in Trigger.new.
- Generates a random 4-digit number using Crypto.getRandomInteger() and prepends “CONF” to create a confirmation code.
- Sets this code into the field Confirmation_Code__c of the reservation.
- Trigger.isAfter && Trigger.isInsert → Runs after the reservation record is saved.
- Creates a map to count how many reservations are booked per hotel.
- Loops through reservations in Trigger.new and populates the map with hotel IDs and reservation counts.
- Queries all the hotels related to these reservations.
- Subtracts the number of new reservations from the hotel’s Available_Rooms__c.Updates the hotels in Salesforce.
- This ensures that available rooms are automatically updated after new reservations are made.
CheckOut Trigger Works (Step-by-Step)
1. Trigger Setup
Object: CheckOut__c
Events: after insert, after update (fires after records are saved to the database)
2. Collect Reservation IDs
Loop through the incoming CheckOut__c records.
If Status__c == ‘Completed’, add its related Reservation__c to a Set<Id> resIds.
3. Query Related Reservation Data
Using resIds, query Reservation__c records and pull:
Stay_Duration__c
Hotel_Room__c
Hotel_Room__r.Price_Per_Day__c
Store results in a Map<Id, Reservation__c> for quick lookup.
4. Query Related Room Services
Run an aggregate query on Room_Service__c to sum up Price__c per reservation.
Put totals into a Map<Id, Decimal> serviceTotals keyed by Reservation__c.
5. Calculate Billing Details
For each Reservation ID:
Room Charges = Price_Per_Day * Stay_Duration.
Service Charges = Total of all related room services (if any).
Subtotal = Room Charges + Service Charges.
CGST = Subtotal × 9%.
SGST = Subtotal × 9%.
Total = Subtotal + CGST + SGST.
6. Create Billing__c Records
For each reservation, create a new Billing__c record and populate:
Reservation__c (lookup)
Invoice_Date__c (today)
Room_Charges__c
Service_Charges__c
CGST__c
SGST__c
Total_Amount__c
Payment_Status__c = ‘Paid’
Add to billsToInsert list.
7. Insert the Bills
After all are built, insert the list of Billing__c records in one DML operation.
trigger CheckOutTrigger on CheckOut__c (after insert, after update) {
// Collect Reservation IDs where Status = Completed
Set<Id> resIds = new Set<Id>();
for (CheckOut__c co : Trigger.new) {
if (co.Status__c == ‘Completed’) {
resIds.add(co.Reservation__c);
}
}
if (!resIds.isEmpty()) {
// Query Reservations with related Room and Stay Duration
Map<Id, Reservation__c> resMap = new Map<Id, Reservation__c>(
[SELECT Id, Stay_Duration__c, Hotel_Room__c,
Hotel_Room__r.Price_Per_Day__c
FROM Reservation__c
WHERE Id IN :resIds]
);
// Query all Room Services related to these Reservations
Map<Id, Decimal> serviceTotals = new Map<Id, Decimal>();
for (AggregateResult ar : [
SELECT Reservation__c rId, SUM(Price__c) totalPrice
FROM Room_Service__c
WHERE Reservation__c IN :resIds
GROUP BY Reservation__c
]) {
serviceTotals.put((Id)ar.get(‘rId’), (Decimal)ar.get(‘totalPrice’));
}
List<Billing__c> billsToInsert = new List<Billing__c>();
for (Id resId : resIds) {
Reservation__c r = resMap.get(resId);
Decimal roomCharges = 0;
Decimal serviceCharges = 0;
if (r != null) {
if (r.Hotel_Room__r.Price_Per_Day__c != null && r.Stay_Duration__c != null) {
roomCharges = r.Hotel_Room__r.Price_Per_Day__c * r.Stay_Duration__c;
}
if (serviceTotals.containsKey(resId)) {
serviceCharges = serviceTotals.get(resId);
}
Decimal subtotal = roomCharges + serviceCharges;
Decimal cgst = subtotal * 0.09; // 9% CGST
Decimal sgst = subtotal * 0.09; // 9% SGST
Decimal total = subtotal + cgst + sgst;
Billing__c b = new Billing__c();
b.Reservation__c = resId;
b.Invoice_Date__c = Date.today();
b.Room_Charges__c = roomCharges;
b.Service_Charges__c = serviceCharges;
b.CGST__c = cgst;
b.SGST__c = sgst;
b.Total_Amount__c = total;
b.Payment_Status__c = ‘Paid’;
billsToInsert.add(b);
}
}
if (!billsToInsert.isEmpty()) {
insert billsToInsert;
}
}
}
5. Test Class
A test class ensures your trigger works correctly and Salesforce deployment requirements are met.
ReservationTriggerTest
@isTest
public class ReservationTriggerTest {
public static String generateConfirmationCode(Reservation__c res) {
String prefix = ‘RES’;
String datePart = String.valueOf(System.today()). replace(‘-‘, ”);
String randomPart = String.valueOf(Math.mod(Crypto.getRandomInteger(), 10000));
return prefix + ‘-‘ + datePart + ‘-‘ + randomPart;
}
@isTest
static void testReservationTrigger() {
// Create a Hotel record
Hotel__c hotel = new Hotel__c(
Name = ‘Test Hotel’,
Total_Rooms__c = 10,
Available_Rooms__c=10
);
insert hotel;
// Create a Reservation record
Reservation__c reservation = new Reservation__c(
Guest_Name__c = ‘Test Guest’,
Check_In__c = Date.today(),
Check_Out__c = Date.today().addDays(2),
Hotel__c = hotel.Id
);
insert reservation;
// Validate Confirmation Code
Reservation__c insertedRes = [SELECT Confirmation_Code__c FROM Reservation__c WHERE Id = :reservation.Id];
System.assertNotEquals(null, insertedRes.Confirmation_Code__c, ‘Confirmation code should not be null.’);
// Validate Available Rooms
Hotel__c updatedHotel = [SELECT Available_Rooms__c FROM Hotel__c WHERE Id = :hotel.Id];
System.assertEquals(9, updatedHotel.Available_Rooms__c, ‘Available rooms should decrease by 1.’);
}
}
Explanation:
1.@isTest → Marks this class as a test class. Salesforce does not count test code toward org limits.
2.Creating a hotel record → Sets up a hotel with 10 available rooms.
3.Creating a reservation record → Assigns the reservation to the hotel.
4.Insert operation → Triggers your ReservationTrigger logic.
5.Validates confirmation code → Checks that Confirmation_Code__c is not null.
6.Validates available rooms → Checks that the hotel’s Available_Rooms__c has decreased by 1 (from 10 → 9).
This ensures that both the before-insert logic (confirmation code generation) and the after-insert logic (room update) work correctly.
 
															6. Key Features
- Automatically generates a confirmation code for each reservation.
- Reduces Available Rooms dynamically upon booking.
- Ensures data consistency using Apex Triggers.
- Covered with Unit Test Class for 100% code coverage.
7. Conclusion
The Easy Stay Hotel Management System successfully demonstrates how Salesforce can be leveraged to build a streamlined hotel and reservation management application. By using custom objects, Apex triggers, and automated business logic, the system ensures that hotel room availability and guest reservations remain accurate and consistent in real-time.
Key benefits include:
- Automation of critical tasks such as confirmation code generation and room availability updates.
- Improved accuracy by eliminating manual updates and reducing the risk of overbooking.
- Scalability as the system can easily be extended with additional features like payment tracking, cancellation handling, or reporting dashboards.
- Reliability through the use of test classes that validate both the trigger logic and data integrity.
In conclusion, the project provides a robust, automated, and extensible solution for hotel reservation management, showcasing the power of Salesforce Apex development and best practices in trigger design and testing.
Handles the final stage of billing and discharge, including discounts and payment tracking after a patient visit
Course Video
- Trigger.isBefore && Trigger.isInsert → This block runs before the reservation is saved to the database.
- Loops through all new reservations in Trigger.new.
- Generates a random 4-digit number using Crypto.getRandomInteger() and prepends “CONF” to create a confirmation code.
- Sets this code into the field Confirmation_Code__c of the reservation.
- Trigger.isAfter && Trigger.isInsert → Runs after the reservation record is saved.
- Creates a map to count how many reservations are booked per hotel.
- Loops through reservations in Trigger.new and populates the map with hotel IDs and reservation counts.
- Queries all the hotels related to these reservations.
- Subtracts the number of new reservations from the hotel’s Available_Rooms__c.Updates the hotels in Salesforce.
- This ensures that available rooms are automatically updated after new reservations are made.





