invoiceMake.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. package service
  2. import (
  3. "ElectronicInvoice/internal/consts"
  4. "context"
  5. "fmt"
  6. "github.com/gogf/gf/v2/database/gdb"
  7. "github.com/gogf/gf/v2/errors/gerror"
  8. "github.com/gogf/gf/v2/frame/g"
  9. "github.com/gogf/gf/v2/util/gconv"
  10. "strconv"
  11. "strings"
  12. "time"
  13. )
  14. // simpleMakeInvoice 简单开票(包含一个订单开多张票)
  15. func (im *InvoiceManager) simpleMakeInvoice(ctx context.Context) (total, okNum int, end bool, err error) {
  16. var (
  17. res gdb.Result
  18. )
  19. //查询需要开票的数据
  20. //(新开发票【a.invoice_status=0 AND a.invoice_changed=0】,红冲后新开【a.invoice_status=2 AND a.invoice_changed=1】)
  21. //线上申请发票【invoice_order_code is null 】, 管理后台一个订单拆分多个发票【invoice_order_code not like '%,%'】
  22. res, err = g.DB().Query(ctx, "SELECT a.*,b.pay_money FROM invoice a INNER JOIN dataexport_order b ON a.order_code=b.order_code WHERE a.invoice_variety like '%电子%' AND ((a.invoice_status=0 AND a.invoice_changed=0) or (a.invoice_status=2 AND a.invoice_changed=1 )) AND (a.invoice_order_code is NULL OR a.invoice_order_code not like '%,%') AND a.create_time > ? ", consts.InvoiceStartTime.Unix())
  23. if err != nil {
  24. err = gerror.Wrap(err, "simpleMakeInvoice-查询待开票异常")
  25. return
  26. }
  27. total, okNum = res.Len(), 0
  28. for _, m := range res.List() {
  29. select {
  30. case im.RunPool <- true:
  31. case <-time.After(time.Minute * 5):
  32. err = gerror.Wrap(consts.WaitTimeOut, "simpleMakeInvoice-开票等待超时")
  33. return
  34. }
  35. var (
  36. iType = gconv.String(m["invoice_type"])
  37. remark = gconv.String(m["remark"])
  38. invoiceVariety = gconv.String(m["invoice_variety"])
  39. invoiceContent = gconv.String(m["invoice_content"])
  40. prices = gconv.Float64(m["invoice_money"]) / float64(100)
  41. id = gconv.Int64(m["id"])
  42. )
  43. if prices == 0 { //开票金额为空,取支付金额
  44. prices = gconv.Float64(m["pay_money"]) / float64(100)
  45. }
  46. c := MakeInvoiceData{
  47. Type: "2",
  48. Id: fmt.Sprintf("id:%d", id), //因为orderCode不唯一,此处禁止使用orderCode
  49. Notes: remark,
  50. Lxdh: gconv.String(m["company_phone"]),
  51. Fhr: g.Cfg().MustGet(ctx, "company.hfr", "贺鹏飞").String(),
  52. Xsfkhh: g.Cfg().MustGet(ctx, "company.bank", "").String(),
  53. Xsfyhzh: g.Cfg().MustGet(ctx, "company.bankNum", "").String(),
  54. InvoiceArr: []MakeInvoiceItems{{
  55. Xmmc: consts.GetTaxCodeByName(invoiceContent), //开票项
  56. WhStatus: 1, //开票项是否维护
  57. Je: strconv.FormatFloat(prices, 'f', -1, 64), //金额
  58. Sl: "1", //数量
  59. }},
  60. }
  61. // 1 增值税专用发票;2 普通发票
  62. if strings.Contains(invoiceVariety, "专用") {
  63. c.Type = "1"
  64. }
  65. if iType == "单位" {
  66. c.Gmfmc = gconv.String(m["company_name"])
  67. c.Gmfnsrsbh = gconv.String(m["taxpayer_identnum"])
  68. c.Gmfdz = gconv.String(m["company_address"]) //"购买方地址"
  69. c.Yhyywdmc = gconv.String(m["bank_name"]) //"购买方开户行"
  70. c.Yhzh = gconv.String(m["bank_account"]) //"购买方银行账号"
  71. } else {
  72. c.Gmfmc = iType
  73. }
  74. err = im.Auth.MakeSingleInvoice(c)
  75. if err != nil {
  76. select {
  77. case <-im.RunPool:
  78. case <-time.After(time.Second * 5):
  79. }
  80. if gerror.Is(err, consts.LoginOutErr) {
  81. end = true
  82. g.Log().Infof(ctx, "simpleMakeInvoice-身份过期,需要重新登录")
  83. return
  84. } else if strings.Contains(err.Error(), "税号有误") { //发票状态改为-1
  85. invoiceErr(ctx, g.Map{"id": id})
  86. g.Log().Infof(ctx, "simpleMakeInvoice-开票异常-税号异常")
  87. } else {
  88. g.Log().Errorf(ctx, "simpleMakeInvoice-开票接口调用异常 %v", err)
  89. }
  90. } else {
  91. okNum++
  92. }
  93. }
  94. return
  95. }
  96. // multipleOrdersMakeInvoice 联合开票(多个订单开一张发票)
  97. func (im *InvoiceManager) multipleOrdersMakeInvoice(ctx context.Context) (total, okNum int, end bool, err error) {
  98. var (
  99. res gdb.Result
  100. )
  101. //(新开发票【a.invoice_status=0 AND a.invoice_changed=0】,红冲后新开【a.invoice_status=2 AND a.invoice_changed=1】)
  102. res, err = g.DB().Query(ctx, "SELECT a.only_Identifying,a.invoice_type,a.remark,a.invoice_variety,a.taxpayer_identnum,a.company_name,a.invoice_content,a.invoice_money,a.company_address,a.phone,a.bank_account,a.bank_name FROM invoice a WHERE a.invoice_variety like '%电子%' AND ((a.invoice_status=0 AND a.invoice_changed=0) or (a.invoice_status=2 AND a.invoice_changed=1)) AND a.invoice_order_code like '%,%' AND a.create_time > ? GROUP BY only_Identifying", consts.InvoiceStartTime.Unix())
  103. if err != nil {
  104. err = gerror.Wrap(err, "multipleOrdersMakeInvoice-查询待开票异常")
  105. return
  106. }
  107. total, okNum = res.Len(), 0
  108. for _, m := range res.List() {
  109. select {
  110. case im.RunPool <- true:
  111. case <-time.After(time.Minute * 5):
  112. err = gerror.Wrap(consts.WaitTimeOut, "multipleOrdersMakeInvoice-开票等待超时")
  113. return
  114. }
  115. var (
  116. onlyIdentifying = gconv.String(m["only_Identifying"])
  117. iType = gconv.String(m["invoice_type"])
  118. prices = gconv.Float64(m["invoice_money"]) / float64(100)
  119. remark = gconv.String(m["remark"])
  120. invoiceVariety = gconv.String(m["invoice_variety"])
  121. invoiceContent = gconv.String(m["invoice_content"])
  122. )
  123. if onlyIdentifying == "" {
  124. continue
  125. }
  126. c := MakeInvoiceData{
  127. Type: "2",
  128. Id: fmt.Sprintf("only_Identifying:%s", onlyIdentifying),
  129. Notes: remark,
  130. Lxdh: gconv.String(m["company_phone"]),
  131. Fhr: g.Cfg().MustGet(ctx, "company.hfr", "贺鹏飞").String(),
  132. Xsfkhh: g.Cfg().MustGet(ctx, "company.bank", "").String(),
  133. Xsfyhzh: g.Cfg().MustGet(ctx, "company.bankNum", "").String(),
  134. InvoiceArr: []MakeInvoiceItems{{
  135. Xmmc: consts.GetTaxCodeByName(invoiceContent), //开票项
  136. WhStatus: 1, //开票项是否维护
  137. Je: strconv.FormatFloat(prices, 'f', -1, 64), //金额
  138. Sl: "1", //数量
  139. }},
  140. }
  141. // 1 增值税专用发票;2 普通发票
  142. if strings.Contains(invoiceVariety, "专用") {
  143. c.Type = "1"
  144. }
  145. if iType == "单位" {
  146. c.Gmfmc = gconv.String(m["company_name"])
  147. c.Gmfnsrsbh = gconv.String(m["taxpayer_identnum"])
  148. c.Gmfdz = gconv.String(m["company_address"]) //"购买方地址"
  149. c.Yhyywdmc = gconv.String(m["bank_name"]) //"购买方开户行"
  150. c.Yhzh = gconv.String(m["bank_account"]) //"购买方银行账号"
  151. } else {
  152. c.Gmfmc = iType
  153. }
  154. err = im.Auth.MakeSingleInvoice(c)
  155. if err != nil {
  156. select {
  157. case <-im.RunPool:
  158. case <-time.After(time.Second * 5):
  159. }
  160. if gerror.Is(err, consts.LoginOutErr) {
  161. g.Log().Infof(ctx, "multipleOrdersMakeInvoice-身份过期,需要重新登录")
  162. end = true
  163. return
  164. } else if strings.Contains(err.Error(), "税号有误") { //发票状态改为-1
  165. invoiceErr(ctx, g.Map{"only_Identifying": onlyIdentifying})
  166. g.Log().Infof(ctx, "multipleOrdersMakeInvoice-开票异常-税号异常")
  167. } else {
  168. g.Log().Errorf(ctx, "multipleOrdersMakeInvoice-开票接口调用异常 %v", err)
  169. }
  170. } else {
  171. okNum++
  172. }
  173. }
  174. return
  175. }
  176. // makeRedInvoice 单票红冲(包含一个订单开多张票)
  177. func (im *InvoiceManager) makeRedInvoice(ctx context.Context) (total, okNum int, end bool, err error) {
  178. var (
  179. res gdb.Result
  180. )
  181. //冲红任务
  182. res, err = g.DB().Query(ctx, "SELECT invoice_number,billing_time FROM invoice a WHERE a.invoice_variety like '%电子%' AND a.invoice_status=0 AND a.invoice_changed=1 AND (a.invoice_order_code is NULL OR a.invoice_order_code not like '%,%') AND a.create_time > ? ", consts.InvoiceStartTime.Unix())
  183. if err != nil {
  184. err = gerror.Wrap(err, "makeRedInvoice-查询待冲红订单异常")
  185. return
  186. }
  187. total, okNum = res.Len(), 0
  188. for _, m := range res.List() {
  189. select {
  190. case im.RunPool <- true:
  191. case <-time.After(time.Minute * 5):
  192. err = gerror.Wrap(consts.WaitTimeOut, "makeRedInvoice-开票等待超时")
  193. return
  194. }
  195. var (
  196. invoiceNumber = gconv.String(m["invoice_number"])
  197. invoiceDate = time.Unix(gconv.Int64(m["billing_time"]), 0)
  198. )
  199. err = im.Auth.MakeSingleRedInvoice(MakeRedInvoiceData{
  200. Num: invoiceNumber,
  201. Date: invoiceDate.Format(consts.DateFormat_Short),
  202. })
  203. if err != nil {
  204. select {
  205. case <-im.RunPool:
  206. case <-time.After(time.Second * 5):
  207. }
  208. if gerror.Is(err, consts.LoginOutErr) {
  209. g.Log().Infof(ctx, "makeRedInvoice-身份过期,需要重新登录")
  210. end = true
  211. return
  212. }
  213. } else {
  214. okNum++
  215. }
  216. }
  217. return
  218. }
  219. // multipleOrdersMakeRedInvoice 联合开票红冲(多个订单开一张发票)
  220. func (im *InvoiceManager) multipleOrdersMakeRedInvoice(ctx context.Context) (total, okNum int, end bool, err error) {
  221. var (
  222. res gdb.Result
  223. )
  224. //冲红任务
  225. res, err = g.DB().Query(ctx, "SELECT invoice_number,billing_time FROM invoice a WHERE a.invoice_variety like '%电子%' AND a.invoice_status=0 AND a.invoice_changed=1 AND a.invoice_order_code like '%,%' AND a.create_time > ? GROUP BY only_Identifying", consts.InvoiceStartTime.Unix())
  226. if err != nil {
  227. err = gerror.Wrap(err, "multipleOrdersMakeRedInvoice-查询待冲红订单异常")
  228. return
  229. }
  230. total, okNum = res.Len(), 0
  231. for _, m := range res.List() {
  232. select {
  233. case im.RunPool <- true:
  234. case <-time.After(time.Minute * 5):
  235. err = gerror.Wrap(consts.WaitTimeOut, "multipleOrdersMakeRedInvoice-开票等待超时")
  236. return
  237. }
  238. var (
  239. invoiceNumber = gconv.String(m["invoice_number"])
  240. invoiceDate = time.Unix(gconv.Int64(m["billing_time"]), 0)
  241. )
  242. err = im.Auth.MakeSingleRedInvoice(MakeRedInvoiceData{
  243. Num: invoiceNumber,
  244. Date: invoiceDate.Format(consts.DateFormat_Short),
  245. })
  246. if err != nil {
  247. select {
  248. case <-im.RunPool:
  249. case <-time.After(time.Second * 5):
  250. }
  251. if gerror.Is(err, consts.LoginOutErr) {
  252. g.Log().Infof(ctx, "multipleOrdersMakeRedInvoice-身份过期,需要重新登录")
  253. end = true
  254. return
  255. }
  256. } else {
  257. okNum++
  258. }
  259. }
  260. return
  261. }
  262. // invoiceErr 开票异常
  263. func invoiceErr(ctx context.Context, query map[string]interface{}) {
  264. _, err := g.DB().Update(ctx, "invoice", g.Map{
  265. "invoice_status": -1,
  266. }, query)
  267. if err != nil {
  268. g.Log().Errorf(ctx, "更改开票失败-状态异常 %+v", query)
  269. }
  270. }