前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用python分析个人所得税

用python分析个人所得税

原创
作者头像
mariolu
修改2024-03-30 17:13:38
1690
修改2024-03-30 17:13:38
举报
文章被收录于专栏:Python实用主义CDN及云技术分享

又到了一年个人所得税报税季。你去退税/缴税了吗?

这里我们用Python实现了一段所得税计算软件,并给出了一些优化的建议。

一、发票识别

像平时的发票识别,这里推荐用腾讯云的图片识别,有针对发票分类的图标识别服务。

https://console.cloud.tencent.com/api/explorer?Product=ocr&Version=2018-11-19&Action=DutyPaidProofOCR

二、个人所得税

2024年最新的税率表如下

添加描述

完整的程序:

代码语言:python
代码运行次数:0
复制
from dataclasses import dataclass
from typing import Optional, List

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
from mpl_toolkits.mplot3d import Axes3D

# 中华人民共和国个人所得税法: http://www.chinatax.gov.cn/n810341/n810755/c3967308/content.html
# 关于个人所得税法修改后有关优惠政策衔接问题的通知:
# http://www.chinatax.gov.cn/n810341/n810755/c3978994/content.html

@dataclass
class TaxRate:
    start: Optional[float]
    end: Optional[float]
    rate: float
    deduction: float


def count_social_insurance(monthly_salary):
    return 0


def check_tax_rate(tax_rates):
    pass


def find_tax_rate(tax_rates: List[TaxRate], salary: float) -> Optional[TaxRate]:
    for r in tax_rates:
        if ((r.start is None or r.start < salary)
                and (r.end is None or r.end >= salary)):
            return r
    raise Exception("Cannot find tax rate")


def count_tax(
        start_point: float,  # 月薪起征点
        tax_rates: List[TaxRate],  # 税率表
        monthly_salary: float,  # 月薪
        bonus: float,  # 年终奖
        deduction: float,  # 专项扣除
) -> float:
    monthly_need_tax = monthly_salary - count_social_insurance(monthly_salary) - start_point - deduction
    if monthly_need_tax < 0:
        monthly_need_tax = 0
    monthly_tax_rate = find_tax_rate(tax_rates, monthly_need_tax)
    monthly_tax = monthly_need_tax * monthly_tax_rate.rate - monthly_tax_rate.deduction
    bonus_tax_rate = find_tax_rate(tax_rates, bonus / 12.0)
    # The bonus tax result is not the accumulated tax, it is what the law says, not a bug
    bonus_tax = bonus * bonus_tax_rate.rate - bonus_tax_rate.deduction
    return 12 * monthly_tax + bonus_tax


def min_tax(
        start_point: float,  # 月薪起征点
        tax_rates: List[TaxRate],  # 税率表
        all_salary: float,
        deduction: float,  # 专项扣除
) -> (float, float, float):
    points = [r.start for r in tax_rates if r.start is not None]
    points.append(0)
    count_points = []

    for p in points:
        monthly_salary = start_point + deduction + p
        bonus = all_salary - 12 * monthly_salary
        if bonus < 0:
            break
        count_points.append((monthly_salary, bonus))
    count_points.append((all_salary/12.0, 0))
    for p in points:
        bonus = 12 * p
        monthly_salary = (all_salary - bonus) / 12.0
        if monthly_salary < 0:
            break
        count_points.append((monthly_salary, bonus))
    count_points.append((0, all_salary))

    min_tax_result = all_salary + 1
    min_monthly_salary = None
    min_bonus = None

    for (monthly_salary, bonus) in count_points:
        if monthly_salary < 0 or bonus < 0:
            continue
        tax = count_tax(start_point, tax_rates, monthly_salary, bonus, deduction)
        # print("M: %f\tB:%f\tT:%f\t" % (monthly_salary, bonus, tax))
        if min_tax_result > tax:
            min_tax_result = tax
            min_monthly_salary = monthly_salary
            min_bonus = bonus

    return min_tax_result, min_monthly_salary, min_bonus


