Ver código fonte

补充申报方法

1 2 semanas atrás
pai
commit
9a8a4e17fe

+ 192 - 0
common/CheckYbjc/Xgm.go

@@ -0,0 +1,192 @@
+package CheckYbjc
+
+import (
+	"git.listensoft.net/tool/jspkit/common"
+	"git.listensoft.net/tool/jspkit/common/models"
+	"git.listensoft.net/tool/jspkit/common/models/sb"
+	"math"
+	"reflect"
+	"strings"
+)
+
+func CheckSmallVat(vat []sb.GsSmallVat, basevat []sb.GsSmallVat, hw bool) (status int, errLog string) {
+	status = 1
+	var errLogs []string
+	// 强制校验
+	{
+		index1 := []string{"本期数-货物及劳务", "本期数-服务、不动产和无形资产", "本年累计-货物及劳务", "本年累计-服务、不动产和无形资产"}
+		for k, v := range index1 {
+			//if hw {
+			//	if k == 1 || k == 3 {
+			//		continue
+			//	}
+			//} else {
+			//	if k == 0 || k == 2 {
+			//		continue
+			//	}
+			//}
+			if Tran(basevat[k].Yzzzsbhsxse) < Tran(vat[k].Yzzzsbhsxse) {
+				errLogs = append(errLogs, v+"-应征增值税不含税销售额(3%征收率)不一致税局为:税局为"+vat[k].Yzzzsbhsxse+"系统为:"+basevat[k].Yzzzsbhsxse)
+			}
+			if Tran(basevat[k].Swjgdkdzzszyfpbhsxse) < Tran(vat[k].Swjgdkdzzszyfpbhsxse) {
+				errLogs = append(errLogs, v+"-增值税专用发票不含税销售额:税局为"+vat[k].Swjgdkdzzszyfpbhsxse+"系统为:"+basevat[k].Swjgdkdzzszyfpbhsxse)
+			}
+			if Tran(basevat[k].Skqjkjdptfpbhsxse) < Tran(vat[k].Skqjkjdptfpbhsxse) {
+				errLogs = append(errLogs, v+"-其他增值税发票不含税销售额:税局为"+vat[k].Skqjkjdptfpbhsxse+"系统为:"+basevat[k].Skqjkjdptfpbhsxse)
+			}
+			//if Tran(basevat[k].Xsczbdcbhsxse) != Tran(vat[k].Xsczbdcbhsxse) {
+			//	errLogs = append(errLogs, v+"-(二)应征增值税不含税销售额(5%征收率):税局为"+vat[k].Xsczbdcbhsxse+"系统为:"+basevat[k].Xsczbdcbhsxse)
+			//}
+			//if Tran(basevat[k].Swjgdkdzzszyfpbhsxse1) != Tran(vat[k].Swjgdkdzzszyfpbhsxse1) {
+			//	errLogs = append(errLogs, v+"-增值税专用发票不含税销售额:税局为"+vat[k].Swjgdkdzzszyfpbhsxse1+"系统为:"+basevat[k].Swjgdkdzzszyfpbhsxse1)
+			//}
+			//if Tran(basevat[k].Skqjkjdptfpbhsxse2) != Tran(vat[k].Skqjkjdptfpbhsxse2) {
+			//	errLogs = append(errLogs, v+"-其他增值税发票不含税销售额:税局为"+vat[k].Skqjkjdptfpbhsxse2+"系统为:"+basevat[k].Skqjkjdptfpbhsxse2)
+			//}
+
+			if Tran(basevat[k].Msxse) < Tran(vat[k].Msxse) {
+				errLogs = append(errLogs, v+"-免税销售额:税局为"+vat[k].Msxse+"系统为:"+basevat[k].Msxse)
+			}
+			if Tran(basevat[k].Xwqymsxse) < Tran(vat[k].Xwqymsxse) {
+				errLogs = append(errLogs, v+"-小微企业免税销售额:税局为"+vat[k].Xwqymsxse+"系统为:"+basevat[k].Xwqymsxse)
+			}
+			if Tran(basevat[k].Wdqzdxse) < Tran(vat[k].Wdqzdxse) {
+				errLogs = append(errLogs, v+"-未达起征点免税销售额:税局为"+vat[k].Wdqzdxse+"系统为:"+basevat[k].Wdqzdxse)
+			}
+			if Tran(basevat[k].Qtmsxse) < Tran(vat[k].Qtmsxse) {
+				errLogs = append(errLogs, v+"-其他免税销售额:税局为"+vat[k].Qtmsxse+"系统为:"+basevat[k].Qtmsxse)
+			}
+
+			if math.Abs(Tran(basevat[k].Bqynsejze)-Tran(vat[k].Bqynsejze)) > 0.5 { // 五毛误差
+				errLogs = append(errLogs, v+"-本期应纳税额减征额:税局为"+vat[k].Bqynsejze+"系统为:"+basevat[k].Bqynsejze)
+			}
+			//if Tran(basevat[k].Bqmse) < Tran(vat[k].Bqmse) {
+			//	errLogs = append(errLogs, v+"-本期免税额:税局为"+vat[k].Bqmse+"系统为:"+basevat[k].Bqmse)
+			//}
+			//if Tran(basevat[k].Xwqymse) < Tran(vat[k].Xwqymse) {
+			//	errLogs = append(errLogs, v+"-小微企业免税额:税局为"+vat[k].Xwqymse+"系统为:"+basevat[k].Xwqymse)
+			//}
+			//if Tran(basevat[k].Wdqzdmse) < Tran(vat[k].Wdqzdmse) {
+			//	errLogs = append(errLogs, v+"-未达起征点免税额:税局为"+vat[k].Wdqzdmse+"系统为:"+basevat[k].Wdqzdmse)
+			//}
+			//if Tran(basevat[k].Bqybtse) != Tran(vat[k].Bqybtse) {
+			//	errLogs = append(errLogs, v+"-本期应补(退)税额:税局为"+vat[k].Bqybtse+"系统为:"+basevat[k].Bqybtse)
+			//}
+			//zaplog.LoggerS.Info(Tran(basevat[k].Cjs), Tran(vat[k].Cjs))
+			//if Tran(basevat[k].Cjs) != Tran(vat[k].Cjs) {
+			//	errLogs = append(errLogs, v+"-城市维护建设税本期应补(退)税额:税局为"+vat[k].Cjs+"系统为:"+basevat[k].Cjs)
+			//}
+			//if Tran(basevat[k].Jyf) != Tran(vat[k].Jyf) {
+			//	errLogs = append(errLogs, v+"-教育费附加本期应补(退)费额:税局为"+vat[k].Jyf+"系统为:"+basevat[k].Jyf)
+			//}
+			//if Tran(basevat[k].Dfjyf) != Tran(vat[k].Dfjyf) {
+			//	errLogs = append(errLogs, v+"-地方教育附加本期应补(退)费额:税局为"+vat[k].Dfjyf+"系统为:"+basevat[k].Dfjyf)
+			//}
+			//if Tran(basevat[k].Bqyjse1) != Tran(vat[k].Bqyjse1) {
+			//	errLogs = append(errLogs, v+"本期预缴税额:税局为"+vat[k].Bqyjse1+"系统为:"+basevat[k].Bqyjse1)
+			//}
+		}
+	}
+	// 普通检验
+
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+
+func CheckSmallAttach2(Attach2 []models.GsVatFjs, baseAttach2 []models.GsVatFjs) (status int, errLog string) {
+	status = 1
+	// 非强制校验
+	{
+		var KeyNAme = []string{
+			"Zzsse",
+			"Bqybtse",
+		}
+		for _, v1 := range Attach2 {
+			for _, v2 := range baseAttach2 {
+				if v1.ZsxmDm == v2.ZsxmDm {
+					r1 := reflect.ValueOf(v1)
+					r2 := reflect.ValueOf(v2)
+					for _, key_name := range KeyNAme {
+						if common.StrToFloat(r1.FieldByName(key_name).String()) != common.StrToFloat(r2.FieldByName(key_name).String()) {
+							status = 2
+							break
+						}
+					}
+					if status == 2 {
+						break
+					}
+				}
+			}
+			if status == 2 {
+				break
+			}
+		}
+	}
+	var errLogs []string
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+
+func CheckSmallJm(jm []sb.GsSmallVatReduce, Jm []sb.GsSmallVatReduce) (status int, errLog string) {
+	status = 1
+	var errLogs []string
+	var jsxm1 []sb.GsSmallVatReduce
+	for _, v := range jm {
+		if v.Type == 1 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			jsxm1 = append(jsxm1, v)
+		}
+	}
+
+	var jsxm2 []sb.GsSmallVatReduce
+	for _, v := range Jm {
+		if v.Type == 1 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			jsxm2 = append(jsxm2, v)
+		}
+	}
+
+	// 非强制校验
+	{
+		// 减税项目
+		if len(jsxm1) != len(jsxm2) {
+			status = 2
+			//errLogs = append(errLogs, fmt.Sprintf("税局减税项目有%d条系统有%d条", len(jsxm1), len(jsxm2)))
+		}
+		for _, v1 := range jsxm1 {
+			find := false
+			for _, v2 := range jsxm2 {
+				if v1.SbJmxzdmJmHm == v2.SbJmxzdmJmHm {
+					find = true
+					if common.StrToFloat(v1.Qcye) == common.StrToFloat(v2.Qcye) && common.StrToFloat(v1.Qmye) == common.StrToFloat(v2.Qmye) && common.StrToFloat(v1.Bqfse) == common.StrToFloat(v2.Bqfse) && common.StrToFloat(v1.Bqydjse) == common.StrToFloat(v2.Bqydjse) {
+						status = 1
+					} else {
+						status = 2
+					}
+					break
+				}
+
+			}
+			if !find {
+				status = 2
+				//errLogs = append(errLogs, fmt.Sprintf("税局减税项目:%s 为在系统中找到,请核实", len(jsxm1), len(jsxm2)))
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return
+}
+
+func Tran(a string) float64 {
+	if a == "" {
+		return 0
+	}
+	return common.StrToFloat(strings.TrimSpace(strings.ReplaceAll(a, ",", "")))
+}

+ 569 - 0
common/CheckYbjc/Ybnsr.go

@@ -0,0 +1,569 @@
+package CheckYbjc
+
+import (
+	"fmt"
+	"git.listensoft.net/tool/jspkit/common"
+	"git.listensoft.net/tool/jspkit/common/models/sb"
+	"git.listensoft.net/tool/jspkit/common/variable"
+	"git.listensoft.net/tool/jspkit/logger"
+	"git.listensoft.net/tool/jspkit/taxerr"
+	"reflect"
+	"strings"
+)
+
+func CheckVatByYbjc(Data string, vat []sb.GsVat, fb1 []sb.GsVatAttach1, fb2 []sb.GsVatAttach2, fb3 []sb.GsVatAttach3, fb4 []sb.GsVatAttach4, fb5 []sb.GsVatAttach5, jm []sb.GsVatJsxm) (status int, editTable string, errLog string) {
+	vats := []sb.GsVat{}
+	common.GetData(variable.GsVat, Data, &vats)
+	var attach1s []sb.GsVatAttach1
+	common.GetData(variable.GsVatAttach1, Data, &attach1s)
+	var attach2s []sb.GsVatAttach2
+	common.GetData(variable.GsVatAttach2, Data, &attach2s)
+	var attach3s []sb.GsVatAttach3
+	common.GetData(variable.GsVatAttach3, Data, &attach3s)
+	var attach4s []sb.GsVatAttach4
+	common.GetData(variable.GsVatAttach4, Data, &attach4s)
+	var vatfjs []sb.GsVatAttach5
+	common.GetData(variable.GsVatAttach5, Data, &vatfjs)
+	if len(vatfjs) != 3 {
+		panic(taxerr.NewUser("附加税生成错误!"))
+	}
+	var gs_vat_qt sb.GsVatQt
+	common.GetData(variable.GsVatQt, Data, &gs_vat_qt)
+	var gsVatJsxm []sb.GsVatJsxm
+	common.GetData(variable.GsVatJsxm, Data, &gsVatJsxm)
+	var jsxm []sb.GsVatJsxm
+	for _, v := range gsVatJsxm {
+		if v.Type == 1 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			jsxm = append(jsxm, v)
+		}
+	}
+	var ckms []sb.GsVatJsxm //出口免税
+	for _, v := range gsVatJsxm {
+		if v.Type == 2 {
+			ckms = append(ckms, v)
+			break
+		}
+	}
+	var kjfw []sb.GsVatJsxm //       其中:跨境服务
+	for _, v := range gsVatJsxm {
+		if v.Type == 3 {
+			kjfw = append(kjfw, v)
+			break
+		}
+	}
+	var msxm []sb.GsVatJsxm
+	for _, v := range gsVatJsxm {
+		if v.Type == 4 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			msxm = append(msxm, v)
+		}
+	}
+	{
+
+	}
+
+	return 1, "", ""
+}
+
+// CheckWpsrLost 无票收入负数发票 税局主表 系统主表 系统附表一;正数发票可以在CheckVat返回2 重新填表
+func CheckWpsrLost(vat []sb.GsVat, baseVat []sb.GsVat, attach1 []sb.GsVatAttach1) bool {
+	// 先判断附表一是不是有未开具发票
+	Check1 := false
+	for _, v := range attach1 {
+		if common.StrToFloat(v.WkjfpXxynse) != 0 || common.StrToFloat(v.WkjfpXse) != 0 {
+			logger.Info(`当前企业含有负数未开具发票,系统附表一数据:`, v.WkjfpXse, v.WkjfpXxynse)
+			Check1 = true
+			break
+		}
+	}
+	// 在判断 主表的减免
+	Check2 := false
+	if common.StrToFloat(baseVat[0].Xxse) < common.StrToFloat(vat[0].Xxse) {
+		Check2 = true
+	}
+	Check3 := true
+	// 还是留几个强制校验
+	{
+		if common.StrToFloat(vat[0].Jxse) > common.StrToFloat(baseVat[0].Jxse) {
+			Check3 = false
+		}
+		if common.StrToFloat(vat[0].Sqldse) != common.StrToFloat(baseVat[0].Sqldse) {
+			Check3 = false
+		}
+		if common.StrToFloat(vat[0].Qcwjse) != common.StrToFloat(baseVat[0].Qcwjse) {
+			Check3 = false
+		}
+	}
+
+	if Check1 && Check2 && Check3 {
+		logger.Info("当前企业含有负数未开具发票:主表数据", baseVat[0].Xxse, vat[0].Xxse)
+		return true
+	}
+	return false
+}
+
+func CheckVat(vat []sb.GsVat, baseVat []sb.GsVat) (status int, errLog string) {
+	status = 1
+	var errLogs []string
+	// 强制校验
+	{
+		i := 0
+		var Prefix = ""
+		switch i {
+		case 0:
+			Prefix = "一般纳税人主表-一般项目本月数-"
+		case 1:
+			Prefix = "一般纳税人主表-一般项目本年累计-"
+		case 2:
+			Prefix = "一般纳税人主表-即征即退项目本月数-"
+		case 3:
+			Prefix = "一般纳税人主表-即征即退项目本年累计-"
+		}
+		//if common.StrToFloat(vat[i].Asysljsxse) != common.StrToFloat(baseVat[i].Asysljsxse) {
+		//	errLogs = append(errLogs, MakeMsg(Prefix+"(一)按适用税率计税销售额", vat[i].Asysljsxse, baseVat[i].Asysljsxse))
+		//}
+		if common.StrToFloat(baseVat[i].Xxse) < common.StrToFloat(vat[i].Xxse) {
+			errLogs = append(errLogs, MakeMsg(Prefix+"销项税额", vat[i].Xxse, baseVat[i].Xxse))
+		}
+		if common.StrToFloat(vat[i].Jxse) > common.StrToFloat(baseVat[i].Jxse) {
+			errLogs = append(errLogs, MakeMsg(Prefix+"进项税额", vat[i].Jxse, baseVat[i].Jxse))
+		}
+		if common.StrToFloat(vat[0].Sqldse) != common.StrToFloat(baseVat[0].Sqldse) {
+			errLogs = append(errLogs, MakeMsg("一般纳税人主表一 一般项目本月数-上期留抵税额", vat[0].Sqldse, baseVat[0].Sqldse))
+		}
+		if common.StrToFloat(vat[0].Qcwjse) != common.StrToFloat(baseVat[0].Qcwjse) {
+			errLogs = append(errLogs, MakeMsg("一般纳税人主表一 一般项目本月数-期初未缴税额", vat[0].Qcwjse, baseVat[0].Qcwjse))
+		}
+		//if common.StrToFloat(vat[i].Bqybtse) != common.StrToFloat(baseVat[i].Bqybtse) {
+		//	errLogs = append(errLogs, MakeMsg(Prefix+"本期应补(退)税额", vat[i].Bqybtse, baseVat[i].Bqybtse))
+		//}
+		// 强制校验失败直接返回
+		if len(errLogs) > 0 {
+			return 3, strings.Join(errLogs, ",")
+		}
+	}
+	for i := 0; i < 4; i++ {
+		// 非强制校验
+		{
+			var KeyName = []string{
+				"Asysljsxse",
+				"Yshwxse",
+				"Yslwxse",
+				"Xxse",
+				"Jxse",
+				//"Sqldse",
+				"Ynsehj",
+				//"Qcwjse",
+
+				"Qmwjse",
+				"Bqybtse",
+				"Cjs",
+				"Jyf",
+				"Dfjyf",
+			}
+			v1 := reflect.ValueOf(vat[0])
+			v2 := reflect.ValueOf(baseVat[0])
+			for _, v := range KeyName {
+				if common.StrToFloat(v1.FieldByName(v).String()) != common.StrToFloat(v2.FieldByName(v).String()) {
+					logger.Info("主表对比不通过:" + v)
+					status = 2
+					break
+				}
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+
+func CheckAttach1(fb1 []sb.GsVatAttach1, attach1 []sb.GsVatAttach1) (status int, errLog string) {
+	status = 1
+	var errLogs []string
+	attach1[0].Jshj = "0" // 这个数据暂时置空 因为系统会计算出来但是税局是---
+	// 非强制校验
+	{
+
+		var KeyName = []string{
+			"KjskzzszyfpXse",
+			"KjskzzszyfpXxynse",
+			"WkjfpXse",
+			"WkjfpXxynse",
+			"KjqtfpXse",
+			"KjqtfpXxynse",
+			"Nsjctzdxse",
+			"NsjctzXxynse",
+		}
+		for i := range attach1 {
+			r1 := reflect.ValueOf(fb1[i])
+			r2 := reflect.ValueOf(attach1[i])
+			for _, key_name := range KeyName {
+				if common.StrToFloat(r1.FieldByName(key_name).String()) != common.StrToFloat(r2.FieldByName(key_name).String()) {
+					status = 2
+					break
+				}
+			}
+		}
+		if common.StrToFloat(fb1[0].Xse) != common.StrToFloat(attach1[0].Xse) {
+			if status != 2 {
+				status = 2
+			}
+		}
+		if common.StrToFloat(fb1[0].HjXxynse) != common.StrToFloat(attach1[0].HjXxynse) {
+			if status != 2 {
+				status = 2
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+
+func CheckAttach2(fb2 []sb.GsVatAttach2, attach2 []sb.GsVatAttach2) (status int, errLog string) {
+	status = 1
+	var errLogs []string
+
+	// 非强制校验
+	{
+		//期初已认证相符但未申报抵扣
+		if common.StrToFloat(fb2[24].Je) != common.StrToFloat(attach2[24].Je) {
+			errLogs = append(errLogs, fmt.Sprintf("附表二:期初已认证相符但未申报抵扣金额不一致:税局为%s系统为%s", fb2[24].Je, attach2[24].Je))
+		}
+		for i := range attach2 {
+			// 三个都判断
+			r1 := reflect.ValueOf(fb2[i])
+			r2 := reflect.ValueOf(attach2[i])
+			if i == 0 || i == 1 || i == 5 || i == 34 {
+				for _, key_name := range []string{"Fs", "Je", "Se"} {
+					if common.StrToFloat(r1.FieldByName(key_name).String()) != common.StrToFloat(r2.FieldByName(key_name).String()) {
+						status = 2
+						break
+					}
+				}
+			}
+			if status == 2 {
+				break
+			}
+			if i > 11 && i < 23 {
+				if common.StrToFloat(r1.FieldByName("Se").String()) != common.StrToFloat(r2.FieldByName("Se").String()) {
+					status = 2
+					break
+				}
+			}
+			if status == 2 {
+				break
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+func CheckAttach3Cq(fb3 []sb.GsVatAttach3, attach3 []sb.GsVatAttach3) (status int, errLog string) {
+	// 暂时没有校验
+	//return 1, ""
+	status = 1
+	var errLogs []string
+	// 非强制校验
+	{
+		for i := 0; i < len(attach3); i++ {
+			status1 := ForeachStruct(fb3[i], attach3[i])
+			if status != 2 {
+				status = status1
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+func CheckAttach3(fb3 []sb.GsVatAttach3, attach3 []sb.GsVatAttach3) (status int, errLog string) {
+	// 暂时没有校验
+	return 1, ""
+	status = 1
+	var errLogs []string
+	// 非强制校验
+	{
+		for i := 0; i < len(attach3); i++ {
+			status1 := ForeachStruct(fb3[i], attach3[i])
+			if status != 2 {
+				status = status1
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+func CheckAttach4(fb4 []sb.GsVatAttach4, attach4 []sb.GsVatAttach4) (status int, errLog string) {
+	status = 1
+	var errLogs []string
+	// 非强制校验
+	{
+		var KeyName = []string{
+			"Bqsjdjse",
+			"Bqfse",
+			"Bqsjjjdkjxse",
+			"Bqkjjdkjxse",
+			"Qcye",
+		}
+		for i := 0; i < len(attach4); i++ {
+			r1 := reflect.ValueOf(fb4[i])
+			r2 := reflect.ValueOf(attach4[i])
+			for _, key_name := range KeyName {
+				if common.StrToFloat(r1.FieldByName(key_name).String()) != common.StrToFloat(r2.FieldByName(key_name).String()) {
+					status = 2
+					break
+				}
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+func CheckAttach5(fb5 []sb.GsVatAttach5, attach5 []sb.GsVatAttach5) (status int, errLog string) {
+	status = 1
+	// 非强制校验
+	{
+		var KeyNAme = []string{
+			"Zzsse",
+			"Ldtsbqkce",
+			"Bqybtse",
+		}
+		for _, v1 := range attach5 {
+			for _, v2 := range fb5 {
+				if v1.ZsxmDm == v2.ZsxmDm {
+					r1 := reflect.ValueOf(v1)
+					r2 := reflect.ValueOf(v2)
+					for _, key_name := range KeyNAme {
+						if common.StrToFloat(r1.FieldByName(key_name).String()) != common.StrToFloat(r2.FieldByName(key_name).String()) {
+							status = 2
+							break
+						}
+					}
+					if status == 2 {
+						break
+					}
+				}
+			}
+			if status == 2 {
+				break
+			}
+		}
+	}
+	var errLogs []string
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+func CheckJm(jm []sb.GsVatJsxm, Jm []sb.GsVatJsxm) (status int, errLog string) {
+	status = 1
+	var errLogs []string
+	var jsxm1 []sb.GsVatJsxm
+	for _, v := range jm {
+		if v.Type == 1 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			jsxm1 = append(jsxm1, v)
+		}
+	}
+	var ckms1 []sb.GsVatJsxm //出口免税
+	for _, v := range jm {
+		if v.Type == 2 {
+			ckms1 = append(ckms1, v)
+			break
+		}
+	}
+	var kjfw1 []sb.GsVatJsxm //       其中:跨境服务
+	for _, v := range jm {
+		if v.Type == 3 {
+			kjfw1 = append(kjfw1, v)
+			break
+		}
+	}
+	var msxm1 []sb.GsVatJsxm
+	for _, v := range jm {
+		if v.Type == 4 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			msxm1 = append(msxm1, v)
+		}
+	}
+
+	var jsxm2 []sb.GsVatJsxm
+	for _, v := range Jm {
+		if v.Type == 1 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			jsxm2 = append(jsxm2, v)
+		}
+	}
+	var ckms2 []sb.GsVatJsxm //出口免税
+	for _, v := range Jm {
+		if v.Type == 2 {
+			ckms2 = append(ckms2, v)
+			break
+		}
+	}
+	var kjfw2 []sb.GsVatJsxm //       其中:跨境服务
+	for _, v := range Jm {
+		if v.Type == 3 {
+			kjfw2 = append(kjfw2, v)
+			break
+		}
+	}
+	var msxm2 []sb.GsVatJsxm
+	for _, v := range Jm {
+		if v.Type == 4 && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Qmye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0) {
+			msxm2 = append(msxm2, v)
+		}
+	}
+
+	// 非强制校验
+	{
+		// 减税项目
+		if len(jsxm1) != len(jsxm2) {
+			status = 2
+			//errLogs = append(errLogs, fmt.Sprintf("税局减税项目有%d条系统有%d条", len(jsxm1), len(jsxm2)))
+		}
+		for _, v1 := range jsxm1 {
+			find := false
+			for _, v2 := range jsxm2 {
+				if v1.SbJmxzdmJmHm == v2.SbJmxzdmJmHm {
+					find = true
+					if common.StrToFloat(v1.Qcye) == common.StrToFloat(v2.Qcye) && common.StrToFloat(v1.Qmye) == common.StrToFloat(v2.Qmye) && common.StrToFloat(v1.Bqfse) == common.StrToFloat(v2.Bqfse) && common.StrToFloat(v1.Bqydjse) == common.StrToFloat(v2.Bqydjse) {
+						status = 1
+					} else {
+						status = 2
+					}
+					break
+				}
+
+			}
+			if !find {
+				status = 2
+				//errLogs = append(errLogs, fmt.Sprintf("税局减税项目:%s 为在系统中找到,请核实", len(jsxm1), len(jsxm2)))
+			}
+		}
+		// 出口
+		if common.StrToFloat(ckms1[0].Qcye) != common.StrToFloat(ckms2[0].Qcye) {
+			status = 2
+		}
+
+		// 跨境
+		if (len(kjfw1) == len(kjfw2)) && len(kjfw1) > 0 && len(kjfw2) > 0 {
+			if common.StrToFloat(kjfw1[0].Qcye) != common.StrToFloat(kjfw2[0].Qcye) {
+				status = 2
+			}
+		}
+		// 免税项目
+		if len(msxm1) != len(msxm2) {
+			status = 2
+			//errLogs = append(errLogs, fmt.Sprintf("税局免税项目有%d条系统有%d条", len(msxm1), len(msxm2)))
+		}
+		for _, v1 := range msxm1 {
+			find := false
+			for _, v2 := range msxm2 {
+				if v1.SbJmxzdmJmHm == v2.SbJmxzdmJmHm {
+					find = true
+					if common.StrToFloat(v1.Qcye) == common.StrToFloat(v2.Qcye) && common.StrToFloat(v1.Qmye) == common.StrToFloat(v2.Qmye) && common.StrToFloat(v1.Bqfse) == common.StrToFloat(v2.Bqfse) && common.StrToFloat(v1.Bqydjse) == common.StrToFloat(v2.Bqydjse) {
+						if status != 2 {
+							status = 1
+						}
+					} else {
+						status = 2
+					}
+					break
+				}
+
+			}
+			if !find {
+				status = 2
+				//errLogs = append(errLogs, fmt.Sprintf("税局免税项目:%s 为在系统中找到,请核实", len(jsxm1), len(jsxm2)))
+			}
+		}
+	}
+	if len(errLogs) > 0 {
+		status = 3
+		errLog = strings.Join(errLogs, ",")
+	}
+	return status, errLog
+}
+
+// 对比结构体数据
+func ForeachStruct(obj1 interface{}, obj2 interface{}) (status int) {
+	status = 1
+	t1 := reflect.TypeOf(obj1)
+	v1 := reflect.ValueOf(obj1)
+	t2 := reflect.TypeOf(obj2)
+	v2 := reflect.ValueOf(obj2)
+	for k := 0; k < t1.NumField(); k++ {
+		KeyName := t1.Field(k).Name
+		if KeyName == "GsMainId" || KeyName == "ID" || KeyName == "GsBaseModel" || KeyName == "Type" || KeyName == "JmxzdmId" || KeyName == "JmxzdmSb" {
+			continue
+		}
+		//fmt.Println(KeyName)
+		Value := common.StrToFloat(v1.Field(k).Interface().(string))
+		for j := 0; j < t2.NumField(); j++ {
+			if KeyName == t2.Field(j).Name {
+				if Value != common.StrToFloat(v2.Field(j).Interface().(string)) {
+					logger.Info(KeyName, "-对比失败[税局为:", Value, "系统为:", common.StrToFloat(v2.Field(j).Interface().(string)), "]")
+					status = 2
+				}
+				break
+			}
+		}
+	}
+	return status
+}
+
+// str:错误内容 data1税局数据 data2系统数据
+func MakeMsg(str, data1, data2 string) string {
+	return fmt.Sprintf(str+"数据对比失败:[税局为:%s;系统为:%s;]", data1, data2)
+}
+
+// 校验减免明细有数 但是没有代码的
+func CheckJmDm(all []sb.GsVatJsxm) error {
+	for _, v := range all {
+		if v.Type != 2 && v.Type != 3 {
+			if v.SbJmxzdmJmDm == "" && v.SbJmxzdmJmHm == "" && (common.StrToFloat(v.Qcye) != 0 || common.StrToFloat(v.Bqfse) != 0 || common.StrToFloat(v.Bqydjse) != 0 || common.StrToFloat(v.Bqsjdjse) != 0 || common.StrToFloat(v.Qmye) != 0) {
+				return taxerr.NewUserV3("存在未填写减免代码的减免项目", "请手动补充后重试")
+			}
+		}
+	}
+	return nil
+}
+
+/*
+逻辑:
+	1.读取发票后采集6张表 生成和系统数据一样的结构体并且除减免表外的其他表机构提数组长度务必相等
+	2.调用上面方法对比每个表 errLog为强制校验
+	3.
+		当所有表对比后返回的状态都是status=1时 直接申报即可
+		当某张表对比后返回status=2时 所有表按系统数据重填神申报
+		当某张表对比后返回status=3时 直接返回错误 taxerr.NewUser(errlog)
+注意点:
+	1.附表一按行采集完22行后 单独把第三行插到23行中
+	2.附表二按系统顺序采集!!!!!!可以看河南内蒙的申报填表注释代码
+	3.当所有表校验完status!=3后再去判断有一个表status=2就需要重新填所有表
+	4.当所有表校验完status=1才能直接点击申报
+传入参数:
+	第一个参数是税局采集的数据
+	第二个参数是任务的数据
+返回参数:
+	status:
+		1 当前表所有数据校验通过
+		2 当前表普通检验不通过 应根据系统的数据填写到报表上
+		3 当前表强之校验不通过 直接返回errLog的错误
+	errLog:
+		目前只返回强制校验错误提示
+*/

+ 28 - 0
common/models/declare.go

@@ -0,0 +1,28 @@
+package models
+
+import "time"
+
+type GsVatFjs struct {
+	ID        uint      `json:"id" gorm:"primary_key"`
+	CreatedAt time.Time `json:"createdAt"`
+	UpdatedAt time.Time `json:"updatedAt"`
+	GsMainID  uint      `json:"gsMainId"` // 增值税主表
+
+	ZsxmDm    string `json:"zsxmDm"`
+	Zzsse     string `json:"zzsse"`
+	Zzsxejmje string `json:"zzsxejmje"`
+	Zzsmdse   string `json:"zzsmdse"`
+	Ldtsbqkce string `json:"ldtsbqkce"`
+	Sl        string `json:"sl"`
+	Bqynse    string `json:"bqynse"`
+	Jmxzdm    string `json:"jmxzdm"`
+	Jmse      string `json:"jmse"`
+	LslfJzbl  string `json:"lslfJzbl"`
+	LslfJze   string `json:"lslfJze"`
+	SdJmxzdm  string `json:"sdJmxzdm"`
+	Bqdmje    string `json:"bqdmje"`
+	Jzbl      string `json:"jzbl"`
+	Jze       string `json:"jze"`
+	Bqyjse    string `json:"bqyjse"`
+	Bqybtse   string `json:"bqybtse"`
+}

+ 1 - 0
common/models/task.go

@@ -22,6 +22,7 @@ type Result struct {
 	Data           any                 `json:"data"`           //采集的数据
 	RobotName      string              `json:"robotName"`      // 执行的机器人名称
 	CwbbDb         bool                // 财报代办已申报过
+	SkipNb         bool                // 年报的税种都可以设置这个跳过检查 防止提前申报查不到
 }
 
 type TaxTask struct {

+ 45 - 4
common/period.go

@@ -4,6 +4,7 @@ import (
 	"errors"
 	"fmt"
 	"git.listensoft.net/tool/jspkit/logger"
+	"github.com/go-rod/rod"
 	"math"
 	"strconv"
 	"strings"
@@ -188,8 +189,8 @@ func GetLastDay(period string) time.Time {
 	loc, _ := time.LoadLocation("Local")                            //重要:获取时区
 	theTime, _ := time.ParseInLocation(timeLayout, toBeCharge, loc) //使用模板在对应时区转化为time.time类型
 	sr := theTime.Unix()                                            //转化为时间戳 类型是int64
-	//zaplog.LoggerS.Info(theTime)                                            //打印输出theTime 2015-01-01 15:15:00 +0800 CST
-	//zaplog.LoggerS.Info(sr)                                                 //打印输出时间戳 1420041600
+	//logger.Info(theTime)                                            //打印输出theTime 2015-01-01 15:15:00 +0800 CST
+	//logger.Info(sr)                                                 //打印输出时间戳 1420041600
 
 	tm := time.Unix(sr, 0)
 	currentYear, currentMonth, _ := tm.Date()
@@ -209,8 +210,8 @@ func GetFirstDay(period string) time.Time {
 	loc, _ := time.LoadLocation("Local")                            //重要:获取时区
 	theTime, _ := time.ParseInLocation(timeLayout, toBeCharge, loc) //使用模板在对应时区转化为time.time类型
 	sr := theTime.Unix()                                            //转化为时间戳 类型是int64
-	//zaplog.LoggerS.Info(theTime)                                            //打印输出theTime 2015-01-01 15:15:00 +0800 CST
-	//zaplog.LoggerS.Info(sr)                                                 //打印输出时间戳 1420041600
+	//logger.Info(theTime)                                            //打印输出theTime 2015-01-01 15:15:00 +0800 CST
+	//logger.Info(sr)                                                 //打印输出时间戳 1420041600
 
 	tm := time.Unix(sr, 0)
 	currentYear, currentMonth, _ := tm.Date()
@@ -314,3 +315,43 @@ func DateFormatter(date string) string {
 func GetNextDateTime(d time.Time) time.Time {
 	return time.Date(d.Year(), d.Month(), d.Day()+1, 0, 0, 0, 0, d.Location())
 }
+
+// 获取去年的第一天和最后一天
+func GetLastYearFirstTimeAndEndTime() (string, string) {
+	now := time.Now()
+	logger.Info(now)
+	currentYear, _, _ := now.Date()
+	currentLocation := now.Location()
+	logger.Info(currentLocation)
+	firstOfYear := time.Date(currentYear-1, time.January, 1, 0, 0, 0, 0, currentLocation)
+	lastOfYear := firstOfYear.AddDate(1, 0, -1)
+	return firstOfYear.Format("2006-01-02"), lastOfYear.Format("2006-01-02")
+}
+
+// 获取今年的第一天和最后一天
+func GetCurrentYearFirstTimeAndEndTime() (string, string) {
+	now := time.Now()
+	logger.Info(now)
+	currentYear, _, _ := now.Date()
+	currentLocation := now.Location()
+	logger.Info(currentLocation)
+	firstOfYear := time.Date(currentYear, time.January, 1, 0, 0, 0, 0, currentLocation)
+	lastOfYear := firstOfYear.AddDate(1, 0, -1)
+	return firstOfYear.Format("2006-01-02"), lastOfYear.Format("2006-01-02")
+}
+
+// 获取上个月的最后一天
+func GetLastMonthLastDate() string {
+	now := time.Now()
+	firstOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.Local)
+	return firstOfMonth.AddDate(0, 0, -1).Format(`2006-01-02`)
+}
+
+// GetLastYear 获取上一年 202210 => 2021
+func GetLastYear() string {
+	now := time.Now()
+	return now.AddDate(-1, 0, 0).Format(`2006`)
+}
+func WaitElementX5(page *rod.Page, xpath string) *rod.Element {
+	return WaitElementXFoTimes(page, xpath, 5)
+}

+ 30 - 0
common/rod_utils.go

@@ -535,3 +535,33 @@ func MustElementsX10(page *rod.Page, xpath string) (x []*rod.Element) {
 	}
 	return x
 }
+
+func WaitMustElementsX(page *rod.Page, xpath string) (elementsX []*rod.Element) {
+	for i := 0; i < 5; i++ {
+		elementsX = MustElementsX(page, xpath)
+		if len(elementsX) != 0 {
+			return
+		}
+		utils.Sleep(1)
+	}
+	return
+}
+func ClickB(page *rod.Page, el string) {
+	box := MustElementX(page, el).MustShape().Box()
+	Click(page, box.X+(box.Width/2), box.Y+(box.Height/2))
+}
+
+func WaitElementX10(page *rod.Page, xpath string) *rod.Element {
+	return WaitElementXFoTimes(page, xpath, 10)
+}
+
+func MustElementX30(page *rod.Page, xpath string) *rod.Element {
+	for i := 0; i < 30; i++ {
+		x, _ := ElementX(page, xpath)
+		if x != nil {
+			return x
+		}
+		utils.Sleep(1)
+	}
+	return nil
+}

+ 162 - 0
common/utils.go

@@ -1,18 +1,24 @@
 package common
 
 import (
+	"bytes"
 	"crypto/md5"
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
 	"git.listensoft.net/tool/jspkit/common/lxhttp"
+	"git.listensoft.net/tool/jspkit/common/models"
 	"git.listensoft.net/tool/jspkit/common/variable"
 	"git.listensoft.net/tool/jspkit/logger"
 	"git.listensoft.net/tool/jspkit/taxerr"
 	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-rod/rod"
+	"github.com/go-rod/rod/lib/input"
+	"github.com/go-rod/rod/lib/utils"
 	"github.com/tidwall/gjson"
 	"io"
 	"math/rand"
+	"net/http"
 	"net/url"
 	"os"
 	"reflect"
@@ -261,3 +267,159 @@ func RandSeq(n int) string {
 	}
 	return string(b)
 }
+
+func SwitchCwbb(baseCwbb, targetCwbb variable.Kjze, basezcfz []models.KjZcfz, baseLrb []models.KjLrb) (zcfz []models.KjZcfz, lrb []models.KjLrb, err error) {
+	uri := `https://daizhang.jsptax.com/api/public/kjzzConvert`
+	payload := map[string]interface{}{
+		"oldKjzz":  string(baseCwbb),
+		"newKjzz":  string(targetCwbb),
+		"dataLrb":  baseLrb,
+		"dataZcfz": basezcfz,
+	}
+	data, _ := json.Marshal(payload)
+	p := "./data/kjzzConvert" + GetTimestamp(13) + ".json"
+	if !PathExists("pdf" + string(p)) {
+		os.MkdirAll("pdf"+string(p), os.ModePerm)
+	}
+	logger.Info(p)
+	_ = utils.OutputFile(p, data)
+	req, err := http.NewRequest("POST", uri, bytes.NewReader(data))
+
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	req.Header.Add("Content-Type", "application/json")
+	client := &http.Client{}
+	res, err := client.Do(req)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	defer res.Body.Close()
+
+	body, err := io.ReadAll(res.Body)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	if gjson.GetBytes(body, "msg").String() != "success" {
+		return nil, nil, taxerr.NewUserV3(gjson.GetBytes(body, "msg").String(), "请核实")
+	}
+	_ = json.Unmarshal([]byte(gjson.GetBytes(body, "data.lrb").String()), &lrb)
+	_ = json.Unmarshal([]byte(gjson.GetBytes(body, "data.zcfz").String()), &zcfz)
+	return
+}
+
+// 获取省份
+func GetProvince(url string) string {
+	if strings.Contains(url, "sichuan") {
+		return "四川省"
+	} else if strings.Contains(url, "beijing") {
+		return "北京市"
+	} else if strings.Contains(url, "tianjin") {
+		return "天津市"
+	} else if strings.Contains(url, "hebei") {
+		return "河北省"
+	} else if strings.Contains(url, "shanxi") {
+		return "山西省"
+	} else if strings.Contains(url, "neimenggu") {
+		return "内蒙古自治区"
+	} else if strings.Contains(url, "liaoning") {
+		return "辽宁省"
+	} else if strings.Contains(url, "dalian") {
+		return "大连市"
+	} else if strings.Contains(url, "jilin") {
+		return "吉林省"
+	} else if strings.Contains(url, "heilongjiang") {
+		return "黑龙江省"
+	} else if strings.Contains(url, "shanghai") {
+		return "上海市"
+	} else if strings.Contains(url, "jiangsu") {
+		return "江苏省"
+	} else if strings.Contains(url, "zhejiang") {
+		return "浙江省"
+	} else if strings.Contains(url, "ningbo") {
+		return "宁波市"
+	} else if strings.Contains(url, "anhui") {
+		return "安徽省"
+	} else if strings.Contains(url, "fujian") {
+		return "福建省"
+	} else if strings.Contains(url, "xiamen") {
+		return "厦门市"
+	} else if strings.Contains(url, "jiangxi") {
+		return "江西省"
+	} else if strings.Contains(url, "shandong") {
+		return "山东省"
+	} else if strings.Contains(url, "qingdao") {
+		return "青岛市"
+	} else if strings.Contains(url, "henan") {
+		return "河南省"
+	} else if strings.Contains(url, "hubei") {
+		return "湖北省"
+	} else if strings.Contains(url, "hunan") {
+		return "湖南省"
+	} else if strings.Contains(url, "guangdong") {
+		return "广东省"
+	} else if strings.Contains(url, "shenzhen") {
+		return "深圳市"
+	} else if strings.Contains(url, "guangxi") {
+		return "广西壮族自治区"
+	} else if strings.Contains(url, "hainan") {
+		return "海南省"
+	} else if strings.Contains(url, "chongqing") {
+		return "重庆市"
+	} else if strings.Contains(url, "guizhou") {
+		return "贵州省"
+	} else if strings.Contains(url, "yunnan") {
+		return "云南省"
+	} else if strings.Contains(url, "xizang") {
+		return "西藏自治区"
+	} else if strings.Contains(url, "shaanxi") {
+		return "陕西省"
+	} else if strings.Contains(url, "gansu") {
+		return "甘肃省"
+	} else if strings.Contains(url, "qinghai") {
+		return "青海省"
+	} else if strings.Contains(url, "ningxia") {
+		return "宁夏回族自治区"
+	} else if strings.Contains(url, "xinjiang") {
+		return "新疆维吾尔自治区"
+	} else if strings.Contains(url, "taiwan") {
+		return "台湾省"
+	} else {
+		return ""
+	}
+}
+
+// 输入文字
+func InputX(p *rod.Page, xPath, inputVal string) {
+	err := rod.Try(func() {
+		if inputVal == "" {
+			inputVal = "0"
+		}
+		_ = rod.Try(func() {
+			elementX := MustElementX(p, xPath)
+			disabled := elementX.MustAttribute(`disabled`)
+			if disabled == nil {
+				elementX.MustType(input.Backspace)
+				elementX.MustSelectAllText().MustInput(inputVal)
+			}
+		})
+	})
+	if err != nil {
+		logger.Info(err.Error() + "-" + xPath + "-" + inputVal)
+	}
+}
+
+// 校验填写的对不对
+func CheckInput(p *rod.Page, xPath, inputVal string, name string) (errMsg string) {
+	if inputVal == "" {
+		inputVal = "0"
+	}
+	val := GetInputValue(p, xPath)
+	if StrToFloat(val) != StrToFloat(inputVal) {
+		errMsg = fmt.Sprintf("%s不一致,税局:%s,系统:%s;", name, val, inputVal)
+	}
+	return
+}