修复求和数据统计的问题
This commit is contained in:
@@ -340,10 +340,14 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
||||
report_date = start_time.strftime('%Y-%m-%d')
|
||||
delete_old_history(config_id, report_date, config['split_type'], config['split_value'])
|
||||
|
||||
# 构建查询SQL - 过滤掉虚拟字段(时段电量等)
|
||||
# 构建查询SQL - 过滤掉虚拟字段(时段电量、自定义服务费、实收金额等)
|
||||
# 虚拟字段不是数据库表中的实际字段,需要动态计算
|
||||
TIME_PERIOD_FIELDS = {'sharp_electricity', 'peak_electricity', 'flat_electricity', 'valley_electricity'}
|
||||
db_fields = [f for f in selected_fields if f not in TIME_PERIOD_FIELDS]
|
||||
VIRTUAL_FIELDS = {'sharp_electricity', 'peak_electricity', 'flat_electricity', 'valley_electricity', 'custom_service_fee', 'total_amount'}
|
||||
db_fields = [f for f in selected_fields if f not in VIRTUAL_FIELDS]
|
||||
|
||||
# 如果选择了实收金额字段,需要确保查询 charge_elecfee_amount(电费金额)
|
||||
if 'total_amount' in selected_fields and 'charge_elecfee_amount' not in db_fields:
|
||||
db_fields.append('charge_elecfee_amount')
|
||||
|
||||
# 确保至少有 order_no 字段用于关联分时数据
|
||||
if 'order_no' not in db_fields:
|
||||
@@ -501,7 +505,10 @@ def generate_daily_report(config_id, start_time=None, end_time=None):
|
||||
split_type=config.get('split_type'),
|
||||
split_value=config.get('split_value'),
|
||||
custom_service_fee_price=config.get('custom_service_fee_price'),
|
||||
custom_service_fee_name=config.get('custom_service_fee_name')
|
||||
custom_service_fee_name=config.get('custom_service_fee_name'),
|
||||
show_custom_service_fee=config.get('show_custom_service_fee', 0) == 1,
|
||||
show_total_amount=config.get('show_total_amount', 0) == 1,
|
||||
total_amount_name=config.get('total_amount_name')
|
||||
)
|
||||
|
||||
log_info(f"[日报生成] Excel文件已生成: {file_path}", 'report')
|
||||
@@ -591,7 +598,8 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
id_name_maps=None, field_custom_names=None, has_supplement=False,
|
||||
show_monthly_total=False, config_id=None, report_date=None, sort_order=None,
|
||||
split_type=None, split_value=None,
|
||||
custom_service_fee_price=None, custom_service_fee_name=None):
|
||||
custom_service_fee_price=None, custom_service_fee_name=None,
|
||||
show_custom_service_fee=False, show_total_amount=False, total_amount_name=None):
|
||||
"""
|
||||
生成Excel文件
|
||||
|
||||
@@ -711,35 +719,36 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
cell.alignment = header_alignment
|
||||
cell.border = thin_border
|
||||
|
||||
has_custom_service_fee = custom_service_fee_price is not None and custom_service_fee_price != ''
|
||||
|
||||
for col_idx, field in enumerate(selected_fields, 2):
|
||||
cell = ws.cell(row=header_row, column=col_idx)
|
||||
if field in field_custom_names and field_custom_names[field]:
|
||||
|
||||
if field == 'custom_service_fee':
|
||||
if custom_service_fee_name and str(custom_service_fee_name).strip():
|
||||
display_name = str(custom_service_fee_name).strip()
|
||||
elif has_custom_service_fee:
|
||||
display_name = f'自定义服务费({custom_service_fee_price}元/kWh)'
|
||||
else:
|
||||
display_name = '自定义服务费'
|
||||
elif field == 'total_amount':
|
||||
if total_amount_name and str(total_amount_name).strip():
|
||||
display_name = str(total_amount_name).strip()
|
||||
else:
|
||||
display_name = '实收金额'
|
||||
elif field in field_custom_names and field_custom_names[field]:
|
||||
display_name = field_custom_names[field]
|
||||
elif field in id_name_maps and id_name_maps[field]:
|
||||
display_name = get_field_display_name(field).replace('ID', '')
|
||||
else:
|
||||
display_name = get_field_display_name(field)
|
||||
|
||||
cell.value = display_name
|
||||
cell.font = header_font
|
||||
cell.fill = header_fill
|
||||
cell.alignment = header_alignment
|
||||
cell.border = thin_border
|
||||
|
||||
# 自定义服务费列表头(如果设置了单价)
|
||||
has_custom_service_fee = custom_service_fee_price is not None and custom_service_fee_price != ''
|
||||
if has_custom_service_fee:
|
||||
custom_fee_col = len(selected_fields) + 2
|
||||
cell = ws.cell(row=header_row, column=custom_fee_col)
|
||||
if custom_service_fee_name and str(custom_service_fee_name).strip():
|
||||
header_name = str(custom_service_fee_name).strip()
|
||||
else:
|
||||
header_name = f'自定义服务费({custom_service_fee_price}元/kWh)'
|
||||
cell.value = header_name
|
||||
cell.font = header_font
|
||||
cell.fill = header_fill
|
||||
cell.alignment = header_alignment
|
||||
cell.border = thin_border
|
||||
|
||||
ws.row_dimensions[header_row].height = 25
|
||||
|
||||
# 写入数据
|
||||
@@ -758,29 +767,44 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
|
||||
for col_idx, field in enumerate(selected_fields, 2):
|
||||
cell = ws.cell(row=row_idx, column=col_idx)
|
||||
value = order.get(field, '')
|
||||
|
||||
# 格式化时间字段
|
||||
if field in ['report_time', 'start_time', 'end_time', 'create_time', 'update_time', 'pay_time']:
|
||||
if isinstance(value, datetime):
|
||||
value = value.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# 将ID转换为名称
|
||||
if field in id_name_maps and value is not None and value != '':
|
||||
name_map = id_name_maps[field]
|
||||
name_value = name_map.get(str(value))
|
||||
if name_value:
|
||||
value = name_value
|
||||
if field == 'custom_service_fee':
|
||||
if has_custom_service_fee:
|
||||
charge_degree = float(order.get('charge_degree', 0) or 0)
|
||||
value = round(charge_degree * float(custom_service_fee_price), 2)
|
||||
else:
|
||||
value = ''
|
||||
elif field == 'total_amount':
|
||||
actual_money = float(order.get('charge_elecfee_amount', 0) or 0)
|
||||
if has_custom_service_fee:
|
||||
charge_degree = float(order.get('charge_degree', 0) or 0)
|
||||
custom_fee = round(charge_degree * float(custom_service_fee_price), 2)
|
||||
value = round(actual_money + custom_fee, 2)
|
||||
else:
|
||||
value = round(actual_money, 2)
|
||||
else:
|
||||
value = order.get(field, '')
|
||||
|
||||
# 格式化时间字段
|
||||
if field in ['report_time', 'start_time', 'end_time', 'create_time', 'update_time', 'pay_time']:
|
||||
if isinstance(value, datetime):
|
||||
value = value.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# 将ID转换为名称
|
||||
if field in id_name_maps and value is not None and value != '':
|
||||
name_map = id_name_maps[field]
|
||||
name_value = name_map.get(str(value))
|
||||
if name_value:
|
||||
value = name_value
|
||||
|
||||
cell.value = value
|
||||
cell.border = thin_border
|
||||
|
||||
# 数字字段靠右对齐,其他居中或靠左
|
||||
if field in numeric_fields:
|
||||
if field in numeric_fields or field in ['custom_service_fee', 'total_amount']:
|
||||
cell.alignment = Alignment(horizontal='right', vertical='center')
|
||||
if isinstance(value, (int, float)):
|
||||
if field in decimal3_fields:
|
||||
cell.number_format = '0.000'
|
||||
cell.number_format = '0.00'
|
||||
elif field in ['order_no', 'vehicle_no', 'gun_no', 'connector_no']:
|
||||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||||
else:
|
||||
@@ -790,19 +814,6 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
if is_even:
|
||||
cell.fill = even_row_fill
|
||||
|
||||
# 自定义服务费列(如果设置了单价)
|
||||
if has_custom_service_fee:
|
||||
custom_fee_col = len(selected_fields) + 2
|
||||
cell = ws.cell(row=row_idx, column=custom_fee_col)
|
||||
charge_degree = float(order.get('charge_degree', 0) or 0)
|
||||
custom_fee = round(charge_degree * float(custom_service_fee_price), 2)
|
||||
cell.value = custom_fee
|
||||
cell.border = thin_border
|
||||
cell.alignment = Alignment(horizontal='right', vertical='center')
|
||||
cell.number_format = '0.00'
|
||||
if is_even:
|
||||
cell.fill = even_row_fill
|
||||
|
||||
ws.row_dimensions[row_idx].height = 22
|
||||
|
||||
# 写入求和行
|
||||
@@ -819,25 +830,33 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
cell = ws.cell(row=sum_row, column=col_idx)
|
||||
cell.fill = sum_fill
|
||||
cell.border = thin_border
|
||||
if field in sum_fields and field in sum_results:
|
||||
|
||||
if field == 'custom_service_fee':
|
||||
if has_custom_service_fee:
|
||||
total_charge_degree = sum_results.get('charge_degree', 0)
|
||||
value = round(float(total_charge_degree) * float(custom_service_fee_price), 2)
|
||||
cell.value = value
|
||||
cell.font = sum_font
|
||||
cell.alignment = Alignment(horizontal='right', vertical='center')
|
||||
cell.number_format = '0.00'
|
||||
elif field == 'total_amount':
|
||||
total_actual_money = sum_results.get('charge_elecfee_amount', 0)
|
||||
if has_custom_service_fee:
|
||||
total_charge_degree = sum_results.get('charge_degree', 0)
|
||||
total_custom_fee = round(float(total_charge_degree) * float(custom_service_fee_price), 2)
|
||||
value = round(float(total_actual_money) + total_custom_fee, 2)
|
||||
else:
|
||||
value = round(float(total_actual_money), 2)
|
||||
cell.value = value
|
||||
cell.font = sum_font
|
||||
cell.alignment = Alignment(horizontal='right', vertical='center')
|
||||
cell.number_format = '0.00'
|
||||
elif field in sum_fields and field in sum_results:
|
||||
cell.value = sum_results[field]
|
||||
cell.font = sum_font
|
||||
cell.alignment = Alignment(horizontal='right', vertical='center')
|
||||
cell.number_format = '0.000'
|
||||
|
||||
# 自定义服务费合计
|
||||
if has_custom_service_fee:
|
||||
custom_fee_col = len(selected_fields) + 2
|
||||
cell = ws.cell(row=sum_row, column=custom_fee_col)
|
||||
cell.fill = sum_fill
|
||||
cell.border = thin_border
|
||||
total_charge_degree = sum_results.get('charge_degree', 0)
|
||||
total_custom_fee = round(float(total_charge_degree) * float(custom_service_fee_price), 2)
|
||||
cell.value = total_custom_fee
|
||||
cell.font = sum_font
|
||||
cell.alignment = Alignment(horizontal='right', vertical='center')
|
||||
cell.number_format = '0.00'
|
||||
|
||||
ws.row_dimensions[sum_row].height = 25
|
||||
|
||||
# 写入当月充电量累计总计行(从求和采集表查询,对账后数据)
|
||||
@@ -881,8 +900,6 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
|
||||
# 总列数
|
||||
total_cols = len(selected_fields) + 2
|
||||
if has_custom_service_fee:
|
||||
total_cols += 1
|
||||
|
||||
# 标题文字
|
||||
title_text = f'当月累计充电量(共{total_days}天,截止{report_date})'
|
||||
@@ -935,10 +952,15 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
log_error(f"[日报生成] 写入月度总计时出错: {e}", 'report')
|
||||
|
||||
# 调整列宽(中文按2个字符宽度计算)
|
||||
# 序号列固定宽度
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
# 序号列固定宽度
|
||||
ws.column_dimensions['A'].width = 8
|
||||
|
||||
# 计算所有字段的宽度
|
||||
col_widths = {}
|
||||
numeric_cols = []
|
||||
|
||||
for col_idx, field in enumerate(selected_fields, 2):
|
||||
header_name = get_field_display_name(field)
|
||||
if field in field_custom_names and field_custom_names[field]:
|
||||
@@ -955,21 +977,25 @@ def generate_excel(orders, selected_fields, sum_fields, sum_results,
|
||||
cell_len = len(cell_str) + cn_count
|
||||
max_length = max(max_length, cell_len)
|
||||
|
||||
from openpyxl.utils import get_column_letter
|
||||
col_letter = get_column_letter(col_idx)
|
||||
ws.column_dimensions[col_letter].width = min(max_length + 2, 50)
|
||||
col_widths[col_idx] = min(max_length + 2, 50)
|
||||
|
||||
# 标记数值类型字段(求和类列)
|
||||
if field in numeric_fields or field in ['custom_service_fee', 'total_amount']:
|
||||
numeric_cols.append(col_idx)
|
||||
|
||||
# 自定义服务费列宽度
|
||||
if has_custom_service_fee:
|
||||
custom_fee_col = len(selected_fields) + 2
|
||||
if custom_service_fee_name and str(custom_service_fee_name).strip():
|
||||
header_name = str(custom_service_fee_name).strip()
|
||||
else:
|
||||
header_name = f'自定义服务费({custom_service_fee_price}元/kWh)'
|
||||
cn_count = sum(1 for c in str(header_name) if '\u4e00' <= c <= '\u9fff')
|
||||
max_length = len(str(header_name)) + cn_count
|
||||
col_letter = get_column_letter(custom_fee_col)
|
||||
ws.column_dimensions[col_letter].width = min(max_length + 2, 50)
|
||||
# 计算数值类型列的最大宽度,使所有求和类列宽度一致
|
||||
if numeric_cols:
|
||||
max_numeric_width = max(col_widths[col] for col in numeric_cols)
|
||||
for col_idx in numeric_cols:
|
||||
col_letter = get_column_letter(col_idx)
|
||||
ws.column_dimensions[col_letter].width = max_numeric_width
|
||||
|
||||
# 设置非数值类型列的宽度
|
||||
for col_idx, width in col_widths.items():
|
||||
if col_idx not in numeric_cols:
|
||||
col_letter = get_column_letter(col_idx)
|
||||
ws.column_dimensions[col_letter].width = width
|
||||
|
||||
# 冻结首行
|
||||
ws.freeze_panes = 'A2'
|
||||
|
||||
Reference in New Issue
Block a user