自存表导出依赖 paymentSummary.receivedAmount,原先仅汇总 V1 biz_protocol_payment;现对 include_sample_payment_modes 路径补齐 合同额、已收、分期明细与退费,避免已缴/退款列为空。 Co-authored-by: Cursor <cursoragent@cursor.com>
219 lines
8.7 KiB
Python
219 lines
8.7 KiB
Python
"""协议列表可显式读取 V2 样本方案,其他费用摘要消费者保持原行为。"""
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
|
|
import pytest
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from app.models.base import Base
|
|
from app.models.models import (
|
|
BizProtocolPaymentSchedule,
|
|
BizProtocolPaymentTransfer,
|
|
BizProtocolRefundRecord,
|
|
BizProtocolSamplePayment,
|
|
)
|
|
from app.services.qc_work_order_fee_summary import build_protocol_payment_summaries
|
|
|
|
|
|
@pytest.mark.parametrize('modes,expected,label', [
|
|
(['dj'], 'dj', '趸交'),
|
|
(['fq', 'fq'], 'fq', '分期'),
|
|
(['fgd'], 'fgd', '分改趸'),
|
|
(['fq', 'dj'], 'djfq', '趸交+分期'),
|
|
(['fgd', 'fq'], 'fq+fgd', '分期+分改趸'),
|
|
])
|
|
def test_protocol_list_uses_active_tenant_v2_payment_modes(modes, expected, label):
|
|
engine = create_engine('sqlite:///:memory:')
|
|
Base.metadata.create_all(engine)
|
|
with sessionmaker(bind=engine)() as db:
|
|
for i, mode in enumerate(modes):
|
|
db.add(BizProtocolSamplePayment(id=str(i), collection_protocol_id='p1', sample_code=str(i), pay_mode=mode, tenant_no='tenant-a', del_flag=0))
|
|
db.add_all([
|
|
BizProtocolSamplePayment(id='deleted', collection_protocol_id='p1', sample_code='deleted', pay_mode='djfq', tenant_no='tenant-a', del_flag=1),
|
|
BizProtocolSamplePayment(id='foreign', collection_protocol_id='p1', sample_code='foreign', pay_mode='djfq', tenant_no='tenant-b', del_flag=0),
|
|
])
|
|
db.commit()
|
|
result = build_protocol_payment_summaries(db, ['p1'], 'tenant-a', include_sample_payment_modes=True)
|
|
assert result['p1']['payMode'] == expected
|
|
assert result['p1']['payModeLabel'] == label
|
|
assert build_protocol_payment_summaries(db, ['p1'], 'tenant-a') == {}
|
|
engine.dispose()
|
|
|
|
|
|
def test_protocol_list_fills_received_from_v2_sample_transfers():
|
|
engine = create_engine('sqlite:///:memory:')
|
|
Base.metadata.create_all(engine)
|
|
with sessionmaker(bind=engine)() as db:
|
|
db.add_all(
|
|
[
|
|
BizProtocolSamplePayment(
|
|
id='sp-dj',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S1',
|
|
pay_mode='dj',
|
|
contract_amount=Decimal('12800'),
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolSamplePayment(
|
|
id='sp-fq',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S2',
|
|
pay_mode='fq',
|
|
contract_amount=Decimal('22880'),
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentSchedule(
|
|
id='sch-dj-1',
|
|
sample_payment_id='sp-dj',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S1',
|
|
schedule_no=1,
|
|
due_amount=Decimal('12800'),
|
|
due_date='20260915',
|
|
schedule_status='cleared',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentSchedule(
|
|
id='sch-fq-1',
|
|
sample_payment_id='sp-fq',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S2',
|
|
schedule_no=1,
|
|
due_amount=Decimal('6480'),
|
|
due_date='20260915',
|
|
schedule_status='cleared',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentSchedule(
|
|
id='sch-fq-2',
|
|
sample_payment_id='sp-fq',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S2',
|
|
schedule_no=2,
|
|
due_amount=Decimal('16400'),
|
|
due_date='20261015',
|
|
schedule_status='open',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentTransfer(
|
|
id='tr-dj',
|
|
schedule_id='sch-dj-1',
|
|
sample_payment_id='sp-dj',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S1',
|
|
transfer_amount=Decimal('12800'),
|
|
transfer_time=datetime(2026, 9, 15, 12, 0, 0),
|
|
pay_status='yjf',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentTransfer(
|
|
id='tr-fq',
|
|
schedule_id='sch-fq-1',
|
|
sample_payment_id='sp-fq',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S2',
|
|
transfer_amount=Decimal('6480'),
|
|
transfer_time=datetime(2026, 9, 15, 11, 13, 1),
|
|
pay_status='yjf',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentTransfer(
|
|
id='tr-pending',
|
|
schedule_id='sch-fq-2',
|
|
sample_payment_id='sp-fq',
|
|
collection_protocol_id='p-v2',
|
|
sample_code='S2',
|
|
transfer_amount=None,
|
|
transfer_time=None,
|
|
pay_status='dfj',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
]
|
|
)
|
|
db.commit()
|
|
result = build_protocol_payment_summaries(
|
|
db, ['p-v2'], 'tenant-a', include_sample_payment_modes=True
|
|
)
|
|
summary = result['p-v2']
|
|
assert summary['payMode'] == 'djfq'
|
|
assert summary['contractAmount'] == 35680.0
|
|
assert summary['receivedAmount'] == 19280.0
|
|
assert summary['pendingAmount'] == 16400.0
|
|
details = summary['paymentDetails']
|
|
assert len(details) == 3
|
|
first = [d for d in details if d['installmentNo'] == 1]
|
|
assert sum(float(d['dueAmount'] or 0) for d in first) == 19280.0
|
|
assert sum(float(d['transferAmount'] or 0) for d in first) == 19280.0
|
|
# 未开启 include 时不补齐 V2 已收(质检费用摘要保持原语义)
|
|
plain = build_protocol_payment_summaries(db, ['p-v2'], 'tenant-a')
|
|
assert plain['p-v2'].get('receivedAmount') is None
|
|
assert plain['p-v2'].get('paymentDetails') == []
|
|
engine.dispose()
|
|
|
|
|
|
def test_protocol_list_fills_refund_amount_from_v2_refund_records():
|
|
engine = create_engine('sqlite:///:memory:')
|
|
Base.metadata.create_all(engine)
|
|
with sessionmaker(bind=engine)() as db:
|
|
db.add_all(
|
|
[
|
|
BizProtocolSamplePayment(
|
|
id='sp-void',
|
|
collection_protocol_id='p-void',
|
|
sample_code='S9',
|
|
pay_mode='dj',
|
|
contract_amount=Decimal('5000'),
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentSchedule(
|
|
id='sch-void',
|
|
sample_payment_id='sp-void',
|
|
collection_protocol_id='p-void',
|
|
sample_code='S9',
|
|
schedule_no=1,
|
|
due_amount=Decimal('5000'),
|
|
due_date='20260918',
|
|
schedule_status='cleared',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolPaymentTransfer(
|
|
id='tr-void',
|
|
schedule_id='sch-void',
|
|
sample_payment_id='sp-void',
|
|
collection_protocol_id='p-void',
|
|
sample_code='S9',
|
|
transfer_amount=Decimal('5000'),
|
|
transfer_time=datetime(2026, 9, 18, 14, 55, 4),
|
|
pay_status='yjf',
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
BizProtocolRefundRecord(
|
|
id='rf-void',
|
|
collection_protocol_id='p-void',
|
|
refund_amount=Decimal('5000'),
|
|
refund_time=datetime(2026, 9, 19, 10, 0, 0),
|
|
tenant_no='tenant-a',
|
|
del_flag=0,
|
|
),
|
|
]
|
|
)
|
|
db.commit()
|
|
summary = build_protocol_payment_summaries(
|
|
db, ['p-void'], 'tenant-a', include_sample_payment_modes=True
|
|
)['p-void']
|
|
assert summary['receivedAmount'] == 5000.0
|
|
assert summary['refundAmount'] == 5000.0
|
|
engine.dispose()
|