From cd88f3b95950baa4815af27e914397f72f85c7a9 Mon Sep 17 00:00:00 2001 From: daovietanh99 Date: Tue, 30 Jan 2024 16:33:42 +0700 Subject: [PATCH] convert dict to xlsx --- cope2n-api/fwd_api/utils/file.py | 120 ++++++++++++++++++++++++++----- cope2n-api/report.xlsx | Bin 0 -> 6546 bytes 2 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 cope2n-api/report.xlsx diff --git a/cope2n-api/fwd_api/utils/file.py b/cope2n-api/fwd_api/utils/file.py index 92142da..44a2e9b 100644 --- a/cope2n-api/fwd_api/utils/file.py +++ b/cope2n-api/fwd_api/utils/file.py @@ -19,6 +19,9 @@ from ..celery_worker.client_connector import c_connector import imagesize import csv +from openpyxl import load_workbook +from openpyxl.styles import Font, Border, Side, PatternFill, NamedStyle + def validate_feedback_file(csv_file_path): required_columns = ['redemptionNumber', 'requestId', 'imeiNumber', 'imeiNumber2', 'Purchase Date', 'retailer', 'Sold to party', 'timetakenmilli'] missing_columns = [] @@ -327,21 +330,104 @@ def build_media_url_v2(media_id: str, user_id: int, sub_id: int, u_sync_id: str) token = image_authenticator.generate_img_token_v2(user_id, sub_id, u_sync_id) return f'{settings.BASE_URL}/api/ctel/v2/media/request/{media_id}/?token={token}' -def json2xlsx(input: json): - """_summary_ - Args: - input (json): - : [{ - Subs: Jan, # Subtotal name - Metadata: {num_imei: 1, - ...: ...} - Data: [{num_imei: 1, - ...: ...}] - }] - OR - input (json): - : [] - Return xlsx (object) - """ - pass \ No newline at end of file +def get_value(_dict, keys): + keys = keys.split('.') + value = _dict + for key in keys: + if not key in value.keys(): + return "-" + else: + value = value.get(key, {}) + + if value != 0: + return value + else: + return "-" + + +def dict2xlsx(input: json): + red = "FF0000" + black = "000000" + green = "E2EFDA" + yellow = "FFF2CC" + gray = "D0CECE" + font_black = Font(name="Calibri", size=11, color=black) + font_black_bold = Font(name="Calibri", size=11, color=black, bold=True) + font_red = Font(name="Calibri", size=11, color=red) + thin = Side(border_style="thin", color=black) + border = Border(left=thin, right=thin, top=thin, bottom=thin) + fill_green = PatternFill(start_color=green, end_color=green, fill_type = "solid") + fill_yellow = PatternFill(start_color=yellow, end_color=yellow, fill_type = "solid") + fill_gray = PatternFill(start_color=gray, end_color=gray, fill_type = "solid") + normal_cell = NamedStyle(name="normal_cell", font=font_black, border=border) + normal_cell_red = NamedStyle(name="normal_cell_red", font=font_red, border=border) + + wb = load_workbook(filename = 'report.xlsx') + ws = wb['Sheet1'] + + mapping = { + 'A': 'subs', + 'B': 'extraction_date', + 'C': 'num_imei', + 'D': 'num_invoice', + 'E': 'total_images', + 'F': 'images_quality.successful', + 'G': 'images_quality.successful_percent', + 'H': 'images_quality.bad', + 'I': 'images_quality.bad_percent', + 'J': 'average_accuracy_rate.imei', + 'K': 'average_accuracy_rate.purchase_date', + 'L': 'average_accuracy_rate.retailer_name', + 'M': 'average_processing_time.imei', + 'N': 'average_processing_time.invoice', + 'O': 'usage.imei', + 'P': 'usage.invoice', + } + + start_index = 5 + + for subtotal in input: + ws['A' + str(start_index)] = subtotal['subs'] + ws['A' + str(start_index)].font = font_black + ws['A' + str(start_index)].border = border + ws['A' + str(start_index)].fill = fill_gray + + ws['B' + str(start_index)] = subtotal['extraction_date'] + ws['B' + str(start_index)].font = font_black_bold + ws['B' + str(start_index)].border = border + ws['B' + str(start_index)].fill = fill_green + + ws['C' + str(start_index)].border = border + ws['D' + str(start_index)].border = border + + for key in ['E', 'F', 'G', 'H', 'I']: + ws[key + str(start_index)] = get_value(subtotal, mapping[key]) + ws[key + str(start_index)].font = font_black + ws[key + str(start_index)].border = border + ws[key + str(start_index)].fill = fill_yellow + + for key in ['J', 'K', 'L', 'M', 'N']: + ws[key + str(start_index)] = get_value(subtotal, mapping[key]) + ws[key + str(start_index)].font = font_black + ws[key + str(start_index)].border = border + ws[key + str(start_index)].fill = fill_gray + + start_index += 1 + + for record in subtotal['data']: + for key in mapping.keys(): + value = get_value(record, mapping[key]) + ws[key + str(start_index)] = value + print(type(value)) + if 'average_accuracy_rate' in mapping[key] and type(value) in [int, float] and value < 95: + ws[key + str(start_index)].style = normal_cell_red + elif 'average_processing_time' in mapping[key] and type(value) in [int, float] and value > 2.0: + ws[key + str(start_index)].style = normal_cell_red + elif 'bad_percent' in mapping[key] and type(value) in [int, float] and value > 10: + ws[key + str(start_index)].style = normal_cell_red + else : + ws[key + str(start_index)].style = normal_cell + start_index += 1 + + return wb diff --git a/cope2n-api/report.xlsx b/cope2n-api/report.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..fc5b37d989c90238850317ab48fca2472ee7f76f GIT binary patch literal 6546 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 H+^+rysSZ9~ literal 0 HcmV?d00001