fapiao_controller.go 35KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. package controllers
  2. import (
  3. "XT_New/common"
  4. "XT_New/enums"
  5. "XT_New/invoice"
  6. "XT_New/models"
  7. "XT_New/service"
  8. "XT_New/service/fapiao"
  9. "XT_New/utils"
  10. "encoding/base64"
  11. "encoding/json"
  12. "fmt"
  13. "github.com/astaxie/beego"
  14. "github.com/shopspring/decimal"
  15. "math"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. func FaPiaoApiRegistRouters() {
  21. beego.Router("/api/fapiao/sms/code", &FapiaoApiController{}, "get:GetLoginUploadCode")
  22. beego.Router("/api/fapiao/sms/login", &FapiaoApiController{}, "get:Login")
  23. beego.Router("/api/fapiao/qrcode/get", &FapiaoApiController{}, "get:GetQRCode")
  24. beego.Router("/api/fapiao/blue", &FapiaoApiController{}, "get:OpenFaPiao")
  25. beego.Router("/api/fapiao/red", &FapiaoApiController{}, "get:RedFaPiao")
  26. beego.Router("/api/order/fapiao/list", &FapiaoApiController{}, "get:GetOrderFaPiaoList")
  27. beego.Router("/api/gdfapiao/list", &FapiaoApiController{}, "get:GetFaPiaoList")
  28. }
  29. type FapiaoApiController struct {
  30. BaseAuthAPIController
  31. }
  32. type InvoiceRequest struct {
  33. SellerName string `json:"seller_name,omitempty"` // 销方名称
  34. SellerTaxpayerNum string `json:"seller_taxpayer_num"` // 销方纳税人识别号
  35. SellerAddress string `json:"seller_address"` // 销方地址
  36. SellerTel string `json:"seller_tel"` // 销方电话
  37. SellerBankName string `json:"seller_bank_name"` // 销方银行名称
  38. SellerBankAccount string `json:"seller_bank_account"` // 销方银行账号
  39. TitleType int `json:"title_type"` // 抬头类型:1 个人、政府事业单位;2 企业
  40. BuyerTitle string `json:"buyer_title"` // 购方名称
  41. BuyerTaxpayerNum string `json:"buyer_taxpayer_num,omitempty"` // 购方纳税人识别号
  42. BuyerAddress string `json:"buyer_address,omitempty"` // 购方地址
  43. BuyerPhone string `json:"buyer_phone,omitempty"` // 购方电话
  44. BuyerBankName string `json:"buyer_bank_name,omitempty"` // 购方银行名称
  45. BuyerBankAccount string `json:"buyer_bank_account,omitempty"` // 购方银行账号
  46. BuyerEmail string `json:"buyer_email,omitempty"` // 收票人邮箱
  47. OrderID string `json:"order_id"` // 商户订单号
  48. InvoiceTypeCode string `json:"invoice_type_code,omitempty"` // 开具发票类型
  49. CallbackURL string `json:"callback_url"` // 发票结果回传地址
  50. Drawer string `json:"drawer"` // 开票人姓名
  51. Payee string `json:"payee,omitempty"` // 收款人姓名
  52. Checker string `json:"checker,omitempty"` // 复核人姓名
  53. TerminalCode string `json:"terminal_code"` // 税盘号
  54. UserOpenID string `json:"user_openid,omitempty"` // 商家用户标识
  55. SpecialInvoiceKind string `json:"special_invoice_kind,omitempty"` // 特殊票种标识
  56. AmountHasTax string `json:"amount_has_tax"` // 含税总金额
  57. TaxAmount string `json:"tax_amount"` // 总税额
  58. AmountWithoutTax string `json:"amount_without_tax"` // 不含税总金额
  59. Remark string `json:"remark,omitempty"` // 备注
  60. StoreNo string `json:"store_no,omitempty"` // 门店编码
  61. Template int `json:"template"` // 发票模板
  62. Info *InvoiceInfo `json:"info,omitempty"` // 冠名票信息
  63. TaxpayerConfirmation *TaxpayerConfirmation `json:"taxpayer_confirmation,omitempty"` // 纳税人确认信息
  64. SpecificBusinessCode string `json:"specific_business_code,omitempty"` // 特定业务代码
  65. RealStaticRent *RealStaticRent `json:"real_static_rent,omitempty"` // 不动产经营租赁信息
  66. PassengerTransport []PassengerTransport `json:"passenger_transport,omitempty"` // 旅客运输信息
  67. GoodsTransport []GoodsTransport `json:"goods_transport,omitempty"` // 货物运输信息
  68. AgriculturalPurchase *AgriculturalPurchase `json:"agricultural_purchase,omitempty"` // 农产品收购信息
  69. BuildingService *BuildingService `json:"building_service,omitempty"` // 建筑服务信息
  70. RealStaticSales *RealStaticSales `json:"real_static_sales,omitempty"` // 不动产销售信息
  71. TractorCombine *TractorCombine `json:"tractor_combine,omitempty"` // 拖拉机与联合收割机信息
  72. UsedCarService *UsedCarService `json:"used_car_service,omitempty"` // 二手车服务信息
  73. UsedCarSell *UsedCarSell `json:"used_car_sell,omitempty"` // 二手车销售信息
  74. DeductionService *DeductionService `json:"deduction_service,omitempty"` // 差额征税信息
  75. Items []Item `json:"items"` // 项目商品明细
  76. }
  77. type InvoiceInfo struct {
  78. UseDate string `json:"use_date,omitempty"` // 入园日期
  79. TicketName string `json:"ticket_name,omitempty"` // 票据名称
  80. }
  81. type TaxpayerConfirmation struct {
  82. RenewableResourceRecyclingFlag int `json:"renewable_resource_recycling_flag,omitempty"` // 再生资源回收单位标志
  83. DrawWithNoBuyerFlag int `json:"draw_with_nobuyer_flag,omitempty"` // 无购买方纳税人信息继续开票标志
  84. NotDutyFreeReason string `json:"not_dutyfree_reason,omitempty"` // 放弃享受减按1%征收率原因
  85. }
  86. type RealStaticRent struct {
  87. PropertyNum string `json:"property_num"` // 房屋产权证号
  88. Location string `json:"location"` // 不动产地址 (省市区县)
  89. AddressDetail string `json:"address_detail"` // 不动产详细地址
  90. RentBeginDate string `json:"rent_begin_date"` // 租赁期起
  91. RentEndDate string `json:"rent_end_date"` // 租赁期止
  92. IntercityFlag string `json:"intercity_flag"` // 跨地市标志
  93. UnitOfArea int `json:"unit_of_area"` // 面积单位
  94. }
  95. type PassengerTransport struct {
  96. Traveler string `json:"traveler,omitempty"` // 出行人
  97. IDType int `json:"id_type,omitempty"` // 证件类型
  98. IDNumber string `json:"id_number,omitempty"` // 证件号码
  99. TravelDate string `json:"travel_date,omitempty"` // 出行日期
  100. DeparturePlace string `json:"departure_place,omitempty"` // 出发地
  101. DestinationPlace string `json:"destination_palce,omitempty"` // 到达地
  102. VehicleType int `json:"vehicle_type,omitempty"` // 交通工具类型
  103. Level string `json:"level,omitempty"` // 等级
  104. }
  105. type GoodsTransport struct {
  106. TransportNumber string `json:"transport_number,omitempty"` // 运输工具号牌
  107. TransportKind string `json:"transport_kind,omitempty"` // 运输工具种类
  108. GoodsName string `json:"goods_name,omitempty"` // 货物名称
  109. DeparturePlace string `json:"departure_place,omitempty"` // 出发地
  110. DestinationPlace string `json:"destination_place,omitempty"` // 到达地
  111. }
  112. type AgriculturalPurchase struct {
  113. IDType string `json:"id_type,omitempty"` // 证件类型
  114. }
  115. type BuildingService struct {
  116. Site string `json:"site"` // 建筑服务发生地
  117. DetailSite string `json:"detail_site,omitempty"` // 详细地址
  118. BuildingProject string `json:"building_project"` // 建筑项目名称
  119. CrossSign string `json:"cross_sign"` // 跨地市标志
  120. }
  121. type RealStaticSales struct {
  122. PropertyNum string `json:"property_num,omitempty"` // 房屋产权证书号
  123. Location string `json:"location"` // 不动产地址
  124. AddressDetail string `json:"address_detail,omitempty"` // 不动产详细地址
  125. CrossSign string `json:"cross_sign"` // 跨市标志
  126. UnitOfArea int `json:"unit_of_area"` // 面积单位
  127. OnlineContractCode string `json:"online_contract_code,omitempty"` // 不动产单元代码/网签合同编码
  128. }
  129. type TractorCombine struct {
  130. ChassisNumber string `json:"chassis_number,omitempty"` // 底盘号或机架号
  131. EngineNumber string `json:"engine_number"` // 发动机号
  132. IsRegister string `json:"is_register,omitempty"` // 是否用于拖拉机和联合收割机登记
  133. }
  134. type UsedCarService struct {
  135. TicketSN string `json:"ticket_sn"` // 发票号码
  136. PaperTicketCode string `json:"paper_ticket_code"` // 纸票发票代码
  137. PaperTicketSN string `json:"paper_ticket_sn"` // 纸票发票号码
  138. }
  139. type UsedCarSell struct {
  140. FrameNumber string `json:"frame_number"` // 车架号码
  141. LicensePlateNumber string `json:"license_plate_number"` // 车牌号
  142. BrandModel string `json:"brand_model"` // 厂牌型号
  143. RegistrationCertificate string `json:"registration_certificate"` // 登记证号
  144. TransferOfficeName string `json:"transfer_office_name"` // 转入地车辆管理所名称
  145. NatureOfEnterprise string `json:"nature_of_enterprise"` // 企业性质
  146. }
  147. type DeductionService struct {
  148. TaxDiffServiceFlag int `json:"tax_diff_service_flag,omitempty"` // 差额征税标识
  149. TaxableServiceName string `json:"taxable_service_name,omitempty"` // 差额征税项目名称
  150. }
  151. type Item struct {
  152. ItemName string `json:"item_name"` // 商品名称
  153. ItemSpec string `json:"item_spec,omitempty"` // 商品规格
  154. ItemUnit string `json:"item_unit"` // 商品单位
  155. ItemQuantity float64 `json:"item_quantity"` // 商品数量
  156. ItemPrice float64 `json:"item_price"` // 商品单价
  157. ItemAmount float64 `json:"item_amount"` // 商品金额
  158. ItemTaxRate float64 `json:"item_tax_rate"` // 商品税率
  159. ItemTaxAmount float64 `json:"item_tax_amount"` // 商品税额
  160. RowType int `json:"row_type"` // 行性质标志
  161. }
  162. func (c *FapiaoApiController) GetFaPiaoList() {
  163. page, _ := c.GetInt64("page", -1)
  164. limit, _ := c.GetInt64("limit", -1)
  165. start_time := c.GetString("start_time")
  166. end_time := c.GetString("end_time")
  167. timeLayout := "2006-01-02"
  168. loc, _ := time.LoadLocation("Local")
  169. var startTime int64
  170. if len(start_time) > 0 {
  171. theTime, err := time.ParseInLocation(timeLayout+" 15:04:05", start_time+" 00:00:00", loc)
  172. if err != nil {
  173. //fmt.Println(err)
  174. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
  175. return
  176. }
  177. startTime = theTime.Unix()
  178. }
  179. var endTime int64
  180. if len(end_time) > 0 {
  181. theTime, err := time.ParseInLocation(timeLayout+" 15:04:05", end_time+" 23:59:59", loc)
  182. if err != nil {
  183. utils.ErrorLog(err.Error())
  184. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
  185. return
  186. }
  187. endTime = theTime.Unix()
  188. }
  189. adminUser := c.GetAdminUserInfo()
  190. org_id := adminUser.CurrentOrgId
  191. order, err, total := service.GetFaPiaoList(org_id, page, limit, startTime, endTime)
  192. if err == nil {
  193. c.ServeSuccessJSON(map[string]interface{}{
  194. "fapiao_record": order,
  195. "total": total,
  196. })
  197. } else {
  198. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
  199. return
  200. }
  201. }
  202. func (c *FapiaoApiController) GetOrderFaPiaoList() {
  203. page, _ := c.GetInt64("page", -1)
  204. limit, _ := c.GetInt64("limit", -1)
  205. start_time := c.GetString("start_time")
  206. end_time := c.GetString("end_time")
  207. is_open_fapiao, _ := c.GetInt64("is_open_fapiao", 0)
  208. sort_type, _ := c.GetInt64("sort_type", 0)
  209. patient_id, _ := c.GetInt64("patient_id", 0)
  210. timeLayout := "2006-01-02"
  211. loc, _ := time.LoadLocation("Local")
  212. var startTime int64
  213. if len(start_time) > 0 {
  214. theTime, err := time.ParseInLocation(timeLayout+" 15:04:05", start_time+" 00:00:00", loc)
  215. if err != nil {
  216. //fmt.Println(err)
  217. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
  218. return
  219. }
  220. startTime = theTime.Unix()
  221. }
  222. var endTime int64
  223. if len(end_time) > 0 {
  224. theTime, err := time.ParseInLocation(timeLayout+" 15:04:05", end_time+" 23:59:59", loc)
  225. if err != nil {
  226. utils.ErrorLog(err.Error())
  227. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
  228. return
  229. }
  230. endTime = theTime.Unix()
  231. }
  232. adminUser := c.GetAdminUserInfo()
  233. org_id := adminUser.CurrentOrgId
  234. order, err, total := service.GetFaPiaoSettleList(org_id, page, limit, startTime, endTime, sort_type, start_time, end_time, is_open_fapiao, patient_id)
  235. if err == nil {
  236. c.ServeSuccessJSON(map[string]interface{}{
  237. "order": order,
  238. "total": total,
  239. })
  240. } else {
  241. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeDataException)
  242. return
  243. }
  244. }
  245. func (c *FapiaoApiController) GetLoginUploadCode() {
  246. sdk := invoice.NewSdk(common.HMAC_SHA256, "5058f0defd12047ee2a7", "51440fbee667ea9a53aaa68c9c408367", "", "test")
  247. var config models.FapiaoConfig
  248. config, _ = service.FindFaPiaoConfigInfo(c.GetAdminUserInfo().CurrentOrgId)
  249. routerAddress, postData := fapiao.GetSMSCode(config) //发票开具
  250. fmt.Println(routerAddress)
  251. fmt.Println(postData)
  252. r, err := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData)
  253. if err != nil {
  254. fmt.Println(err)
  255. } else {
  256. var resp SmsCode
  257. // 将 byte 切片转换为结构体
  258. json.Unmarshal(r, &resp)
  259. if resp.Code == 0 {
  260. c.ServeSuccessJSON(map[string]interface{}{
  261. "msg": resp.Message,
  262. })
  263. }
  264. }
  265. }
  266. type SmsCode struct {
  267. Code int `json:"code"`
  268. Message string `json:"message"`
  269. }
  270. func (c *FapiaoApiController) Login() {
  271. code := c.GetString("code")
  272. var config models.FapiaoConfig
  273. config, _ = service.FindFaPiaoConfigInfo(c.GetAdminUserInfo().CurrentOrgId)
  274. sdk := invoice.NewSdk(common.HMAC_SHA256, "5058f0defd12047ee2a7", "51440fbee667ea9a53aaa68c9c408367", "", "test")
  275. routerAddress, postData := fapiao.Login(code, config) //发票开具
  276. r, err := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData)
  277. if err != nil {
  278. fmt.Println(err)
  279. } else {
  280. var resp SmsCode
  281. // 将 byte 切片转换为结构体
  282. json.Unmarshal(r, &resp)
  283. if resp.Code == 0 {
  284. c.ServeSuccessJSON(map[string]interface{}{
  285. "msg": resp.Message,
  286. })
  287. }
  288. }
  289. }
  290. func (c *FapiaoApiController) GetQRCode() {
  291. sdk := invoice.NewSdk(common.HMAC_SHA256, "5058f0defd12047ee2a7", "51440fbee667ea9a53aaa68c9c408367", "", "test")
  292. var config models.FapiaoConfig
  293. config, _ = service.FindFaPiaoConfigInfo(c.GetAdminUserInfo().CurrentOrgId)
  294. routerAddress, postData := fapiao.GetQRCode(config) //发票开具
  295. r, err := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData)
  296. if err != nil {
  297. fmt.Println(err)
  298. } else {
  299. var resp QRAuth
  300. // 将 byte 切片转换为结构体
  301. err := json.Unmarshal(r, &resp)
  302. fmt.Println(resp)
  303. if err != nil {
  304. fmt.Println("Error unmarshalling:", err)
  305. } else {
  306. if resp.Code == 0 {
  307. decodedBytes, _ := base64.StdEncoding.DecodeString(resp.Data.QrCode)
  308. if len(resp.Data.AuthId) == 0 { //还没进行授权,则获取二维码信息
  309. c.ServeSuccessJSON(map[string]interface{}{
  310. "cus_status": 1,
  311. "qr_code": string(decodedBytes),
  312. })
  313. } else {
  314. status := GetQRStatus(c.GetAdminUserInfo().CurrentOrgId, resp.Data.AuthId)
  315. if status == "UNDEFINE" {
  316. c.ServeSuccessJSON(map[string]interface{}{
  317. "cus_status": -1,
  318. "msg": "未定义",
  319. })
  320. } else if status == "UNHANDLED" {
  321. c.ServeSuccessJSON(map[string]interface{}{
  322. "cus_status": 1,
  323. "qr_code": string(decodedBytes),
  324. })
  325. } else if status == "REAL_AUTH_SUCCESS" {
  326. c.ServeSuccessJSON(map[string]interface{}{
  327. "cus_status": 2,
  328. "msg": "已经实名认证成功",
  329. })
  330. } else if status == "REFRESH" {
  331. c.ServeSuccessJSON(map[string]interface{}{
  332. "cus_status": 1,
  333. "qr_code": string(decodedBytes),
  334. })
  335. } else if status == "NEED_RELOGIN_BUREAU" {
  336. c.ServeSuccessJSON(map[string]interface{}{
  337. "cus_status": -3,
  338. "msg": "登录失效,请重新短信登录税局",
  339. })
  340. }
  341. }
  342. } else {
  343. c.ServeSuccessJSON(map[string]interface{}{
  344. "cus_status": -4,
  345. "msg": resp.Message,
  346. })
  347. }
  348. }
  349. //fmt.Println(string(r))
  350. }
  351. }
  352. func (c *FapiaoApiController) OpenFaPiao() {
  353. //var config models.FapiaoConfig
  354. //config, _ = service.FindFaPiaoConfigInfo(c.GetAdminUserInfo().CurrentOrgId)
  355. //认证接口
  356. sdk := invoice.NewSdk(common.HMAC_SHA256, "5058f0defd12047ee2a7", "51440fbee667ea9a53aaa68c9c408367", "", "test")
  357. status := GetQRStatusTwo(c.GetAdminUserInfo().CurrentOrgId)
  358. fmt.Println("11112222")
  359. fmt.Println(status)
  360. if status == 0 {
  361. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeAuthWrong)
  362. return
  363. }
  364. //查询余量接口
  365. //routerAddress, postData := fapiao.QueryStock(config)
  366. //r, err := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData)
  367. //fmt.Println(string(r))
  368. //if err != nil {
  369. // fmt.Println(err)
  370. //} else {
  371. // var resp2 FapiaoStock
  372. // // 将 byte 切片转换为结构体
  373. // err2 := json.Unmarshal(r, &resp2)
  374. // if err2 != nil {
  375. // fmt.Println(err2)
  376. //
  377. // } else {
  378. // if resp2.Code == 0 {
  379. // if resp2.Data.LeftQuantity <= 0 {
  380. // c.ServeSuccessJSON(map[string]interface{}{
  381. // "msg": "发票余量不足,请登录高灯平台申领发票",
  382. // "status": -1,
  383. // })
  384. // return
  385. // }
  386. // }
  387. // }
  388. //}
  389. //return
  390. //开蓝票逻辑
  391. order_ids := c.GetString("order_ids")
  392. admin_user_id, _ := c.GetInt64("admin_user_id")
  393. ids := strings.Split(order_ids, ",")
  394. orders, _ := service.GetFaPiaoOrderByIDS(ids)
  395. var MedfeeSumamt float64 = 0 //治疗费用
  396. var PsnCashPay float64 = 0 //治疗费用
  397. var FundPaySumamt float64 = 0 //治疗费用
  398. var details []models.HisOrderInfo
  399. var numbers []string
  400. decimal.DivisionPrecision = 2
  401. for _, oss := range orders {
  402. MedfeeSumamt, _ = decimal.NewFromFloat(MedfeeSumamt).Add(decimal.NewFromFloat(oss.MedfeeSumamt)).Float64()
  403. PsnCashPay, _ = decimal.NewFromFloat(PsnCashPay).Add(decimal.NewFromFloat(oss.PsnCashPay)).Float64()
  404. FundPaySumamt, _ = decimal.NewFromFloat(FundPaySumamt).Add(decimal.NewFromFloat(oss.FundPaySumamt)).Float64()
  405. numbers = append(numbers, oss.Number)
  406. }
  407. details, _ = service.GetFaPiaoOrderInfoByNumbers(numbers)
  408. role, _ := service.GetAdminUserRole(admin_user_id, c.GetAdminUserInfo().CurrentOrgId)
  409. role.UserName = "邹碧琳"
  410. type CostType struct {
  411. name string
  412. price float64
  413. }
  414. var cts []CostType
  415. var ct CostType
  416. var bedCostTotal float64 = 0 //床位总费
  417. var operationCostTotal float64 = 0 //手术费
  418. var otherCostTotal float64 = 0 //其他费用
  419. var materialCostTotal float64 = 0 //材料费
  420. var westernMedicineCostTotal float64 = 0 //西药费
  421. var chineseTraditionalMedicineCostTotal float64 = 0 //中成药
  422. var checkCostTotal float64 = 0 //检查费
  423. var laboratoryCostTotal float64 = 0 //化验费
  424. var treatCostTotal float64 = 0 //治疗费用
  425. var huliCostTotal float64 = 0 //治疗费用
  426. var zhencaCostTotal float64 = 0 //治疗费用
  427. for _, item := range details {
  428. if item.MedChrgitmType == "01" { //床位费
  429. bedCostTotal, _ = decimal.NewFromFloat(bedCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  430. }
  431. if item.MedChrgitmType == "07" { //护理费
  432. huliCostTotal, _ = decimal.NewFromFloat(huliCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  433. }
  434. if c.GetAdminUserInfo().CurrentOrgId == 10188 || c.GetAdminUserInfo().CurrentOrgId == 10217 {
  435. if item.MedChrgitmType == "03" { //检查费
  436. laboratoryCostTotal, _ = decimal.NewFromFloat(laboratoryCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  437. }
  438. } else {
  439. if item.MedChrgitmType == "03" { //检查费
  440. checkCostTotal, _ = decimal.NewFromFloat(checkCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  441. }
  442. }
  443. if item.MedChrgitmType == "04" { //化验费
  444. laboratoryCostTotal, _ = decimal.NewFromFloat(laboratoryCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  445. }
  446. if item.MedChrgitmType == "05" || item.MedChrgitmType == "1402" || item.MedChrgitmType == "1403" { //治疗费
  447. treatCostTotal, _ = decimal.NewFromFloat(treatCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  448. }
  449. if item.MedChrgitmType == "06" { //手术费
  450. operationCostTotal, _ = decimal.NewFromFloat(operationCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  451. }
  452. if item.MedChrgitmType == "08" { //材料费
  453. materialCostTotal, _ = decimal.NewFromFloat(materialCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  454. }
  455. if item.MedChrgitmType == "09" { //西药费
  456. westernMedicineCostTotal, _ = decimal.NewFromFloat(westernMedicineCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  457. }
  458. if item.MedChrgitmType == "11" { //中成费
  459. chineseTraditionalMedicineCostTotal, _ = decimal.NewFromFloat(chineseTraditionalMedicineCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  460. }
  461. if item.MedChrgitmType == "14" || item.MedChrgitmType == "0" || item.MedChrgitmType == "12" { //其他费
  462. otherCostTotal, _ = decimal.NewFromFloat(otherCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  463. }
  464. if item.MedChrgitmType == "02" { //诊察
  465. zhencaCostTotal, _ = decimal.NewFromFloat(zhencaCostTotal).Add(decimal.NewFromFloat(item.DetItemFeeSumamt)).Float64()
  466. }
  467. }
  468. if bedCostTotal > 0 {
  469. ct.name = "床位费"
  470. ct.price = bedCostTotal
  471. cts = append(cts, ct)
  472. }
  473. if operationCostTotal > 0 {
  474. ct.name = "手术费"
  475. ct.price = operationCostTotal
  476. cts = append(cts, ct)
  477. }
  478. if otherCostTotal > 0 {
  479. ct.name = "其他费"
  480. ct.price = otherCostTotal
  481. cts = append(cts, ct)
  482. }
  483. if materialCostTotal > 0 {
  484. ct.name = "材料费"
  485. ct.price = materialCostTotal
  486. cts = append(cts, ct)
  487. }
  488. if westernMedicineCostTotal > 0 {
  489. ct.name = "西药费"
  490. ct.price = westernMedicineCostTotal
  491. cts = append(cts, ct)
  492. }
  493. if chineseTraditionalMedicineCostTotal > 0 {
  494. ct.name = "中成药费"
  495. ct.price = chineseTraditionalMedicineCostTotal
  496. cts = append(cts, ct)
  497. }
  498. if checkCostTotal > 0 {
  499. ct.name = "检查费"
  500. ct.price = checkCostTotal
  501. cts = append(cts, ct)
  502. }
  503. if laboratoryCostTotal > 0 {
  504. ct.name = "化验费"
  505. ct.price = laboratoryCostTotal
  506. cts = append(cts, ct)
  507. }
  508. if treatCostTotal > 0 {
  509. ct.name = "治疗费"
  510. ct.price = treatCostTotal
  511. cts = append(cts, ct)
  512. }
  513. if huliCostTotal > 0 {
  514. ct.name = "护理费"
  515. ct.price = huliCostTotal
  516. cts = append(cts, ct)
  517. }
  518. if zhencaCostTotal > 0 {
  519. ct.name = "诊察费"
  520. ct.price = zhencaCostTotal
  521. cts = append(cts, ct)
  522. }
  523. fmt.Println(cts)
  524. org_config, _ := service.FindMedicalInsuranceInfo(c.GetAdminUserInfo().CurrentOrgId)
  525. var config2 models.FapiaoConfig
  526. config2, _ = service.FindFaPiaoConfigInfo(c.GetAdminUserInfo().CurrentOrgId)
  527. number := strconv.FormatInt(time.Now().Unix(), 10) + "_" + strconv.FormatInt(orders[0].UserOrgId, 10) + "_" + strconv.FormatInt(orders[0].PatientId, 10)
  528. amountWithoutTax, _, taxAmount, amountHasTax := CalculatePriceDetails(MedfeeSumamt, 1, 0.13)
  529. postData3 := map[string]interface{}{
  530. "seller_name": org_config.OrgName,
  531. "seller_taxpayer_num": config2.SellerTaxpayerNum,
  532. "seller_address": config2.SellerAddress,
  533. "seller_tel": config2.SellerTel,
  534. "seller_bank_name": config2.SellerBankName,
  535. "seller_bank_account": config2.SellerBankAccount,
  536. "title_type": 1,
  537. "buyer_title": orders[0].PsnName,
  538. "buyer_taxpayer_num": "",
  539. "buyer_address": "",
  540. "buyer_phone": "",
  541. "buyer_bank_name": "",
  542. "buyer_bank_account": "",
  543. "buyer_email": "",
  544. "order_id": number,
  545. "invoice_type_code": "082",
  546. "callback_url": "http://www.goldentec.com/callback",
  547. "drawer": role.UserName,
  548. "payee": "",
  549. "checker": "",
  550. "terminal_code": config2.TerminalCode,
  551. "user_openid": "",
  552. "special_invoice_kind": "",
  553. "zsfs": "",
  554. "deduction": "",
  555. "amount_has_tax": amountHasTax,
  556. "tax_amount": taxAmount,
  557. "amount_without_tax": amountWithoutTax,
  558. "remark": "医疗发票",
  559. }
  560. ////项目商品明细
  561. items := make([]map[string]interface{}, 0)
  562. for _, ct := range cts {
  563. item := make(map[string]interface{})
  564. amountWithoutTax, _, taxAmount, _ := CalculatePriceDetails(ct.price, 1, 0.06)
  565. item["name"] = ct.name
  566. item["tax_code"] = "3070202000000000000"
  567. item["models"] = ""
  568. item["unit"] = ""
  569. item["total_price"] = amountWithoutTax
  570. item["total"] = "1"
  571. item["price"] = amountWithoutTax
  572. item["tax_rate"] = "0.06"
  573. item["tax_amount"] = taxAmount
  574. item["discount"] = "0"
  575. item["preferential_policy_flag"] = ""
  576. item["zero_tax_flag"] = ""
  577. item["vat_special_management"] = ""
  578. items = append(items, item)
  579. }
  580. postData3["items"] = items
  581. routerAddress, postData4 := fapiao.Blue(postData3) //发票开具
  582. r, err4 := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData4)
  583. fmt.Println("blue")
  584. fmt.Println(string(r))
  585. if err4 != nil {
  586. fmt.Println(err4)
  587. } else {
  588. var resp OpenFaPiaoResultResponse
  589. // 将 byte 切片转换为结构体
  590. err := json.Unmarshal(r, &resp)
  591. fmt.Println(resp)
  592. if err != nil {
  593. fmt.Println("Error unmarshalling:", err)
  594. } else {
  595. fmt.Println(resp)
  596. if resp.Code == 0 {
  597. //开具蓝票成功,请求查询接口,获取发票相关数据
  598. routerAddress2, postData2 := fapiao.Query(config2.SellerTaxpayerNum, resp.Data.OrderSn, number)
  599. r3, err2 := sdk.HttpPost("https://apigw.goldentec.com", routerAddress2, postData2)
  600. fmt.Println("query")
  601. fmt.Println(string(r3))
  602. if err2 != nil {
  603. fmt.Println(err2)
  604. } else {
  605. var resp3 QueryFaPiaoResultResponse
  606. // 将 byte 切片转换为结构体
  607. json.Unmarshal(r3, &resp3)
  608. if resp3.Code == 0 {
  609. var fapiao models.HisFaPiaoOrder
  610. fapiao.InvoiceId = resp.Data.InvoiceId
  611. fapiao.OrderSn = resp.Data.OrderSn
  612. fapiao.TicketSn = resp3.Data.TicketSn
  613. fapiao.TicketDate = resp3.Data.TicketDate
  614. fapiao.AmountWithTax = resp3.Data.AmountWithoutTax
  615. fapiao.AmountWithoutTax = resp3.Data.AmountWithoutTax
  616. fapiao.TaxAmount = resp3.Data.TaxAmount
  617. fapiao.IsRedWashed = strconv.FormatInt(int64(resp3.Data.IsRedWashed), 10)
  618. fapiao.PdfUrl = resp3.Data.PdfUrl
  619. fapiao.OfdUrl = resp3.Data.OfdUrl
  620. fapiao.XmlUrl = resp3.Data.XmlUrl
  621. fapiao.FapiaoStatus = "1"
  622. fapiao.OrderIds = order_ids
  623. fapiao.UserOrgId = c.GetAdminUserInfo().CurrentOrgId
  624. fapiao.Status = 1
  625. fapiao.PatientId = orders[0].PatientId
  626. fapiao.Ctime = time.Now().Unix()
  627. fapiao.Mtime = time.Now().Unix()
  628. fapiao.Creator = role.UserName
  629. fapiao.MedfeeSumamt = MedfeeSumamt
  630. fapiao.FundPaySumamt = FundPaySumamt
  631. fapiao.PsnCashPay = PsnCashPay
  632. err5 := service.SaveFaPiaoOrder(fapiao)
  633. fmt.Println(err5)
  634. if err5 == nil {
  635. service.UpdateFaPiaoNumber(resp3.Data.TicketSn, ids) //同步发票号码
  636. c.ServeSuccessJSON(map[string]interface{}{
  637. "msg": "开具成功",
  638. })
  639. }
  640. } else {
  641. //错误处理
  642. }
  643. }
  644. } else {
  645. //错误处理
  646. }
  647. }
  648. }
  649. }
  650. func (c *FapiaoApiController) RedFaPiao() {
  651. //认证
  652. status := GetQRStatusTwo(c.GetAdminUserInfo().CurrentOrgId)
  653. if status == 0 {
  654. c.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeAuthWrong)
  655. return
  656. }
  657. id, _ := c.GetInt64("id")
  658. admin_user_id, _ := c.GetInt64("admin_user_id")
  659. role2, _ := service.GetAdminUserRole(admin_user_id, c.GetAdminUserInfo().CurrentOrgId)
  660. fapiao_config, _ := service.GetFaPiaoOrderById(id)
  661. var config models.FapiaoConfig
  662. config, _ = service.FindFaPiaoConfigInfo(c.GetAdminUserInfo().CurrentOrgId)
  663. sdk := invoice.NewSdk(common.HMAC_SHA256, "5058f0defd12047ee2a7", "51440fbee667ea9a53aaa68c9c408367", "", "test")
  664. routerAddress, postData := fapiao.Red(config.SellerTaxpayerNum, "", fapiao_config.OrderSn) //发票开具
  665. fmt.Println("postData")
  666. fmt.Println(postData)
  667. fmt.Println("postData")
  668. red, err := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData)
  669. fmt.Println("red")
  670. fmt.Println(red)
  671. fmt.Println("red")
  672. if err != nil {
  673. fmt.Println(err)
  674. } else {
  675. var resp RedResult
  676. // 将 byte 切片转换为结构体
  677. json.Unmarshal(red, &resp)
  678. fmt.Println("resp")
  679. fmt.Println(resp)
  680. fmt.Println("resp")
  681. if resp.Code == 0 {
  682. if resp.Data[0].State == 1 {
  683. //查询红票开具情况
  684. routerAddress2, postData2 := fapiao.Query(config.SellerTaxpayerNum, fapiao_config.OrderSn, "")
  685. r3, _ := sdk.HttpPost("https://apigw.goldentec.com", routerAddress2, postData2)
  686. var resp3 QueryFaPiaoResultResponse
  687. // 将 byte 切片转换为结构体
  688. json.Unmarshal(r3, &resp3)
  689. fmt.Println("resp")
  690. fmt.Println(string(r3))
  691. fmt.Println(resp3)
  692. fmt.Println("resp")
  693. if resp3.Code == 0 {
  694. if resp3.Data.IsRedWashed == 1 {
  695. fapiao_config.IsRedWashed = "1"
  696. fapiao_config.Status = 0
  697. fapiao_config.RedInvoiceId = resp.Data[0].InvoiceId
  698. fapiao_config.RedInvoiceCreator = role2.UserName
  699. service.SaveFaPiaoOrder(fapiao_config)
  700. //将结算表的发票号码清空
  701. service.UpdateFaPiaoNumberByNumber(fapiao_config.TicketSn)
  702. c.ServeSuccessJSON(map[string]interface{}{
  703. "msg": "红冲成功",
  704. })
  705. } else {
  706. c.ServeSuccessJSON(map[string]interface{}{
  707. "msg": "红冲失败",
  708. })
  709. }
  710. } else {
  711. c.ServeSuccessJSON(map[string]interface{}{
  712. "msg": "红冲失败",
  713. })
  714. }
  715. } else {
  716. c.ServeSuccessJSON(map[string]interface{}{
  717. "msg": "红冲失败",
  718. })
  719. }
  720. } else {
  721. c.ServeSuccessJSON(map[string]interface{}{
  722. "msg": "红冲失败",
  723. })
  724. }
  725. }
  726. }
  727. func GetQRStatusTwo(org_id int64) (status int64) {
  728. sdk := invoice.NewSdk(common.HMAC_SHA256, "5058f0defd12047ee2a7", "51440fbee667ea9a53aaa68c9c408367", "", "test")
  729. var config models.FapiaoConfig
  730. config, _ = service.FindFaPiaoConfigInfo(org_id)
  731. routerAddress, postData := fapiao.GetQRCode(config) //发票开具
  732. r, err := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData)
  733. if err != nil {
  734. fmt.Println(err)
  735. } else {
  736. var resp QRAuth
  737. // 将 byte 切片转换为结构体
  738. err := json.Unmarshal(r, &resp)
  739. fmt.Println(resp)
  740. if err != nil {
  741. fmt.Println("Error unmarshalling:", err)
  742. } else {
  743. if len(resp.Data.AuthId) == 0 { //还没实名认证
  744. } else {
  745. status = 1
  746. status_str := GetQRStatus(org_id, resp.Data.AuthId)
  747. if status_str == "UNDEFINE" {
  748. status = 0
  749. } else if status_str == "UNHANDLED" {
  750. status = 0
  751. } else if status_str == "REAL_AUTH_SUCCESS" {
  752. status = 1
  753. } else if status_str == "REFRESH" {
  754. status = 0
  755. } else if status_str == "NEED_RELOGIN_BUREAU" {
  756. status = 0
  757. }
  758. }
  759. }
  760. }
  761. return
  762. }
  763. type RedResult struct {
  764. Code int `json:"code"`
  765. Data []struct {
  766. State int `json:"state"`
  767. Message string `json:"message"`
  768. OrderSn string `json:"order_sn"`
  769. InvoiceId string `json:"invoice_id"`
  770. } `json:"data"`
  771. Message string `json:"message"`
  772. }
  773. type QueryFaPiaoResultResponse struct {
  774. Code int `json:"code"`
  775. Data struct {
  776. OrderSn string `json:"order_sn"`
  777. Status int `json:"status"`
  778. Message string `json:"message"`
  779. TicketDate string `json:"ticket_date"`
  780. TicketSn string `json:"ticket_sn"`
  781. TicketCode string `json:"ticket_code"`
  782. CheckCode string `json:"check_code"`
  783. AmountWithTax string `json:"amount_with_tax"`
  784. AmountWithoutTax string `json:"amount_without_tax"`
  785. TaxAmount string `json:"tax_amount"`
  786. IsRedWashed int `json:"is_red_washed"`
  787. PdfUrl string `json:"pdf_url"`
  788. OfdUrl string `json:"ofd_url"`
  789. XmlUrl string `json:"xml_url"`
  790. } `json:"data"`
  791. Message string `json:"message"`
  792. }
  793. type OpenFaPiaoResultResponse struct {
  794. Code int `json:"code"`
  795. Message string `json:"message"`
  796. Data struct {
  797. State int `json:"state"`
  798. OrderSn string `json:"order_sn"`
  799. InvoiceId string `json:"invoice_id"`
  800. } `json:"data"`
  801. }
  802. type SurplusStockResponse struct {
  803. Code int `json:"code"`
  804. Message string `json:"message"`
  805. Data struct {
  806. LeftQuantity int `json:"left_quantity"`
  807. } `json:"data"`
  808. }
  809. func GetFaPiaoStock(org_id int64) (left_quantity int) {
  810. sdk := invoice.NewSdk(common.HMAC_SHA256, "8ca4ee7b152c0abceff9", "17402aff152dbeedf7a7b30be553f4c4", "", "test")
  811. var config models.FapiaoConfig
  812. config, _ = service.FindFaPiaoConfigInfo(org_id)
  813. routerAddress, postData := fapiao.QueryStock(config)
  814. r, err := sdk.HttpPost("https://apigw-test.goldentec.com", routerAddress, postData)
  815. if err != nil {
  816. fmt.Println(err)
  817. } else {
  818. var resp SurplusStockResponse
  819. // 将 byte 切片转换为结构体
  820. err := json.Unmarshal(r, &resp)
  821. if err != nil {
  822. fmt.Println("Error unmarshalling:", err)
  823. } else {
  824. if resp.Code == 0 {
  825. left_quantity = resp.Data.LeftQuantity
  826. }
  827. }
  828. }
  829. return
  830. }
  831. type Response struct {
  832. Code int `json:"code"`
  833. Message string `json:"message"`
  834. Data struct {
  835. Status string `json:"status"`
  836. } `json:"data"`
  837. }
  838. func GetQRStatus(org_id int64, auth_id string) (status string) {
  839. sdk := invoice.NewSdk(common.HMAC_SHA256, "5058f0defd12047ee2a7", "51440fbee667ea9a53aaa68c9c408367", "", "test")
  840. fmt.Println(sdk)
  841. var config models.FapiaoConfig
  842. config, _ = service.FindFaPiaoConfigInfo(org_id)
  843. fmt.Println(config)
  844. routerAddress, postData := fapiao.GetQRStatus(auth_id, config) //发票开具
  845. fmt.Println(routerAddress)
  846. fmt.Println(postData)
  847. r, err := sdk.HttpPost("https://apigw.goldentec.com", routerAddress, postData)
  848. if err != nil {
  849. status = "FAILD"
  850. fmt.Println(err)
  851. } else {
  852. fmt.Println(r)
  853. var resp Response
  854. // 将 byte 切片转换为结构体
  855. err := json.Unmarshal(r, &resp)
  856. fmt.Println(string(r))
  857. if err != nil {
  858. status = "FAILD"
  859. fmt.Println("Error unmarshalling:", err)
  860. } else {
  861. status = resp.Data.Status
  862. fmt.Printf("Parsed struct: %+v\n", resp)
  863. }
  864. }
  865. return status
  866. //return
  867. }
  868. // 计算商品价格、税额等函数
  869. func CalculatePriceDetails(totalCost float64, itemCount int, taxRate float64) (string, string, string, string) {
  870. // 商品不含税总金额,保留两位小数
  871. amountWithoutTax := roundTo(totalCost/(1+taxRate), 2)
  872. // 商品不含税单价,保留八位小数
  873. pricePerItem := roundTo(amountWithoutTax/float64(itemCount), 8)
  874. // 税额,保留两位小数
  875. taxAmount := roundTo(amountWithoutTax*taxRate, 2)
  876. // 含税总金额
  877. amountHasTax := amountWithoutTax + taxAmount
  878. return fmt.Sprintf("%f", amountWithoutTax), fmt.Sprintf("%f", pricePerItem), fmt.Sprintf("%f", taxAmount), fmt.Sprintf("%f", amountHasTax)
  879. }
  880. // 保留指定小数位数的函数
  881. func roundTo(value float64, places int) float64 {
  882. scale := math.Pow(10, float64(places))
  883. return math.Round(value*scale) / scale
  884. }
  885. type QRAuth struct {
  886. Code int `json:"code"`
  887. Message string `json:"message"`
  888. Data struct {
  889. AuthId string `json:"auth_id"`
  890. QrCode string `json:"qr_code"`
  891. } `json:"data"`
  892. }
  893. type FapiaoStock struct {
  894. Code int `json:"code"`
  895. Data struct {
  896. LeftQuantity int `json:"left_quantity"`
  897. } `json:"data"`
  898. Message string `json:"message"`
  899. }