Stock.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  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. NatsServer.AddUserLogs(c.User.T_uuid, "仓库管理", "入库", T_product)
  355. var_ := Stock.StockIn{
  356. T_number: T_number,
  357. T_depot_id: T_depot_id,
  358. T_date: T_date,
  359. T_remark: T_remark,
  360. T_submit: c.User.T_uuid,
  361. }
  362. StockInProductDao := Stock.NewStockInProduct(o)
  363. StockDao := Stock.NewStock(o)
  364. DeviceDao := Stock.NewDevice(o)
  365. IotCardDao := Property.NewIotCard(&o)
  366. _, err := StockInDao.Add_StockIn(var_)
  367. if err != nil {
  368. o.Rollback()
  369. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  370. c.ServeJSON()
  371. return
  372. }
  373. if len(T_product) == 0 {
  374. o.Rollback()
  375. c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
  376. c.ServeJSON()
  377. return
  378. }
  379. productList := lib.SplitString(T_product, "|")
  380. for _, v := range productList {
  381. product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
  382. product, _ := Basic.Read_Product_ById(product_id)
  383. num, _ := strconv.Atoi(strings.Split(v, "-")[1])
  384. T_relation_sn := strings.Split(v, "-")[2]
  385. if T_relation_sn == "" && product.T_relation_sn == 1 {
  386. o.Rollback()
  387. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!", T_relation_sn)}
  388. c.ServeJSON()
  389. return
  390. }
  391. if len(T_relation_sn) > 0 {
  392. snList := strings.Split(strings.Trim(T_relation_sn, ","), ",")
  393. for _, sn := range snList {
  394. mqtt := Stock.Read_MqttUser(sn)
  395. // 添加设备
  396. device := Stock.Device{
  397. T_contract_number: "",
  398. T_out_number: "",
  399. T_product_id: product_id,
  400. T_in_number: T_number,
  401. T_sn: sn,
  402. T_iccid: mqtt.Iccid,
  403. T_imei: mqtt.Imei,
  404. T_State: 2,
  405. }
  406. _, err = DeviceDao.AddOrUpdate_Device(device, 2)
  407. if err != nil {
  408. o.Rollback()
  409. c.Data["json"] = lib.JSONS{Code: 202, Msg: sn + "入库失败"}
  410. c.ServeJSON()
  411. return
  412. }
  413. // 添加物联网卡
  414. iotCard := Property.IotCard{
  415. T_iccid: mqtt.Iccid,
  416. T_sn: sn,
  417. T_State: 2, //1-未使用 2-已使用 3-已作废
  418. T_type: "4G",
  419. }
  420. _, err = IotCardDao.AddOrUpdate_IotCard(iotCard)
  421. if err != nil {
  422. o.Rollback()
  423. c.Data["json"] = lib.JSONS{Code: 202, Msg: "入库失败"}
  424. c.ServeJSON()
  425. return
  426. }
  427. }
  428. }
  429. stockInProduct := Stock.StockInProduct{
  430. T_number: T_number,
  431. T_product_id: product_id,
  432. T_depot_id: T_depot_id,
  433. T_num: num, // 入库数量
  434. T_date: T_date, // 入库日期
  435. T_relation_sn: T_relation_sn,
  436. }
  437. _, err = StockInProductDao.Add_StockInProduct(stockInProduct)
  438. if err != nil {
  439. o.Rollback()
  440. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  441. c.ServeJSON()
  442. return
  443. }
  444. _, err = StockDao.AddOrUpdate_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 2)
  445. if err != nil {
  446. o.Rollback()
  447. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  448. c.ServeJSON()
  449. return
  450. }
  451. }
  452. o.Commit()
  453. NatsServer.AddUserLogs(c.User.T_uuid, "入库", "入库", var_)
  454. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  455. c.ServeJSON()
  456. return
  457. }
  458. func (c *StockController) StockOut_List() {
  459. // 分页参数 初始化
  460. page, _ := c.GetInt("page")
  461. if page < 1 {
  462. page = 1
  463. }
  464. page_z, _ := c.GetInt("page_z")
  465. if page_z < 1 {
  466. page_z = conf.Page_size
  467. }
  468. // 查询
  469. T_depot_id, _ := c.GetInt("T_depot_id")
  470. T_contract_number := c.GetString("T_contract_number")
  471. T_start_date := c.GetString("T_start_date")
  472. T_end_date := c.GetString("T_end_date")
  473. userList, _ := NatsServer.Read_User_List_All()
  474. Account.Read_User_All_Map(userList)
  475. Basic.Read_Depot_All_Map()
  476. StockOutDao := Stock.NewStockOut(orm.NewOrm())
  477. R_List, R_cnt := StockOutDao.Read_StockOut_List(T_depot_id, T_contract_number, T_start_date, T_end_date, page, page_z)
  478. var r_jsons lib.R_JSONS
  479. r_jsons.Num = R_cnt
  480. r_jsons.Data = R_List
  481. r_jsons.Page = page
  482. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  483. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  484. c.ServeJSON()
  485. return
  486. }
  487. func (c *StockController) StockOut_Get() {
  488. // 查询
  489. T_number := c.GetString("T_number")
  490. o := orm.NewOrm()
  491. StockOutDao := Stock.NewStockOut(o)
  492. StockOutProductDao := Stock.NewStockOutProduct(o)
  493. stockIn, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  494. if err != nil {
  495. c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
  496. c.ServeJSON()
  497. return
  498. }
  499. productList := StockOutProductDao.Read_StockOutProduct_List(stockIn.T_number)
  500. var pList []Stock.StockOutProduct_R
  501. for _, v := range productList {
  502. pList = append(pList, Stock.StockOutProductToStockOutProduct_R(v))
  503. }
  504. userList, _ := NatsServer.Read_User_List_All()
  505. Account.Read_User_All_Map(userList)
  506. Basic.Read_Depot_All_Map()
  507. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Stock.StockOutToStockOut_Detail(stockIn, pList)}
  508. c.ServeJSON()
  509. return
  510. }
  511. func (c *StockController) StockOut_Add() {
  512. rand_x := 0
  513. T_number := ""
  514. o := orm.NewOrm()
  515. o.Begin()
  516. StockOutDao := Stock.NewStockOut(o)
  517. for true {
  518. T_number = "CK-" + lib.GetRandstring(8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", int64(rand_x))
  519. _, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  520. if err != nil && err.Error() == orm.ErrNoRows.Error() {
  521. break
  522. }
  523. rand_x += 1
  524. }
  525. T_contract_number := c.GetString("T_contract_number")
  526. T_depot_id, _ := c.GetInt("T_depot_id")
  527. T_type, _ := c.GetInt("T_type") // 出库类型 1-领料出库 2-销售出库
  528. T_date := c.GetString("T_date")
  529. T_receive := c.GetString("T_receive")
  530. T_product := c.GetString("T_product")
  531. T_remark := c.GetString("T_remark")
  532. T_delivery_type, _ := c.GetInt("T_delivery_type")
  533. T_signer_unit := c.GetString("T_signer_unit")
  534. T_signer := c.GetString("T_signer")
  535. T_signer_phone := c.GetString("T_signer_phone")
  536. T_signer_date := c.GetString("T_signer_date")
  537. T_courier_number := c.GetString("T_courier_number")
  538. if _, is := lib.DateStrToTime(T_date); !is {
  539. c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
  540. c.ServeJSON()
  541. return
  542. }
  543. var_ := Stock.StockOut{
  544. T_number: T_number,
  545. T_contract_number: T_contract_number,
  546. T_depot_id: T_depot_id,
  547. T_type: T_type,
  548. T_date: T_date,
  549. T_receive: T_receive,
  550. T_remark: T_remark,
  551. T_submit: c.User.T_uuid,
  552. // 销售出库
  553. T_delivery_type: T_delivery_type, // 1-自送 2-自提 3-快递
  554. T_signer_unit: T_signer_unit,
  555. T_signer: T_signer,
  556. T_signer_phone: T_signer_phone,
  557. T_signer_date: T_signer_date,
  558. T_courier_number: T_courier_number,
  559. }
  560. StockOutProductDao := Stock.NewStockOutProduct(o)
  561. StockDao := Stock.NewStock(o)
  562. DeviceDao := Stock.NewDevice(o)
  563. ContractDao := Contract.NewContract(o)
  564. ContractProductDao := Contract.NewContractProduct(o)
  565. _, err := StockOutDao.Add_StockOut(var_)
  566. if err != nil {
  567. o.Rollback()
  568. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  569. c.ServeJSON()
  570. return
  571. }
  572. // 1、添加出库单
  573. contract, _ := ContractDao.Read_Contract_ByT_number(T_contract_number)
  574. if contract.Id == 0 && T_type == 2 {
  575. o.Rollback()
  576. c.Data["json"] = lib.JSONS{Code: 203, Msg: "合同编号错误!"}
  577. c.ServeJSON()
  578. return
  579. }
  580. if len(T_product) == 0 {
  581. o.Rollback()
  582. c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
  583. c.ServeJSON()
  584. return
  585. }
  586. productList := lib.SplitString(T_product, "|")
  587. for _, v := range productList {
  588. product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
  589. product, _ := Basic.Read_Product_ById(product_id)
  590. num, _ := strconv.Atoi(strings.Split(v, "-")[1])
  591. T_relation_sn := strings.Split(v, "-")[2]
  592. if T_relation_sn == "" && product.T_relation_sn == 1 {
  593. o.Rollback()
  594. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!", product.T_name)}
  595. c.ServeJSON()
  596. return
  597. }
  598. // 2、更新设备状态为已出库
  599. if len(T_relation_sn) > 0 {
  600. snList := strings.Split(T_relation_sn, ",")
  601. for _, sn := range snList {
  602. mqtt := Stock.Read_MqttUser(sn)
  603. device := Stock.Device{
  604. T_contract_number: T_contract_number,
  605. T_product_id: product_id,
  606. T_out_number: T_number,
  607. T_sn: sn,
  608. T_iccid: mqtt.Iccid,
  609. T_imei: mqtt.Imei,
  610. T_State: 1,
  611. }
  612. _, err = DeviceDao.AddOrUpdate_Device(device, 1)
  613. if err != nil {
  614. o.Rollback()
  615. c.Data["json"] = lib.JSONS{Code: 202, Msg: "出库失败"}
  616. c.ServeJSON()
  617. return
  618. }
  619. }
  620. }
  621. // 3、添加出库产品清单
  622. stockOutProduct := Stock.StockOutProduct{
  623. T_number: T_number,
  624. T_product_id: product_id,
  625. T_depot_id: T_depot_id,
  626. T_num: num, // 出库数量
  627. T_date: T_date, // 出库数量
  628. T_relation_sn: T_relation_sn,
  629. }
  630. _, err = StockOutProductDao.Add_StockOutProduct(stockOutProduct)
  631. if err != nil {
  632. o.Rollback()
  633. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  634. c.ServeJSON()
  635. return
  636. }
  637. // 4、更改合同产品列表清单
  638. contractProduct, _ := ContractProductDao.Read_ContractProduct_ByT_number_T_product_id(T_contract_number, product_id)
  639. contractProduct.T_product_out += num
  640. if contractProduct.T_product_out > contractProduct.T_product_total && T_type == 2 {
  641. o.Rollback()
  642. p, _ := Basic.Read_Product_ById(product_id)
  643. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("【%s】出库数量超过预计出库数量!", p.T_name)}
  644. c.ServeJSON()
  645. return
  646. }
  647. contractProduct.T_State = 2
  648. if contractProduct.T_product_out == 0 {
  649. contractProduct.T_State = 1
  650. }
  651. if contractProduct.T_product_out == contractProduct.T_product_total {
  652. contractProduct.T_State = 3
  653. }
  654. err = ContractProductDao.Update_ContractProduct(contractProduct, "T_product_out", "T_State")
  655. if err != nil {
  656. o.Rollback()
  657. c.Data["json"] = lib.JSONS{Code: 202, Msg: "更新合同产品清单失败"}
  658. c.ServeJSON()
  659. return
  660. }
  661. // 5、更新产品库存列表
  662. _, err = StockDao.AddOrUpdate_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 1)
  663. if err != nil {
  664. o.Rollback()
  665. c.Data["json"] = lib.JSONS{Code: 203, Msg: "更新库存失败"}
  666. c.ServeJSON()
  667. return
  668. }
  669. }
  670. o.Commit()
  671. o2 := orm.NewOrm()
  672. o2.Begin()
  673. ContractDao2 := Contract.NewContract(o2)
  674. ContractProductDao2 := Contract.NewContractProduct(o2)
  675. // 5、更新合同出库状态
  676. var T_out int
  677. if contract.T_State == 1 {
  678. T_out = 2
  679. // 查询合同产品清单是否全部都为已出库
  680. state := ContractProductDao2.Read_ContractProduct_T_State_List(contract.T_number)
  681. if state == 1 {
  682. T_out = 1
  683. }
  684. if state == 3 {
  685. T_out = 3
  686. }
  687. }
  688. if T_out != contract.T_out {
  689. contract.T_out = T_out
  690. err = ContractDao2.Update_Contract(contract, "T_out")
  691. if err != nil {
  692. o2.Rollback()
  693. c.Data["json"] = lib.JSONS{Code: 202, Msg: "更新合同出库状态失败"}
  694. c.ServeJSON()
  695. return
  696. }
  697. }
  698. o2.Commit()
  699. NatsServer.AddUserLogs(c.User.T_uuid, "出库", "出库", var_)
  700. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  701. c.ServeJSON()
  702. return
  703. }
  704. func (c *StockController) StockOut_Edit() {
  705. T_number := c.GetString("T_number")
  706. T_remark := c.GetString("T_remark")
  707. T_delivery_type, _ := c.GetInt("T_delivery_type")
  708. T_signer_unit := c.GetString("T_signer_unit")
  709. T_signer := c.GetString("T_signer")
  710. T_signer_phone := c.GetString("T_signer_phone")
  711. T_signer_date := c.GetString("T_signer_date")
  712. T_courier_number := c.GetString("T_courier_number")
  713. o := orm.NewOrm()
  714. StockOutDao := Stock.NewStockOut(o)
  715. stockOut, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  716. if err != nil {
  717. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库编号错误!"}
  718. c.ServeJSON()
  719. return
  720. }
  721. if len(T_remark) > 0 {
  722. stockOut.T_remark = T_remark
  723. }
  724. if T_delivery_type > 0 {
  725. stockOut.T_delivery_type = T_delivery_type
  726. }
  727. if len(T_signer_unit) > 0 {
  728. stockOut.T_signer_unit = T_signer_unit
  729. }
  730. if len(T_signer) > 0 {
  731. stockOut.T_signer = T_signer
  732. }
  733. if len(T_signer_phone) > 0 {
  734. stockOut.T_signer_phone = T_signer_phone
  735. }
  736. if len(T_signer_date) > 0 {
  737. stockOut.T_signer_date = T_signer_date
  738. }
  739. if len(T_courier_number) > 0 {
  740. stockOut.T_courier_number = T_courier_number
  741. }
  742. err = StockOutDao.Update_StockOut(stockOut, "T_remark", "T_delivery_type", "T_signer_unit", "T_signer", "T_signer_phone", "T_signer_date", "T_courier_number")
  743. if err != nil {
  744. o.Rollback()
  745. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  746. c.ServeJSON()
  747. return
  748. }
  749. NatsServer.AddUserLogs(c.User.T_uuid, "出库", "修改发货单", stockOut)
  750. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  751. c.ServeJSON()
  752. return
  753. }
  754. func Cron_StockMonth() {
  755. //创建一个定时任务对象
  756. c := cron.New(cron.WithSeconds())
  757. //给对象增加定时任务
  758. // @monthly 每月运行一次,每月第一天午夜 0 0 0 1 * *
  759. //c.AddFunc("0 */1 * * * ?", Cron_StockMonth_Add)
  760. c.AddFunc("@monthly", Cron_StockMonth_Add)
  761. //启动定时任务
  762. c.Start()
  763. defer c.Stop()
  764. //查询语句,阻塞,让main函数不退出,保持程序运行
  765. select {}
  766. }
  767. // 保存每月入库出库明细
  768. func Cron_StockMonth_Add() {
  769. T_month := time.Now().AddDate(0, -1, 0).Format("2006-01")
  770. logs.Info("开始统计" + T_month + "库存明细数据")
  771. o := orm.NewOrm()
  772. StockDao := Stock.NewStock(o)
  773. StockOutDao := Stock.NewStockOut(o)
  774. StockMonthDao := Stock.NewStockMonth(o)
  775. StockOutProductDao := Stock.NewStockOutProduct(o)
  776. StockInProductDao := Stock.NewStockInProduct(o)
  777. stockList, _ := StockDao.Read_Stock_List(0, 0, "", "", 0, 9999)
  778. for _, stock := range stockList {
  779. stockMonth := Stock.StockMonth{
  780. T_depot_id: stock.T_depot_id,
  781. T_product_id: stock.T_product_id,
  782. T_product_class: stock.T_product_class,
  783. T_month: T_month,
  784. }
  785. // 获取当前产品本月出库数量
  786. stockMonth.T_in = StockInProductDao.Read_StockIn_Total(stock.T_depot_id, stock.T_product_id, T_month)
  787. stockMonth.T_out = StockOutProductDao.Read_StockOut_Total(stock.T_depot_id, stock.T_product_id, T_month)
  788. s := StockMonthDao.Read_StockMonth_ByT_depot_id_T_product_id(stock.T_depot_id, stock.T_product_id, T_month)
  789. if len(s) > 0 {
  790. stockMonth.T_beginning = s[0].T_ending
  791. } else {
  792. stockMonth.T_beginning = 0
  793. }
  794. // 期末库存 = 期初库存+入库-出库
  795. stockMonth.T_ending = stockMonth.T_beginning + stockMonth.T_in - stockMonth.T_out
  796. stockMonth.T_project = StockOutDao.Read_StockOut_T_contract_number(stock.T_depot_id, stock.T_product_id, T_month)
  797. _, err := StockMonthDao.Add_StockMonth(stockMonth)
  798. if err != nil {
  799. NatsServer.AddSysLogs("库存明细统计", fmt.Sprintf("库存明细统计失败%s:%d:%d", T_month, stock.T_depot_id, stock.T_product_id), stockMonth)
  800. }
  801. }
  802. }