"""独立核验DJ091—100:用整数分和Decimal复算家庭账表示例。""" from decimal import Decimal as D from pathlib import Path import json def calculate(): out={} # 091:内部本金守恒,另扣手续费时净资产仅减少费用。 a,b,transfer,fee=10000,5000,3000,5 out['DJ091']={'before':a+b,'a_after':a-transfer,'b_after':b+transfer, 'after':a-transfer+b+transfer,'with_fee':a-transfer-fee+b+transfer} assert out['DJ091']['before']==out['DJ091']['after'] and out['DJ091']['with_fee']==14995 # 092:信用卡消费形成负债,还本不再损耗净资产。 cash,expense=8000,1200 out['DJ092']={'net_after_purchase':cash-expense,'cash_after_repayment':cash-expense, 'debt_after_repayment':expense-expense,'with_extra_fee':cash-expense-20} assert out['DJ092']['net_after_purchase']==out['DJ092']['cash_after_repayment'] # 093:两种预算归属都回到相同两月净现金,双冲会多减800。 dec_income,jan_income,dec_expense,jan_expense,refund=10000,10000,6000,6200,800 out['DJ093']={'dec_cash':dec_income-dec_expense,'jan_cash':jan_income-jan_expense+refund, 'total_cash':dec_income+jan_income-dec_expense-jan_expense+refund, 'origin_month_expense':dec_expense-refund,'receipt_month_expense':jan_expense-refund, 'retained_expense':dec_expense+jan_expense-refund, 'incorrect_double_refund_surplus':dec_income+jan_income-(dec_expense-refund)-(jan_expense-refund)} assert out['DJ093']['total_cash']==8600 and out['DJ093']['incorrect_double_refund_surplus']==9400 # 094:由现金转应收,再确认个人承担200,回款不再创造收入。 original,advance,approved=10000,1800,1600 out['DJ094']={'cash_after_advance':original-advance,'net_before_approval':original-advance+advance, 'net_after_approval':original-advance+approved,'final_cash':original-advance+approved, 'personal_cost':advance-approved} assert out['DJ094']['net_before_approval']-out['DJ094']['final_cash']==out['DJ094']['personal_cost'] # 095:本金资产转换,费用与市值变化分别核对。 cash,payment,fee=12000,3000,30 shares=D(payment-fee)/D('1') out['DJ095']={'cash_after':cash-payment,'initial_units':int(shares),'initial_assets':cash-fee, 'market_value_after_rise':str(shares*D('1.1')), 'total_assets_after_rise':str(D(cash-payment)+shares*D('1.1')), 'net_change_after_rise':str(D(cash-payment)+shares*D('1.1')-D(cash))} assert D(out['DJ095']['net_change_after_rise'])==D('267') # 096:预留属于资金用途,实际支出只发生一次。 monthly,months,target=600,12,7200 schedule=[monthly*i for i in range(1,months+1)] out['DJ096']={'reserves_before_payment':schedule,'after_payment':schedule[-1]-target, 'lower_bill_carryover':schedule[-1]-6000,'seven_equal_payments':str((D(target)/7).quantize(D('.01'))), 'seven_payments_at_600':monthly*7,'shortfall':target-monthly*7} assert out['DJ096']['after_payment']==0 and out['DJ096']['lower_bill_carryover']==1200 # 097:唯一账户汇总与分摊视图应相等。 personal_a,personal_b,joint=30000,20000,40000 out['DJ097']={'family':personal_a+personal_b+joint,'a_share':personal_a+joint//2, 'b_share':personal_b+joint//2,'wrong_double_joint':personal_a+personal_b+joint*2} assert out['DJ097']['a_share']+out['DJ097']['b_share']==out['DJ097']['family'] # 098:本息、估值和提前还本分开桥接。 house,cash,debt,principal,interest=1000000,100000,600000,3000,2000 after_cash=cash-principal-interest;after_debt=debt-principal out['DJ098']={'before_net':house+cash-debt,'after_cash':after_cash,'after_debt':after_debt, 'after_net':house+after_cash-after_debt,'after_valuation_rise':house+20000+after_cash-after_debt, 'after_extra_principal':house+(after_cash-20000)-(after_debt-20000), 'original_case_sale_cash':house-40000-debt+cash} assert out['DJ098']['before_net']-out['DJ098']['after_net']==interest assert out['DJ098']['after_extra_principal']==out['DJ098']['after_net'] # 099:原币、预算汇率、结算汇率及未退费用分别核对。 foreign,budget_rate,actual_rate,fee_rate,refund_rate=map(D,('100','7.00','7.12','.015','7.05')) actual=foreign*actual_rate;budget=foreign*budget_rate;fee=actual*fee_rate out['DJ099']={k:str(v) for k,v in {'budget':budget,'settled':actual,'fee':fee,'total':actual+fee, 'over_budget':actual+fee-budget,'refund':foreign*refund_rate,'remaining_cost':actual+fee-foreign*refund_rate, 'unspent_currency_valuation_change':D('200')*(actual_rate-budget_rate)}.items()} assert D(out['DJ099']['over_budget'])==D('22.68') and D(out['DJ099']['remaining_cost'])==D('17.68') # 100:三个错误分别从同一基准出发,不能错误地视为同一组并发交易。 baseline=1500000+1200000-800000-100000 out['DJ100']={'baseline_cents':baseline,'after_fee_cents':baseline-2000, 'duplicate_salary_cents':baseline+1200000,'pending_refund_as_cash_cents':baseline+50000, 'matched_internal_transfer_net':-200000+200000} assert out['DJ100']['baseline_cents']==1800000 and out['DJ100']['matched_internal_transfer_net']==0 return out if __name__=='__main__': result={'passed':True,'method':'整数分、Decimal与逐账户守恒核对;仅验证构造算例,不替代合同与规则核验','articles':calculate()} path=Path(__file__).with_suffix('.json');path.write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n',encoding='utf-8') print(json.dumps(result,ensure_ascii=False,indent=2))