Stock.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. package controllers
  2. import (
  3. "ERP_storage/Nats"
  4. "ERP_storage/Nats/NatsServer"
  5. "ERP_storage/conf"
  6. "ERP_storage/logs"
  7. "ERP_storage/models/Account"
  8. "ERP_storage/models/Basic"
  9. "ERP_storage/models/Contract"
  10. "ERP_storage/models/Property"
  11. "ERP_storage/models/Stock"
  12. "fmt"
  13. natslibs "git.baozhida.cn/ERP_libs/Nats"
  14. userlibs "git.baozhida.cn/ERP_libs/User"
  15. "git.baozhida.cn/ERP_libs/lib"
  16. "github.com/beego/beego/v2/adapter/orm"
  17. beego "github.com/beego/beego/v2/server/web"
  18. "github.com/robfig/cron/v3"
  19. "github.com/xuri/excelize/v2"
  20. "math"
  21. "os"
  22. "strconv"
  23. "strings"
  24. "time"
  25. )
  26. type StockController struct {
  27. beego.Controller
  28. User userlibs.User
  29. }
  30. func (c *StockController) Prepare() {
  31. c.User = *Account.User_r
  32. }
  33. func (c *StockController) Device_List() {
  34. // 分页参数 初始化
  35. page, _ := c.GetInt("page")
  36. if page < 1 {
  37. page = 1
  38. }
  39. page_z, _ := c.GetInt("page_z")
  40. if page_z < 1 {
  41. page_z = conf.Page_size
  42. }
  43. T_state, _ := c.GetInt("T_state")
  44. T_name := c.GetString("T_name")
  45. DeviceDao := Stock.NewDevice(orm.NewOrm())
  46. R_List, R_cnt := DeviceDao.Read_Device_List(T_name, T_state, page, page_z)
  47. var r_jsons lib.R_JSONS
  48. r_jsons.Num = R_cnt
  49. r_jsons.Data = R_List
  50. r_jsons.Page = page
  51. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  52. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  53. c.ServeJSON()
  54. return
  55. }
  56. func (c *StockController) Device_Check() {
  57. T_sn := c.GetString("T_sn")
  58. T_type, _ := c.GetInt("T_type") //1-出库 2-入库
  59. DeviceDao := Stock.NewDevice(orm.NewOrm())
  60. device, err := DeviceDao.Read_Device_ByT_sn(T_sn)
  61. if err != nil && err.Error() != orm.ErrNoRows.Error() {
  62. c.Data["json"] = lib.JSONS{Code: 202, Msg: "请稍后重试!"}
  63. c.ServeJSON()
  64. return
  65. }
  66. // T_State 1-已出库 2-未出库/入库
  67. if len(device.T_in_number) > 0 && device.T_State == 2 && T_type == 2 {
  68. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("【%s】已入库,请勿重复提交!", T_sn)}
  69. c.ServeJSON()
  70. return
  71. }
  72. if T_type == 2 {
  73. mqtt := Stock.Read_MqttUser(T_sn)
  74. if len(mqtt.Username) == 0 {
  75. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("【%s】未授权,请先授权!", T_sn)}
  76. c.ServeJSON()
  77. return
  78. }
  79. }
  80. if len(device.T_out_number) > 0 && device.T_State == 1 && T_type == 1 {
  81. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("【%s】已出库,请勿重复提交!", T_sn)}
  82. c.ServeJSON()
  83. return
  84. }
  85. if T_type == 1 {
  86. if device.Id == 0 {
  87. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("【%s】未入库,请先入库!", T_sn)}
  88. c.ServeJSON()
  89. return
  90. }
  91. }
  92. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
  93. c.ServeJSON()
  94. return
  95. }
  96. func (c *StockController) Stock_List() {
  97. // 分页参数 初始化
  98. page, _ := c.GetInt("page")
  99. if page < 1 {
  100. page = 1
  101. }
  102. page_z, _ := c.GetInt("page_z")
  103. if page_z < 1 {
  104. page_z = conf.Page_size
  105. }
  106. // 查询
  107. T_depot_id, _ := c.GetInt("T_depot_id")
  108. // 查询
  109. T_product_name := c.GetString("T_product_name")
  110. T_product_model := c.GetString("T_product_model")
  111. T_product_class, _ := c.GetInt("T_product_class")
  112. userList, _ := NatsServer.Read_User_List_All()
  113. Account.Read_User_All_Map(userList)
  114. Basic.Read_Depot_All_Map()
  115. StockDao := Stock.NewStock(orm.NewOrm())
  116. R_List, R_cnt := StockDao.Read_Stock_List(T_depot_id, T_product_class, T_product_name, T_product_model, page, page_z)
  117. var r_jsons lib.R_JSONS
  118. r_jsons.Num = R_cnt
  119. r_jsons.Data = R_List
  120. r_jsons.Page = page
  121. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  122. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  123. c.ServeJSON()
  124. return
  125. }
  126. func (c *StockController) Stock_Detail_List() {
  127. // 查询
  128. T_depot_id, _ := c.GetInt("T_depot_id")
  129. // 查询
  130. T_product_id, _ := c.GetInt("T_product_id")
  131. T_start_date := c.GetString("T_start_date")
  132. T_end_date := c.GetString("T_end_date")
  133. now := time.Now()
  134. if len(T_start_date) == 0 {
  135. T_start_date = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.Local).Format("2006-01")
  136. }
  137. if len(T_end_date) == 0 {
  138. T_start_date = now.Format("2006-01")
  139. }
  140. StockMonthDao := Stock.NewStockMonth(orm.NewOrm())
  141. R_List := StockMonthDao.Read_StockMonth_List(T_depot_id, T_product_id, 0, T_start_date, T_end_date)
  142. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: R_List}
  143. c.ServeJSON()
  144. return
  145. }
  146. func (c *StockController) Stock_Detail_Excel() {
  147. // 查询
  148. T_depot_id, _ := c.GetInt("T_depot_id")
  149. T_product_id, _ := c.GetInt("T_product_id")
  150. // 查询
  151. T_start_date := c.GetString("T_start_date")
  152. T_end_date := c.GetString("T_end_date")
  153. now := time.Now()
  154. if len(T_start_date) == 0 {
  155. T_start_date = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.Local).Format("2006-01")
  156. }
  157. if len(T_end_date) == 0 {
  158. T_start_date = now.Format("2006-01")
  159. }
  160. var class_List []Basic.ProductClass_R
  161. filename := fmt.Sprintf("进销存(%s)", lib.GetRandstring(6, "0123456789", 0))
  162. if T_product_id > 0 {
  163. product, _ := Basic.Read_Product_ById(T_product_id)
  164. filename = fmt.Sprintf("进销存-%s明细(%s)", product.T_name, lib.GetRandstring(6, "0123456789", 0))
  165. class, _ := Basic.Read_ProductClass_ById(product.T_class)
  166. class_List = append(class_List, Basic.ProductClassToProductClass_R(class))
  167. } else {
  168. class_List, _ = Basic.Read_ProductClass_List("", 0, 9999)
  169. }
  170. f := excelize.NewFile() // 设置单元格的值
  171. Style1, _ := f.NewStyle(
  172. &excelize.Style{
  173. Font: &excelize.Font{Bold: true, Size: 12, Family: "宋体"},
  174. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  175. })
  176. Style2, _ := f.NewStyle(
  177. &excelize.Style{
  178. Font: &excelize.Font{Bold: true, Size: 10, Family: "宋体"},
  179. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
  180. Border: []excelize.Border{
  181. {Type: "left", Color: "000000", Style: 1},
  182. {Type: "top", Color: "000000", Style: 1},
  183. {Type: "bottom", Color: "000000", Style: 1},
  184. {Type: "right", Color: "000000", Style: 1},
  185. },
  186. })
  187. StockMonthDao := Stock.NewStockMonth(orm.NewOrm())
  188. for i, r := range class_List {
  189. StockList := StockMonthDao.Read_StockMonth_List(T_depot_id, T_product_id, r.Id, T_start_date, T_end_date)
  190. if len(StockList) == 0 {
  191. continue
  192. }
  193. if i == 0 {
  194. f.SetSheetName("Sheet1", r.T_name)
  195. } else {
  196. f.NewSheet(r.T_name)
  197. }
  198. f.MergeCell(r.T_name, "A1", "K1")
  199. f.SetRowStyle(r.T_name, 1, 1, Style1)
  200. f.SetCellValue(r.T_name, "A1", fmt.Sprintf("宝智达科技产品进销存统计表"))
  201. f.SetRowHeight(r.T_name, 1, 30)
  202. // 这里设置表头
  203. f.SetCellStyle(r.T_name, "A2", "K2", Style2)
  204. f.SetRowHeight(r.T_name, 2, 20)
  205. f.SetCellValue(r.T_name, "A2", "序号")
  206. f.SetCellValue(r.T_name, "B2", "产品名称")
  207. f.SetCellValue(r.T_name, "C2", "型号")
  208. f.SetCellValue(r.T_name, "D2", "规格")
  209. f.SetCellValue(r.T_name, "E2", "月份")
  210. f.SetCellValue(r.T_name, "F2", "期初库存")
  211. f.SetCellValue(r.T_name, "G2", "当月入库")
  212. f.SetCellValue(r.T_name, "H2", "当月出库")
  213. f.SetCellValue(r.T_name, "I2", "期末库存")
  214. f.SetCellValue(r.T_name, "J2", "出库项目")
  215. f.SetCellValue(r.T_name, "K2", "备注")
  216. // 设置列宽
  217. f.SetColWidth(r.T_name, "A", "A", 10)
  218. f.SetColWidth(r.T_name, "B", "B", 10)
  219. f.SetColWidth(r.T_name, "C", "D", 10)
  220. f.SetColWidth(r.T_name, "D", "D", 10)
  221. f.SetColWidth(r.T_name, "E", "E", 10)
  222. f.SetColWidth(r.T_name, "F", "F", 10)
  223. f.SetColWidth(r.T_name, "G", "G", 10)
  224. f.SetColWidth(r.T_name, "H", "H", 10)
  225. f.SetColWidth(r.T_name, "I", "I", 10)
  226. f.SetColWidth(r.T_name, "J", "J", 10)
  227. f.SetColWidth(r.T_name, "K", "K", 10)
  228. line := 2
  229. // 循环写入数据
  230. for _, v := range StockList {
  231. line++
  232. product, _ := Basic.Read_Product_ById(v.T_product_id)
  233. f.SetCellValue(r.T_name, fmt.Sprintf("A%d", line), line-2)
  234. f.SetCellValue(r.T_name, fmt.Sprintf("B%d", line), product.T_name)
  235. f.SetCellValue(r.T_name, fmt.Sprintf("C%d", line), r.T_name)
  236. f.SetCellValue(r.T_name, fmt.Sprintf("D%d", line), product.T_spec)
  237. f.SetCellValue(r.T_name, fmt.Sprintf("E%d", line), v.T_month)
  238. f.SetCellValue(r.T_name, fmt.Sprintf("F%d", line), v.T_beginning)
  239. f.SetCellValue(r.T_name, fmt.Sprintf("G%d", line), v.T_in)
  240. f.SetCellValue(r.T_name, fmt.Sprintf("H%d", line), v.T_out)
  241. f.SetCellValue(r.T_name, fmt.Sprintf("I%d", line), v.T_ending)
  242. f.SetCellValue(r.T_name, fmt.Sprintf("J%d", line), v.T_project)
  243. }
  244. Style4, _ := f.NewStyle(
  245. &excelize.Style{
  246. Font: &excelize.Font{Size: 10, Family: "宋体"},
  247. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
  248. Border: []excelize.Border{
  249. {Type: "left", Color: "000000", Style: 1},
  250. {Type: "top", Color: "000000", Style: 1},
  251. {Type: "bottom", Color: "000000", Style: 1},
  252. {Type: "right", Color: "000000", Style: 1},
  253. },
  254. })
  255. f.SetCellStyle(r.T_name, "A2", fmt.Sprintf("K%d", line), Style4)
  256. }
  257. // 保存文件
  258. if err := f.SaveAs("ofile/" + filename + ".xlsx"); err != nil {
  259. fmt.Println(err)
  260. }
  261. var url string
  262. //// 上传 OSS
  263. nats := natslibs.NewNats(Nats.Nats, conf.NatsSubj_Prefix)
  264. url, is := nats.Qiniu_UploadFile(lib.GetCurrentDirectory()+"/ofile/"+filename+".xlsx", "ofile/"+filename+".xlsx")
  265. if !is {
  266. c.Data["json"] = lib.JSONS{Code: 202, Msg: "oss!"}
  267. c.ServeJSON()
  268. return
  269. }
  270. //删除目录
  271. err := os.Remove("ofile/" + filename + ".xlsx")
  272. if err != nil {
  273. logs.Error(lib.FuncName(), err)
  274. }
  275. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: url}
  276. c.ServeJSON()
  277. return
  278. }
  279. func (c *StockController) StockIn_List() {
  280. // 分页参数 初始化
  281. page, _ := c.GetInt("page")
  282. if page < 1 {
  283. page = 1
  284. }
  285. page_z, _ := c.GetInt("page_z")
  286. if page_z < 1 {
  287. page_z = conf.Page_size
  288. }
  289. // 查询
  290. T_depot_id, _ := c.GetInt("T_depot_id")
  291. T_start_date := c.GetString("T_start_date")
  292. T_end_date := c.GetString("T_end_date")
  293. userList, _ := NatsServer.Read_User_List_All()
  294. Account.Read_User_All_Map(userList)
  295. Basic.Read_Depot_All_Map()
  296. StockInDao := Stock.NewStockIn(orm.NewOrm())
  297. R_List, R_cnt := StockInDao.Read_StockIn_List(T_depot_id, T_start_date, T_end_date, page, page_z)
  298. var r_jsons lib.R_JSONS
  299. r_jsons.Num = R_cnt
  300. r_jsons.Data = R_List
  301. r_jsons.Page = page
  302. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  303. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  304. c.ServeJSON()
  305. return
  306. }
  307. func (c *StockController) StockIn_Get() {
  308. // 查询
  309. T_number := c.GetString("T_number")
  310. o := orm.NewOrm()
  311. StockInDao := Stock.NewStockIn(o)
  312. StockInProductDao := Stock.NewStockInProduct(o)
  313. stockIn, err := StockInDao.Read_StockIn_ByT_number(T_number)
  314. if err != nil {
  315. c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
  316. c.ServeJSON()
  317. return
  318. }
  319. productList := StockInProductDao.Read_StockInProduct_List(stockIn.T_number)
  320. var pList []Stock.StockInProduct_R
  321. for _, v := range productList {
  322. pList = append(pList, Stock.StockInProductToStockInProduct_R(v))
  323. }
  324. userList, _ := NatsServer.Read_User_List_All()
  325. Account.Read_User_All_Map(userList)
  326. Basic.Read_Depot_All_Map()
  327. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Stock.StockInToStockIn_Detail(stockIn, pList)}
  328. c.ServeJSON()
  329. return
  330. }
  331. func (c *StockController) StockIn_Add() {
  332. rand_x := 0
  333. T_number := ""
  334. o := orm.NewOrm()
  335. o.Begin()
  336. StockInDao := Stock.NewStockIn(o)
  337. for true {
  338. T_number = "RK-" + lib.GetRandstring(8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", int64(rand_x))
  339. _, err := StockInDao.Read_StockIn_ByT_number(T_number)
  340. if err != nil && err.Error() == orm.ErrNoRows.Error() {
  341. break
  342. }
  343. rand_x += 1
  344. }
  345. T_depot_id, _ := c.GetInt("T_depot_id")
  346. T_date := c.GetString("T_date")
  347. T_product := c.GetString("T_product")
  348. T_remark := c.GetString("T_remark")
  349. if _, is := lib.DateStrToTime(T_date); !is {
  350. c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
  351. c.ServeJSON()
  352. return
  353. }
  354. var_ := Stock.StockIn{
  355. T_number: T_number,
  356. T_depot_id: T_depot_id,
  357. T_date: T_date,
  358. T_remark: T_remark,
  359. T_submit: c.User.T_uuid,
  360. }
  361. StockInProductDao := Stock.NewStockInProduct(o)
  362. StockDao := Stock.NewStock(o)
  363. DeviceDao := Stock.NewDevice(o)
  364. IotCardDao := Property.NewIotCard(&o)
  365. _, err := StockInDao.Add_StockIn(var_)
  366. if err != nil {
  367. o.Rollback()
  368. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  369. c.ServeJSON()
  370. return
  371. }
  372. if len(T_product) == 0 {
  373. o.Rollback()
  374. c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
  375. c.ServeJSON()
  376. return
  377. }
  378. productList := lib.SplitString(T_product, "|")
  379. for _, v := range productList {
  380. product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
  381. product, _ := Basic.Read_Product_ById(product_id)
  382. num, _ := strconv.Atoi(strings.Split(v, "-")[1])
  383. T_relation_sn := strings.Split(v, "-")[2]
  384. if T_relation_sn == "" && product.T_relation_sn == 1 {
  385. o.Rollback()
  386. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!")}
  387. c.ServeJSON()
  388. return
  389. }
  390. if len(T_relation_sn) > 0 {
  391. snList := strings.Split(strings.Trim(T_relation_sn, ","), ",")
  392. for _, sn := range snList {
  393. mqtt := Stock.Read_MqttUser(sn)
  394. // 添加设备
  395. device := Stock.Device{
  396. T_contract_number: "",
  397. T_out_number: "",
  398. T_product_id: product_id,
  399. T_in_number: T_number,
  400. T_sn: sn,
  401. T_iccid: mqtt.Iccid,
  402. T_imei: mqtt.Imei,
  403. T_State: 2,
  404. }
  405. _, err = DeviceDao.AddOrUpdate_Device(device, 2)
  406. if err != nil {
  407. o.Rollback()
  408. c.Data["json"] = lib.JSONS{Code: 202, Msg: "入库失败"}
  409. c.ServeJSON()
  410. return
  411. }
  412. // 添加物联网卡
  413. iotCard := Property.IotCard{
  414. T_iccid: mqtt.Iccid,
  415. T_sn: sn,
  416. T_State: 2, //1-未使用 2-已使用 3-已作废
  417. T_type: "4G",
  418. }
  419. _, err = IotCardDao.AddOrUpdate_IotCard(iotCard)
  420. if err != nil {
  421. o.Rollback()
  422. c.Data["json"] = lib.JSONS{Code: 202, Msg: "入库失败"}
  423. c.ServeJSON()
  424. return
  425. }
  426. }
  427. }
  428. stockInProduct := Stock.StockInProduct{
  429. T_number: T_number,
  430. T_product_id: product_id,
  431. T_depot_id: T_depot_id,
  432. T_num: num, // 入库数量
  433. T_date: T_date, // 入库日期
  434. T_relation_sn: T_relation_sn,
  435. }
  436. _, err = StockInProductDao.Add_StockInProduct(stockInProduct)
  437. if err != nil {
  438. o.Rollback()
  439. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  440. c.ServeJSON()
  441. return
  442. }
  443. _, err = StockDao.AddOrUpdate_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 2)
  444. if err != nil {
  445. o.Rollback()
  446. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  447. c.ServeJSON()
  448. return
  449. }
  450. }
  451. o.Commit()
  452. NatsServer.AddUserLogs(c.User.T_uuid, "入库", "入库", var_)
  453. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  454. c.ServeJSON()
  455. return
  456. }
  457. func (c *StockController) StockOut_List() {
  458. // 分页参数 初始化
  459. page, _ := c.GetInt("page")
  460. if page < 1 {
  461. page = 1
  462. }
  463. page_z, _ := c.GetInt("page_z")
  464. if page_z < 1 {
  465. page_z = conf.Page_size
  466. }
  467. // 查询
  468. T_depot_id, _ := c.GetInt("T_depot_id")
  469. T_contract_number := c.GetString("T_contract_number")
  470. T_start_date := c.GetString("T_start_date")
  471. T_end_date := c.GetString("T_end_date")
  472. userList, _ := NatsServer.Read_User_List_All()
  473. Account.Read_User_All_Map(userList)
  474. Basic.Read_Depot_All_Map()
  475. StockOutDao := Stock.NewStockOut(orm.NewOrm())
  476. R_List, R_cnt := StockOutDao.Read_StockOut_List(T_depot_id, T_contract_number, T_start_date, T_end_date, page, page_z)
  477. var r_jsons lib.R_JSONS
  478. r_jsons.Num = R_cnt
  479. r_jsons.Data = R_List
  480. r_jsons.Page = page
  481. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  482. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  483. c.ServeJSON()
  484. return
  485. }
  486. func (c *StockController) StockOut_Get() {
  487. // 查询
  488. T_number := c.GetString("T_number")
  489. o := orm.NewOrm()
  490. StockOutDao := Stock.NewStockOut(o)
  491. StockOutProductDao := Stock.NewStockOutProduct(o)
  492. stockIn, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  493. if err != nil {
  494. c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
  495. c.ServeJSON()
  496. return
  497. }
  498. productList := StockOutProductDao.Read_StockOutProduct_List(stockIn.T_number)
  499. var pList []Stock.StockOutProduct_R
  500. for _, v := range productList {
  501. pList = append(pList, Stock.StockOutProductToStockOutProduct_R(v))
  502. }
  503. userList, _ := NatsServer.Read_User_List_All()
  504. Account.Read_User_All_Map(userList)
  505. Basic.Read_Depot_All_Map()
  506. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Stock.StockOutToStockOut_Detail(stockIn, pList)}
  507. c.ServeJSON()
  508. return
  509. }
  510. func (c *StockController) StockOut_Add() {
  511. rand_x := 0
  512. T_number := ""
  513. o := orm.NewOrm()
  514. o.Begin()
  515. StockOutDao := Stock.NewStockOut(o)
  516. for true {
  517. T_number = "CK-" + lib.GetRandstring(8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", int64(rand_x))
  518. _, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  519. if err != nil && err.Error() == orm.ErrNoRows.Error() {
  520. break
  521. }
  522. rand_x += 1
  523. }
  524. T_contract_number := c.GetString("T_contract_number")
  525. T_depot_id, _ := c.GetInt("T_depot_id")
  526. T_type, _ := c.GetInt("T_type") // 出库类型 1-领料出库 2-销售出库
  527. T_date := c.GetString("T_date")
  528. T_receive := c.GetString("T_receive")
  529. T_product := c.GetString("T_product")
  530. T_remark := c.GetString("T_remark")
  531. T_delivery_type, _ := c.GetInt("T_delivery_type")
  532. T_signer_unit := c.GetString("T_signer_unit")
  533. T_signer := c.GetString("T_signer")
  534. T_signer_phone := c.GetString("T_signer_phone")
  535. T_signer_date := c.GetString("T_signer_date")
  536. T_courier_number := c.GetString("T_courier_number")
  537. if _, is := lib.DateStrToTime(T_date); !is {
  538. c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
  539. c.ServeJSON()
  540. return
  541. }
  542. var_ := Stock.StockOut{
  543. T_number: T_number,
  544. T_contract_number: T_contract_number,
  545. T_depot_id: T_depot_id,
  546. T_type: T_type,
  547. T_date: T_date,
  548. T_receive: T_receive,
  549. T_remark: T_remark,
  550. T_submit: c.User.T_uuid,
  551. // 销售出库
  552. T_delivery_type: T_delivery_type, // 1-自送 2-自提 3-快递
  553. T_signer_unit: T_signer_unit,
  554. T_signer: T_signer,
  555. T_signer_phone: T_signer_phone,
  556. T_signer_date: T_signer_date,
  557. T_courier_number: T_courier_number,
  558. }
  559. StockOutProductDao := Stock.NewStockOutProduct(o)
  560. StockDao := Stock.NewStock(o)
  561. DeviceDao := Stock.NewDevice(o)
  562. ContractDao := Contract.NewContract(o)
  563. ContractProductDao := Contract.NewContractProduct(o)
  564. _, err := StockOutDao.Add_StockOut(var_)
  565. if err != nil {
  566. o.Rollback()
  567. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  568. c.ServeJSON()
  569. return
  570. }
  571. // 1、添加出库单
  572. contract, _ := ContractDao.Read_Contract_ByT_number(T_contract_number)
  573. if contract.Id == 0 && T_type == 2 {
  574. o.Rollback()
  575. c.Data["json"] = lib.JSONS{Code: 203, Msg: "合同编号错误!"}
  576. c.ServeJSON()
  577. return
  578. }
  579. if len(T_product) == 0 {
  580. o.Rollback()
  581. c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
  582. c.ServeJSON()
  583. return
  584. }
  585. productList := lib.SplitString(T_product, "|")
  586. for _, v := range productList {
  587. product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
  588. product, _ := Basic.Read_Product_ById(product_id)
  589. num, _ := strconv.Atoi(strings.Split(v, "-")[1])
  590. T_relation_sn := strings.Split(v, "-")[2]
  591. if T_relation_sn == "" && product.T_relation_sn == 1 {
  592. o.Rollback()
  593. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!", product.T_name)}
  594. c.ServeJSON()
  595. return
  596. }
  597. // 2、更新设备状态为已出库
  598. if len(T_relation_sn) > 0 {
  599. snList := strings.Split(T_relation_sn, ",")
  600. for _, sn := range snList {
  601. mqtt := Stock.Read_MqttUser(sn)
  602. device := Stock.Device{
  603. T_contract_number: T_contract_number,
  604. T_product_id: product_id,
  605. T_out_number: T_number,
  606. T_sn: sn,
  607. T_iccid: mqtt.Iccid,
  608. T_imei: mqtt.Imei,
  609. T_State: 1,
  610. }
  611. _, err = DeviceDao.AddOrUpdate_Device(device, 1)
  612. if err != nil {
  613. o.Rollback()
  614. c.Data["json"] = lib.JSONS{Code: 202, Msg: "出库失败"}
  615. c.ServeJSON()
  616. return
  617. }
  618. }
  619. }
  620. // 3、添加出库产品清单
  621. stockOutProduct := Stock.StockOutProduct{
  622. T_number: T_number,
  623. T_product_id: product_id,
  624. T_depot_id: T_depot_id,
  625. T_num: num, // 出库数量
  626. T_date: T_date, // 出库数量
  627. T_relation_sn: T_relation_sn,
  628. }
  629. _, err = StockOutProductDao.Add_StockOutProduct(stockOutProduct)
  630. if err != nil {
  631. o.Rollback()
  632. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  633. c.ServeJSON()
  634. return
  635. }
  636. // 4、更改合同产品列表清单
  637. contractProduct, _ := ContractProductDao.Read_ContractProduct_ByT_number_T_product_id(T_contract_number, product_id)
  638. contractProduct.T_product_out += num
  639. if contractProduct.T_product_out > contractProduct.T_product_total && T_type == 2 {
  640. o.Rollback()
  641. p, _ := Basic.Read_Product_ById(product_id)
  642. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("【%s】出库数量超过预计出库数量!", p.T_name)}
  643. c.ServeJSON()
  644. return
  645. }
  646. contractProduct.T_State = 2
  647. if contractProduct.T_product_out == 0 {
  648. contractProduct.T_State = 1
  649. }
  650. if contractProduct.T_product_out == contractProduct.T_product_total {
  651. contractProduct.T_State = 3
  652. }
  653. err = ContractProductDao.Update_ContractProduct(contractProduct, "T_product_out", "T_State")
  654. if err != nil {
  655. o.Rollback()
  656. c.Data["json"] = lib.JSONS{Code: 202, Msg: "更新合同产品清单失败"}
  657. c.ServeJSON()
  658. return
  659. }
  660. // 5、更新产品库存列表
  661. _, err = StockDao.AddOrUpdate_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 1)
  662. if err != nil {
  663. o.Rollback()
  664. c.Data["json"] = lib.JSONS{Code: 203, Msg: "更新库存失败"}
  665. c.ServeJSON()
  666. return
  667. }
  668. }
  669. o.Commit()
  670. o2 := orm.NewOrm()
  671. o2.Begin()
  672. ContractDao2 := Contract.NewContract(o2)
  673. ContractProductDao2 := Contract.NewContractProduct(o2)
  674. // 5、更新合同出库状态
  675. var T_out int
  676. if contract.T_State == 1 {
  677. T_out = 2
  678. // 查询合同产品清单是否全部都为已出库
  679. state := ContractProductDao2.Read_ContractProduct_T_State_List(contract.T_number)
  680. if state == 1 {
  681. T_out = 1
  682. }
  683. if state == 3 {
  684. T_out = 3
  685. }
  686. }
  687. if T_out != contract.T_out {
  688. contract.T_out = T_out
  689. err = ContractDao2.Update_Contract(contract, "T_out")
  690. if err != nil {
  691. o2.Rollback()
  692. c.Data["json"] = lib.JSONS{Code: 202, Msg: "更新合同出库状态失败"}
  693. c.ServeJSON()
  694. return
  695. }
  696. }
  697. o2.Commit()
  698. NatsServer.AddUserLogs(c.User.T_uuid, "出库", "出库", var_)
  699. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  700. c.ServeJSON()
  701. return
  702. }
  703. func (c *StockController) StockOut_Edit() {
  704. T_number := c.GetString("T_number")
  705. T_remark := c.GetString("T_remark")
  706. T_delivery_type, _ := c.GetInt("T_delivery_type")
  707. T_signer_unit := c.GetString("T_signer_unit")
  708. T_signer := c.GetString("T_signer")
  709. T_signer_phone := c.GetString("T_signer_phone")
  710. T_signer_date := c.GetString("T_signer_date")
  711. T_courier_number := c.GetString("T_courier_number")
  712. o := orm.NewOrm()
  713. StockOutDao := Stock.NewStockOut(o)
  714. stockOut, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  715. if err != nil {
  716. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库编号错误!"}
  717. c.ServeJSON()
  718. return
  719. }
  720. if len(T_remark) > 0 {
  721. stockOut.T_remark = T_remark
  722. }
  723. if T_delivery_type > 0 {
  724. stockOut.T_delivery_type = T_delivery_type
  725. }
  726. if len(T_signer_unit) > 0 {
  727. stockOut.T_signer_unit = T_signer_unit
  728. }
  729. if len(T_signer) > 0 {
  730. stockOut.T_signer = T_signer
  731. }
  732. if len(T_signer_phone) > 0 {
  733. stockOut.T_signer_phone = T_signer_phone
  734. }
  735. if len(T_signer_date) > 0 {
  736. stockOut.T_signer_date = T_signer_date
  737. }
  738. if len(T_courier_number) > 0 {
  739. stockOut.T_courier_number = T_courier_number
  740. }
  741. err = StockOutDao.Update_StockOut(stockOut, "T_remark", "T_delivery_type", "T_signer_unit", "T_signer", "T_signer_phone", "T_signer_date", "T_courier_number")
  742. if err != nil {
  743. o.Rollback()
  744. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  745. c.ServeJSON()
  746. return
  747. }
  748. NatsServer.AddUserLogs(c.User.T_uuid, "出库", "修改发货单", stockOut)
  749. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  750. c.ServeJSON()
  751. return
  752. }
  753. func Cron_StockMonth() {
  754. //创建一个定时任务对象
  755. c := cron.New(cron.WithSeconds())
  756. //给对象增加定时任务
  757. // @monthly 每月运行一次,每月第一天午夜 0 0 0 1 * *
  758. //c.AddFunc("0 */1 * * * ?", Cron_StockMonth_Add)
  759. c.AddFunc("@monthly", Cron_StockMonth_Add)
  760. //启动定时任务
  761. c.Start()
  762. defer c.Stop()
  763. //查询语句,阻塞,让main函数不退出,保持程序运行
  764. select {}
  765. }
  766. // 保存每月入库出库明细
  767. func Cron_StockMonth_Add() {
  768. T_month := time.Now().AddDate(0, -1, 0).Format("2006-01")
  769. logs.Info("开始统计" + T_month + "库存明细数据")
  770. o := orm.NewOrm()
  771. StockDao := Stock.NewStock(o)
  772. StockOutDao := Stock.NewStockOut(o)
  773. StockMonthDao := Stock.NewStockMonth(o)
  774. StockOutProductDao := Stock.NewStockOutProduct(o)
  775. StockInProductDao := Stock.NewStockInProduct(o)
  776. stockList, _ := StockDao.Read_Stock_List(0, 0, "", "", 0, 9999)
  777. for _, stock := range stockList {
  778. stockMonth := Stock.StockMonth{
  779. T_depot_id: stock.T_depot_id,
  780. T_product_id: stock.T_product_id,
  781. T_product_class: stock.T_product_class,
  782. T_month: T_month,
  783. }
  784. // 获取当前产品本月出库数量
  785. stockMonth.T_in = StockInProductDao.Read_StockIn_Total(stock.T_depot_id, stock.T_product_id, T_month)
  786. stockMonth.T_out = StockOutProductDao.Read_StockOut_Total(stock.T_depot_id, stock.T_product_id, T_month)
  787. s := StockMonthDao.Read_StockMonth_ByT_depot_id_T_product_id(stock.T_depot_id, stock.T_product_id, T_month)
  788. if len(s) > 0 {
  789. stockMonth.T_beginning = s[0].T_ending
  790. } else {
  791. stockMonth.T_beginning = 0
  792. }
  793. // 期末库存 = 期初库存+入库-出库
  794. stockMonth.T_ending = stockMonth.T_beginning + stockMonth.T_in - stockMonth.T_out
  795. stockMonth.T_project = StockOutDao.Read_StockOut_T_contract_number(stock.T_depot_id, stock.T_product_id, T_month)
  796. _, err := StockMonthDao.Add_StockMonth(stockMonth)
  797. if err != nil {
  798. NatsServer.AddSysLogs("库存明细统计", fmt.Sprintf("库存明细统计失败%s:%d:%d", T_month, stock.T_depot_id, stock.T_product_id), stockMonth)
  799. }
  800. }
  801. }