1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Đề tài lập trình phát triển phân hệ kế toán bán hàng của cửa hàng lotteria

73 4 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Lập Trình Phát Triển Phân Hệ Kế Toán Bán Hàng Của Cửa Hàng Lotteria
Tác giả Nguyễn Trần Anh Thư
Người hướng dẫn ThS. GVC. Võ Xuân Thể
Trường học Trường Đại Học Tài Chính – Marketing
Chuyên ngành Công Nghệ Thông Tin
Thể loại đồ án
Năm xuất bản 2021
Thành phố TP.HCM
Định dạng
Số trang 73
Dung lượng 1,66 MB

Cấu trúc

  • Chương 1: GIỚI THIỆU VỀ ĐỒ ÁN HỌC PHẦN 10 1.1. Tổng quan về ĐỒ ÁN HỌC PHẦN (9)
    • 1.2. Nội dung chuyên môn chính của ĐỒ ÁN HỌC PHẦN (9)
    • 1.3. Công cụ và nền tảng kỹ thuật thực hiện ĐỒ ÁN HỌC PHẦN (10)
    • 1.4. Sản phẩm của ĐỒ ÁN HỌC PHẦN (10)
    • 1.5. Bố cục của báo cáo (0)
  • Chương 2: CƠ SỞ LÝ THUYẾT CỦA HỌC PHẦN 12 2.1. Tổng quan về nghiệp vụ kế toán liên quan (12)
    • 2.1.1. Nguyên lý kế toán (12)
    • 2.1.2. Kế toán chính (13)
    • 2.1.3. Kế toán quản trị (0)
    • 2.1.4. Kế toán chi phí (0)
    • 2.1.5. Phân tích tài chính (0)
    • 2.2.2. Lập trình Winform đơn giản trên .NET (15)
    • 2.3. Truyền tham số từ Form này =sang=>Form khác (17)
    • 2.4. Lập trình xử lý RBTV dữ liệu (khi xóa) (17)
    • 2.5. Lập trình Form màn hình chính (MainForm) (17)
    • 2.6. Lập trình Form màn hình Quản lý hàng hóa - dịch vụ (GoogManagement) (17)
    • 2.7. Lập trình Form màn hình Xử lý RBTV dữ liệu khi “Xóa” (RBTV) (18)
    • 2.8. Lập trình Form màn hình Xử lý Chuyển Nhóm Hàng hóa – Dịch vụ (ChuyeNhom). 20 2.9. Lập trình Form màn hình Xử lý Nghiệp vụ hạch toán kế toán (0)
    • 2.10. Đóng gói bộ cài đặt SetUp cho WinApp kế toán (0)
  • Chương 3: THIẾT KẾ & CẬP NHẬT CSDL PHỤC VỤ CHO WINAPP KẾ TOÁN 21 3.1. Giới thiệu về CSDL của hệ thống (0)
    • 3.2. Thiết kế DB quản lý hạch toán kế toán hàng bán dịch vụ lưu trú (20)
    • 3.3. Thiết kế (Design) các Tables của CSDL kế toán ..<nghiệp vụ>…<đối tượng quản lý>… (0)
      • 3.3.1. Danh mục nhóm mặt hàng (NHOMMH) (21)
      • 3.3.2. Danh mục Mặt hàng (MH) (21)
    • 3.4. Chuỗi kết nối DB của App: App.config (24)
    • 3.5. Giới thiệu một số Trigger và SP trong DB hạch toán kế toán nêu trên (25)
  • Chương 4. THIẾT KẾ VÀ LẬP TRÌNH CÁC WINFORMs QUẢN LÝ 23 4.1. Giới thiệu các Winforms quản lý của phân hệ kế toán …<nghiệp vụ>… (0)
    • 4.2. Thiết kế và lập trình FrMain.cs: màn hình chính (26)
      • 4.2.1. Thiết kế (Design) (26)
      • 4.2.2. Lập trình (Code) của FrMain (28)
    • 4.3. Thiết kế & lập trình FrGoodsMan.cs: màn hình Quản lý ..<đối tượng của đề tài> (30)
      • 4.3.1. Thiết kế (Design) (30)
      • 4.3.2. Lập trình (Codes) (30)
    • 4.4. Lập trình chức năng Thêm _ Xóa _ Sửa dữ liệu trên FrGoodsMan.cs (32)
      • 4.4.1. Xử lý chọn hình ảnh cho <sản phẩm> và biến toàn cục (0)
      • 4.4.2. Thêm mới <hàng hóa – dịch vụ> (0)
      • 4.4.3. Sửa chữa thông tin <hàng hóa – dịch vụ> (33)
      • 4.4.4. Xóa <hàng hóa – dịch vụ> khỏi danh mục (CHƯA xử lý RBTV DL) (0)
    • 4.5. Xử lý RBTV dữ liệu khi Xóa <hàng hóa – dịch vụ> khỏi danh mục: FrRBTV.cs (0)
    • 4.6. Xử lý Chuyển Nhóm: FrChuyenNhom.cs (44)
      • 4.6.1. Giới thiệu về thủ tục chuyển nhóm (44)
      • 4.6.2. Thiết kế Form chuyển nhóm (Desgin View) (45)
      • 4.6.3. Mã lệnh lập trình Form chuyển nhóm (Codes View) (47)
        • 4.6.3.1. ButtonLR: > (47)
        • 4.6.3.2. ButtonRL: < (48)
        • 4.6.3.3. ButtonAllLR: btnALR >> (48)
        • 4.6.3.4. ButtonAllRL: btnARL << (50)
      • 4.6.4. Các xử lý khác trong Form chuyển nhóm (50)
        • 4.6.4.1. Ẩn các nút trong các trường hợp không chuyển được (51)
        • 4.6.4.2. Các Combobox không chọn giống nhau (51)
  • Chương 5: THIẾT KẾ & LẬP TRÌNH WINFORMS HỖ TRỢ HẠCH TOÁN KẾ TOÁN (0)
    • 5.1. Giới thiệu nghiệp vụ kế toán liên quan trên Winforms của phân hệ kế toán (52)
    • 5.2. Thiết kế và lập trình FrAccSaleNVKT.cs: <nghiệp vụ> đối với <đối tượng> tại <đơn vị> (0)
      • 5.2.1. Thiết kế (Design) (53)
      • 5.2.2. Lập trình (Code) (53)
  • Chương 6: THIẾT LẬP BỘ CÀI ĐẶT SETUP CHO PHÂN HỆ KẾ TOÁN. 45 6.1. Giới thiệu chung (0)
    • 6.2. Công cụ sử dụng thiết lập bộ cài đặt Setup cho App (64)
    • 6.3. Thiết lập bộ cài đặt Setup cho App (64)
    • 6.4. Cài đặt Setup App vào máy tính NSD (67)
  • Chương 7: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN CỦA ĐỒ ÁN 49 7.1. Kết luận (0)
    • 7.1.1. Những kết quả đạt được (71)
    • 7.1.2. Hạn chế (71)
    • 7.2. Hướng phát triển (71)

Nội dung

DANH MỤC CÁC TỪ VIẾT TẮTCSDL hoặc DBCơ sở dữ liệu: DataBaseHQTCSDL = DBMSHệ quản trị Cơ sở dữ liệu NSD = Users = AccountNgười Sử Dụng = là quyền làm việc trên WebApp được đảm bảo bởi tối

GIỚI THIỆU VỀ ĐỒ ÁN HỌC PHẦN 10 1.1 Tổng quan về ĐỒ ÁN HỌC PHẦN

Nội dung chuyên môn chính của ĐỒ ÁN HỌC PHẦN

 Vận dụng kiến thức căn bản về nghiệp vụ kế toán:

+ Nguyên lý kế toán: các kiến thức căn bản về hạch toán kế toán doanh nghiệp TMDV||

+ Kế toán chính: Nghiệp vụ hạch toán kế toán bán hàng

+ Kế toán quản trị: Nghiệp vụ liên quan kế toán tổng hợp phục vụ hoạt động hoạch định kinh doanh

+ Kế toán chi phí (Cost accounting) là vị trí kế toán đảm nhận công việc thu nhập, ghi chép và thực hiện phân loại mọi chi phí có liên quan đến việc hoàn thành một mục tiêu kinh doanh Kế toán chi phí có vai trò quan trọng trong việc hợp lý hóa quy trình sản xuất nhằm giảm chi phí cho doanh nghiệp và đem đến những lợi nhuận cao hơn cho doanh số bán sản phẩm riêng.

+ Phân tích tài chính: (Financial Analysis) là quá trình đánh giá các doanh nghiệp, dự án, ngân sách và các giao dịch khác liên quan đến tài chính để xác định hiệu suất và tính phù hợp của chúng Thông thường, nghiệp vụ này được sử dụng để phân tích xem một đơn vị kinh tế có tính ổn định, lưu động, khả năng thanh khoản hoặc đủ sinh lời để đảm bảo đầu tư tiền tệ hay không Chuyên gia phân tích tài chính là người đưa ra các khuyến nghị kinh doanh cho một tổ chức, dựa trên phân tích về các yếu tố như xu hướng thị trường, tình trạng tài chính doanh nghiệp và kết quả dự đoán cho một loại giao dịch nhất định.

 Kết hợp vận dụng kiến thức và kỹ năng lập trình C#.NET trên Visual Studio 201? với NETFramework 4.6.1 để hiện thực các nghiệp vụ kế toán nêu trên trong hệ thống WinApp hỗ trợ hạch toán kế toán bán hàng đối với cửa hàng Lotteria

