Sfoglia il codice sorgente

综合财务报表:增加续约合同查询,解决月份匹配的bug

Ping 1 anno fa
parent
commit
a75658d689
2 ha cambiato i file con 51 aggiunte e 10 eliminazioni
  1. 20 10
      etl_bill_detail.py
  2. 31 0
      utils.py

+ 20 - 10
etl_bill_detail.py

@@ -12,11 +12,12 @@ import json
 from dateutil.relativedelta import relativedelta
 import calendar
 from urllib.parse import quote_plus
-from utils import load_config, truncate_target_db
+from utils import load_config, truncate_target_db, find_renewal_contract
 
 debug = False
 if debug:
-    debug_condition = "and bd.biz_id='1687400201327599617'"  # P.53
+    # debug_condition = "and bd.biz_id='1687400201327599617'"  # P.53
+    debug_condition = "and bd.biz_id='1731870365341253635'"  # 调试押金权责
     # debug_condition = ''
 else:
     debug_condition = ''
@@ -89,11 +90,12 @@ def extract(conn, batch_size, i) -> pd.DataFrame:
             bd.bill_id, bd.id as 'bill_detail_id', bd.fee_subject_id, sd.label as 'fee_subject_label', sd.name as 'fee_subject_name', 
             rc.`type` 'contract_type',
             0 'splitter',
+            rc.quite_date,
             bd.fee_direction, bd.original_money, bd.occurred_money,
             bd.begin_time, bd.end_time, bd.is_occur, rc.cancel_info, bd.predict_time
         from yuxin_finance.fin_finance_bill_detail bd
         left join yuxin_setting.setting_dictionary sd on sd.id=bd.fee_subject_id
-        left join yuxin_contract.cont_renter_contract rc on rc.id=bd.biz_id
+        left join yuxin_contract.cont_renter_contract rc on rc.id=bd.biz_id and rc.is_delete=0
         left join yuxin_house.hse_house_room hhr on hhr.is_delete=0 and hhr.id=rc.house_id
         left join yuxin_house.hse_house_base hhb on hhb.is_delete=0 and hhb.id=rc.house_id
         left join yuxin_setting.setting_department house_sd on house_sd.id=hhb.dept_id and house_sd.is_delete=0
@@ -109,7 +111,7 @@ def extract(conn, batch_size, i) -> pd.DataFrame:
     return source_data
 
 
-def transform(data) -> pd.DataFrame:
+def transform(conn, data) -> pd.DataFrame:
     """ Transforms the dataset into desired structure and filters
         --- 维度:租户,合同,房源,维护人,所属部门,日,财务科目分类,财务科目,应收,应付,实收,实付
         --- 指标:金额(尾差保留在最后一日中)
@@ -131,9 +133,17 @@ def transform(data) -> pd.DataFrame:
 
     # Iterate over each row in the DataFrame
     for index, row in data.iterrows():
-        
+        # 查找续租合同
+        renewed_end_time = find_renewal_contract(conn, row['contract_id'])
+
         begin_date = row['begin_time']
-        end_date = row['end_time']
+        if renewed_end_time is None:
+            end_date = row['quite_date'] if row['quite_date'] is not None and not pd.isnull(
+                row['quite_date']) else row['end_time']
+        else:
+            end_date = renewed_end_time
+
+        # end_date = renewed_end_time
         # Calculate the number of days between the two dates
         num_days = (end_date - begin_date).days + 1
         num_months = (end_date.year - begin_date.year) * 12 + (end_date.month - begin_date.month) + 1
@@ -180,9 +190,9 @@ def transform(data) -> pd.DataFrame:
         while current_month <= end_date:
             first_day = 1
             last_day = calendar.monthrange(current_month.year, current_month.month)[1]
-            if current_month.month == begin_date.month:
+            if current_month.month == begin_date.month and current_month.year == begin_date.year:
                 first_day = begin_date.day
-            if current_month.month == end_date.month:
+            if current_month.month == end_date.month and current_month.year == end_date.year:
                 last_day = end_date.day
             num_days_month = last_day - first_day + 1
             # print('current_month', current_month, first_day, last_day, num_days_month)
@@ -191,7 +201,7 @@ def transform(data) -> pd.DataFrame:
             new_row['day'] = current_month.date()
             new_row['is_apportion'] = 1
             
-            if current_month.month == end_date.month:
+            if current_month.month == end_date.month and current_month.year == end_date.year:
                 # keep remainder in the last day
                 new_row['money'] = remainder
             else:
@@ -315,7 +325,7 @@ def etl():
         # Write the data to the table in batches
         for i in tqdm(range(0, total, batch_size)):
             data = extract(conn, batch_size, i)
-            data = transform(data)
+            data = transform(conn, data)
 
             if debug:
                 print(data.head())

+ 31 - 0
utils.py

@@ -24,3 +24,34 @@ def truncate_target_db(conn, target_db) -> None:
                 TRUNCATE TABLE {target_db}
             """.format(target_db=target_db)
         conn.execute(text(sql))
+
+
+def find_renewal_contract(conn, contract_id):
+    query = """
+        select crc1.id, crc1.begin_time, crc1.end_time, crc1.quite_date, 
+               crc2.id, crc2.begin_time, crc2.end_time, crc2.quite_date, 
+               crc3.id, crc3.begin_time, crc3.end_time, crc3.quite_date
+        from yuxin_contract.cont_renter_contract crc1
+        left join yuxin_contract.cont_renter_contract crc2 on crc2.contract_pid=crc1.id and crc2.is_delete=0 and crc2.contract_status<>4 and crc2.sign_type=2
+        left join yuxin_contract.cont_renter_contract crc3 on crc3.contract_pid=crc2.id and crc3.is_delete=0 and crc3.contract_status<>4 and crc3.sign_type=2
+        where crc1.is_delete=0 and crc1.contract_status<>4 and crc1.sign_type=2
+            and crc1.contract_pid='{contract_id}'
+        """.format(contract_id=contract_id)
+
+    result = conn.execute(text(query)).fetchone()
+    if result is None:
+        return None
+
+    if result[11] is not None:
+        return result[11]
+    elif result[10] is not None:
+        return result[10]
+    elif result[7] is not None:
+        return result[7]
+    elif result[6] is not None:
+        return result[6]
+    elif result[3] is not None:
+        return result[3]
+    elif result[2] is not None:
+        return result[2]
+    return None