# coding=utf-8 import traceback import json from django.db import models,connection from libs.utils import strftime, strfdate from django.conf import settings from django.utils import timezone from apps.base import Formater from django.db.models import Q, Sum, F from django.views.decorators.csrf import csrf_exempt from django.db import transaction,IntegrityError from django.db.models import ProtectedError from apps.account.decorators import token_required, permission_required, isHasPermissions from apps.foundation.models import BizLog, Option from apps.goods.filters import GoodsFilter, GoodsGodownEntryFilter, GoodsProductFilter from apps.goods.models import Goods, GoodsGodownEntry, GoodsGodownEntryDetail from apps.goods.resources import GoodsResource, GoodsImporter, GoodsGodownEntryResource, GoodsGodownEntryDetailResource, \ GoodsGodownEntryImporter, GoodsProductResource, GodownEntryQueryResource from apps.goods.serializers import GoodsSerializer, GoodsGodownEntrySerializer, GoodsGodownEntryDetailSerializer, GoodsProductSerializer from apps.product.models import ProductBase from apps.product.serializers import ProductBaseSerializer from apps.warehouse.biz import BizWarehouse, GetWarehouseSrockRecord from apps.warehouse.models import WarehouseStock, Warehouse, WarehouseRecord, WarehouseStockRecord, InventoryDetail, WarehouseRecordDetail from apps.order.models import GoodsDeliver, GoodsDeliverReturnDetail, GoodsDeliverDetail, GoodsDeliverReturn from libs.http import JSONResponse, JSONError, DataGridJSONResponse from libs import utils from apps.exceptions import CustomError, ExportChange @permission_required('goods.view_goods') def goods_list(request): f = GoodsFilter(request.GET, queryset=Goods.objects.filter()) rows, total = utils.get_page_data(request, f.qs) serializer = GoodsSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total) @permission_required('goods.export_goods') def goods_export(request): f = GoodsFilter(request.GET, queryset=Goods.objects.filter()) serializer = GoodsSerializer(f.qs, many=True) export_data = ExportChange.dict_to_obj(serializer) export_data = GoodsResource().export(export_data) filename = utils.attachment_save(export_data) return JSONResponse({'filename': filename}) @csrf_exempt @permission_required('goods.add_goods') def goods_save(request): id = request.GET.get('id') data = json.loads(request.body) try: with transaction.atomic(): product_base_id = None data['type'] = ProductBase.GOODS serializer = GoodsSerializer.factory(request.user, data, id) if serializer.instance: product_base_id = serializer.instance.product_base_id data['standard'] = data['base_standard'] pb = ProductBaseSerializer.factory(request.user,data,product_base_id) pb = pb.validSave() data['product_base'] = pb.id serializer.validSave() except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'保存失败!') return JSONResponse() @permission_required('goods.delete_goods') def goods_delete(request): id = int(request.GET.get('id')) try: with transaction.atomic(): goods = Goods.getById(id) product_base_id = goods.product_base.id BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除成品[%s],id=%d" % (goods.product_base.name, goods.id)) goods.delete() WarehouseStock.removeStockByProduct(goods.product_base) ProductBase.objects.filter(id=product_base_id).delete() except CustomError, e: return JSONError(e.get_error_msg()) except ProtectedError: return JSONError(u'该成品已被使用,禁止删除!') except IntegrityError: return JSONError(u'该成品已被使用,禁止删除!') except Exception, e: traceback.print_exc() return JSONError(u'删除失败!') return JSONResponse({}) @csrf_exempt @permission_required('goods.import_goods') def goods_import(request): file = request.FILES.get('excel_file') try: line = 2 importer = GoodsImporter() excel_rows = importer.getExcelData(file) with transaction.atomic(): for excel_row in excel_rows: try: row = importer.validRow(excel_row) option = Option.getByName(row[u'类别'], Option.GOODS_MODE) data = { 'name': row[u'名称'], 'model': row[u'代码'], 'option_type': option.id, 'standard': row[u'标准'], 'goods_pack': row[u'包装'], 'warehouse_place': row[u'库位'], 'retail_price': row[u'销售价'], 'notes': row[u'备注'], 'enabled': 1, } data['type'] = ProductBase.GOODS pb = ProductBaseSerializer.factory(request.user,data) pb = pb.validSave() data['product_base'] = pb.id serializer = GoodsSerializer.factory(request.user,data) serializer.validSave() except CustomError,e: raise CustomError(u'第%d行:%s' % (line,e.get_error_msg())) except Exception,e: raise CustomError(u'第%d行:%s' %(line,unicode(e))) line += 1 BizLog.objects.addnew(request.user, BizLog.IMPORT, u"导入成品数据[%s]条" % (line - 2)) except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'导入失败!') return JSONResponse() @csrf_exempt @token_required def goods_select(request): param = request.GET.get('param') warehouse_id = request.GET.get('warehouse') rows = Goods.objects.filter(product_base__enabled=True) if param: rows = rows.filter( Q(product_base__name__icontains=param) | Q(product_base__model__icontains=param) ) rows, total = utils.get_page_data(request, rows) data = [] for row in rows: record_data = [] if warehouse_id: record_data = GetWarehouseSrockRecord.getRecord(row.product_base.id, warehouse_id) item = { 'id': row.id, 'product_id': row.product_base.id, 'name': row.product_base.name, 'model': row.product_base.model, 'unit': row.product_base.unit, 'base_standard': row.product_base.standard, 'type_text': row.product_base.get_type_display(), 'option_type': row.product_base.option_type.name, 'retail_price': Formater.formatPriceShow(row.retail_price), 'standard': row.standard, 'goods_pack': row.goods_pack, # 'entry_price': entry_price, # 'total_cost': total_cost, 'record_data': record_data } data.append(item) return DataGridJSONResponse(data, total) @permission_required('goods.view_goods_godown_entry') def godownentry_list(request): product_notes = request.GET.get('product_notes') warehouses_ids = Warehouse.getManagerWarehouses(request.user) department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() rows = GoodsGodownEntry.objects.filter(warehouse_id__in=warehouses_ids) rows = rows.filter( Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)) if product_notes: g_ids = rows.values_list('id') d_ids = GoodsGodownEntryDetail.objects.filter(main_id__in=g_ids, notes__icontains=product_notes).values_list('main_id') rows = rows.filter(id__in=d_ids) f = GoodsGodownEntryFilter(request.GET, queryset=rows) total_row = f.qs.aggregate(total_count=Sum('total_count'), total_amount=Sum('total_amount')) more = { 'total_count': Formater.formatCountShow(total_row['total_count']), 'total_amount': Formater.formatAmountShow(total_row['total_amount']) } rows, total = utils.get_page_data(request, f.qs) serializer = GoodsGodownEntrySerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total, more) @csrf_exempt @permission_required('goods.add_goods_godown_entry') def godownentry_save(request): id = request.GET.get('id') main_data = json.loads(request.POST.get('main')) items_data = json.loads(request.POST.get('item')) try: with transaction.atomic(): serializer = GoodsGodownEntrySerializer.factory(request.user, main_data, id) if serializer.instance and serializer.instance.status == settings.PASS: raise CustomError(u'该成品入库单已审核,禁止修改!') serializer = serializer.validSave() GoodsGodownEntryDetail.objects.filter(main=serializer).delete() for item in items_data: item['main'] = serializer.id detail_serializer = GoodsGodownEntryDetailSerializer.factory(request.user, data=item) detail_serializer.validSave() serializer.update_total() except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'保存失败!') return JSONResponse() @token_required def godownentry_detail(request): id = request.GET.get('id') instance = GoodsGodownEntry.getById(id) company = instance.department.getCompany() if instance.status == settings.PASS: status_text = u'已审核' else: status_text = u'待审核' main_data = { 'id': instance.id, 'warehouse_id': instance.warehouse_id, 'warehouse_name': instance.warehouse.name, 'create_user': instance.create_user.name, 'create_time': Formater.formatStrTime(instance.create_time), 'total_count': Formater.formatCountShow(instance.total_count), 'total_amount': Formater.formatAmountShow(instance.total_amount), 'total_invoice_amount': Formater.formatAmountShow(instance.total_invoice_amount), 'status_text': status_text, 'check_user_text': instance.check_user and instance.check_user.name or ' ', 'check_time': Formater.formatStrTime(instance.create_time), 'notes': instance.notes, 'company': company.name, 'no': instance.no } data = { 'main_data': main_data, 'items_data': [] } detail_rows = GoodsGodownEntryDetail.objects.filter(main=instance) for detail_row in detail_rows: item_data = { 'id': detail_row.id, 'goods_id': detail_row.goods_id, 'goods_name': detail_row.goods.product_base.name, 'goods_model': detail_row.goods.product_base.model, 'price': Formater.formatPriceShow(detail_row.price), 'count': Formater.formatCountShow(detail_row.count), 'amount': Formater.formatAmountShow(detail_row.amount), 'invoice_amount': Formater.formatAmountShow(detail_row.invoice_amount), 'unit': detail_row.goods.product_base.unit or '', 'warehouse_place': detail_row.goods.product_base.warehouse_place or '', 'notes': detail_row.notes or '' } data['items_data'].append(item_data) return JSONResponse(data) @permission_required('goods.delete_goods_godown_entry') def godownentry_delete(request): id = request.GET.get('id') try: with transaction.atomic(): instance = GoodsGodownEntry.getById(id) if instance.status == settings.PASS: raise CustomError(u'该成品入库单已审核,禁止删除!') BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除成品入库单[%s],id=%d" % (instance.no, instance.id)) GoodsGodownEntryDetail.objects.filter(main=instance).delete() instance.delete() except CustomError, e: return JSONError(e.get_error_msg()) except ProtectedError: return JSONError(u'该成品入库单已被引用,禁止删除!') except IntegrityError: return JSONError(u'该成品入库单已被引用,禁止删除!') except Exception, e: traceback.print_exc() return JSONError(u'删除失败!') return JSONResponse({}) @permission_required('goods.export_goods_godown_entry') def godownentry_export(request): try: warehouses_ids = Warehouse.getManagerWarehouses(request.user) department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() rows = GoodsGodownEntry.objects.filter(warehouse_id__in=warehouses_ids) rows = rows.filter( Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user)) f = GoodsGodownEntryFilter(request.GET, queryset=rows) serializer = GoodsGodownEntrySerializer(f.qs, many=True) export_data = ExportChange.dict_to_obj(serializer) is_show_cost = isHasPermissions(request.user, 'goods.view_goods_cost') export_data = GoodsGodownEntryResource(is_show_cost).export(export_data) filename = utils.attachment_save(export_data) BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出成品入库单" ) except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'导出列表失败!') return JSONResponse({'filename': filename}) @permission_required('goods.export_goods_godown_entry') def godownentry_export_detail(request): id = request.GET.get('id') try: instance = GoodsGodownEntry.getById(id) godown_entry_detail = GoodsGodownEntryDetail.objects.filter(main=instance) serializer = GoodsGodownEntryDetailSerializer(godown_entry_detail, many=True) export_data = ExportChange.dict_to_obj(serializer) is_show_cost = isHasPermissions(request.user, 'goods.view_goods_cost') export_data = GoodsGodownEntryDetailResource(is_show_cost).export(export_data) filename = utils.attachment_save(export_data) BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出成品入库单[%s]明细,id=%d" % (instance.no, instance.id)) except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'导出明细失败!') return JSONResponse({'filename': filename}) @csrf_exempt @permission_required('goods.import_goods_godown_entry') def godownentry_import(request): file = request.FILES.get('excel_file') main_data = json.loads(request.POST.get('main_data')) try: line = 2 importer = GoodsGodownEntryImporter() excel_rows = importer.getExcelData(file) with transaction.atomic(): serializer = GoodsGodownEntrySerializer.factory(request.user, main_data) serializer = serializer.validSave() for excel_row in excel_rows: try: row = importer.validRow(excel_row) model = row[u'成品代码'] goods = Goods.objects.filter(product_base__model=model, product_base__type=ProductBase.GOODS) if goods.count() == 0: raise CustomError(u'成品代码不存在') elif goods.count() > 1: raise CustomError(u'成品代码重复,前往基础数据设置修改') else: goods = goods.first() items_data = {} items_data['goods'] = goods.id items_data['main'] = serializer.id items_data['price'] = row[u'单价'] items_data['count'] = row[u'数量'] items_data['invoice_amount'] = row[u'发票金额'] items_data['notes'] = row[u'备注'] detail_serializer = GoodsGodownEntryDetailSerializer.factory(request.user, items_data) detail_serializer.validSave() except CustomError, e: raise CustomError(u'第%d行:%s' % (line, e.get_error_msg())) except Exception, e: raise CustomError(u'第%d行:%s' % (line, unicode(e))) line += 1 serializer.update_total() BizLog.objects.addnew(request.user, BizLog.IMPORT, u"导入成品入库单[%s],id=%d" % (serializer.no, serializer.id)) except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'导入失败!') return JSONResponse() @permission_required('goods.check_goods_godown_entry') def godownentry_check(request): id = request.GET.get('id') try: with transaction.atomic(): instance = GoodsGodownEntry.getById(id) if instance.status == settings.PASS: raise CustomError(u'该成品入库单已审核') godownentry_details = GoodsGodownEntryDetail.objects.filter(main=instance) for godownentry_detail in godownentry_details: stock_record = BizWarehouse.entry(type=WarehouseRecord.RK_ZJ, product=godownentry_detail.goods.product_base, warehouse=instance.warehouse, supplier=None, entry_count=godownentry_detail.count, entry_price=godownentry_detail.price, entry_price2=godownentry_detail.price) godownentry_detail.stock_record = stock_record godownentry_detail.save() instance.status = settings.PASS instance.check_user = request.user instance.check_time = timezone.now() BizLog.objects.addnew( request.user, BizLog.CHECK, u"审核原料入库[%s],id=%d" % (instance.no, instance.id), ) instance.save() except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'审核失败') return JSONResponse({}) @csrf_exempt @permission_required('goods.edit_goods_godown_entry') def godownentry_senior_edit(request): def updateStock(product_base, warehouse): sum_row = WarehouseRecord.objects.filter( warehouse=warehouse, product=product_base ).aggregate( count=Sum('count'), amount=Sum('amount'), amount2=Sum('amount2') ) warehouse_stock = WarehouseStock.objects.filter(product=product_base, warehouse=warehouse).first() if warehouse_stock: warehouse_stock.count = sum_row['count'] or 0 warehouse_stock.amount = sum_row['amount'] or 0 warehouse_stock.amount2 = sum_row['amount2'] or 0 if warehouse_stock.count != 0: warehouse_stock.avg_cost_price = warehouse_stock.amount / warehouse_stock.count warehouse_stock.avg_cost_price2 = warehouse_stock.amount2 / warehouse_stock.count warehouse_stock.save() sum_row = WarehouseStock.objects.filter( product=product_base ).aggregate( count=Sum('count'), amount=Sum('amount'), amount2=Sum('amount2') ) product_base.stock_count = sum_row['count'] or 0 product_base.stock_amount = sum_row['amount'] or 0 product_base.stock_amount2 = sum_row['amount2'] or 0 if product_base.stock_count > 0: product_base.avg_cost_price = product_base.stock_amount / product_base.stock_count product_base.avg_cost_price2 = product_base.stock_amount2 / product_base.stock_count product_base.save() def updateWarehouseRecord(warehouse_record): sum_row = WarehouseRecordDetail.objects.filter( warehouse_record=warehouse_record ).aggregate( sum_amount=Sum(F('count') * F('warehouse_stock_record__entry_price')), sum_amount2=Sum(F('count') * F('warehouse_stock_record__entry_price2')), sum_count=Sum('count') ) warehouse_record.amount = sum_row['sum_amount'] or 0 warehouse_record.amount2 = sum_row['sum_amount2'] or 0 warehouse_record.count = sum_row['sum_count'] or 0 warehouse_record.save() def changeEntryPrice(entry_detail,entry_price,entry_price2): changeEntryPriceBase(entry_detail, entry_price, entry_price2) rows = WarehouseRecordDetail.objects.filter(warehouse_stock_record=entry_detail.stock_record) ck_type = (WarehouseRecord.CK_ZJ, WarehouseRecord.CK_XS,) pk_type = (WarehouseRecord.CK_PK,) tl_type = (WarehouseRecord.TL,) for row in rows: warehouse_record = row.warehouse_record updateWarehouseRecord(warehouse_record) if warehouse_record.type in ck_type: deliver_detail = GoodsDeliverDetail.objects.filter(warehouse_record=warehouse_record).first() if deliver_detail: #更新出库明细的合计成本 deliver_detail.total_cost = warehouse_record.amount deliver_detail.save() # 更新出库单的合计成本 order = deliver_detail.main sum_row = GoodsDeliverDetail.objects.filter( main=order ).aggregate( sum_cost=Sum('total_cost') ) order.total_cost = sum_row['sum_cost'] or 0 order.save() elif warehouse_record.type in tl_type: detail = GoodsDeliverReturnDetail.objects.filter(warehouse_record=warehouse_record).first() if detail: #更新退料明细的合计成本 old_amount = detail.return_cost detail.return_cost = warehouse_record.amount detail.save() # 更新出库明细的退料合计成本 new_amount = detail.return_cost detail.deliver_detail.return_cost += new_amount - old_amount detail.deliver_detail.save() #更新出库单的退料合计成本 detail.deliver_detail.main.return_cost += new_amount - old_amount detail.deliver_detail.main.save() #更新退料单的合计成本 order = detail.main sum_row = GoodsDeliverReturnDetail.objects.filter( main=order ).aggregate( sum_cost=Sum('return_cost') ) order.return_cost = sum_row['sum_cost'] or 0 order.save() elif warehouse_record.type in pk_type: detail = InventoryDetail.objects.filter(warehouse_record=warehouse_record).first() if detail: #更新盘存明细 detail.amount = warehouse_record.amount detail.price = 0 if detail.count: detail.price = detail.amount / detail.count detail.save() # 更新盘存单 order = detail.main sum_row = InventoryDetail.objects.filter( main=order ).aggregate( sum_amount=Sum('amount') ) order.total_amount = sum_row['sum_amount'] or 0 order.save() def changeEntryPriceBase(entry_detail,entry_price,entry_price2): entry_detail.price = entry_price entry_detail.amount = entry_detail.count * entry_price entry_detail.save() if entry_detail.stock_record: entry_detail.stock_record.entry_price = entry_price entry_detail.stock_record.entry_price2 = entry_price2 entry_detail.stock_record.save() def changePrice(godownentry_detail,new_entry_price): changeEntryPrice(godownentry_detail, new_entry_price, new_entry_price) updateStock(godownentry_detail.goods.product_base, godownentry_detail.main.warehouse) def addCount(godownentry_detail,add_count): godownentry_detail.count += add_count godownentry_detail.amount = godownentry_detail.count * godownentry_detail.price godownentry_detail.save() if godownentry_detail.stock_record: godownentry_detail.stock_record.entry_count += add_count godownentry_detail.stock_record.surplus_count += add_count godownentry_detail.stock_record.save() record_detail = WarehouseRecordDetail.objects.filter( warehouse_stock_record=godownentry_detail.stock_record, warehouse_record__type__in=(WarehouseRecord.RK_CG, WarehouseRecord.RK_ZJ) ).first() if record_detail: record_detail.count += add_count record_detail.save() updateWarehouseRecord(record_detail.warehouse_record) updateStock(godownentry_detail.goods.product_base, godownentry_detail.main.warehouse) def decCount(godownentry_detail,red_count): godownentry_detail.count -= red_count godownentry_detail.amount = godownentry_detail.count * godownentry_detail.price godownentry_detail.save() if godownentry_detail.stock_record: if red_count > godownentry_detail.stock_record.surplus_count: raise CustomError(u'该入库单中的配件[%s],剩余%s,不能减少%s,请使用退货减少库存' % ( godownentry_detail.goods.product_base.name, Formater.formatCountShow(godownentry_detail.stock_record.surplus_count), Formater.formatCountShow(red_count) )) godownentry_detail.stock_record.entry_count -= red_count godownentry_detail.stock_record.surplus_count -= red_count godownentry_detail.stock_record.save() record_detail = WarehouseRecordDetail.objects.filter( warehouse_stock_record=godownentry_detail.stock_record, warehouse_record__type__in=(WarehouseRecord.RK_CG, WarehouseRecord.RK_ZJ) ).first() if record_detail: record_detail.count -= red_count record_detail.save() updateWarehouseRecord(record_detail.warehouse_record) updateStock(godownentry_detail.goods.product_base, godownentry_detail.main.warehouse) new_rows = json.loads(request.POST.get('item')) id = request.GET.get('id') try: with transaction.atomic(): godownentry = GoodsGodownEntry.objects.filter(pk=int(id)).first() if not godownentry: raise CustomError(u'未找到相应的入库单') if godownentry.status != settings.PASS: raise CustomError(u'未通过审核的入库单不允许高级修改') for row in new_rows: new_entry_count = Formater.formatCount(row['new_count']) new_entry_price = Formater.formatPrice(row['new_price']) if new_entry_count < 0: raise CustomError(u'入库数量不能小于0') if new_entry_price < 0: raise CustomError(u'入库价不能小于0') detail = GoodsGodownEntryDetail.objects.filter(id=int(row['new_detail_id'])).first() if not detail: continue if detail.price != new_entry_price: changePrice(detail,new_entry_price) if detail.count < new_entry_count: addCount(detail,new_entry_count-detail.count) if detail.count > new_entry_count: decCount(detail, detail.count-new_entry_count) WarehouseRecord.updateCurStockByProduct(detail.main.warehouse_id, detail.goods.product_base_id) count = 0 amount = 0 sum_row = GoodsGodownEntryDetail.objects.filter(main=godownentry).aggregate( count_sum=Sum('count'), amount_sum=Sum('amount') ) if sum_row: count = sum_row['count_sum'] or 0 amount = sum_row['amount_sum'] or 0 godownentry.total_count = count godownentry.total_amount = amount godownentry.save() BizLog.objects.addnew( request.user, BizLog.UPDATE, u"原料高级修改[单号=%s],id=%d" % (godownentry.no, godownentry.id) ) except CustomError, e: return JSONError(e.get_error_msg()) except Exception, e: traceback.print_exc() return JSONError(u'修改失败') return JSONResponse({}) @csrf_exempt @permission_required('warehouse.view_goods_stock_log') def goods_stock_log(request): keyword = request.GET.get('keyword') action = request.GET.get('action') happen_time = request.GET.get('happen_time') warehouse_id = request.GET.get('warehouse_id') product_id = request.GET.get('product_id') page, page_size = utils.get_page_info(request) product_id = int(product_id) warehouse_id = int(warehouse_id) where = '' if happen_time: happen_time = happen_time.split(' - ') where += " AND m.happen_time >= '%s' " % happen_time[0] where += " AND m.happen_time <= '%s' " % (happen_time[1] + ' 23:59:59') if action: where += ' AND m.type = %d' % int(action) if keyword and len(keyword) > 0: where += " AND (m.order_no like '%" + keyword + "%' " \ " or m.warehouse_name like '%" + keyword + "%' )" page_sql = ' LIMIT %d OFFSET %d ' % (page_size, page * page_size) sql = """SELECT * FROM( SELECT pwr.type, pwr.happen_time, (CASE WHEN pwr.type in (3, 4) THEN gd.`no` WHEN pwr.type = 5 THEN iv.`no` WHEN pwr.type = 7 THEN gdr.`no` else '' END) AS order_no, (CASE WHEN pwr.type in (3, 4) THEN gdd.price WHEN pwr.type = 5 THEN ind.price WHEN pwr.type = 7 THEN rdgd.price else '' END) AS order_price, pwr.count, pwr.amount, pwr.amount/pwr.count as cost, pw.name as warehouse_name, pwr.warehouse_id AS warehouse_id, pwr.product_id AS product_id, pwr.id AS id, pwr.cur_count as cur_count, pwr.cur_amount as cur_amount FROM product_warehouse_record pwr LEFT JOIN product_warehouse pw ON pwr.warehouse_id = pw.id LEFT JOIN product_warehouse_stock pws ON pwr.product_id = pws.product_id AND pwr.warehouse_id=pws.warehouse_id LEFT JOIN goods_deliver_detail gdd ON pwr.id=gdd.warehouse_record_id LEFT JOIN goods_deliver gd ON gdd.main_id=gd.id LEFT JOIN goods_deliver_detail_return gdrd ON pwr.id = gdrd.warehouse_record_id LEFT JOIN goods_deliver_detail rdgd ON rdgd.id = gdrd.deliver_detail_id LEFT JOIN goods_deliver_return gdr ON gdrd.main_id = gdr.id LEFT JOIN inventory_detail ind on ind.warehouse_record_id=pwr.id left join inventory iv ON iv.id=ind.main_id WHERE pwr.warehouse_id = %(warehose)d AND pwr.product_id = %(product)d AND pwr.type >=3 UNION ALL SELECT pwr.type, pwr.happen_time, (CASE WHEN pwr.type in (0, 1) THEN gge.`no` WHEN pwr.type = 2 THEN iv.`no` else '' END) AS order_no, (CASE WHEN pwr.type in (0, 1) THEN gded.price WHEN pwr.type = 2 THEN ind.price else '' END) AS order_price, pwr.count, pwr.amount, pwr.amount/pwr.count as cost, pw.name as warehouse_name, pwr.warehouse_id AS warehouse_id, pwr.product_id AS product_id, pwr.id AS id, pwr.cur_count as cur_count, pwr.cur_amount as cur_amount FROM product_warehouse_record pwr LEFT JOIN product_warehouse pw ON pwr.warehouse_id = pw.id LEFT JOIN product_warehouse_stock pws ON pwr.product_id = pws.product_id AND pwr.warehouse_id=pws.warehouse_id LEFT JOIN product_warehouse_record_detail pwrd ON pwr.id=pwrd.warehouse_record_id LEFT JOIN goods_godown_entry_detail gded ON pwrd.warehouse_stock_record_id=gded.stock_record_id LEFT JOIN goods_godown_entry gge ON gded.main_id=gge.id LEFT JOIN inventory_detail ind on ind.warehouse_stock_record_id = pwrd.warehouse_stock_record_id left join inventory iv ON iv.id = ind.main_id WHERE pwr.warehouse_id = %(warehose)d AND pwr.product_id = %(product)d AND (pwr.type <= 2) ) as m WHERE 1=1 %(where)s ORDER BY m.happen_time DESC """ % {'warehose': warehouse_id, 'product': product_id, 'where': where} sum_sql = """ SELECT COUNT(0) FROM (%s) AS t """ % sql items = [] sql = '%s %s' % (sql, page_sql) cursor = connection.cursor() cursor.execute(sql) row = cursor.fetchone() total = 0 while row: action_text = WarehouseRecord.TYPE_CHOICES[row[0]][1] text = '' if row[0] == WarehouseRecord.RK_ZJ: text = u'入库单[' + row[2] + u']' elif row[0] == WarehouseRecord.RK_CG: text = u'采购转入库,入库单[' + row[2] + u']' elif row[0] == WarehouseRecord.RK_PY: text = u'盘盈单[' + row[2] + u']' elif row[0] == WarehouseRecord.CK_ZJ: text = u'出库单[' + row[2] + ']' elif row[0] == WarehouseRecord.CK_XS: text = u'订单转出库,出库单[' + row[2] + u']' elif row[0] == WarehouseRecord.CK_PK: text = u'盘亏单[' + row[2] + u']' elif row[0] == WarehouseRecord.TH: text = u'退货单[' + row[2] + u']' elif row[0] == WarehouseRecord.TL: text = u'退料单[' + row[2] + u']' item = { 'action': row[0], 'action_text': action_text, 'create_time': strftime(row[1]), 'order_no': row[2], 'count': Formater.formatCountShow(row[4]), 'cost': Formater.formatPriceShow(row[6]), 'price': Formater.formatPriceShow(row[3]), 'warehouse_text': row[7], 'text': text, 'cur_count': Formater.formatCountShow(row[11]), 'cur_amount': Formater.formatAmountShow(row[12]), } items.append(item) row = cursor.fetchone() cursor.execute(sum_sql) row = cursor.fetchone() if row: total = row[0] return DataGridJSONResponse(items, total) @csrf_exempt @permission_required('product.view_goods_product') def goods_product_list(request): empty = request.GET.get('empty') rows = ProductBase.objects.filter(type=ProductBase.GOODS) if empty == '0': rows = rows.filter(stock_count=0) elif empty == '1': rows = rows.filter(stock_count__gt=0) f = GoodsProductFilter(request.GET, queryset=rows) total_row = f.qs.aggregate(sum_count=Sum('stock_count')) more = { 'sum_count': Formater.formatCountShow(total_row['sum_count']) } rows, total = utils.get_page_data(request, f.qs) serializer = GoodsProductSerializer(rows, many=True) return DataGridJSONResponse(serializer.data, total, more) @csrf_exempt @permission_required('product.export_goods_product') def goods_product_export(request): empty = request.GET.get('empty') rows = ProductBase.objects.filter(type=ProductBase.GOODS) if empty == '0': rows = rows.filter(stock_count=0) elif empty == '1': rows = rows.filter(stock_count__gt=0) f = GoodsProductFilter(request.GET, queryset=rows) serializer = GoodsProductSerializer(f.qs, many=True) export_data = ExportChange.dict_to_obj(serializer) export_data = GoodsProductResource().export(export_data) filename = utils.attachment_save(export_data) return JSONResponse({'filename': filename}) @token_required @permission_required('order.view_goods_godownentry_query') def godownentry_query_list(request): rows = get_filter_data(request) total_row = rows.aggregate(godownentry_total_count=Sum('goods_godown_entry_detail_ref_stock_record__count'), inventory_total_count=Sum('inventory_details_ref_warehouse_stock_record__count'), godownentry_total_amount=Sum('goods_godown_entry_detail_ref_stock_record__amount'), inventory_total_amount=Sum('inventory_details_ref_warehouse_stock_record__amount'), godownentry_total_deliver_count=Sum( 'goods_godown_entry_detail_ref_stock_record__deliver_count'), inventory_total_deliver_count=Sum( 'inventory_details_ref_warehouse_stock_record__deliver_count'), total_surplus_count=Sum('surplus_count') ) more = { 'total_count': Formater.formatCountShow( (total_row['godownentry_total_count'] or 0) + (total_row['inventory_total_count'] or 0)), 'total_amount': Formater.formatAmountShow( (total_row['godownentry_total_amount'] or 0) + (total_row['inventory_total_amount'] or 0)), 'total_deliver_count': Formater.formatCountShow( (total_row['godownentry_total_deliver_count'] or 0) + (total_row['inventory_total_deliver_count'] or 0)), 'total_surplus_count': Formater.formatCountShow(total_row['total_surplus_count'] or 0) } rows, total = utils.get_page_data(request, rows) data = get_godownentry_query_data(rows) return DataGridJSONResponse(data, total, more) @token_required @permission_required('order.export_goods_godownentry_query') def godownentry_query_export(request): try: rows = get_filter_data(request) data = get_godownentry_query_data(rows) export_data = ExportChange.dict_to_obj2(data) is_show_cost = isHasPermissions(request.user, 'goods.view_goods_cost') export_data = GodownEntryQueryResource(is_show_cost).export(export_data) filename = utils.attachment_save(export_data) BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出成品入库查询") except Exception, e: traceback.print_exc() return JSONError(u'导出成品入库查询失败!') return JSONResponse({'filename': filename}) @token_required def godownentry_query_detail(request): rows = get_filter_data(request) data = get_godownentry_query_data(rows) return JSONResponse(data) def get_filter_data(request): entry_time = request.GET.get('entry_time') no = request.GET.get('no') create_user = request.GET.get('create_user') product_text = request.GET.get('product_text') product_model = request.GET.get('product_model') warehouse = request.GET.get('warehouse') entry_type = request.GET.get('entry_type') notes = request.GET.get('notes') rows = WarehouseStockRecord.objects.filter( product__type=ProductBase.GOODS, warehouse_record_detail_ref_stock_record__warehouse_record__type__in=[0,1,2]).order_by( '-id' ) if entry_type: rows = rows.filter(warehouse_record_detail_ref_stock_record__warehouse_record__type=int(entry_type)) if notes: rows = rows.filter(Q(goods_godown_entry_detail_ref_stock_record__notes__icontains=notes) | Q(inventory_details_ref_warehouse_stock_record__notes__icontains=notes)) if product_text: rows = rows.filter(product__name__icontains=product_text) if product_model: rows = rows.filter(product__model__icontains=product_model) if warehouse: rows = rows.filter(warehouse__name__icontains=warehouse) if entry_time: entry_time_begin = entry_time.split(' - ')[0] entry_time_end = entry_time.split(' - ')[1] + ' 23:59:59' rows = rows.filter(entry_time__gt=entry_time_begin, entry_time__lt=entry_time_end) if no: rows = rows.filter(Q(goods_godown_entry_detail_ref_stock_record__main__no__icontains=no) | Q(inventory_details_ref_warehouse_stock_record__main__no__icontains=no)) if create_user: rows = rows.filter(Q(goods_godown_entry_detail_ref_stock_record__main__create_user__name__icontains=create_user) | Q(inventory_details_ref_warehouse_stock_record__main__create_user__name__icontains=create_user)) warehouses_ids = Warehouse.getManagerWarehouses(request.user) department_ids = request.user.getSubDepartmentIds() user_ids = request.user.getSubEmployeeIds() rows = rows.filter(warehouse_id__in=warehouses_ids) rows = rows.filter(Q( Q(goods_godown_entry_detail_ref_stock_record__main__department_id__in=department_ids) | Q(goods_godown_entry_detail_ref_stock_record__main__create_user_id__in=user_ids) | Q(goods_godown_entry_detail_ref_stock_record__main__create_user=request.user)) | Q( Q(inventory_details_ref_warehouse_stock_record__main__department_id__in=department_ids) | Q(inventory_details_ref_warehouse_stock_record__main__create_user_id__in=user_ids) | Q(inventory_details_ref_warehouse_stock_record__main__create_user=request.user) )) return rows def get_godownentry_query_data(rows): rows = rows.values( 'id', 'goods_godown_entry_detail_ref_stock_record__goods__product_base__name', 'goods_godown_entry_detail_ref_stock_record__goods__product_base__model', 'goods_godown_entry_detail_ref_stock_record__goods__product_base__unit', 'goods_godown_entry_detail_ref_stock_record__goods__product_base__type', 'goods_godown_entry_detail_ref_stock_record__goods__product_base__warehouse_place', 'inventory_details_ref_warehouse_stock_record__product__name', 'inventory_details_ref_warehouse_stock_record__product__model', 'inventory_details_ref_warehouse_stock_record__product__unit', 'inventory_details_ref_warehouse_stock_record__product__type', 'inventory_details_ref_warehouse_stock_record__product__warehouse_place', 'warehouse__name', 'warehouse_record_detail_ref_stock_record__warehouse_record__type', 'goods_godown_entry_detail_ref_stock_record__id', 'goods_godown_entry_detail_ref_stock_record__price', 'goods_godown_entry_detail_ref_stock_record__count', 'goods_godown_entry_detail_ref_stock_record__amount', 'goods_godown_entry_detail_ref_stock_record__deliver_count', 'goods_godown_entry_detail_ref_stock_record__notes', 'goods_godown_entry_detail_ref_stock_record__main__create_user__name', 'goods_godown_entry_detail_ref_stock_record__main__check_time', 'goods_godown_entry_detail_ref_stock_record__main__no', 'inventory_details_ref_warehouse_stock_record__price', 'inventory_details_ref_warehouse_stock_record__count', 'inventory_details_ref_warehouse_stock_record__amount', 'inventory_details_ref_warehouse_stock_record__notes', 'inventory_details_ref_warehouse_stock_record__deliver_count', 'inventory_details_ref_warehouse_stock_record__main__create_user__name', 'inventory_details_ref_warehouse_stock_record__main__check_time', 'inventory_details_ref_warehouse_stock_record__main__no', ) data = [] for row in rows: warehouse_record_type = WarehouseRecord.TYPE_CHOICES[row['warehouse_record_detail_ref_stock_record__warehouse_record__type']][1] if row['warehouse_record_detail_ref_stock_record__warehouse_record__type'] == WarehouseRecord.RK_PY: product_type_text = ProductBase.TYPE_CHOICES[row['inventory_details_ref_warehouse_stock_record__product__type']][1] surplus_count = row['inventory_details_ref_warehouse_stock_record__count'] - row['inventory_details_ref_warehouse_stock_record__deliver_count'] item = { 'id': row['id'], 'type': warehouse_record_type, 'product_type': product_type_text, 'product_name': row['inventory_details_ref_warehouse_stock_record__product__name'], 'product_model': row['inventory_details_ref_warehouse_stock_record__product__model'], 'product_unit': row['inventory_details_ref_warehouse_stock_record__product__unit'], 'warehouse_place': row['inventory_details_ref_warehouse_stock_record__product__warehouse_place'], 'warehouse': row['warehouse__name'], 'price': Formater.formatPriceShow(row['inventory_details_ref_warehouse_stock_record__price']), 'count': Formater.formatCountShow(row['inventory_details_ref_warehouse_stock_record__count']), 'amount': Formater.formatAmountShow(row['inventory_details_ref_warehouse_stock_record__amount']), 'deliver_count': Formater.formatCountShow(row['inventory_details_ref_warehouse_stock_record__deliver_count']), 'surplus_count': Formater.formatCountShow(surplus_count), 'create_user': row['inventory_details_ref_warehouse_stock_record__main__create_user__name'], 'check_time': Formater.formatStrTime(row['inventory_details_ref_warehouse_stock_record__main__check_time']), 'notes': row['inventory_details_ref_warehouse_stock_record__notes'], 'no': row['inventory_details_ref_warehouse_stock_record__main__no'], } else: product_type_text = ProductBase.TYPE_CHOICES[row['goods_godown_entry_detail_ref_stock_record__goods__product_base__type']][1] surplus_count = row['goods_godown_entry_detail_ref_stock_record__count'] - row['goods_godown_entry_detail_ref_stock_record__deliver_count'] item = { 'id': row['id'], 'godownentry_detail_id': row['goods_godown_entry_detail_ref_stock_record__id'], 'type': warehouse_record_type, 'product_type': product_type_text, 'product_name': row['goods_godown_entry_detail_ref_stock_record__goods__product_base__name'], 'product_model': row['goods_godown_entry_detail_ref_stock_record__goods__product_base__model'], 'product_unit': row['goods_godown_entry_detail_ref_stock_record__goods__product_base__unit'], 'warehouse_place': row['goods_godown_entry_detail_ref_stock_record__goods__product_base__warehouse_place'], 'warehouse': row['warehouse__name'], 'price': Formater.formatPriceShow(row['goods_godown_entry_detail_ref_stock_record__price']), 'count': Formater.formatCountShow(row['goods_godown_entry_detail_ref_stock_record__count']), 'amount': Formater.formatAmountShow(row['goods_godown_entry_detail_ref_stock_record__amount']), 'deliver_count': Formater.formatCountShow(row['goods_godown_entry_detail_ref_stock_record__deliver_count']), 'surplus_count': Formater.formatCountShow(surplus_count), 'create_user': row['goods_godown_entry_detail_ref_stock_record__main__create_user__name'], 'check_time': Formater.formatStrTime(row['goods_godown_entry_detail_ref_stock_record__main__check_time']), 'notes': row['goods_godown_entry_detail_ref_stock_record__notes'], 'no': row['goods_godown_entry_detail_ref_stock_record__main__no'], } data.append(item) return data