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)