|
|
import datetime
|
|
|
from datetime import timedelta
|
|
|
from decimal import Decimal
|
|
|
from tortoise.queryset import Q
|
|
|
|
|
|
from conf.setting import setting
|
|
|
from helper.drug import milligram_to_gram, gram_to_milligram
|
|
|
from helper.log import record_log
|
|
|
from helper.logger import logger
|
|
|
from models.dictionary import Dictionary
|
|
|
from models.drawer_board import DrawerBoard
|
|
|
from models.drug import Drug, DrugStateEnum
|
|
|
from models.drug_use_log import DrugUseLog, DrugUseStateEnum
|
|
|
from models.template import Template
|
|
|
from models.terminal import Terminal
|
|
|
from models.user import User
|
|
|
from models.cabinet import Cabinet
|
|
|
from transfer.basic import BasicStandard
|
|
|
|
|
|
class Standard(BasicStandard):
|
|
|
'''标准流转类'''
|
|
|
|
|
|
def __init__(self, users: list[str]):
|
|
|
self.users = users
|
|
|
|
|
|
self.rfid = ""
|
|
|
self.hole = None
|
|
|
self.drug_obj = None
|
|
|
self.drawer_board_obj = None
|
|
|
|
|
|
self.in_return_func = {
|
|
|
DrugStateEnum.OUT: self.return_drug,
|
|
|
DrugStateEnum.INITIAL: self.in_drug,
|
|
|
DrugStateEnum.IN: self.in_drug,
|
|
|
DrugStateEnum.EMPTY: None
|
|
|
}
|
|
|
|
|
|
async def _get_drug_related(self, cabinet_id):
|
|
|
drugs = await Drug.filter(rfid=self.rfid).prefetch_related("dictionary", "template")
|
|
|
if not drugs:
|
|
|
return False
|
|
|
self.drug_obj = drugs[0]
|
|
|
# self.drawer_board_obj = await DrawerBoard.filter(cabinet_id=cabinet_id).prefetch_related("cabinet", "drawer", "board").first()
|
|
|
self.template_obj = self.drug_obj.template
|
|
|
self.terminal_obj = await Terminal.get_or_none(id=setting.TERMINAL_ID)
|
|
|
self.cabinet_obj = await Cabinet.get_or_none(id=cabinet_id)
|
|
|
return True
|
|
|
|
|
|
def parse_position(self, hole):
|
|
|
"""
|
|
|
解析位置信息
|
|
|
:return:
|
|
|
"""
|
|
|
# terminal_name = self.terminal_obj.name
|
|
|
drawer_label = self.drawer_board_obj.drawer.label if self.drawer_board_obj else ""
|
|
|
cabinet_location_label = f"{self.cabinet_obj.label}"
|
|
|
board_hole = ""
|
|
|
if self.drawer_board_obj:
|
|
|
board_hole = self.drawer_board_obj.board.chip_dict.get(str(hole), "") if self.drawer_board_obj.board.chip_dict \
|
|
|
else ""
|
|
|
position_str = f"{cabinet_location_label}-{drawer_label}"
|
|
|
if self.drawer_board_obj and self.drawer_board_obj.label:
|
|
|
position_str += f"-{self.drawer_board_obj.label}"
|
|
|
if board_hole:
|
|
|
position_str += f"-{board_hole}"
|
|
|
return position_str
|
|
|
|
|
|
async def return_drug(self):
|
|
|
"""
|
|
|
归还药剂
|
|
|
归还输入用量
|
|
|
:return:
|
|
|
"""
|
|
|
|
|
|
if self.drug_obj.state == DrugStateEnum.EMPTY:
|
|
|
operate_state = DrugUseStateEnum.EMPTY
|
|
|
else:
|
|
|
operate_state = DrugUseStateEnum.PUT
|
|
|
operate_type = "return"
|
|
|
|
|
|
response_info = {
|
|
|
"operate_type": operate_type,
|
|
|
"operate_state": operate_state,
|
|
|
}
|
|
|
return response_info
|
|
|
|
|
|
async def in_drug(self):
|
|
|
"""
|
|
|
入库药剂
|
|
|
:return:
|
|
|
"""
|
|
|
if self.drug_obj.state == DrugStateEnum.EMPTY:
|
|
|
operate_state = DrugUseStateEnum.EMPTY
|
|
|
else:
|
|
|
operate_state = DrugUseStateEnum.IN
|
|
|
operate_type = "in"
|
|
|
response_info = {
|
|
|
"operate_type": operate_type,
|
|
|
"operate_state": operate_state,
|
|
|
}
|
|
|
return response_info
|
|
|
|
|
|
async def put_in(self, rfid: str, cabinet_id: str, position):
|
|
|
"""
|
|
|
归还/入库
|
|
|
:param rfid: rfid
|
|
|
:param cabinet_id: 柜体id
|
|
|
:param line_no: 接线号
|
|
|
:param hole: 孔位
|
|
|
:return:
|
|
|
"""
|
|
|
self.rfid = rfid
|
|
|
# check = await self._get_drug_related(cabinet_id,)
|
|
|
# if not check:
|
|
|
# return False
|
|
|
|
|
|
# 入库或归还
|
|
|
response_info = await self.in_return_func[self.drug_obj.state]()
|
|
|
operate_state = response_info.get("operate_state")
|
|
|
|
|
|
operate_type = response_info.get("operate_type")
|
|
|
if operate_type == 'return':
|
|
|
# 归还流转日志保存
|
|
|
user_id = self.users[0]
|
|
|
peer_ids = ",".join(self.users[1:])
|
|
|
users_name = await User.parse_id_user(self.users)
|
|
|
drug_use_dict = {
|
|
|
"drug": self.drug_obj,
|
|
|
"state": operate_state,
|
|
|
"user_id": user_id,
|
|
|
"peer_ids": peer_ids,
|
|
|
"users": users_name,
|
|
|
"cabinet_id": cabinet_id,
|
|
|
# "drawer_id": self.drawer_board_obj.drawer_id if self.drawer_board_obj else None,
|
|
|
# "drawer_board_id": self.drawer_board_obj.id if self.drawer_board_obj else None,
|
|
|
"position": position,
|
|
|
|
|
|
}
|
|
|
else:
|
|
|
# 入库流转日志保存
|
|
|
drug_use_dict = {
|
|
|
"drug": self.drug_obj,
|
|
|
"state": operate_state,
|
|
|
"user_id": self.users[0],
|
|
|
"peer_ids": ",".join(self.users[1:]),
|
|
|
"users": await User.parse_id_user(self.users),
|
|
|
"cabinet_id": cabinet_id,
|
|
|
# "drawer_id": self.drawer_board_obj.drawer_id if self.drawer_board_obj else None,
|
|
|
# "drawer_board_id": self.drawer_board_obj.id if self.drawer_board_obj else None,
|
|
|
"position": position,
|
|
|
# "weight": weight,
|
|
|
# "use_weight": use_weight,
|
|
|
# "alarm_state": response_info.get("alarm_state"),
|
|
|
# "alarm_desc": response_info.get("alarm_desc"),
|
|
|
}
|
|
|
if setting.TERMINAL_ID:
|
|
|
drug_use_dict.update({
|
|
|
"terminal_id": setting.TERMINAL_ID
|
|
|
})
|
|
|
|
|
|
return_obj = await DrugUseLog().create(**drug_use_dict)
|
|
|
if operate_type == 'return':
|
|
|
receive_obj = await DrugUseLog.filter(drug_id=self.drug_obj.id, state=2).order_by('-created_at').first()
|
|
|
if receive_obj:
|
|
|
# 更新return_log_id字段
|
|
|
receive_obj.return_log_id = return_obj.id
|
|
|
await receive_obj.save()
|
|
|
# 药剂更新
|
|
|
drug_update_dict = {
|
|
|
"state": DrugStateEnum.IN if self.drug_obj.state != DrugStateEnum.EMPTY else DrugStateEnum.EMPTY,
|
|
|
# "drawer_board": self.drawer_board_obj if self.drawer_board_obj else None,
|
|
|
# "board_id": self.drawer_board_obj.board_id if self.drawer_board_obj else None,
|
|
|
# "drawer_id": self.drawer_board_obj.drawer_id if self.drawer_board_obj else None,
|
|
|
"cabinet_id": cabinet_id,
|
|
|
# "position": position,
|
|
|
}
|
|
|
if operate_type == "in":
|
|
|
drug_update_dict.update({
|
|
|
"storage_id": self.users[0],
|
|
|
"storage_at": self._now_strftime(),
|
|
|
})
|
|
|
else:
|
|
|
drug_update_dict.update({
|
|
|
"last_return_at": self._now_strftime(),
|
|
|
"last_return_id": self.users[0],
|
|
|
"last_use_weight": None,
|
|
|
})
|
|
|
await self.drug_obj.update_from_dict(drug_update_dict)
|
|
|
await self.drug_obj.save()
|
|
|
|
|
|
# data = {
|
|
|
# "drug_info": await self.drug_obj.attribute_drug_info(),
|
|
|
# "position": position,
|
|
|
# "operate_type": operate_type,
|
|
|
# "remain_gross_weight": milligram_to_gram(self.drug_obj.remain_gross_weight),
|
|
|
# "use_weight": milligram_to_gram(float(use_weight)) if use_weight else None,
|
|
|
# "created_at": self._now_strftime(),
|
|
|
# "state": drug_update_dict["state"],
|
|
|
# "unit_code": self.drug_obj.attribute("unit_code"), # 单位编码
|
|
|
# "expired_at": self.drug_obj.expired_at.strftime("%Y-%m-%d") if self.drug_obj.expired_at else None # 过期时间
|
|
|
# }
|
|
|
# await self.write_log(operate_type, drug_use_dict)
|
|
|
# return data
|
|
|
|
|
|
async def take_out(self, rfid: str, cabinet_id: str, position):
|
|
|
"""
|
|
|
领用
|
|
|
领用需称重的情况,关上柜门选择条目称重,更新重量。如果没有称,定时任务五分钟扫到后报警
|
|
|
领用的时候如果上一次归还必称重未称重,drug_use_log中weight为空,那么就必须称重,称重后更新上一次的归还记录重量与用量
|
|
|
:param rfid:
|
|
|
:param cabinet_id:
|
|
|
:param line_no:
|
|
|
:return: 领用清单条目
|
|
|
"""
|
|
|
self.rfid = rfid
|
|
|
# check = await self._get_drug_related(cabinet_id, line_no)
|
|
|
# if not check or self.drug_obj.state == 3:
|
|
|
# self.drug_obj.position = None
|
|
|
# await self.drug_obj.save()
|
|
|
# return False
|
|
|
|
|
|
# 领用是否需称重(上次归还未称重则本次领用需称重)
|
|
|
# receive_require_weigh = await DrugUseLog.judge_receive_require_weigh(drug_id=self.drug_obj.id,
|
|
|
# terminal_obj=self.terminal_obj)
|
|
|
#
|
|
|
# # 是否领用即空瓶
|
|
|
drug_obj = await Drug.get(rfid=rfid).prefetch_related('template','dictionary')
|
|
|
# terminal_obj = await Template.get(id=drug_obj.template.id).prefetch_related('archive')
|
|
|
# first_will_empty = terminal_obj.archive.params.get("first_will_empty", '')
|
|
|
# first_will_open = terminal_obj.archive.params.get("first_will_open", '')
|
|
|
|
|
|
# position = f"{self.parse_position(self.drug_obj.hole)}"
|
|
|
drug_use_dict = {
|
|
|
"drug": self.drug_obj,
|
|
|
"state": DrugUseStateEnum.TAKE,
|
|
|
"user_id": self.users[0],
|
|
|
"peer_ids": ",".join(self.users[1:]),
|
|
|
"users": await User.parse_id_user(self.users),
|
|
|
|
|
|
"terminal_id": setting.TERMINAL_ID,
|
|
|
"cabinet_id": cabinet_id,
|
|
|
# "drawer_id": self.drawer_board_obj.drawer_id,
|
|
|
# "drawer_board_id": self.drawer_board_obj.id,
|
|
|
"hole": self.drug_obj.hole,
|
|
|
"position": position,
|
|
|
|
|
|
}
|
|
|
await DrugUseLog().create(**drug_use_dict)
|
|
|
|
|
|
# 更新药剂信息
|
|
|
drug_update_dict = {
|
|
|
"state": DrugStateEnum.OUT if self.drug_obj.state != DrugStateEnum.EMPTY else DrugStateEnum.EMPTY,
|
|
|
# "last_weight": 0,
|
|
|
# "drawer_board": self.drawer_board_obj,
|
|
|
# "board_id": self.drawer_board_obj.board_id,
|
|
|
"last_receive_at": self._now_strftime(),
|
|
|
"last_receive_id": self.users[0],
|
|
|
"position": position,
|
|
|
}
|
|
|
|
|
|
await self.drug_obj.update_from_dict(drug_update_dict)
|
|
|
await self.drug_obj.save()
|
|
|
|
|
|
dic_obj = await Dictionary.get(id=drug_obj.dictionary.id)
|
|
|
dic_obj.use_count += 1
|
|
|
await dic_obj.save()
|
|
|
|
|
|
# data = {
|
|
|
# "drug_info": await self.drug_obj.attribute_drug_info(),
|
|
|
# "position": position,
|
|
|
# "hole": self.drug_obj.hole,
|
|
|
# "remain_gross_weight": await self.drug_obj.format_weight(), # 领用清单条目余重
|
|
|
# "created_at": self._now_strftime(),
|
|
|
# "state": drug_update_dict["state"],
|
|
|
# "unit_code": self.drug_obj.attribute("unit_code"), # 单位编码
|
|
|
# "expired_at": self.drug_obj.expired_at.strftime("%Y-%m-%d"), # 过期时间
|
|
|
# "fill_json_content": self.drug_obj.fill_json_content
|
|
|
# }
|
|
|
# await self.write_log("take_out", drug_use_dict)
|
|
|
#
|
|
|
# return data
|
|
|
|
|
|
|
|
|
|
|
|
async def decap(self, rfid: str, cabinet_id: str, line_no: str, hole: int = 0):
|
|
|
'''报废处置 传入值是什么?'''
|
|
|
self.rfid = rfid
|
|
|
await self._get_drug_related(cabinet_id, line_no)
|
|
|
drug_use_dict = {
|
|
|
"drug": self.drug_obj,
|
|
|
"state": DrugUseStateEnum.SCRAP,
|
|
|
"user_id": self.users[0],
|
|
|
"peer_ids": ",".join(self.users[1:]),
|
|
|
"users": await User.parse_id_user(self.users),
|
|
|
|
|
|
"terminal_id": setting.TERMINAL_ID,
|
|
|
"cabinet_id": self.drawer_board_obj.cabinet_id,
|
|
|
"drawer_id": self.drawer_board_obj.drawer_id,
|
|
|
"drawer_board_id": self.drawer_board_obj.id,
|
|
|
"hole": hole,
|
|
|
"position": self.drug_obj.position,
|
|
|
"alerted": False,
|
|
|
"use_weight": 0,
|
|
|
}
|
|
|
drug_use_log_obj = await DrugUseLog().create(**drug_use_dict)
|
|
|
|
|
|
# 更新药剂信息
|
|
|
drug_update_dict = {
|
|
|
"state": DrugStateEnum.SCRAP,
|
|
|
"last_use_weight": 0,
|
|
|
"drawer_board_id": self.drawer_board_obj.id,
|
|
|
"hole": hole,
|
|
|
"board_id": self.drawer_board_obj.board_id,
|
|
|
}
|
|
|
|
|
|
await self.drug_obj.update_from_dict(drug_update_dict)
|
|
|
await self.drug_obj.save()
|
|
|
|
|
|
drug_use_dict.update({
|
|
|
"drug_use_log_id": drug_use_log_obj.id,
|
|
|
})
|
|
|
return drug_use_dict
|
|
|
|