Nhân viên → Trưởng bộ phận
Email tự động khi duyệt

Nền tảng: Power Apps (Canvas App – Phone) + SharePoint + Power Automate (Email)
🎯 MỤC TIÊU BUỔI HỌC
Sau bài này, học viên sẽ làm được:
- Nhân viên tạo đơn nghỉ phép và lưu vào SharePoint
- Trưởng bộ phận duyệt 1 cấp ngay trên app
- Khi duyệt, Power Automate tự gửi email thông báo kết quả
📂 PHẦN 1: CHUẨN BỊ DỮ LIỆU (SHAREPOINT)
1.1 Tạo SharePoint List: LeaveRequests
Tạo list mới tên LeaveRequests, gồm các cột:
| Tên cột | Kiểu dữ liệu | Ý nghĩa nghiệp vụ |
|---|---|---|
| Title | Single line of text | Tiêu đề đơn (để dễ tìm trong SharePoint) |
| EmployeeName | Single line of text | Tên nhân viên gửi đơn |
| EmployeeEmail | Single line of text | Email nhân viên (để gửi mail thông báo) |
| Department | Single line of text | Phòng ban nhân viên |
| LeaveType | Choice | Loại nghỉ (Phép năm / Ốm / Không lương) |
| StartDate | Date | Ngày bắt đầu nghỉ |
| EndDate | Date | Ngày kết thúc nghỉ |
| Reason | Multiple lines of text | Lý do nghỉ |
| Status | Choice | Trạng thái: Pending/Approved/Rejected |
| ManagerEmail | Single line of text | Email trưởng bộ phận (để định tuyến duyệt) |
Thiết lập Choice khuyến nghị:
LeaveType: Annual Leave, Sick Leave, Unpaid LeaveStatus: Pending, Approved, Rejected
Lưu ý cho người mới: SharePoint “Choice” giúp dữ liệu chuẩn, tránh gõ sai chính tả.
1.2 15 dòng dữ liệu mẫu (dạng TABLE)
👉 Cách nhập nhanh: vào list LeaveRequests → Edit in grid view → copy-paste bảng dưới.
(Dữ liệu có đủ Pending/Approved/Rejected để test quy trình và Flow email)
| Title | EmployeeName | EmployeeEmail | Department | LeaveType | StartDate | EndDate | Reason | Status | ManagerEmail |
|---|---|---|---|---|---|---|---|---|---|
| Lan-2026-02-01 | Nguyễn Thị Lan | lan@contoso.com | HR | Annual Leave | 2026-02-20 | 2026-02-21 | Việc gia đình | Pending | hr.manager@contoso.com |
| Nam-2026-02-02 | Trần Văn Nam | nam@contoso.com | IT | Sick Leave | 2026-02-18 | 2026-02-18 | Sốt cao | Pending | it.manager@contoso.com |
| Huy-2026-02-03 | Lê Minh Huy | huy@contoso.com | Sales | Unpaid Leave | 2026-02-25 | 2026-02-26 | Việc cá nhân | Pending | sales.manager@contoso.com |
| Mai-2026-02-04 | Phạm Thu Mai | mai@contoso.com | Marketing | Annual Leave | 2026-03-02 | 2026-03-04 | Du lịch | Pending | mkt.manager@contoso.com |
| Khoa-2026-02-05 | Đặng Quốc Khoa | khoa@contoso.com | Finance | Sick Leave | 2026-02-19 | 2026-02-20 | Khám bệnh | Pending | fin.manager@contoso.com |
| Linh-2026-01-01 | Vũ Ngọc Linh | linh@contoso.com | HR | Annual Leave | 2026-01-10 | 2026-01-10 | Nghỉ phép năm | Approved | hr.manager@contoso.com |
| Tu-2026-01-02 | Nguyễn Anh Tú | tu@contoso.com | IT | Sick Leave | 2026-01-12 | 2026-01-13 | Cảm cúm | Approved | it.manager@contoso.com |
| My-2026-01-03 | Trần Ngọc My | my@contoso.com | Sales | Annual Leave | 2026-01-15 | 2026-01-16 | Việc gia đình | Rejected | sales.manager@contoso.com |
| Son-2026-01-04 | Lê Hoàng Sơn | son@contoso.com | Marketing | Unpaid Leave | 2026-01-20 | 2026-01-20 | Bận đột xuất | Approved | mkt.manager@contoso.com |
| Dung-2026-01-05 | Phạm Thị Dung | dung@contoso.com | Finance | Annual Leave | 2026-01-22 | 2026-01-24 | Nghỉ phép | Rejected | fin.manager@contoso.com |
| Quang-2026-02-06 | Nguyễn Quang | quang@contoso.com | IT | Annual Leave | 2026-03-05 | 2026-03-06 | Đám cưới | Pending | it.manager@contoso.com |
| Hanh-2026-02-07 | Trần Hạnh | hanh@contoso.com | HR | Sick Leave | 2026-02-22 | 2026-02-22 | Đau bụng | Pending | hr.manager@contoso.com |
| Phuc-2026-02-08 | Lê Phúc | phuc@contoso.com | Sales | Annual Leave | 2026-03-01 | 2026-03-01 | Nghỉ phép năm | Pending | sales.manager@contoso.com |
| Trang-2026-02-09 | Nguyễn Trang | trang@contoso.com | Marketing | Sick Leave | 2026-02-17 | 2026-02-17 | Khám bệnh | Pending | mkt.manager@contoso.com |
| Viet-2026-02-10 | Trần Quốc Việt | viet@contoso.com | Finance | Unpaid Leave | 2026-03-10 | 2026-03-11 | Việc riêng | Pending | fin.manager@contoso.com |
✅ Dữ liệu này giúp học viên test được:
- Lọc danh sách theo Pending
- Duyệt/ từ chối
- Flow email chỉ chạy khi Approved
🛠️ PHẦN 2: TẠO APP (POWER APPS)
2.1 Tạo Canvas App (Phone)
- Vào make.powerapps.com
- Create → Blank app → Blank canvas app
- Name:
App Xin Nghỉ Phép - Format: Phone
- Create
2.2 Kết nối SharePoint List
- Thanh trái chọn Data (biểu tượng hình trụ)
- Add data
- Chọn SharePoint
- Chọn Site → tick list LeaveRequests
- Connect
Nếu không thấy list: kiểm tra bạn đang ở đúng Site hoặc quyền truy cập SharePoint.
👤 PHẦN 3: MÀN HÌNH NHÂN VIÊN GỬI ĐƠN
3.1 Tạo màn hình
- New screen → Blank
- Đổi tên screen:
scrCreateRequest
Vì sao cần screen riêng?
- Nhân viên chỉ cần tạo đơn + xem đơn của mình
- Trưởng bộ phận có màn hình riêng để duyệt
3.2 Thêm các control (đặt tên chuẩn)
(1) Tiêu đề màn hình
- Insert → Label
- Text:
XIN NGHỈ PHÉP
(2) Tên nhân viên
- Insert → Text input
- Name:
txtEmployeeName - HintText:
Họ và tên
(3) Email nhân viên
- Insert → Text input
- Name:
txtEmployeeEmail - HintText:
Email (vd: lan@contoso.com)
(4) Phòng ban
- Insert → Text input
- Name:
txtDepartment - HintText:
Phòng ban (IT/HR/Sales...)
(5) Loại nghỉ
- Insert → Dropdown
- Name:
drpLeaveType - Items:
["Annual Leave","Sick Leave","Unpaid Leave"]
Giải thích: Dropdown giúp chọn đúng giá trị (tránh gõ sai).
(6) Ngày bắt đầu / kết thúc
- Insert → Date picker
- Start: Name
dpStartDate - End: Name
dpEndDate
(7) Lý do nghỉ
- Insert → Text input
- Name:
txtReason - Set Mode = Multiline
- HintText:
Nhập lý do nghỉ
3.3 Nút “GỬI ĐƠN”
- Insert → Button
- Name:
btnSubmit - Text:
GỬI ĐƠN
OnSelect (dán công thức)
Chọn btnSubmit → thuộc tính OnSelect → dán:
Patch(
LeaveRequests,
Defaults(LeaveRequests),
{
Title: txtEmployeeName.Text & " - " & Text(Today(), "yyyy-mm-dd"),
EmployeeName: txtEmployeeName.Text,
EmployeeEmail: txtEmployeeEmail.Text,
Department: txtDepartment.Text,
LeaveType: drpLeaveType.Selected.Value,
StartDate: dpStartDate.SelectedDate,
EndDate: dpEndDate.SelectedDate,
Reason: txtReason.Text,
Status: "Pending",
ManagerEmail: "manager@contoso.com"
}
);
Notify("Đã gửi đơn thành công!", NotificationType.Success);
Reset(txtEmployeeName);
Reset(txtEmployeeEmail);
Reset(txtDepartment);
Reset(txtReason);
Reset(drpLeaveType);
Reset(dpStartDate);
Reset(dpEndDate)
Giải thích từng phần (cho người mới)
Patch(...)= ghi dữ liệu vào SharePointDefaults(LeaveRequests)= tạo dòng mớiTitle= đặt tiêu đề dễ tìm (Tên + ngày)Status: "Pending"= đơn vừa gửi luôn ở trạng thái chờ duyệtNotify()= hiện thông báo thành côngReset()= xóa form để nhập đơn tiếp theo
Lưu ý:
ManagerEmailở đây đang để cố định. Sau này nâng cao có thể tự động theo phòng ban.
3.4 Gallery “ĐƠN CỦA TÔI” (để nhân viên theo dõi)
- Insert → Vertical gallery
- Name:
galMyRequests
Items:
Filter(LeaveRequests, EmployeeEmail = txtEmployeeEmail.Text)
Giải thích: Khi nhân viên nhập email của mình, gallery sẽ hiện các đơn của email đó.
Nếu muốn “chuẩn” theo đăng nhập Microsoft 365 thì thường dùng
User().Email, nhưng trong bài thực hành cơ bản, dùng input email giúp học viên dễ test ngay.
👨💼 PHẦN 4: MÀN HÌNH TRƯỞNG BỘ PHẬN DUYỆT 1 CẤP
4.1 Tạo màn hình
- New screen → Blank
- Đổi tên:
scrManager
Thêm Label tiêu đề: DUYỆT NGHỈ PHÉP
4.2 Gallery danh sách đơn chờ duyệt
- Insert → Vertical gallery
- Name:
galPending
Items:
Filter(LeaveRequests, Status = "Pending")
Trong gallery hiển thị các trường:
- Title:
ThisItem.EmployeeName - Subtitle:
ThisItem.Department & " - " & ThisItem.LeaveType - Body:
Text(ThisItem.StartDate, "dd/mm/yyyy") & " → " & Text(ThisItem.EndDate, "dd/mm/yyyy")
4.3 Nút “DUYỆT” và “TỪ CHỐI”
(A) Icon DUYỆT (✔)
- Insert → Icon → Check
- Name:
icoApprove
OnSelect:
Patch(
LeaveRequests,
ThisItem,
{ Status: "Approved" }
);
Notify("Đã duyệt đơn!", NotificationType.Success)
(B) Icon TỪ CHỐI (✖)
- Insert → Icon → Cancel
- Name:
icoReject
OnSelect:
Patch(
LeaveRequests,
ThisItem,
{ Status: "Rejected" }
);
Notify("Đã từ chối đơn!", NotificationType.Warning)
Giải thích:
ThisItem= đúng đơn bạn đang bấm trong gallery- Patch chỉ cập nhật field Status nên rất nhanh
📧 PHẦN 5: EMAIL TỰ ĐỘNG KHI DUYỆT (POWER AUTOMATE)
5.1 Tạo Flow tự động
- Mở Power Automate
- Create → Automated cloud flow
- Trigger chọn: When an item is modified (SharePoint)
- Chọn đúng:
- Site Address
- List Name:
LeaveRequests
5.2 Thêm điều kiện chỉ gửi khi “Approved”
Add step → Condition
- Left:
Status Value(dynamic content từ SharePoint) - Operator:
is equal to - Right:
Approved
✅ Nhánh Yes = gửi email
✅ Nhánh No = không làm gì
5.3 Gửi email cho nhân viên
Nhánh Yes → Add action → Send an email (V2)
- To:
EmployeeEmail - Subject:
Đơn nghỉ phép đã được duyệt - Body (gợi ý mẫu):
Chào @{triggerOutputs()?['body/EmployeeName']},
Đơn nghỉ phép của bạn đã được duyệt.
Loại nghỉ: @{triggerOutputs()?['body/LeaveType/Value']}
Thời gian: @{triggerOutputs()?['body/StartDate']} đến @{triggerOutputs()?['body/EndDate']}
Lý do: @{triggerOutputs()?['body/Reason']}
Trân trọng.
Nếu bạn dùng “Dynamic content” giao diện kéo-thả, hãy chọn đúng các trường: EmployeeName, LeaveType Value, StartDate, EndDate, Reason.
🧪 PHẦN 6: KIỂM THỬ THỰC TẾ (BẮT BUỘC LÀM)
Test 1 — Nhân viên gửi đơn
Mục tiêu: tạo đơn mới, Status phải là Pending
Thao tác:
- Vào
scrCreateRequest - Nhập:
- Name: Nguyễn Thị Lan
- Email: lan@contoso.com
- Department: HR
- LeaveType: Annual Leave
- Start/End: chọn 2 ngày bất kỳ
- Reason: Việc gia đình
- Bấm GỬI ĐƠN
Kết quả mong đợi:
- App báo “Đã gửi đơn thành công!”
- Trong SharePoint có dòng mới,
Status = Pending
Test 2 — Trưởng bộ phận duyệt
Mục tiêu: patch đổi Status → Approved
Thao tác:
- Vào
scrManager - Thấy đơn Pending vừa tạo
- Bấm icon ✔
Kết quả mong đợi:
- Status đổi thành Approved
- Đơn biến mất khỏi danh sách Pending (vì gallery đang lọc Pending)
Test 3 — Email tự động
Mục tiêu: Flow gửi email khi Approved
Thao tác:
- Sau khi duyệt, mở mailbox của
lan@contoso.com - Kiểm tra thư đến
Kết quả mong đợi:
- Nhận email với subject “Đơn nghỉ phép đã được duyệt”
- Nội dung có tên, loại nghỉ, thời gian
Nếu chưa có email: vào Flow → Run history → mở lần chạy mới nhất để xem lỗi (thường do thiếu connector Outlook hoặc sai trường Status Value).
🏁 KẾT QUẢ CUỐI BÀI
Bạn đã có:
- ✅ App xin nghỉ phép (nhân viên tạo đơn)
- ✅ Duyệt 1 cấp (trưởng bộ phận duyệt)
- ✅ Email tự động khi duyệt (Power Automate)