Công cụ và nền tảng kỹ thuật thực hiện ĐỒ ÁN HỌC PHẦN

+ NETFramework 4.6.1 trên MS Visual Studio 2017

+ Hệ quản trị CSDL MS SQL Server 2017: trên Local và trên Internet: somee.com dùng chung với WebApp.

+ Bộ công cụ thiết lập Setup trên Visual NET 2017: VSI_bundle.exe

Sản phẩm của ĐỒ ÁN HỌC PHẦN

1G118NTAThu_SaleLotte hỗ trợ hạch toán kế bán hàng đối với cửa hàng Lotteria

+ Bộ cài đặt Setup.exe: Cài đặt trên các máy tính cá nhận bộ phận kế toán bán hàng của cửa hàng Lottte

Bố cục của báo cáo

Báo cáo gồm những nội dung như sau:

Chương 1: Giới thiệu đồ án của HP là hệ thống kế toán bán hàng đối với cửa hàng Lotteria Chương 2: Các cơ sở lý thuyết của HP Lập trình kế toán phục việc thực hiện đề tài HP Chương 3: Thiết kế và cập nhật CSDL phục vụ cho WinApp kế toán nêu trên

Chương 4: Thiết kế và lập trình các Winforms quản lý các đối tượng liên quan đến dịch vụ bán hàng đối với cửa hàng Lotteria FrMain.cs, FrGoodsMan.cs, FrRBTV.cs,

Chương 5: Thiết kế và lập trình Winforms hỗ trợ hạch toán kế toán bán hàng đối với cửa hàng Lotteria: Fr… cs

Chương 6: Thiết lập bộ cài đặt Setup cho hệ thống WinApp nêu trên.

Chương 7: Tổng kết các kết quả đạt được và còn hạn chế của đồ án, đồng thời đề xuất hướng khắc phục hạn chế và phát triển Đồ án.

Bố cục của báo cáo

2.1 Tổng quan về nghiệp vụ kế toán liên quan

 Hạch toán kế toán ( còn gọi là kế toán ) là một môn khoa học phản ánh và giám đốc các mặt hoạt động kinh tế tài chính ở tất cả các doanh nghiệp, tổ chức sự nghiệp và các cơ quan.

 Những yêu cầu quan trọng đối với hạch toán là đầy đủ, chính xác, kịp thời về nội dung và thống nhất về phương pháp, bảo đảm tiêu chuẩn hoá (quy cách hoá) và so sánh được các số liệu hạch toán.

- Hạch toán kinh tế: Là một phạm trù kinh tế của nền kinh tế hàng hoá nói chung, đặc biệt dùng trong nền kinh tế xã hội chủ nghĩa thực hiện phương thức quản lí hoạt động kinh doanh của các doanh nghiệp, trên cơ sở kế hoạch hoá kết hợp với sử dụng các quan hệ hàng hoá – tiền tệ và áp dụng phương pháp thương mại.

- Hạch toán kinh tế quốc dân: Bao gồm những bộ phận như hạch toán thu nhập quốc dân; hạch toán tài chính và lưu chuyển vốn; hạch toán thu chi bằng tiền mặt của dân cư; hạch toán thanh toán quốc tế.

- Hạch toán nghiệp vụ (còn gọi là hạch toán nghiệp vụ kỹ thuật): Là sự quan sát, phản ánh và giám đốc trực tiếp từng nghiệp vụ kinh tế kỹ thuật cụ thể, để chỉ đạo thường xuyên và kịp thời các nghiệp vụ đó Đối tượng của hạch toán nghiệp vụ là các nghiệp vụ kinh tế hoặc kỹ thuật sản xuất như tiến độ thực hiện các hoạt động cung cấp, sản xuất, tiêu thụ, tình hình biến động và sử dụng các yếu tố của quá trình tái sản xuất, các nghiệp vụ cụ thể về kết quả sản xuất kinh doanh v.v

- Hạch toán thống kê (hay còn được gọi là thống kê): Là khoa học nghiên cứu mặt lượng trong mối liên hệ mật thiết với mặt chất các hiện tượng kinh tế xã

CƠ SỞ LÝ THUYẾT CỦA HỌC PHẦN 12 2.1 Tổng quan về nghiệp vụ kế toán liên quan

Nguyên lý kế toán

 Hạch toán kế toán ( còn gọi là kế toán ) là một môn khoa học phản ánh và giám đốc các mặt hoạt động kinh tế tài chính ở tất cả các doanh nghiệp, tổ chức sự nghiệp và các cơ quan.

 Những yêu cầu quan trọng đối với hạch toán là đầy đủ, chính xác, kịp thời về nội dung và thống nhất về phương pháp, bảo đảm tiêu chuẩn hoá (quy cách hoá) và so sánh được các số liệu hạch toán.

- Hạch toán kinh tế: Là một phạm trù kinh tế của nền kinh tế hàng hoá nói chung, đặc biệt dùng trong nền kinh tế xã hội chủ nghĩa thực hiện phương thức quản lí hoạt động kinh doanh của các doanh nghiệp, trên cơ sở kế hoạch hoá kết hợp với sử dụng các quan hệ hàng hoá – tiền tệ và áp dụng phương pháp thương mại.

- Hạch toán kinh tế quốc dân: Bao gồm những bộ phận như hạch toán thu nhập quốc dân; hạch toán tài chính và lưu chuyển vốn; hạch toán thu chi bằng tiền mặt của dân cư; hạch toán thanh toán quốc tế.

- Hạch toán nghiệp vụ (còn gọi là hạch toán nghiệp vụ kỹ thuật): Là sự quan sát, phản ánh và giám đốc trực tiếp từng nghiệp vụ kinh tế kỹ thuật cụ thể, để chỉ đạo thường xuyên và kịp thời các nghiệp vụ đó Đối tượng của hạch toán nghiệp vụ là các nghiệp vụ kinh tế hoặc kỹ thuật sản xuất như tiến độ thực hiện các hoạt động cung cấp, sản xuất, tiêu thụ, tình hình biến động và sử dụng các yếu tố của quá trình tái sản xuất, các nghiệp vụ cụ thể về kết quả sản xuất kinh doanh v.v

- Hạch toán thống kê (hay còn được gọi là thống kê): Là khoa học nghiên cứu mặt lượng trong mối liên hệ mật thiết với mặt chất các hiện tượng kinh tế xã

- 12 - hội số lớn trong điều kiện thời gian và địa điểm cụ thể nhằm rút ra bản chất và tính qui luật trong sự phát triển của các hiện tượng đó Hạch toán thống kê nghiên cứu trong mối qua hệ hữu cơ các hiện tượng kinh tế xã hội số lớn sảy ra trong không gian và thời gian cụ thể như tình hình tăng năng suất lao động,giá trị tổng sản lượng, thu nhập quốc dân, tình hình giá cả, tình hình

Kế toán chính

Kế toán bán hàng(Sales Accountant) là vị trí có trách nhiệm quản lý, ghi chép toàn bộ các công việc ảnh hưởng đến nghiệp vụ bán hàng của tổ chức, từ ghi hóa đơn kinh doanh, ghi sổ chi tiết doanh thu hàng bán, thuế giá trị gia tăng (GTGT) phải nộp, ghi sổ chi tiết hàng hóa, thành phẩm xuất bán đến xử lý hóa đơn chứng từ, lập báo cáo bán hàng liên quan theo quy định…

Nghiệp vụ hạch toán kế toán bán hàng đối với cửa hàng Lotteria

- Cập nhật giá, hàng hóa và quản lý các hóa đơn, chứng từ ảnh hưởng đến hoạt động bán hàng

- Cuối ngày tiến hành vào bảng kê chi tiết các hóa đơn bán hàng; tính tổng giá trị hàng đã bán, thuế GTGT (nếu có) trong ngày Cùng với Kế toán kho, Thủ kho đối chiếu số liệu hàng xuất – tồn; tổng hợp số liệu bán – mua hàng trong ngày, lấy đó làm căn cứ để lập báo cáo liên quan vào cuối ngày.

- Lập hóa đơn bán hàng(Bill) , hóa đơn thu tiền (Invoice), Quản lý các danh mục hàng hóa,….

Kế toán quản trị dụng các phương pháp chuyên biệt để phản ánh và xử lý thông tin kế toán theo hướng chỉ phục vụ cho hoạt động quản lý và ra quyết định của nhà quản trị doanh nghiệp (đối tượng bên trong) nhằm tiến hành các hoạt động kinh doanh của doanh nghiệp. kế toán quản trị thường chỉ tập trung đáp ứng yêu cầu trực tiếp của các nhà quản trị hơn là các chuẩn mực, phạm vi báo cáo cần chi tiết, cụ thể chứ không đơn thuần là bao quát toàn bộ doanh nghiệp Trên thực tế hiện nay, cùng với sự phát triển của công nghệ thông tin,nhiều doanh nghiệp đã vận hành các hệ thống thông tin quản lý hay các hệ thống quản trị nguồn lực doanh nghiệp, trong đó kết hợp cả kế toán tài chính và kế toán quản trị.

