Tổng quan
- Version: 1.0
- Author: Tùng Thanh
- Created: 20/02/2022
Lưu trữ tất cả các thông tin profile của sale. Theo mô hình EAV
Entity-Attribute-Value
Tham khảo mô hình EAV tại đây
Mô hình Database Structure:
User Profile
Database
users table
Field name | Type | Note |
---|---|---|
ID |
int(10) index key unique | ID dùng để xác định 1 user, tất cả các function khi xài user data đều phải dựa trên userID |
fullName |
varchar (100) | Tên user |
fullNameAncii |
varchar (100) | Tên user dạng Ancii( dùng cho filter) |
password |
varchar (128) | Hiện ko còn xài |
mobilePhone |
varchar (100) index | Số điện thoại |
sex |
varchar (10) | Giới tính |
idNumber |
varchar (100) | Số CMND/ CCCD |
status |
varchar (20) | Trạng thái |
rsmUserID |
int (11) | userID của RSM |
userReferral |
int (11) | userID của RSA |
... |
Và các fields khác |
user_login table
Field name | Type | Note |
---|---|---|
ID |
int(10) index key unique | |
userID |
int (10) | ID của user |
username |
varchar (255) | Tên đăng nhập của user. Khi type là "phone" thì username = mobilePhone |
type |
varchar (10) | phone or social |
referralCode |
varchar (255) unique |
Mã MFast, được gen theo thuật toán random chuỗi bất kì
|
u_meta table
Field name | Type | Note |
---|---|---|
ID |
int(10) index key unique | |
alias |
varchar (50) | key của Entity |
group |
varchar (50) | |
type |
varchar (50) | kiểu dữ liệu |
lengh |
int (11) | Độ dài giá trị |
label_vi |
varchar (255) | Label của Entity |
u_meta_data table
Field name | Type | Note |
---|---|---|
ID |
int(10) index key unique | |
userID |
int(10) index | ID của user |
metaID |
int(10) index | ID của u_meta |
metaValue |
varchar (255) | Giá trị của Value Meta |
updatedDate |
timestamp | Ngày giờ cập nhật |
Modeling
Các Model tương ứng được đặt tại /models/meta/
User_m
User_login_m
U_meta_data_m
U_meta_m
Functions
$this->U_meta_data_m->update($metaID, $value, $userID);
$this->load->model('u_meta/U_meta_data_m');
$this->U_meta_data_m->get_full_data($userID);
Result:
(
[tax_committed_photo] => /uploads/support/4755/16375719774755.JPG
[country_id_number] => 187149279
[full_name] => Tungtung
[mobile_phone] => 0905044591
[email_address] => jxjxj@gmail.com
[address_current] => Xã Nghĩa Tiến Thị Xã Thái Hòa, Nghệ An
[gender] => male
[country_id_date_of_birth] => 01-02-1992
[country_id_issued_date] => 2010-01-01
[date_of_birth] => 01-02-1992
[tax_number_status] => PENDING
[address_current_district] => Q. Gò Vấp - Hồ Chí Minh
[is_verified_email] => 1
[tax_number] => 8330771206
[tax_number_org] => Cục Thuế TP Đà Nẵng
[place_of_birth] => Thanh Hoá
[country_id_issued_by] => Bạc Liêu
[country_id_number_household] => 0909097949
[country_id_name] => Tên này từ meta
[country_id_address] => Xã Nghĩa Tiến Thị Xã Thái Hòa, Nghệ An
[selfie_photo_with_id_number] => /uploads/support/4755/16375719734755.JPG
[tax_committed_photo_status] => FAILURE
[tax_committed_photo_message] => Tên công ty trên cam kết thuế phải là: Công ty TNHH Dịch vụ Thương Mại Viễn Thông Số
[ctv_agreement] => 1
[selfie_photo] =>
[potential_skills] => 1
[last_time_login] => 1645008862339
[is_online] =>
[country_id_photo_front] => /uploads/support/4755/16375719664755.JPG
[country_id_photo_back] => /uploads/support/4755/16375719664755.JPG
[payment_gateway_confirm] => 0
)
VD: Cần lấy thông tin số CMND/ CCCD của user
$this->load->model('u_meta/U_meta_data_m');
$this->U_meta_data_m->get_by_meta(8, $userID);
Result:
(
[ID] => 607
[userID] => 4755
[metaID] => 8
[metaValue] => 187149279
[updatedDate] => 2021-04-06 18:14:24
)
$this->load->model('u_meta/U_meta_data_m');
$this->U_meta_data_m->value_by_meta($metaID, $userID)
VD: Cần lấy họ tên của user
$this->U_meta_data_m->value_by_meta(11, 4755)
Result:
"Nguyễn Thanh Tùng"
Định danh (KYC)
Định danh tài khoản( kyc) là bước bắt buộc trong quy trình onboard của 1 pro user (sale). User sau khi được định danh thì mới có thể thực hiện các tác vụ mua sắm, lên hồ sơ vay Khác hàng, mua bảo hiểm,...
Để kiểm tra user đã được định danh hay chưa bằng cách sử dụng
$this->User_m->has_kyc($userID)
Nếu result là true
thì user đó đã được định danh
Flow
Link thiết kế zeplin https://app.zeplin.io/project/5ccbe514ece43c3484787679/dashboard?tag=%C4%90%E1%BB%8Bnh%20danh
Step 1: Thông tin cá nhân
Field name | Meta ID | Note |
---|---|---|
Giới tính |
7 | male/ female |
email |
4 | |
Huyện/ Tỉnh |
6 | ID của table districts |
Địa chỉ liên hệ |
5 |
Step 2: xác thực Email
Sau khi hoàn tất bước 1 thì hệ thống sẽ gửi 1 email có 4 số đến email mà user cung cấp
/mfast_api_v1/personal/sent_otp_email
OTP email được storage tại table user_otp_email
thông qua Model User_otp_email_m
Step 3: xác thực hình tải lên CMND/ CCCD
User khi upload hình mặt trước và mặt sau CMND/ CCCD sẽ nhận diện thông qua OCR được cung cấp bởi đối tác VVNAI hoặc FPT qua api
/app_api_v1/ocr/identify
Nếu hình chụp CMND/ CCCD được OCR đúng sẽ auto fill các thông tin
Field name | Meta ID | Meta Alias |
---|---|---|
Họ tên |
11 | country_id_name |
Số CMND/ CCCD |
8 | country_id_number |
Ngày cấp |
13 | country_id_issued_date |
Nơi cấp |
14 | country_id_issued_by |
Step 4: Kí hợp động dịch vụ
User đọc và đồng ý điều khoản MFast.
Tất cả thông tin 4 steps trên sẽ được post qua api
/app/user/addInfomationSubmit
Thông tin Ngân hàng
Dùng để rút tiền từ ví MFast
Database Structure
Table main_banking
Field name | Meta ID | Note |
---|---|---|
userID |
int (10) index unique | ID của table users |
bank_accountNumber |
varchar (30) | Số tài khoản NH |
bank_name |
varchar (50) | Tên NH |
bank_branch |
varchar (255) | Chi nhánh NH |
platform |
varchar (10) | Default "mfast" |
Modeling
Được đặt tại /models/main/Main_banking_m.php
deleted
= 1
$this->Main_banking_m->_save($data_save);
Result:
111 // bankingID
$this->load->model('main/Main_banking_m');
$this->Main_banking_m->pick_one($userID);
Result:
(
[ID] => 36934
[userID] => 4755
[cmnd_path] => https://dgp-storage.nyc3.digitaloceanspaces.com/dasdasd
[cmnd_sau_path] => https://appay-rc.cloudcms.vn/
[sign_path] =>
[tax_path] => https://appay-rc.cloudcms.vn/uploads/support/4755/6e839daef0ad02d210f3f69fa05fbd61.png
[selfie_path] => https://appay-rc.cloudcms.vn/uploads/support/4755/d9a462d87e189cf46fac2629023e4e99.png
[idNumberIssueDate] => 2010-01-01
[idNumberIssueBy] => Bạc Liêu
[dob] =>
[status] => success
[error_message] => Hình chân dung không hợp lệ
[created_date] => 2021-05-06 14:29:49
[updated_date] => 2021-05-07 14:32:34
[bank_fullName] => NGUYEN THI TEST
[bank_accountNumber] => 700071004542
[bank_name] => SHINHAN VIETNAM
[bank_branch] => SHINHAN VIETNAM HO CHI MINH (HCM)
[bank_idNumber] => 205341091
[user_verified] => admin
[verified_tax] => 0
[verified_tax_status] => failed
[verified_tax_message] => Cam kết thuế 2021 hết hạn, vui lòng tải và cập nhật CKT 2022 mới bạn nhé!!!
[deleted] => 0
[tax_number] => 8117508662
[address] => Xã Nghĩa Tiến Thị Xã Thái Hòa, Nghệ An
[tax_confirm] => human
[tax_confirm_message] =>
[user_pending] =>
[userCMND] => 187149279
[platform] => mfast
[movedCloud] => 0
[note] =>
[correct] => 1
)
Mã số thuế Cá nhân
Dùng để xác định nguồn tiền ra của user
Database Structure
Được storage tại 2 nơi table u_meta_data
với metaID
17 và table main_banking
với field tax_number
Functions
$this->U_meta_data_m->update(17, 'ma_so_thue', $userID);
$this->U_meta_data_m->value_by_meta(17, $userID);
Result
19880921
Vay cá nhân (PL)
Nghiệp vụ (Subscriptions)
MFast định nghĩa nghiệp vụ dựa trên quá trình handle 1 hồ sơ vay Khách hàng:
A. Giới thiệu Khách hàng: Làm nhiệm vụ tìm Khách hàng tiềm năng và thu thập thông tin cơ bản: Họ tên KH, CMND/ CCCD, số điện thoại và địa chỉ
B. Tư vấn Khách hàng: Làm nhiệm vụ tư vấn nhu cầu vay của Khách hàng như sản phẩm vay, khoản vay, số tháng vay và lựa chọn công ty tài chính phù hợp
C. Thu thập hồ sơ: Làm nhiệm vụ thu thập chứng từ hồ sơ Khách hàng như giấy tờ Hộ khẩu, phiếu thông tin KH, chụp ảnh KH, ...
Từ đó MFast phân loại user thành nghiệp vụ với quy định và mức commission khác nhau:
predsa
Thực hiện công đoạn A
dsa
Thực hiện công đoạn A B C
tsa
Thực hiện công đoạn A B
courier
Thực hiện công đoạn C
ftsa
Thực hiện công đoạn B C
pos
Thực hiện công đoạn A B
Các nghiệp vụ của user được storage trong table project_subscriptions
model Project_subscription_m
tương ứng
Database Structure
NoteMFast chia user làm 2 loại: normal user và pro user>
normal user: chỉ có nghiệp vụ predsa
pro user: có nghiệp vụ predsa
và 1 trong số các nghiệp vụ: dsa
tsa
courier
ftsa
pos
Level
Mỗi nghiệp vụ subscription sẽ có nhiều cấp bậc (level) của nghiệp vụ đó. Level được tổ chức storage tại table main_role_levels
. Trong từng level sẽ config tham gia #dự án tài chính nào
Table project_subscriptions
Field name | Type | Note |
---|---|---|
userID |
int (10) index unique | ID của table users |
projectRoleID |
int (10) index | ID của table project_roles |
projectAlias |
varchar (20) | alias của table project_roles |
projectLevelID |
int (10) index | ID của table main_role_levels |
projectLevelAlias |
varchar (20) | alias của table main_role_levels |
status |
varchar (20) | Trạng thái của nghiệp vụ: active còn hoạt động disabled ngừng hoạt động |
createdDate |
datetime | Ngày tạo |
updatedDate |
datetime | Ngày cập nhật |
Modeling
/model/Project_role_m
/model/main/Main_role_level_m
/model/Project_subscription_m
Functions
$this->Project_subscription_m->list_by_userID($userID, 'active');
Result:
(
[0] => Array
(
[ID] => 14248
[secret] => 9b1772305383393bcfc907896dbca662
[userID] => 4755
[parentUserID] =>
[projectID] => 1
[projectRoleID] => 2
[projectRoleAlias] => predsa
[projectLevelID] => 0
[projectLevelAlias] => V_PREDSA
[status] => active
[statusNote] =>
[money] => 0
[point] => 0
[pointRep] => 490
[pointRepQuota] => 500
[subscriptionCode] =>
[ownerID] => 0
[ownerRoleAlias] =>
[referralID] => 936741
[referralRoleAlias] => rsa
[createdDate] => 2018-01-27 20:03:20
[updatedDate] => 2019-09-20 16:48:45
[underID] =>
[asmUserID] =>
[supUserID] =>
[balanceOutOfDate] => 0
[balanceUpdateDate] => 2018-04-06 15:15:30
[dsa_crLimitLead] => 150
[is_tsa] => 0
[receive_tsa_lead] => 1
[receive_ftsa_lead] => 1
[preferences] =>
[privateCourier] => 0
[leadCount] => 37
[tsaMaxLoadPerDay] => 10
[hr_area] =>
[platform] => appay
[convertRateLimit] => 0.00
)
[1] => Array
(
[ID] => 14249
[secret] => 39dc10a1543d90e5b363e1900ed80028
[userID] => 4755
[parentUserID] =>
[projectID] => 1
[projectRoleID] => 8
[projectRoleAlias] => rsa
[projectLevelID] => 0
[projectLevelAlias] => FEDSA_FE_RSA
[status] => active
[statusNote] =>
[money] => 0
[point] => 0
[pointRep] => 500
[pointRepQuota] => 500
[subscriptionCode] =>
[ownerID] => 0
[ownerRoleAlias] =>
[referralID] => 0
[referralRoleAlias] =>
[createdDate] => 2018-01-27 20:03:20
[updatedDate] => 2019-09-20 16:48:45
[underID] =>
[asmUserID] =>
[supUserID] =>
[balanceOutOfDate] => 0
[balanceUpdateDate] => 2020-10-01 10:55:30
[dsa_crLimitLead] => 150
[is_tsa] => 0
[receive_tsa_lead] => 1
[receive_ftsa_lead] => 1
[preferences] =>
[privateCourier] => 0
[leadCount] => 0
[tsaMaxLoadPerDay] => 10
[hr_area] =>
[platform] => appay
[convertRateLimit] => 0.00
)
)
$this->Project_subscription_m->is_exist($userID, $projectRoleAlias, $exceptSubsID="");
Ví dụ: Muốn kiểm tra user 4755 đã có nghiệp vụ dsa
hay chưa
$this->Project_subscription_m->is_exist(4755, 'dsa');
false // chưa có nghiệp vụ
true // nghiệp vụ đó đã tồn tại
$this->Main_role_level_m->detail_by_subsID($subscriptionID);
Ví dụ: Muốn get detail level của nghiệp vụ dsa
từ user 4755
$this->Main_role_level_m->detail_by_subsID(375095);
Result:
[ID] => 253
[levelName] => mDSA
[projectRoleID] => 1
[levelDescription] => Mfast DSA
[levelTerm] =>
[partnerID] => 0
[projectID] => ["1", "2", "7", "27", "23", "31", "32", "34","36"]
[levelGroup] => 28
[appayRate] => 0
[incentiveRate] => 0
[lead_priority] => 0
[leadPerDay] => 0
[leadPerMonth] => 0
[is_display] => 1
[checkin_campaign_allow] =>
[platform] => mfast
Ứng tuyển nghiệp vụ
Để tham gia lên hồ sơ dự án tài chính, ngoài nghiệp vụ predsa
được cấp mặc định cho user thì user phải đăng ký ứng tuyển nghiệp vụ theo từng dự án tài chính
Quy trình ứng tuyển:
Khách hàng (customers)
Được storage tại table main_customers
Database Structure
Table main_customers
Field name | Meta ID | Note |
---|---|---|
ID |
int(10) index key unique | ID dùng để xác định 1 Khách hàng, tất cả các function thuộc PL khi xài Khách hàng đều phải dựa trên customerID |
fullName |
varchar (100) | Tên Khách hàng |
fullNameAncii |
varchar (100) | Tên Khách hàng dạng Ancii( dùng cho filter) |
mobilePhone |
varchar (100) index | Số điện thoại |
sex |
varchar (10) | Giới tính |
idNumber |
varchar (100) | Số CMND/ CCCD |
status |
varchar (20) | Trạng thái |
addressProvince |
int (11) | ID của table provinces |
addressDistrict |
int (11) | ID của districts |
addressFull |
varchar (300) | Địa chỉ full của Khách hàng |
personalTaxNumber |
varchar (20) | Mã số thuế của Khách hàng |
Modeling
Đặt tại
models/main/Main_customer_m
Functions
$this->Main_customer_m->get_by_id($customerID);
Result:
[ID] => 1603264
[fullName] => NGUYỄN HỒNG MY
[fullNameAncii] => NGUYEN HONG MY
[idNumber] => 212812363
[addressProvince] => 41
[addressDistrict] => 458
[addressFull] =>
[addressNow] =>
[dob] =>
[area] =>
[gender] => F
[age] => 0
[mobilePhone] => 0938058693
[mobilePhone_new] =>
[otherPhone] =>
[officePhone] =>
[dashboardPhone] =>
[dpdPhone] =>
[companyName] =>
[companyAddress] =>
[createdDate] => 2022-02-24 14:28:02
[createdByUserID] => 40197
[updatedDate] =>
[updatedByUserID] => 0
[status] => 1
[customerSource] => predsa
[feDistrict] =>
[feProvince] =>
[date_of_birth] =>
[bank_accountNumber] =>
[personalTaxNumber] =>
[job] =>
[monthlyIncome] =>
[email] =>
$data_customer_save = [
'fullName' => clean_text($input['fullName']),
'fullNameAncii' => strip_unicode($input['fullName']),
'mobilePhone' => $input['mobilePhone'],
'addressProvince' => $district_detail['province_id'],
'addressDistrict' => $input['districtID'],
'addressFull' => "Đang cập nhật",
'customerSource' => $subscription['projectRoleAlias'],
'createdDate' => create_date(),
'createdByUserID' => $subscription['userID'],
'idNumber' => $input['idNumber'],
'status' => 1
];
$customerID = $this->Main_customer_m->save($data_customer_save, $customerID=null (for update));
Dự án tài chính
Flow
Database Structure
Table main_apps
Field name | Meta ID | Note |
---|---|---|
ID |
int(10) index key unique | ID dùng để xác định 1 hồ sơ Khách hàng |
customerID |
int (11) | ID của table main_customers |
projectID |
int (11) | ID của table projects xác định hs thuộc đối tác tài chính |
progress |
tinyint (1) index |
Tiến trình của hồ sơ: 0 đang xử lý (processing)2 hs bị đóng (hủy/ từ chối) closed 1 hs giải ngân (completed)
|
appUID |
varchar (100) | ID của hồ sơ từ phía đối tác (partner) |
appModel |
varchar (100) | Mô hình hồ sơ |
uwProductCode |
varchar (100) | Mã sản phẩm, productCode của table main_products_code |
uwProductName |
varchar (100) | Tên sản phẩm, productName của table main_products_code |
ccposCode |
varchar (50) | sale Code của hồ sơ |
uwRequestAmount |
double (0) | Khoản vay mà khách hàng yêu cầu |
uwTenureRequested |
double (0) | Thời hạn vay mà khách hàng yêu cầu |
uwInsurance |
tinyint (1) | Bảo hiểm khoản vay, quyết định đến commission của sale |
uwApproveAmount |
double (0) | Khoản vay được giải ngân |
uwTermApproved |
int (5) | Thời hạn vay được duyệt |
uwDateOfDisbursal |
date | Ngày giải ngân |
init... |
Xác định sale đầu tiên tạo hs |
initProcessUserID int (11): xác định sale đầu tiên lên hs, ID của table users initProcessSubsID int (11): nghiệp vụ, ID của table project_subscriptions initProcessID int (11): ID của process, ID của table main_role_process initProcessText varchar (100): processName của table main_role_process initProcessNote varchar (500): Ghi chúinitProcessDate datetime: Ngày giờ
|
last... |
Xác định sale cuối cùng cập nhật hs |
lastProcessUserID int (11): xác định sale cuối cùng lên hs, ID của table users lastProcessSubsID int (11): nghiệp vụ, ID của table project_subscriptions lastProcessID int (11): ID của process, ID của table main_role_process lastProcessText varchar (100): processName của table main_role_process lastProcessNote varchar (500): Ghi chúlastProcessDate datetime: Ngày giờ
|
[roleID]... |
Xác định sale cập nhật hs |
[roleID]ProcessUserID int (11): xác định sale cập nhật lên hs, ID của table users [roleID]ProcessSubsID int (11): nghiệp vụ, ID của table project_subscriptions [roleID]ProcessID int (11): ID của process, ID của table main_role_process [roleID]ProcessText varchar (100): processName của table main_role_process [roleID]ProcessNote varchar (500): Ghi chú[roleID]ProcessDate datetime: Ngày giờ
|
assign... |
Ủy quyền cho sale tiếp theo cập nhật hs |
assignProcessUserID int (11): xác định sale được giao, ID của table users assignProcessSubsID int (11): nghiệp vụ của sale được giao, ID của table project_subscriptions assignProcessDate datetime: Ngày giờ ủy quyền
|
Modeling
Note Model của các dự án tài chính đều phải extends từ PL_Model
. Ví dụ
// located: /models/[Partner_name]/[Partner_name]_m.php
class [Partner_name]_m extends PL_Model{
function __construct() {
parent::__construct();
$this->_table_name = "[Partner_name]_table";
}
}
Functions
Ví tích lũy MFast
Flow
Modeling
Được đặt tại /models/User_balance_m.php
Functions
$this->User_balance_m->add($userID, $amount, $title, $isTax=FALSE, $transData = [], $has_notify=TRUE);
// $userID: user được cộng tiền
// $amount: số tiền trước thuế user được cộng
// $title: Tiêu đề (VD: Cty thanh toán hoa hồng tháng 03/2022)
// $isTax: Có tính thuế hay không (true: có, false: không)
// $transData: dùng để add thêm giá trị của table transactions
// $has_notify: có notify cho user hay không
Thuế Thu nhập cá nhân
Flow
Modeling
Xác định user thuộc loại Cộng tác viên hay Hợp đồng lao động
Để xét user có thuộc HĐLĐ hay không thì check trong table tsa_ranking
-
Cộng tác viên: Xét user đã có Cam kết thuế hay chưa:
- Có CKT: khấu trừ thuế khi mức thu nhập trong tháng hơn >= 9,000,000
- Chưa có CKT: khấu trừ thuế khi mức thu nhập trong tháng hơn >= 2,000,000
- Hợp đồng lao động: Theo mức thu nhập lũy tiến
Sử dụng:
$this->Income_tax_m->mfast($currentAmount, $userID, $date=null, $estimate=FALSE);
// $currentAmount: số tiền cần tính
// $userID: cho user
// $date: tháng tính thuế
// $estimate: nếu là FALSE thì sẽ return kết quả tính chứ không trả cho user
Thu nhập Hoa hồng
Flow
Modeling
$amount
= [commAmount]
* [rate]
[rate]
được tính như sau:
- Sale: field
commLevel1_balance
của tablemfast_comm_rate
- RSA: field
commLevel2_balance
của tablemfast_comm_rate
- RSM: ưu tiên lấy từ table
mfast_rsm_tracking_by_project
rồi đến tablemfast_rsm_tracking
theorsmUserID
vàprojectAlias
Lưu ý: Đối với 2 loại cake
và tnex
thì không trả cho cấp RSM
[commAmount]
được tính như sau:
1. Hoa hồng là INS
/ DAA
:
Theo mệnh giá của projectAlias
2. Hoa hồng là PL
: sẽ đươc chi trả theo nhiều phase tùy vào dự án.
Theo công thức: loanATM
* insuranceRate
* roleRate
* productRate
loanATM
: số tiền giải ngân uwApproveAmount
trong main_apps
(đối với $nap là field uwLoanAmountNotInsurance
)
insuranceRate
: bảo hiểm khoản vay, nếu hồ sơ có bảo hiểm khoản vay hệ số là 1
, không có là 0.8
roleRate
: tỉ lệ theo nghiệp vụ, field mfastRoleRate
trong table project_roles
productRate
: tỉ lệ sản phẩm, field mfast_specRate
trong table main_products_code
theo uwProductCode
của main_apps
Lưu ý: Đối với 2 nghiệp vụ predsa
và courier
thì hoa hồng được tính trực tiếp field mfastRoleDirect
trong project_roles
mfast_comm_path
Functions
$this->Comm_m->process($user_id, $item_id, $project_alias, $total_amount, $extraData);
// $user_id: user được hưởng
// $item_id: ID của item tính hoa hồng
// $project_alias: loại INS/ DAA
// $total_amount: số tiền tính
// $extraData: thông tin thêm cần lưu trong table transactions (optional)
$this->Comm_m->pl($appID, $season = 1);
// $appID: ID của table main_apps
// $season: phase trả hoa hồng