warhouse_service.go 49KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  1. package service
  2. import (
  3. "XT_New/models"
  4. "XT_New/models/service"
  5. "XT_New/utils"
  6. "errors"
  7. "fmt"
  8. _ "fmt"
  9. "github.com/jinzhu/gorm"
  10. "math"
  11. "strconv"
  12. "strings"
  13. "time"
  14. )
  15. // 药品出库
  16. func DrugsDelivery(orgID int64, creater int64, advice *models.DoctorAdvice) (err error) {
  17. // 1.判断药品是否来自专用字典的药品库
  18. // 2.判断当天当前机构有没有创建出库单,没有则创建
  19. // 3.创建出库流程
  20. // 3.1 实现先进先出逻辑 由于药品执行后,不可以修改和删除,所以不考虑出库后的退库和修改出库数量等
  21. isHasWay := false
  22. record_time := int64(0)
  23. if advice.Way == 1 {
  24. isHasWay = true
  25. record_time = advice.RecordDate
  26. }
  27. fmt.Println("isHasway99999999999999999999999999999999", isHasWay)
  28. if isHasWay {
  29. //判断当天当前机构有没有创建出库单,没有则创建
  30. out, err := FindDrugStockOutByIsSys(orgID, 1, record_time)
  31. if err == gorm.ErrRecordNotFound {
  32. timeStr := time.Now().Format("2006-01-02")
  33. timeArr := strings.Split(timeStr, "-")
  34. total, _ := FindAllDrugWarehouseOut(orgID)
  35. total = total + 1
  36. warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
  37. number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
  38. number = number + total
  39. warehousing_out_order = "YPCKD" + strconv.FormatInt(number, 10)
  40. // creater := adminUserInfo.AdminUser.Id
  41. warehouseOut := models.DrugWarehouseOut{
  42. WarehouseOutOrderNumber: warehousing_out_order,
  43. OperationTime: time.Now().Unix(),
  44. OrgId: orgID,
  45. Creater: creater,
  46. Ctime: time.Now().Unix(),
  47. Status: 1,
  48. WarehouseOutTime: record_time,
  49. Dealer: 0,
  50. Manufacturer: 0,
  51. Type: 1,
  52. IsSys: 1,
  53. }
  54. err := AddSigleDrugWarehouseOut(&warehouseOut)
  55. if err != nil {
  56. utils.TraceLog("创建出库单失败 err = %v", err)
  57. return err
  58. } else {
  59. out = warehouseOut
  60. }
  61. }
  62. // 出库流程
  63. // 1.查询改药品在药品库的规格信息,并将处方里的规格进行换算(尽量将拆零单位转换成包装单位)
  64. drup, _ := FindBaseDrugLibRecord(orgID, advice.DrugId)
  65. if drup.ID > 0 {
  66. prescribingNumber := advice.PrescribingNumber
  67. DrugDeliverInfo(orgID, prescribingNumber, &out, &drup, advice)
  68. } else {
  69. return errors.New("药品信息不存在")
  70. }
  71. }
  72. return
  73. }
  74. // 药品出库 递归方式
  75. func DrugDeliverInfo(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DoctorAdvice) (err error) {
  76. // 判断处方里药品单位是拆零单位还是包装单位, 如果是包装单位,则根据规格,将包装数量转为拆零数量
  77. var deliver_number int64 = 0
  78. var stock_number int64 = 0
  79. prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
  80. count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)
  81. fmt.Println("单位1", advice.PrescribingNumber)
  82. fmt.Println("单位2", drup.MaxUnit)
  83. if advice.PrescribingNumberUnit == drup.MaxUnit {
  84. deliver_number = count * drup.MinNumber
  85. } else {
  86. deliver_number = count
  87. }
  88. // 根据先进先出原则,查询最先入库的批次,进行出库
  89. // 如果没有对应的库存,则报错
  90. //开启事物
  91. warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId)
  92. if err != nil {
  93. return err
  94. }
  95. // 将该批次的剩余库存数量转换为拆零数量
  96. stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber
  97. fmt.Println("stock_number999999999999", stock_number)
  98. fmt.Println("deliver_number88888888888", deliver_number)
  99. // 当库存数量大于或等于出库数量的话,则正常出库该批次
  100. if stock_number >= deliver_number {
  101. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  102. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  103. WarehouseOutId: warehouseout.ID,
  104. Status: 1,
  105. Ctime: time.Now().Unix(),
  106. Remark: "",
  107. OrgId: orgID,
  108. Type: 1,
  109. Manufacturer: 0,
  110. Dealer: 0,
  111. IsSys: 1,
  112. SysRecordTime: advice.RecordDate,
  113. DrugId: advice.DrugId,
  114. }
  115. warehouseOutInfo.Count = deliver_number
  116. warehouseOutInfo.CountUnit = drup.MinUnit
  117. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  118. if errOne != nil {
  119. return errOne
  120. } else {
  121. details := &models.DrugAutomaticReduceDetail{
  122. WarehouseOutId: warehouseOutInfo.ID,
  123. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  124. PatientId: advice.PatientId,
  125. Ctime: time.Now().Unix(),
  126. Mtime: time.Now().Unix(),
  127. Status: 1,
  128. RecordTime: advice.RecordDate,
  129. OrgId: orgID,
  130. DrugId: advice.DrugId,
  131. Count: deliver_number,
  132. CountUnit: drup.MinUnit,
  133. }
  134. errTwo := AddSigleDrugAutoReduceRecordInfo(details)
  135. if errTwo != nil {
  136. return errTwo
  137. }
  138. }
  139. // 出库完成后,要减去对应批次的库存数量
  140. // 判断处方里药品单位是拆零单位还是包装单位, 如果是拆零单位,则根据规格,将拆零数量转为包装数量
  141. var maxNumber int64 = 0
  142. var minNumber int64 = 0
  143. if advice.PrescribingNumberUnit == drup.MinUnit {
  144. maxNumber = count / drup.MinNumber
  145. minNumber = count % drup.MinNumber
  146. } else {
  147. maxNumber = count
  148. }
  149. if warehouse.StockMaxNumber < maxNumber {
  150. return errors.New("库存数量不足")
  151. }
  152. warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
  153. warehouse.Mtime = time.Now().Unix()
  154. if warehouse.StockMinNumber < minNumber {
  155. warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
  156. warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
  157. } else {
  158. warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
  159. }
  160. if warehouse.StockMaxNumber < 0 {
  161. return errors.New("库存数量不足")
  162. }
  163. errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
  164. if errThree != nil {
  165. return errThree
  166. }
  167. return nil
  168. } else {
  169. // 当该批次的库存数量小于出库数量的话,则先把该批次出库完后,再进行递归出库
  170. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  171. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  172. WarehouseOutId: warehouseout.ID,
  173. Status: 1,
  174. Ctime: time.Now().Unix(),
  175. Remark: "",
  176. OrgId: orgID,
  177. Type: 1,
  178. Manufacturer: 0,
  179. Dealer: 0,
  180. IsSys: 1,
  181. SysRecordTime: advice.RecordDate,
  182. DrugId: advice.DrugId,
  183. }
  184. warehouseOutInfo.Count = stock_number
  185. warehouseOutInfo.CountUnit = drup.MinUnit
  186. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  187. if errOne != nil {
  188. return errOne
  189. } else {
  190. details := &models.DrugAutomaticReduceDetail{
  191. WarehouseOutId: warehouseOutInfo.ID,
  192. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  193. PatientId: advice.PatientId,
  194. Ctime: time.Now().Unix(),
  195. Mtime: time.Now().Unix(),
  196. Status: 1,
  197. RecordTime: advice.RecordDate,
  198. OrgId: orgID,
  199. DrugId: advice.DrugId,
  200. Count: stock_number,
  201. CountUnit: drup.MinUnit,
  202. }
  203. errTwo := AddSigleDrugAutoReduceRecordInfo(details)
  204. if errTwo != nil {
  205. return errTwo
  206. }
  207. }
  208. // 出库完成后,要将该批次库存清零
  209. warehouse.StockMaxNumber = 0
  210. warehouse.StockMinNumber = 0
  211. warehouse.Mtime = time.Now().Unix()
  212. errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
  213. if errThree != nil {
  214. return errThree
  215. }
  216. // 清零完该库存后,还有剩余出库未出完,进行对应的递归操作
  217. prescribingNumber_two_temp := deliver_number - stock_number
  218. overPlusNumber := float64(prescribingNumber_two_temp)
  219. advice.PrescribingNumber = float64(prescribingNumber_two_temp)
  220. advice.PrescribingNumberUnit = drup.MinUnit
  221. DrugDeliverInfo(orgID, overPlusNumber, warehouseout, drup, advice)
  222. }
  223. return
  224. }
  225. // 药品出库
  226. func HisDrugsDelivery(orgID int64, creater int64, advice *models.HisDoctorAdviceInfo) (err error) {
  227. // 1.判断药品是否来自专用字典的药品库
  228. // 2.判断当天当前机构有没有创建出库单,没有则创建
  229. // 3.创建出库流程
  230. // 3.1 实现先进先出逻辑 由于药品执行后,不可以修改和删除,所以不考虑出库后的退库和修改出库数量等
  231. isHasWay := false
  232. record_time := int64(0)
  233. isHasWay = true
  234. record_time = advice.RecordDate
  235. if isHasWay {
  236. //判断当天当前机构有没有创建出库单,没有则创建
  237. out, err := FindDrugStockOutByIsSys(orgID, 1, record_time)
  238. if err == gorm.ErrRecordNotFound {
  239. timeStr := time.Now().Format("2006-01-02")
  240. timeArr := strings.Split(timeStr, "-")
  241. total, _ := FindAllDrugWarehouseOut(orgID)
  242. total = total + 1
  243. warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
  244. number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
  245. number = number + total
  246. warehousing_out_order = "YPCKD" + strconv.FormatInt(number, 10)
  247. // creater := adminUserInfo.AdminUser.Id
  248. warehouseOut := models.DrugWarehouseOut{
  249. WarehouseOutOrderNumber: warehousing_out_order,
  250. OperationTime: time.Now().Unix(),
  251. OrgId: orgID,
  252. Creater: creater,
  253. Ctime: time.Now().Unix(),
  254. Status: 1,
  255. WarehouseOutTime: record_time,
  256. Dealer: 0,
  257. Manufacturer: 0,
  258. Type: 1,
  259. IsSys: 1,
  260. }
  261. err := AddSigleDrugWarehouseOut(&warehouseOut)
  262. if err != nil {
  263. utils.TraceLog("创建出库单失败 err = %v", err)
  264. return err
  265. } else {
  266. out = warehouseOut
  267. }
  268. }
  269. // 出库流程
  270. // 1.查询改药品在药品库的规格信息,并将处方里的规格进行换算(尽量将拆零单位转换成包装单位)
  271. drup, _ := FindBaseDrugLibRecord(orgID, advice.DrugId)
  272. if drup.ID > 0 {
  273. prescribingNumber := advice.PrescribingNumber
  274. HisDrugDeliverInfo(orgID, prescribingNumber, &out, &drup, advice)
  275. } else {
  276. return errors.New("药品信息不存在")
  277. }
  278. }
  279. return
  280. }
  281. // 药品出库 递归方式
  282. func HisDrugDeliverInfo(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.HisDoctorAdviceInfo) (err error) {
  283. // 判断处方里药品单位是拆零单位还是包装单位, 如果是包装单位,则根据规格,将包装数量转为拆零数量
  284. var deliver_number int64 = 0
  285. var stock_number int64 = 0
  286. prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
  287. count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)
  288. fmt.Println("单位99999999999999999999999999", advice.PrescribingNumberUnit)
  289. fmt.Println("drup777777777777766666666", drup.MaxUnit)
  290. if advice.PrescribingNumberUnit == drup.MaxUnit {
  291. deliver_number = count * drup.MinNumber
  292. } else {
  293. deliver_number = count
  294. }
  295. // 根据先进先出原则,查询最先入库的批次,进行出库
  296. // 如果没有对应的库存,则报错
  297. //开启事物
  298. warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId)
  299. if err != nil {
  300. return err
  301. }
  302. // 将该批次的剩余库存数量转换为拆零数量
  303. stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber
  304. fmt.Println("拆零数量2222222222222222222", stock_number)
  305. fmt.Println("出库数量55555555555555555555", deliver_number)
  306. // 当库存数量大于或等于出库数量的话,则正常出库该批次
  307. if stock_number >= deliver_number {
  308. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  309. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  310. WarehouseOutId: warehouseout.ID,
  311. Status: 1,
  312. Ctime: time.Now().Unix(),
  313. Remark: "",
  314. OrgId: orgID,
  315. Type: 1,
  316. Manufacturer: 0,
  317. Dealer: 0,
  318. IsSys: 1,
  319. SysRecordTime: advice.RecordDate,
  320. DrugId: advice.DrugId,
  321. }
  322. warehouseOutInfo.Count = deliver_number
  323. warehouseOutInfo.CountUnit = advice.PrescribingNumberUnit
  324. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  325. if errOne != nil {
  326. return errOne
  327. } else {
  328. details := &models.DrugAutomaticReduceDetail{
  329. WarehouseOutId: warehouseOutInfo.ID,
  330. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  331. PatientId: advice.PatientId,
  332. Ctime: time.Now().Unix(),
  333. Mtime: time.Now().Unix(),
  334. Status: 1,
  335. RecordTime: advice.RecordDate,
  336. OrgId: orgID,
  337. DrugId: advice.DrugId,
  338. Count: deliver_number,
  339. CountUnit: advice.PrescribingNumberUnit,
  340. }
  341. errTwo := AddSigleDrugAutoReduceRecordInfo(details)
  342. if errTwo != nil {
  343. return errTwo
  344. }
  345. }
  346. // 出库完成后,要减去对应批次的库存数量
  347. // 判断处方里药品单位是拆零单位还是包装单位, 如果是拆零单位,则根据规格,将拆零数量转为包装数量
  348. var maxNumber int64 = 0
  349. var minNumber int64 = 0
  350. if advice.PrescribingNumberUnit == drup.MinUnit {
  351. maxNumber = count / drup.MinNumber
  352. minNumber = count % drup.MinNumber
  353. } else {
  354. maxNumber = count
  355. }
  356. if warehouse.StockMaxNumber < maxNumber {
  357. return errors.New("库存数量不足")
  358. }
  359. warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
  360. warehouse.Mtime = time.Now().Unix()
  361. if warehouse.StockMinNumber < minNumber {
  362. warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
  363. warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
  364. } else {
  365. warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
  366. }
  367. if warehouse.StockMaxNumber < 0 {
  368. return errors.New("库存数量不足")
  369. }
  370. errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
  371. if errThree != nil {
  372. return errThree
  373. }
  374. return nil
  375. } else {
  376. // 当该批次的库存数量小于出库数量的话,则先把该批次出库完后,再进行递归出库
  377. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  378. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  379. WarehouseOutId: warehouseout.ID,
  380. Status: 1,
  381. Ctime: time.Now().Unix(),
  382. Remark: "",
  383. OrgId: orgID,
  384. Type: 1,
  385. Manufacturer: 0,
  386. Dealer: 0,
  387. IsSys: 1,
  388. SysRecordTime: advice.RecordDate,
  389. DrugId: advice.DrugId,
  390. }
  391. warehouseOutInfo.Count = stock_number
  392. warehouseOutInfo.CountUnit = drup.MinUnit
  393. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  394. if errOne != nil {
  395. return errOne
  396. } else {
  397. details := &models.DrugAutomaticReduceDetail{
  398. WarehouseOutId: warehouseOutInfo.ID,
  399. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  400. PatientId: advice.PatientId,
  401. Ctime: time.Now().Unix(),
  402. Mtime: time.Now().Unix(),
  403. Status: 1,
  404. RecordTime: advice.RecordDate,
  405. OrgId: orgID,
  406. DrugId: advice.DrugId,
  407. Count: stock_number,
  408. CountUnit: drup.MinUnit,
  409. }
  410. errTwo := AddSigleDrugAutoReduceRecordInfo(details)
  411. if errTwo != nil {
  412. return errTwo
  413. }
  414. }
  415. // 出库完成后,要将该批次库存清零
  416. warehouse.StockMaxNumber = 0
  417. warehouse.StockMinNumber = 0
  418. warehouse.Mtime = time.Now().Unix()
  419. errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
  420. if errThree != nil {
  421. return errThree
  422. }
  423. // 清零完该库存后,还有剩余出库未出完,进行对应的递归操作
  424. prescribingNumber_two_temp := deliver_number - stock_number
  425. overPlusNumber := float64(prescribingNumber_two_temp)
  426. advice.PrescribingNumber = float64(prescribingNumber_two_temp)
  427. advice.PrescribingNumberUnit = drup.MinUnit
  428. HisDrugDeliverInfo(orgID, overPlusNumber, warehouseout, drup, advice)
  429. }
  430. return
  431. }
  432. // 药品出库 递归方式
  433. func AutoDrugDeliverInfo(orgID int64, prescribingNumber int64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DrugWarehouseOutInfo) (err error) {
  434. // 判断处方里药品单位是拆零单位还是包装单位, 如果是包装单位,则根据规格,将包装数量转为拆零数量
  435. var deliver_number int64 = 0
  436. var stock_number int64 = 0
  437. fmt.Println("单位1", advice.CountUnit)
  438. fmt.Println("单位2", drup.MaxUnit)
  439. if advice.CountUnit == drup.MaxUnit {
  440. deliver_number = prescribingNumber * drup.MinNumber
  441. } else {
  442. deliver_number = prescribingNumber
  443. }
  444. // 根据先进先出原则,查询最先入库的批次,进行出库
  445. // 如果没有对应的库存,则报错
  446. //开启事物
  447. warehouse, err := FindLastDrugWarehousingInfoByID(advice.DrugId)
  448. if err != nil {
  449. return err
  450. }
  451. // 将该批次的剩余库存数量转换为拆零数量
  452. stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber
  453. fmt.Println("88i8uu7777777777777777777777777777", stock_number)
  454. fmt.Println("77777544656666666666666666", deliver_number)
  455. // 当库存数量大于或等于出库数量的话,则正常出库该批次
  456. if stock_number >= deliver_number {
  457. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  458. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  459. WarehouseOutId: warehouseout.ID,
  460. Status: 1,
  461. Ctime: time.Now().Unix(),
  462. Remark: "",
  463. OrgId: orgID,
  464. Type: 1,
  465. Manufacturer: 0,
  466. Dealer: 0,
  467. IsSys: 0,
  468. SysRecordTime: advice.Ctime,
  469. DrugId: advice.DrugId,
  470. }
  471. warehouseOutInfo.Count = deliver_number
  472. warehouseOutInfo.CountUnit = advice.CountUnit
  473. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  474. if errOne != nil {
  475. return errOne
  476. }
  477. // 出库完成后,要减去对应批次的库存数量
  478. // 判断处方里药品单位是拆零单位还是包装单位, 如果是拆零单位,则根据规格,将拆零数量转为包装数量
  479. var maxNumber int64 = 0
  480. var minNumber int64 = 0
  481. if advice.CountUnit == drup.MinUnit {
  482. maxNumber = prescribingNumber / drup.MinNumber
  483. minNumber = prescribingNumber % drup.MinNumber
  484. } else {
  485. maxNumber = prescribingNumber
  486. }
  487. if warehouse.StockMaxNumber < maxNumber {
  488. return errors.New("库存数量不足")
  489. }
  490. warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
  491. warehouse.Mtime = time.Now().Unix()
  492. if warehouse.StockMinNumber < minNumber {
  493. warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
  494. warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
  495. } else {
  496. warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
  497. }
  498. if warehouse.StockMaxNumber < 0 {
  499. return errors.New("库存数量不足")
  500. }
  501. errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
  502. if errThree != nil {
  503. return errThree
  504. }
  505. return nil
  506. } else {
  507. // 当该批次的库存数量小于出库数量的话,则先把该批次出库完后,再进行递归出库
  508. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  509. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  510. WarehouseOutId: warehouseout.ID,
  511. Status: 1,
  512. Ctime: time.Now().Unix(),
  513. Remark: "",
  514. OrgId: orgID,
  515. Type: 1,
  516. Manufacturer: 0,
  517. Dealer: 0,
  518. IsSys: 0,
  519. SysRecordTime: advice.Ctime,
  520. DrugId: advice.DrugId,
  521. }
  522. warehouseOutInfo.Count = stock_number
  523. warehouseOutInfo.CountUnit = advice.CountUnit
  524. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  525. if errOne != nil {
  526. return errOne
  527. }
  528. // 出库完成后,要将该批次库存清零
  529. warehouse.StockMaxNumber = 0
  530. warehouse.StockMinNumber = 0
  531. warehouse.Mtime = time.Now().Unix()
  532. errThree := UpDateDrugWarehouseInfoByStock(&warehouse)
  533. if errThree != nil {
  534. return errThree
  535. }
  536. // 清零完该库存后,还有剩余出库未出完,进行对应的递归操作
  537. prescribingNumber_two_temp := deliver_number - stock_number
  538. advice.CountUnit = drup.MinUnit
  539. AutoDrugDeliverInfo(orgID, prescribingNumber_two_temp, warehouseout, drup, advice)
  540. }
  541. return
  542. }
  543. // 耗材出库
  544. func ConsumablesDeliveryTotal(orgID int64, patient_id int64, record_time int64, goods []*models.DialysisBeforePrepareGoods, goodOne []*models.NewDialysisBeforePrepareGoods) (err error) {
  545. //查询该患者当天已经出库的耗材信息
  546. goods_yc, _ := FindConsumablesByDateTwo(orgID, patient_id, record_time)
  547. // 和新请求的出库数据进行对比,分出那些是继续出库的,那些是需要删除出库的
  548. for i := len(goods_yc) - 1; i >= 0; i-- {
  549. goods_yc_temp := goods_yc[i]
  550. for j := len(goods) - 1; j >= 0; j-- {
  551. goods_temp := goods[j]
  552. // 已经出库和新请求出库都存在该耗材,则判断出库数量,分成是继续出库,还是删除出库
  553. if goods_yc_temp.GoodTypeId == goods_temp.GoodTypeId && goods_yc_temp.GoodId == goods_temp.GoodId {
  554. // 已经出库和新请求出库的出库数量一致,则清除两个结构体里的数据(既不出库,也不删除出库)
  555. if goods_yc_temp.Count == goods_temp.Count {
  556. goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)
  557. goods = append(goods[:j], goods[j+1:]...)
  558. break
  559. }
  560. // 如果已经出库的数量 大于 新请求出库的数量,则代表需要删除出库
  561. if goods_yc_temp.Count > goods_temp.Count {
  562. temp_count := goods_yc_temp.Count - goods_temp.Count
  563. goods_yc[i].Count = temp_count
  564. goods = append(goods[:j], goods[j+1:]...)
  565. break
  566. }
  567. // 如果已经出库的数量 小于 新请求出库的梳理,则代表需要增加出库
  568. if goods_yc_temp.Count < goods_temp.Count {
  569. temp_count := goods_temp.Count - goods_yc_temp.Count
  570. //fmt.Println("988888888888888", temp_count)
  571. goods[j].Count = temp_count
  572. goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)
  573. //fmt.Println("888888888", goods_yc)
  574. break
  575. }
  576. }
  577. }
  578. }
  579. // goods_yc 这个数据就是需要已经出库了,但是现在需要删除出库的耗材数据
  580. // goods 这个数据就是需要出库的耗材的数据(新增的数据)
  581. fmt.Println("goods222222222222", goods)
  582. fmt.Println("goodsy999999999999", goods_yc)
  583. if len(goods) > 0 {
  584. out, err := FindStockOutByIsSys(orgID, 1, record_time)
  585. if err == gorm.ErrRecordNotFound {
  586. //没有记录,则创建出库单
  587. timeStr := time.Now().Format("2006-01-02")
  588. timeArr := strings.Split(timeStr, "-")
  589. total, _ := FindAllWarehouseOut(orgID)
  590. total = total + 1
  591. warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
  592. number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
  593. number = number + total
  594. warehousing_out_order = "CKD" + strconv.FormatInt(number, 10)
  595. warehouseOut := models.WarehouseOut{
  596. WarehouseOutOrderNumber: warehousing_out_order,
  597. OperationTime: time.Now().Unix(),
  598. OrgId: orgID,
  599. Creater: 0,
  600. Ctime: time.Now().Unix(),
  601. Status: 1,
  602. WarehouseOutTime: record_time,
  603. Dealer: 0,
  604. Manufacturer: 0,
  605. Type: 1,
  606. IsSys: 1,
  607. }
  608. err := AddSigleWarehouseOut(&warehouseOut)
  609. if err != nil {
  610. utils.TraceLog("创建出库单失败 err = %v", err)
  611. return err
  612. } else {
  613. out = warehouseOut
  614. }
  615. }
  616. for _, item := range goods {
  617. var newCount int64 = 0
  618. for _, it := range goodOne {
  619. if item.GoodTypeId == it.GoodTypeId && item.GoodId == it.GoodId {
  620. newCount = it.Count
  621. }
  622. }
  623. prepare := models.DialysisBeforePrepare{
  624. GoodTypeId: item.GoodTypeId,
  625. GoodId: item.GoodId,
  626. Count: item.Count,
  627. }
  628. ConsumablesDelivery(orgID, patient_id, record_time, &prepare, &out, newCount)
  629. }
  630. }
  631. if len(goods_yc) > 0 {
  632. for _, good_yc := range goods_yc {
  633. out, _ := FindStockOutByIsSys(orgID, 1, record_time)
  634. ConsumablesDeliveryDelete(orgID, patient_id, record_time, good_yc, &out)
  635. }
  636. }
  637. return nil
  638. }
  639. //耗材出库
  640. func ConsumablesDelivery(orgID int64, patient_id int64, record_time int64, goods *models.DialysisBeforePrepare, warehouseOut *models.WarehouseOut, count int64) (err error) {
  641. // 判断处方里药品单位是拆零单位还是包装单位, 如果是包装单位,则根据规格,将包装数量转为拆零数量
  642. var deliver_number int64 = 0
  643. var stock_number int64 = 0
  644. var maxNumber int64 = 0
  645. deliver_number = goods.Count
  646. fmt.Println("添加数量", deliver_number)
  647. // 根据先进先出原则,查询最先入库的批次,进行出库
  648. // 如果没有对应的库存,则报错
  649. warehouse, err := FindFirstWarehousingInfoByStock(goods.GoodId, goods.GoodTypeId)
  650. fmt.Println("库存数量", warehouse.StockCount)
  651. if err != nil {
  652. return
  653. }
  654. // 将该批次的剩余库存数量转换为拆零数量
  655. stock_number = warehouse.StockCount
  656. // 当库存数量大于或等于出库数量的话,则正常出库该批次
  657. if stock_number >= deliver_number {
  658. warehouseOutInfo := &models.WarehouseOutInfo{
  659. WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
  660. WarehouseOutId: warehouseOut.ID,
  661. WarehouseInfotId: warehouse.ID,
  662. Status: 1,
  663. Ctime: time.Now().Unix(),
  664. Remark: "",
  665. OrgId: orgID,
  666. Type: 1,
  667. Manufacturer: 0,
  668. Dealer: 0,
  669. IsSys: 1,
  670. SysRecordTime: record_time,
  671. GoodTypeId: goods.GoodTypeId,
  672. GoodId: goods.GoodId,
  673. PatientId: patient_id,
  674. }
  675. warehouseOutInfo.Count = count
  676. stockInInfo, _ := FindLastStockInInfoRecord(goods.GoodId, orgID)
  677. warehouseOutInfo.Price = stockInInfo.Price
  678. errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
  679. if errOne != nil {
  680. return errOne
  681. } else {
  682. details := models.BloodAutomaticReduceDetail{
  683. WarehouseOutId: warehouseOutInfo.ID,
  684. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  685. PatientId: patient_id,
  686. Ctime: time.Now().Unix(),
  687. Mtime: time.Now().Unix(),
  688. Status: 1,
  689. RecordTime: record_time,
  690. OrgId: orgID,
  691. GoodId: goods.GoodId,
  692. GoodTypeId: goods.GoodTypeId,
  693. Count: count,
  694. }
  695. //查询当天耗材是否已经存在数据
  696. _, errcode := GetAutoMaticReduceDetail(orgID, patient_id, record_time, goods.GoodId, goods.GoodTypeId)
  697. if errcode == gorm.ErrRecordNotFound {
  698. errTwo := CreateAutoReduceRecord(&details)
  699. if errTwo != nil {
  700. return errTwo
  701. }
  702. } else if errcode == nil {
  703. DeleteAutoRedeceDetailTwo(orgID, patient_id, record_time, goods.GoodId, goods.GoodTypeId)
  704. CreateAutoReduceRecord(&details)
  705. }
  706. }
  707. maxNumber = goods.Count
  708. if warehouse.StockCount < maxNumber {
  709. return errors.New("库存数量不足")
  710. }
  711. warehouse.StockCount = warehouse.StockCount - maxNumber
  712. warehouse.Mtime = time.Now().Unix()
  713. if warehouse.StockCount < 0 {
  714. return errors.New("库存数量不足")
  715. }
  716. errThree := UpDateWarehouseInfoByStock(&warehouse)
  717. if errThree != nil {
  718. return errThree
  719. }
  720. return nil
  721. } else {
  722. // 出库完成后,要将该批次库存清零
  723. warehouse.StockCount = 0
  724. warehouse.Mtime = time.Now().Unix()
  725. errThree := UpDateWarehouseInfoByStock(&warehouse)
  726. if errThree != nil {
  727. return errThree
  728. }
  729. // 清零完该库存后,还有剩余出库未出完,进行对应的递归操作
  730. goods.Count = deliver_number - stock_number
  731. ConsumablesDelivery(orgID, patient_id, record_time, goods, warehouseOut, count)
  732. }
  733. return nil
  734. }
  735. //耗材出库删除
  736. func ConsumablesDeliveryDelete(orgID int64, patient_id int64, record_time int64, good_yc *models.DialysisBeforePrepare, warehouseOut *models.WarehouseOut) (err error) {
  737. // 先根据相关信息查询当天该耗材的出库信息
  738. warehouseOutInfos, err := FindStockOutInfoByStock(orgID, good_yc.GoodTypeId, good_yc.GoodId, record_time, patient_id)
  739. if err != nil {
  740. return err
  741. }
  742. var delete_count int64 = 0
  743. for _, ware := range warehouseOutInfos {
  744. // 判断当前出库的数据和删除出库数量
  745. if good_yc.Count <= ware.Count {
  746. delete_count = good_yc.Count
  747. } else {
  748. delete_count = ware.Count
  749. }
  750. // 在出库记录表里记录退库详情
  751. warehouseOutInfo := &models.WarehouseOutInfo{
  752. WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
  753. WarehouseOutId: warehouseOut.ID,
  754. //WarehouseInfoId: warehouse.ID,
  755. Status: 1,
  756. Ctime: time.Now().Unix(),
  757. Remark: "",
  758. OrgId: orgID,
  759. Type: 1,
  760. Manufacturer: 0,
  761. Dealer: 0,
  762. IsSys: 2,
  763. SysRecordTime: record_time,
  764. GoodTypeId: good_yc.GoodTypeId,
  765. GoodId: good_yc.GoodId,
  766. PatientId: patient_id,
  767. }
  768. warehouseOutInfo.Count = ware.Count - delete_count
  769. stockInInfo, _ := FindLastStockInInfoRecord(good_yc.GoodId, orgID)
  770. warehouseOutInfo.Price = stockInInfo.Price
  771. errOne := UpdateAutoMaticReduceDetail(good_yc.GoodId, good_yc.GoodTypeId, record_time, patient_id, orgID, warehouseOutInfo)
  772. if errOne != nil {
  773. return errOne
  774. } else {
  775. details := &models.AutomaticReduceDetail{
  776. WarehouseOutId: warehouseOutInfo.ID,
  777. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  778. PatientId: patient_id,
  779. Ctime: time.Now().Unix(),
  780. Mtime: time.Now().Unix(),
  781. Status: 1,
  782. RecordTime: record_time,
  783. OrgId: orgID,
  784. GoodId: good_yc.GoodId,
  785. GoodTypeId: good_yc.GoodTypeId,
  786. Count: warehouseOutInfo.Count,
  787. Type: 2,
  788. }
  789. //查询是否当天已经存在数据
  790. _, errcode := GetAutoMaticReduceDetail(orgID, patient_id, record_time, good_yc.GoodId, good_yc.GoodTypeId)
  791. if errcode == gorm.ErrRecordNotFound {
  792. errTwo := AddSigleAutoReduceRecordInfo(details)
  793. if errTwo != nil {
  794. return errTwo
  795. }
  796. } else if errcode == nil {
  797. DeleteAutoRedeceDetailTwo(orgID, patient_id, record_time, good_yc.GoodId, good_yc.GoodTypeId)
  798. AddSigleAutoReduceRecordInfo(details)
  799. }
  800. }
  801. // 删除出库完成后,要增加对应批次的库存数量
  802. errThree := UpDateWarehouseInfoByStockDelete(ware.WarehouseInfotId, delete_count)
  803. if errThree != nil {
  804. return errThree
  805. }
  806. // 增加了对应的库存后,看看还有多少需要退库的
  807. good_yc.Count = good_yc.Count - delete_count
  808. if good_yc.Count == 0 {
  809. return nil
  810. }
  811. }
  812. if good_yc.Count == 0 {
  813. return nil
  814. } else {
  815. return errors.New("退库和出库数据不匹配")
  816. }
  817. }
  818. func GetAutoReduceRecordInfoByPatientId(orgid int64, patient_id int64, recordTime int64) (autoReduce []*models.AutomaticReduceDetail, err error) {
  819. err = XTReadDB().Model(&autoReduce).Where("org_id = ? and patient_id = ? and record_time = ? and status = 1", orgid, patient_id, recordTime).Find(&autoReduce).Error
  820. return autoReduce, err
  821. }
  822. func DeleteDialysisBefor(orgid int64, patient_id int64, record_date int64, goodid int64, goodtypeid int64) error {
  823. prepare := models.DialysisBeforePrepare{}
  824. err := XTWriteDB().Model(&prepare).Where("user_org_id = ? and patient_id = ? and record_date = ? and status = 1 and good_id = ? and good_type_id = ?", orgid, patient_id, record_date, goodid, goodtypeid).Updates(map[string]interface{}{"status": 0, "count": 0, "mtime": time.Now().Unix()}).Error
  825. return err
  826. }
  827. func DeleteDialysisBeforThree(orgid int64, patient_id int64, record_date int64) error {
  828. prepare := models.DialysisBeforePrepare{}
  829. err := XTWriteDB().Model(&prepare).Where("user_org_id = ? and patient_id = ? and record_date = ? and status = 1", orgid, patient_id, record_date).Updates(map[string]interface{}{"status": 0, "count": 0, "mtime": time.Now().Unix()}).Error
  830. return err
  831. }
  832. func ConsumablesDeliveryTotalOne(orgID int64, patient_id int64, record_time int64, goods []*models.DialysisBeforePrepareGoods, goodOne []*models.NewDialysisBeforePrepareGoods) (err error) {
  833. //查询该患者当天已经出库的耗材信息
  834. goods_yc, _ := FindConsumablesByDateTwo(orgID, patient_id, record_time)
  835. for _, item := range goods_yc {
  836. fmt.Println("item0000000000000", item.Count)
  837. }
  838. for _, item := range goods {
  839. fmt.Println("item1111111111111", item.Count)
  840. }
  841. // 和新请求的出库数据进行对比,分出那些是继续出库的,那些是需要删除出库的
  842. for i := len(goods_yc) - 1; i >= 0; i-- {
  843. goods_yc_temp := goods_yc[i]
  844. for j := len(goods) - 1; j >= 0; j-- {
  845. goods_temp := goods[j]
  846. // 已经出库和新请求出库都存在该耗材,则判断出库数量,分成是继续出库,还是删除出库
  847. if goods_yc_temp.GoodTypeId == goods_temp.GoodTypeId && goods_yc_temp.GoodId == goods_temp.GoodId {
  848. // 已经出库和新请求出库的出库数量一致,则清除两个结构体里的数据(既不出库,也不删除出库)
  849. if goods_yc_temp.Count == goods_temp.Count {
  850. goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)
  851. goods = append(goods[:j], goods[j+1:]...)
  852. }
  853. fmt.Println("998888888888888", goods_yc_temp.Count)
  854. fmt.Println("7777777777777777", goods_temp.Count)
  855. // 如果已经出库的数量 大于 新请求出库的数量,则代表需要删除出库
  856. if goods_yc_temp.Count > goods_temp.Count {
  857. fmt.Println("进来了是吗")
  858. temp_count := goods_yc_temp.Count - goods_temp.Count
  859. goods_yc[i].Count = temp_count
  860. goods = append(goods[:j], goods[j+1:]...)
  861. break
  862. }
  863. fmt.Println("555555555555", goods_yc_temp.Count)
  864. fmt.Println("444444444444", goods_temp.Count)
  865. // 如果已经出库的数量 小于 新请求出库的梳理,则代表需要增加出库
  866. if goods_yc_temp.Count < goods_temp.Count {
  867. temp_count := goods_temp.Count - goods_yc_temp.Count
  868. fmt.Println("988888888888888", temp_count)
  869. goods[j].Count = temp_count
  870. goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)
  871. fmt.Println("888888888", goods_yc)
  872. }
  873. }
  874. }
  875. }
  876. // goods_yc 这个数据就是需要已经出库了,但是现在需要删除出库的耗材数据
  877. // goods 这个数据就是需要出库的耗材的数据
  878. fmt.Println("goods222222222222", goods)
  879. fmt.Println("goodsy999999999999", goods_yc)
  880. if len(goods) > 0 {
  881. out, err := FindStockOutByIsSys(orgID, 1, record_time)
  882. if err == gorm.ErrRecordNotFound {
  883. //没有记录,则创建出库单
  884. timeStr := time.Now().Format("2006-01-02")
  885. timeArr := strings.Split(timeStr, "-")
  886. total, _ := FindAllWarehouseOut(orgID)
  887. total = total + 1
  888. warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
  889. number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
  890. number = number + total
  891. warehousing_out_order = "CKD" + strconv.FormatInt(number, 10)
  892. warehouseOut := models.WarehouseOut{
  893. WarehouseOutOrderNumber: warehousing_out_order,
  894. OperationTime: time.Now().Unix(),
  895. OrgId: orgID,
  896. Creater: 0,
  897. Ctime: time.Now().Unix(),
  898. Status: 1,
  899. WarehouseOutTime: record_time,
  900. Dealer: 0,
  901. Manufacturer: 0,
  902. Type: 1,
  903. IsSys: 1,
  904. }
  905. err := AddSigleWarehouseOut(&warehouseOut)
  906. if err != nil {
  907. utils.TraceLog("创建出库单失败 err = %v", err)
  908. return err
  909. } else {
  910. out = warehouseOut
  911. }
  912. }
  913. for _, item := range goods {
  914. for _, it := range goodOne {
  915. if item.GoodTypeId == it.GoodTypeId && it.GoodId == it.GoodId {
  916. it.NewCount = item.Count
  917. }
  918. }
  919. }
  920. for _, item := range goodOne {
  921. //prepare := models.DialysisBeforePrepare{
  922. // GoodTypeId: item.GoodTypeId,
  923. // GoodId: item.GoodId,
  924. // Count: item.Count,
  925. // NewCount: item.NewCount,
  926. //}
  927. info := models.WarehouseOutInfo{
  928. GoodTypeId: item.GoodTypeId,
  929. GoodId: item.GoodId,
  930. Count: item.Count,
  931. }
  932. ConsumablesDeliveryOne(orgID, record_time, &info, &out, item.Count)
  933. }
  934. }
  935. if len(goods_yc) > 0 {
  936. for _, good_yc := range goods_yc {
  937. out, _ := FindStockOutByIsSys(orgID, 1, record_time)
  938. ConsumablesDeliveryDeleteOne(orgID, record_time, good_yc, &out)
  939. }
  940. }
  941. return nil
  942. }
  943. //耗材出库
  944. func ConsumablesDeliveryOne(orgID int64, record_time int64, goods *models.WarehouseOutInfo, warehouseOut *models.WarehouseOut, count int64) (err error) {
  945. // 判断处方里药品单位是拆零单位还是包装单位, 如果是包装单位,则根据规格,将包装数量转为拆零数量
  946. var deliver_number int64 = 0
  947. var stock_number int64 = 0
  948. var maxNumber int64 = 0
  949. deliver_number = goods.Count
  950. fmt.Println("添加数量", deliver_number)
  951. // 根据先进先出原则,查询最先入库的批次,进行出库
  952. // 如果没有对应的库存,则报错
  953. warehouse, err := FindFirstWarehousingInfoByStock(goods.GoodId, goods.GoodTypeId)
  954. fmt.Println("err222222222222222222222", warehouse.StockCount)
  955. if err != nil {
  956. fmt.Println("232323232323进来")
  957. return err
  958. }
  959. // 将该批次的剩余库存数量转换为拆零数量
  960. stock_number = warehouse.StockCount
  961. fmt.Println("3434343434343434", stock_number)
  962. fmt.Println("8888888888888888888", deliver_number)
  963. // 当库存数量大于或等于出库数量的话,则正常出库该批次
  964. if stock_number >= deliver_number {
  965. warehouseOutInfo := &models.WarehouseOutInfo{
  966. WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
  967. WarehouseOutId: warehouseOut.ID,
  968. WarehouseInfotId: warehouse.ID,
  969. Status: 1,
  970. Ctime: time.Now().Unix(),
  971. Remark: goods.Remark,
  972. OrgId: orgID,
  973. Type: 1,
  974. Manufacturer: goods.Manufacturer,
  975. Dealer: goods.Dealer,
  976. IsSys: 0,
  977. SysRecordTime: record_time,
  978. GoodTypeId: goods.GoodTypeId,
  979. GoodId: goods.GoodId,
  980. ExpiryDate: goods.ExpiryDate,
  981. ProductDate: goods.ProductDate,
  982. Number: goods.Number,
  983. Price: goods.Price,
  984. }
  985. warehouseOutInfo.Count = goods.Count
  986. stockInInfo, _ := FindLastStockInInfoRecord(goods.GoodId, orgID)
  987. warehouseOutInfo.Price = stockInInfo.Price
  988. errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
  989. if errOne != nil {
  990. return errOne
  991. }
  992. maxNumber = goods.Count
  993. if warehouse.StockCount < maxNumber {
  994. return errors.New("库存数量不足")
  995. }
  996. warehouse.StockCount = warehouse.StockCount - maxNumber
  997. warehouse.Mtime = time.Now().Unix()
  998. if warehouse.StockCount < 0 {
  999. fmt.Println("进来33232323232232323233232", warehouse.StockCount)
  1000. return errors.New("库存数量不足")
  1001. }
  1002. return nil
  1003. } else {
  1004. // 当改批次的库存数量小于出库数量的话,则先把该批次出库完后,再进行递归出库
  1005. warehouseOutInfo := &models.WarehouseOutInfo{
  1006. WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
  1007. WarehouseOutId: warehouseOut.ID,
  1008. WarehouseInfotId: warehouse.ID,
  1009. Status: 1,
  1010. Ctime: time.Now().Unix(),
  1011. Remark: goods.Remark,
  1012. OrgId: orgID,
  1013. Type: 1,
  1014. Manufacturer: goods.Manufacturer,
  1015. Dealer: goods.Dealer,
  1016. IsSys: 0,
  1017. SysRecordTime: record_time,
  1018. GoodTypeId: goods.GoodTypeId,
  1019. GoodId: goods.GoodId,
  1020. ExpiryDate: goods.ExpiryDate,
  1021. ProductDate: goods.ProductDate,
  1022. Number: goods.Number,
  1023. Price: goods.Price,
  1024. }
  1025. warehouseOutInfo.Count = stock_number
  1026. stockInInfo, _ := service.FindLastStockInInfoRecord(goods.GoodId, orgID)
  1027. warehouseOutInfo.Price = stockInInfo.Price
  1028. errOne := service.AddSigleWarehouseOutInfo(warehouseOutInfo)
  1029. if errOne != nil {
  1030. return errOne
  1031. }
  1032. // 出库完成后,要将该批次库存清零
  1033. warehouse.StockCount = 0
  1034. warehouse.Mtime = time.Now().Unix()
  1035. errThree := UpDateWarehouseInfoByStock(&warehouse)
  1036. if errThree != nil {
  1037. return errThree
  1038. }
  1039. // 清零完该库存后,还有剩余出库未出完,进行对应的递归操作
  1040. goods.Count = deliver_number - stock_number
  1041. ConsumablesDeliveryOne(orgID, record_time, goods, warehouseOut, count)
  1042. }
  1043. return nil
  1044. }
  1045. //耗材出库删除
  1046. func ConsumablesDeliveryDeleteOne(orgID int64, record_time int64, good_yc *models.DialysisBeforePrepare, warehouseOut *models.WarehouseOut) (err error) {
  1047. // 先根据相关信息查询当天该耗材的出库信息
  1048. warehouseOutInfos, err := FindStockOutInfoByStockOne(orgID, good_yc.GoodTypeId, good_yc.GoodId, record_time)
  1049. if err != nil {
  1050. return err
  1051. }
  1052. var delete_count int64 = 0
  1053. for _, ware := range warehouseOutInfos {
  1054. // 判断当前出库的数据和删除出库数量
  1055. if good_yc.Count <= ware.Count {
  1056. delete_count = good_yc.Count
  1057. } else {
  1058. delete_count = ware.Count
  1059. }
  1060. // 在出库记录表里记录退库详情
  1061. warehouseOutInfo := &models.WarehouseOutInfo{
  1062. WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
  1063. WarehouseOutId: warehouseOut.ID,
  1064. //WarehouseInfoId: warehouse.ID,
  1065. Status: 1,
  1066. Ctime: time.Now().Unix(),
  1067. Remark: "",
  1068. OrgId: orgID,
  1069. Type: 1,
  1070. Manufacturer: 0,
  1071. Dealer: 0,
  1072. IsSys: 0,
  1073. SysRecordTime: record_time,
  1074. GoodTypeId: good_yc.GoodTypeId,
  1075. GoodId: good_yc.GoodId,
  1076. }
  1077. warehouseOutInfo.Count = delete_count
  1078. stockInInfo, _ := FindLastStockInInfoRecord(good_yc.GoodId, orgID)
  1079. warehouseOutInfo.Price = stockInInfo.Price
  1080. errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
  1081. if errOne != nil {
  1082. return errOne
  1083. }
  1084. // 删除出库完成后,要增加对应批次的库存数量
  1085. errThree := UpDateWarehouseInfoByStockDelete(ware.WarehouseInfotId, delete_count)
  1086. if errThree != nil {
  1087. return errThree
  1088. }
  1089. // 增加了对应的库存后,看看还有多少需要退库的
  1090. good_yc.Count = good_yc.Count - delete_count
  1091. if good_yc.Count == 0 {
  1092. return nil
  1093. }
  1094. }
  1095. if good_yc.Count == 0 {
  1096. return nil
  1097. } else {
  1098. return errors.New("退库和出库数据不匹配")
  1099. }
  1100. }
  1101. func ConsumablesDeliveryTotalSix(orgID int64, patient_id int64, record_time int64, goods []*models.DialysisBeforePrepareGoods, goodOne []*models.NewDialysisBeforePrepareGoods) (err error) {
  1102. //查询该患者当天已经出库的耗材信息
  1103. goods_yc, _ := FindConsumablesByDateThree(orgID, patient_id, record_time)
  1104. // 和新请求的出库数据进行对比,分出那些是继续出库的,那些是需要删除出库的
  1105. for i := len(goods_yc) - 1; i >= 0; i-- {
  1106. goods_yc_temp := goods_yc[i]
  1107. for j := len(goods) - 1; j >= 0; j-- {
  1108. goods_temp := goods[j]
  1109. // 已经出库和新请求出库都存在该耗材,则判断出库数量,分成是继续出库,还是删除出库
  1110. if goods_yc_temp.GoodTypeId == goods_temp.GoodTypeId && goods_yc_temp.GoodId == goods_temp.GoodId {
  1111. // 已经出库和新请求出库的出库数量一致,则清除两个结构体里的数据(既不出库,也不删除出库)
  1112. if goods_yc_temp.Count == goods_temp.Count {
  1113. goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)
  1114. goods = append(goods[:j], goods[j+1:]...)
  1115. break
  1116. }
  1117. // 如果已经出库的数量 大于 新请求出库的数量,则代表需要删除出库
  1118. if goods_yc_temp.Count > goods_temp.Count {
  1119. temp_count := goods_yc_temp.Count - goods_temp.Count
  1120. goods_yc[i].Count = temp_count
  1121. goods = append(goods[:j], goods[j+1:]...)
  1122. break
  1123. }
  1124. // 如果已经出库的数量 小于 新请求出库的梳理,则代表需要增加出库
  1125. if goods_yc_temp.Count < goods_temp.Count {
  1126. temp_count := goods_temp.Count - goods_yc_temp.Count
  1127. //fmt.Println("988888888888888", temp_count)
  1128. goods[j].Count = temp_count
  1129. goods_yc = append(goods_yc[:i], goods_yc[i+1:]...)
  1130. //fmt.Println("888888888", goods_yc)
  1131. break
  1132. }
  1133. }
  1134. }
  1135. }
  1136. // goods_yc 这个数据就是需要已经出库了,但是现在需要删除出库的耗材数据
  1137. // goods 这个数据就是需要出库的耗材的数据(新增的数据)
  1138. fmt.Println("goods222222222222", goods)
  1139. fmt.Println("goodsy999999999999", goods_yc)
  1140. if len(goods) > 0 {
  1141. out, err := FindStockOutByIsSys(orgID, 1, record_time)
  1142. if err == gorm.ErrRecordNotFound {
  1143. //没有记录,则创建出库单
  1144. timeStr := time.Now().Format("2006-01-02")
  1145. timeArr := strings.Split(timeStr, "-")
  1146. total, _ := FindAllWarehouseOut(orgID)
  1147. total = total + 1
  1148. warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
  1149. number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
  1150. number = number + total
  1151. warehousing_out_order = "CKD" + strconv.FormatInt(number, 10)
  1152. warehouseOut := models.WarehouseOut{
  1153. WarehouseOutOrderNumber: warehousing_out_order,
  1154. OperationTime: time.Now().Unix(),
  1155. OrgId: orgID,
  1156. Creater: 0,
  1157. Ctime: time.Now().Unix(),
  1158. Status: 1,
  1159. WarehouseOutTime: record_time,
  1160. Dealer: 0,
  1161. Manufacturer: 0,
  1162. Type: 1,
  1163. IsSys: 1,
  1164. }
  1165. err := AddSigleWarehouseOut(&warehouseOut)
  1166. if err != nil {
  1167. utils.TraceLog("创建出库单失败 err = %v", err)
  1168. return err
  1169. } else {
  1170. out = warehouseOut
  1171. }
  1172. }
  1173. for _, item := range goods {
  1174. var newCount int64 = 0
  1175. for _, it := range goodOne {
  1176. if item.GoodTypeId == it.GoodTypeId && item.GoodId == it.GoodId {
  1177. newCount = it.Count
  1178. }
  1179. }
  1180. prepare := models.DialysisBeforePrepare{
  1181. GoodTypeId: item.GoodTypeId,
  1182. GoodId: item.GoodId,
  1183. Count: item.Count,
  1184. }
  1185. ConsumablesDelivery(orgID, patient_id, record_time, &prepare, &out, newCount)
  1186. }
  1187. }
  1188. if len(goods_yc) > 0 {
  1189. for _, good_yc := range goods_yc {
  1190. out, _ := FindStockOutByIsSys(orgID, 1, record_time)
  1191. ConsumablesDeliveryDeleteThree(orgID, record_time, good_yc, &out)
  1192. }
  1193. }
  1194. return nil
  1195. }
  1196. //耗材出库删除
  1197. func ConsumablesDeliveryDeleteThree(orgID int64, record_time int64, good_yc *models.BloodAutomaticReduceDetail, warehouseOut *models.WarehouseOut) (err error) {
  1198. // 先根据相关信息查询当天该耗材的出库信息
  1199. warehouseOutInfos, err := FindStockOutInfoByStockOne(orgID, good_yc.GoodTypeId, good_yc.GoodId, record_time)
  1200. if err != nil {
  1201. return err
  1202. }
  1203. var delete_count int64 = 0
  1204. for _, ware := range warehouseOutInfos {
  1205. // 判断当前出库的数据和删除出库数量
  1206. if good_yc.Count <= ware.Count {
  1207. delete_count = good_yc.Count
  1208. } else {
  1209. delete_count = ware.Count
  1210. }
  1211. // 在出库记录表里记录退库详情
  1212. warehouseOutInfo := &models.WarehouseOutInfo{
  1213. WarehouseOutOrderNumber: warehouseOut.WarehouseOutOrderNumber,
  1214. WarehouseOutId: warehouseOut.ID,
  1215. //WarehouseInfoId: warehouse.ID,
  1216. Status: 1,
  1217. Ctime: time.Now().Unix(),
  1218. Remark: "",
  1219. OrgId: orgID,
  1220. Type: 1,
  1221. Manufacturer: 0,
  1222. Dealer: 0,
  1223. IsSys: 0,
  1224. SysRecordTime: record_time,
  1225. GoodTypeId: good_yc.GoodTypeId,
  1226. GoodId: good_yc.GoodId,
  1227. }
  1228. warehouseOutInfo.Count = delete_count
  1229. stockInInfo, _ := FindLastStockInInfoRecord(good_yc.GoodId, orgID)
  1230. warehouseOutInfo.Price = stockInInfo.Price
  1231. errOne := AddSigleWarehouseOutInfo(warehouseOutInfo)
  1232. if errOne != nil {
  1233. return errOne
  1234. }
  1235. // 删除出库完成后,要增加对应批次的库存数量
  1236. errThree := UpDateWarehouseInfoByStockDelete(ware.WarehouseInfotId, delete_count)
  1237. if errThree != nil {
  1238. return errThree
  1239. }
  1240. // 增加了对应的库存后,看看还有多少需要退库的
  1241. good_yc.Count = good_yc.Count - delete_count
  1242. if good_yc.Count == 0 {
  1243. return nil
  1244. }
  1245. }
  1246. if good_yc.Count == 0 {
  1247. return nil
  1248. } else {
  1249. return errors.New("退库和出库数据不匹配")
  1250. }
  1251. }