Compare commits

3 Commits

View File

@ -8,7 +8,6 @@ from datetime import datetime
import traceback
from openpyxl.utils import get_column_letter
# ==========================================
# 第一部分:业务逻辑核心
# ==========================================
@ -129,16 +128,31 @@ class DataProcessor:
except:
return str(val)
# [修改] 优化后的日期处理逻辑过滤0000-00-00无效日期留空
def format_date_str(self, val):
if pd.isna(val) or str(val).strip() == "": return ""
if pd.isna(val): return ""
s_val = str(val).strip()
# 1. 显式过滤无效的 0 值或 0000 开头的日期
if s_val == "" or s_val == "0" or s_val.startswith("0000"):
return ""
try:
s_val = str(val).strip()
if len(s_val) == 10 and s_val[4] == '-' and s_val[7] == '-': return s_val
# 2. 如果已经是标准格式 YYYY-MM-DD直接返回避免解析开销
if len(s_val) == 10 and s_val[4] == '-' and s_val[7] == '-':
return s_val
# 3. 尝试解析日期
dt = pd.to_datetime(val, errors='coerce')
if pd.isnull(dt): return s_val
# 4. 如果解析结果是 NaT (Not a Time),说明不是有效日期,返回空
if pd.isnull(dt):
return ""
return dt.strftime('%Y-%m-%d')
except:
return str(val)
# 5. 发生任何异常都返回空,保证不填入垃圾数据
return ""
def load_multiple_csvs(self, file_paths):
if isinstance(file_paths, str):
@ -375,11 +389,11 @@ class DataProcessor:
result['外购'] = df_unique['外购产品金额'].apply(self.format_money_str)
result['收款日期'] = df_unique['最新收款日期'].apply(self.format_date_str)
# [说明] 此处调用更新后的 format_date_str会自动处理空值和0000-00-00
if '最晚发货期' in target_cols: result['最晚发货期'] = df_unique['最晚发货期'].apply(self.format_date_str)
if '付款方式' in target_cols: result['付款方式'] = df_unique['付款比例及期限']
if '发货日期' in target_cols: result['发货日期'] = ""
# [修改] 汇率原样读取
if '合同币种/美元' in target_cols:
result['合同币种/美元'] = df_unique['合同币种/美元'].fillna("").astype(str)
@ -494,12 +508,8 @@ class DataProcessor:
if '报价RMB总价' in new_row: new_row['报价RMB总价'] = self.format_money_str(row.get('产品小计', ''))
if '报价总价' in new_row: new_row['报价总价'] = self.format_money_str(row.get('产品小计', ''))
# [修改] 汇率原样读取,不做处理
rate_val = str(row.get('汇率', '')).strip()
if rate_val.lower() == 'nan': rate_val = ""
if '计算汇率' in new_row: new_row['计算汇率'] = rate_val
if '合同币种/美元' in new_row: new_row['合同币种/美元'] = rate_val
if '计算汇率' in new_row: new_row['计算汇率'] = ""
if '合同币种/美元' in new_row: new_row['合同币种/美元'] = ""
discount_col = '折扣率' if '折扣率' in new_row else '折扣率(%)'
if discount_col in new_row: new_row[discount_col] = self.format_percent_str(row.get('折扣率', ''))
@ -589,10 +599,15 @@ class DataProcessor:
col_gen = '厂家'
col_det = '厂家.1' if '厂家.1' in csv_df.columns else '厂家'
# [修改] 定义判断 ASD 的正则模式:包含 ASD 或 SciAps
asd_pattern = r'ASD|SciAps'
if is_asd:
df_subset = csv_df[csv_df[col_gen].str.contains('ASD', case=False, na=False)]
# 筛选 ASD 表:厂家包含 ASD 或 SciAps
df_subset = csv_df[csv_df[col_gen].str.contains(asd_pattern, case=False, na=False, regex=True)]
else:
df_subset = csv_df[~csv_df[col_gen].str.contains('ASD', case=False, na=False)]
# 筛选 NonASD 表:厂家不包含 ASD 且不包含 SciAps
df_subset = csv_df[~csv_df[col_gen].str.contains(asd_pattern, case=False, na=False, regex=True)]
csv_foreign = df_subset[df_subset['合同类型'] == '外贸'].copy()
csv_domestic = df_subset[df_subset['合同类型'] == '内贸'].copy()
@ -626,7 +641,7 @@ class DataProcessor:
old_df[col] = old_df[col].astype(object)
is_unique_index = (old_df[unique_col].duplicated().sum() == 0) and (
new_df[unique_col].duplicated().sum() == 0)
new_df[unique_col].duplicated().sum() == 0)
if is_unique_index:
old_df.set_index(unique_col, inplace=True, drop=False)
@ -715,7 +730,7 @@ class DataProcessor:
class ContractApp:
def __init__(self, root):
self.root = root
self.root.title("合同数据处理系统 V4.9 (排序优化&汇率原样版)")
self.root.title("合同数据处理系统 V5.2 (含SciAps分类优化)")
self.root.geometry("1300x850")
self.root.minsize(1000, 700)
@ -1147,7 +1162,7 @@ class ContractApp:
if self.status_var.get() != "已取消写入":
self.status_var.set("准备就绪")
#
if __name__ == "__main__":
root = tk.Tk()
try: