Эх сурвалжийг харах

新增 價格檢查欄位增加 被檢驗預算書價格% 和 參考預算書價格 %

maa3606 1 долоо хоног өмнө
parent
commit
653f293e18
1 өөрчлөгдсөн 57 нэмэгдсэн , 13 устгасан
  1. 57 13
      BudgetX.py

+ 57 - 13
BudgetX.py

@@ -32,7 +32,7 @@ GRAND_TOTAL_NAME = "總價"
 
 # DataFrame Column Names
 COMP_COLS = ["參考預算書獨有項目 (-)", "共有項目 (∩)", "被檢驗預算書獨有項目 (+)"]
-PRICE_COLS = ["項目", "單位", "數量", "單價", "復價", "檢查"]
+PRICE_COLS = ["項目", "單位", "數量", "單價", "復價", "檢查", "被檢驗預算書價格 %", "參考預算書價格 %"]
 CODE_VERIFY_COLS = ["項目", "單位", "編碼", "章碼章名(1~5碼)檢查", "6碼請您比對", "7碼請您比對", "8碼請您比對", "9碼請您比對", "10碼比對"]
 
 # Hard-coded row and column positions for the demo.
@@ -123,7 +123,7 @@ def comp_items(pdf1_data, pdf2_data):
     # print(f"Comparison DF:\n{rtn}")
     return rtn
 
-def verify_prices(pdf2_data):
+def verify_prices(pdf1_data, pdf1_total_price, pdf2_data, pdf2_total_price):
     """
     Runs a variety of tests against the prices in the second budget PDF.
 
@@ -154,7 +154,9 @@ def verify_prices(pdf2_data):
                         PRICE_COLS[2]: "",
                         PRICE_COLS[3]: "",
                         PRICE_COLS[4]: "",
-                        PRICE_COLS[5]: f"有多個 總價 欄位!第一個找到的: {grand_total_name}"
+                        PRICE_COLS[5]: f"有多個 總價 欄位!第一個找到的: {grand_total_name}",
+                        PRICE_COLS[6]: "",
+                        PRICE_COLS[7]: "",
                     })
                     rtn = pd.concat([rtn, row], ignore_index=True)
                 else:
@@ -167,15 +169,30 @@ def verify_prices(pdf2_data):
                 running_total += total
                 check = "數量乘單價與復價的差異大於 1 !" if abs(amount*unit_price - total) > 1.0 else "OK"
 
+                # pdf2 的復價百分比
+                pdf2_percent = str(round(total / pdf2_total_price * 100, 2)) + "%"
+
+                # pdf1 的復價百分比
+                pdf1_match = pdf1_data[pdf1_data.iloc[:, ITEMS_COL] == item]
+                if not pdf1_match.empty:
+                    try:
+                        pdf1_total = float(pdf1_match.iloc[0, TOTAL_COL].replace(",", ""))
+                        pdf1_percent = str(round(pdf1_total / pdf1_total_price * 100, 2)) + "%"
+                    except Exception:
+                        pdf1_percent = ""
+                else:
+                    pdf1_percent = ""
+
                 row = pd.DataFrame({
-                    PRICE_COLS[0]: item,
-                    PRICE_COLS[1]: unit,
-                    PRICE_COLS[2]: [amount],
-                    PRICE_COLS[3]: [unit_price],
-                    PRICE_COLS[4]: [total],
-                    PRICE_COLS[5]: check
+                    PRICE_COLS[0]: [item],
+                    PRICE_COLS[1]: [unit],
+                    PRICE_COLS[2]: [round(amount, 2)],
+                    PRICE_COLS[3]: [round(unit_price, 2)],
+                    PRICE_COLS[4]: [round(total, 2)],
+                    PRICE_COLS[5]: [check],
+                    PRICE_COLS[6]: [pdf2_percent],
+                    PRICE_COLS[7]: [pdf1_percent],
                 })
-                # print(f"Appending new row:\n{row}")
                 rtn = pd.concat([rtn, row], ignore_index=True)
         except ValueError as v:
             # print(f"String to float Error: {v}.  Skipping non-value row:\n{pdf2_data.iloc[i]}")
@@ -189,7 +206,9 @@ def verify_prices(pdf2_data):
             PRICE_COLS[2]: "",
             PRICE_COLS[3]: "",
             PRICE_COLS[4]: "",
-            PRICE_COLS[5]: "預算書中沒有 總價!"
+            PRICE_COLS[5]: "預算書中沒有 總價!",
+            PRICE_COLS[6]: "",
+            PRICE_COLS[7]: "",
         })
     else:
         check = f"總價與所有復價加總大於 1 !復價加總:{running_total}" if abs(grand_total - running_total) > 1.0 else "OK"
@@ -199,13 +218,34 @@ def verify_prices(pdf2_data):
             PRICE_COLS[2]: "",
             PRICE_COLS[3]: "",
             PRICE_COLS[4]: [grand_total],
-            PRICE_COLS[5]: check
+            PRICE_COLS[5]: check,
+            PRICE_COLS[6]: "",
+            PRICE_COLS[7]: "",
         })
     rtn = pd.concat([rtn, row], ignore_index=True)
 
     # print(f"Verify Prices Result:\n{rtn}")
     return rtn
 
+def get_total_price(pdf_data):
+    grand_total = 0
+    for i in range(len(pdf_data)):
+        try:
+            item = pdf_data.iloc[i, ITEMS_COL]
+            amount_str = pdf_data.iloc[i, AMOUNT_COL]
+            unit_price_str = pdf_data.iloc[i, UNITPRICE_COL]
+            total_str = pdf_data.iloc[i, TOTAL_COL]
+
+            if GRAND_TOTAL_NAME in item and amount_str == "" and unit_price_str == "" and total_str != "":
+                grand_total = float(total_str.replace(",", ""))
+                break
+        except ValueError as v:
+            print(f"String to float Error: {v}.  Skipping non-value row:\n{pdf_data.iloc[i]}")
+            continue
+
+    print(f"Total Prices :\n{grand_total}")
+    return grand_total
+
 def read_code_file(chapter):
     """
     Attempts to find a read in the work code file of the given chapter.
@@ -383,13 +423,16 @@ def update_table(pdf1, pdf2):
     # This can be useful if we need to speed up processing by caching the data one day...
     # global pdf1_data, pdf2_data
     pdf1_data = None
+    pdf1_total_price = None
     pdf2_data = None
+    pdf2_total_price = None
 
     # Process first PDF
     if pdf1:
         result = process_pdf(pdf1.name)
         if isinstance(result, pd.DataFrame):
             pdf1_data = result
+            pdf1_total_price = get_total_price(pdf1_data)
         else:
             return None, None, None, MSG_PREFIX+f"參考預算書 PDF 處理錯誤: {result}"+MSG_POSTFIX
 
@@ -398,6 +441,7 @@ def update_table(pdf1, pdf2):
         result = process_pdf(pdf2.name)
         if isinstance(result, pd.DataFrame):
             pdf2_data = result
+            pdf2_total_price = get_total_price(pdf2_data)
         else:
             return None, None, None, MSG_PREFIX+f"被檢驗預算書 PDF 處理錯誤: {result}"+MSG_POSTFIX
     
@@ -411,7 +455,7 @@ def update_table(pdf1, pdf2):
             return None, None, None, MSG_PREFIX+f"預算書 比對 失敗!錯誤訊息:{comp}"+MSG_POSTFIX
 
         # 2. Verify prices
-        price = verify_prices(pdf2_data)
+        price = verify_prices(pdf1_data, pdf1_total_price, pdf2_data, pdf2_total_price)
         if not isinstance(price, pd.DataFrame):
             return comp, None, None, MSG_PREFIX + f"預算書 價格確認 失敗!錯誤訊息:{price}" + MSG_POSTFIX