warhouse_service.go 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package service
  2. import (
  3. "XT_New/models"
  4. "XT_New/utils"
  5. "errors"
  6. _ "fmt"
  7. "github.com/jinzhu/gorm"
  8. "math"
  9. "strconv"
  10. "strings"
  11. "time"
  12. )
  13. // 药品出库
  14. func DrugsDelivery(orgID int64, advice *models.DoctorAdvice) (err error) {
  15. // 1.判断药品是否来自专用字典的药品库
  16. // 2.判断当天当前机构有没有创建出库单,没有则创建
  17. // 3.创建出库流程
  18. // 3.1 实现先进先出逻辑 由于药品执行后,不可以修改和删除,所以不考虑出库后的退库和修改出库数量等
  19. isHasWay := false
  20. record_time := int64(0)
  21. if advice.Way == 1 {
  22. isHasWay = true
  23. record_time = advice.RecordDate
  24. }
  25. if isHasWay {
  26. //判断当天当前机构有没有创建出库单,没有则创建
  27. out, err := FindDrugStockOutByIsSys(orgID, 1, record_time)
  28. if err == gorm.ErrRecordNotFound {
  29. timeStr := time.Now().Format("2006-01-02")
  30. timeArr := strings.Split(timeStr, "-")
  31. total, _ := FindAllDrugWarehouseOut(orgID)
  32. total = total + 1
  33. warehousing_out_order := strconv.FormatInt(orgID, 10) + timeArr[0] + timeArr[1] + timeArr[2] + "000"
  34. number, _ := strconv.ParseInt(warehousing_out_order, 10, 64)
  35. number = number + total
  36. warehousing_out_order = "YPCKD" + strconv.FormatInt(number, 10)
  37. // creater := adminUserInfo.AdminUser.Id
  38. warehouseOut := models.DrugWarehouseOut{
  39. WarehouseOutOrderNumber: warehousing_out_order,
  40. OperationTime: time.Now().Unix(),
  41. OrgId: orgID,
  42. Creater: 0,
  43. Ctime: time.Now().Unix(),
  44. Status: 1,
  45. WarehouseOutTime: record_time,
  46. Dealer: 0,
  47. Manufacturer: 0,
  48. Type: 1,
  49. IsSys: 1,
  50. }
  51. err := AddSigleDrugWarehouseOut(&warehouseOut)
  52. if err != nil {
  53. utils.TraceLog("创建出库单失败 err = %v", err)
  54. return err
  55. } else {
  56. out = warehouseOut
  57. }
  58. }
  59. // 出库流程
  60. // 1.查询改药品在药品库的规格信息,并将处方里的规格进行换算(尽量将拆零单位转换成包装单位)
  61. drup, _ := FindBaseDrugLibRecord(orgID, advice.DrugId)
  62. if drup.ID > 0 {
  63. prescribingNumber := advice.PrescribingNumber
  64. DrugDeliverInfo(orgID, prescribingNumber, &out, &drup, advice)
  65. } else {
  66. return errors.New("药品信息不存在")
  67. }
  68. }
  69. return
  70. }
  71. // 药品出库 递归方式
  72. func DrugDeliverInfo(orgID int64, prescribingNumber float64, warehouseout *models.DrugWarehouseOut, drup *models.BaseDrugLib, advice *models.DoctorAdvice) (err error) {
  73. // 判断处方里药品单位是拆零单位还是包装单位, 如果是包装单位,则根据规格,将包装数量转为拆零数量
  74. var deliver_number int64 = 0
  75. var stock_number int64 = 0
  76. prescribingNumber_temp := strconv.FormatFloat(math.Abs(prescribingNumber), 'f', 0, 64)
  77. count, _ := strconv.ParseInt(prescribingNumber_temp, 10, 64)
  78. if advice.PrescribingNumberUnit == drup.MaxUnit {
  79. deliver_number = count * drup.MinNumber
  80. } else {
  81. deliver_number = count
  82. }
  83. // 根据先进先出原则,查询最先入库的批次,进行出库
  84. // 如果没有对应的库存,则报错
  85. warehouse, err := FindLastWarehousingInfoByID(advice.DrugId)
  86. if err != nil {
  87. return err
  88. }
  89. // 将该批次的剩余库存数量转换为拆零数量
  90. stock_number = warehouse.StockMaxNumber*drup.MinNumber + warehouse.StockMinNumber
  91. // 当库存数量大于或等于出库数量的话,则正常出库该批次
  92. if stock_number >= deliver_number {
  93. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  94. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  95. WarehouseOutId: warehouseout.ID,
  96. Status: 1,
  97. Ctime: time.Now().Unix(),
  98. Remark: "",
  99. OrgId: orgID,
  100. Type: 1,
  101. Manufacturer: 0,
  102. Dealer: 0,
  103. IsSys: 1,
  104. SysRecordTime: advice.RecordDate,
  105. DrugId: advice.DrugId,
  106. }
  107. warehouseOutInfo.Count = deliver_number
  108. warehouseOutInfo.CountUnit = drup.MinUnit
  109. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  110. if errOne != nil {
  111. return errOne
  112. } else {
  113. // prescribingNumber := strconv.FormatFloat(math.Abs(item.PrescribingNumber), 'f', 0, 64)
  114. // count, _ := strconv.ParseInt(prescribingNumber, 10, 64)
  115. details := &models.DrugAutomaticReduceDetail{
  116. WarehouseOutId: warehouseOutInfo.ID,
  117. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  118. PatientId: advice.PatientId,
  119. Ctime: time.Now().Unix(),
  120. Mtime: time.Now().Unix(),
  121. Status: 1,
  122. RecordTime: advice.RecordDate,
  123. OrgId: orgID,
  124. DrugId: advice.DrugId,
  125. Count: deliver_number,
  126. CountUnit: drup.MinUnit,
  127. }
  128. errTwo := AddSigleDrugAutoReduceRecordInfo(details)
  129. if errTwo != nil {
  130. return errTwo
  131. }
  132. }
  133. // 出库完成后,要减去对应批次的库存数量
  134. // 判断处方里药品单位是拆零单位还是包装单位, 如果是拆零单位,则根据规格,将拆零数量转为包装数量
  135. var maxNumber int64 = 0
  136. var minNumber int64 = 0
  137. if advice.PrescribingNumberUnit == drup.MinUnit {
  138. maxNumber = count / drup.MinNumber
  139. minNumber = count % drup.MinNumber
  140. } else {
  141. maxNumber = count
  142. }
  143. if warehouse.StockMaxNumber < maxNumber {
  144. return errors.New("库存数量不足")
  145. }
  146. warehouse.StockMaxNumber = warehouse.StockMaxNumber - maxNumber
  147. warehouse.Mtime = time.Now().Unix()
  148. if warehouse.StockMinNumber < minNumber {
  149. warehouse.StockMaxNumber = warehouse.StockMaxNumber - 1
  150. warehouse.StockMinNumber = warehouse.StockMinNumber + drup.MinNumber - minNumber
  151. } else {
  152. warehouse.StockMinNumber = warehouse.StockMinNumber - minNumber
  153. }
  154. if warehouse.StockMaxNumber < 0 {
  155. return errors.New("库存数量不足")
  156. }
  157. errThree := UpDateWarehouseInfoByStock(&warehouse)
  158. if errThree != nil {
  159. return errThree
  160. }
  161. return nil
  162. } else {
  163. // 当改批次的库存数量小于出库数量的话,则先把该批次出库完后,再进行递归出库
  164. warehouseOutInfo := &models.DrugWarehouseOutInfo{
  165. WarehouseOutOrderNumber: warehouseout.WarehouseOutOrderNumber,
  166. WarehouseOutId: warehouseout.ID,
  167. Status: 1,
  168. Ctime: time.Now().Unix(),
  169. Remark: "",
  170. OrgId: orgID,
  171. Type: 1,
  172. Manufacturer: 0,
  173. Dealer: 0,
  174. IsSys: 1,
  175. SysRecordTime: advice.RecordDate,
  176. DrugId: advice.DrugId,
  177. }
  178. // prescribingNumber := strconv.FormatFloat(math.Abs(item.PrescribingNumber), 'f', 0, 64)
  179. // count, _ := strconv.ParseInt(prescribingNumber, 10, 64)
  180. warehouseOutInfo.Count = stock_number
  181. warehouseOutInfo.CountUnit = drup.MinUnit
  182. errOne := AddSigleDrugWarehouseOutInfo(warehouseOutInfo)
  183. if errOne != nil {
  184. return errOne
  185. } else {
  186. details := &models.DrugAutomaticReduceDetail{
  187. WarehouseOutId: warehouseOutInfo.ID,
  188. WarehouseOutOrderNumber: warehouseOutInfo.WarehouseOutOrderNumber,
  189. PatientId: advice.PatientId,
  190. Ctime: time.Now().Unix(),
  191. Mtime: time.Now().Unix(),
  192. Status: 1,
  193. RecordTime: advice.RecordDate,
  194. OrgId: orgID,
  195. DrugId: advice.DrugId,
  196. Count: stock_number,
  197. CountUnit: drup.MinUnit,
  198. }
  199. errTwo := AddSigleDrugAutoReduceRecordInfo(details)
  200. if errTwo != nil {
  201. return errTwo
  202. }
  203. }
  204. // 出库完成后,要将该批次库存清零
  205. warehouse.StockMaxNumber = 0
  206. warehouse.StockMinNumber = 0
  207. warehouse.Mtime = time.Now().Unix()
  208. errThree := UpDateWarehouseInfoByStock(&warehouse)
  209. if errThree != nil {
  210. return errThree
  211. }
  212. // 清零完该库存后,还有剩余出库未出完,进行对应的递归操作
  213. prescribingNumber_two_temp := deliver_number - stock_number
  214. advice.PrescribingNumber = float64(prescribingNumber_two_temp)
  215. advice.PrescribingNumberUnit = drup.MinUnit
  216. DrugDeliverInfo(orgID, prescribingNumber, warehouseout, drup, advice)
  217. }
  218. return
  219. }