Tiền lương của giảng viên không chỉ dựa trên hệ số lương cơ bản mà còn phụ thuộc vào nhiều yếu tố như số tiết giảng dạy, hệ số bằng cấp, hệ số sinh viên, hệ số học phần.... Để khắc phục
Trang 1MỤC LỤC
Chương I: Tổng quan về phần mềm tính tiền lương cho
giảng viên 2
1.1.Mô tả bài toán 2
1.2.Sơ đồ Usecase tổng quát 4
1.3.Mô tả ngắn gọn các tác nhân 4
1.3.1.Giảng viên 4
1.3.2 Phòng Đào tạo 4
1.3.3.Trưởng khoa 4
1.3.4 Phòng Kế toán 5
Chương II: Kiến trúc hệ thống, công nghệ sử dụng 5
2.1 Kiến trúc tổng thể 5
2.2 Mô tả từng thành phần kiến trúc 6
2.3 Công nghệ sử dụng 8
CHƯƠNG III: CÀI ĐẶT CÁC CHỨC NĂNG 8
3.1 Cấu trúc thư mục 9
3.2 Cài đặt một số chức năng 10
3.2.1 Chức năng thêm giảng viên mới 10
3.2.2 Phân công giảng dạy 11
3.2.3 Thêm định mức tiền theo tiết 12
3.3 Mô tả cài đặt thuật toán tính tiền dạy 13
3.3.1 Công thức tổng quát 13
3.3.2 Cài đặt hàm tính tiền dạy 13
3.3.3 Ví dụ cụ thể 13
3.3.4 Cài đặt báo cáo tổng tiền dạy trong năm học 14
3.3.5 Kết luận 17
Trang 2BÁO CÁO CÀI ĐẶT
Chương I: Tổng quan về phần mềm tính tiền lương cho giảng viên.
1.1.Mô tả bài toán.
Trong các cơ sở giáo dục như trường đại học, việc tính lương cho giảng viên là một công việc quan trọng, phức tạp và đòi hỏi
độ chính xác cao Tiền lương của giảng viên không chỉ dựa trên
hệ số lương cơ bản mà còn phụ thuộc vào nhiều yếu tố như số tiết giảng dạy, hệ số bằng cấp, hệ số sinh viên, hệ số học
phần
Tuy nhiên, hiện nay nhiều trường vẫn còn thực hiện việc tính lương bằng phương pháp thủ công hoặc bán tự động thông qua Excel Điều này dẫn đến nhiều bất cập như:
Mất nhiều thời gian khi xử lý dữ liệu cho số lượng lớn giảng viên
Dễ xảy ra sai sót trong quá trình tính toán
Khó kiểm soát, tổng hợp và lưu trữ lịch sử lương
Thiếu tính linh hoạt trong việc cập nhật chính sách tiền lương, phụ cấp hay quy định mới từ nhà trường hoặc cơ quan quản lý giáo dục
Để khắc phục các vấn đề trên, bài toán đặt ra là xây dựng một phần mềm quản lý và tính tiền lương cho giảng viên với các chức năng chính như:
Quản lý thông tin giảng viên:
+ Quản lý danh mục bằng cấp: mã bằng cấp, tên bằng cấp, tên viết tắt
+ Quản lý khoa: Mã khoa, tên khoa
+ Quản lý giảng viên: Mã giảng viên, họ và tên, khoa, bằng cấp, email, sdt
Trang 3Quản lý lớp học phần:
+ Quản lý học phần
+ Quản lý kỳ học
+ Quản lý mở lớp học phần
+ Phân công giảng dạy cho giảng viên
Tính tiền dạy:
+ Tiền theo tiết
+ Hệ số bằng cấp
+ Hệ số sinh viên
+ Tính tiền dạy
Báo cáo:
+ Báo cáo theo năm
+ Theo khoa
+ Theo giảng viên
Cung cấp giao diện thân thiện, dễ sử dụng cho người quản trị
Mục tiêu của phần mềm là tự động hóa quá trình tính lương, giảm thiểu sai sót, tiết kiệm thời gian, nâng cao hiệu quả quản lý
và đảm bảo sự minh bạch, chính xác trong chi trả thu nhập cho giảng viên
1.2.Sơ đồ Usecase tổng quát.
1.3.Mô tả ngắn gọn các tác nhân.
1.3.1.Giảng viên
Trang 4Tra cứu thông tin cá nhân, lịch giảng dạy, số tiết đã dạy.
Kiểm tra tiền dạy được tính theo từng kỳ/học phần
1.3.2 Phòng Đào tạo
Quản lý và cập nhật thông tin lớp học phần, phân công giảng viên giảng dạy
Xác nhận khối lượng giảng dạy làm cơ sở tính tiền
1.3.3.Trưởng khoa
Quản lý thông tin giảng viên thuộc khoa
Xem báo cáo tình hình giảng dạy, xác nhận thông tin cho phòng
kế toán
1.3.4 Phòng Kế toán
Thực hiện chức năng tính tiền dạy dựa vào dữ liệu đã xác thực Tổng hợp và xuất báo cáo lương, chi trả cho giảng viên
Chương II: Kiến trúc hệ thống, công nghệ sử dụng
2.1 Kiến trúc tổng thể
Hệ thống được thiết kế và xây dựng theo mô hình kiến trúc 3 lớp (Three-tier Architecture) Đây là mô hình phổ biến và hiệu quả, thường được áp dụng trong các hệ thống thông tin hiện đại nhờ khả năng phân tách rõ ràng trách nhiệm của từng lớp, giúp
Trang 5hệ thống dễ bảo trì, dễ mở rộng, nâng cấp và đảm bảo an toàn thông tin
Cấu trúc kiến trúc 3 lớp bao gồm:
Lớp giao diện người dùng (Presentation Layer): Là nơi người dùng tương tác trực tiếp với hệ thống Tại đây, các chức năng như nhập liệu, hiển thị thông tin giảng viên, học phần, bảng lương, được thể hiện thông qua các giao diện trực quan, dễ sử dụng Giao diện có thể hoạt động trên nền tảng web hoặc thiết bị
di động tùy theo nhu cầu triển khai
Lớp xử lý nghiệp vụ (Business Logic Layer): Lớp này đóng vai trò trung gian giữa giao diện người dùng và cơ sở dữ liệu Tất cả các quy trình tính toán, kiểm tra điều kiện, xử lý nghiệp vụ như tính lương giảng viên, xác thực người dùng, phân quyền truy cập, đều được xử lý tại đây Đây là phần quan trọng nhất đảm bảo logic và quy định nghiệp vụ của hệ thống
Lớp dữ liệu (Data Access Layer): Đây là lớp làm nhiệm vụ quản
lý dữ liệu và giao tiếp với hệ quản trị cơ sở dữ liệu Tất cả các
dữ liệu của hệ thống như thông tin giảng viên, bảng lương, phân công giảng dạy, hệ số, định mức, người dùng, đều được lưu trữ và truy xuất tại lớp này
Việc áp dụng kiến trúc 3 lớp giúp đảm bảo hệ thống:
Có khả năng mở rộng theo từng thành phần riêng biệt
Dễ dàng bảo trì, nâng cấp khi có thay đổi
Đảm bảo tính bảo mật và hiệu năng
2.2 Mô tả từng thành phần kiến trúc
Giao diện người dùng (Frontend)
Trang 6Thành phần này là nơi tiếp nhận thao tác của người dùng thông qua trình duyệt web Giao diện được thiết kế đơn giản, trực quan, dễ sử dụng nhằm đáp ứng nhiều đối tượng người dùng khác nhau như: giảng viên, trưởng khoa, cán bộ kế toán hoặc quản trị viên
Các chức năng chính tại giao diện bao gồm:
Nhập thông tin số tiết giảng dạy
Xem bảng lương
Xác nhận và duyệt lương
Truy xuất các báo cáo và thống kê
Lớp xử lý nghiệp vụ (Backend / API Server)
Đây là thành phần xử lý các yêu cầu được gửi từ giao diện người dùng Dựa vào logic nghiệp vụ, hệ thống sẽ thực hiện:
Tính toán tiền lương dựa trên số tiết thực dạy, hệ số giảng viên, khối lượng giảng dạy so với định mức
Kiểm tra điều kiện hợp lệ trước khi cập nhật dữ liệu
Xử lý phân quyền, xác thực thông tin người dùng thông qua token
Gửi dữ liệu trả về lại cho frontend hiển thị
Cơ sở dữ liệu (Database)
Thành phần này chịu trách nhiệm lưu trữ toàn bộ dữ liệu của hệ thống Một số bảng dữ liệu quan trọng bao gồm:
Bảng thông tin giảng viên
Bảng phân công giảng dạy theo năm học, học kỳ
Trang 7Bảng định mức số tiết.
Bảng hệ số tính lương
Bảng bảng lương chi tiết theo từng giảng viên, theo tháng hoặc năm
Việc tổ chức dữ liệu hợp lý và chuẩn hóa giúp đảm bảo hiệu quả truy xuất, tránh trùng lặp, đồng thời dễ dàng tổng hợp và thống
kê khi cần
Hệ thống phân quyền người dùng
Hệ thống hỗ trợ nhiều vai trò người dùng với quyền hạn khác nhau như:
Admin: Quản lý toàn bộ hệ thống, thêm/sửa/xóa người dùng, phân quyền
Trưởng khoa: Xem thông tin giảng viên thuộc khoa mình, duyệt bảng lương
Cán bộ kế toán: Tính lương, xuất báo cáo, xác nhận bảng lương
Giảng viên: Xem bảng lương cá nhân và thông tin phân công giảng dạy
Cơ chế phân quyền đảm bảo mỗi người dùng chỉ có thể thao tác trên phạm vi chức năng được cấp phép
Module báo cáo và thống kê
Hệ thống tích hợp chức năng xuất báo cáo và thống kê như:
Tổng hợp bảng lương theo tháng, năm, theo khoa hoặc toàn trường
Xuất báo cáo sang file Excel hoặc PDF để phục vụ in ấn và lưu trữ
Trang 8Hiển thị biểu đồ lương, số tiết giảng dạy vượt định mức, nếu cần mở rộng sau này
2.3 Công nghệ sử dụng.
Giao diện người dùng HTML5, CSS3, JavaScript,
Bootstrap hoặc thư viện ReactJS
Xử lý nghiệp vụ Backend Nodejs với expressjs
Xác thực và bảo mật JSON Web Token (JWT), thư
viện bcrypt để mã hóa mật khẩu
Quản lý mã nguồn Git, GitHub hoặc GitLab
Công cụ phát triển Visual Studio Code
Môi trường triển khai Localhost
CHƯƠNG III: CÀI ĐẶT CÁC CHỨC NĂNG
3.1 Cấu trúc thư mục
Dự án được xây dựng theo kiến trúc phân tầng với Node.js, áp dụng mô hình MVC mở rộng để dễ bảo trì và mở rộng trong tương lai Cấu trúc thư mục của hệ thống như sau:
BackEnd-KT/
├── config/ // Cấu hình kết nối cơ sở dữ liệu, biến môi trường
│ └── db.js
│
├── node_modules/ // Thư viện phụ thuộc được cài bởi npm
│
├── src/ // Mã nguồn chính của hệ thống
Trang 9│ ├── controller/ // Xử lý logic cho từng chức năng cụ thể
│ │ ├── auth.js
│ │ ├── baocao.js
│ │ ├── degree.js
│ │ ├── dinhmuctiet.js
│ │ ├── Faculty.js
│ │ ├── hesobangcap.js
│ │ ├── hesolop.js
│ │ ├── hocphan.js
│ │ ├── kyhoc.js
│ │ ├── lopHocPhan.js
│ │ ├── phancong.js
│ │ ├── teacher.js
│ │ ├── tinhtienday.js
│ │ └── user.js
│ │
│ ├── middlewares/ // Middleware xử lý xác thực và phân quyền
│ │ └── auth.middleware.js
│ │
│ └── routers/ // Định nghĩa các tuyến API tương ứng với controller
│ ├── auth.routes.js
│ ├── teacher.routes.js
│ ├── luong.routes.js
│ └──
│
├── env // Tệp cấu hình biến môi trường (PORT, DB_URL, )
├── package.json // Khai báo thông tin dự án và thư viện sử dụng
├── package-lock.json // Khóa phiên bản thư viện
└── server.js // Điểm khởi động server ứng dụng
Mô hình này giúp tách biệt các phần xử lý logic nghiệp vụ, định tuyến, và truy cập dữ liệu, từ đó dễ dàng nâng cấp, mở rộng hoặc thay thế từng thành phần Đồng thời, mô hình phân lớp rõ
Trang 10ràng còn giúp quản lý mã nguồn tốt hơn khi làm việc nhóm hoặc phát triển lâu dài
3.2 Cài đặt một số chức năng
Trong hệ thống quản lý tiền dạy, có nhiều chức năng quan trọng, nhưng dưới đây sẽ trình bày chi tiết việc cài đặt một số chức năng tiêu biểu nhất Mỗi chức năng được triển khai dưới dạng API RESTful, nhận dữ liệu từ client, xử lý dữ liệu, truy vấn database thông qua thư viện Knex.js và trả về kết quả
3.2.1 Chức năng thêm giảng viên mới
Chức năng cho phép thêm mới giảng viên vào hệ thống bao gồm các thông tin như mã giảng viên, họ tên, học vị, mã khoa, Giúp nhà trường quản lý thông tin đội ngũ giảng viên
Mã nguồn: controller/teacher.js
const addTeacher = async(req, res)=>{
try {
const {ho_ten, ma_khoa, ma_bang_cap, sdt, email, ma_gv}
= req.body;
const [ma_gv1] = await db('giangvien').insert({
ho_ten,
ma_khoa,
ma_bang_cap,
ma_gv,
sdt,
});
const newTeacher = await
db('giangvien').select('*').where({ma_gv: ma_gv1});
res.json({
newTeacher: newTeacher,
message: "Thêm giảng viên thành công"
});
Trang 11} catch (error) {
console.log(error);
res.status(500).json({ message: "Lỗi server" });
}
};
3.2.2 Phân công giảng dạy
Chức năng này cho phép phân công giảng viên giảng dạy một lớp học phần cụ thể trong một kỳ học Mỗi bản ghi bao gồm mã giảng viên, lớp học phần, kỳ học, sĩ số lớp Việc phân công là cơ
sở để tính toán tiền dạy cho giảng viên
Mã nguồn: controller/phancong.js
const assignGiangVien = async (req, res) => {
try {
const { ma_gv, lop_hoc_phan_id, ky_hoc_id, si_so } =
req.body;
if (!ma_gv || !lop_hoc_phan_id || !ky_hoc_id) {
return res.status(400).json({ message: 'Thiếu thông tin phân công' });
}
const existed = await db('phancong_giangday')
where({ ma_gv, lop_hoc_phan_id, ky_hoc_id })
first();
if (existed) {
return res.status(400).json({ message: 'Phân công đã tồn tại' });
}
await db('phancong_giangday').insert({ ma_gv,
lop_hoc_phan_id, ky_hoc_id, si_so });
Trang 12res.status(201).json({ message: 'Phân công giảng viên thành công' });
} catch (error) {
console.error('Lỗi phân công:', error);
res.status(500).json({ message: 'Lỗi server' });
}
};
3.2.3 Thêm định mức tiền theo tiết
Chức năng này cho phép cập nhật mức tiền cho mỗi tiết học, thay đổi theo từng năm học Đây là yếu tố then chốt trong công thức tính lương giảng dạy
Mã nguồn: controller/dinhmuctiet.js
exports.create = async (req, res) => {
try {
const { nam_hoc, so_tien_mot_tiet, ghi_chu } = req.body; await db('dinh_muc_tiet').insert({ nam_hoc, so_tien_mot_tiet, ghi_chu });
res.sendStatus(200);
} catch (err) {
console.error(err);
res.status(500).send('Lỗi khi thêm');
}
};
3.3 Mô tả cài đặt thuật toán tính tiền dạy
3.3.1 Công thức tổng quát
Tiền_dạy_mỗi_lớp = Số_tiết_thực_tế × (Hệ_số_học_phần + Hệ_số_lớp) × Hệ_số_giáo_viên × Tiền_mỗi_tiết
Trong đó:
Số tiết thực tế: tổng số tiết giảng viên được phân công dạy
Hệ số học phần: phụ thuộc loại môn học
Trang 13Hệ số lớp: phụ thuộc vào sĩ số lớp học
Hệ số giáo viên: phụ thuộc vào học vị (Thạc sĩ, Tiến sĩ, ) Tiền mỗi tiết: được thiết lập theo từng năm học
3.3.2 Cài đặt hàm tính tiền dạy
Chi tiết mã cài đặt đã được trình bày ở phần trước, sử dụng các truy vấn để lấy thông tin giảng viên, lớp học phần, hệ số và áp dụng công thức tính toán
3.3.3 Ví dụ cụ thể
Giả sử:
Số tiết thực tế: 45
Hệ số học phần: 1.0
Hệ số lớp: 1.1
Hệ số giáo viên: 1.5
Tiền mỗi tiết: 60.000 VNĐ
=> Số tiết quy đổi: 45 * (1.0 + 1.1) = 94.5
=> Tiền dạy: 94.5 * 1.5 * 60.000 = 8.505.000 VNĐ
3.3.4 Cài đặt báo cáo tổng tiền dạy trong năm học
Chức năng này truy vấn tất cả lớp học phần mà mỗi giảng viên
đã dạy trong một năm học cụ thể, sau đó tính tổng tiền lương của họ bằng cách cộng dồn tiền dạy từng lớp
Mã nguồn: controller/baocao.js
const db = require(" / /config/db");
exports.baoCaoTienDay = async (req, res) => {
Trang 14try {
const { nam_hoc, ma_gv, ma_khoa } = req.query;
if (!nam_hoc) {
return res.status(400).json({ message: "Thiếu năm học" }); }
// 1 Lấy danh sách giảng viên
let gvQuery = db("giangvien as gv")
leftJoin("bangcap as bc", "gv.ma_bang_cap",
"bc.ma_bang_cap")
leftJoin("khoa as k", "gv.ma_khoa", "k.ma_khoa")
select(
"gv.ma_gv",
"gv.ho_ten",
"gv.ma_bang_cap",
"bc.ten_bang_cap",
"k.ten_khoa"
);
if (ma_gv) gvQuery = gvQuery.where("gv.ma_gv", ma_gv);
if (ma_khoa) gvQuery = gvQuery.where("gv.ma_khoa", ma_khoa);
const giangVienList = await gvQuery;
// 2 Lấy danh sách lớp phân công
const pcList = await db("phancong_giangday as pc")
join("lop_hoc_phan as lop", "pc.lop_hoc_phan_id",
"lop.id")
join("hocphan as hp", "lop.hoc_phan_id", "hp.STT")
join("kyhoc as ky", "pc.ky_hoc_id", "ky.id")
where("ky.nam_hoc", nam_hoc)
select(
"pc.ma_gv",
"lop.ma_lop_hp",
"lop.ten_lop_hp",
Trang 15"hp.ten_hp",
"hp.so_tiet",
"hp.he_so_hp",
"pc.si_so"
);
// 3 Lấy hệ số & định mức
const heSoBangCapList = await
db("he_so_bangcap").where({ nam_hoc });
const heSoSVList = await
db("he_so_sv").where({ nam_hoc });
const dinhMuc = await
db("dinh_muc_tiet").where({ nam_hoc }).first();
const tienMotTiet = dinhMuc?.so_tien_mot_tiet || 0;
const calcHeSoLop = (si_so) => {
for (const h of heSoSVList) {
if (si_so >= h.tu && si_so <= h.den) return
parseFloat(h.he_so);
}
return 1;
};
const ketQua = giangVienList.map((gv) => {
const pcGv = pcList.filter(p => p.ma_gv === gv.ma_gv); const hsb = heSoBangCapList.find(h => h.ma_bang_cap
=== gv.ma_bang_cap);
const he_so_gv = hsb?.he_so || 1;
let tong_so_tiet = 0;
let tong_tiet_qd = 0;
let tong_tien_day = 0;
const chi_tiet = pcGv.map((row, i) => {
const so_tiet = row.so_tiet || 0;
const he_so_hp = parseFloat(row.he_so_hp || 0);
const he_so_lop = calcHeSoLop(row.si_so || 0);