diff --git a/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs b/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs
index a6d70c6..15927f5 100644
--- a/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs
+++ b/DOAN.Admin.WebApi/Controllers/MES/Product/ProWorkorderController.cs
@@ -131,6 +131,29 @@ namespace DOAN.Admin.WebApi.Controllers
return ToResponse(response);
}
+ ///
+ /// 批量安全删除工单
+ ///
+ ///
+ [HttpPost("BatchDeleteWorkOrder")]
+ [ActionPermissionFilter(Permission = "productManagement:proworkorder:add")]
+ [Log(Title = "删除工单", BusinessType = BusinessType.DELETE)]
+ public IActionResult BatchDeleteWorkOrder([FromBody] WorkOrderBatchDto parm)
+ {
+ try
+ {
+ var response = _ProWorkorderService.BatchDeleteWorkOrder(parm);
+
+ return SUCCESS(response);
+ }
+ catch (Exception ex)
+ {
+
+ return ToResponse(new ApiResult(500,ex.Message));
+ }
+
+ }
+
/////
///// 生成工单号
/////
@@ -553,6 +576,32 @@ namespace DOAN.Admin.WebApi.Controllers
}
}
+ ///
+ /// 批量领料接口
+ ///
+ /// 领料请求参数
+ /// 操作结果
+ [HttpPost("BatchTakeMaterialByIds")]
+ [ActionPermissionFilter(Permission = "productManagement:proworkorder:edit")]
+ [Log(Title = "批量领料", BusinessType = BusinessType.UPDATE)]
+ public IActionResult BatchTakeMaterialByIds([FromBody] WorkOrderBatchDto parm)
+ {
+ try
+ {
+ if (parm == null)
+ {
+ return ToResponse(ApiResult.Error($"领料请求参数不能为空"));
+ }
+
+ var response = _ProWorkorderMaterialService.BatchTakeMaterialByIds(parm);
+ return SUCCESS(response);
+ }
+ catch (Exception ex)
+ {
+ return ToResponse(new ApiResult(500, ex.Message));
+ }
+ }
+
///
/// 成品入库接口
///
diff --git a/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs b/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs
index 6bee835..c61e7ec 100644
--- a/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs
+++ b/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs
@@ -52,6 +52,9 @@ namespace DOAN.Model.BZFM.Dto
public string SupplierName { get; set; }
+ // 炉号(原材料领料外联查询)
+ public string StoveCode { get; set; }
+
public string BatchNo { get; set; }
public decimal CurrentQty { get; set; }
diff --git a/DOAN.Model/MES/Product/Dto/ProWorkorderDto.cs b/DOAN.Model/MES/Product/Dto/ProWorkorderDto.cs
index 496b62a..44416e7 100644
--- a/DOAN.Model/MES/Product/Dto/ProWorkorderDto.cs
+++ b/DOAN.Model/MES/Product/Dto/ProWorkorderDto.cs
@@ -60,6 +60,11 @@ namespace DOAN.Model.MES.product.Dto
public int PlanNum { get; set; } = 0;
public int ShipmentNum { get; set; } = 0;
+ // 领料数
+ public int MaterialNum { get; set; } = 0;
+ // 成品在库数
+ public int InInventoryNum { get; set; } = 0;
+
public int ProductNum { get; set; } = 0;
public int DefectNum { get; set; } = 0;
public int? Sort { get; set; }
@@ -230,6 +235,32 @@ namespace DOAN.Model.MES.product.Dto
public string BOMVersion { get; set; }
}
+ ///
+ /// 工单批量操作Dto
+ ///
+ public class WorkOrderBatchDto
+ {
+ ///
+ /// ID号数组
+ ///
+ public List Ids { get; set; }
+
+ ///
+ /// 批号
+ ///
+ public string BatchNo { get; set; }
+
+ ///
+ /// 数量
+ ///
+ public decimal Quantity { get; set; }
+
+ ///
+ /// 操作人
+ ///
+ public string Operator { get; set; }
+ }
+
///
/// 工单进度追溯
///
diff --git a/DOAN.Service/MES/Material/MmInventoryService.cs b/DOAN.Service/MES/Material/MmInventoryService.cs
index 27d2c65..0947d7e 100644
--- a/DOAN.Service/MES/Material/MmInventoryService.cs
+++ b/DOAN.Service/MES/Material/MmInventoryService.cs
@@ -32,7 +32,14 @@ namespace DOAN.Service.BZFM
var response = Queryable()
.Where(predicate.ToExpression())
- .ToPage(parm);
+ .Select(it => new MmInventoryDto
+ {
+ Id = it.Id,
+ StoveCode = SqlFunc.Subqueryable()
+ .Where(sub=>sub.BatchNo == it.BatchNo)
+ .Select(sub => sub.StoveCode)
+ },true)
+ .ToPage(parm);
return response;
}
diff --git a/DOAN.Service/MES/Product/IService/IProWorkorderCoreService.cs b/DOAN.Service/MES/Product/IService/IProWorkorderCoreService.cs
index cf3eec5..6a839c8 100644
--- a/DOAN.Service/MES/Product/IService/IProWorkorderCoreService.cs
+++ b/DOAN.Service/MES/Product/IService/IProWorkorderCoreService.cs
@@ -44,5 +44,13 @@ namespace DOAN.Service.MES.product.IService
///
///
int Insert_workOrder2(ProWorkorder proWorkorder, string next_id);
+
+ ///
+ /// 批量删除工单
+ ///
+ ///
+ ///
+ ///
+ int BatchDeleteWorkOrder(WorkOrderBatchDto parm);
}
}
\ No newline at end of file
diff --git a/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs b/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs
index 15e78a3..20e0559 100644
--- a/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs
+++ b/DOAN.Service/MES/Product/IService/IProWorkorderMaterialService.cs
@@ -75,6 +75,13 @@ namespace DOAN.Service.MES.product.IService
/// 操作结果
bool TakeMaterial(MaterialTakeRequestDto request);
+ ///
+ /// 根据工单Ids批量领料
+ ///
+ /// 领料请求参数
+ /// 操作结果
+ int BatchTakeMaterialByIds(WorkOrderBatchDto request);
+
///
/// 根据工单成品入库
///
diff --git a/DOAN.Service/MES/Product/IService/IProWorkorderService.cs b/DOAN.Service/MES/Product/IService/IProWorkorderService.cs
index 09eef6a..e2c5d30 100644
--- a/DOAN.Service/MES/Product/IService/IProWorkorderService.cs
+++ b/DOAN.Service/MES/Product/IService/IProWorkorderService.cs
@@ -33,6 +33,8 @@ namespace DOAN.Service.MES.product.IService
int UpdateProWorkorder(ProWorkorder parm);
+ int BatchDeleteWorkOrder(WorkOrderBatchDto parm);
+
int Generate_workorder(ProWorkorderQueryDto2 parm);
int Insert_workOrder(ProWorkorder proWorkorder, string next_id);
diff --git a/DOAN.Service/MES/Product/ProWorkorderCoreService.cs b/DOAN.Service/MES/Product/ProWorkorderCoreService.cs
index c716654..49c1519 100644
--- a/DOAN.Service/MES/Product/ProWorkorderCoreService.cs
+++ b/DOAN.Service/MES/Product/ProWorkorderCoreService.cs
@@ -4,13 +4,17 @@ using DOAN.Model.MES.product.Dto;
using DOAN.Service.MES.product.IService;
using Infrastructure.Attribute;
using Infrastructure.Converter;
+using Microsoft.IdentityModel.Tokens;
namespace DOAN.Service.MES.product
{
///
/// 核心工单管理服务
///
- [AppService(ServiceType = typeof(IProWorkorderCoreService), ServiceLifetime = LifeTime.Transient)]
+ [AppService(
+ ServiceType = typeof(IProWorkorderCoreService),
+ ServiceLifetime = LifeTime.Transient
+ )]
public class ProWorkorderCoreService : BaseService, IProWorkorderCoreService
{
///
@@ -51,7 +55,7 @@ namespace DOAN.Service.MES.product
Workorder = model.Workorder,
Log = "修改生产工单",
ChangeTime = DateTime.Now,
- Operator = model.CreatedBy
+ Operator = model.CreatedBy,
};
Context.Insertable(logObj).ExecuteCommand();
@@ -210,7 +214,7 @@ namespace DOAN.Service.MES.product
Log = "手动新增",
ChangeTime = DateTime.Now,
Operator = proWorkorder.CreatedBy,
- CreatedBy = proWorkorder.CreatedBy
+ CreatedBy = proWorkorder.CreatedBy,
};
UseTran2(() =>
{
@@ -373,7 +377,8 @@ namespace DOAN.Service.MES.product
}
// 批量获取工单信息
- var workorders = Context.Queryable()
+ var workorders = Context
+ .Queryable()
.Where(it => workorderIds.Contains(it.Id))
.ToList();
@@ -412,11 +417,81 @@ namespace DOAN.Service.MES.product
int progress = CalculateProductionProgressByStatus(workorder.Status);
// 返回包含生产进度的工单信息
- return new
+ return new { Workorder = workorder, ProductionProgress = progress };
+ }
+
+ public int BatchDeleteWorkOrder(WorkOrderBatchDto parm)
+ {
+ try
{
- Workorder = workorder,
- ProductionProgress = progress
- };
+ // 删除参数校验
+ if (parm == null)
+ {
+ throw new Exception("传入参数parm为空");
+ }
+ List workorderIds = parm.Ids;
+ if (workorderIds.Count == 0)
+ {
+ throw new Exception("传入参数Ids为空,无修改工单");
+ }
+ List deleteWorkOrderList = new();
+ // 删除业务前置校验
+ foreach (string workOrderId in workorderIds)
+ {
+ ProWorkorder workOrderInfo = Context
+ .Queryable()
+ .Where(it => it.Id == workOrderId)
+ .First();
+ if (workOrderInfo == null || string.IsNullOrEmpty(workOrderInfo.Workorder))
+ {
+ throw new Exception($"工单异常{workOrderId},未找到工单");
+ }
+ string workOrder = workOrderInfo.Workorder;
+ // 是否有领料记录
+ bool hasOutMaterialRecord = Context.Queryable()
+ .Where(it => it.Workorder == workOrder)
+ .Where(it => it.TransactionType == "领料出库")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
+ .Any();
+ if (hasOutMaterialRecord)
+ {
+ throw new Exception($"该工单{workOrder}存在领料记录,无法删除");
+ }
+ // 是否存在成品入库记录
+ bool hasWarehousingRecord = Context.Queryable()
+ .Where(it => it.Workorder == workOrder)
+ .Where(it => it.TransactionType == "生产入库")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
+ .Any();
+ if (hasWarehousingRecord)
+ {
+ throw new Exception($"该工单{workOrder}存在生产入库记录,无法删除");
+ }
+ // 是否存在出货记录
+ bool hasOutRecord = Context.Queryable()
+ .Where(it => it.Workorder == workOrder)
+ .Where(it => it.TransactionType == "出货出库")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
+ .Any();
+ if (hasOutRecord)
+ {
+ throw new Exception($"该工单{workOrder}存在出货记录,无法删除");
+ }
+ bool hasReportRecord = Context.Queryable()
+ .Where(it => it.Workorder == workOrder)
+ .Any();
+ if (hasReportRecord)
+ {
+ throw new Exception($"该工单{workOrder}存在报工记录,无法删除");
+ }
+ deleteWorkOrderList.Add(workOrderInfo);
+ }
+ return Context.Deleteable(deleteWorkOrderList).ExecuteCommand();
+ }
+ catch (Exception)
+ {
+ throw;
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs b/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs
index 1050daa..3999ff6 100644
--- a/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs
+++ b/DOAN.Service/MES/Product/ProWorkorderMaterialService.cs
@@ -1,3 +1,4 @@
+using Aliyun.OSS;
using DOAN.Model.BZFM;
using DOAN.Model.MES.order;
using DOAN.Model.MES.order.Dto;
@@ -9,6 +10,7 @@ using DOAN.Service.MES.product.IService;
using DOAN.Service.Mobile;
using Infrastructure.Attribute;
using MailKit.Search;
+using Microsoft.Data.SqlClient;
using Microsoft.IdentityModel.Tokens;
using SqlSugar.DistributedSystem.Snowflake;
using System.Collections.Generic;
@@ -37,7 +39,7 @@ namespace DOAN.Service.MES.product
.Queryable()
.Where(it => it.Workorder == workorder)
.Where(it => it.TransactionType == "领料出库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
//.WhereIF(isHideZero, it => it != "已撤销")
.Select(it => new MaterialTakeDto
{
@@ -88,7 +90,7 @@ namespace DOAN.Service.MES.product
.Queryable()
.Where(it => it.Workorder == workorder)
.Where(it => it.TransactionType == "生产入库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
.Select(it => new ProductStorageDto
{
Id = it.Id,
@@ -119,7 +121,7 @@ namespace DOAN.Service.MES.product
.Queryable()
.Where(it => it.Workorder == workorder)
.Where(it => it.TransactionType == "出货出库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
.Select(it => new ShipmentDto
{
Id = it.Id,
@@ -271,7 +273,7 @@ namespace DOAN.Service.MES.product
.LeftJoin((mri,pro)=>mri.Workorder == pro.Workorder)
.Where((mri, pro) => mri.MaterialCode == workorderInfo.MaterialCode)
.Where((mri, pro) => mri.TransactionType == "生产入库")
- .Where((mri, pro) => mri.Remarks != "已撤销")
+ .Where((mri, pro) => mri.Remarks != "已撤销" || mri.Remarks == null)
//.Where((mri, pro) => pro.ShipmentNum < pro.PlanNum)
.OrderByDescending((mri, pro) => mri.Workorder)
.Select(
@@ -476,6 +478,7 @@ namespace DOAN.Service.MES.product
);
// 示例返回true
return result;
+
}
catch (Exception ex)
{
@@ -485,6 +488,122 @@ namespace DOAN.Service.MES.product
}
}
+ ///
+ /// 工单批量领料
+ ///
+ ///
+ ///
+ public int BatchTakeMaterialByIds(WorkOrderBatchDto parm)
+ {
+ try
+ {
+ // 删除参数校验
+ if (parm == null)
+ {
+ throw new Exception("传入参数parm为空");
+ }
+ List workorderIds = parm.Ids;
+ if (workorderIds.Count == 0)
+ {
+ throw new Exception("传入参数Ids为空,无修改工单");
+ }
+ // 检查是否有采购记录
+ var inboundRecordInfo = Context.Queryable()
+ .Where(it => it.BatchNo == parm.BatchNo)
+ .Where(it => it.TransactionType == "采购入库")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
+ .First();
+ if (inboundRecordInfo == null)
+ {
+ throw new Exception($"批次号{parm.BatchNo}无对应采购记录,请检查");
+ }
+ // 批量领料业务
+ int result = 0;
+ string standardMaterialCode = string.Empty;
+ // 业务处理前校验
+ List batchTakeMaterialWorkOrderList = new();
+ foreach (string workOrderId in workorderIds)
+ {
+ ProWorkorder workOrderInfo = Context
+ .Queryable()
+ .Where(it => it.Id == workOrderId)
+ .First();
+ if (workOrderInfo == null || string.IsNullOrEmpty(workOrderInfo.Workorder))
+ {
+ throw new Exception($"工单异常{workOrderId},未找到工单");
+ }
+ if(workOrderInfo.RouteCode == "10")
+ {
+ throw new Exception("10线工单不可批量领料");
+ }
+ if (string.IsNullOrEmpty(standardMaterialCode))
+ {
+ standardMaterialCode = workOrderInfo.MaterialCode;
+ }
+ else
+ {
+ if(standardMaterialCode != workOrderInfo.MaterialCode)
+ {
+ throw new Exception($"工单{workOrderInfo.Workorder}原材料与上一个工单不一致,上一个工单{standardMaterialCode}");
+ }
+ }
+ string workOrder = workOrderInfo.Workorder;
+ // 是否有领料记录
+ bool hasOutMaterialRecord = Context.Queryable()
+ .Where(it => it.Workorder == workOrder)
+ .Where(it => it.TransactionType == "领料出库")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
+ .Any();
+ if (hasOutMaterialRecord)
+ {
+ throw new Exception($"该工单{workOrder}已存在领料记录,无法再次领料");
+ }
+ batchTakeMaterialWorkOrderList.Add(workOrderInfo);
+ }
+ if(batchTakeMaterialWorkOrderList.Count == 0)
+ {
+ throw new Exception($"待领料工单数量异常");
+ }
+ // 检查库存容量是否足够
+ var inventoryInfo = Context.Queryable()
+ .Where(it => it.BatchNo == parm.BatchNo)
+ .Where(it => it.MaterialCode == batchTakeMaterialWorkOrderList[0].MaterialCode)
+ .Where(it => it.LocationCode == "YCL001")
+ .First();
+ if (inventoryInfo.CurrentQty < batchTakeMaterialWorkOrderList.Count * parm.Quantity)
+ {
+ throw new Exception($"该批次库存数不足,目前库存数{inventoryInfo.CurrentQty},需要{batchTakeMaterialWorkOrderList.Count * parm.Quantity}");
+ }
+
+ foreach (var workorderInfo in batchTakeMaterialWorkOrderList)
+ {
+ MaterialTakeRequestDto takeDto = new()
+ {
+ Workorder = workorderInfo.Workorder,
+ WorkorderRaw = string.Empty,
+ Quantity = parm.Quantity,
+ MaterialInventoryId = inventoryInfo.Id,
+ StoveCode = inboundRecordInfo.StoveCode,
+ Operator = parm.Operator
+ };
+ bool isOk = TakeMaterial(takeDto);
+ if (isOk)
+ {
+ result++;
+ }
+ else
+ {
+ throw new Exception($"领料异常结束,只成功{result}个工单");
+ }
+ }
+ return result;
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ }
+
///
/// 工单成品入库接口
///
@@ -617,5 +736,6 @@ namespace DOAN.Service.MES.product
throw new Exception(ex.Message);
}
}
+
}
}
diff --git a/DOAN.Service/MES/Product/ProWorkorderQueryService.cs b/DOAN.Service/MES/Product/ProWorkorderQueryService.cs
index 1cce63b..df72d3d 100644
--- a/DOAN.Service/MES/Product/ProWorkorderQueryService.cs
+++ b/DOAN.Service/MES/Product/ProWorkorderQueryService.cs
@@ -1,3 +1,4 @@
+using DOAN.Model.BZFM;
using DOAN.Model.MES.product;
using DOAN.Model.MES.product.Dto;
using DOAN.Repository;
@@ -131,9 +132,25 @@ namespace DOAN.Service.MES.product
var response = Context
.Queryable()
.Where(predicate)
+ .Select(
+ it => new ProWorkorderDto
+ {
+ Id = it.Id,
+ MaterialNum = (int)
+ SqlFunc.Abs(
+ SqlFunc
+ .Subqueryable()
+ .Where(sub => sub.Workorder == it.Workorder)
+ .Where(sub => sub.TransactionType == "领料出库")
+ .Where(sub => sub.Remarks != "已撤销" || sub.Remarks == null)
+ .Select(sub => sub.Quantity)
+ ),
+ InInventoryNum = it.ProductNum - it.ShipmentNum,
+ },
+ true
+ )
.OrderBy(it => it.Sort)
- .ToPage(parm);
-
+ .ToPage(parm);
return response;
}
diff --git a/DOAN.Service/MES/Product/ProWorkorderService.cs b/DOAN.Service/MES/Product/ProWorkorderService.cs
index 137a7f7..40d29d2 100644
--- a/DOAN.Service/MES/Product/ProWorkorderService.cs
+++ b/DOAN.Service/MES/Product/ProWorkorderService.cs
@@ -98,6 +98,18 @@ namespace DOAN.Service.MES.product
return _coreService.UpdateProWorkorder(model);
}
+ ///
+ /// 安全批量删除工单
+ ///
+ ///
+ ///
+ public int BatchDeleteWorkOrder(WorkOrderBatchDto parm)
+ {
+ return _coreService.BatchDeleteWorkOrder(parm);
+ }
+
+
+
///
/// 插入工单、新增工单
///
diff --git a/DOAN.Service/MES/Quality/IPQC/QcScrapRecordsService.cs b/DOAN.Service/MES/Quality/IPQC/QcScrapRecordsService.cs
index 7a5da6a..8236f5a 100644
--- a/DOAN.Service/MES/Quality/IPQC/QcScrapRecordsService.cs
+++ b/DOAN.Service/MES/Quality/IPQC/QcScrapRecordsService.cs
@@ -183,7 +183,7 @@ namespace DOAN.Service.BZFM
.Queryable()
.Where(it => it.BatchNo == workorderInfo.FeedOrder)
.Where(it => it.TransactionType == "采购入库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
.First();
if (purchaseInfo != null)
{
@@ -241,7 +241,7 @@ namespace DOAN.Service.BZFM
.Queryable()
.Where(it => it.BatchNo == workorderInfo.FeedOrder)
.Where(it => it.TransactionType == "采购入库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
.First();
if (purchaseInfo != null)
{
@@ -725,7 +725,7 @@ namespace DOAN.Service.BZFM
.Queryable()
.Where(it => it.BatchNo == workorderInfo.FeedOrder)
.Where(it => it.TransactionType == "采购入库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
.First();
if (purchaseInfo != null)
{
diff --git a/DOAN.Service/Mobile/ReportFlowService.cs b/DOAN.Service/Mobile/ReportFlowService.cs
index 9d90a8c..cb150d5 100644
--- a/DOAN.Service/Mobile/ReportFlowService.cs
+++ b/DOAN.Service/Mobile/ReportFlowService.cs
@@ -11,6 +11,7 @@ using DOAN.Service.BZFM;
using DOAN.Service.Mobile.IService;
using Infrastructure.Attribute;
using Mapster;
+using System;
namespace DOAN.Service.Mobile;
@@ -175,7 +176,7 @@ public class ReportFlowService : BaseService, IReportFlowServic
.Queryable()
.Where(it => it.Workorder == workorder)
.Where(it => it.TransactionType == "领料出库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销" || it.Remarks == null)
.First();
//1.检查领料是否超出限额
@@ -198,7 +199,7 @@ public class ReportFlowService : BaseService, IReportFlowServic
.Queryable()
.Where(it => it.Workorder == workorderRaw)
.Where(it => it.TransactionType == "生产入库")
- .Where(it => it.Remarks != "已撤销")
+ .Where(it => it.Remarks != "已撤销"|| it.Remarks == null)
.First();
if (inboundRecord == null)
{