2026-01-22 17:25:17 +08:00
|
|
|
|
using DOAN.Model.BZFM;
|
2026-02-10 19:00:54 +08:00
|
|
|
|
using DOAN.Model.BZFM.Dto;
|
|
|
|
|
|
using DOAN.Model.MES.product;
|
2026-01-22 17:25:17 +08:00
|
|
|
|
using DOAN.Repository;
|
|
|
|
|
|
using DOAN.Service.BZFM.IService;
|
2026-02-10 19:00:54 +08:00
|
|
|
|
using Infrastructure.Attribute;
|
|
|
|
|
|
using Infrastructure.Extensions;
|
|
|
|
|
|
using SqlSugar.DistributedSystem.Snowflake;
|
2026-01-22 17:25:17 +08:00
|
|
|
|
|
|
|
|
|
|
namespace DOAN.Service.BZFM
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2026-01-26 17:57:18 +08:00
|
|
|
|
/// Service业务层处理
|
2026-01-22 17:25:17 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
[AppService(ServiceType = typeof(IQcScrapRecordsService), ServiceLifetime = LifeTime.Transient)]
|
|
|
|
|
|
public class QcScrapRecordsService : BaseService<QcScrapRecords>, IQcScrapRecordsService
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 查询报废记录表列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public PagedInfo<QcScrapRecordsDto> GetList(QcScrapRecordsQueryDto parm)
|
|
|
|
|
|
{
|
|
|
|
|
|
var predicate = QueryExp(parm);
|
|
|
|
|
|
|
|
|
|
|
|
var response = Queryable()
|
|
|
|
|
|
.Where(predicate.ToExpression())
|
2026-02-10 19:00:54 +08:00
|
|
|
|
.OrderByDescending(it => it.CreatedTime)
|
2026-01-22 17:25:17 +08:00
|
|
|
|
.ToPage<QcScrapRecords, QcScrapRecordsDto>(parm);
|
|
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取详情
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="Id"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcScrapRecords GetInfo(long Id)
|
|
|
|
|
|
{
|
2026-02-10 19:00:54 +08:00
|
|
|
|
var response = Queryable().Where(x => x.Id == Id).First();
|
2026-01-22 17:25:17 +08:00
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 添加报废记录表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="model"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcScrapRecords AddQcScrapRecords(QcScrapRecords model)
|
|
|
|
|
|
{
|
2026-01-26 17:57:18 +08:00
|
|
|
|
// 如果没有提供报废单号,则生成一个
|
|
|
|
|
|
if (string.IsNullOrEmpty(model.ScrapOrderNo))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 根据报废类型选择前缀
|
|
|
|
|
|
string prefix = model.ScrapType == "转用" ? "ZY" : "BF";
|
|
|
|
|
|
model.ScrapOrderNo = GenerateScrapOrderNo(prefix);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Context.Insertable(model).ExecuteReturnEntity();
|
2026-01-22 17:25:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 修改报废记录表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="model"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public int UpdateQcScrapRecords(QcScrapRecords model)
|
|
|
|
|
|
{
|
|
|
|
|
|
return Update(model, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 查询导出表达式
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private static Expressionable<QcScrapRecords> QueryExp(QcScrapRecordsQueryDto parm)
|
|
|
|
|
|
{
|
2026-01-26 17:57:18 +08:00
|
|
|
|
var predicate = Expressionable
|
|
|
|
|
|
.Create<QcScrapRecords>()
|
|
|
|
|
|
// 模糊搜索字段
|
2026-02-10 19:00:54 +08:00
|
|
|
|
.AndIF(
|
|
|
|
|
|
!string.IsNullOrEmpty(parm.ScrapOrderNo),
|
|
|
|
|
|
it => it.ScrapOrderNo.Contains(parm.ScrapOrderNo)
|
|
|
|
|
|
)
|
|
|
|
|
|
.AndIF(
|
|
|
|
|
|
!string.IsNullOrEmpty(parm.Workorder),
|
|
|
|
|
|
it => it.Workorder.Contains(parm.Workorder)
|
|
|
|
|
|
)
|
|
|
|
|
|
.AndIF(
|
|
|
|
|
|
!string.IsNullOrEmpty(parm.StoveCode),
|
|
|
|
|
|
it => it.StoveCode.Contains(parm.StoveCode)
|
|
|
|
|
|
)
|
|
|
|
|
|
.AndIF(
|
|
|
|
|
|
!string.IsNullOrEmpty(parm.ProductCode),
|
|
|
|
|
|
it => it.ProductCode.Contains(parm.ProductCode)
|
|
|
|
|
|
)
|
2026-01-26 17:57:18 +08:00
|
|
|
|
.AndIF(!string.IsNullOrEmpty(parm.BatchNo), it => it.BatchNo.Contains(parm.BatchNo))
|
|
|
|
|
|
// 精确搜索字段
|
2026-02-10 19:00:54 +08:00
|
|
|
|
.AndIF(
|
|
|
|
|
|
!string.IsNullOrEmpty(parm.MaterialCode),
|
|
|
|
|
|
it => it.MaterialCode == parm.MaterialCode
|
|
|
|
|
|
)
|
|
|
|
|
|
.AndIF(
|
|
|
|
|
|
!string.IsNullOrEmpty(parm.SupplierCode),
|
|
|
|
|
|
it => it.SupplierCode == parm.SupplierCode
|
|
|
|
|
|
)
|
2026-01-26 17:57:18 +08:00
|
|
|
|
.AndIF(!string.IsNullOrEmpty(parm.ScrapType), it => it.ScrapType == parm.ScrapType)
|
|
|
|
|
|
.AndIF(!string.IsNullOrEmpty(parm.LineCode), it => it.LineCode == parm.LineCode)
|
|
|
|
|
|
.AndIF(!string.IsNullOrEmpty(parm.Status), it => it.Status == parm.Status);
|
2026-01-22 17:25:17 +08:00
|
|
|
|
|
|
|
|
|
|
return predicate;
|
|
|
|
|
|
}
|
2026-01-26 17:57:18 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-02-20 10:44:52 +08:00
|
|
|
|
/// 生成不良单号
|
2026-01-26 17:57:18 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="prefix">前缀,默认BF表示报废</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private string GenerateScrapOrderNo(string prefix = "BF")
|
|
|
|
|
|
{
|
|
|
|
|
|
var datePart = DateTime.Now.ToString("yyyyMMdd");
|
|
|
|
|
|
var baseNo = prefix + datePart + "-";
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试从报废记录表中获取当天最大的编号后缀
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var last = Context
|
|
|
|
|
|
.Queryable<QcScrapRecords>()
|
|
|
|
|
|
.Where(it => it.ScrapOrderNo.StartsWith(prefix + datePart))
|
|
|
|
|
|
.OrderByDescending(it => it.ScrapOrderNo)
|
|
|
|
|
|
.Select(it => it.ScrapOrderNo)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(last))
|
|
|
|
|
|
{
|
|
|
|
|
|
return baseNo + "001";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var suf = last.Substring((prefix + datePart).Length).TrimStart('-', '_');
|
|
|
|
|
|
if (int.TryParse(suf, out var n))
|
|
|
|
|
|
{
|
|
|
|
|
|
return baseNo + (n + 1).ToString("D3");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return baseNo + "001";
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
return baseNo + "001";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建报废单
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcScrapRecords CreateScrapOrder(QcScrapRecords parm)
|
|
|
|
|
|
{
|
2026-02-10 19:00:54 +08:00
|
|
|
|
try
|
2026-01-26 17:57:18 +08:00
|
|
|
|
{
|
2026-02-10 19:00:54 +08:00
|
|
|
|
QcScrapRecords newQcScrapRecords = parm;
|
|
|
|
|
|
var workorderInfo = Context
|
|
|
|
|
|
.Queryable<ProWorkorder>()
|
|
|
|
|
|
.Where(x => x.Workorder == parm.Workorder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
// 工单号创建,根据工单信息填充报废单的相关字段
|
|
|
|
|
|
if (workorderInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
newQcScrapRecords.ProductCode = workorderInfo.productionCode;
|
|
|
|
|
|
newQcScrapRecords.ProductName = workorderInfo.productionName;
|
|
|
|
|
|
newQcScrapRecords.LineCode = workorderInfo.RouteCode;
|
|
|
|
|
|
newQcScrapRecords.StoveCode = workorderInfo.StoveCode;
|
|
|
|
|
|
newQcScrapRecords.BatchNo = workorderInfo.FeedOrder;
|
|
|
|
|
|
newQcScrapRecords.MaterialCode = workorderInfo.MaterialCode;
|
|
|
|
|
|
newQcScrapRecords.MaterialName = workorderInfo.MaterialName;
|
|
|
|
|
|
// 如有领料记录,则绑定采购记录
|
|
|
|
|
|
var purchaseInfo = Context
|
|
|
|
|
|
.Queryable<MmRecordInbound>()
|
|
|
|
|
|
.Where(it => it.BatchNo == workorderInfo.FeedOrder)
|
|
|
|
|
|
.Where(it => it.TransactionType == "采购入库")
|
|
|
|
|
|
.Where(it => it.Remarks != "已撤销")
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (purchaseInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
newQcScrapRecords.SupplierCode = purchaseInfo.SupplierCode;
|
|
|
|
|
|
newQcScrapRecords.SupplierName = purchaseInfo.SupplierName;
|
|
|
|
|
|
newQcScrapRecords.StoveCode = purchaseInfo.StoveCode;
|
|
|
|
|
|
newQcScrapRecords.Unit = purchaseInfo.Unit;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 生成报废单号
|
|
|
|
|
|
newQcScrapRecords.ScrapOrderNo = GenerateScrapOrderNo();
|
|
|
|
|
|
|
|
|
|
|
|
// 设置状态为待审批
|
|
|
|
|
|
newQcScrapRecords.Status = "待审批";
|
|
|
|
|
|
newQcScrapRecords.ScrapType = "报废";
|
|
|
|
|
|
newQcScrapRecords.TenantId = 0;
|
|
|
|
|
|
newQcScrapRecords.Version = 1;
|
|
|
|
|
|
return Context.Insertable(newQcScrapRecords).ExecuteReturnEntity();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception(ex.Message);
|
2026-01-26 17:57:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建转用单
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcScrapRecords CreateTransferOrder(QcScrapRecords parm)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 验证工单号
|
|
|
|
|
|
if (string.IsNullOrEmpty(parm.Workorder))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("工单号不能为空");
|
|
|
|
|
|
}
|
2026-02-10 19:00:54 +08:00
|
|
|
|
QcScrapRecords newQcScrapRecords = parm;
|
|
|
|
|
|
var workorderInfo = Context
|
|
|
|
|
|
.Queryable<ProWorkorder>()
|
|
|
|
|
|
.Where(x => x.Workorder == parm.Workorder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
// 工单号创建,根据工单信息填充报废单的相关字段
|
|
|
|
|
|
if (workorderInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
newQcScrapRecords.ProductCode = workorderInfo.productionCode;
|
|
|
|
|
|
newQcScrapRecords.ProductName = workorderInfo.productionName;
|
|
|
|
|
|
newQcScrapRecords.LineCode = workorderInfo.RouteCode;
|
|
|
|
|
|
newQcScrapRecords.StoveCode = workorderInfo.StoveCode;
|
|
|
|
|
|
newQcScrapRecords.BatchNo = workorderInfo.FeedOrder;
|
|
|
|
|
|
newQcScrapRecords.MaterialCode = workorderInfo.MaterialCode;
|
|
|
|
|
|
newQcScrapRecords.MaterialName = workorderInfo.MaterialName;
|
|
|
|
|
|
// 如有领料记录,则绑定采购记录
|
|
|
|
|
|
var purchaseInfo = Context
|
|
|
|
|
|
.Queryable<MmRecordInbound>()
|
|
|
|
|
|
.Where(it => it.BatchNo == workorderInfo.FeedOrder)
|
|
|
|
|
|
.Where(it => it.TransactionType == "采购入库")
|
|
|
|
|
|
.Where(it => it.Remarks != "已撤销")
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (purchaseInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
newQcScrapRecords.SupplierCode = purchaseInfo.SupplierCode;
|
|
|
|
|
|
newQcScrapRecords.SupplierName = purchaseInfo.SupplierName;
|
|
|
|
|
|
newQcScrapRecords.StoveCode = purchaseInfo.StoveCode;
|
|
|
|
|
|
newQcScrapRecords.Unit = purchaseInfo.Unit;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-26 17:57:18 +08:00
|
|
|
|
|
2026-02-10 19:00:54 +08:00
|
|
|
|
// 生成单号
|
|
|
|
|
|
newQcScrapRecords.ScrapOrderNo = GenerateScrapOrderNo("ZY"); // ZY表示转用
|
2026-01-26 17:57:18 +08:00
|
|
|
|
|
2026-02-10 19:00:54 +08:00
|
|
|
|
// 设置状态为待审批,类型为转用
|
|
|
|
|
|
newQcScrapRecords.Status = "待审批";
|
|
|
|
|
|
newQcScrapRecords.ScrapType = "转用";
|
|
|
|
|
|
newQcScrapRecords.TenantId = 0;
|
|
|
|
|
|
newQcScrapRecords.Version = 1;
|
|
|
|
|
|
return Context.Insertable(newQcScrapRecords).ExecuteReturnEntity();
|
2026-01-26 17:57:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 审批报废记录
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">记录ID</param>
|
|
|
|
|
|
/// <param name="isApproved">是否批准</param>
|
|
|
|
|
|
/// <param name="approver">审批人</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public int ApproveScrapRecord(long id, bool isApproved, string approver)
|
|
|
|
|
|
{
|
|
|
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
|
|
|
|
UseTran2(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// 获取记录信息
|
|
|
|
|
|
var record = Context.Queryable<QcScrapRecords>().Where(x => x.Id == id).First();
|
|
|
|
|
|
|
|
|
|
|
|
if (record == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("记录不存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 只有待审批状态的记录才能被审批
|
|
|
|
|
|
if (record.Status != "待审批")
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("只有待审批状态的记录才能被审批");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新审批信息
|
|
|
|
|
|
var updateObj = new QcScrapRecords
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = id,
|
|
|
|
|
|
Status = isApproved ? "已批准" : "已拒绝",
|
|
|
|
|
|
ApprovalDate = DateTime.Now,
|
|
|
|
|
|
SupervisorName = approver,
|
2026-02-10 19:00:54 +08:00
|
|
|
|
UpdatedTime = DateTime.Now,
|
2026-01-26 17:57:18 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-02-10 19:00:54 +08:00
|
|
|
|
result = Context
|
|
|
|
|
|
.Updateable(updateObj)
|
|
|
|
|
|
.UpdateColumns(x => new
|
|
|
|
|
|
{
|
|
|
|
|
|
x.Status,
|
|
|
|
|
|
x.ApprovalDate,
|
|
|
|
|
|
x.SupervisorName,
|
|
|
|
|
|
x.UpdatedTime,
|
|
|
|
|
|
})
|
|
|
|
|
|
.ExecuteCommand();
|
2026-01-26 17:57:18 +08:00
|
|
|
|
|
|
|
|
|
|
if (isApproved)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 根据报废类型处理
|
|
|
|
|
|
if (record.ScrapType == "转用")
|
|
|
|
|
|
{
|
|
|
|
|
|
// 转用单批准:生成新工单(这里需要根据实际业务调整工单生成逻辑)
|
|
|
|
|
|
// 注意:需要确保工单服务的命名空间和方法名正确
|
|
|
|
|
|
// 示例:_proWorkorderService.GenerateWorkorder(record);
|
2026-02-10 19:00:54 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果有工单则工单报废数增加
|
|
|
|
|
|
if (!string.IsNullOrEmpty(record.Workorder))
|
|
|
|
|
|
{
|
|
|
|
|
|
var workorderInfo = Context
|
|
|
|
|
|
.Queryable<ProWorkorder>()
|
|
|
|
|
|
.Where(x => x.Workorder == record.Workorder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (workorderInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
workorderInfo.DefectNum += (int)record.ScrapQuantity;
|
|
|
|
|
|
Context
|
|
|
|
|
|
.Updateable(workorderInfo)
|
|
|
|
|
|
.UpdateColumns(x => new { x.DefectNum })
|
|
|
|
|
|
.ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 入报废库
|
|
|
|
|
|
InboundReceiptDto revokeRecepitDto = new()
|
|
|
|
|
|
{
|
|
|
|
|
|
ReceiptType = 1,
|
|
|
|
|
|
MaterialCode = record.ProductCode,
|
|
|
|
|
|
BatchNo = "000",
|
|
|
|
|
|
LocationCode = "ZYK001",
|
|
|
|
|
|
WarehouseCode = "WH005",
|
|
|
|
|
|
SupplierCode = record.SupplierCode,
|
|
|
|
|
|
StoveCode = record.StoveCode,
|
|
|
|
|
|
Workorder = record.Workorder,
|
|
|
|
|
|
WorkorderRaw = record.ScrapOrderNo,
|
|
|
|
|
|
Operator = approver,
|
|
|
|
|
|
Quantity = record.ScrapQuantity,
|
|
|
|
|
|
TransactionType = "转用入库",
|
|
|
|
|
|
Remarks = $"转用入库,转用单号:{record.ScrapOrderNo}",
|
|
|
|
|
|
};
|
|
|
|
|
|
MmInventoryService mmInventoryService = new();
|
|
|
|
|
|
string createReceiptresult = mmInventoryService.CreateInboundReceipt(
|
|
|
|
|
|
revokeRecepitDto
|
|
|
|
|
|
);
|
|
|
|
|
|
if (createReceiptresult != "ok")
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception(createReceiptresult);
|
|
|
|
|
|
}
|
2026-01-26 17:57:18 +08:00
|
|
|
|
}
|
2026-02-10 19:00:54 +08:00
|
|
|
|
else if (record.ScrapType == "报废")
|
2026-01-26 17:57:18 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 报废单批准:生成入库单到报废库(这里需要根据实际业务调整入库逻辑)
|
2026-02-10 19:00:54 +08:00
|
|
|
|
// 如果有工单则工单报废数增加
|
|
|
|
|
|
if (!string.IsNullOrEmpty(record.Workorder))
|
|
|
|
|
|
{
|
|
|
|
|
|
var workorderInfo = Context
|
|
|
|
|
|
.Queryable<ProWorkorder>()
|
|
|
|
|
|
.Where(x => x.Workorder == record.Workorder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (workorderInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
workorderInfo.DefectNum += (int)record.ScrapQuantity;
|
|
|
|
|
|
Context
|
|
|
|
|
|
.Updateable(workorderInfo)
|
|
|
|
|
|
.UpdateColumns(x => new { x.DefectNum })
|
|
|
|
|
|
.ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 调用入库单服务添加到报废库
|
|
|
|
|
|
InboundReceiptDto revokeRecepitDto = new()
|
|
|
|
|
|
{
|
|
|
|
|
|
ReceiptType = 1,
|
|
|
|
|
|
MaterialCode = record.ProductCode,
|
|
|
|
|
|
BatchNo = "000",
|
|
|
|
|
|
LocationCode = "BFK001",
|
|
|
|
|
|
WarehouseCode = "WH006",
|
|
|
|
|
|
SupplierCode = record.SupplierCode,
|
|
|
|
|
|
StoveCode = record.StoveCode,
|
|
|
|
|
|
Workorder = record.Workorder,
|
|
|
|
|
|
WorkorderRaw = record.ScrapOrderNo,
|
|
|
|
|
|
Operator = approver,
|
|
|
|
|
|
Quantity = record.ScrapQuantity,
|
|
|
|
|
|
TransactionType = "报废入库",
|
|
|
|
|
|
Remarks = $"报废入库,报废单号:{record.ScrapOrderNo}",
|
|
|
|
|
|
};
|
|
|
|
|
|
MmInventoryService mmInventoryService = new();
|
|
|
|
|
|
string createReceiptresult = mmInventoryService.CreateInboundReceipt(
|
|
|
|
|
|
revokeRecepitDto
|
|
|
|
|
|
);
|
|
|
|
|
|
if (createReceiptresult != "ok")
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception(createReceiptresult);
|
|
|
|
|
|
}
|
2026-01-26 17:57:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 撤销报废记录
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">记录ID</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public int RevokeScrapRecord(long id)
|
|
|
|
|
|
{
|
2026-02-10 19:00:54 +08:00
|
|
|
|
int result = 0;
|
|
|
|
|
|
UseTran2(() =>
|
2026-01-26 17:57:18 +08:00
|
|
|
|
{
|
2026-02-10 19:00:54 +08:00
|
|
|
|
// 获取记录信息
|
|
|
|
|
|
var record = Context.Queryable<QcScrapRecords>().Where(x => x.Id == id).First();
|
2026-01-26 17:57:18 +08:00
|
|
|
|
|
2026-02-10 19:00:54 +08:00
|
|
|
|
if (record == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("记录不存在");
|
|
|
|
|
|
}
|
2026-01-26 17:57:18 +08:00
|
|
|
|
|
2026-02-10 19:00:54 +08:00
|
|
|
|
// 只有待审批状态的记录才能被撤销
|
|
|
|
|
|
if (record.Status != "已批准")
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("只有已批准状态的记录才能被撤销");
|
|
|
|
|
|
}
|
|
|
|
|
|
// 撤销库存操作记录与工单不良数
|
|
|
|
|
|
var workorderInfo = Context
|
|
|
|
|
|
.Queryable<ProWorkorder>()
|
|
|
|
|
|
.Where(it => it.Workorder == record.Workorder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (workorderInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
workorderInfo.DefectNum -= (int)Math.Abs(record.ScrapQuantity);
|
|
|
|
|
|
Context
|
|
|
|
|
|
.Updateable(workorderInfo)
|
|
|
|
|
|
.UpdateColumns(it => new { it.DefectNum })
|
|
|
|
|
|
.ExecuteCommand();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MmInventoryService mmInventoryService = new();
|
|
|
|
|
|
int InBoundId = Context
|
|
|
|
|
|
.Queryable<MmRecordInbound>()
|
|
|
|
|
|
.Where(it => it.WorkorderRaw == record.ScrapOrderNo)
|
|
|
|
|
|
.Select(it => it.Id)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (InBoundId > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
mmInventoryService.RevokeReceipt(
|
|
|
|
|
|
new MmInventoryRevokeDto { Id = InBoundId, Type = 1 }
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 撤销:将状态改为待审批
|
|
|
|
|
|
var updateObj = new QcScrapRecords
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = id,
|
|
|
|
|
|
Status = "待审批",
|
|
|
|
|
|
UpdatedTime = DateTime.Now,
|
|
|
|
|
|
};
|
2026-01-26 17:57:18 +08:00
|
|
|
|
|
2026-02-10 19:00:54 +08:00
|
|
|
|
result = Context
|
|
|
|
|
|
.Updateable(updateObj)
|
|
|
|
|
|
.UpdateColumns(x => new { x.Status, x.UpdatedTime })
|
|
|
|
|
|
.ExecuteCommand();
|
|
|
|
|
|
});
|
|
|
|
|
|
return result;
|
2026-01-26 17:57:18 +08:00
|
|
|
|
}
|
2026-02-09 17:46:24 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据工单号查询不良品记录
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="workorder">工单号</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public PagedInfo<QcScrapRecordsDto> GetQcScrapRecordsByWorkorder(string workorder)
|
|
|
|
|
|
{
|
2026-02-10 19:00:54 +08:00
|
|
|
|
var queryDto = new QcScrapRecordsQueryDto { Workorder = workorder };
|
|
|
|
|
|
var result = Context
|
|
|
|
|
|
.Queryable<QcScrapRecords>()
|
|
|
|
|
|
.Where(x => x.Workorder == workorder)
|
|
|
|
|
|
.ToPage<QcScrapRecords, QcScrapRecordsDto>(queryDto);
|
|
|
|
|
|
return result;
|
2026-02-09 17:46:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据工单号填写报废单
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm">报废单数据</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcScrapRecords CreateScrapOrderByWorkorder(QcScrapRecords parm)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 验证工单号
|
|
|
|
|
|
if (string.IsNullOrEmpty(parm.Workorder))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("工单号不能为空");
|
|
|
|
|
|
}
|
|
|
|
|
|
// 调用现有的创建报废单方法
|
|
|
|
|
|
return CreateScrapOrder(parm);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据工单号填写转用单
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm">转用单数据</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcScrapRecords CreateTransferOrderByWorkorder(QcScrapRecords parm)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 验证工单号
|
|
|
|
|
|
if (string.IsNullOrEmpty(parm.Workorder))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("工单号不能为空");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 调用现有的创建转用单方法
|
|
|
|
|
|
return CreateTransferOrder(parm);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-20 10:44:52 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据工单号填写不良品单据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm">不良品单数据</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public QcScrapRecords CreateDefectOrderByWorkorder(QcScrapRecords parm)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 验证工单号
|
|
|
|
|
|
if (string.IsNullOrEmpty(parm.Workorder))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("工单号不能为空");
|
|
|
|
|
|
}
|
|
|
|
|
|
QcScrapRecords newQcScrapRecords = parm;
|
|
|
|
|
|
var workorderInfo = Context
|
|
|
|
|
|
.Queryable<ProWorkorder>()
|
|
|
|
|
|
.Where(x => x.Workorder == parm.Workorder)
|
|
|
|
|
|
.First();
|
|
|
|
|
|
|
|
|
|
|
|
// 单据不良数校验
|
|
|
|
|
|
if(parm.ScrapQuantity + workorderInfo.DefectNum > workorderInfo.PlanNum)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("不良数量总和大于计划数,请检查输入!");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (parm.ScrapQuantity < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("不良数量需要为正数!");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 工单号创建,根据工单信息填充报废单的相关字段
|
|
|
|
|
|
if (workorderInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
newQcScrapRecords.ProductCode = workorderInfo.productionCode;
|
|
|
|
|
|
newQcScrapRecords.ProductName = workorderInfo.productionName;
|
|
|
|
|
|
newQcScrapRecords.LineCode = workorderInfo.RouteCode;
|
|
|
|
|
|
newQcScrapRecords.StoveCode = workorderInfo.StoveCode;
|
|
|
|
|
|
newQcScrapRecords.BatchNo = workorderInfo.FeedOrder;
|
|
|
|
|
|
newQcScrapRecords.MaterialCode = workorderInfo.MaterialCode;
|
|
|
|
|
|
newQcScrapRecords.MaterialName = workorderInfo.MaterialName;
|
|
|
|
|
|
// 如有领料记录,则绑定采购记录
|
|
|
|
|
|
var purchaseInfo = Context
|
|
|
|
|
|
.Queryable<MmRecordInbound>()
|
|
|
|
|
|
.Where(it => it.BatchNo == workorderInfo.FeedOrder)
|
|
|
|
|
|
.Where(it => it.TransactionType == "采购入库")
|
|
|
|
|
|
.Where(it => it.Remarks != "已撤销")
|
|
|
|
|
|
.First();
|
|
|
|
|
|
if (purchaseInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
newQcScrapRecords.SupplierCode = purchaseInfo.SupplierCode;
|
|
|
|
|
|
newQcScrapRecords.SupplierName = purchaseInfo.SupplierName;
|
|
|
|
|
|
newQcScrapRecords.StoveCode = purchaseInfo.StoveCode;
|
|
|
|
|
|
newQcScrapRecords.Unit = purchaseInfo.Unit;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 生成单号
|
|
|
|
|
|
newQcScrapRecords.ScrapOrderNo = GenerateScrapOrderNo("BL"); // BL表示不良
|
|
|
|
|
|
|
|
|
|
|
|
// 设置状态为待审批,类型为转用
|
|
|
|
|
|
newQcScrapRecords.Status = "待审批";
|
|
|
|
|
|
newQcScrapRecords.ScrapType = "不良品";
|
|
|
|
|
|
newQcScrapRecords.TenantId = 0;
|
|
|
|
|
|
newQcScrapRecords.Version = 1;
|
|
|
|
|
|
return Context.Insertable(newQcScrapRecords).ExecuteReturnEntity();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-09 17:46:24 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据不良品记录ID撤销不良品记录
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">不良品记录ID</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public int RevokeScrapRecordById(long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 调用现有的撤销方法
|
|
|
|
|
|
return RevokeScrapRecord(id);
|
|
|
|
|
|
}
|
2026-02-20 10:44:52 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据不良记录进行审批
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parm"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public string ApproveDefectRecordById(DefectApproveDto parm)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
|
}
|
2026-01-22 17:25:17 +08:00
|
|
|
|
}
|
2026-02-10 19:00:54 +08:00
|
|
|
|
}
|