- Doanh thu: Là tổng giá trị các lợi ích kinh tế doanh nghiệp thu được trong kỳ kế toán, phát sinh từ các hoạt động sản xuất, kinh doanh thông thường của doanh nghiệp, góp phần làm tăng vốn chủ sở hữu.

- Chi phí là toàn bộ khoản tiêu hao của tài sản được tiêu thụ hoặc dịch vụ được sử dụng trong quá trình kiếm doanh thu.

- Kết quả kinh doanh là phần chênh lệch giữa doanh thu và chi phí phát sinh trong kỳ để tạo ra khoản doanh thu đó.

Kế toán chi phí (Cost accounting) là vị trí kế toán đảm nhận công việc thu nhập, ghi chép và thực hiện phân loại mọi chi phí có liên quan đến việc hoàn thành một mục tiêu kinh doanh Kế toán chi phí có vai trò quan trọng trong việc hợp lý hóa quy trình sản xuất nhằm giảm chi phí cho doanh nghiệp và đem đến những lợi nhuận cao hơn cho doanh số bán sản phẩm riêng.

- Kế toán chi phí bán hàng: Chi phí bán hàng là những khoản chi phí phát sinh có liên quan tới các hoạt động tiêu thụ hàng hóa Chi phí bán hàng có thể bao gồm phí thuê nhân viên bán hàng, phí vật liệu bao bì, dụng cụ, đồ dùng, phí khấu hao tài sản cố định, bảo hành sản phẩm, phí dịch vụ mua ngoài,…

- Kế toán chi phí doanh nghiệp: Chi phí doanh nghiệp là những khoản chi phí phát sinh liên quan đến những hoạt động của cả doanh nghiệp và không thể tách riêng được cho bất kỳ một hoạt động nào Chi phí quản lý doanh nghiệp bao gồm những khoản chi phí như chi phí nhân viên quản lý, đồ dùng văn phòng, khấu hao TSCĐ, thuế và lệ phí, những chi phí dự phòng, chi phí dịch vụ mua ngoài và những chi phí bằng tiền…

Phân tích tài chính là nhằm đánh giá hiệu suất và mức độ rủi ro của các hoạt động tài chính Chúng ta biết rằng các dòng dịch chuyển tài chính vận động liên tục và có thể ví như hệ tuần hoàn trong cơ thể con người Hầu như mọi dấu hiệu tốt hay xấu trong hoạt động của công ty đều có thể biểu hiện qua các dấu hiệu tài chính Bản thân công ty cũng như các nhà cung cấp vốn bên ngoài - chủ nợ và nhà đầu tư - tất thảy đều cần phải phân tích tài chính để

- 14 - nắm vững tình hình tài chính của công ty Tuy nhiên, tùy vào mối quan hệ của các đối tác bên ngoài với công ty mà họ sẽ quan tâm đến các khía cạnh tài chính khác nhau.

2.2 Tổng quan về Lập trình Winform dùng C#.NET trên Visual

2.2.1 Tổng quan về lập trình kế toán

Sử dụng kiến thức và kỹ năng lập trình kết hợp nghiệp vụ kế toán để phát triển các ứng dung phục vụ hoặc hỗ trợ các hoạt động hạch toán kế toán liên quan.

2.2.2 Lập trình Winform đơn giản trên NET

2.2.2.1 Bổ sung thêm Form mới vào ứng dụng WinApp (Project) 2.2.2.2 Chọn Form được chạy ban đầu (MainForm = Màn hình chính) static void Main()

2.2.2.3 Cách gọi Form từ Form khác

//GỌI FORM QUA.N LÝ DANH MỤC MÓN ĂN private void qua.nLýDanhMụcMónĂnToolStripMenuItem_Click(object sender, EventArgs e)

FrQuanLyHangHoa fr = new FrQuanLyHangHoa(); fr.ShowDialog();

2.2.2.4 Cách Đóng Form và Thoát chương trình

/// THU TỤC THOÁT CHƯƠNG TRÌNH

/// private void btnClose_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Thoát chương trình (Y/N)?" , "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ch == DialogResult.Yes) // User đã chọn Yes đồTng ý thoát chương trình

2.2.2.5 Giới thiệu đối tượng MessageBox

2.2.2.6 Bắt lỗi chạy chương trình

{MessageBox.Show("Có lồYi chưa sư.a thồng tin món ăn mới : " + ex.Message); }

2.2.2.7 Toolbox WinApp DOTNET (View: Designer )

2.2.2.9 Làm quen với một số công cụ lập trình Winapp

[2] Tạo biểu tượng chương trình / vùng=khay hệ thống = System Tray: NotifyIcon / Common Controls

[3][4] Thực đơn: Menu + ContextMenu / Menu & Toolbars

[5] Thanh công cụ: Toolbar / ToolStrip : Menu & Toolbars

[6] Dòng trạng thái: Statusbar / StatusStrip : Menu & Toolbars

[7] Bắt lỗi NSD nhập dữ liệu: ErrorProvider / Component:

ErrorProvider: Bắt lỗi NSD nhập dữ liệu;

VD không được để trống, phải nhập số,…

ImageList: Sử dụng ds hình ảnh cho một số đối tượng thiết kế khác

2.3 Truyền tham số từ Form này =sang=>Form khác 2.4 Lập trình xử lý RBTV dữ liệu (khi xóa)

2.5 Lập trình Form màn hình chính (MainForm)

2.6 Lập trình Form màn hình Quản lý hàng hóa - dịch vụ

2.7 Lập trình Form màn hình Xử lý RBTV dữ liệu khi “Xóa” (RBTV)

2.8 Lập trình Form màn hình Xử lý Nghiệp vụ hạch toán kế toán

2.9 Đóng gói bộ cài đặt SetUp cho WinApp kế toán

Lập trình Winform đơn giản trên NET

2.2.2.1 Bổ sung thêm Form mới vào ứng dụng WinApp (Project) 2.2.2.2 Chọn Form được chạy ban đầu (MainForm = Màn hình chính) static void Main()

2.2.2.3 Cách gọi Form từ Form khác

//GỌI FORM QUA.N LÝ DANH MỤC MÓN ĂN private void qua.nLýDanhMụcMónĂnToolStripMenuItem_Click(object sender, EventArgs e)

FrQuanLyHangHoa fr = new FrQuanLyHangHoa(); fr.ShowDialog();

2.2.2.4 Cách Đóng Form và Thoát chương trình

/// THU TỤC THOÁT CHƯƠNG TRÌNH

/// private void btnClose_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Thoát chương trình (Y/N)?" , "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ch == DialogResult.Yes) // User đã chọn Yes đồTng ý thoát chương trình

2.2.2.5 Giới thiệu đối tượng MessageBox

2.2.2.6 Bắt lỗi chạy chương trình

{MessageBox.Show("Có lồYi chưa sư.a thồng tin món ăn mới : " + ex.Message); }

2.2.2.7 Toolbox WinApp DOTNET (View: Designer )

2.2.2.9 Làm quen với một số công cụ lập trình Winapp

[2] Tạo biểu tượng chương trình / vùng=khay hệ thống = System Tray: NotifyIcon / Common Controls

[3][4] Thực đơn: Menu + ContextMenu / Menu & Toolbars

[5] Thanh công cụ: Toolbar / ToolStrip : Menu & Toolbars

[6] Dòng trạng thái: Statusbar / StatusStrip : Menu & Toolbars

[7] Bắt lỗi NSD nhập dữ liệu: ErrorProvider / Component:

ErrorProvider: Bắt lỗi NSD nhập dữ liệu;

VD không được để trống, phải nhập số,…

ImageList: Sử dụng ds hình ảnh cho một số đối tượng thiết kế khác

Truyền tham số từ Form này =sang=>Form khác

2.5 Lập trình Form màn hình chính (MainForm)

2.6 Lập trình Form màn hình Quản lý hàng hóa - dịch vụ

Lập trình Form màn hình Quản lý hàng hóa - dịch vụ (GoogManagement)

Lập trình Form màn hình Xử lý RBTV dữ liệu khi “Xóa” (RBTV)

2.8 Lập trình Form màn hình Xử lý Nghiệp vụ hạch toán kế toán

2.9 Đóng gói bộ cài đặt SetUp cho WinApp kế toán

THIẾT KẾ & CẬP NHẬT CSDL PHỤC VỤ CHO WINAPP KẾ TOÁN 21 3.1 Giới thiệu về CSDL của hệ thống

Thiết kế DB quản lý hạch toán kế toán hàng bán dịch vụ lưu trú

Căn cứ vào phân tích từ phần 3.1 nêu trên, ta có Diagram của DB phục vụ cho hoạt động của hỗ trợ hạch toán kế toán bán hàng đối với cửa hàng Lotteria như

Thiết kế (Design) các Tables của CSDL kế toán <nghiệp vụ>…<đối tượng quản lý>…

3.3.1 Danh mục nhóm mặt hàng (NHOMMH)

Data của Nhóm mặt hàng (NHOMMH)

3.3.2 Danh mục Mặt hàng (MH)

Data của Nhóm mặt hàng (NHOMMH)

3.3.3 Danh mục Thương hiệu (TH)

Data của Thương hiệu (TH)

3.3.4 Danh mục Hóa đơn (HD)

