You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
11 KiB
211 lines
11 KiB
3 months ago
|
from diff.stock import getDiffStockList
|
||
|
from utils.PageHepler import db_page
|
||
|
from sqlalchemy import func
|
||
|
from utils.apiDoc import *
|
||
|
from utils.configOperatingTypeHelper import *
|
||
|
from utils.statisticsHelper import export_diff, get_complete_number, get_complete_current_type_number
|
||
|
from openpyxl import Workbook
|
||
|
from openpyxl.styles import Alignment, Border, Side, Font
|
||
|
import pandas as pd
|
||
|
|
||
|
|
||
|
def alignment_merge(ws, area, value, isAlignment=True):
|
||
|
name_area = ws[area]
|
||
|
ws.merge_cells(area)
|
||
|
if isAlignment:
|
||
|
name_area[0][0].alignment = Alignment(horizontal='center', vertical='center')
|
||
|
name_area[0][0].value = value
|
||
|
|
||
|
|
||
|
@statistics.route('/log')
|
||
|
class StatisticsInStock(Resource):
|
||
|
@staticmethod
|
||
|
def get():
|
||
|
if request.args.get('type') is None:
|
||
|
return BadResponse(ResultCode.PARAM_IS_INVALID, None, None)
|
||
|
outStockReagentFilter = db.session.query(
|
||
|
(ReagtLog.ReagentName + ReagtLog.ReagentSpecification).label('TotalName'),
|
||
|
func.sum(ReagtLog.ReagentNumber).label('TotalNumber')). \
|
||
|
group_by(ReagtLog.ReagentName, ReagtLog.ReagentSpecification).filter(
|
||
|
ReagtLog.OperatingType == GetOperatingTypeUseName(request.args['type'])).filter(
|
||
|
ReagtLog.OperatingTime < datetime.now()). \
|
||
|
filter(ReagtLog.OperatingTime > (datetime.now() - timedelta(days=10))).order_by(
|
||
|
func.sum(ReagtLog.ReagentNumber)).all()
|
||
|
if request.args.get('startTime') is not None and request.args.get('endTime') is not None:
|
||
|
outStockReagentFilter = db.session.query(
|
||
|
(ReagtLog.ReagentName + ReagtLog.ReagentSpecification).label('TotalName'),
|
||
|
func.sum(ReagtLog.ReagentNumber).label('TotalNumber')). \
|
||
|
group_by(ReagtLog.ReagentName, ReagtLog.ReagentSpecification).filter(
|
||
|
ReagtLog.OperatingType == GetOperatingTypeUseName(request.args['type'])).filter(
|
||
|
ReagtLog.OperatingTime < request.args['endTime']). \
|
||
|
filter(ReagtLog.OperatingTime > request.args['startTime']).order_by(
|
||
|
func.sum(ReagtLog.ReagentNumber)).all()
|
||
|
return SuccessResponse(ResultCode.SUCCESS, outStockReagentFilter, None)
|
||
|
|
||
|
|
||
|
@statistics.route('/list')
|
||
|
class StatisticsList(Resource):
|
||
|
@staticmethod
|
||
|
def get():
|
||
|
data = request.args
|
||
|
reagentLogFilter = export_diff(data)
|
||
|
return SuccessResponse(ResultCode.SUCCESS, {'totalNumber': reagentLogFilter.count(),
|
||
|
'list': db_page(reagentLogFilter, ReagtLog.OperatingTime,
|
||
|
data, 13)}, None)
|
||
|
|
||
|
|
||
|
@statistics.route('/export')
|
||
|
class StatisticsExport(Resource):
|
||
|
@staticmethod
|
||
|
def get():
|
||
|
data = request.args
|
||
|
timestamp = datetime.now().timestamp()
|
||
|
reagentLogFilter = export_diff(data)
|
||
|
ReagentName, ReagentSpecification, ReagentNumber, \
|
||
|
Unit, OperateMinNumber, UnitPrice, SmallestUnit, ReagentPosition, \
|
||
|
ProductionBatch, Maker, Expiration, Code, OperatingTime, \
|
||
|
OperatingPeople, SupplierName, Remark = [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []
|
||
|
for item in reagentLogFilter:
|
||
|
ReagentName.append(item.ReagentName)
|
||
|
ReagentSpecification.append(item.ReagentSpecification)
|
||
|
ReagentNumber.append(item.ReagentNumber)
|
||
|
Unit.append(item.Unit)
|
||
|
UnitPrice.append(item.UnitPrice)
|
||
|
Maker.append(item.Maker)
|
||
|
OperateMinNumber.append(item.OperateMinNumber)
|
||
|
SmallestUnit.append(item.SmallestUnit)
|
||
|
ReagentPosition.append(item.ReagentPosition)
|
||
|
ProductionBatch.append(item.ProductionBatch)
|
||
|
Expiration.append(item.Expiration)
|
||
|
Code.append(item.Code)
|
||
|
OperatingTime.append(item.OperatingTime)
|
||
|
OperatingPeople.append(item.OperatingPeople)
|
||
|
SupplierName.append(item.SupplierName)
|
||
|
Remark.append(item.Remark)
|
||
|
dit = {'耗材名称': ReagentName, '规格': ReagentSpecification, '数量(大单位)': ReagentNumber, '大单位': Unit,
|
||
|
'数量(小单位)': OperateMinNumber, '小单位': SmallestUnit, '供应商': SupplierName, '单价': UnitPrice,
|
||
|
'生产厂家': Maker, '产品批号': ProductionBatch, '效期': Expiration, '操作时间': OperatingTime,
|
||
|
'入库批号': Code, '操作员': OperatingPeople}
|
||
|
writer = pd.ExcelWriter('./file/' + data.get('title') + str(timestamp).replace('.', '-') + '.xlsx')
|
||
|
df = pd.DataFrame(dit)
|
||
|
# columns参数用于指定生成的excel中列的顺序
|
||
|
df.to_excel(writer, columns=['耗材名称', '规格', '数量(大单位)', '大单位', '数量(小单位)', '小单位',
|
||
|
'供应商', '单价', '生产厂家', '产品批号', '效期', '操作时间',
|
||
|
'入库批号', '操作员'], index=False, encoding='utf-8',
|
||
|
sheet_name=data.get('title'))
|
||
|
writer.save()
|
||
|
return SuccessResponse(ResultCode.SUCCESS, data.get('title') + str(timestamp).replace('.', '-'), None)
|
||
|
|
||
|
|
||
|
@statistics.route('/complete')
|
||
|
class StatisticsComplete(Resource):
|
||
|
@staticmethod
|
||
|
def get():
|
||
|
data = request.args
|
||
|
start_date = data.get('startDate') if data.get('startDate') is not None else (datetime.now() -
|
||
|
timedelta(days=10))
|
||
|
end_data = data.get('endDate') if data.get('endDate') is not None else datetime.now()
|
||
|
timestamp = datetime.now().timestamp()
|
||
|
wb = Workbook()
|
||
|
ws = wb.active
|
||
|
ws.title = '试剂与耗材统计汇总表'
|
||
|
alignment = Alignment(horizontal='center', vertical='center')
|
||
|
|
||
|
border = Border(left=Side(border_style='thin', color='000000'),
|
||
|
right=Side(border_style='thin', color='000000'),
|
||
|
top=Side(border_style='thin', color='000000'),
|
||
|
bottom=Side(border_style='thin', color='000000'))
|
||
|
|
||
|
title_area = ws['A1:AH1']
|
||
|
ws.merge_cells('A1:AH1')
|
||
|
title_area[0][0].alignment = alignment
|
||
|
title_area[0][0].value = '按试剂名称分类出入数汇总表'
|
||
|
title_area[0][0].font = Font(name='黑体', bold=True, size=16)
|
||
|
|
||
|
alignment_merge(ws, 'A2:AH2', '统计日期:' + str(start_date) + '至' + str(end_data),
|
||
|
isAlignment=False)
|
||
|
alignment_merge(ws, 'A3:A4', '耗材名称')
|
||
|
alignment_merge(ws, 'B3:B4', '规格')
|
||
|
alignment_merge(ws, 'C3:C4', '生产厂家')
|
||
|
alignment_merge(ws, 'D3:D4', '批准文号')
|
||
|
alignment_merge(ws, 'E3:E4', '生产批号')
|
||
|
alignment_merge(ws, 'F3:F4', '耗材类型')
|
||
|
alignment_merge(ws, 'G3:G4', '进货价')
|
||
|
alignment_merge(ws, 'H3:H4', '销售价')
|
||
|
alignment_merge(ws, 'I3:I4', '有效期')
|
||
|
alignment_merge(ws, 'J3:N3', '上期结存')
|
||
|
alignment_merge(ws, 'O3:S3', '本期进向汇总')
|
||
|
alignment_merge(ws, 'T3:X3', '本期出向汇总')
|
||
|
alignment_merge(ws, 'Y3:AC3', '本期调整数合计(报损、报废合计)')
|
||
|
alignment_merge(ws, 'AD3:AH3', '本期余额')
|
||
|
ws['J4'] = '数量'
|
||
|
ws['K4'] = '大单位'
|
||
|
ws['L4'] = '数量'
|
||
|
ws['M4'] = '小单位'
|
||
|
ws['N4'] = '数量描述'
|
||
|
ws['O4'] = '数量'
|
||
|
ws['P4'] = '大单位'
|
||
|
ws['Q4'] = '数量'
|
||
|
ws['R4'] = '小单位'
|
||
|
ws['S4'] = '数量描述'
|
||
|
ws['T4'] = '数量'
|
||
|
ws['U4'] = '大单位'
|
||
|
ws['V4'] = '数量'
|
||
|
ws['W4'] = '小单位'
|
||
|
ws['X4'] = '数量描述'
|
||
|
ws['Y4'] = '数量'
|
||
|
ws['Z4'] = '大单位'
|
||
|
ws['AA4'] = '数量'
|
||
|
ws['AB4'] = '小单位'
|
||
|
ws['AC4'] = '数量描述'
|
||
|
ws['AD4'] = '数量'
|
||
|
ws['AE4'] = '大单位'
|
||
|
ws['AF4'] = '数量'
|
||
|
ws['AG4'] = '小单位'
|
||
|
ws['AH4'] = '数量描述'
|
||
|
title_area = ws['A1:AH4']
|
||
|
for row in title_area:
|
||
|
for cell in row:
|
||
|
cell.border = border
|
||
|
|
||
|
filterObject = getDiffStockList()
|
||
|
reagent_stock = filterObject.filter(ReagtStock.Using).order_by(ReagtStock.PinYinCode).all()
|
||
|
reagent_id_list = []
|
||
|
index = 0
|
||
|
for reagent in reagent_stock:
|
||
|
if reagent.ReagentId in reagent_id_list:
|
||
|
continue
|
||
|
reagent_log_before = ReagtLog.query.filter_by(ReagentId=reagent.ReagentId) \
|
||
|
.filter(ReagtLog.OperatingTime < start_date) \
|
||
|
.order_by(ReagtLog.OperatingTime.desc()).all()
|
||
|
excel_cell = [reagent.Name, reagent.Specification, reagent.Maker, reagent.CertificationCode,
|
||
|
reagent.ProductionBatch,
|
||
|
reagent.TypeName, str(reagent.UnitPrice), str(reagent.SellingPrice), str(reagent.Expiration)]
|
||
|
get_complete_number(reagent_log_before, reagent, excel_cell)
|
||
|
reagent_log_current_in_stock = (ReagtLog.query.filter_by(ReagentId=reagent.ReagentId,
|
||
|
OperatingType=GetOperatingTypeInStock())
|
||
|
.filter(ReagtLog.OperatingTime > start_date)
|
||
|
.order_by(ReagtLog.OperatingTime).all())
|
||
|
get_complete_number(reagent_log_current_in_stock, reagent, excel_cell)
|
||
|
get_complete_current_type_number(start_date, reagent, excel_cell, GetOperatingTypeOutStock())
|
||
|
get_complete_current_type_number(start_date, reagent, excel_cell, GetOperatingTypeBad(),
|
||
|
GetOperatingTypeScrap())
|
||
|
|
||
|
excel_cell.append(str(reagent.LastNumber))
|
||
|
excel_cell.append(reagent.Unit)
|
||
|
excel_cell.append(str(reagent.MinNumberUnit))
|
||
|
excel_cell.append(reagent.SmallestUnit)
|
||
|
excel_cell.append(str(reagent.LastNumber) + reagent.Unit + str(reagent.MinNumberUnit) +
|
||
|
reagent.SmallestUnit)
|
||
|
ws._current_row = 4 + index
|
||
|
ws.append(excel_cell)
|
||
|
reagent_id_list.append(reagent.ReagentId)
|
||
|
index += 1
|
||
|
for row in ws.rows:
|
||
|
for cell in row:
|
||
|
cell.border = border
|
||
|
|
||
|
wb.save('./file/' + '按试剂名称分类出入数汇总表' + str(timestamp).replace('.', '-') + '.xlsx')
|
||
|
return SuccessResponse(ResultCode.SUCCESS, '按试剂名称分类出入数汇总表' + str(timestamp).replace('.', '-'),
|
||
|
None)
|