Thiết kế giao diện của lớp Trong chương này, chúng ta sẽ mô tả các giao diện của các lớp chính trong hệ thống quản lý.Các giao diện này cung cấp các phương thức cơ bản để thực hiện các t
Giới thiệu về đề tài
Giới thiệu đề tài
Trong thời đại số hóa, việc ứng dụng công nghệ thông tin vào quản lý quán cà phê trở nên thiết yếu để duy trì cạnh tranh và tăng trưởng Đề tài "Ứng dụng quản lý quán cà phê" phát triển một ứng dụng di động toàn diện nhằm tối ưu hóa quản lý và điều hành quán Ứng dụng hỗ trợ theo dõi đơn hàng, kiểm soát tồn kho và xử lý giao dịch tài chính hiệu quả, đồng thời cung cấp tính năng quản lý nhân viên, phân tích doanh thu và báo cáo chi tiết Đặc biệt, ứng dụng tích hợp quản lý khách hàng, giúp theo dõi lịch sử đơn hàng và sở thích, từ đó đề xuất khuyến mãi phù hợp Điều này nâng cao trải nghiệm khách hàng và hỗ trợ chủ quán đưa ra quyết định kinh doanh thông minh hơn Ứng dụng quản lý quán cà phê sẽ tối ưu hóa hoạt động, giảm sai sót và nâng cao hiệu quả công việc, góp phần vào sự thành công bền vững trong môi trường cạnh tranh khốc liệt hiện nay.
Kế hoạch thực hiện đề tài
Dự án phát triển hệ thống phần mềm sử dụng PostgreSQL làm cơ sở dữ liệu và Java theo nguyên tắc lập trình hướng đối tượng (OOP) Hệ thống tập trung vào quản lý dữ liệu hiệu quả, cung cấp giao diện người dùng trực quan và đảm bảo tính mở rộng, dễ bảo trì Các bước chính bao gồm thiết kế cơ sở dữ liệu, phát triển lớp đối tượng trong Java và tích hợp chúng để tạo ra hệ thống đồng nhất, hoạt động mượt mà.
Bước đầu tiên trong dự án là thiết kế và triển khai cơ sở dữ liệu bằng PostgreSQL, bao gồm việc xác định các bảng, mối quan hệ và chỉ mục cần thiết để tối ưu hóa hiệu suất truy vấn Chúng tôi sẽ thiết kế sơ đồ cơ sở dữ liệu phù hợp với cấu trúc và yêu cầu của ứng dụng, đảm bảo các thao tác dữ liệu diễn ra hiệu quả và nhất quán Các câu lệnh SQL sẽ được sử dụng để tạo ra các bảng và quy tắc toàn vẹn dữ liệu.
Trong quá trình phát triển ứng dụng, chúng tôi sẽ sử dụng Java và nguyên tắc lập trình hướng đối tượng để xây dựng các lớp và đối tượng cần thiết Điều này bao gồm việc tạo lớp mô tả thực thể trong cơ sở dữ liệu, triển khai các phương thức CRUD (Create, Read, Update, Delete), và thiết kế lớp điều khiển cho logic ứng dụng Chúng tôi sẽ áp dụng các nguyên tắc kế thừa, đóng gói và đa hình để tạo mã nguồn dễ bảo trì và mở rộng.
Giai đoạn cuối cùng của quá trình phát triển phần mềm bao gồm tích hợp hệ thống và kiểm thử để đảm bảo sự hoạt động hài hòa giữa các thành phần Chúng tôi sẽ thực hiện kiểm thử đơn vị để xác nhận từng lớp và phương thức hoạt động đúng như mong đợi Sau đó, kiểm thử tích hợp sẽ được tiến hành nhằm kiểm tra sự phối hợp giữa ứng dụng Java và cơ sở dữ liệu PostgreSQL Cuối cùng, các bài kiểm thử chức năng và hiệu suất sẽ được thực hiện để đảm bảo hệ thống đáp ứng đầy đủ các yêu cầu và tiêu chuẩn đã đề ra.
Các công nghệ sử dụng
PostgreSQL là hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở mạnh mẽ, nổi bật với tính năng mở rộng và khả năng xử lý giao dịch Hệ thống này được sử dụng để lưu trữ và quản lý dữ liệu, cung cấp hỗ trợ cho các loại dữ liệu phong phú, chỉ mục mạnh mẽ và khả năng mở rộng cao, từ đó tối ưu hóa hiệu suất và đảm bảo tính toàn vẹn của dữ liệu Ngoài ra, PostgreSQL cũng hỗ trợ các chức năng giao dịch ACID, đảm bảo rằng các thao tác dữ liệu được thực hiện một cách an toàn và chính xác.
Java là một ngôn ngữ lập trình hướng đối tượng nổi bật, được biết đến với tính di động và khả năng mở rộng Trong dự án này, Java sẽ được sử dụng để phát triển các thành phần của ứng dụng như lớp đối tượng, lớp điều khiển và giao diện người dùng Hệ sinh thái phong phú của Java, bao gồm thư viện và công cụ hỗ trợ lập trình, giúp rút ngắn thời gian phát triển và nâng cao hiệu suất ứng dụng Đặc biệt, Java OOP cho phép tổ chức mã nguồn một cách mô-đun, dễ bảo trì và hỗ trợ các nguyên tắc lập trình như kế thừa, đa hình và đóng gói.
JDBC là một API trong Java cho phép kết nối và thao tác với cơ sở dữ liệu, trong dự án này, nó sẽ được sử dụng để thiết lập kết nối giữa ứng dụng Java và cơ sở dữ liệu PostgreSQL JDBC cung cấp các lớp và giao diện để thực hiện các câu lệnh SQL, đồng thời xử lý kết quả trả về từ cơ sở dữ liệu, giúp tích hợp dữ liệu vào ứng dụng một cách dễ dàng và hiệu quả.
Hình 3 JDBC (Java Database Connectivity)
Spring Framework là nền tảng mã nguồn mở cho phát triển ứng dụng Java, nổi bật trong việc hỗ trợ phát triển ứng dụng doanh nghiệp và ứng dụng web.
Spring là một framework mạnh mẽ giúp quản lý các thành phần của ứng dụng, xử lý yêu cầu HTTP và tích hợp với cơ sở dữ liệu Với các tính năng như Dependency Injection và Aspect-Oriented Programming, cùng với các module hỗ trợ phát triển web, Spring không chỉ đơn giản hóa quá trình xây dựng ứng dụng mà còn nâng cao khả năng bảo trì của chúng.
Maven là công cụ quản lý dự án và xây dựng cho Java, giúp tự động hóa quy trình xây dựng và quản lý phụ thuộc Trong dự án này, Maven sẽ quản lý thư viện và plugin cần thiết, cấu hình quy trình xây dựng, và đảm bảo tất cả thành phần được xây dựng và triển khai đồng nhất Maven cung cấp cách tiếp cận tiêu chuẩn để quản lý dự án, cải thiện khả năng phối hợp và tổ chức mã nguồn.
Phân công công việc
Tên Mã sinh viên Công việc
Phân công nhóm, triển khai interface và CRUD, Database
Viết interface Tạo giao diện
Bảng 1 Phân công công việc
Kết chương 1
Chương 1 đã trình bày tổng quan về dự án phát triển ứng dụng sử dụng PostgreSQL và Java OOP, nêu rõ mục tiêu và phạm vi của hệ thống phần mềm dự kiến Mục tiêu chính của dự án là xây dựng một ứng dụng hiệu quả, có khả năng mở rộng và dễ bảo trì bằng cách kết hợp các công nghệ tiên tiến Cơ sở dữ liệu sẽ được thiết kế và triển khai sử dụng PostgreSQL, một hệ quản trị cơ sở dữ liệu quan hệ mã nguồn mở, nổi bật với khả năng xử lý giao dịch mạnh mẽ và hỗ trợ các loại dữ liệu phong phú Điều này đảm bảo rằng hệ thống quản lý dữ liệu hoạt động ổn định và cung cấp hiệu suất tối ưu trong suốt quá trình sử dụng.
Trong quá trình phát triển ứng dụng, ngôn ngữ lập trình Java được áp dụng với nguyên tắc lập trình hướng đối tượng (OOP), cho phép xây dựng lớp đối tượng và lớp điều khiển hiệu quả, giúp mã nguồn dễ bảo trì JDBC kết nối ứng dụng Java với cơ sở dữ liệu PostgreSQL, thực hiện câu lệnh SQL và xử lý dữ liệu trả về, tạo cầu nối vững chắc giữa ứng dụng và cơ sở dữ liệu Đối với giao diện người dùng, JFrame từ thư viện Swing cung cấp khả năng tạo giao diện đồ họa đơn giản và hiệu quả Maven được sử dụng để quản lý phụ thuộc và quy trình xây dựng, đảm bảo sự đồng nhất và tổ chức cho toàn bộ dự án Sự kết hợp của các công nghệ này không chỉ đảm bảo tính hiệu quả và bảo mật mà còn tạo điều kiện thuận lợi cho việc mở rộng và bảo trì ứng dụng trong tương lai, góp phần đạt được các mục tiêu và mang lại giá trị thực tiễn cho người dùng.
Mô hình hệ thống
Mô hình chức năng
Hình 6 Mô hình chức năng hệ thống
Thiết kế giao diện của lớp
Trong chương này, chúng ta sẽ trình bày các giao diện của các lớp chính trong hệ thống quản lý, cung cấp phương thức cơ bản để thực hiện các thao tác quản lý đối tượng Dưới đây là mô tả chi tiết về các giao diện lớp.
Mô tả: Giao diện ISanPham định nghĩa các phương thức cần thiết để thực hiện các thao tác với sản phẩm trong hệ thống.
Thêm một sản phẩm mới vào hệ thống Phương thức trả về true nếu việc thêm sản phẩm thành công, ngược lại trả về false.
Cập nhật thông tin sản phẩm trong hệ thống với phương thức trả về true khi cập nhật thành công và false khi không thành công.
Xóa sản phẩm dựa trên mã sản phẩm (id) Phương thức trả về true nếu việc xóa thành công, ngược lại trả về false.
Tìm kiếm sản phẩm dựa trên mã sản phẩm (id) Phương thức trả về đối tượng SanPham nếu tìm thấy, ngược lại trả về null.
Lấy danh sách tất cả các sản phẩm trong hệ thống Phương thức trả về danh sách các đối tượng SanPham.
Mô tả: Giao diện IKhachHang định nghĩa các phương thức cần thiết để thực hiện các thao tác với khách hàng trong hệ thống.
Thêm một khách hàng mới vào hệ thống Phương thức trả về true nếu việc thêm khách hàng thành công, ngược lại trả về false.
Cập nhật thông tin khách hàng đã có trong hệ thống, phương thức sẽ trả về true nếu cập nhật thành công; nếu không, sẽ trả về false.
Xóa khách hàng dựa trên mã khách hàng (id) Phương thức trả về true nếu việc xóa thành công, ngược lại trả về false.
Tìm kiếm khách hàng dựa trên mã khách hàng (id) Phương thức trả về đối tượng KhachHang nếu tìm thấy, ngược lại trả về null.
Lấy danh sách tất cả các khách hàng trong hệ thống Phương thức trả về danh sách các đối tượng KhachHang.
Mô tả: Giao diện IHoaDon định nghĩa các phương thức cần thiết để thực hiện các thao tác với hóa đơn trong hệ thống.
Thêm một hóa đơn mới vào hệ thống Phương thức trả về true nếu việc thêm hóa đơn thành công, ngược lại trả về false.
Cập nhật thông tin hóa đơn đã có trong hệ thống Phương thức sẽ trả về true nếu việc cập nhật thành công, ngược lại sẽ trả về false.
Xóa hóa đơn dựa trên mã hóa đơn (id) Phương thức trả về true nếu việc xóa thành công, ngược lại trả về false.
Tìm kiếm hóa đơn dựa trên mã hóa đơn (id) Phương thức trả về đối tượng HoaDon nếu tìm thấy, ngược lại trả về null.
Lấy danh sách tất cả các hóa đơn trong hệ thống Phương thức trả về danh sách các đối tượng HoaDon.
Mô tả: Giao diện IChiTietHoaDon định nghĩa các phương thức cần thiết để thực hiện các thao tác với chi tiết hóa đơn trong hệ thống.
Thêm một chi tiết hóa đơn mới vào hệ thống Phương thức trả về true nếu việc thêm chi tiết hóa đơn thành công, ngược lại trả về false.
Cập nhật thông tin cho một chi tiết hóa đơn đã có trong hệ thống Phương thức sẽ trả về true nếu việc cập nhật thành công, ngược lại sẽ trả về false.
Xóa chi tiết hóa đơn dựa trên mã chi tiết hóa đơn (id) Phương thức trả về true nếu việc xóa thành công, ngược lại trả về false.
Tìm kiếm chi tiết hóa đơn dựa trên mã chi tiết hóa đơn (id) Phương thức trả về đối tượng ChiTietHoaDon nếu tìm thấy, ngược lại trả về null.
Lấy danh sách tất cả các chi tiết hóa đơn trong hệ thống Phương thức trả về danh sách các đối tượng ChiTietHoaDon.
Mô hình kiến trúc hệ thống
Mô hình kiến trúc hệ thống của dự án được thiết kế nhằm quản lý các đối tượng quan trọng như hóa đơn, chi tiết hóa đơn, khách hàng và sản phẩm Hệ thống áp dụng các lớp dịch vụ và lớp kế thừa để cung cấp các chức năng nghiệp vụ cần thiết, đồng thời đảm bảo tính mở rộng và dễ bảo trì Các lớp dịch vụ giữ vai trò trung tâm trong việc xử lý dữ liệu, trong khi lớp kế thừa cụ thể hóa chức năng cho từng loại đối tượng quản lý.
Lớp dịch vụ là thành phần quan trọng trong hệ thống, cung cấp các phương thức nghiệp vụ cho các thao tác cơ bản trên các đối tượng quản lý Nó sử dụng giao diện để đảm bảo tính linh hoạt và cho phép thay thế các phần tử cụ thể mà không làm ảnh hưởng đến toàn bộ hệ thống.
Lớp caffee là lớp cơ sở dịch vụ quan trọng, đảm nhiệm việc xử lý hóa đơn, chi tiết hóa đơn, thông tin khách hàng và sản phẩm Lớp này tương tác với các đối tượng dữ liệu thông qua các giao diện như IHoaDon, IChiTietHoaDon, IKhachHang và ISanPham.
IHoaDon hoaDonRepo là giao diện cho phép thực hiện các thao tác liên quan đến đối tượng hóa đơn, bao gồm thêm, sửa, xóa và tìm kiếm hóa đơn Thuộc tính này rất quan trọng trong lớp caffee, giúp quản lý hóa đơn một cách hiệu quả và thuận tiện.
IChiTietHoaDon chiTietHoaDonRepo là một đối tượng quan trọng trong việc quản lý chi tiết hóa đơn, cung cấp các phương thức cần thiết để thêm, sửa, xóa và tìm kiếm thông tin chi tiết hóa đơn một cách hiệu quả.
IKhachHang khachHangRepo là một thuộc tính quan trọng trong lớp caffee, cho phép thực hiện các thao tác quản lý đối tượng khách hàng Nó hỗ trợ các chức năng như thêm, sửa, xóa và tìm kiếm thông tin khách hàng một cách hiệu quả.
ISanPham sanPhamRepo là giao diện thực hiện các thao tác với đối tượng sản phẩm, cho phép lớp caffee thực hiện các chức năng như thêm, sửa, xóa và tìm kiếm sản phẩm một cách hiệu quả.
themHoaDon(HoaDon hoaDon): Thêm một hóa đơn mới vào hệ thống.
suaHoaDon(HoaDon hoaDon): Cập nhật thông tin của một hóa đơn đã tồn tại.
xoaHoaDon(String id): Xóa hóa đơn theo ID.
themChiTietHoaDon(ChiTietHoaDon chiTietHoaDon): Thêm một chi tiết hóa đơn mới vào hệ thống.
suaChiTietHoaDon(ChiTietHoaDon chiTietHoaDon): Cập nhật thông tin của một chi tiết hóa đơn đã tồn tại.
xoaChiTietHoaDon(String id): Xóa chi tiết hóa đơn theo ID.
themKhachHang(KhachHang khachHang): Thêm một khách hàng mới vào hệ thống.
suaKhachHang(KhachHang khachHang): Cập nhật thông tin của một khách hàng đã tồn tại.
xoaKhachHang(String id): Xóa khách hàng theo ID.
themSanPham(SanPham sanPham): Thêm một sản phẩm mới vào hệ thống.
suaSanPham(SanPham sanPham): Cập nhật thông tin của một sản phẩm đã tồn tại.
xoaSanPham(String id): Xóa sản phẩm theo ID.
Các lớp kế thừa từ lớp caffee mở rộng và cụ thể hóa chức năng cho từng loại đối tượng quản lý Mỗi lớp kế thừa cung cấp các phương thức cụ thể để thao tác với đối tượng dữ liệu của nó, đồng thời tận dụng các phương thức cơ bản đã được định nghĩa trong lớp caffee.
Lớp SanPhamLG kế thừa từ lớp caffee, chuyên trách các nghiệp vụ liên quan đến sản phẩm Lớp này sử dụng giao diện ISanPham để thực hiện các thao tác với dữ liệu sản phẩm, bao gồm tìm kiếm sản phẩm theo ID và lấy danh sách tất cả các sản phẩm.
Phương thức timKiemSanPham(String id) cho phép tìm kiếm sản phẩm dựa trên ID và trả về danh sách sản phẩm tương ứng Trước khi thêm sản phẩm vào danh sách kết quả, phương thức này sẽ kiểm tra xem sản phẩm có tồn tại hay không.
getAllSanPham(): Lấy danh sách tất cả sản phẩm hiện có trong hệ thống.
Lớp KhachHangLG, kế thừa từ lớp caffee, thực hiện các nghiệp vụ liên quan đến khách hàng Lớp này sử dụng giao diện IKhachHang để thao tác với dữ liệu khách hàng, bao gồm tìm kiếm theo ID và lấy danh sách tất cả khách hàng.
Phương thức timKiemKhachHang(String id) cho phép tìm kiếm khách hàng dựa trên ID và trả về danh sách khách hàng phù hợp Trước khi thêm khách hàng vào danh sách kết quả, phương thức này sẽ kiểm tra xem khách hàng có tồn tại hay không.
getAllKhachHang(): Lấy danh sách tất cả khách hàng hiện có trong hệ thống.
Lớp HoaDonLG kế thừa từ lớp caffee và chuyên xử lý các nghiệp vụ liên quan đến hóa đơn Lớp này sử dụng giao diện IHoaDon để thực hiện các thao tác với dữ liệu hóa đơn, bao gồm tìm kiếm hóa đơn theo ID và lấy danh sách tất cả các hóa đơn.
Phương thức timKiemHoaDon(String id) cho phép tìm kiếm hóa đơn dựa trên ID, đồng thời trả về danh sách các hóa đơn tương ứng Trước khi thêm hóa đơn vào danh sách kết quả, phương thức này sẽ kiểm tra xem hóa đơn đó có tồn tại hay không.
getAllHoaDon(): Lấy danh sách tất cả hóa đơn hiện có trong hệ thống.
Lớp ChiTietHoaDonLG kế thừa từ lớp caffee và thực hiện các nghiệp vụ liên quan đến chi tiết hóa đơn Lớp này sử dụng giao diện IChiTietHoaDon để thao tác với dữ liệu chi tiết hóa đơn, bao gồm việc tìm kiếm theo ID và lấy danh sách tất cả các chi tiết hóa đơn.
Mô hình cơ sở dữ liệu
Mô hình cơ sở dữ liệu đóng vai trò quan trọng trong thiết kế hệ thống, giúp tổ chức và quản lý dữ liệu hiệu quả Trong hệ thống quản lý hóa đơn và khách hàng, mô hình này bao gồm bốn bảng chính: SanPham, KhachHang, HoaDon, và ChiTietHoaDon Mỗi bảng được thiết kế nhằm lưu trữ thông tin quan trọng về sản phẩm, khách hàng, hóa đơn và chi tiết hóa đơn.
Bảng SanPham lưu trữ thông tin chi tiết về các sản phẩm có sẵn trong hệ thống, với mỗi sản phẩm được xác định bằng một mã định danh duy nhất Bảng này bao gồm các thuộc tính quan trọng như tên sản phẩm và giá cả, cùng với các cột chính để quản lý thông tin hiệu quả.
Mã định danh sản phẩm (id) là một chuỗi ký tự dài 10, đóng vai trò là khóa chính trong bảng Cột này đảm bảo mỗi sản phẩm trong hệ thống có một mã định danh duy nhất, không bị trùng lặp.
ten (VARCHAR(100)): Cột này lưu tên của sản phẩm Tên sản phẩm giúp người dùng nhận diện và phân loại sản phẩm trong hệ thống.
Cột "gia" (INT) lưu trữ giá sản phẩm tính bằng đồng, là thông tin quan trọng để tính tổng tiền trong hóa đơn.
Bảng KhachHang lưu trữ thông tin chi tiết về khách hàng, bao gồm tên, địa chỉ email và số điện thoại Các cột chính trong bảng này cung cấp cái nhìn tổng quan về dữ liệu khách hàng.
Mã định danh khách hàng (id) là một chuỗi ký tự có độ dài tối đa 10, đóng vai trò là khóa chính trong bảng dữ liệu Cột này đảm bảo rằng mỗi khách hàng trong hệ thống đều có một mã định danh duy nhất, không bị trùng lặp.
ten (VARCHAR(100)): Cột này lưu tên của khách hàng Tên khách hàng là thông tin quan trọng để nhận diện và quản lý khách hàng trong hệ thống.
email (VARCHAR(100)): Cột này lưu địa chỉ email của khách hàng Email được sử dụng để gửi thông báo và liên hệ với khách hàng.
Cột so_dien_thoai (VARCHAR(15)) lưu trữ số điện thoại của khách hàng, được sử dụng để liên hệ trực tiếp khi cần thiết.
Bảng HoaDon lưu trữ thông tin chi tiết về các hóa đơn được tạo ra trong hệ thống, mỗi hóa đơn đều liên kết với một khách hàng cụ thể Thông tin trong bảng bao gồm ngày lập hóa đơn và tổng số tiền phải thanh toán Các cột chính trong bảng HoaDon bao gồm các dữ liệu quan trọng liên quan đến hóa đơn.
Mã định danh hóa đơn (id) là một chuỗi ký tự dài 10, đảm bảo tính duy nhất cho mỗi hóa đơn trong hệ thống Cột này được xác định là khóa chính (Primary Key) của bảng, giúp ngăn chặn sự trùng lặp và đảm bảo rằng mỗi hóa đơn đều có một mã riêng biệt.
Cột id_khach_hang (VARCHAR(10)) là khóa ngoại, tham chiếu đến mã định danh của khách hàng trong bảng KhachHang, giúp liên kết hóa đơn với khách hàng cụ thể.
ngay_lap (DATE): Cột này lưu trữ ngày lập hóa đơn Ngày lập hóa đơn là thông tin quan trọng để theo dõi thời điểm xuất hóa đơn.
Cột "tong_tien" (INT) lưu trữ tổng số tiền của hóa đơn, được tính bằng đơn vị tiền tệ (đồng) Tổng tiền hóa đơn được xác định dựa trên các sản phẩm và số lượng tương ứng của chúng.
Bảng ChiTietHoaDon lưu trữ thông tin chi tiết về sản phẩm trong từng hóa đơn, liên kết hóa đơn với các sản phẩm cụ thể Bảng này chứa thông tin về số lượng và giá của từng sản phẩm, với các cột chính bao gồm:
Mã định danh chi tiết hóa đơn (id) là một chuỗi ký tự dài 10, giữ vai trò là khóa chính trong bảng Cột này đảm bảo rằng mỗi chi tiết hóa đơn trong hệ thống có một mã định danh duy nhất, không bị trùng lặp.
Cột id_hoa_don (VARCHAR(10)) là khóa ngoại, tham chiếu đến mã định danh của hóa đơn trong bảng HoaDon, giúp liên kết chi tiết hóa đơn với hóa đơn cụ thể.
Cột id_san_pham (VARCHAR(10)) là khóa ngoại tham chiếu đến mã định danh của sản phẩm trong bảng SanPham, giúp liên kết chi tiết hóa đơn với sản phẩm cụ thể.
so_luong (INT): Cột này lưu trữ số lượng sản phẩm trong chi tiết hóa đơn Số lượng được sử dụng để tính toán tổng tiền của hóa đơn.
Giao diện người dùng
Trang Main của ứng dụng Quản lý Highlands Coffee là giao diện chính, cho phép người dùng truy cập và điều hướng đến các chức năng quan trọng Giao diện này được thiết kế trực quan và dễ sử dụng, giúp người dùng thao tác hiệu quả và nhanh chóng.
Trang Main được phát triển dựa trên lớp MainForm, kế thừa từ javax.swing.JFrame, tạo ra một khung cơ bản cho giao diện đồ họa Giao diện này bao gồm các thành phần điều khiển và tích hợp các chức năng chính của hệ thống thông qua nút bấm và các thành phần hiển thị khác.
Chức năng của khu vực này là làm nơi chứa chính cho các thành phần giao diện khác, được thiết kế nhằm tạo ra một không gian gọn gàng và rõ ràng cho các thành phần điều khiển trong ứng dụng.
Hình thức giao diện với nền màu đỏ (RGB: 255, 0, 51) không chỉ tạo sự nổi bật và dễ nhận diện, mà còn nâng cao tính thẩm mỹ và nhấn mạnh các phần quan trọng của giao diện.
Sử dụng javax.swing.GroupLayout để bố trí các thành phần con giúp căn chỉnh chính xác và hài hòa các nút bấm và nhãn.
Chức năng: Hiển thị tiêu đề của ứng dụng, "QUẢN LÝ HIGHLANDS COFFEE", nhằm cung cấp thông tin rõ ràng về mục đích của ứng dụng.
Sử dụng font chữ lớn (36) và kiểu chữ đậm (Font("Segoe UI", 1, 36)) cho tiêu đề giúp nó dễ đọc và nổi bật trên giao diện Điều này không chỉ hỗ trợ người dùng nhận diện ứng dụng ngay từ cái nhìn đầu tiên mà còn mang lại cảm giác chuyên nghiệp.
Chức năng: Nút bấm "Quản lý sản phẩm" cho phép người dùng truy cập vào giao diện quản lý sản phẩm.
Hình thức được thiết kế nhằm thu hút sự chú ý và dễ dàng nhận diện, với ActionListener được gán để mở cửa sổ SanPhamForm khi người dùng nhấn nút Điều này cho phép quản lý danh sách sản phẩm trong hệ thống một cách hiệu quả.
Chức năng: Nút bấm "Quản lý khách hàng" cho phép người dùng truy cập vào giao diện quản lý thông tin khách hàng.
Hình thức giúp người dùng dễ dàng truy cập thông tin liên quan đến khách hàng ActionListener được sử dụng để mở cửa sổ KhachHangForm, cho phép người dùng thực hiện các thao tác thêm, sửa hoặc xóa thông tin khách hàng một cách thuận tiện.
Chức năng: Nút bấm "Quản lý hóa đơn" cung cấp quyền truy cập vào giao diện quản lý hóa đơn.
Hình thức này được thiết kế để hỗ trợ người dùng trong việc quản lý hóa đơn một cách dễ dàng Khi nhấn nút, cửa sổ HoaDonForm sẽ mở ra, cho phép người dùng thực hiện các thao tác liên quan đến hóa đơn một cách thuận tiện.
Chức năng: Nút bấm "Chi tiết hóa đơn" cho phép người dùng truy cập vào giao diện chi tiết hóa đơn.
Hình thức: Được gán ActionListener để mở cửa sổ ChiTietHoaDonForm, nơi người dùng có thể xem và quản lý các chi tiết liên quan đến từng hóa đơn.
Bố trí các thành phần:
Các nút bấm được bố trí theo hàng ngang, giúp người dùng dễ dàng nhận diện và truy cập các chức năng chính một cách rõ ràng và thuận tiện.
Các nút bấm được căn chỉnh với khoảng cách đều nhau, mang lại giao diện gọn gàng và dễ sử dụng Sự sắp xếp này không chỉ giúp tránh nhầm lẫn mà còn tạo cảm giác hài hòa cho người dùng.
Kích thước và thiết kế nút bấm rất quan trọng, với kích thước đồng nhất 150x50 pixels giúp tạo sự đồng bộ và dễ sử dụng Kích thước này đảm bảo người dùng có thể dễ dàng nhấn vào mà không gặp bất tiện.
Sử dụng màu sắc nổi bật và font chữ lớn không chỉ giúp tăng cường khả năng đọc mà còn cải thiện trải nghiệm người dùng Điều này đặc biệt quan trọng để đảm bảo rằng các chức năng chính được làm nổi bật, giúp người dùng dễ dàng nhận diện và tương tác.
Thêm Xử Lý Sự Kiện:
Mỗi nút bấm trong hệ thống được gán một ActionListener riêng biệt để xử lý các hành động của người dùng Khi người dùng nhấn một nút, cửa sổ tương ứng sẽ mở ra, cho phép thực hiện các thao tác liên quan đến chức năng của nút đó.
Các sự kiện tương tác người dùng được tổ chức nhằm nâng cao trải nghiệm sử dụng ứng dụng, giúp người dùng dễ dàng tiếp cận và sử dụng các chức năng của hệ thống một cách hiệu quả hơn.
Các tiện ích
Trong bài viết này, chúng tôi sẽ trình bày các tiện ích của hệ thống liên quan đến quản lý hóa đơn, chi tiết hóa đơn, khách hàng và sản phẩm Những tiện ích này không chỉ nâng cao khả năng quản lý mà còn cải thiện thao tác với dữ liệu trong hệ thống Dưới đây là phần mô tả chi tiết về các lớp xử lý nghiệp vụ.
Lớp caffee là lớp cơ sở cung cấp các phương thức cơ bản để thao tác với các đối tượng như hóa đơn, chi tiết hóa đơn, khách hàng và sản phẩm Nó cho phép thực hiện các thao tác thêm, sửa và xóa thông qua các giao diện tương ứng.
Phương thức thêm hóa đơn: themHoaDon(HoaDon hoaDon)
Phương thức sửa hóa đơn: suaHoaDon(HoaDon hoaDon)
Phương thức xóa hóa đơn: xoaHoaDon(String id)
Phương thức thêm chi tiết hóa đơn: themChiTietHoaDon(ChiTietHoaDon chiTietHoaDon)
Phương thức sửa chi tiết hóa đơn: suaChiTietHoaDon(ChiTietHoaDon chiTietHoaDon)
Phương thức xóa chi tiết hóa đơn: xoaChiTietHoaDon(String id)
Phương thức thêm khách hàng: themKhachHang(KhachHang khachHang)
Phương thức sửa khách hàng: suaKhachHang(KhachHang khachHang)
Phương thức xóa khách hàng: xoaKhachHang(String id)
Phương thức thêm sản phẩm: themSanPham(SanPham sanPham)
Phương thức sửa sản phẩm: suaSanPham(SanPham sanPham)
Phương thức xóa sản phẩm: xoaSanPham(String id)
Lớp SanPhamLG mở rộng lớp caffee và cung cấp các chức năng nghiệp vụ cho việc quản lý sản phẩm:
Tìm kiếm sản phẩm theo ID: timKiemSanPham(String id) - Phương thức này tìm kiếm sản phẩm theo ID và trả về danh sách chứa sản phẩm tìm được.
Lấy tất cả sản phẩm: getAllSanPham() - Phương thức này trả về danh sách tất cả sản phẩm hiện có trong hệ thống.
Lớp KhachHangLG kế thừa từ lớp caffee và cung cấp các chức năng nghiệp vụ cho việc quản lý khách hàng:
Tìm kiếm khách hàng theo ID: timKiemKhachHang(String id) - Phương thức này tìm kiếm khách hàng theo ID và trả về danh sách chứa khách hàng tìm được.
Lấy tất cả khách hàng: getAllKhachHang() - Phương thức này trả về danh sách tất cả khách hàng hiện có trong hệ thống.
Lớp HoaDonLG kế thừa từ lớp caffee và cung cấp các chức năng nghiệp vụ cho việc quản lý hóa đơn:
Tìm kiếm hóa đơn theo ID: timKiemHoaDon(String id) - Phương thức này tìm kiếm hóa đơn theo ID và trả về danh sách chứa hóa đơn tìm được.
Lấy tất cả hóa đơn: getAllHoaDon() - Phương thức này trả về danh sách tất cả hóa đơn hiện có trong hệ thống.
Lớp ChiTietHoaDonLG kế thừa từ lớp caffee và cung cấp các chức năng nghiệp vụ cho việc quản lý chi tiết hóa đơn:
Phương thức timKiemChiTietHoaDon(String id) cho phép người dùng tìm kiếm chi tiết hóa đơn dựa trên ID, và sẽ trả về danh sách các chi tiết hóa đơn đã tìm thấy.
Lấy tất cả chi tiết hóa đơn: getAllChiTietHoaDon() - Phương thức này trả về danh sách tất cả chi tiết hóa đơn hiện có trong hệ thống.
Kết chương 2
Trong chương 2, chúng tôi đã mô tả chi tiết mô hình hệ thống của ứng dụng quản lý hóa đơn, bao gồm các đối tượng chính như hóa đơn, chi tiết hóa đơn, khách hàng và sản phẩm Chương này nhấn mạnh việc xây dựng cấu trúc dữ liệu hợp lý và hiệu quả, cùng với các chức năng nghiệp vụ cần thiết để quản lý hệ thống một cách tốt nhất.
Chúng tôi mô tả các lớp chính như caffee, SanPhamLG, KhachHangLG, HoaDonLG, và ChiTietHoaDonLG, đóng vai trò quan trọng trong quản lý và thao tác dữ liệu Các lớp này cung cấp chức năng thêm, sửa, xóa và tìm kiếm cho hóa đơn, chi tiết hóa đơn, khách hàng và sản phẩm Sự kế thừa giữa các lớp cùng với việc sử dụng giao diện đã giúp đơn giản hóa mã nguồn và nâng cao tính mở rộng của hệ thống.
Các lớp trong hệ thống cung cấp nhiều tiện ích quan trọng cho việc quản lý, chẳng hạn như lớp SanPhamLG giúp tìm kiếm và quản lý sản phẩm, lớp KhachHangLG hỗ trợ quản lý khách hàng, và lớp HoaDonLG cùng ChiTietHoaDonLG cung cấp chức năng cho hóa đơn và chi tiết hóa đơn Những lớp này không chỉ thực hiện các thao tác cơ bản mà còn cung cấp phương thức truy xuất dữ liệu cần thiết cho phân tích và báo cáo.
Chương này trình bày các lớp và phương thức, thể hiện một thiết kế hệ thống có cấu trúc rõ ràng Việc phân chia chức năng theo lớp không chỉ giúp bảo trì mà còn tạo điều kiện mở rộng hệ thống trong tương lai Hơn nữa, sự kế thừa và giao diện góp phần nâng cao tính tái sử dụng và linh hoạt của mã nguồn.
Kết thúc chương này, chúng tôi đã xây dựng một nền tảng vững chắc cho việc phát triển và triển khai hệ thống Các mô hình và lớp đã được trình bày sẽ là cơ sở cho các bước phát triển tiếp theo, bao gồm tích hợp giao diện người dùng và kiểm thử hệ thống Chương tiếp theo sẽ tập trung vào phát triển giao diện người dùng, nhằm đảm bảo người dùng dễ dàng tương tác và thực hiện các thao tác quản lý hiệu quả.
Phát triển hệ thống
Phát triển các giao diện
Giao diện ISanPham: import DB.SanPham; import java.util.List; public interface ISanPham { boolean themSanPham(SanPham sanPham); boolean suaSanPham(SanPham sanPham); boolean xoaSanPham(String id);
Giao diện IKhachHang: import DB.KhachHang; import java.util.List; public interface IKhachHang { boolean themKhachHang(KhachHang khachHang); boolean suaKhachHang(KhachHang khachHang); boolean xoaKhachHang(String id);
Giao diện IHoaDon: import DB.HoaDon; import java.util.List; public interface IHoaDon { boolean themHoaDon(HoaDon hoaDon); boolean suaHoaDon(HoaDon hoaDon); boolean xoaHoaDon(String id);
Giao diện IChiTietHoaDon: import DB.ChiTietHoaDon; import java.util.List; public interface IChiTietHoaDon { boolean themChiTietHoaDon(ChiTietHoaDon chiTietHoaDon); boolean suaChiTietHoaDon(ChiTietHoaDon chiTietHoaDon); boolean xoaChiTietHoaDon(String id);
Phát triển các lớp, triển khai các giao diện
The `SanPhamDB` class implements the `ISanPham` interface and establishes a connection to the database using the `KetNoi` class It initializes a `Connection` object within its constructor, ensuring that the connection to the database is successfully established for further operations.
@Override public boolean themSanPham(SanPham sanPham) { try {
To insert a new product into the SanPham table, use the SQL query "INSERT INTO SanPham (id, ten, gia) VALUES (?, ?, ?)" Prepare the statement with the connection object and set the parameters using the product's ID, name, and price Execute the update and return true if the operation affected more than zero rows, indicating a successful insertion.
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean suaSanPham(SanPham sanPham) { try {
To update a product's name and price in the database, use the SQL query "UPDATE SanPham SET ten = ?, gia = ? WHERE id = ?" Create a PreparedStatement with this query and set the product's name, price, and ID using `pstmt.setString()` and `pstmt.setInt()` Execute the update with `pstmt.executeUpdate()`, and return true if the operation affected one or more rows.
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean xoaSanPham(String id) { try {
String query = "DELETE FROM SanPham WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public SanPham timKiemSanPham(String id) { try {
String query = "SELECT * FROM SanPham WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id);
ResultSet rs = pstmt.executeQuery(); if (rs.next()) { return new SanPham(rs.getString("id"), rs.getString("ten"), rs.getInt("gia")); }
@Override public List getAllSanPham() {
List danhSachSanPham = new ArrayList(); try {
String query = "SELECT * FROM SanPham";
ResultSet rs = stmt.executeQuery(query); while (rs.next()) {
SanPham sanPham = new SanPham(rs.getString("id"), rs.getString("ten"), rs.getInt("gia")); danhSachSanPham.add(sanPham);
The KhachHangDB class implements the IKhachHang interface, establishing a connection to the database through the KetNoi class It initializes a Connection object to facilitate database interactions.
@Override public boolean themKhachHang(KhachHang khachHang) { try {
String query = "INSERT INTO KhachHang (id, ten, email, so_dien_thoai) VALUES (?, ?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, khachHang.getId()); pstmt.setString(2, khachHang.getTen()); pstmt.setString(3, khachHang.getEmail()); pstmt.setString(4, khachHang.getSoDienThoai()); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean suaKhachHang(KhachHang khachHang) { try {
String query = "UPDATE KhachHang SET ten = ?, email = ?, so_dien_thoai = ? WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, khachHang.getTen()); pstmt.setString(2, khachHang.getEmail()); pstmt.setString(3, khachHang.getSoDienThoai()); pstmt.setString(4, khachHang.getId()); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean xoaKhachHang(String id) { try {
String query = "DELETE FROM KhachHang WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public KhachHang timKiemKhachHang(String id) { try {
String query = "SELECT * FROM KhachHang WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id);
ResultSet rs = pstmt.executeQuery(); if (rs.next()) { return new KhachHang(rs.getString("id"), rs.getString("ten"), rs.getString("email"), rs.getString("so_dien_thoai"));
@Override public List getAllKhachHang() {
List danhSachKhachHang = new ArrayList(); try {
String query = "SELECT * FROM KhachHang";
ResultSet rs = stmt.executeQuery(query); while (rs.next()) {
KhachHang khachHang = new KhachHang(rs.getString("id"), rs.getString("ten"), rs.getString("email"), rs.getString("so_dien_thoai")); danhSachKhachHang.add(khachHang);
The `HoaDonDB` class implements the `IHoaDon` interface and establishes a database connection using the `KetNoi` class It initializes the connection within its constructor, allowing for efficient database operations related to invoice management.
@Override public boolean themHoaDon(HoaDon hoaDon) { try {
String query = "INSERT INTO HoaDon (id, id_khach_hang, ngay_lap, tong_tien) VALUES (?, ?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, hoaDon.getId()); pstmt.setString(2, hoaDon.getIdKhachHang()); pstmt.setDate(3, hoaDon.getNgayLap()); pstmt.setInt(4, hoaDon.getTongTien()); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean suaHoaDon(HoaDon hoaDon) { try {
String query = "UPDATE HoaDon SET id_khach_hang = ?, ngay_lap = ?, tong_tien = ? WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, hoaDon.getIdKhachHang()); pstmt.setDate(2, hoaDon.getNgayLap()); pstmt.setInt(3, hoaDon.getTongTien()); pstmt.setString(4, hoaDon.getId()); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean xoaHoaDon(String id) { try {
String query = "DELETE FROM HoaDon WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public HoaDon timKiemHoaDon(String id) { try {
String query = "SELECT * FROM HoaDon WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id);
ResultSet rs = pstmt.executeQuery(); if (rs.next()) { return new HoaDon(rs.getString("id"), rs.getString("id_khach_hang"), rs.getDate("ngay_lap"), rs.getInt("tong_tien"));
@Override public List getAllHoaDon() {
List danhSachHoaDon = new ArrayList(); try {
String query = "SELECT * FROM HoaDon";
ResultSet rs = stmt.executeQuery(query); while (rs.next()) {
HoaDon hoaDon = new HoaDon(rs.getString("id"), rs.getString("id_khach_hang"), rs.getDate("ngay_lap"), rs.getInt("tong_tien")); danhSachHoaDon.add(hoaDon);
The ChiTietHoaDonDB class implements the IChiTietHoaDon interface and is designed to manage database operations related to invoice details It establishes a connection to the database using the KetNoi class, enabling interaction with SQL data The constructor of ChiTietHoaDonDB initializes the database connection, ensuring that the application can retrieve and manipulate invoice information effectively.
@Override public boolean themChiTietHoaDon(ChiTietHoaDon chiTietHoaDon) { try {
String query = "INSERT INTO ChiTietHoaDon (id, id_hoa_don, id_san_pham, so_luong, gia) VALUES (?, ?, ?, ?, ?)";
To execute a SQL query using a PreparedStatement in Java, initialize the PreparedStatement with the connection and query Set the parameters for the PreparedStatement by using the appropriate getter methods from the `chiTietHoaDon` object, including the ID, invoice ID, product ID, quantity, and price After preparing the statement, execute the update and check if the number of affected rows is greater than zero to confirm successful execution.
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean suaChiTietHoaDon(ChiTietHoaDon chiTietHoaDon) { try {
String query = "UPDATE ChiTietHoaDon SET id_hoa_don = ?, id_san_pham = ?, so_luong = ?, gia = ? WHERE id = ?";
To execute a prepared statement in Java, initialize it with the connection and query Set the parameters using the appropriate data types from the `chiTietHoaDon` object, including the invoice ID, product ID, quantity, price, and a unique identifier Finally, execute the update and return true if the operation affected one or more rows.
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public boolean xoaChiTietHoaDon(String id) { try {
String query = "DELETE FROM ChiTietHoaDon WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id); int rows = pstmt.executeUpdate(); return rows > 0;
} catch (SQLException e) { e.printStackTrace(); return false;
@Override public ChiTietHoaDon timKiemChiTietHoaDon(String id) { try {
String query = "SELECT * FROM ChiTietHoaDon WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(query); pstmt.setString(1, id);
The code snippet executes a query using `pstmt` and retrieves a `ResultSet` If the `ResultSet` contains data, it creates and returns a new `ChiTietHoaDon` object, populated with values for "id", "id_hoa_don", "id_san_pham", "so_luong", and "gia".
@Override public List getAllChiTietHoaDon() {
List danhSachChiTietHoaDon = new ArrayList(); try {
String query = "SELECT * FROM ChiTietHoaDon";
ResultSet rs = stmt.executeQuery(query); while (rs.next()) {
ChiTietHoaDon chiTietHoaDon = new ChiTietHoaDon(rs.getString("id"), rs.getString("id_hoa_don"), rs.getString("id_san_pham"), rs.getInt("so_luong"), rs.getInt("gia")); danhSachChiTietHoaDon.add(chiTietHoaDon);
Phát triển giao diện người dùng
1 MainForm private void addEventHandlers() { jButton1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new SanPhamForm().setVisible(true);
}); jButton2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new KhachHangForm().setVisible(true); }
}); jButton3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new HoaDonForm().setVisible(true);
@Override public void actionPerformed(ActionEvent e) { new ChiTietHoaDonForm().setVisible(true);
Hình 9 Form quản lý quán caffee
2 SanPhamForm private void initMyCustomComponents() { jTable1.addMouseListener(new java.awt.event.MouseAdapter()
{ public void mouseClicked(java.awt.event.MouseEvent evt) { jTable1MouseClicked(evt);
List danhSachSanPham sanPhamLG.getAllSanPham(); tableModel = (DefaultTableModel) jTable1.getModel(); tableModel.setRowCount(0); for (SanPham sp : danhSachSanPham) { tableModel.addRow( new Object[] {sp.getId(), sp.getTen(), sp.getGia()}); }
} private void jTable1MouseClicked(MouseEvent evt) { int row = jTable1.getSelectedRow(); if (row >= 0) { try {
Object IdObj = jTable1.getValueAt(row, 0);
Object tenObj = jTable1.getValueAt(row, 1);
Object giaObj = jTable1.getValueAt(row, 2);
String Id = IdObj instanceof String ? (String) IdObj : IdObj.toString();
String ten = tenObj instanceof String ? (String) tenObj : tenObj.toString(); int gia = giaObj instanceof Number ? ((Number) giaObj).intValue()
: Integer.parseInt(giaObj.toString()); jTextField1.setText(Id); jTextField2.setText(ten); jTextField3.setText(String.valueOf(gia));
JOptionPane.showMessageDialog(null, "Lỗi khi xử lý dữ liệu: " + e.getMessage(), "Lỗi",
JOptionPane.showMessageDialog(null, "Vui lòng chọn một hàng trong bảng.", "Cảnh báo",
} private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim();
String ten = jTextField2.getText().trim();
String giatxt = jTextField3.getText().trim(); int gia = 0; try { gia = Integer.parseInt(giatxt);
JOptionPane.showMessageDialog(this, "Phải là một số hợp lệ!");
SanPham sp = new SanPham(Id, ten, gia); boolean success = sanPhamLG.themSanPham(sp); if (success) {
JOptionPane.showMessageDialog(this, "Thêm thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Thêm thất bại!"); }
} private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim();
String ten = jTextField2.getText().trim();
String giatxt = jTextField3.getText().trim(); int gia = 0; try { gia = Integer.parseInt(giatxt);
JOptionPane.showMessageDialog(this, "Phải là một số hợp lệ!");
SanPham sp = new SanPham(Id, ten, gia); boolean success = sanPhamLG.suaSanPham(sp); if (success) {
JOptionPane.showMessageDialog(this, "Sửa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Sửa thất bại!");
} private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim(); boolean success = sanPhamLG.xoaSanPham(Id); if (success) {
JOptionPane.showMessageDialog(this, "Xóa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Xóa thất bại!"); }
} private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim();
The code snippet retrieves a list of products by searching for a specific ID using the `timKiemSanPham` method from the `sanPhamLG` object It then clears the current data in the table model by setting the row count to zero If the retrieved product list is not null and not empty, it iterates through each product, adding its ID, name, and price to the table model.
JOptionPane.showMessageDialog(this, "Không tìm thấy!"); }
Hình 10 Quản lý sản phẩm
3 KhachHangForm private void initMyCustomComponents() { jTable1.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { jTable1MouseClicked(evt);
List danhSachKhachHang khachHangLG.getAllKhachHang(); tableModel = (DefaultTableModel) jTable1.getModel(); tableModel.setRowCount(0); for (KhachHang kh : danhSachKhachHang) { tableModel.addRow( new Object[] {kh.getId(), kh.getTen(), kh.getEmail(), kh.getSoDienThoai()});
} private void jTable1MouseClicked(MouseEvent evt) { int row = jTable1.getSelectedRow(); if (row >= 0) { try {
Object idObj = jTable1.getValueAt(row, 0);
Object tenObj = jTable1.getValueAt(row, 1);
Object emailObj = jTable1.getValueAt(row, 2);
Object soDienThoaiObj = jTable1.getValueAt(row, 3); String id = idObj instanceof String ? (String) idObj : idObj.toString();
String ten = tenObj instanceof String ? (String) tenObj : tenObj.toString();
String email = emailObj instanceof String ? (String) emailObj : emailObj.toString();
String soDienThoai = soDienThoaiObj instanceof String ? (String) soDienThoaiObj : soDienThoaiObj.toString(); jTextField1.setText(id); jTextField2.setText(ten); jTextField3.setText(email); jTextField4.setText(soDienThoai);
JOptionPane.showMessageDialog(null, "Lỗi khi xử lý dữ liệu: " + e.getMessage(), "Lỗi",
JOptionPane.showMessageDialog(null, "Vui lòng chọn một hàng trong bảng.", "Cảnh báo",
} private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim();
String ten = jTextField2.getText().trim();
String email = jTextField3.getText().trim();
String soDienThoai = jTextField4.getText().trim();
KhachHang kh = new KhachHang(id, ten, email, soDienThoai); boolean success = khachHangLG.themKhachHang(kh); if (success) {
JOptionPane.showMessageDialog(this, "Thêm thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Thêm thất bại!");
} private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim();
String ten = jTextField2.getText().trim();
String email = jTextField3.getText().trim();
String soDienThoai = jTextField4.getText().trim();
KhachHang kh = new KhachHang(id, ten, email, soDienThoai); boolean success = khachHangLG.suaKhachHang(kh); if (success) {
JOptionPane.showMessageDialog(this, "Sửa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Sửa thất bại!");
} private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim(); boolean success = khachHangLG.xoaKhachHang(id); if (success) {
JOptionPane.showMessageDialog(this, "Xóa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Xóa thất bại!"); }
} private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim();
The code snippet retrieves a list of customers using the method `timKiemKhachHang(id)` from the `khachHangLG` object It first clears the existing data in the table model by setting the row count to zero If the retrieved customer list is not null and not empty, it iterates through each customer, adding their ID, name, email, and phone number to the table model.
JOptionPane.showMessageDialog(this, "Không tìm thấy!"); }
Hình 11 Quản lý khách hàng
4 HoaDonForm private void initMyCustomComponents() { jTable1.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { jTable1MouseClicked(evt);
The code snippet retrieves a list of invoices from the `hoaDonLG` object and initializes the table model for displaying the data It first clears any existing data in the table by setting the row count to zero Then, it iterates through each invoice in the list, adding a new row to the table for each invoice, which includes the invoice ID, customer ID, creation date, and total amount.
} private void jTable1MouseClicked(java.awt.event.MouseEvent evt) { int row = jTable1.getSelectedRow(); if (row >= 0) {
String id = (String) jTable1.getValueAt(row, 0);
String idKhachHang = (String) jTable1.getValueAt(row, 1); Date ngayLap = (Date) jTable1.getValueAt(row, 2);
Object tongTienObj = jTable1.getValueAt(row, 3);
String ngayLapStr = sdf.format(ngayLap); int tongTien = tongTienObj instanceof Number ? ((Number) tongTienObj).intValue()
: Integer.parseInt(tongTienObj.toString()); jTextField1.setText(id); jTextField2.setText(idKhachHang); jTextField3.setText(ngayLapStr); jTextField4.setText(String.valueOf(tongTien));
} private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim();
String idKhachHang = jTextField2.getText().trim();
Date ngayLap = null; try { ngayLap = sdf.parse(jTextField3.getText().trim());
JOptionPane.showMessageDialog(this, "Ngày không hợp lệ!"); return;
} java.sql.Date sqlNgayLap = new java.sql.Date(ngayLap.getTime());
String tongTienText = jTextField4.getText().trim(); int tongTien = 0; try { tongTien = Integer.parseInt(tongTienText);
JOptionPane.showMessageDialog(this, "Số không hợp lệ!"); }
HoaDon hd = new HoaDon(id, idKhachHang, sqlNgayLap, tongTien); boolean success = hoaDonLG.themHoaDon(hd); if (success) {
JOptionPane.showMessageDialog(this, "Thêm thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Thêm thất bại!"); }
} private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim();
String idKhachHang = jTextField2.getText().trim();
Date ngayLap = null; try { ngayLap = sdf.parse(jTextField3.getText().trim());
JOptionPane.showMessageDialog(this, "Ngày không hợp lệ!"); return;
} java.sql.Date sqlNgayLap = new java.sql.Date(ngayLap.getTime());
String tongTienText = jTextField4.getText().trim(); int tongTien = 0; try { tongTien = Integer.parseInt(tongTienText);
JOptionPane.showMessageDialog(this, "Số không hợp lệ!"); }
HoaDon hd = new HoaDon(id, idKhachHang, sqlNgayLap, tongTien); boolean success = hoaDonLG.suaHoaDon(hd); if (success) {
JOptionPane.showMessageDialog(this, "Sửa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Sửa thất bại!");
} private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim(); boolean success = hoaDonLG.xoaHoaDon(id); if (success) {
JOptionPane.showMessageDialog(this, "Xóa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Xóa thất bại!"); }
} private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
String id = jTextField1.getText().trim();
The code snippet retrieves a list of invoices using the method `hoaDonLG.timKiemHoaDon(id)` and clears the current data in the table by setting the row count to zero If the list of invoices, `danhSachHoaDon`, is not null and not empty, it iterates through each invoice, `hd`, and adds a new row to the table model with the invoice's ID, customer ID, creation date, and total amount.
JOptionPane.showMessageDialog(this, "Không tìm thấy!"); }
Hình 12 Quản lý hóa đơn
5 ChiTietHoaDonForm private void initMyCustomComponents() { jTable1.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { jTable1MouseClicked(evt);
List danhSachChiTietHoaDon chiTietHoaDonLG.getAllChiTietHoaDon(); tableModel = (DefaultTableModel) jTable1.getModel(); tableModel.setRowCount(0); for (ChiTietHoaDon ct : danhSachChiTietHoaDon) { tableModel.addRow( new Object[] {ct.getId(), ct.getIdHoaDon(), ct.getIdSanPham(), ct.getSoLuong(), ct.getGia()});
} private void jTable1MouseClicked(MouseEvent evt) { int row = jTable1.getSelectedRow(); if (row >= 0) { try {
Object IdObj = jTable1.getValueAt(row, 0);
Object IdHoaDonObj = jTable1.getValueAt(row, 1);
Object IdSanPhamObj = jTable1.getValueAt(row, 2);
Object soLuongObj = jTable1.getValueAt(row, 3);
Object giaObj = jTable1.getValueAt(row, 4);
String Id = IdObj instanceof String ? (String) IdObj :
String IdHoaDon = IdHoaDonObj instanceof String ? (String) IdHoaDonObj : IdHoaDonObj.toString();
String IdSanPham = IdSanPhamObj instanceof String ? (String) IdSanPhamObj : IdSanPhamObj.toString(); int soLuong = soLuongObj instanceof Number ? ((Number) soLuongObj).intValue()
: Integer.parseInt(soLuongObj.toString()); int gia = giaObj instanceof Number ? ((Number) giaObj).intValue()
: Integer.parseInt(giaObj.toString()); jTextField1.setText(Id); jTextField2.setText(IdHoaDon); jTextField3.setText(IdSanPham); jTextField4.setText(String.valueOf(soLuong)); jTextField5.setText(String.valueOf(gia));
JOptionPane.showMessageDialog(null, "Lỗi khi xử lý dữ liệu: " + e.getMessage(), "Lỗi",
JOptionPane.showMessageDialog(null, "Vui lòng chọn một hàng trong bảng.", "Cảnh báo",
} private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim();
String IdHoaDon = jTextField2.getText().trim();
String IdSanPham = jTextField3.getText().trim();
String soLuongtxt = jTextField4.getText().trim();
String giatxt = jTextField5.getText().trim(); int soLuong = 0; try { soLuong = Integer.parseInt(soLuongtxt);
JOptionPane.showMessageDialog(this, "Phải là một số hợp lệ!");
} int gia = 0; try { gia = Integer.parseInt(giatxt);
JOptionPane.showMessageDialog(this, "Phải là một số hợp lệ!");
ChiTietHoaDon ct = new ChiTietHoaDon(Id, IdHoaDon,
IdSanPham, soLuong, gia); boolean success = chiTietHoaDonLG.themChiTietHoaDon(ct); if (success) {
JOptionPane.showMessageDialog(this, "Thêm thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Thêm thất bại!"); }
} private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim();
String IdHoaDon = jTextField2.getText().trim();
String IdSanPham = jTextField3.getText().trim();
String soLuongtxt = jTextField4.getText().trim();
String giatxt = jTextField5.getText().trim(); int soLuong = 0; try { soLuong = Integer.parseInt(soLuongtxt);
JOptionPane.showMessageDialog(this, "Phải là một số hợp lệ!");
} int gia = 0; try { gia = Integer.parseInt(giatxt);
JOptionPane.showMessageDialog(this, "Phải là một số hợp lệ!");
ChiTietHoaDon ct = new ChiTietHoaDon(Id, IdHoaDon,
IdSanPham, soLuong, gia); boolean success = chiTietHoaDonLG.suaChiTietHoaDon(ct); if (success) {
JOptionPane.showMessageDialog(this, "Sửa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Sửa thất bại!");
} private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim(); boolean success = chiTietHoaDonLG.xoaChiTietHoaDon(Id); if (success) {
JOptionPane.showMessageDialog(this, "Xóa thành công!"); loadTableData();
JOptionPane.showMessageDialog(this, "Xóa thất bại!"); }
} private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
String Id = jTextField1.getText().trim();
The method `timKiemChiTietHoaDon` retrieves a list of invoice details based on the provided ID Before displaying the results, the current data in the table is cleared by setting the row count to zero If the retrieved list of invoice details is not null and contains entries, each detail is added to the table model, including the ID, invoice ID, product ID, quantity, and price.
JOptionPane.showMessageDialog(this, "Không tìm thấy!"); }
Hình 13 Chi tiết hóa đơn
CREATE TABLE SanPham ( id VARCHAR(10) PRIMARY KEY, ten VARCHAR(100) NOT NULL, gia INT NOT NULL
CREATE TABLE KhachHang ( id VARCHAR(10) PRIMARY KEY, ten VARCHAR(100) NOT NULL, email VARCHAR(100), so_dien_thoai VARCHAR(15)
CREATE TABLE HoaDon ( id VARCHAR(10) PRIMARY KEY, id_khach_hang VARCHAR(10) REFERENCES KhachHang(id), ngay_lap DATE NOT NULL, tong_tien INT NOT NULL
The SQL command creates a table named "ChiTietHoaDon," which serves as a detailed invoice record This table includes five columns: "id," which is a primary key of type VARCHAR(10); "id_hoa_don," a foreign key referencing the "HoaDon" table; "id_san_pham," a foreign key referencing the "SanPham" table; "so_luong," an integer column representing the quantity of products; and "gia," an integer column indicating the price Each column is essential for maintaining the integrity and relationships of invoice details within the database.
INSERT INTO SanPham (id, ten, gia) VALUES
INSERT INTO KhachHang (id, ten, email, so_dien_thoai) VALUES
('KH001', 'Nguyen Van A', 'nguyenvana@gmail.com', '0123456789'),
('KH002', 'Le Thi B', 'lethib@gmail.com', '0987654321'),
('KH003', 'Tran Van C', 'tranvanc@gmail.com', '0234567890'),
('KH004', 'Pham Thi D', 'phamthid@gmail.com', '0345678901'),
('KH005', 'Hoang Van E', 'hoangvane@gmail.com', '0456789012');
INSERT INTO HoaDon (id, id_khach_hang, ngay_lap, tong_tien) VALUES ('HD001', 'KH001', '2024-09-09', 165),
INSERT INTO ChiTietHoaDon (id, id_hoa_don, id_san_pham, so_luong, gia) VALUES ('CTHD001', 'HD001', 'SP001', 2, 50),