3.3.5 Danh mục Chi tiết hóa đơn (CTHD)

3.3.6 Danh mục Khách hàng (KH)

3.3.7 Danh mục Nhân viên (NV)

3.3.8 Danh mục Tồn kho (TK)

3.3.9 Danh mục Cửa hàng (CH)

Chuỗi kết nối DB của App: App.config

+ DB chạy cục bộ trên máy tính cá nhân [Local]

+ DB chạy Online trên Internat thông quan free host somee.com [Online somee]: dùng chung với WebApp của Học phần Lập trình DataBase

THIẾT KẾ VÀ LẬP TRÌNH CÁC WINFORMs QUẢN LÝ 23 4.1 Giới thiệu các Winforms quản lý của phân hệ kế toán …<nghiệp vụ>…

Thiết kế và lập trình FrMain.cs: màn hình chính

Màn hình chính của sản phẩm như Hình 4 -1

Hình 4-1 Màn hình chính của sản phẩm

Danh sách các Menus trong màn hình chính

+ “HỆ THỐNG”, Hình 4 -2 trang 27 : Bao gồm các chức năng quản trị chung của hệ thống, như máy in, đăng nhập, tài khoản NSD, phân quyền, tham số hệ thống, backup và restore BD,

4.2.2 Lập trình (Code) của FrMain

/// THU TỤC THOÁT CHƯƠNG TRÌNH

/// private void btnClose_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Thoát chương trình (Y/N)?" , "Xác nhận",MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ch == DialogResult.Yes) // User đã chọn Yes đồTng ý thoát chương trình

//this.Close();// Đóng frMain = thoát chương trình

}// NếWu chọn No thì tiếWp tục chạy

//THU TỤC NÀY ĐƯỢC TỰ ĐỘNG CHẠY MỖYI KHI FORM NÀY ĐƯỢC MƠ RA private void FrMain_Load(object sender, EventArgs e)

MessageBox.Show("Welcome to PhầTn mếTm KếW toán Bán hàng");

//GỌI FORM QUA.N LÝ HÀNG HÓA private void qua.nLýDanhMụcMónĂnToolStripMenuItem_Click(object sender, EventArgs e) {

FrQuanLyHangHoa fr = new FrQuanLyHangHoa();//Khai báo biếWn đồWi tượng fr thuộc form QLHH GoodsMan fr.ShowDialog();//Mơ Form FrGoodsMan lến dạng Form con cu.a Form Main }

//GỌI FORM: LẬP PHIẾWU TÍNH TIẾTN(FRBILL) private void btnBill_Click(object sender, EventArgs e)

FrBill fr = new FrBill(); // Khai báo biếWn đồWi tượng cu.a frBill và chạy thu tục thiếWt lập fr.ShowDialog(); // Mơ frBill với tư cách một from con cu.a FrMain

//fr.Show(); // Mơ FrBill với tư cách ngang hàng frMain

Gán vào nút chọn “QLHH” (Qua.n lý hàng hóa) trong toolStripButton1

Và mục chọn “Qua.n lý danh mục hàng bán” trong toolStripMenuItem1 cu.a contextMenuStrip1

/// private void timer1_Tick(object sender, EventArgs e)

{ lbtime.Text = StatusLBTime.Text System.DateTime.Now.ToLongTimeString(); //LầWy giờ hiện tại (now) gán vào nút trến thanh Status góc dưới

/// DỪNG OR CHẠY ĐỖTNG HỖT

/// private void button1_Click(object sender, EventArgs e)

//GỌI FORM CHUYẾ.N NHÓM private void chuyế.nNhómToolStripMenuItem_Click(object sender, EventArgs e)

FrChuyenNhom fr = new FrChuyenNhom(); fr.ShowDialog();

Thiết kế & lập trình FrGoodsMan.cs: màn hình Quản lý <đối tượng của đề tài>

ăn của cửa hàng Lotteria:

Hình 4-4 Màn hình quản lý sản phẩm, dịch vụ

Màn hình quản lý Danh mục Món ăn của cửa hàng Lotteria như Hình 4 -4 trang 30

//KHAI BÁO CÁC THAM SỐ" TOÀN CỤC static string name = "", pass = ""; string apppath= System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(Application.StartupPath )) + "\\Images\\" ; //BIẾWN TOÀN CỤC LƯU ĐƯỜNG DẪYN ĐẾW THƯ MỤC LƯU APP BÀI LÀM NAY

//string apppath = "D:\\G118NTATSaleLotte\\G118NTATSaleLotte\\Images\\";

//BIẾWN TOÀN CỤC LƯU ĐƯỜNG DẪYN ĐẾW THƯ MỤC LƯU APP BÀI LÀM NAY

//public FrGoodsMan(string n, string p) public FrQuanLyHangHoa()

//THỦ4 TỤC ĐƯỢC TỰ ĐỘNG CHAY KHI FORM QỦA4N LÝ HÀNG HÓA DỊCH VỤ MỞ4 LÊN private void FrQuanLyHangHoa_Load(object sender, EventArgs e)

// TODO: This line of code loads data into the

'_1G118NTAThu_SaleLotteriaDataSet.NHOMMH' table You can move, or remove it, as needed. this.nHOMMHTableAdapter.Fill(this._1G118NTAThu_SaleLotteriaDataSet.NHOMMH);

// TODO: This line of code loads data into the

'_1G118NTAT_SaleQLDataSetNhomMH.MH' table You can move, or remove it, as needed. this.mHTableAdapter.Fill(this._1G118NTAT_SaleQLDataSetNhomMH.MH); //Nhóm try

// TODO: This line of code loads data into the

'_1G118NTAThu_SaleQLDataSetMH.MH' table You can move, or remove it, as needed. this.mHTableAdapter1.Fill(this._1G118NTAThu_SaleQLDataSetMH.MH, comboBoxNhomMH.SelectedValue.ToString().Trim()); //Mặt hàng

// TODO: This line of code loads data into the

'_1G118NTAT_SaleQLDataSetTH.THUONGHIEU' table You can move, or remove it, as needed. this.tHUONGHIEUTableAdapter.Fill(this._1G118NTAT_SaleQLDataSetTH.THUONGHIEU);

//TỦ DONG TAI LAI DS MH KHI NSD CHON LAI NHOM MH private void comboBoxNhomMH_SelectedIndexChanged(object sender, EventArgs e)

{ // Tai ds cac MH vao DataGridView ben duoi theo Nhom MH da chon trong ComboBox phia tren

// TODO: This line of code loads data into the

'_1G118NTAThu_SaleQLDataSetMH.MH' table You can move, or remove it, as needed. this.mHTableAdapter1.Fill(this._1G118NTAThu_SaleQLDataSetMH.MH, comboBoxNhomMH.SelectedValue.ToString().Trim());

} catch (System.Exception ex) { } //bat moi he thong = tranh truong hop ctr bi dung dot ngot

//ĐÓNG MÀN HÌNH, VÊG LẠI MÀN HÌNH CHÍNH private void btnDong_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Thiệt đóng màn hình khồng (Y/N)", "Xác nhận", MessageBoxButtons.YesNo,

MessageBoxIcon.Question); if(ch == DialogResult.Yes)

//THOÁT CHƯỞNG TRÌNH private void btnThoat_Click(object sender, EventArgs e) if (ch == DialogResult.Yes)

Lập trình chức năng Thêm _ Xóa _ Sửa dữ liệu trên FrGoodsMan.cs

 Khi thêm món ăn mới Hoặc Sửa thông tin một món ăn đã có (thay đỗi hình mẫu cho món ăn):

//CHỌN HÌNH MẪYU CHO SA.N PHẪ.M static string imagechoose = ""; //BiếW n toàn cục Lưu tến file hình mà NSD đã chọn (Thếm/Sư a) đồW i với

PictureBox private void pictureBoxHinh_Click(object sender, EventArgs e)

DialogResult ch = openFileDialogHinh.ShowDialog();//Mơ hộp thoại cho phép NSD chọn hình cho sa n phầ m if(ch == DialogResult.OK)//NSD đồTng ý với hình đã chọn

//1 Lưu tến file cu a hình vừa copy nếu trến vào biếW n toàn cục đế sau này (Thếm/Sư a) sẽ cập nhật vào 2 thuộc tính hinh (Win Acc) và hinhweb (cu a Web) trong Table MH cu a DB imagechoose = System.IO.Path.GetFileName(openFileDialogHinh.FileName);

//chỉ lầW y tến file ko lầW y đường dầY n

//2 Copy hình vừa chọn vào thư mục hình Images cu.a App

(đế sau này Copy App đi nơi khác thư mục hình sẽ tự đi theo) try

System.IO.File.Copy(openFileDialogHinh.FileName, apppath + imagechoose, true); }catch(System.Exception ex) { MessageBox.Show("Có lồY i sao chép hình vào thư mục cu a App" + ex.Message); }

//MessageBox.Show(imagechoose); // chỉ viếWt đế thực nghiệm (sau này Khóa lại) }

 Biến toàn cục lưu giữ đường dẫn vật lý lưu trữ App mà ta đang lập trình: nhờ đó khi copy App này đi nơi khác (đường dẫn bị thay đổi) khi đó chi cần sữa chữa đường trong biến này là sẽ có hiệu lực cho toàn bộ App string apppath = "D:\\G18NTATSaleLotte\\ G18NTATSaleLotte\\Images\\";

