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

145 lines
5.3 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("=" * 160)
print("【方法3在7月/8月中同一月份有多个相同描述和金额的仕訳】")
print("=" * 160)
print("\n这种情况通常表示错误的重复输入应该保留1条删除其余\n")
# 找出在7月/8月中同一月份有多个相同描述和金额的仕訳
cur.execute("""
WITH july_august_with_counts AS (
SELECT
je.journal_entry_id,
je.entry_date,
EXTRACT(MONTH FROM je.entry_date)::INT as month,
je.description,
COALESCE(SUM(jl.debit), 0)::BIGINT as total_debit,
COALESCE(SUM(jl.credit), 0)::BIGINT as total_credit,
ROW_NUMBER() OVER (PARTITION BY EXTRACT(MONTH FROM je.entry_date), je.description,
COALESCE(SUM(jl.debit), 0), COALESCE(SUM(jl.credit), 0)
ORDER BY je.journal_entry_id) as rn,
COUNT(*) OVER (PARTITION BY EXTRACT(MONTH FROM je.entry_date), je.description,
COALESCE(SUM(jl.debit), 0), COALESCE(SUM(jl.credit), 0)) as cnt
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)
GROUP BY je.journal_entry_id, je.entry_date, je.description
)
SELECT
month,
description,
total_debit,
total_credit,
cnt,
STRING_AGG(journal_entry_id::TEXT || '(' || TO_CHAR(entry_date, 'MM-DD') || ')',
', ' ORDER BY journal_entry_id) as ids
FROM july_august_with_counts
WHERE cnt > 1
GROUP BY month, description, total_debit, total_credit, cnt
ORDER BY cnt DESC, month, description
""")
duplicates_in_month = cur.fetchall()
print(f"找到 {len(duplicates_in_month)} 个在同一月份有重复的仕訳模式\n")
duplicates_for_deletion = []
for month, description, debit, credit, cnt, ids in duplicates_in_month:
print(f"{cnt}重複!】{month}月 | 借={debit:>12,} 貸={credit:>12,}")
print(f" 説明: {description}")
print(f" IDs: {ids}")
print()
# 对于每个重复的模式,删除除了第一个外的其他记录
cur.execute("""
WITH duplicates AS (
SELECT
je.journal_entry_id,
ROW_NUMBER() OVER (PARTITION BY EXTRACT(MONTH FROM je.entry_date), je.description,
COALESCE(SUM(jl.debit), 0), COALESCE(SUM(jl.credit), 0)
ORDER BY je.journal_entry_id) as rn
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) = %s
AND je.description = %s
GROUP BY je.journal_entry_id, je.entry_date, je.description
)
SELECT journal_entry_id FROM duplicates WHERE rn > 1
ORDER BY journal_entry_id
""", (month, description))
to_delete = cur.fetchall()
for (entry_id,) in to_delete:
duplicates_for_deletion.append(entry_id)
print(f" ├─ 删除: ID={entry_id}")
print("\n" + "=" * 160)
print(f"【汇总】共 {len(duplicates_for_deletion)} 条重复记录需要删除")
print("=" * 160)
if duplicates_for_deletion:
print(f"\n要删除的IDs: {duplicates_for_deletion}")
# 计算删除影响
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 entry_id 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
""", (entry_id,))
impact = cur.fetchone()[0]
deletion_impact += impact
expected_after = current_balance - deletion_impact
print(f"普通預金的总变化: -{deletion_impact:>15,.0f}")
print(f"删除后普通預金期末残高: {expected_after:>15,.0f}")
print(f"\n期望目标值: 14,916,322円")
if expected_after == 14_916_322:
print(f"✓ 完美匹配!")
else:
diff = 14_916_322 - expected_after
if diff > 0:
print(f"∆ 删除后仍低于目标: {diff:>15,.0f}")
else:
print(f"∆ 删除后高于目标: {-diff:>15,.0f}")
else:
print("\n没有找到单月内的重复记录")
cur.close()
conn.close()