# -*- 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/', 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/', 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//', 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/', 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//', 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//', 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 }