Files
njts-accounting-core/identify_all_duplicates.py
2026-02-20 15:47:27 +09:00

143 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import psycopg2
conn = psycopg2.connect(
host="192.168.0.61",
port=55432,
database="njts_acct",
user="njts_app",
password="njts_app2025"
)
cur = conn.cursor()
print("=" * 140)
print("【识别可能的6月→7月/8月复制数据】")
print("=" * 140)
# 第1步找出6月所有有的仕訳描述+金额的组合)
print("\n第1步提取6月的所有仕訳描述和金额作为KEY")
cur.execute("""
SELECT DISTINCT
je.description,
COALESCE(SUM(jl.debit), 0)::BIGINT as total_debit,
COALESCE(SUM(jl.credit), 0)::BIGINT as total_credit
FROM journal_entries je
LEFT JOIN journal_lines jl ON je.journal_entry_id = jl.journal_entry_id
WHERE je.is_deleted = false
AND je.is_latest = true
AND EXTRACT(YEAR FROM je.entry_date) = 2025
AND EXTRACT(MONTH FROM je.entry_date) = 6
GROUP BY je.journal_entry_id, je.description
ORDER BY je.description
""")
june_patterns = cur.fetchall()
print(f"找到 {len(june_patterns)} 个6月的仕訳模式")
# 第2步在7月和8月中查找相同的仕訳
print("\n第2步在7月和8月中查找相同描述和金额的仕訳")
duplicates_for_deletion = []
for description, debit, credit in june_patterns:
cur.execute("""
SELECT
je.journal_entry_id,
TO_CHAR(je.entry_date, 'YYYY-MM-DD') as entry_date,
EXTRACT(MONTH FROM je.entry_date)::INT as month,
COALESCE(SUM(jl.debit), 0)::BIGINT as calc_debit,
COALESCE(SUM(jl.credit), 0)::BIGINT as calc_credit
FROM journal_entries je
LEFT JOIN journal_lines jl ON je.journal_entry_id = jl.journal_entry_id
WHERE je.is_deleted = false
AND je.is_latest = true
AND EXTRACT(YEAR FROM je.entry_date) = 2025
AND EXTRACT(MONTH FROM je.entry_date) IN (7, 8)
AND je.description = %s
GROUP BY je.journal_entry_id, je.entry_date
HAVING COALESCE(SUM(jl.debit), 0) = %s
AND COALESCE(SUM(jl.credit), 0) = %s
""", (description, debit, credit))
matches = cur.fetchall()
if matches:
for entry_id, entry_date, month, calc_debit, calc_credit in matches:
duplicates_for_deletion.append({
'entry_id': entry_id,
'date': entry_date,
'month': month,
'description': description,
'debit': debit,
'credit': credit
})
# 按月份排序
duplicates_for_deletion.sort(key=lambda x: (x['month'], x['entry_id']))
print(f"\n找到 {len(duplicates_for_deletion)} 个可能的复制记录7月/8月中与6月相同的")
if duplicates_for_deletion:
print("\n【可能的复制记录列表】\n")
current_month = None
for dup in duplicates_for_deletion:
if dup['month'] != current_month:
print(f"\n--- {dup['month']}月 ---")
current_month = dup['month']
print(f"ID={dup['entry_id']:3d} | {dup['date']} | 借={dup['debit']:>12,} 貸={dup['credit']:>12,}")
print(f" └─ {dup['description'][:80]}")
print("\n" + "=" * 140)
print(f"【预期删除】{len(duplicates_for_deletion)} 条记录")
print("=" * 140)
# 计算删除前后的普通預金期末残高变化
cur.execute("""
SELECT
COALESCE(SUM(COALESCE(jl.debit, 0) - COALESCE(jl.credit, 0)), 0) as balance
FROM journal_lines jl
INNER JOIN journal_entries je ON jl.journal_entry_id = je.journal_entry_id
WHERE jl.account_id = 2 -- 普通預金
AND je.is_deleted = false
AND je.is_latest = true
""")
current_balance = cur.fetchone()[0]
print(f"\n删除前普通預金期末残高: {current_balance:>15,.0f}")
# 计算这些重复记录对普通預金的影响
deletion_impact = 0
for dup in duplicates_for_deletion:
cur.execute("""
SELECT COALESCE(SUM(COALESCE(jl.debit, 0) - COALESCE(jl.credit, 0)), 0)
FROM journal_lines jl
WHERE jl.journal_entry_id = %s
AND jl.account_id = 2 -- 普通預金
""", (dup['entry_id'],))
impact = cur.fetchone()[0]
deletion_impact += impact
expected_balance_after = current_balance - deletion_impact
print(f"这些记录对普通預金的总影响: {deletion_impact:>15,.0f}")
print(f"删除后预期普通預金期末残高: {expected_balance_after:>15,.0f}")
print(f"\n期望目标值: 14,916,322円")
print(f"删除后vs目标值差距: {14_916_322 - expected_balance_after:>15,.0f}")
cur.close()
conn.close()
# 保存删除列表到Python变量以供后续使用
print("\n" + "=" * 140)
print(f"识别完成。找到 {len(duplicates_for_deletion)} 条可能的复制记录")
print("=" * 140)
# 返回delete_list供后续使用
import json
print("\n【识别的删除对象IDs】")
delete_ids = [dup['entry_id'] for dup in duplicates_for_deletion]
print(delete_ids)