//BIẾWN TOÀN CỤC LƯU ĐƯỜNG DẪYN ĐẾW THƯ MỤC LƯU APP BÀI LÀM NAY

HOẶC string apppath = System.IO.Path.GetDirectoryName

(System.IO.Path.GetDirectoryName(Application.StartupPath))

+ "\\Images\\" ; //BIẾWN TOÀN CỤC LƯU ĐƯỜNG DẪYN ĐẾW THƯ MỤC LƯU APP BÀI LÀM NAY

 Sử dụng nút Task của mHTableAdapter1 viết lại câu lệnh InsertCommand như sau:

(msmh, tenmh, dvt, giaban, giavon, mota, hinh, msnhom, hsd, math)

(@msmh,@tenmh,@dvt,@giaban,@giavon,@mota,@hinh,@msnhom,@hsd,@math)

 Viết code cho nút lệnh btnThem

4.4.3 Sửa chữa thông tin món ăn:

/// private void btnthem_Click(object sender, EventArgs e)

//Cho or khồng cho : Thay đồ.i các ồ textbox chi tiếWt món ăn(Bến pha.i) txtmsMH.Enabled = !txtmsMH.Enabled; txttenMH.Enabled = !txttenMH.Enabled; txtgiavon.Enabled = !txtgiavon.Enabled; txtgiaban.Enabled = !txtgiaban.Enabled; txtdvtban.Enabled = !txtdvtban.Enabled; //Giữ nguyến txtDVTvon chỉ cầTu thếm 1 đvt -> tự update bến dvtvon txtmota.Enabled = !txtmota.Enabled; comboBoxTH.Enabled = !comboBoxTH.Enabled; dateTimePickerhsd.Enabled = !dateTimePickerhsd.Enabled;

//Khóa các nút lệnh Sư.a, Xóa, Chuyế.n btnsua.Enabled = !btnsua.Enabled; btnxoa.Enabled = !btnxoa.Enabled; btnchuyenhom.Enabled = !btnchuyenhom.Enabled; btnchuyenTH.Enabled = !btnchuyenTH.Enabled;

// Đồ.i nút lệnh từ thếm thành Lưu if (btnthem.Text.Trim() == "Thếm món ăn mới")

{ txtmsMH.Text = "Khồng đế trồWng"; txttenMH.Text = ""; txtgiavon.Text = "L" + ex.Message); }

//B2: Ta.i 2 danh sách MH lến 2 ListBox (S, D) theo Nhóm MH tương ứng đã chon try

