业务背景
在实际工作中,经常会遇到计算合同金额、合同价款、合同税款的情况,公式如下:
合同金额 = 合同价款 + 合同税款
合同税款 = 合同价款 * 合同税率
合同金额 = 合同价款 + 合同价款 * 合同税率 = 合同价款 * (1 + 合同税率)
如果已知合同金额和合同税率,那么
合同价款 = 合同金额 / (1 + 合同税率)
上述逻辑适用于合同税率单一的情况,实操中,一个合同往往还包括产品费用和实施费用,而二者的增值税率不一样,前者为13%,后者为6%,那么价款和税款又可以分为产品价款、产品税款、实施价款、实施税款这四类。
作为IT从业人员,无论您是甲方项目经理,还是乙方项目经理、销售经理、商务经理,计算上面的数字是经常的事情。人工计算难免出错,也不利于核验,会说科技根据以上逻辑编写完成如下价款和税款Python代码一段,送给需要的呢。
#python#

Python代码
实操中,对金额往往只需保留两位小数,因此首先写一个四舍五入并且保留两位小数的函数,定义为round_up。为什么要重新定义呢,因为Python原生的round对于精细化的四舍五入无法做到精准,往往会错位,具体您可以试一下。
def round_up(value):
# 替换内置round函数,实现保留2位小数的精确四舍五入
return round(value * 100) / 100.0
下面定义本文的核心函数,即价款、税款计算函数,传入参数为产品金额、产品税率、实施金额、实施税率,返回报错信息、产品价款、产品税款、实施价款、实施税款。
#正则表达式#
#计算价款和税额
import re
#productMoney:产品金额
#productRate:产品税率
#modelMoney:实施金额
#modelRate:实施税率
def tax_compute(productMoney,productRate,modelMoney,modelRate):
errmsg = ''
productAmt = 0 #产品价款
productTax = 0 #产品税款
modelAmt = 0 #实施价款
modelTax = 0 #实施税款
#将参数转成字符串,以便应用正则表达式匹配
#不做转换,re无法识别
productMoneyStr = str(productMoney)
productRateStr = str(productRate)
modelMoneyStr = str(modelMoney)
modelRateStr = str(modelRate)
#正则表达式,匹配金额0.00-999999999.999999
moneyPattern = r'([1-9]\d{0,9}|0)(\.\d{1,6})'
#如果参数输入不合法则报错返回
if re.match(moneyPattern,productMoneyStr) == False or re.match(moneyPattern,productRateStr) == False:
errmsg = '产品金额或税率不正确'
return errmsg,productAmt,productTax,modelAmt,modelTax
if re.match(moneyPattern,modelMoneyStr) == False or re.match(moneyPattern,modelRateStr) == False:
errmsg = '实施金额或税率不正确'
return errmsg,productAmt,productTax,modelAmt,modelTax
if productMoney < 0:
errmsg = '产品金额不正确'
return errmsg,productAmt,productTax,modelAmt,modelTax
if productRate < 0 or productRate > 1:
errmsg = '产品税率不正确'
return errmsg,productAmt,productTax,modelAmt,modelTax
if modelMoney < 0:
errmsg = '实施金额不正确'
return errmsg,productAmt,productTax,modelAmt,modelTax
if modelRate < 0 or modelRate > 1:
errmsg = '产品税率不正确'
return errmsg,productAmt,productTax,modelAmt,modelTax
#合同价款
productAmt = productMoney/(1+productRate)
#合同税款
#中间一定要有操作符,不然报'float' object is not callable的错误
productTax = productAmt * productRate
#校验合同价款、税款、金额
checkProductMoney = productAmt+productTax
#实施价款
modelAmt = modelMoney / (1+modelRate)
#实施税款
modelTax = modelAmt * modelRate
#校验实施价款、税款、金额
checkModelMoney = modelAmt + modelTax
#校验通过
#结果校验未通过,请联系管理员12345678【600000.0000000001=600000.0,1216000.0=1216000.0
#直接用==会出现同一个数字因为精度不同导致的不一致,因此改用abs
if abs(checkProductMoney - productMoney) < 0.00001 and abs(checkModelMoney - modelMoney) < 0.00001:
errmsg = '校验通过,结果如下:'
return errmsg,round_up(productAmt),round_up(productTax),round_up(modelAmt),round_up(modelTax)
else:
errmsg = '结果校验未通过:【'+str(checkProductMoney)+'='+str(productMoney)+','+str(checkModelMoney)+'='+str(modelMoney)
return errmsg,round_up(productAmt),round_up(productTax),round_up(modelAmt),round_up(modelTax)

有了上面的核心函数,我们下面验证一下,与通过计算器计算的结果一致。#Python函数#
errmsg,productAmt,productTax,modelAmt,modelTax = tax_compute(800000.00,0.13,1200000.00,0.06)
if(errmsg == ''):
print('产品价款:',productAmt)
print('产品税额:',productTax)
print('产品金额:',productAmt+productTax)
print('实施价款:',modelAmt)
print('实施税额:',modelTax)
print('实施金额:',modelAmt+modelTax)
else:
print(errmsg)
print('产品价款:',productAmt)
print('产品税额:',productTax)
print('产品金额:',productAmt+productTax)
print('实施价款:',modelAmt)
print('实施税额:',modelTax)
print('实施金额:',modelAmt+modelTax)
#结果为
校验通过,结果如下:
产品价款: 707964.6
产品税额: 92035.4
产品金额: 800000.0
实施价款: 1132075.47
实施税额: 67924.53
实施金额: 1200000.0
我是会说科技,关注我,一起聊聊科技、IT、数据、金融那些事