369 lines
18 KiB
Python
369 lines
18 KiB
Python
# -*- coding: utf-8 -*-
|
|
import base64
|
|
import datetime
|
|
import json
|
|
import os
|
|
|
|
import pdfkit
|
|
import pytz
|
|
from unidecode import unidecode
|
|
|
|
from ..models.template import SimpleTemplate
|
|
from ..utils import lang, util_datetime
|
|
from odoo import http
|
|
from odoo.http import request
|
|
from weasyprint import HTML
|
|
path_file = os.path.dirname(__file__)
|
|
|
|
dict_languages = {
|
|
'de': json.load(open(f'{path_file}/../static/lang/de.json'))
|
|
}
|
|
tz = pytz.timezone('Asia/Ho_Chi_Minh')
|
|
|
|
|
|
def read_all_object(obj, prefix_loop: str = "", delete_old_field=True) -> dict:
|
|
ret = obj.read()[0]
|
|
for f in ret.keys():
|
|
if isinstance(ret[f], datetime.date):
|
|
if f == 'ngay_tao_ho_so':
|
|
_month = lang.convert_common(lang.convert_month(ret['ngay_tao_ho_so'].month))
|
|
ret['ngay_tao_ho_so'] = ret['ngay_tao_ho_so'].strftime(f"%d. {_month} %Y")
|
|
else:
|
|
ret[f] = ret[f].strftime("%d.%m.%Y")
|
|
if prefix_loop != "":
|
|
for f in ['kinh_nghiem_lam_viecs', 'thong_tin_giao_ducs', 'thong_tin_phu_huynhs', 'lich_su_cham_socs',
|
|
'ky_nang_ngon_ngus', 'ky_nang_khacs',
|
|
'lich_su_update_ho_so', 'lich_su_dao_taos', 'ho_so_chung_chis', 'chuong_trinh_tham_gias',
|
|
'tinh_trang_ho_so_visas', 'ky_nang_tin_hocs']:
|
|
ret[prefix_loop + f] = [gd.read()[0] for gd in obj.__getattribute__(f)]
|
|
ret[f + '_display'] = "unset" if ret[prefix_loop + f] else "none"
|
|
|
|
if f == 'thong_tin_giao_ducs':
|
|
ret[prefix_loop + f + '_pho_thong'] = []
|
|
ret[prefix_loop + f + '_dai_hoc'] = []
|
|
for e in ret[prefix_loop + f]:
|
|
loai_bang_cap = e['loai_bang_cap']
|
|
e['thoi_gian_tu'] = util_datetime.validate(e['thoi_gian_tu'])
|
|
e['thoi_gian_den'] = util_datetime.validate(e['thoi_gian_den'])
|
|
e['loai_bang_cap'] = lang.convert_common(e['loai_bang_cap'])
|
|
if loai_bang_cap in ['high_school', 'middle_school', 'primary_school']:
|
|
ret[prefix_loop + f + '_pho_thong'].append(e)
|
|
else:
|
|
ret[prefix_loop + f + '_dai_hoc'].append(e)
|
|
ret[f + '_dai_hoc_display'] = "unset" if ret[prefix_loop + f + '_dai_hoc'] else "none"
|
|
ret[f + '_pho_thong_display'] = "unset" if ret[prefix_loop + f + '_pho_thong'] else "none"
|
|
elif f == 'thong_tin_phu_huynhs':
|
|
tmp = ret[prefix_loop + f].copy()
|
|
for idx, v in enumerate(tmp):
|
|
v['ten_phu_huynh'] = lang.convert_common(v.get('ten_phu_huynh', ''))
|
|
v['moi_quan_he'] = lang.convert_common(v.get('moi_quan_he', ''))
|
|
v['so_dien_thoai'] = lang.convert_common(v.get('so_dien_thoai', ''))
|
|
v['email'] = lang.convert_common(v.get('email', ''))
|
|
v['dia_chi'] = lang.convert_common(v.get('dia_chi', ''))
|
|
v['ghi_chu'] = lang.convert_common(v.get('ghi_chu', ''))
|
|
ret[prefix_loop + f][idx] = v
|
|
elif f == 'lich_su_cham_socs':
|
|
tmp = ret[prefix_loop + f].copy()
|
|
for idx, v in enumerate(tmp):
|
|
v['ngay_cham_soc'] = util_datetime.validate(v.get('ngay_cham_soc'))
|
|
v['noi_dung'] = lang.convert_common(v.get('noi_dung', ''))
|
|
v['danh_gia'] = lang.convert_common(v.get('danh_gia', ''))
|
|
v['ket_qua'] = lang.convert_common(v.get('ket_qua', ''))
|
|
v['ghi_chu'] = lang.convert_common(v.get('ghi_chu', ''))
|
|
ret[prefix_loop + f][idx] = v
|
|
elif f == 'ky_nang_ngon_ngus':
|
|
tmp = ret[prefix_loop + f].copy()
|
|
for idx, v in enumerate(tmp):
|
|
ret[prefix_loop + f][idx]['loai_ngon_ngu'] = lang.convert_common(v['loai_ngon_ngu'])
|
|
ret[prefix_loop + f][idx]['thoi_gian_tu'] = util_datetime.validate(v['thoi_gian_tu'])
|
|
ret[prefix_loop + f][idx]['thoi_gian_den'] = util_datetime.validate(v['thoi_gian_den'])
|
|
else:
|
|
tmp = ret[prefix_loop + f].copy()
|
|
for idx, v in enumerate(tmp):
|
|
ret[prefix_loop + f][idx]['thoi_gian_tu'] = util_datetime.validate(v.get('thoi_gian_tu'))
|
|
ret[prefix_loop + f][idx]['thoi_gian_den'] = util_datetime.validate(v.get('thoi_gian_den'))
|
|
if delete_old_field:
|
|
del ret[f]
|
|
ret['ho'] = unidecode(ret['ho']).upper()
|
|
ret['ten'] = unidecode(ret['ten']).upper()
|
|
return ret
|
|
|
|
|
|
template_cv_dhk = SimpleTemplate(open(f"{path_file}/../static/template/cv/lebenslauf-hocvien-cenacademy.html").read())
|
|
template_cv_cdvb = SimpleTemplate(open(f"{path_file}/../static/template/cv/lebenslauf-hocvien-cenacademy.html").read())
|
|
template_thu_dong_luc = SimpleTemplate(
|
|
open(f"{path_file}/../static/template/thu_dong_luc/motivationsschreiben-nganhnghe-cdvb-cenacademy.html").read())
|
|
template_lich_phong_van = SimpleTemplate(
|
|
open(f"{path_file}/../static/template/phong_van/lich_phong_van.html").read())
|
|
template_ket_qua_phong_van = SimpleTemplate(
|
|
open(f"{path_file}/../static/template/phong_van/ket_qua_phong_van.html").read())
|
|
cv_header_png = "data:image/png;base64," + base64.b64encode(
|
|
open(f"{path_file}/../static/template/header.png", "rb").read()).decode('utf-8')
|
|
cv_frame_png = "data:image/png;base64," + base64.b64encode(
|
|
open(f"{path_file}/../static/template/frame.png", "rb").read()).decode('utf-8')
|
|
cv_footer_png = "data:image/png;base64," + base64.b64encode(
|
|
open(f"{path_file}/../static/template/footer.png", "rb").read()).decode('utf-8')
|
|
cv_profile_png = "data:image/png;base64," + base64.b64encode(
|
|
open(f"{path_file}/../static/template/profile.png", "rb").read()).decode('utf-8')
|
|
|
|
# options = {
|
|
# 'encoding': 'UTF-8',
|
|
# 'javascript-delay': '10', # Optional
|
|
# 'enable-local-file-access': True, # To be able to access CSS
|
|
# 'orientation': 'Portrait',
|
|
# 'page-size': 'A4',
|
|
# 'custom-header': [('Accept-Encoding', 'gzip')],
|
|
# 'print-media-type': None,
|
|
# "disable-local-file-access": None,
|
|
# }
|
|
# options = {
|
|
# 'page-size': 'Letter',
|
|
# 'margin-top': '0.1in',
|
|
# 'margin-right': '0.1in',
|
|
# 'margin-bottom': '0.75in',
|
|
# 'margin-left': '0.1in',
|
|
# 'encoding': "UTF-8",
|
|
# 'no-outline': None
|
|
# }
|
|
|
|
options = {
|
|
'page-size': 'A4', # Đảm bảo trang được đặt kích thước là A4
|
|
'margin-top': '0in', # Đặt lề trên thành 0 để nội dung chiếm toàn bộ trang
|
|
'margin-right': '0in', # Đặt lề phải thành 0
|
|
'margin-bottom': '0in', # Đặt lề dưới thành 0
|
|
'margin-left': '0in', # Đặt lề trái thành 0
|
|
'encoding': "UTF-8", # Đặt mã hóa là UTF-8 để hỗ trợ ký tự đặc biệt
|
|
'enable-local-file-access': True, # Cho phép truy cập tệp cục bộ (CSS, hình ảnh...)
|
|
'zoom': '1.0' # Sử dụng zoom để điều chỉnh kích thước nếu cần
|
|
}
|
|
|
|
|
|
def read_object_quan_he_hoc_vien_doi_tac(obj, vong_phong_van):
|
|
ret = obj.read()[0]
|
|
print(ret)
|
|
list_keys = list(ret.keys())
|
|
for k in list_keys:
|
|
if k.startswith(f'pv{vong_phong_van}_feedback_'):
|
|
sub_key = k.replace(f'pv{vong_phong_van}_feedback_', '')
|
|
value = int(ret[k]) if ret[k] != False else 0
|
|
for i in range(5): # Độ đánh giá là trên thang 5
|
|
ret[f"{sub_key}_{i + 1}"] = '-o' if value < i + 1 else ''
|
|
ret['vong_phong_van'] = vong_phong_van
|
|
for f in ['thoi_gian', 'hinh_thuc', 'dia_diem', 'nhom_nganh', 'nghe_nghiep', 'nhan_xet']:
|
|
ret[f] = ret[f'pv{vong_phong_van}_{f}']
|
|
ret['thoi_gian'] = ret[f'pv{vong_phong_van}_thoi_gian'].astimezone(tz).strftime("%H:%M:%S %m/%d/%Y")
|
|
ret['thoi_gian_ngay'] = ret[f'pv{vong_phong_van}_thoi_gian'].astimezone(tz).strftime("%m/%d/%Y")
|
|
ret['nhom_nganh'] = '' if ret['nhom_nganh'] == False else ret['nhom_nganh'][1]
|
|
ret['passed'] = 'checked' if ret[f'pv{vong_phong_van}_ket_qua'] == 'passed' else ''
|
|
ret['failed'] = 'checked' if ret[f'pv{vong_phong_van}_ket_qua'] == 'failed' else ''
|
|
return ret
|
|
|
|
|
|
class CenhomesStudent(http.Controller):
|
|
@http.route('/cenhomes/hoc_vien_phong_thu_tuc/<sale_id>', auth='public', website=True)
|
|
def hoc_vien_phong_thu_tuc(self, sale_id, **kw):
|
|
try:
|
|
if sale_id != "default":
|
|
sale_id = base64.b64decode(sale_id).decode()
|
|
sale_id = request.env["res.users"].sudo().search([('id', '=', int(sale_id))])
|
|
sale_id = sale_id.id
|
|
if not sale_id:
|
|
return request.redirect('/cenhomes/404')
|
|
else:
|
|
sale_id = False
|
|
except Exception as err:
|
|
print(err)
|
|
return request.redirect('/cenhomes/404')
|
|
|
|
for k in kw.keys():
|
|
kw[k] = None if kw.get(k) == '' else kw.get(k)
|
|
if kw.get('ten') and kw.get('ho') and kw.get('email') and kw.get('so_dien_thoai_lien_he'):
|
|
kw['sale'] = sale_id
|
|
result_create = request.env["cenhomes.hoc_vien_phong_thu_tuc"].sudo().create(kw)
|
|
print("result_create", result_create)
|
|
return request.redirect('/cenhomes/phong_thu_tuc/success')
|
|
|
|
return http.request.render('cenhomes_student.form_create_new_hoc_vien', {})
|
|
|
|
@http.route('/cenhomes/phong_thu_tuc/success', auth='public', website=True)
|
|
def hoc_vien_phong_thu_tuc_success(self, **kw):
|
|
return http.request.render('cenhomes_student.notify_create_new_hoc_vien', {})
|
|
|
|
@http.route('/cenhomes/404', auth='public', website=True)
|
|
def page_404(self, **kw):
|
|
return http.request.render('cenhomes_student.page_404', {})
|
|
|
|
@http.route('/cenhomes/hoc_vien/objects', auth='public')
|
|
def list(self, **kw):
|
|
return http.request.render('cenhomes_student.cenhomes_hoc_vien_listing', {
|
|
'root': '/cenhomes/hoc_vien',
|
|
'objects': http.request.env['cenhomes.hoc_vien'].search([]),
|
|
})
|
|
|
|
@http.route('/cenhomes/hoc_vien/objects/<model("cenhomes.hoc_vien"):obj>', auth='public')
|
|
def object(self, obj, **kw):
|
|
return http.request.render('cenhomes_student.cenhomes_hoc_vien_object', {
|
|
'object': obj
|
|
})
|
|
|
|
@http.route(
|
|
'/cenhomes/du_hoc_kep/hoc_vien/thu_dong_luc/<model("cenhomes.hoc_vien"):hoc_vien>/<model("cenhomes.thu_dong_luc"):thu_dong_luc>',
|
|
auth='user')
|
|
def view_thu_dong_luc(self, hoc_vien, thu_dong_luc, **kw):
|
|
x = hoc_vien.read()[0]
|
|
path_thu_dong_luc = f'{path_file}/../static/template/thu_dong_luc'
|
|
path_html = f'{path_thu_dong_luc}/thu_dong_luc_{hoc_vien.id}_{thu_dong_luc.id}.html'
|
|
path_pdf = f'{path_thu_dong_luc}/thu_dong_luc_pdf_{hoc_vien.id}_{thu_dong_luc.id}.pdf'
|
|
|
|
for k, v in thu_dong_luc.read()[0].items():
|
|
x[k] = v
|
|
_month = lang.convert_common(lang.convert_month(x['ngay_tao_ho_so'].month))
|
|
x['ngay_tao_ho_so'] = x['ngay_tao_ho_so'].strftime(f"%d. {_month} %Y")
|
|
|
|
thu_dong_luc = template_thu_dong_luc.render(x)
|
|
thu_dong_luc = thu_dong_luc.replace('header.png', cv_header_png)
|
|
thu_dong_luc = thu_dong_luc.replace('frame.png', cv_frame_png)
|
|
thu_dong_luc = thu_dong_luc.replace('footer.png', cv_footer_png)
|
|
if x['anh_profile']:
|
|
thu_dong_luc = thu_dong_luc.replace('profile.png',
|
|
"data:image/png;base64," + x['anh_profile'].decode('utf-8'))
|
|
else:
|
|
thu_dong_luc = thu_dong_luc.replace('profile.png', cv_profile_png)
|
|
|
|
with open(path_html, 'w') as f:
|
|
f.write(thu_dong_luc)
|
|
|
|
pdfkit.from_file(path_html, path_pdf, options=options, verbose=True)
|
|
pdf = open(path_pdf, 'rb').read()
|
|
pdf_http_headers = [
|
|
('Content-Type', 'application/pdf'),
|
|
('Content-Length', len(pdf)),
|
|
]
|
|
return request.make_response(pdf, headers=pdf_http_headers)
|
|
|
|
@http.route('/cenhomes/du_hoc_kep/hoc_vien/cv/<model("cenhomes.hoc_vien"):obj>', auth='user')
|
|
def view_cv(self, obj, **kw):
|
|
type_cv = kw.get('type')
|
|
x = read_all_object(obj, "loop:")
|
|
cv = template_cv_dhk.render(x)
|
|
path_cv = f'{path_file}/../static/template/cv'
|
|
path_html = f'{path_cv}/cv_{obj.id}.html'
|
|
|
|
# Lấy ngày hiện tại và định dạng theo định dạng mong muốn
|
|
ngay_cap_nhat = datetime.datetime.today().strftime('%Y_%m_%d')
|
|
# Remove diacritics and replace spaces for the student's name
|
|
ten_hoc_vien = unidecode(obj.ho).replace(' ', '_') + "_" + unidecode(obj.ten).replace(' ', '_')
|
|
# path_pdf = f'{path_cv}/cv_pdf_{obj.id}.pdf'
|
|
path_pdf = f'{path_cv}/cv_{ten_hoc_vien}_{obj.id}_Lebenslauf_{ngay_cap_nhat}.pdf'
|
|
|
|
cv = cv.replace('header.png', cv_header_png)
|
|
cv = cv.replace('frame.png', cv_frame_png)
|
|
cv = cv.replace('footer.png', cv_footer_png)
|
|
if x['anh_profile']:
|
|
cv = cv.replace('profile.png', "data:image/png;base64," + x['anh_profile'].decode('utf-8'))
|
|
else:
|
|
cv = cv.replace('profile.png', cv_profile_png)
|
|
|
|
with open(path_html, 'w') as f:
|
|
f.write(cv)
|
|
|
|
# # pdfkit.from_file(path_html, path_pdf, options=options, verbose=True)
|
|
# HTML(path_html).write_pdf(path_pdf)
|
|
# pdf = open(path_pdf, 'rb').read()
|
|
# pdf_http_headers = [
|
|
# ('Content-Type', 'application/pdf'),
|
|
# ('Content-Length', len(pdf)),
|
|
# ('Content-Disposition', f'attachment; filename="{ten_hoc_vien}_{obj.id}_Lebenslauf_{ngay_cap_nhat}.pdf"'),
|
|
# ]
|
|
# return request.make_response(pdf, headers=pdf_http_headers)
|
|
# Đọc nội dung HTML từ file
|
|
with open(path_html, 'r') as f:
|
|
html_content = f.read()
|
|
|
|
# Trả về nội dung HTML trực tiếp cho trình duyệt
|
|
html_http_headers = [
|
|
('Content-Type', 'text/html; charset=utf-8'),
|
|
('Content-Length', len(html_content)),
|
|
]
|
|
|
|
return request.make_response(html_content, headers=html_http_headers)
|
|
|
|
@http.route('/cenhomes/du_hoc_kep/hoc_vien/huong_dan_anh_so_yeu_ly_lich', auth='public')
|
|
def huong_dan_anh_so_yeu_ly_lich(self, **kw):
|
|
pdf = open(f'{path_file}/../static/Muster_Lebenslauf_Hocvien_Cenacademy.pdf', 'rb').read()
|
|
pdf_http_headers = [
|
|
('Content-Type', 'application/pdf'),
|
|
('Content-Length', len(pdf)),
|
|
('Content-disposition', 'inline; filename=\"huong_dan_anh_so_yeu_ly_lich.pdf\"'),
|
|
]
|
|
return request.make_response(pdf, headers=pdf_http_headers)
|
|
|
|
@http.route(
|
|
'/cenhomes/du_hoc_kep/hoc_vien/lich_phong_van/<model("cenhomes.hoc_vien"):obj>/<model("cenhomes.quan_he_hoc_vien_doi_tac"):quan_he_hoc_vien_doi_tac>',
|
|
auth='user')
|
|
def view_lich_phong_van(self, obj, quan_he_hoc_vien_doi_tac, **kw):
|
|
vong_phong_van = kw.get('vong_phong_van')
|
|
x = obj.read()[0]
|
|
x.update(read_object_quan_he_hoc_vien_doi_tac(quan_he_hoc_vien_doi_tac, vong_phong_van))
|
|
print(x)
|
|
lich_pvan = template_lich_phong_van.render(x)
|
|
path_lich_phong_van = f'{path_file}/../static/template/phong_van'
|
|
path_html = f'{path_lich_phong_van}/lich_phong_van_{obj.id}.html'
|
|
path_pdf = f'{path_lich_phong_van}/lich_phong_van_pdf_{obj.id}.pdf'
|
|
|
|
with open(path_html, 'w') as f:
|
|
f.write(lich_pvan)
|
|
|
|
pdfkit.from_file(path_html, path_pdf, options=options,
|
|
verbose=True, css=f'{path_file}/../static/src/css/font-awesome.min.css')
|
|
pdf = open(path_pdf, 'rb').read()
|
|
pdf_http_headers = [
|
|
('Content-Type', 'application/pdf'),
|
|
('Content-Length', len(pdf)),
|
|
]
|
|
return request.make_response(pdf, headers=pdf_http_headers)
|
|
|
|
@http.route(
|
|
'/cenhomes/du_hoc_kep/hoc_vien/ket_qua_phong_van/<model("cenhomes.hoc_vien"):obj>/<model("cenhomes.quan_he_hoc_vien_doi_tac"):quan_he_hoc_vien_doi_tac>',
|
|
auth='user')
|
|
def view_ket_qua_phong_van(self, obj, quan_he_hoc_vien_doi_tac, **kw):
|
|
x = obj.read()[0]
|
|
vong_phong_van = kw.get('vong_phong_van')
|
|
x.update(read_object_quan_he_hoc_vien_doi_tac(quan_he_hoc_vien_doi_tac, vong_phong_van))
|
|
print(x)
|
|
ket_qua_pvan = template_ket_qua_phong_van.render(x)
|
|
path_ket_qua_phong_van = f'{path_file}/../static/template/phong_van'
|
|
path_html = f'{path_ket_qua_phong_van}/ket_qua_phong_van_{obj.id}.html'
|
|
path_pdf = f'{path_ket_qua_phong_van}/ket_qua_phong_van_pdf_{obj.id}.pdf'
|
|
|
|
with open(path_html, 'w') as f:
|
|
f.write(ket_qua_pvan)
|
|
|
|
pdfkit.from_file(path_html, path_pdf, options=options,
|
|
verbose=True, css=f'{path_file}/../static/src/css/font-awesome.min.css')
|
|
pdf = open(path_pdf, 'rb').read()
|
|
pdf_http_headers = [
|
|
('Content-Type', 'application/pdf'),
|
|
('Content-Length', len(pdf)),
|
|
]
|
|
return request.make_response(pdf, headers=pdf_http_headers)
|
|
|
|
@http.route('/cenhomes/test', type='http', auth="none", methods=['GET'], csrf=False)
|
|
def test1111(self, **kw):
|
|
print(kw)
|
|
if request.httprequest.method == 'HEAD':
|
|
return ''
|
|
return kw['hub.challenge']
|
|
|
|
@http.route('/cenhomes/test', type='json', auth="none", methods=['POST'], csrf=False)
|
|
def test2222(self, *args, **kwargs):
|
|
print(kwargs)
|
|
print('received webhook data')
|
|
data = json.loads(request.httprequest.data)
|
|
print('data', data)
|
|
return {
|
|
'success': True,
|
|
'status': 'OK',
|
|
'code': 200
|
|
}
|