山东雷驰
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.
 
 
 
 

470 lines
20 KiB

using Kean.Application.Command.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Kean.Presentation.Rest.Controllers
{
/// <summary>
/// 库存服务
/// </summary>
[ApiController, Route("api/stocks")]
public class StocksController : ControllerBase
{
private readonly Application.Command.Interfaces.IStockService _stockCommandService; // 库存命令服务
private readonly Application.Query.Interfaces.IStockService _stockQueryService; // 库存查询服务
private readonly Application.Query.Interfaces.IWarehouseService _warehouseQueryService; // 库房查询服务
private readonly Application.Query.Interfaces.IIdentityService _identityQueryService; // 身份查询服务
/// <summary>
/// 依赖注入
/// </summary>
public StocksController(
Application.Command.Interfaces.IStockService stockCommandService,
Application.Query.Interfaces.IStockService stockQueryService,
Application.Query.Interfaces.IIdentityService identityQueryService,
Application.Query.Interfaces.IWarehouseService warehouseQueryService)
{
_stockCommandService = stockCommandService;
_stockQueryService = stockQueryService;
_identityQueryService = identityQueryService;
_warehouseQueryService = warehouseQueryService;
}
/// <summary>
/// 获取库存列表
/// </summary>
/// <response code="200">成功</response>
[HttpGet]
[ProducesResponseType(200)]
public async Task<IActionResult> GetList(
[FromQuery] int[] area,
[FromQuery] bool? pallet,
[FromQuery] bool? palletized,
[FromQuery] int[] category,
[FromQuery] string code,
[FromQuery] string name,
[FromQuery] string batch,
[FromQuery] string barcode,
[FromQuery] string cell,
[FromQuery] string qc,
[FromQuery] string qualityState,
[FromQuery] string materialAgeStatus,
[FromQuery] DateTime? inboundTimeFrom,
[FromQuery] DateTime? inboundTimeTo,
[FromQuery] DateTime? manufacturingDateFrom,
[FromQuery] DateTime? manufacturingDateTo,
[FromQuery] DateTime? inventoryTimeFrom,
[FromQuery] DateTime? inventoryTimeTo,
[FromQuery] bool? overdue,
[FromQuery] bool? enabled,
[FromQuery] bool? excludeTask,
[FromQuery] string sort,
[FromQuery] int? offset,
[FromQuery] int? limit,
[FromQuery] string remark,
[FromQuery] string supplier,
[FromQuery] string laneway,
[FromQuery] string workorderNo,
[FromQuery] bool bQty,
[FromQuery] string bill)
{
if (area.Length == 0)
{
area = null;
}
if (category.Length == 0)
{
category = null;
}
var items = await _stockQueryService.GetStockList(area, pallet, palletized, category, code, name, batch, barcode, cell, qc, inboundTimeFrom, inboundTimeTo, inventoryTimeFrom, inventoryTimeTo, overdue, enabled, excludeTask, sort, offset, limit, qualityState, materialAgeStatus, manufacturingDateFrom, manufacturingDateTo, remark, supplier, laneway, workorderNo, bill);
decimal qtyCurrent = 0;
decimal qtySum = 0;
decimal transQtyCurrent = 0;
decimal transQtySum = 0;
if (bQty)
{
qtyCurrent = await _stockQueryService.GetStockQtySum(area, pallet, palletized, category, code, name, batch, barcode, cell, qc, inboundTimeFrom, inboundTimeTo, inventoryTimeFrom, inventoryTimeTo, overdue, enabled, excludeTask, sort, offset, limit, qualityState, materialAgeStatus, manufacturingDateFrom, manufacturingDateTo, remark, supplier, laneway, workorderNo, bill);
transQtyCurrent = qtyCurrent;
}
if (offset.HasValue || limit.HasValue)
{
var total = await _stockQueryService.GetStockCount(area, pallet, palletized, category, code, name, batch, barcode, cell, qc, inboundTimeFrom, inboundTimeTo, inventoryTimeFrom, inventoryTimeTo, overdue, enabled, excludeTask, qualityState, materialAgeStatus, manufacturingDateFrom, manufacturingDateTo, remark, supplier, laneway, workorderNo, bill);
if (bQty)
{
qtySum = await _stockQueryService.GetStockQtySum(area, pallet, palletized, category, code, name, batch, barcode, cell, qc, inboundTimeFrom, inboundTimeTo, inventoryTimeFrom, inventoryTimeTo, overdue, enabled, excludeTask, null, null, null, qualityState, materialAgeStatus, manufacturingDateFrom, manufacturingDateTo, remark, supplier, laneway, workorderNo, bill);
transQtySum = qtySum;
Application.Query.ViewModels.Stock statistics = new Application.Query.ViewModels.Stock();
statistics.QualifiedNum = $"{qtyCurrent} / {qtySum}";
statistics.TransQty = $"{transQtyCurrent} / {transQtySum}";
statistics.Barcode = "";
items = items.Concat(new[]{ statistics});
}
return StatusCode(200, new {
items,
total
});
}
else
{
if (bQty)
{
var statistics = new Application.Query.ViewModels.Stock();
statistics.QualifiedNum = $"{qtyCurrent} / {qtyCurrent}";
statistics.TransQty = $"{transQtyCurrent} / {transQtyCurrent}";
statistics.Barcode = "";
items = items.Concat(new[] { statistics });
}
return StatusCode(200, new {
items,
total = items.Count()
});
}
}
/// <summary>
/// 导出库存列表
/// </summary>
/// <response code="200">成功</response>
[HttpGet("excel")]
[ProducesResponseType(200)]
public async Task<IActionResult> Export(
[FromQuery] int[] area,
[FromQuery] bool? pallet,
[FromQuery] bool? palletized,
[FromQuery] int[] category,
[FromQuery] string code,
[FromQuery] string name,
[FromQuery] string batch,
[FromQuery] string barcode,
[FromQuery] string cell,
[FromQuery] string qc,
[FromQuery] string qualityState,
[FromQuery] string materialAgeStatus,
[FromQuery] DateTime? inboundTimeFrom,
[FromQuery] DateTime? inboundTimeTo,
[FromQuery] DateTime? inventoryTimeFrom,
[FromQuery] DateTime? inventoryTimeTo,
[FromQuery] bool? overdue,
[FromQuery] bool? enabled,
[FromQuery] bool? excludeTask,
[FromQuery] DateTime? manufacturingDateFrom,
[FromQuery] DateTime? manufacturingDateTo,
[FromQuery] string remark,
[FromQuery] string supplier,
[FromQuery] string laneway,
[FromQuery] string workorderNo,
[FromQuery] string bill)
{
if (area.Length == 0)
{
area = null;
}
if (category.Length == 0)
{
category = null;
}
using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
var column = 0;
worksheet.Cells[1, ++column].Value = "托盘";
worksheet.Cells[1, ++column].Value = "物料编码";
worksheet.Cells[1, ++column].Value = "物料名称";
worksheet.Cells[1, ++column].Value = "仓库";
worksheet.Cells[1, ++column].Value = "货位";
worksheet.Cells[1, ++column].Value = "膜卷码";
worksheet.Cells[1, ++column].Value = "质量状态";
worksheet.Cells[1, ++column].Value = "库存状态";
worksheet.Cells[1, ++column].Value = "过账状态";
worksheet.Cells[1, ++column].Value = "生产日期";
worksheet.Cells[1, ++column].Value = "货龄(天)";
worksheet.Cells[1, ++column].Value = "创建时间";
worksheet.Cells[1, ++column].Value = "工单号";
worksheet.Cells[1, ++column].Value = "数量";
worksheet.Cells[1, ++column].Value = "单位";
worksheet.Cells[1, ++column].Value = "备注";
var index = 1;
foreach (var item in await _stockQueryService.GetStockList(area, pallet, palletized, category, code, name, batch, barcode, cell, qc, inboundTimeFrom, inboundTimeTo, inventoryTimeFrom, inventoryTimeTo, overdue, enabled, excludeTask, null, null, null, qualityState, materialAgeStatus, manufacturingDateFrom, manufacturingDateTo, remark, supplier, laneway, workorderNo, bill))
{
index++;
column = 0;
worksheet.Cells[index, ++column].Value = item.Barcode;
worksheet.Cells[index, ++column].Value = item.Code;
worksheet.Cells[index, ++column].Value = item.Name;
worksheet.Cells[index, ++column].Value = item.Warehouse;
worksheet.Cells[index, ++column].Value = item.Cell;
worksheet.Cells[index, ++column].Value = item.Bill;
string qs = "";
if (item.QualityState == "ok")
{
qs = "合格";
} else if (item.QualityState == "ng")
{
qs = "NG";
}
else if (item.QualityState == "check")
{
qs = "验证品";
}
worksheet.Cells[index, ++column].Value = qs;
worksheet.Cells[index, ++column].Value = item.Enabled == true? "可用": "冻结";
worksheet.Cells[index, ++column].Value = "";
worksheet.Cells[index, ++column].Value = item.ManufacturingDate;
worksheet.Cells[index, column].Style.Numberformat.Format = "yyyy-MM-dd HH:mm:ss";
worksheet.Cells[index, ++column].Value = item.MaterialAge;
worksheet.Cells[index, ++column].Value = item.InboundTime;
worksheet.Cells[index, column].Style.Numberformat.Format = "yyyy-MM-dd HH:mm:ss";
worksheet.Cells[index, ++column].Value = item.WorkorderNo;
worksheet.Cells[index, ++column].Value = item.TransQty;
worksheet.Cells[index, ++column].Value = item.TransUnit;
worksheet.Cells[index, ++column].Value = item.Remark;
}
return File(package.GetAsByteArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
/// <summary>
/// 创建库动
/// </summary>
/// <response code="201">成功</response>
/// <response code="405">非法操作</response>
/// <response code="422">请求内容错误</response>
[HttpPost]
[ProducesResponseType(201)]
[ProducesResponseType(405)]
[ProducesResponseType(422)]
public async Task<IActionResult> Operate(
[FromMember] string operation,
[FromMember] Stock stock,
[FromMember] bool? full,
[FromMember] int? destination,
[FromMiddleware] int session)
{
stock.Operator = session;
var user = await _identityQueryService.GetUser(session);
try
{
JObject jObj = JObject.Parse(stock.Tag);
JToken jPostUser = jObj.SelectToken("postUser");
if (jPostUser == null)
{
jObj.Add("postUser", user.Name);
}
else
{
jObj["postUser"] = user.Name;
}
stock.Tag = JsonConvert.SerializeObject(jObj);
}
catch { }
Failure failure;
(string Device, Failure Failure) commandResult;
commandResult.Device = "";
switch (operation)
{
case "palletIn":
failure = await _stockCommandService.PalletIn(stock, full, destination);
break;
case "scanInbound":
commandResult = await _stockCommandService.ScanInbound(stock, full, destination);
failure = commandResult.Failure;
break;
case "inbound":
failure = await _stockCommandService.Inbound(stock, full, destination);
break;
case "outbound":
failure = await _stockCommandService.Outbound(stock);
break;
case "update":
failure = await _stockCommandService.Update(stock);
break;
case "combine":
failure = await _stockCommandService.Combine(stock, full, destination);
break;
case "inventory":
failure = await _stockCommandService.Inventory(stock);
break;
case "applyin":
//var user = await _identityQueryService.GetUser(session);
foreach (var r in stock.Lines)
{
r.Postuser = user.Name;
}
commandResult = await _stockCommandService.ApplyIn(stock, full, destination);
failure = commandResult.Failure;
break;
default:
return StatusCode(405);
}
if (failure == null)
{
return StatusCode(201, commandResult.Device);
}
else
{
return StatusCode(422, failure);
}
}
/// <summary>
/// 获取安全库存列表
/// </summary>
/// <response code="200">成功</response>
[HttpGet("safeties")]
[ProducesResponseType(200)]
public async Task<IActionResult> GetSafetyList(
[FromQuery] string type,
[FromQuery] int[] warehouse,
[FromQuery] int[] category,
[FromQuery] string code,
[FromQuery] string name,
[FromQuery] string sort,
[FromQuery] int? offset,
[FromQuery] int? limit)
{
if (warehouse.Length == 0)
{
warehouse = null;
}
if (category.Length == 0)
{
category = null;
}
var items = await _stockQueryService.GetSafetyList(type, warehouse, category, code, name, sort, offset, limit);
if (offset.HasValue || limit.HasValue)
{
var total = await _stockQueryService.GetSafetyCount(type, warehouse, category, code, name);
return StatusCode(200, new { items, total });
}
else
{
return StatusCode(200, new { items, total = items.Count() });
}
}
/// <summary>
/// 导出安全库存列表
/// </summary>
/// <response code="200">成功</response>
[HttpGet("safeties/excel")]
[ProducesResponseType(200)]
public async Task<IActionResult> ExportSafety(
[FromQuery] string type,
[FromQuery] int[] warehouse,
[FromQuery] int[] category,
[FromQuery] string code,
[FromQuery] string name)
{
if (warehouse.Length == 0)
{
warehouse = null;
}
if (category.Length == 0)
{
category = null;
}
using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
var column = 0;
worksheet.Cells[1, ++column].Value = "物料号";
worksheet.Cells[1, ++column].Value = "物料名";
worksheet.Cells[1, ++column].Value = "规格型号";
worksheet.Cells[1, ++column].Value = "数量";
worksheet.Cells[1, ++column].Value = "单位";
worksheet.Cells[1, ++column].Value = "安全库存";
var warehouseName = (await _warehouseQueryService.GetWarehouseList(null, null, null)).ToDictionary(w => w.Id.ToString(), w => w.Name);
var index = 1;
foreach (var item in await _stockQueryService.GetSafetyList(type, warehouse, category, code, name, null, null, null))
{
index++;
column = 0;
worksheet.Cells[index, ++column].Value = item.Code;
worksheet.Cells[index, ++column].Value = item.Name;
worksheet.Cells[index, ++column].Value = item.Model;
worksheet.Cells[index, ++column].Value = item.Quantity;
worksheet.Cells[index, ++column].Value = item.Unit;
worksheet.Cells[index, ++column].Value = $"{item.LowerLimit} ~ {item.UpperLimit} ( {string.Join(" + ", item.Warehouse.Split(',').Select(i => warehouseName.ContainsKey(i) ? warehouseName[i] : "?"))} )";
}
return File(package.GetAsByteArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
///////////////////////////////////////////////////////
/// <summary>
/// 获取批次码列表
/// </summary>
/// <response code="200">成功</response>
[HttpGet("batch")]
[ProducesResponseType(200)]
public async Task<IActionResult> GetBatchList([FromQuery] int? material)
{
var items = await _stockQueryService.GetBatchList(material);
return StatusCode(200, new
{
items
});
}
/// <summary>
/// 冻结
/// </summary>
/// <response code="201">成功</response>
/// <response code="405">非法操作</response>
/// <response code="422">请求内容错误</response>
[HttpPost("setQcStatus")]
[ProducesResponseType(201)]
[ProducesResponseType(405)]
[ProducesResponseType(422)]
public async Task<IActionResult> SetQcStatus(
[FromMember] string operation,
[FromMember] int? code,
[FromMember] string batch,
[FromMember] DateTime? mfgFrom,
[FromMember] DateTime? mfgTo,
[FromMember] DateTime? inboundTimeFrom,
[FromMember] DateTime? inboundTimeTo,
[FromMember] string barcode,
[FromMember] string supplier,
[FromMember] string[] barcodes,
[FromMiddleware] int session)
{
Failure failure;
(int barcodeCount, Failure Failure) commandResult;
commandResult.barcodeCount = 0;
commandResult = await _stockCommandService.SetQcStatus(session, operation, code, batch, mfgFrom, mfgTo, inboundTimeFrom, inboundTimeTo, barcode, supplier, barcodes);
failure = commandResult.Failure;
if (failure == null)
{
return StatusCode(201, commandResult.barcodeCount);
}
else
{
return StatusCode(422, failure);
}
}
}
}