Stock.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  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. var j = 0
  189. for _, r := range class_List {
  190. StockList := StockMonthDao.Read_StockMonth_List(T_depot_id, T_product_id, r.Id, T_start_date, T_end_date)
  191. if len(StockList) == 0 {
  192. continue
  193. }
  194. if j == 0 {
  195. f.SetSheetName("Sheet1", r.T_name)
  196. } else {
  197. f.NewSheet(r.T_name)
  198. }
  199. j += 1
  200. f.MergeCell(r.T_name, "A1", "J1")
  201. f.SetRowStyle(r.T_name, 1, 1, Style1)
  202. f.SetCellValue(r.T_name, "A1", fmt.Sprintf("宝智达科技产品进销存统计表"))
  203. f.SetRowHeight(r.T_name, 1, 30)
  204. // 这里设置表头
  205. f.SetCellStyle(r.T_name, "A2", "J2", Style2)
  206. f.SetRowHeight(r.T_name, 2, 20)
  207. f.SetCellValue(r.T_name, "A2", "序号")
  208. f.SetCellValue(r.T_name, "B2", "产品名称")
  209. f.SetCellValue(r.T_name, "C2", "型号")
  210. f.SetCellValue(r.T_name, "D2", "规格")
  211. f.SetCellValue(r.T_name, "E2", "月份")
  212. f.SetCellValue(r.T_name, "F2", "期初库存")
  213. f.SetCellValue(r.T_name, "G2", "当月入库")
  214. f.SetCellValue(r.T_name, "H2", "当月出库")
  215. f.SetCellValue(r.T_name, "I2", "期末库存")
  216. f.SetCellValue(r.T_name, "J2", "出库项目")
  217. //f.SetCellValue(r.T_name, "K2", "备注")
  218. // 设置列宽
  219. f.SetColWidth(r.T_name, "A", "A", 10)
  220. f.SetColWidth(r.T_name, "B", "B", 10)
  221. f.SetColWidth(r.T_name, "C", "D", 10)
  222. f.SetColWidth(r.T_name, "D", "D", 10)
  223. f.SetColWidth(r.T_name, "E", "E", 10)
  224. f.SetColWidth(r.T_name, "F", "F", 10)
  225. f.SetColWidth(r.T_name, "G", "G", 10)
  226. f.SetColWidth(r.T_name, "H", "H", 10)
  227. f.SetColWidth(r.T_name, "I", "I", 10)
  228. f.SetColWidth(r.T_name, "J", "J", 10)
  229. //f.SetColWidth(r.T_name, "K", "K", 10)
  230. line := 2
  231. // 循环写入数据
  232. for _, v := range StockList {
  233. line++
  234. product, _ := Basic.Read_Product_ById(v.T_product_id)
  235. f.SetCellValue(r.T_name, fmt.Sprintf("A%d", line), line-2)
  236. f.SetCellValue(r.T_name, fmt.Sprintf("B%d", line), product.T_name)
  237. f.SetCellValue(r.T_name, fmt.Sprintf("C%d", line), product.T_model)
  238. f.SetCellValue(r.T_name, fmt.Sprintf("D%d", line), product.T_spec)
  239. f.SetCellValue(r.T_name, fmt.Sprintf("E%d", line), v.T_month)
  240. f.SetCellValue(r.T_name, fmt.Sprintf("F%d", line), v.T_beginning)
  241. f.SetCellValue(r.T_name, fmt.Sprintf("G%d", line), v.T_in)
  242. f.SetCellValue(r.T_name, fmt.Sprintf("H%d", line), v.T_out)
  243. f.SetCellValue(r.T_name, fmt.Sprintf("I%d", line), v.T_ending)
  244. f.SetCellValue(r.T_name, fmt.Sprintf("J%d", line), v.T_project)
  245. }
  246. Style4, _ := f.NewStyle(
  247. &excelize.Style{
  248. Font: &excelize.Font{Size: 10, Family: "宋体"},
  249. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
  250. Border: []excelize.Border{
  251. {Type: "left", Color: "000000", Style: 1},
  252. {Type: "top", Color: "000000", Style: 1},
  253. {Type: "bottom", Color: "000000", Style: 1},
  254. {Type: "right", Color: "000000", Style: 1},
  255. },
  256. })
  257. f.SetCellStyle(r.T_name, "A2", fmt.Sprintf("J%d", line), Style4)
  258. }
  259. // 保存文件
  260. if err := f.SaveAs("ofile/" + filename + ".xlsx"); err != nil {
  261. fmt.Println(err)
  262. }
  263. var url string
  264. //// 上传 OSS
  265. nats := natslibs.NewNats(Nats.Nats, conf.NatsSubj_Prefix)
  266. url, is := nats.Qiniu_UploadFile(lib.GetCurrentDirectory()+"/ofile/"+filename+".xlsx", "ofile/"+filename+".xlsx")
  267. if !is {
  268. c.Data["json"] = lib.JSONS{Code: 202, Msg: "oss!"}
  269. c.ServeJSON()
  270. return
  271. }
  272. //删除目录
  273. err := os.Remove("ofile/" + filename + ".xlsx")
  274. if err != nil {
  275. logs.Error(lib.FuncName(), err)
  276. }
  277. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: url}
  278. c.ServeJSON()
  279. return
  280. }
  281. func (c *StockController) StockIn_List() {
  282. // 分页参数 初始化
  283. page, _ := c.GetInt("page")
  284. if page < 1 {
  285. page = 1
  286. }
  287. page_z, _ := c.GetInt("page_z")
  288. if page_z < 1 {
  289. page_z = conf.Page_size
  290. }
  291. // 查询
  292. T_depot_id, _ := c.GetInt("T_depot_id")
  293. T_start_date := c.GetString("T_start_date")
  294. T_end_date := c.GetString("T_end_date")
  295. userList, _ := NatsServer.Read_User_List_All()
  296. Account.Read_User_All_Map(userList)
  297. Basic.Read_Depot_All_Map()
  298. StockInDao := Stock.NewStockIn(orm.NewOrm())
  299. R_List, R_cnt := StockInDao.Read_StockIn_List(T_depot_id, T_start_date, T_end_date, page, page_z)
  300. var r_jsons lib.R_JSONS
  301. r_jsons.Num = R_cnt
  302. r_jsons.Data = R_List
  303. r_jsons.Page = page
  304. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  305. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  306. c.ServeJSON()
  307. return
  308. }
  309. func (c *StockController) StockIn_List_Product() {
  310. // 分页参数 初始化
  311. page, _ := c.GetInt("page")
  312. if page < 1 {
  313. page = 1
  314. }
  315. page_z, _ := c.GetInt("page_z")
  316. if page_z < 1 {
  317. page_z = conf.Page_size
  318. }
  319. // 查询
  320. T_depot_id, _ := c.GetInt("T_depot_id")
  321. T_name := c.GetString("T_name")
  322. T_start_date := c.GetString("T_start_date")
  323. T_end_date := c.GetString("T_end_date")
  324. userList, _ := NatsServer.Read_User_List_All()
  325. Account.Read_User_All_Map(userList)
  326. Basic.Read_Depot_All_Map()
  327. StockInDao := Stock.NewStockIn(orm.NewOrm())
  328. R_List, R_cnt := StockInDao.Read_StockInProduct_List(T_name, T_start_date, T_end_date, T_depot_id, page, page_z)
  329. var r_jsons lib.R_JSONS
  330. r_jsons.Num = R_cnt
  331. r_jsons.Data = R_List
  332. r_jsons.Page = page
  333. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  334. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  335. c.ServeJSON()
  336. return
  337. }
  338. func (c *StockController) StockIn_Get() {
  339. // 查询
  340. T_number := c.GetString("T_number")
  341. o := orm.NewOrm()
  342. StockInDao := Stock.NewStockIn(o)
  343. StockInProductDao := Stock.NewStockInProduct(o)
  344. stockIn, err := StockInDao.Read_StockIn_ByT_number(T_number)
  345. if err != nil {
  346. c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
  347. c.ServeJSON()
  348. return
  349. }
  350. productList := StockInProductDao.Read_StockInProduct_List_ByT_number(stockIn.T_number)
  351. var pList []Stock.StockInProduct_R
  352. for _, v := range productList {
  353. pList = append(pList, Stock.StockInProductToStockInProduct_R(v))
  354. }
  355. userList, _ := NatsServer.Read_User_List_All()
  356. Account.Read_User_All_Map(userList)
  357. Basic.Read_Depot_All_Map()
  358. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Stock.StockInToStockIn_Detail(stockIn, pList)}
  359. c.ServeJSON()
  360. return
  361. }
  362. func (c *StockController) StockIn_Add() {
  363. rand_x := 0
  364. T_number := ""
  365. o := orm.NewOrm()
  366. o.Begin()
  367. StockInDao := Stock.NewStockIn(o)
  368. for true {
  369. T_number = "RK-" + lib.GetRandstring(8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", int64(rand_x))
  370. _, err := StockInDao.Read_StockIn_ByT_number(T_number)
  371. if err != nil && err.Error() == orm.ErrNoRows.Error() {
  372. break
  373. }
  374. rand_x += 1
  375. }
  376. T_depot_id, _ := c.GetInt("T_depot_id")
  377. T_date := c.GetString("T_date")
  378. T_product := c.GetString("T_product")
  379. T_remark := c.GetString("T_remark")
  380. if _, is := lib.DateStrToTime(T_date); !is {
  381. c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
  382. c.ServeJSON()
  383. return
  384. }
  385. NatsServer.AddUserLogs(c.User.T_uuid, "仓库管理", "入库", T_product)
  386. var_ := Stock.StockIn{
  387. T_number: T_number,
  388. T_depot_id: T_depot_id,
  389. T_date: T_date,
  390. T_remark: T_remark,
  391. T_submit: c.User.T_uuid,
  392. }
  393. StockInProductDao := Stock.NewStockInProduct(o)
  394. StockDao := Stock.NewStock(o)
  395. DeviceDao := Stock.NewDevice(o)
  396. IotCardDao := Property.NewIotCard(&o)
  397. _, err := StockInDao.Add_StockIn(var_)
  398. if err != nil {
  399. o.Rollback()
  400. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  401. c.ServeJSON()
  402. return
  403. }
  404. if len(T_product) == 0 {
  405. o.Rollback()
  406. c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
  407. c.ServeJSON()
  408. return
  409. }
  410. productList := lib.SplitString(T_product, "|")
  411. for _, v := range productList {
  412. product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
  413. product, _ := Basic.Read_Product_ById(product_id)
  414. num, _ := strconv.Atoi(strings.Split(v, "-")[1])
  415. T_relation_sn := strings.Split(v, "-")[2]
  416. if T_relation_sn == "" && product.T_relation_sn == 1 {
  417. o.Rollback()
  418. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!", T_relation_sn)}
  419. c.ServeJSON()
  420. return
  421. }
  422. if len(T_relation_sn) > 0 {
  423. snList := strings.Split(strings.Trim(T_relation_sn, ","), ",")
  424. for _, sn := range snList {
  425. mqtt := Stock.Read_MqttUser(sn)
  426. // 添加设备
  427. device := Stock.Device{
  428. T_contract_number: "",
  429. T_out_number: "",
  430. T_product_id: product_id,
  431. T_in_number: T_number,
  432. T_sn: sn,
  433. T_iccid: mqtt.Iccid,
  434. T_imei: mqtt.Imei,
  435. T_State: 2,
  436. }
  437. _, err = DeviceDao.AddOrUpdate_Device(device, 2)
  438. if err != nil {
  439. o.Rollback()
  440. c.Data["json"] = lib.JSONS{Code: 202, Msg: sn + "入库失败"}
  441. c.ServeJSON()
  442. return
  443. }
  444. // 添加物联网卡
  445. iotCard := Property.IotCard{
  446. T_iccid: mqtt.Iccid,
  447. T_sn: sn,
  448. T_State: 2, //1-未使用 2-已使用 3-已作废
  449. T_type: "4G",
  450. }
  451. _, err = IotCardDao.AddOrUpdate_IotCard(iotCard)
  452. if err != nil {
  453. o.Rollback()
  454. c.Data["json"] = lib.JSONS{Code: 202, Msg: "入库失败"}
  455. c.ServeJSON()
  456. return
  457. }
  458. }
  459. }
  460. stockInProduct := Stock.StockInProduct{
  461. T_number: T_number,
  462. T_product_id: product_id,
  463. T_depot_id: T_depot_id,
  464. T_num: num, // 入库数量
  465. T_date: T_date, // 入库日期
  466. T_relation_sn: T_relation_sn,
  467. }
  468. _, err = StockInProductDao.Add_StockInProduct(stockInProduct)
  469. if err != nil {
  470. o.Rollback()
  471. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  472. c.ServeJSON()
  473. return
  474. }
  475. _, err = StockDao.AddOrUpdate_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 2)
  476. if err != nil {
  477. o.Rollback()
  478. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  479. c.ServeJSON()
  480. return
  481. }
  482. }
  483. o.Commit()
  484. NatsServer.AddUserLogs(c.User.T_uuid, "入库", "入库", var_)
  485. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  486. c.ServeJSON()
  487. return
  488. }
  489. func (c *StockController) StockIn_Edit() {
  490. o := orm.NewOrm()
  491. o.Begin()
  492. StockInDao := Stock.NewStockIn(o)
  493. T_number := c.GetString("T_number") // 入库单号
  494. T_depot_id, _ := c.GetInt("T_depot_id")
  495. T_date := c.GetString("T_date")
  496. T_product := c.GetString("T_product")
  497. T_remark := c.GetString("T_remark")
  498. if _, is := lib.DateStrToTime(T_date); !is {
  499. c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
  500. c.ServeJSON()
  501. return
  502. }
  503. NatsServer.AddUserLogs(c.User.T_uuid, "仓库管理", "入库", T_product)
  504. var_ := Stock.StockIn{
  505. T_number: T_number,
  506. T_depot_id: T_depot_id,
  507. T_date: T_date,
  508. T_remark: T_remark,
  509. T_submit: c.User.T_uuid,
  510. }
  511. StockInProductDao := Stock.NewStockInProduct(o)
  512. StockDao := Stock.NewStock(o)
  513. DeviceDao := Stock.NewDevice(o)
  514. IotCardDao := Property.NewIotCard(&o)
  515. _, err := StockInDao.Add_StockIn(var_)
  516. if err != nil {
  517. o.Rollback()
  518. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  519. c.ServeJSON()
  520. return
  521. }
  522. if len(T_product) == 0 {
  523. o.Rollback()
  524. c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
  525. c.ServeJSON()
  526. return
  527. }
  528. productList := lib.SplitString(T_product, "|")
  529. for _, v := range productList {
  530. product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
  531. product, _ := Basic.Read_Product_ById(product_id)
  532. num, _ := strconv.Atoi(strings.Split(v, "-")[1])
  533. T_relation_sn := strings.Split(v, "-")[2]
  534. if T_relation_sn == "" && product.T_relation_sn == 1 {
  535. o.Rollback()
  536. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!", T_relation_sn)}
  537. c.ServeJSON()
  538. return
  539. }
  540. if len(T_relation_sn) > 0 {
  541. snList := strings.Split(strings.Trim(T_relation_sn, ","), ",")
  542. for _, sn := range snList {
  543. mqtt := Stock.Read_MqttUser(sn)
  544. // 添加设备
  545. device := Stock.Device{
  546. T_contract_number: "",
  547. T_out_number: "",
  548. T_product_id: product_id,
  549. T_in_number: T_number,
  550. T_sn: sn,
  551. T_iccid: mqtt.Iccid,
  552. T_imei: mqtt.Imei,
  553. T_State: 2,
  554. }
  555. _, err = DeviceDao.AddOrUpdate_Device(device, 2)
  556. if err != nil {
  557. o.Rollback()
  558. c.Data["json"] = lib.JSONS{Code: 202, Msg: sn + "入库失败"}
  559. c.ServeJSON()
  560. return
  561. }
  562. // 添加物联网卡
  563. iotCard := Property.IotCard{
  564. T_iccid: mqtt.Iccid,
  565. T_sn: sn,
  566. T_State: 2, //1-未使用 2-已使用 3-已作废
  567. T_type: "4G",
  568. }
  569. _, err = IotCardDao.AddOrUpdate_IotCard(iotCard)
  570. if err != nil {
  571. o.Rollback()
  572. c.Data["json"] = lib.JSONS{Code: 202, Msg: "入库失败"}
  573. c.ServeJSON()
  574. return
  575. }
  576. }
  577. }
  578. stockInProduct := Stock.StockInProduct{
  579. T_number: T_number,
  580. T_product_id: product_id,
  581. T_depot_id: T_depot_id,
  582. T_num: num, // 入库数量
  583. T_date: T_date, // 入库日期
  584. T_relation_sn: T_relation_sn,
  585. }
  586. _, err = StockInProductDao.Add_StockInProduct(stockInProduct)
  587. if err != nil {
  588. o.Rollback()
  589. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  590. c.ServeJSON()
  591. return
  592. }
  593. _, err = StockDao.AddOrUpdate_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 2)
  594. if err != nil {
  595. o.Rollback()
  596. c.Data["json"] = lib.JSONS{Code: 203, Msg: "入库失败"}
  597. c.ServeJSON()
  598. return
  599. }
  600. }
  601. o.Commit()
  602. NatsServer.AddUserLogs(c.User.T_uuid, "入库", "入库", var_)
  603. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  604. c.ServeJSON()
  605. return
  606. }
  607. func (c *StockController) StockOut_List() {
  608. // 分页参数 初始化
  609. page, _ := c.GetInt("page")
  610. if page < 1 {
  611. page = 1
  612. }
  613. page_z, _ := c.GetInt("page_z")
  614. if page_z < 1 {
  615. page_z = conf.Page_size
  616. }
  617. // 查询
  618. T_depot_id, _ := c.GetInt("T_depot_id")
  619. T_contract_number := c.GetString("T_contract_number")
  620. T_start_date := c.GetString("T_start_date")
  621. T_end_date := c.GetString("T_end_date")
  622. userList, _ := NatsServer.Read_User_List_All()
  623. Account.Read_User_All_Map(userList)
  624. Basic.Read_Depot_All_Map()
  625. StockOutDao := Stock.NewStockOut(orm.NewOrm())
  626. R_List, R_cnt := StockOutDao.Read_StockOut_List(T_depot_id, T_contract_number, T_start_date, T_end_date, page, page_z)
  627. var r_jsons lib.R_JSONS
  628. r_jsons.Num = R_cnt
  629. r_jsons.Data = R_List
  630. r_jsons.Page = page
  631. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  632. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  633. c.ServeJSON()
  634. return
  635. }
  636. func (c *StockController) StockOut_List_Product() {
  637. // 分页参数 初始化
  638. page, _ := c.GetInt("page")
  639. if page < 1 {
  640. page = 1
  641. }
  642. page_z, _ := c.GetInt("page_z")
  643. if page_z < 1 {
  644. page_z = conf.Page_size
  645. }
  646. // 查询
  647. T_depot_id, _ := c.GetInt("T_depot_id")
  648. T_name := c.GetString("T_name")
  649. T_start_date := c.GetString("T_start_date")
  650. T_end_date := c.GetString("T_end_date")
  651. userList, _ := NatsServer.Read_User_List_All()
  652. Account.Read_User_All_Map(userList)
  653. Basic.Read_Depot_All_Map()
  654. StockOutDao := Stock.NewStockOut(orm.NewOrm())
  655. R_List, R_cnt := StockOutDao.Read_StockOutProduct_List(T_name, T_start_date, T_end_date, T_depot_id, page, page_z)
  656. var r_jsons lib.R_JSONS
  657. r_jsons.Num = R_cnt
  658. r_jsons.Data = R_List
  659. r_jsons.Page = page
  660. r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))
  661. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
  662. c.ServeJSON()
  663. return
  664. }
  665. func (c *StockController) StockOut_Get() {
  666. // 查询
  667. T_number := c.GetString("T_number")
  668. o := orm.NewOrm()
  669. StockOutDao := Stock.NewStockOut(o)
  670. StockOutProductDao := Stock.NewStockOutProduct(o)
  671. stockIn, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  672. if err != nil {
  673. c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询失败!"}
  674. c.ServeJSON()
  675. return
  676. }
  677. productList := StockOutProductDao.Read_StockOutProduct_List(stockIn.T_number)
  678. var pList []Stock.StockOutProduct_R
  679. for _, v := range productList {
  680. pList = append(pList, Stock.StockOutProductToStockOutProduct_R(v))
  681. }
  682. userList, _ := NatsServer.Read_User_List_All()
  683. Account.Read_User_All_Map(userList)
  684. Basic.Read_Depot_All_Map()
  685. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: Stock.StockOutToStockOut_Detail(stockIn, pList)}
  686. c.ServeJSON()
  687. return
  688. }
  689. func (c *StockController) StockOut_Add() {
  690. rand_x := 0
  691. T_number := ""
  692. o := orm.NewOrm()
  693. o.Begin()
  694. StockOutDao := Stock.NewStockOut(o)
  695. for true {
  696. T_number = "CK-" + lib.GetRandstring(8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", int64(rand_x))
  697. _, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  698. if err != nil && err.Error() == orm.ErrNoRows.Error() {
  699. break
  700. }
  701. rand_x += 1
  702. }
  703. T_contract_number := c.GetString("T_contract_number")
  704. T_depot_id, _ := c.GetInt("T_depot_id")
  705. T_type, _ := c.GetInt("T_type") // 出库类型 1-领料出库 2-销售出库
  706. T_date := c.GetString("T_date")
  707. T_receive := c.GetString("T_receive")
  708. T_product := c.GetString("T_product")
  709. T_remark := c.GetString("T_remark")
  710. T_project := c.GetString("T_project")
  711. T_delivery_type, _ := c.GetInt("T_delivery_type")
  712. T_signer_unit := c.GetString("T_signer_unit")
  713. T_signer := c.GetString("T_signer")
  714. T_signer_phone := c.GetString("T_signer_phone")
  715. T_signer_date := c.GetString("T_signer_date")
  716. T_courier_number := c.GetString("T_courier_number")
  717. if _, is := lib.DateStrToTime(T_date); !is {
  718. c.Data["json"] = lib.JSONS{Code: 202, Msg: "日期格式错误!"}
  719. c.ServeJSON()
  720. return
  721. }
  722. var_ := Stock.StockOut{
  723. T_number: T_number,
  724. T_contract_number: T_contract_number,
  725. T_depot_id: T_depot_id,
  726. T_type: T_type,
  727. T_date: T_date,
  728. T_receive: T_receive,
  729. T_remark: T_remark,
  730. T_project: T_project,
  731. T_submit: c.User.T_uuid,
  732. // 销售出库
  733. T_delivery_type: T_delivery_type, // 1-自送 2-自提 3-快递
  734. T_signer_unit: T_signer_unit,
  735. T_signer: T_signer,
  736. T_signer_phone: T_signer_phone,
  737. T_signer_date: T_signer_date,
  738. T_courier_number: T_courier_number,
  739. }
  740. StockOutProductDao := Stock.NewStockOutProduct(o)
  741. StockDao := Stock.NewStock(o)
  742. DeviceDao := Stock.NewDevice(o)
  743. ContractDao := Contract.NewContract(o)
  744. ContractProductDao := Contract.NewContractProduct(o)
  745. _, err := StockOutDao.Add_StockOut(var_)
  746. if err != nil {
  747. o.Rollback()
  748. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  749. c.ServeJSON()
  750. return
  751. }
  752. // 1、添加出库单
  753. contract, _ := ContractDao.Read_Contract_ByT_number(T_contract_number)
  754. if contract.Id == 0 && T_type == 2 {
  755. o.Rollback()
  756. c.Data["json"] = lib.JSONS{Code: 203, Msg: "合同编号错误!"}
  757. c.ServeJSON()
  758. return
  759. }
  760. if len(T_product) == 0 {
  761. o.Rollback()
  762. c.Data["json"] = lib.JSONS{Code: 202, Msg: "产品明细不能为空"}
  763. c.ServeJSON()
  764. return
  765. }
  766. productList := lib.SplitString(T_product, "|")
  767. for _, v := range productList {
  768. product_id, _ := strconv.Atoi(strings.Split(v, "-")[0])
  769. product, _ := Basic.Read_Product_ById(product_id)
  770. num, _ := strconv.Atoi(strings.Split(v, "-")[1])
  771. T_relation_sn := strings.Split(v, "-")[2]
  772. if T_relation_sn == "" && product.T_relation_sn == 1 {
  773. o.Rollback()
  774. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("%s关联SN,请先添加SN!", product.T_name)}
  775. c.ServeJSON()
  776. return
  777. }
  778. // 2、更新设备状态为已出库
  779. if len(T_relation_sn) > 0 {
  780. snList := strings.Split(T_relation_sn, ",")
  781. for _, sn := range snList {
  782. mqtt := Stock.Read_MqttUser(sn)
  783. device := Stock.Device{
  784. T_contract_number: T_contract_number,
  785. T_product_id: product_id,
  786. T_out_number: T_number,
  787. T_sn: sn,
  788. T_iccid: mqtt.Iccid,
  789. T_imei: mqtt.Imei,
  790. T_State: 1,
  791. T_project: T_project,
  792. }
  793. _, err = DeviceDao.AddOrUpdate_Device(device, 1)
  794. if err != nil {
  795. o.Rollback()
  796. c.Data["json"] = lib.JSONS{Code: 202, Msg: "出库失败"}
  797. c.ServeJSON()
  798. return
  799. }
  800. }
  801. }
  802. // 3、添加出库产品清单
  803. stockOutProduct := Stock.StockOutProduct{
  804. T_number: T_number,
  805. T_product_id: product_id,
  806. T_depot_id: T_depot_id,
  807. T_num: num, // 出库数量
  808. T_date: T_date, // 出库数量
  809. T_relation_sn: T_relation_sn,
  810. }
  811. _, err = StockOutProductDao.Add_StockOutProduct(stockOutProduct)
  812. if err != nil {
  813. o.Rollback()
  814. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  815. c.ServeJSON()
  816. return
  817. }
  818. // 4、更改合同产品列表清单
  819. contractProduct, _ := ContractProductDao.Read_ContractProduct_ByT_number_T_product_id(T_contract_number, product_id)
  820. contractProduct.T_product_out += num
  821. if contractProduct.T_product_out > contractProduct.T_product_total && T_type == 2 {
  822. o.Rollback()
  823. p, _ := Basic.Read_Product_ById(product_id)
  824. c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("【%s】出库数量超过预计出库数量!", p.T_name)}
  825. c.ServeJSON()
  826. return
  827. }
  828. contractProduct.T_State = 2
  829. if contractProduct.T_product_out == 0 {
  830. contractProduct.T_State = 1
  831. }
  832. if contractProduct.T_product_out == contractProduct.T_product_total {
  833. contractProduct.T_State = 3
  834. }
  835. err = ContractProductDao.Update_ContractProduct(contractProduct, "T_product_out", "T_State")
  836. if err != nil {
  837. o.Rollback()
  838. c.Data["json"] = lib.JSONS{Code: 202, Msg: "更新合同产品清单失败"}
  839. c.ServeJSON()
  840. return
  841. }
  842. // 5、更新产品库存列表
  843. _, err = StockDao.AddOrUpdate_Stock(T_depot_id, product.Id, product.T_class, product.T_name, product.T_model, num, 1)
  844. if err != nil {
  845. o.Rollback()
  846. c.Data["json"] = lib.JSONS{Code: 203, Msg: "更新库存失败"}
  847. c.ServeJSON()
  848. return
  849. }
  850. }
  851. o.Commit()
  852. o2 := orm.NewOrm()
  853. o2.Begin()
  854. ContractDao2 := Contract.NewContract(o2)
  855. ContractProductDao2 := Contract.NewContractProduct(o2)
  856. // 5、更新合同出库状态
  857. var T_out int
  858. if contract.T_State == 1 {
  859. T_out = 2
  860. // 查询合同产品清单是否全部都为已出库
  861. state := ContractProductDao2.Read_ContractProduct_T_State_List(contract.T_number)
  862. if state == 1 {
  863. T_out = 1
  864. }
  865. if state == 3 {
  866. T_out = 3
  867. }
  868. }
  869. if T_out != contract.T_out {
  870. contract.T_out = T_out
  871. err = ContractDao2.Update_Contract(contract, "T_out")
  872. if err != nil {
  873. o2.Rollback()
  874. c.Data["json"] = lib.JSONS{Code: 202, Msg: "更新合同出库状态失败"}
  875. c.ServeJSON()
  876. return
  877. }
  878. }
  879. o2.Commit()
  880. NatsServer.AddUserLogs(c.User.T_uuid, "出库", "出库", var_)
  881. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  882. c.ServeJSON()
  883. return
  884. }
  885. func (c *StockController) StockOut_Edit() {
  886. T_number := c.GetString("T_number")
  887. T_remark := c.GetString("T_remark")
  888. T_project := c.GetString("T_project")
  889. T_delivery_type, _ := c.GetInt("T_delivery_type")
  890. T_signer_unit := c.GetString("T_signer_unit")
  891. T_signer := c.GetString("T_signer")
  892. T_signer_phone := c.GetString("T_signer_phone")
  893. T_signer_date := c.GetString("T_signer_date")
  894. T_courier_number := c.GetString("T_courier_number")
  895. o := orm.NewOrm()
  896. StockOutDao := Stock.NewStockOut(o)
  897. stockOut, err := StockOutDao.Read_StockOut_ByT_number(T_number)
  898. if err != nil {
  899. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库编号错误!"}
  900. c.ServeJSON()
  901. return
  902. }
  903. if len(T_remark) > 0 {
  904. stockOut.T_remark = T_remark
  905. }
  906. if len(T_project) > 0 {
  907. stockOut.T_project = T_project
  908. }
  909. if T_delivery_type > 0 {
  910. stockOut.T_delivery_type = T_delivery_type
  911. }
  912. if len(T_signer_unit) > 0 {
  913. stockOut.T_signer_unit = T_signer_unit
  914. }
  915. if len(T_signer) > 0 {
  916. stockOut.T_signer = T_signer
  917. }
  918. if len(T_signer_phone) > 0 {
  919. stockOut.T_signer_phone = T_signer_phone
  920. }
  921. if len(T_signer_date) > 0 {
  922. stockOut.T_signer_date = T_signer_date
  923. }
  924. if len(T_courier_number) > 0 {
  925. stockOut.T_courier_number = T_courier_number
  926. }
  927. err = StockOutDao.Update_StockOut(stockOut, "T_remark", "T_delivery_type", "T_signer_unit", "T_signer", "T_signer_phone", "T_signer_date", "T_courier_number", "T_project")
  928. if err != nil {
  929. o.Rollback()
  930. c.Data["json"] = lib.JSONS{Code: 203, Msg: "出库失败"}
  931. c.ServeJSON()
  932. return
  933. }
  934. NatsServer.AddUserLogs(c.User.T_uuid, "出库", "修改发货单", stockOut)
  935. c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: T_number}
  936. c.ServeJSON()
  937. return
  938. }
  939. func Cron_StockMonth() {
  940. //创建一个定时任务对象
  941. c := cron.New(cron.WithSeconds())
  942. //给对象增加定时任务
  943. // @monthly 每月运行一次,每月第一天午夜 0 0 0 1 * *
  944. //c.AddFunc("0 */1 * * * ?", Cron_StockMonth_Add)
  945. c.AddFunc("@monthly", Cron_StockMonth_Add)
  946. //启动定时任务
  947. c.Start()
  948. defer c.Stop()
  949. //查询语句,阻塞,让main函数不退出,保持程序运行
  950. select {}
  951. }
  952. // 保存每月入库出库明细
  953. func Cron_StockMonth_Add() {
  954. T_month := time.Now().AddDate(0, -1, 0).Format("2006-01")
  955. logs.Info("开始统计" + T_month + "库存明细数据")
  956. o := orm.NewOrm()
  957. StockDao := Stock.NewStock(o)
  958. StockOutDao := Stock.NewStockOut(o)
  959. StockMonthDao := Stock.NewStockMonth(o)
  960. StockOutProductDao := Stock.NewStockOutProduct(o)
  961. StockInProductDao := Stock.NewStockInProduct(o)
  962. stockList, _ := StockDao.Read_Stock_List(0, 0, "", "", 0, 9999)
  963. for _, stock := range stockList {
  964. stockMonth := Stock.StockMonth{
  965. T_depot_id: stock.T_depot_id,
  966. T_product_id: stock.T_product_id,
  967. T_product_class: stock.T_product_class,
  968. T_month: T_month,
  969. }
  970. // 获取当前产品本月出库数量
  971. stockMonth.T_in = StockInProductDao.Read_StockIn_Total(stock.T_depot_id, stock.T_product_id, T_month)
  972. stockMonth.T_out = StockOutProductDao.Read_StockOut_Total(stock.T_depot_id, stock.T_product_id, T_month)
  973. s := StockMonthDao.Read_StockMonth_ByT_depot_id_T_product_id(stock.T_depot_id, stock.T_product_id, T_month)
  974. if len(s) > 0 {
  975. stockMonth.T_beginning = s[0].T_ending
  976. } else {
  977. stockMonth.T_beginning = 0
  978. }
  979. // 期末库存 = 期初库存+入库-出库
  980. stockMonth.T_ending = stockMonth.T_beginning + stockMonth.T_in - stockMonth.T_out
  981. stockMonth.T_project = StockOutDao.Read_StockOut_T_contract_number(stock.T_depot_id, stock.T_product_id, T_month)
  982. _, err := StockMonthDao.Add_StockMonth(stockMonth)
  983. if err != nil {
  984. NatsServer.AddSysLogs("库存明细统计", fmt.Sprintf("库存明细统计失败%s:%d:%d", T_month, stock.T_depot_id, stock.T_product_id), stockMonth)
  985. }
  986. }
  987. }