tax_rates_2024 = [
    TaxRate(None, 3000, 0.03, 0),  # 全年应纳税不超过36000元的
    TaxRate(3000, 12000, 0.1, 210),  # 超过36000至144000元的部分
    TaxRate(12000, 25000, 0.2, 1410), # 超过144000至300000元的部分
    TaxRate(25000, 35000, 0.25, 2660), # 超过300000至420000元的部分
    TaxRate(35000, 55000, 0.3, 4410), # 超过420000至660000元的部分
    TaxRate(55000, 80000, 0.35, 7160), # 超过660000至960000元的部分
    TaxRate(80000, None, 0.45, 15160), # 超过960000元的部分
]

monthly_start_point_2024 = 60000 / 12.0


def count_tax_2024(monthly_salary, bonus, deduction):
    """
    计算个人所得税
    :param monthly_salary: 月薪
    :param bonus: 年终奖
    :param deduction: 每月专项扣除
    :return: 全年需要缴纳的个人所得税
    """
    return count_tax(monthly_start_point_2024, tax_rates_2024, monthly_salary,
                     bonus, deduction)


def min_tax_2024(year_salary, monthly_deduction):
    """
    计算最优的年终奖方案
    :param year_salary: 年薪
    :param monthly_deduction: 每月专项扣除
    :return: (全年需要缴纳的个人所得税, 月薪, 年终奖)
    """
    return min_tax(monthly_start_point_2024, tax_rates_2024, year_salary, monthly_deduction)


def draw_tax_2024():
    x = []
    y = []
    z = []
    for monthly_salary in range(0, 200000, 2000):
        for bonus in range(0, 2000000, 20000):
            salary = 12 * monthly_salary + bonus
            tax = count_tax_2024(monthly_salary, bonus, 0)
            after_tax = salary - tax
            x.append(monthly_salary)
            y.append(bonus)
            z.append(after_tax)
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_trisurf(np.array(x), np.array(y), np.array(z))
    #plt.show()
    #plt.imshow(img)
    fig.savefig('plot2.png', dpi=80)


def draw_min_tax_2024():
    min_taxes = []
    all_salaries = []
    after_taxes = []
    avoid_taxes = []
    bonuses = []
    for all_salary in range(0, 3000000, 12000):
        tax, monthly_salary, bonus = min_tax_2024(all_salary, 0)
        raw_tax = count_tax_2024(all_salary / 12.0, 0, 0)
        print("All: %f\ttax: %f\tmonthly: %f\tbonus: %f" % (all_salary, tax, monthly_salary, bonus))
        all_salaries.append(all_salary)
        min_taxes.append(tax)
        after_taxes.append(all_salary-tax)
        avoid_taxes.append(raw_tax - tax)
        bonuses.append(bonus)
    plt.plot(all_salaries, all_salaries, label="Salary per year")
    plt.plot(all_salaries, min_taxes, label="Minimal tax")
    plt.plot(all_salaries, after_taxes, label="Salary after tax")
    plt.plot(all_salaries, avoid_taxes, label="Avoided tax")
    plt.plot(all_salaries, bonuses, label="Best bones divid")
    plt.xlabel('Salary per year')
    plt.ylabel('Money')
    plt.title("Tax Counter")
    plt.legend()
    #plt.show()
    fig = plt.figure()
    fig.savefig('plot2.png', dpi=80)


draw_tax_2024()
#draw_min_tax_2024()

阿尼纳

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、发票识别
    • 二、个人所得税
    相关产品与服务
    增值税发票核验
    增值税发票核验(Value-Added Tax Invoice Verification,VTIV)基于行业前沿的深度学习技术,为您提供增值税发票的识别及信息准确性核验服务。产品支持多种发票类型,可应用于企业费控报销管理、供应链发票核验、财税代理记账等场景。产品智能、快速、稳定、安全,满足您的多样性业务需求。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档