{ this.mHTableAdapterS.Fill(this._ 1G18NTAT_SaleLotteDataSetMHS.MH, comboBoxS.SelectedValue.ToString().Trim());

{ this.mHTableAdapterD.Fill(this._ 1G18NTAT_SaleLotteDataSetMHD.MH, comboBoxD.SelectedValue.ToString().Trim());

Bổ sung thêm câu lệnh SQL UpdateQuery cho mhTableAdapter2 như

Hình 4-12 Bổ sung câu lệnh SQL cho mhTableAdapter bên Source (S)

Với câu lệnh Update được viết như sau:

UPDATE MH SET msnhom = @msnhom_new mã nhóm (mới, sau chuyển) WHERE (msnhom = @msnhom) mã nhóm (cũ, trước chuyển) Viết thủ tục nút lệnh btnALR

B1: Chuyển Tất cả các MH từ Nhóm S sang Nhóm D;

B2: Xong, tải dữ liệu mới lên 2 ListBox (như trên=> Copy từ Fr_Load)

/// CHUYẾ.N TẪWT CA HM TỪ NHÓM S (L) => NHÓM D (R)

/// private void btnARL_Click(object sender, EventArgs e)

//B1: Chuyế.n TầWt ca MH từ Nhóm S sang Nhóm D; try{ mhTableAdapter2.UpdateQuery(comboBoxD.SelectedValue.ToString().Trim(), comboBoxS.SelectedValue.ToString().Trim());

}catch(System.Exception ex){MessageBox.Show("Có lồYi chuyế.n tầWt ca các MH L=>R" + ex.Message); }

//B2: Ta.i 2 danh sách MH lến 2 ListBox (S, D) theo Nhóm MH tương ứng đã chon try

{ this.mHTableAdapterS.Fill(this._1G18NTAT_SaleLotteDataSetMHS.MH, comboBoxS.SelectedValue.ToString().Trim());

{ this.mHTableAdapterD.Fill(this._1G18NTAT_SaleLotteDataSetMHD.MH,

Bổ sung thêm câu lệnh SQL UpdateQuery cho mhTableAdapterD tương tự 4.6.3.3

Với câu lệnh Update được viết như sau:

UPDATE MH SET msnhom = @msnhom_new mã nhóm (mới, sau chuyển) WHERE (msnhom = @msnhom) mã nhóm (cũ, trước chuyển) Viết thủ tục nút lệnh btnARL

B1: Chuyển Tất cả các MH từ Nhóm D sang Nhóm S;

B2: Xong, tải dữ liệu mới lên 2 ListBox (như trên=> Copy từ Fr_Load)

/// CHUYẾ.N TẪWT CA HM TỪ NHÓM D (R) => NHÓM S (L)

/// private void btnARL_Click_1(object sender, EventArgs e)

{ //B1: Chuyế.n TầWt ca MH từ Nhóm D sang Nhóm S; try{ mHTableAdapterD.UpdateQuery(comboBoxS.SelectedValue.ToString().Trim(), comboBoxD.SelectedValue.ToString().Trim());

}catch (System.Exception ex){MessageBox.Show("Có lồYi chuyế.n tầWt ca các MH R=>L" + ex.Message);}

//B2: Ta.i 2 danh sách MH lến 2 ListBox (S, D) theo Nhóm MH tương ứng đã chon try

{ this.mHTableAdapterS.Fill(this._1G18NTAT_SaleLotteDataSetMHS.MH, comboBoxS.SelectedValue.ToString().Trim());

{ this.mHTableAdapterD.Fill(this._1G18NTAT_SaleLotteDataSetMHD.MH, comboBoxD.SelectedValue.ToString().Trim());

4.6.4 Các xử lý khác trong Form chuyển nhóm

Bổ sung công cụ ToolTip từ ToolBox vào App: toolTip1

4.6.4.1 Ẩn các nút trong các trường hợp không chuyển được

* Không chọn được [.Enable = False] các nút chuyển( > < >> Copy từ Fr_Load)

//CHUYẾ.N 1 HM TỪ NHÓM S (L) => NHÓM D (R) private void btnLR_Click(object sender, EventArgs e)

{//B1: Chuyế.n MH từ Nhóm S sang Nhóm D; try{

//B2: Ta.i 2 danh sách MH lến 2 ListBox (S, D) theo Nhóm MH tương ứng đã chon try

{ this.mHTableAdapterS.Fill(this._1G18NTAT_SaleLotteDataSetMHS.MH, comboBoxS.SelectedValue.ToString().Trim());

{ this.mHTableAdapterD.Fill(this._1G18NTAT_SaleLotteDataSetMHD.MH, comboBoxD.SelectedValue.ToString().Trim());

Viết lại SQL Update cho mHTableAdapterD

UPDATE MH SET msnhom = @msnhom :mã nhóm

WHERE (msmh = @msmh) :mã hàng

Viết thủ tục nút lệnh btnRL

B1: Chuyển MH từ Nhóm D sang Nhóm S;

B2: Xong, tải dữ liệu mới lên 2 ListBox (như trên=> Copy từ Fr_Load)

//CHUYẾ.N 1 HM TỪ NHÓM D (R) => NHÓM S (L) private void btnRL_Click(object sender, EventArgs e)

//B1: Chuyế.n MH từ Nhóm D sang Nhóm S; try { mHTableAdapterD.Update(comboBoxS.SelectedValue.ToString().Trim(), listBoxD.SelectedValue.ToString().Trim()); }catch (System.Exception ex) { MessageBox.Show("Có lồYi chuyế.n 1 MH R=>L" + ex.Message); }

//B2: Ta.i 2 danh sách MH lến 2 ListBox (S, D) theo Nhóm MH tương ứng đã chon try

{ this.mHTableAdapterS.Fill(this._ 1G18NTAT_SaleLotteDataSetMHS.MH, comboBoxS.SelectedValue.ToString().Trim());

{ this.mHTableAdapterD.Fill(this._ 1G18NTAT_SaleLotteDataSetMHD.MH, comboBoxD.SelectedValue.ToString().Trim());

Bổ sung thêm câu lệnh SQL UpdateQuery cho mhTableAdapter2 như

Hình 4-12 Bổ sung câu lệnh SQL cho mhTableAdapter bên Source (S)

Với câu lệnh Update được viết như sau:

UPDATE MH SET msnhom = @msnhom_new mã nhóm (mới, sau chuyển) WHERE (msnhom = @msnhom) mã nhóm (cũ, trước chuyển) Viết thủ tục nút lệnh btnALR

B1: Chuyển Tất cả các MH từ Nhóm S sang Nhóm D;

B2: Xong, tải dữ liệu mới lên 2 ListBox (như trên=> Copy từ Fr_Load)

/// CHUYẾ.N TẪWT CA HM TỪ NHÓM S (L) => NHÓM D (R)

/// private void btnARL_Click(object sender, EventArgs e)

//B1: Chuyế.n TầWt ca MH từ Nhóm S sang Nhóm D; try{ mhTableAdapter2.UpdateQuery(comboBoxD.SelectedValue.ToString().Trim(), comboBoxS.SelectedValue.ToString().Trim());

}catch(System.Exception ex){MessageBox.Show("Có lồYi chuyế.n tầWt ca các MH L=>R" + ex.Message); }

//B2: Ta.i 2 danh sách MH lến 2 ListBox (S, D) theo Nhóm MH tương ứng đã chon try

{ this.mHTableAdapterS.Fill(this._1G18NTAT_SaleLotteDataSetMHS.MH, comboBoxS.SelectedValue.ToString().Trim());

{ this.mHTableAdapterD.Fill(this._1G18NTAT_SaleLotteDataSetMHD.MH,

Bổ sung thêm câu lệnh SQL UpdateQuery cho mhTableAdapterD tương tự 4.6.3.3

Với câu lệnh Update được viết như sau:

UPDATE MH SET msnhom = @msnhom_new mã nhóm (mới, sau chuyển) WHERE (msnhom = @msnhom) mã nhóm (cũ, trước chuyển) Viết thủ tục nút lệnh btnARL

B1: Chuyển Tất cả các MH từ Nhóm D sang Nhóm S;

B2: Xong, tải dữ liệu mới lên 2 ListBox (như trên=> Copy từ Fr_Load)

/// CHUYẾ.N TẪWT CA HM TỪ NHÓM D (R) => NHÓM S (L)

/// private void btnARL_Click_1(object sender, EventArgs e)

{ //B1: Chuyế.n TầWt ca MH từ Nhóm D sang Nhóm S; try{ mHTableAdapterD.UpdateQuery(comboBoxS.SelectedValue.ToString().Trim(), comboBoxD.SelectedValue.ToString().Trim());

}catch (System.Exception ex){MessageBox.Show("Có lồYi chuyế.n tầWt ca các MH R=>L" + ex.Message);}

//B2: Ta.i 2 danh sách MH lến 2 ListBox (S, D) theo Nhóm MH tương ứng đã chon try

{ this.mHTableAdapterS.Fill(this._1G18NTAT_SaleLotteDataSetMHS.MH, comboBoxS.SelectedValue.ToString().Trim());

{ this.mHTableAdapterD.Fill(this._1G18NTAT_SaleLotteDataSetMHD.MH, comboBoxD.SelectedValue.ToString().Trim());

4.6.4 Các xử lý khác trong Form chuyển nhóm

Bổ sung công cụ ToolTip từ ToolBox vào App: toolTip1

4.6.4.1 Ẩn các nút trong các trường hợp không chuyển được

* Không chọn được [.Enable = False] các nút chuyển( > < >> S.D ALL THU TỤC (System.Data) static Boolean kh = false, nv = false;//băWt đầTu lập HD = đã Xác định (chọn)

KH và NV public frInvoice(DataTable tb)

InitializeComponent(); b = tb; //LẪWY THAM SỖW DS CHI TIẾWT BILL SANG ĐẪY

} private void frInvoice_Load(object sender, EventArgs e)

// TODO: This line of code loads data into the

'_1G118NTAT_SaleLotteDataSetHD.HOADON' table You can move, or remove it, as needed. this.hOADONTableAdapter.Fill(this._1G118NTAT_SaleLotteDataSetHD.HOADON); //1.NV comboBoxNV_SelectedIndexChanged(sender, e); lbNgay.Text = System.DateTime.Now.ToShortDateString(); lbTGio.Text = "Chưa băWt đầTu";

//2.Hóa đơn comboBoxloai_SelectedIndexChanged(sender, e); if (b != null)//ĐÃ CÓ PHIẾWU TÌNH TIẾTN (BILL) KHỖNG RỖYNG => LẬP

INVOICE(ĐÃ ĐỊNH NGHĨA ĐÚNG DATAPROPERT)

{ lbBillSUM.Text = "PHIẾWU HÓA ĐƠN HIỆN CÓ :" + b.Compute("Count(msmh)", "").ToString() + "MÓN, TỖ.NG TIẾTN =" + b.Compute("Sum(thanhtien)", "").ToString() + "Đ"; dataGridViewBill.DataSource = b;//Ta.i DATATABLE b (đã cập nhật chi tiếWt món ăn)

} else//BILL RỖYNG => CHĂWC CHĂWN KHỖNG XA.Y RA

/// [1]TIM KH-nếWu khồng có - [2] NHẬP KH MỚI - [3] LƯU VÀO KH MOWISDB -[4] CHỌN KH

/// TÌM KH THEO THỖNG TIN ĐƯỢC NHẬP TRONG Textbox Tìm,

/// [1] TÌM THẪWY ÍT NHẪWT 1 KH => CHO NSD CHỌN 1 TRONG DATAGRIDVIEW

/// [2]NẾWU KO TÌM THẪWY THÌ CHO THẾM MỚI &

/// [3] LƯU THỖNG TIN KH MỚI => CHO CHỌN KH MỚI NÀY

/// [4] NẾWU KH MỚI NHẬP OR TÌM THẪWY (ít nhầWt 1 KH) THÌ CHO NSD CHỌN 1 TRONG DATAGRIDVIEW

- 54 - private void btnTimKH_Click(object sender, EventArgs e)

{ btnHuyKH.Visible = true; //Hu.y Tìm bầWt cứ lúc nào if (btnTimKH.Text.Trim() == "Tìm KH") //[1]TìM KH

{//1.1 Tìm theo nội dung nhập try

{ this.kHACHHANGTableAdapter.Fill(this._1G118NTAThu_SaleLotteDataKH.KHACHHANG, txtTimKH.Text.Trim(), txtTimKH.Text, txtTimKH.Text, txtTimKH.Text, txtTimKH.Text); } catch (System.Exception) { }

//1.2 Tìm khồng có KH nến cho nhập KH mới (Hiện nội dung thếm KH mới, Ẫ.n DS DataGridView) if (dataGridViewKH.Rows.Count < 2) //Khồng tìm thầWy KH(luồn có dòng trồWng)=> cho thếm KH mới

{ btnTimKH.Text = "Thếm KH mới"; dataGridViewKH.Visible = false;//Ẫ.n DS KH (datagridViewKH): khồng có dữ liệu KHỖNG tự ầ.n

} else //tìm thầWy, cho Chọn 1 KH trong dataGridView

{ btnTimKH.Text = "Chọn đi"; dataGridViewKH.Visible = true;

} else if (btnTimKH.Text.Trim() == "Thếm KH mới")

{//2.1 Hiện các ồ TextBox nhập thồng tin KH mới lbmskh.Visible = true; lbtenkh.Visible = true; lbdckh.Visible = true; lbsdt.Visible = true; lbmsthue.Visible = true; txtmskh.Visible = true; txttenkh.Visible = true; txtdckh.Visible = true; txtsdt.Visible = true; txtmsthue.Visible = true; txtmskh.Enabled = true; txttenkh.Enabled = true; txtdckh.Enabled = true; txtsdt.Enabled = true; txtmsthue.Enabled = true;

//2.2 Xóa trồWng các ồ textbox đế NSD nhập KH mới txtmskh.Text = txtTimKH.Text.Trim();//Vì tìm khồng có nến khồng trùng mskh txttenkh.Text = ""; txtdckh.Text = ""; txtsdt.Text = ""; txtmsthue.Text = "";

//2.3 ĐỖ.I NHÃN NÚT LỆNH THÀNH =>"Lưu KH" mới nhập btnTimKH.Text = "Lưu KH mới";

} else if (btnTimKH.Text.Trim() == "Lưu KH mới")//[3] LƯU THỖNG TIN KH MỚI {//3.1 Lưu thồng tin vào DB (Pha.i viếWt SQL Insert TableAdapterKH) if (txtmskh.Text != "")

MessageBox.Show("Thếm KH mới xong!");

//3.2 Cho phép chọn KH txtTimKH.Text = txtmskh.Text.Trim();//Gán mskh vừa nhập mới lến txtTimKH = đế thồWng nhầWt chọn btnTimKH.Text = "Chọn KH";//Xư lý bến dưới

//3.3 Khóa các ồ TextBox thồng tin KH txtmskh.Enabled = false; txttenkh.Enabled = false; txtdckh.Enabled = false; txtsdt.Enabled = false; txtmsthue.Enabled = false;

MessageBox.Show("Có lồYi thếm KH mới =" + ex.Message); btnTimKH.Text = "Thếm KH mới";

MessageBox.Show("Pha.i nhập ít nhầWt là mã KH"); btnTimKH.Text = "Thếm KH mới";

} else if (btnTimKH.Text.Trim() == "Chọn KH")//[4] NẾWU KH MỚI NHẬP OR TÌM THẪWY (ít nhầWt 1 KH) THÌ CHO NSD CHỌN 1 TRONG DATAGRIDVIEW

//4.2 Khóa các ồ TextBox thồng tin KH và cho hiện lến txtmskh.Enabled = false; txttenkh.Enabled = false; txtdckh.Enabled = false; txtsdt.Enabled = false; txtmsthue.Enabled = false;

//Hiện TextBox nhập thồng tin KH mới lbmskh.Visible = true; lbtenkh.Visible = true; lbdckh.Visible = true; lbsdt.Visible = true; lbmsthue.Visible = true; txtmskh.Visible = true; txttenkh.Visible = true; txtdckh.Visible = true; txtsdt.Visible = true; txtmsthue.Visible = true;

//4.3 Khồng cho tìm nữa(NếWu TimKh khác sư dụng button "Hu.y tìm") btnTimKH.Enabled = false; txtTimKH.Enabled = false;

//4.4 CÁC XƯ LÝ HÓA ĐƠN kh = true; //Đã xác định được KH

//XÁC ĐỊNH VỊ TRÍ CHỌN KH static int vt = 0;//Mặc định KH đầTu tiến private void dataGridViewKH_CellClick(object sender,

{ vt = e.RowIndex; txtmskh.Text = txtTimKH.Text dataGridViewKH.Rows[vt].Cells[0].Value.ToString().Trim();

- 56 - txttenkh.Text = txtTimKH.Text dataGridViewKH.Rows[vt].Cells[1].Value.ToString(); txtdckh.Text = txtTimKH.Text dataGridViewKH.Rows[vt].Cells[2].Value.ToString(); txtsdt.Text = txtTimKH.Text dataGridViewKH.Rows[vt].Cells[4].Value.ToString(); txtmsthue.Text = txtTimKH.Text dataGridViewKH.Rows[vt].Cells[3].Value.ToString();

/// private void btnHuyKH_Click(object sender, EventArgs e)

//1 Cho tìm lại btnTimKH.Enabled = true; txtTimKH.Enabled = true; txtTimKH.Text = ""; btnTimKH.Text = "Tìm KH";

//2.Ẫ.n tầWt ca các nội dung kếWt qua tìm

// Hiện các Textbox nhập thồng tin KH mới lbmskh.Visible = false; lbtenkh.Visible = false; lbdckh.Visible = false; lbsdt.Visible = false; lbmsthue.Visible = false; txtmskh.Visible = false; txttenkh.Visible = false; txtdckh.Visible = false; txtsdt.Visible = false; txtmsthue.Visible = false;

//Xóa trồWng các Textbox đế NSD nhập mới txtmskh.Text = ""; txttenkh.Text = ""; txtdckh.Text = ""; txtsdt.Text = ""; txtmsthue.Text = "";

//Ẫ.n DS KH dataGridViewKH.Visible = false;

//3.Ẫ.n btnHuyTim(chính là button này) btnHuyKH.Visible = false;

//4.HU.Y HÓA ĐƠN kh = false;

/// private void comboBoxNV_SelectedIndexChanged(object sender, EventArgs e) this.nHANVIENTableAdapter.Fill(this._1G118NTAThu_SaleLotteDataNV.NHANVIEN); lbmsnv.Text = comboBoxNV.SelectedValue.ToString().Trim();

//NHA.Y ĐỖTNG HỖT private void timer1_Tick(object sender, EventArgs e)

{ lbtime.Text = System.DateTime.Now.ToLongTimeString();

//CHỌN NV private void btnChonNV_Click(object sender, EventArgs e)

{ btnHuyChonNV.Visible = true; comboBoxNV.Enabled = false; btnChonNV.Enabled = false; lbNgay.Text = System.DateTime.Now.ToShortDateString(); lbTGio.Text = lbtime.Text.Trim();

//CÁC XƯ LÝ HÓA ĐƠN nv = true;

//HU.Y CHỌN NV private void btnHuyChonNV_Click(object sender, EventArgs e)

{ btnHuyChonNV.Visible = false; comboBoxNV.Enabled = true; btnChonNV.Enabled = true; lbNgay.Text = System.DateTime.Now.ToShortDateString(); lbTGio.Text = "Chưa băWt đầTu";

//CÁC XƯ LÝ HÓA ĐƠN nv = false;

//PHẪTN CHI TIẾWT HÓA ĐƠN

/// private void Invoice()

{ if (!kh || !nv) groupBoxHD.Visible = false;//CHƯA XÁC ĐỊNH ĐU KH HOẶC NV NẾN Ẫ.N HÓA ĐƠN else //ĐÃ XÁC ĐỊNH ĐU.

DateTime t = System.DateTime.Now; lbngaylap.Text = t.ToShortDateString(); lbmshd.Text = txtTimKH.Text.Trim() + t.Year.ToString().Substring(2,

2) + t.Month.ToString().Trim() + t.Day.ToString().Trim() + t.Day.ToString().Trim() + t.Hour.ToString().Trim() + t.Minute.ToString().Trim() + t.Second.ToString().Trim();

//2.HĐ cùng KH được lập cách nhau ít nhầWt 1s

//LƯU HD và CTHD vào DB

- 58 - private void btnAccept_Click(object sender, EventArgs e)

{ hDTableAdapter.Insert(lbmshd.Text.Trim(), DateTime.Parse(lbngaylap.T ext.Trim()), txtTimKH.Text.Trim(), lbmsnv.Text.Trim(), comboBoxLoai.SelectedIndex); MessageBox.Show("HD OK"); foreach(DataRow r in b.Rows)

{ cTHDTableAdapter.Insert(lbmshd.Text.Trim(), r["msmh"].ToString().Trim(), double.Parse(r["sl"].ToString().Trim()));

}catch(System.Exception ex) { MessageBox.Show("LỖYI THẾM

HD và CTHD" +ex.Message); }

//KO CHO HUY TIM KH or HUY TÌM NV => CHI HU.Y HD btnHuyChonNV.Visible = false; btnHuyTimKH.Visible = false;

//HU.Y HD private void btnHuyHD_Click(object sender, EventArgs e)

{ cTHDTableAdapter.Delete(lbmshd.Text.Trim(), r["msmh"].ToString().Trim());

MessageBox.Show("DELETE CTHD OK"); hDTableAdapter.Delete(lbmshd.Text.Trim());

MessageBox.Show("delete HD OK");

} catch (System.Exception ex) { MessageBox.Show("LỖYI XÓA

HD và CTHD" + ex.Message); }

//MƠ KH và NV btnHuyTimKH_Click(sender, e); btnHuyChonNV_Click(sender, e);

TRÌNH================================================================================== //Đóng vếT form Main private void buttonClose_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Đóng khồng (Y/N)?", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ch == DialogResult.Yes)

//Đóng hă.n chương trình private void btnExit_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Thoát chương trình khồng (Y/N)?",

"Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ch == DialogResult.Yes)

FORM BILL using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace G118NTAThu_SaleLotte

{ public partial class FrBill : Form

//Đóng FrBill vếT FrMain private void btnClose_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Đóng khồng (Y/N)?", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ch == DialogResult.Yes)

//Thoát hă.n chương trình private void btnExit_Click(object sender, EventArgs e)

DialogResult ch = MessageBox.Show("Thoát chương trình khồng (Y/N)?",

"Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ch == DialogResult.Yes)

} private void FrBill_Load(object sender, EventArgs e)

// TODO: This line of code loads data into the

'_1G118NTAThu_SaleDSetNHOMMH.NHOMMH' table You can move, or remove it, as needed. this.nHOMMHTableAdapter.Fill(this._1G118NTAThu_SaleDSetNHOMMH.NHOMMH); try

// TODO: This line of code loads data into the

'_1G118NTAThu_SaleDSetMH.MH' table You can move, or remove it, as needed. this.mHTableAdapter.Fill(this._1G118NTAThu_SaleDSetMH.MH, comboBox1.SelectedValue.ToString().Trim());

// TODO: This line of code loads data into the

'_1G118NTAThu_SaleLotteDataSetTH.THUONGHIEU' table You can move, or remove it, as needed. this.tHUONGHIEUTableAdapter.Fill(this._1G118NTAThu_SaleLotteDataSetTH.THUONGHIEU);

} private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e) { try

// TODO: This line of code loads data into the

'_1G118NTAThu_SaleDSetMH.MH' table You can move, or remove it, as needed. this.mHTableAdapter.Fill(this._1G118NTAThu_SaleDSetMH.MH, comboBox1.SelectedValue.ToString().Trim());

} catch (System.Exception ex) { }; txtSL.Text = "1";

/// XÁC ĐỊNH VỊ TRÍ CU.A MÓN ĂN ĐƯỢC CHỌN => CHUYẾ.N BILL TÍNH TIẾTN

/// static int vt = 0; //biếWn toàn cục lưu vị trí cu.a món ăn được chọn

/// CHỌN MÓN ĂN VÀO PHIẾWU TÍNH TIẾTN

/// static float c = 0, s = 0; private void dataGridViewMH_CellClick(object sender,

} private void btnBILL_Click(object sender, EventArgs e)

.I CÓ ÍT NHẪWT 1 MÓN ĂN

//2.LẪWY MÓN ĂN ĐÃ CHỌN TRONG DANH SÁCH CHUẪ.N BỊ NẠP VÀO BILL

//3 XƯ LÝ TRÙNG MÓN ĂN ĐÃ CÓ SĂYN TRONG DS CHUẪ.N BỊ NẠP VÀO => CHI TĂNG SỖW LƯỢNG(khồng thếm món ăn) for (int i = 0; i < dataGridViewBill.Rows.Count - 1; i++)

{ if (dataGridViewBill.Rows[i].Cells[i].Value.ToString().Trim() = h.Cells[0].Value.ToString().Trim())

{ float sl float.Parse(dataGridViewBill.Rows[i].Cells[4].Value.ToString().Trim()); sl += float.Parse(txtSL.Text.Trim()); dataGridViewBill.Rows[i].Cells[4].Value = sl.ToString(); goto kt;

}//Chạy hếWt vòng lặp for mà khồng có if nào được thực hiện => món ăn đang chọn

//4 THẾM MÓN ĂN MỚI ĐÃ CHỌN TRONG DS NẠP VÀO BILL dataGridViewBill.Rows.Add(h.Cells[0].Value.ToString().Trim(), h.Cells[1].Value.ToString(), float.Parse(h.Cells[2].Value.ToString().Trim()), h.Cells[3].Value.ToString(), float.Parse(txtSL.Text.Trim()), float.Parse(h.Cells[2].Value.ToString().Trim()) * float.Parse(txtSL.Text.Trim())); //5.TÍNH TỖ.NG MÓN ĂN & TỖ.NG TIẾTN TRẾN BILL: XUẪWT RA LBSUM c += 1; //Tăng lến 1 món kt: s += float.Parse(h.Cells[2].Value.ToString().Trim()) * float.Parse(txtSL.Text.Trim());//tồ.ng tiếTn = cồng thếm thành tiếTn cu.a món mới thếm lbBillSUM.Text = "PHIẾWU TÍNH TIẾTN HIỆN CÓ :" + c.ToString() +

"MÓN, TỖ.NG TIẾTN =" + s.ToString() + "Đ";

Chương 3: THIẾT LẬP BỘ CÀI ĐẶT SETUP CHO PHÂN HỆ KẾ

Phần App được lập trình nêu trên là phần Source Code (mã nguồn) do tác giả lưu giữ nhằm đảm bảo bản quyền và phục vụ việc nâng cấp, cải tiến và phát triển chương trình sau này Để có thể chuyển App đến người dùng thỉ phải thực hiện thủ tục đóng gói và chuyển giao sản phẩm đến người dùng (Gọi là: Package and Deployment) hoặc lập bộ Setup.

Ngường sử dụng sẽ dùng bộ Setup (thông thường có file Setup.exe hoặc Install.exe) để cài đặt vào máy tính làm việc của mình Thông thường, sau khi cài đặt, sản phẩm phần mềm sẽ lưu trong thư mục C:\Program Files [x86]\ đồng thời sẽ có biểu tượng (icon) trên Desktop và Program Menu của người dùng để tiện sử dụng.

Sản phẩm sau khi cài đặt trên máy tính người dùng (tức là, trong C:\Program Files [x86]\ ) là sản phẩm mã máy Không thể đọc hiểu theo dạng văn bản (text: mở trên

NotePad), kế cả tác giả Về nguyên tắc là không dịch ngược: mã máy (không thể hiểu) => mã lệnh (if, while,….).

Tóm lại: trình tự sản phẩm phần mềm từ sản xuất (lập trình) đến người dùng, thông thường phải qua 3 bước:

Lập trình Source Codes (đang học)

=> Đóng thành bộ Setup.exe (nhiệm vụ chương này)

=> Cài lên máy tính người dùng (C:\Program Files [x86]\ ): NSD dùng phần mềm

THIẾT LẬP BỘ CÀI ĐẶT SETUP CHO PHÂN HỆ KẾ TOÁN 45 6.1 Giới thiệu chung

Công cụ sử dụng thiết lập bộ cài đặt Setup cho App

Bộ công cụ hỗ trợ lập bộ cài đặt (Setup/Install) của các phần mềm WinApp:

[1] VSI_bundle.exe (Visual Studio Insataller): Gói dịch vụ cài đặt bổ sung vào MS Visual Studio NET hỗ trợ thiết lập bộ cài đặt (Setup) dạng đơn giản: Đề tài này sử dụng gói dịch vụ này.

[2] InstallShield2019LimitedEdition.exe: Gói dịch vụ cài đặt bổ sung vào MS Visual Studio NET 2019 hỗ trợ thiết lập bộ cài đặt (Setup) dạng đầy đủ Để bộ công công cụ MS Visual Studio NET có chức năng đóng gói (Package) bộ cài đặt (Setup/Install) thì phải cài đặt bổ sung bộ hỗ trợ kèm theo (nêu trên) với phiên bản phù hợp (Ví dụ: 2015, 2017, )

Thiết lập bộ cài đặt Setup cho App

Phài mở source winapp trên Visual Studio NET, đản bảo chạy được: không lỗi.

Bước 1: THÊM PROJECT MỚI VÀO SOLUTION HIỆN TẠI, Như Hình 0 -13

+ Phải[tên Solution]->Add->New Project : G118NTAThu_SaleLotteSetup

Hình 0-13 Lập Project bộ cài đặt Setup

+ Installed: Other Project Types : Visual Studio Installer (Lập bộ cài đặt đơn giản):

Hình 0-14 Thiết lập các thông tin cho Project Setup

Bước 2: THIẾT LẬP CÁC THÀNH PHẦN KẾT QUẢ CÀI ĐẶT, như Hình 0 -15

+ Application Folder : Thư mục của phần mềm trong %OS%\Program Files… + User’s Desktop : trên nền Desktop

+ User’s Program Menu: mục chọn trong [Start]->Programs->…

Phải[mục tương ứng nêu trên]->Add->Project Output: Primary Output (Active)

Hình 0-15 Thiết lập sản phẩm bộ Setup (cài đặt ở đâu)

Bước 3: CẤU HÌNH BIÊN DỊCH, như Hình 0 -16

Phải[tên Solution]/SolutionExplorer->Configuration Manager: [x] Setup [Build] Với Release (thương mại) || Debug (thử nghiệm)

Hình 0-16 Thiết lập biên dịch bộ Setup

Bước 4: BIÊN DỊCH BỘ CÀI ĐẶT

[Build]->(Re)Build Solution: trên dòng trạng thái (dưới, trái) Successful

Sản phẩm bộ cài trong thư mục:

D:\G118NTAThu_SaleLotteV2\G118NTAThu_SaleLotteSetup\Release: vì đã lực chọn trong Bước 3 là Release

D:\G118NTAThu_SaleLotteV2\G118NTAThu_SaleLotteSetup\Debug

CHUYỂN GIAO BỘ CÀI ĐẶT : SETUP CHO NSD

Khi cần thảo gỡ (Uninstall) phần mềm thì phải thực hiện trong:

+ Control Panel: Programs and Features

+ Không được Xóa thư mục phần mềm %OS%\Program Files…

Vì nếu “Xóa” sẽ không cài đặt lại được (khi cài đặt sẽ bị báo là đã có => chỉ có thể khắc phục bằng cách Xóa các Key trong Registry)

Bước 5: THIẾT LẬP THÊM CÁC ĐẶC TÍNH KHÁC CỦA BỘ CÀI ĐẶT Đặt chọn vào vị trí Project Setup / Solution Explorer:

Sử dụng thanh công cụ ngày trên Solution Explorer

+ File System Editor: Thiết lập các kết quả cài đặt / máy tính NSD

+ Registry Editor: thiết lập các Key bảo mật và tự động / Registry của máy tính NSD

+ User’s Interface Editor: Thiết kế các màn hình chờ trong quá trình cài đặt PM

Start: Bắt đầu cài đặt

Progress: Trong quá trình cài đặt

End : kết thúc việc cài đặt

Có thể: thêm / xóa bớt (Thay đổi thứ tự) các cửa sổ màn hình chờ cài đặt

Thay đổi = thiết kế lại (VD: Việt hóa) : sử dụng của sổ Properties

+ Custom Action: Thiết kế các các thành phần hỗ trợ khác của bộ cài đặt ;

VD bộ tháo gỡ (Uninstall, Rolback, )

+ Launch Conditional Editor: Thiết lệp kênh giao tiếp trên Inrternet giữa NSD và công ty sản xuất phần mềm để hỗ trợ NSD phần mềm có bản quyền (VD: khi xảy ra lỗi, gửi lổi về công ty sản xuất -> hỗ trợ trực tuyến được).

+ File Types Editor: thiếp lập các “đuôi” = phần mở rộng của tên các tập tin liên quan PM (VD: PM Word có các “đuôi” khi double click sẽ mở PM Word, doc docx …

BIÊN DỊCH LẠI -> CÀI ĐẶT LẠI: ĐỂ CÓ TÁC DỤNG

GHI CHÚ: CÁC THUỘC TÍNH KHÁC CỦA PM

[Solution Explorer]: Properties->AssemblyInfo.cs

+ Phải cài đặt DB riêng -> khai báo lại chuỗi kết nối trong file XML kèm theo sau khi cài đặt

Cài đặt Setup App vào máy tính NSD

- Copy file Release ra ngoài desktop

- Lưu vào ổ: C:\ProgramFiles(x86)\DefaultCompanyName\ G118NTAThu_SaleLotteSetup\

- Kiểm tra bảo mật thành công

- Chuổi kết nối dữ liệu có thể thay đổi nếu cần:

NÀY SANG MÁY TÍNH KHÁC PHA.I ĐIẾTU CHI.NH CHUỖYI NÀY, NẾWU CẪTN >

Ngày đăng: 13/04/2024, 21:44

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w