1243 lines
63 KiB
C#
1243 lines
63 KiB
C#
using JNPF;
|
||
using JNPF.Common.Core.Manager;
|
||
using JNPF.Common.Extension;
|
||
using JNPF.Common.Filter;
|
||
using JNPF.Common.Security;
|
||
using JNPF.DependencyInjection;
|
||
using JNPF.DynamicApiController;
|
||
using JNPF.Extras.CollectiveOAuth.Models;
|
||
using JNPF.Extras.CollectiveOAuth.Utils;
|
||
using JNPF.FriendlyException;
|
||
using JNPF.Logging;
|
||
using JNPF.Systems.Entitys.Permission;
|
||
using JNPF.Systems.Entitys.System;
|
||
using JNPF.Systems.Interfaces.System;
|
||
using JNPF.VisualDev;
|
||
using JNPF.VisualDev.Entitys.Dto.VisualDevModelData;
|
||
using JNPF.VisualDev.Interfaces;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Newtonsoft.Json;
|
||
using SqlSugar;
|
||
using Tnb.BasicData;
|
||
using Tnb.BasicData.Entities;
|
||
using Tnb.EquipMgr.Entities;
|
||
using Tnb.ProductionMgr.Entities;
|
||
using Tnb.ProductionMgr.Entities.Dto;
|
||
using Tnb.ProductionMgr.Entities.Dto.PrdManage;
|
||
using Tnb.ProductionMgr.Entities.Enums;
|
||
using Tnb.ProductionMgr.Interfaces;
|
||
using AuthResponse = JNPF.Extras.CollectiveOAuth.Models.AuthResponse;
|
||
using StringExtensions = JNPF.Common.Extension.StringExtensions;
|
||
|
||
namespace Tnb.ProductionMgr
|
||
{
|
||
/// <summary>
|
||
/// 生产计划管理
|
||
/// </summary>
|
||
[ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)]
|
||
[Route("api/[area]/[controller]/[action]")]
|
||
[OverideVisualDev(ModuleId)]
|
||
public class PrdMoService : IOverideVisualDevService, IPrdMoService, IDynamicApiController, ITransient
|
||
{
|
||
// private const string ModuleId = "25018860321301";
|
||
private const string ModuleId = "26900026924053";
|
||
private readonly ISqlSugarRepository<PrdMo> _repository;
|
||
private readonly IDataBaseManager _dataBaseManager;
|
||
private readonly IUserManager _userManager;
|
||
private readonly IDictionaryDataService _dictionaryDataService;
|
||
private readonly IRunService _runService;
|
||
private readonly IVisualDevService _visualDevService;
|
||
private readonly ISqlSugarClient _db;
|
||
|
||
public OverideVisualDevFunc OverideFuncs { get; } = new OverideVisualDevFunc();
|
||
|
||
public PrdMoService(
|
||
ISqlSugarRepository<PrdMo> repository,
|
||
IDataBaseManager dataBaseManager,
|
||
IUserManager userManager,
|
||
IDictionaryDataService dictionaryDataService,
|
||
IRunService runService,
|
||
IVisualDevService visualDevService
|
||
)
|
||
{
|
||
_repository = repository;
|
||
_dataBaseManager = dataBaseManager;
|
||
_userManager = userManager;
|
||
_dictionaryDataService = dictionaryDataService;
|
||
_runService = runService;
|
||
_visualDevService = visualDevService;
|
||
_db = _repository.AsSugarClient();
|
||
OverideFuncs.GetListAsync = GetList;
|
||
}
|
||
|
||
// private async Task<dynamic> GetList(VisualDevModelListQueryInput input)
|
||
// {
|
||
// var db = _repository.AsSugarClient();
|
||
// VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleId, true);
|
||
// var data = await _runService.GetListResult(templateEntity, input);
|
||
// if (data?.list?.Count > 0)
|
||
// {
|
||
// foreach (var row in data.list)
|
||
// {
|
||
// var dic = row.ToDictionary(x => x.Key, x => x.Value);
|
||
// var pkName = "material_id_id";
|
||
// if (dic.ContainsKey(pkName))
|
||
// {
|
||
// var materialId = dic[pkName]?.ToString();
|
||
// var material = await db.Queryable<BasMaterial>().FirstAsync(it => it.id == materialId);
|
||
// if (material != null)
|
||
// {
|
||
// row.Add("material_name", material.name);
|
||
// row.Add($"material_attribute", material.attribute);
|
||
// if (dic.ContainsKey("material_id"))
|
||
// {
|
||
// row["material_id"] = material.code + "/" + material.name;
|
||
// }
|
||
// }
|
||
//
|
||
// if (dic.ContainsKey("unit_id"))
|
||
// {
|
||
// string unitId = dic["unit_id"]?.ToString() ?? "";
|
||
// var unit = await db.Queryable<DictionaryDataEntity>().SingleAsync(x => x.Id == unitId);
|
||
// row["unit_id"] = unit?.FullName ?? "";
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// return data!;
|
||
// }
|
||
|
||
private async Task<dynamic> GetList(VisualDevModelListQueryInput input)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
Dictionary<string, string> queryJson = !string.IsNullOrEmpty(input.queryJson) ? Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(input.queryJson) : new Dictionary<string, string>();
|
||
string moCode = queryJson.ContainsKey("mo_code") ? queryJson["mo_code"].ToString() : "";
|
||
string moStatus = queryJson.ContainsKey("mo_status") ? queryJson["mo_status"].ToString() : "";
|
||
string combineMoCode = queryJson.ContainsKey("combine_mo_code") ? queryJson["combine_mo_code"].ToString() : "";
|
||
var result = await db.Queryable<PrdMo>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.LeftJoin<DictionaryTypeEntity>((a, b, c) => c.EnCode == DictConst.MeasurementUnit)
|
||
.LeftJoin<DictionaryDataEntity>((a, b, c, d) => c.Id == d.DictionaryTypeId && a.unit_id == d.Id)
|
||
.LeftJoin<DictionaryDataEntity>((a, b, c, d, e) => a.mo_status == e.Id)
|
||
.LeftJoin<DictionaryDataEntity>((a, b, c, d, e,f) => a.mo_type==f.Id)
|
||
.WhereIF(!string.IsNullOrEmpty(moCode), (a, b, c, d, e) => a.mo_code.Contains(moCode))
|
||
.WhereIF(!string.IsNullOrEmpty(combineMoCode),
|
||
(a, b, c, d, e) => a.combine_mo_code.Contains(combineMoCode))
|
||
.WhereIF(!string.IsNullOrEmpty(moStatus), (a, b, c, d, e) => a.mo_status == moStatus)
|
||
.Where(a=>SqlFunc.IsNullOrEmpty(a.parent_id))
|
||
.OrderByDescending(a=>a.create_time)
|
||
.Select((a, b, c, d, e,f) => new PrdMoListOuput
|
||
{
|
||
id = a.id,
|
||
mo_type = f.FullName,
|
||
mo_source = a.mo_source=="1" ? "ERP同步" : "新建/导入",
|
||
mo_code = a.mo_code,
|
||
plan_start_date = a.plan_start_date==null ? "" : a.plan_start_date.Value.ToString("yyyy-MM-dd"),
|
||
plan_end_date = a.plan_end_date==null ? "" : a.plan_end_date.Value.ToString("yyyy-MM-dd"),
|
||
material_id = b.code+"/"+b.name,
|
||
material_id_id = b.id,
|
||
plan_qty = a.plan_qty,
|
||
unit_id = d.FullName,
|
||
mo_status = e.FullName,
|
||
remark = a.remark,
|
||
children = SqlFunc.Subqueryable<PrdMo>()
|
||
.LeftJoin<BasMaterial>((aa, bb) => aa.material_id == bb.id)
|
||
.LeftJoin<DictionaryTypeEntity>((aa, bb, cc) => cc.EnCode == DictConst.MeasurementUnit)
|
||
.LeftJoin<DictionaryDataEntity>((aa, bb, cc, dd) => cc.Id == dd.DictionaryTypeId && aa.unit_id == dd.Id)
|
||
.LeftJoin<DictionaryDataEntity>((aa, bb, cc, dd, ee) => aa.mo_status == ee.Id)
|
||
.LeftJoin<DictionaryDataEntity>((aa, bb, cc, dd, ee,ff) => aa.mo_type==ff.Id)
|
||
.Where(aa=>aa.parent_id==a.id)
|
||
.ToList((aa,bb,cc,dd,ee,ff)=>new PrdMoListOuput
|
||
{
|
||
id = aa.id,
|
||
mo_type = ff.FullName,
|
||
mo_source = aa.mo_source=="1" ? "ERP同步" : "新建/导入",
|
||
mo_code = aa.mo_code,
|
||
plan_start_date = aa.plan_start_date==null ? "" : aa.plan_start_date.Value.ToString("yyyy-MM-dd"),
|
||
plan_end_date = aa.plan_end_date==null ? "" : aa.plan_end_date.Value.ToString("yyyy-MM-dd"),
|
||
material_id = bb.code+"/"+bb.name,
|
||
material_id_id = bb.id,
|
||
plan_qty = aa.plan_qty,
|
||
unit_id = dd.FullName,
|
||
mo_status = ee.FullName,
|
||
remark = aa.remark,
|
||
})
|
||
}).ToPagedListAsync(input.currentPage, int.MaxValue);
|
||
return PageResult<PrdMoListOuput>.SqlSugarPageResult(result);
|
||
}
|
||
|
||
|
||
#region Get
|
||
|
||
|
||
/// <summary>
|
||
/// 获取自建报废记录
|
||
/// </summary>
|
||
/// <param name="icmoCode"></param>
|
||
/// <returns></returns>
|
||
[HttpGet("{icmoCode}")]
|
||
public async Task<dynamic> GetReportRecord(string icmoCode)
|
||
{
|
||
var db = _repository.AsSugarClient();
|
||
var output = new PrdMoTaskDefectOutput();
|
||
//output.mo_task_code = icmoCode;
|
||
//var scrap = (await db.Queryable<PrdScrapped>().FirstAsync(it => it.icmo_code == icmoCode));
|
||
//output.items = new List<CategoryItem>();
|
||
//var categorys = await db.Queryable<PrdScrappedDefectiveCagetory>().Where(it => it.icmo_code == icmoCode).ToListAsync();
|
||
//foreach (var category in categorys)
|
||
//{
|
||
// var categoryItem = category.Adapt<SelfTestScrappedOutputItem>();
|
||
// categoryItem.items = new List<PrdScrappedDefectiveItem>();
|
||
// var items = await db.Queryable<PrdScrappedDefectiveItem>().Where(it => it.defective_cagetory_id == category.id).ToListAsync();
|
||
// categoryItem.items.AddRange(items);
|
||
// output.categoryItems.Add(categoryItem);
|
||
//}
|
||
return output;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Post
|
||
|
||
/// <summary>
|
||
/// 生产工单创建-生产工单下发
|
||
/// </summary>
|
||
/// <param name="input">生产工单下发输入参数</param>
|
||
/// <returns></returns>
|
||
[HttpPut]
|
||
public async Task<dynamic> WorkOrderIssue(MoCrInput input)
|
||
{
|
||
if (input is null)
|
||
{
|
||
throw new ArgumentNullException(nameof(input));
|
||
}
|
||
if (StringExtensions.IsNullOrWhiteSpace(input.Behavior))
|
||
{
|
||
throw new ArgumentException($"{nameof(input.Behavior)},not be null or empty");
|
||
}
|
||
|
||
var db = _repository.AsSugarClient();
|
||
//获取同组工单的Id,一起下发
|
||
var combineMoCodes = await db.Queryable<PrdMo>().Where(it => input.WorkOrderIds.Contains(it.id)).Select(it => it.combine_mo_code).ToListAsync();
|
||
if (combineMoCodes?.Count > 0)
|
||
{
|
||
var moIds = await db.Queryable<PrdMo>().Where(it => combineMoCodes.Contains(it.combine_mo_code) && !input.WorkOrderIds.Contains(it.id)).Select(it => it.id).ToListAsync();
|
||
input.WorkOrderIds = input.WorkOrderIds.Concat(moIds).ToList();
|
||
}
|
||
|
||
string getMoStatus(MoBehavior behavior)
|
||
{
|
||
string status = "";
|
||
switch (behavior)
|
||
{
|
||
case MoBehavior.Release:
|
||
status = DictConst.IssueId;
|
||
break;
|
||
case MoBehavior.Closed:
|
||
status = DictConst.MoCloseId;
|
||
break;
|
||
}
|
||
return status!;
|
||
}
|
||
var behavior = input.Behavior.ToEnum<MoBehavior>();
|
||
var status = getMoStatus(behavior);
|
||
var row = await db.Updateable<PrdMo>()
|
||
.SetColumns(it => new PrdMo { mo_status = status })
|
||
.Where(it => input.WorkOrderIds.Contains(it.id))
|
||
.ExecuteCommandAsync();
|
||
return (row > 0);
|
||
}
|
||
// /// <summary>
|
||
// /// 关联同组工单
|
||
// /// </summary>
|
||
// /// <param name="input">关联同组工单输入参数</param>
|
||
// /// <returns></returns>
|
||
// [HttpPost]
|
||
// public async Task<dynamic> RelevancySameGroupMo(MoCrInput input)
|
||
// {
|
||
// (bool executeRes, string errMsg) multi = (true, "");
|
||
// var list = await _repository.AsSugarClient().Queryable<PrdMo>()
|
||
// .InnerJoin<ToolMolds>((a, b) => a.material_id == b.material_id)
|
||
// .Where((a, b) => input.WorkOrderIds.Contains(a.id))
|
||
// .Select((a, b) => new
|
||
// {
|
||
// planDate = a.plan_start_date,
|
||
// mold_code = b.mold_code,
|
||
// }).ToListAsync();
|
||
// var planDateAll = true;
|
||
// var moldIdAll = true;
|
||
// if (list?.Count > 0)
|
||
// {
|
||
// var planDate = list.FirstOrDefault()?.planDate;
|
||
// var moldCode = list.FirstOrDefault()?.mold_code;
|
||
//
|
||
// planDateAll = list.Skip(1).All(x => x.planDate == planDate);
|
||
// moldIdAll = list.Skip(1).All(x => x.mold_code == moldCode);
|
||
// if (planDateAll && moldIdAll)
|
||
// {
|
||
// var groupId = SnowflakeIdHelper.NextId();
|
||
// multi.executeRes = await _repository.AsSugarClient().Updateable<PrdMo>()
|
||
// .SetColumns(c => new PrdMo { combine_mo_code = groupId })
|
||
// .Where(it => input.WorkOrderIds.Contains(it.id))
|
||
// .ExecuteCommandHasChangeAsync();
|
||
// }
|
||
// else
|
||
// {
|
||
// multi.executeRes = false;
|
||
// if (!planDateAll)
|
||
// {
|
||
// throw new AppFriendlyException("计划开始日期不一致", null);
|
||
// }
|
||
// if (!moldIdAll)
|
||
// {
|
||
// throw new AppFriendlyException("未关联到同一模具下", null);
|
||
// }
|
||
// }
|
||
// }
|
||
// return multi;
|
||
// }
|
||
|
||
/// <summary>
|
||
/// 关联同组工单
|
||
/// </summary>
|
||
/// <param name="input">关联同组工单输入参数</param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> RelevancySameGroupMo(MoCrInput input)
|
||
{
|
||
(bool executeRes, string errMsg) multi = (true, "");
|
||
var list = await _repository.AsSugarClient().Queryable<PrdMo>()
|
||
.LeftJoin<ToolMoldsMaterial>((a, b) => a.material_id == b.material_id)
|
||
.LeftJoin<ToolMolds>((a,b,c)=>b.mold_id==c.id)
|
||
.Where((a, b,c) => input.WorkOrderIds.Contains(a.id))
|
||
.Select((a, b,c) => new
|
||
{
|
||
planDate = a.plan_start_date,
|
||
mold_code = c.mold_code,
|
||
}).ToListAsync();
|
||
var planDateAll = true;
|
||
var moldIdAll = true;
|
||
if (list?.Count > 0)
|
||
{
|
||
var planDate = list.FirstOrDefault()?.planDate;
|
||
var moldCode = list.FirstOrDefault()?.mold_code;
|
||
|
||
planDateAll = list.All(x => x.planDate == planDate);
|
||
moldIdAll = moldCode != null && list.All(x => x.mold_code == moldCode);
|
||
if (planDateAll && moldIdAll)
|
||
{
|
||
var groupId = SnowflakeIdHelper.NextId();
|
||
multi.executeRes = await _repository.AsSugarClient().Updateable<PrdMo>()
|
||
.SetColumns(c => new PrdMo { combine_mo_code = groupId })
|
||
.Where(it => input.WorkOrderIds.Contains(it.id))
|
||
.ExecuteCommandHasChangeAsync();
|
||
}
|
||
else
|
||
{
|
||
multi.executeRes = false;
|
||
if (!planDateAll)
|
||
{
|
||
throw Oops.Bah("计划开始日期不一致");
|
||
}
|
||
if (!moldIdAll)
|
||
{
|
||
throw Oops.Bah("未关联到同一模具下");
|
||
}
|
||
}
|
||
}
|
||
return multi;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消关联
|
||
/// </summary>
|
||
/// <param name="input">取消关联输入参数</param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> CanelRelevancy(MoCrInput input)
|
||
{
|
||
return await _repository.AsSugarClient().Updateable<PrdMo>()
|
||
.SetColumns(c => new PrdMo { combine_mo_code = "" })
|
||
.Where(it => input.WorkOrderIds.Contains(it.id))
|
||
.ExecuteCommandHasChangeAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工单统计
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> GetPrdMoStatistics(PrdMoStatisticsInput input)
|
||
{
|
||
var result = await _db.Queryable<PrdMo>()
|
||
.LeftJoin<DictionaryDataEntity>((a, b) => a.mo_status == b.Id)
|
||
.LeftJoin<BasMaterial>((a, b, c) => a.material_id == c.id)
|
||
.WhereIF(!string.IsNullOrEmpty(input.mo_status), (a, b) => b.EnCode == input.mo_status)
|
||
// .OrderByDescending((a,b,c)=>a.reported_work_qty==null?0:a.reported_work_qty*100/a.plan_qty)
|
||
.Select((a, b, c) => new PrdMoStatisticsOutput
|
||
{
|
||
id = a.id,
|
||
mo_code = a.mo_code,
|
||
mo_status = b.FullName,
|
||
material_code = c.code,
|
||
material_name = c.name,
|
||
plan_qty = a.plan_qty,
|
||
scheduled_qty = a.scheduled_qty,
|
||
tobe_scheduled_qty = a.plan_qty - a.scheduled_qty,
|
||
reported_work_qty = a.reported_work_qty,
|
||
complete_rate = a.reported_work_qty==null?0:SqlFunc.ToDecimal(a.reported_work_qty*100)/SqlFunc.ToDecimal(a.plan_qty),
|
||
children = SqlFunc.Subqueryable<PrdMoTask>()
|
||
.LeftJoin<DictionaryDataEntity>((x,y)=>x.mo_task_status==y.EnCode && y.DictionaryTypeId==DictConst.PrdTaskStatusTypeId)
|
||
.Where(x=>x.mo_id==a.id && SqlFunc.IsNullOrEmpty(x.parent_id))
|
||
.OrderByDesc((x,y)=>x.create_time)
|
||
.ToList((x,y)=>new PrdMoStatisticsDetailOutput()
|
||
{
|
||
id = x.id,
|
||
mo_task_code = x.mo_task_code,
|
||
mo_task_status = y.FullName,
|
||
estimated_start_date = x.estimated_start_date==null ? "" : x.estimated_start_date.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
estimated_end_date = x.estimated_end_date==null ? "" : x.estimated_end_date.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
scheduled_qty = x.scheduled_qty,
|
||
reported_work_qty = x.reported_work_qty,
|
||
scrap_qty = x.scrap_qty,
|
||
}),
|
||
})
|
||
.MergeTable().OrderByDescending(a=>a.complete_rate)
|
||
.ToPagedListAsync(input.currentPage, input.pageSize);
|
||
|
||
return PageResult<PrdMoStatisticsOutput>.SqlSugarPageResult(result);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 正向工单追溯相关
|
||
|
||
/// <summary>
|
||
/// 工单追溯一级列表
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoFromOneList(PrdMoFromQueryInput input)
|
||
{
|
||
List<string> ids = new List<string>();
|
||
List<string> ids1 = new List<string>();
|
||
List<string> ids2 = new List<string>();
|
||
if (!string.IsNullOrEmpty(input.mo_task_code))
|
||
{
|
||
ids1 = await _db.Queryable<PrdMoTask>().Where(x => x.mo_task_code.Contains(x.mo_task_code)).Select(x => x.mo_id).ToListAsync();
|
||
ids = ids1;
|
||
}
|
||
if (!string.IsNullOrEmpty(input.barcode))
|
||
{
|
||
ids2 = await _db.Queryable<PrdReport>()
|
||
.LeftJoin<PrdMoTask>((a,b)=>a.mo_task_id==b.id)
|
||
.Where((a,b) => a.barcode.Contains(input.barcode)).Select((a,b) => b.mo_id).ToListAsync();
|
||
ids = ids2;
|
||
}
|
||
|
||
if (!string.IsNullOrEmpty(input.mo_task_code) && !string.IsNullOrEmpty(input.barcode))
|
||
{
|
||
ids = ids1.Intersect(ids2).ToList();
|
||
}
|
||
|
||
var result = await _db.Queryable<PrdMo>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.WhereIF(!string.IsNullOrEmpty(input.mo_code),(a,b)=>a.mo_code.Contains(input.mo_code))
|
||
.WhereIF(ids!=null && ids.Count>0,(a,b)=>ids.Contains(a.id))
|
||
.Select((a, b) =>
|
||
new PrdMoFromOneListOutput
|
||
{
|
||
id = a.id,
|
||
mo_code = a.mo_code,
|
||
material_id = a.material_id,
|
||
type = (a.mo_type==DictConst.PrdMoTypeZS || a.mo_type==DictConst.PrdMoTypeJC ) ? 1 : 2,
|
||
material_code = b.code,
|
||
material_name = b.name,
|
||
material_standard = b.material_standard,
|
||
act_start_date = a.act_start_date==null ? "" : a.act_start_date.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
act_end_date = a.act_end_date==null ? "" : a.act_end_date.Value.ToString("yyyy-MM-dd HH:mm:ss")
|
||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||
return PageResult<PrdMoFromOneListOutput>.SqlSugarPageResult(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工单追溯二级列表
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoFromTwoList(PrdMoFromTwoQueryInput prdMoFromTwoQueryInput)
|
||
{
|
||
string mo_id = prdMoFromTwoQueryInput.mo_id ?? "";
|
||
string mo_task_code = prdMoFromTwoQueryInput.mo_task_code ?? "";
|
||
string barcode = prdMoFromTwoQueryInput.barcode ?? "";
|
||
List<string> ids = new List<string>();
|
||
if (!string.IsNullOrEmpty(barcode))
|
||
{
|
||
ids = await _db.Queryable<PrdReport>().Where(x => x.barcode.Contains(barcode)).Select(x=>x.mo_task_id).ToListAsync();
|
||
}
|
||
|
||
PrdMo prdMo = await _repository.GetSingleAsync(x => x.id == mo_id);
|
||
if (prdMo.mo_type is DictConst.PrdMoTypeZS or DictConst.PrdMoTypeJC)
|
||
{
|
||
return await _db.Queryable<PrdMoTask>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.LeftJoin<OrganizeRelationEntity>((a,b,c)=>a.eqp_id==c.ObjectId && c.ObjectType=="Eqp")
|
||
.LeftJoin<OrganizeEntity>((a,b,c,d)=>c.OrganizeId==d.Id)
|
||
.LeftJoin<OrganizeEntity>((a,b,c,d,e)=>d.OrganizeIdTree.Contains(e.Id) && e.Category==DictConst.RegionCategoryWorkshopCode)
|
||
.LeftJoin<EqpEquipment>((a,b,c,d,e,f)=>a.eqp_id==f.id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_id),(a,b,c,d)=>a.mo_id==mo_id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_task_code),(a,b,c,d)=>a.mo_task_code==mo_task_code)
|
||
.WhereIF(ids!=null && ids.Count>0,(a,b,c,d)=>ids.Contains(a.id))
|
||
.Select((a, b, c, d,e,f) =>
|
||
new PrdMoFromTwoListOutput
|
||
{
|
||
id = a.id,
|
||
mo_task_code = a.mo_task_code,
|
||
material_id = a.material_id,
|
||
material_code = b.code,
|
||
material_name = b.name,
|
||
material_standard = b.material_standard,
|
||
act_start_date = a.act_start_date == null ? "" : a.act_start_date.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
act_end_date = a.act_end_date == null ? "" : a.act_end_date.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
workshop_name = e.FullName,
|
||
station_name = d.FullName,
|
||
equip_code = f.code
|
||
}).ToListAsync();
|
||
}
|
||
else
|
||
{
|
||
return await _db.Queryable<PrdMoTask>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.LeftJoin<OrganizeEntity>((a, b, c) => a.workline_id == c.Id)
|
||
.LeftJoin<BasMbom>((a, b, c, d) => a.bom_id == d.id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_id),(a,b,c,d)=>a.mo_id==mo_id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_task_code),(a,b,c,d)=>a.mo_task_code.Contains(mo_task_code))
|
||
.WhereIF(ids!=null && ids.Count>0,(a,b,c,d)=>ids.Contains(a.id))
|
||
.Select((a, b, c, d) =>
|
||
new PrdMoFromTwoListOutput
|
||
{
|
||
id = a.id,
|
||
mo_task_code = a.mo_task_code,
|
||
material_id = a.material_id,
|
||
material_code = b.code,
|
||
material_name = b.name,
|
||
material_standard = b.material_standard,
|
||
act_start_date = a.act_start_date == null ? "" : a.act_start_date.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
act_end_date = a.act_end_date == null ? "" : a.act_end_date.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
workline_name = c.FullName,
|
||
mbom_version = d.version
|
||
}).ToListAsync();
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工单追溯三级级列表
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoFromThreeList(PrdMoFromThreeQueryInput prdMoFromThreeQueryInput)
|
||
{
|
||
string mo_task_id = prdMoFromThreeQueryInput.mo_task_id ?? "";
|
||
string mo_task_code = prdMoFromThreeQueryInput.mo_task_code ?? "";
|
||
string barcode = prdMoFromThreeQueryInput.barcode ?? "";
|
||
List<string> ids = new List<string>();
|
||
if (!string.IsNullOrEmpty(barcode))
|
||
{
|
||
ids = await _db.Queryable<PrdReport>().Where(x => x.barcode.Contains(barcode)).Select(x=>x.mo_task_id).ToListAsync();
|
||
}
|
||
|
||
PrdMoTask prdMoTask = await _db.Queryable<PrdMoTask>().SingleAsync(x => x.id == mo_task_id);
|
||
List<BasProcessStation> processStations = await _db.Queryable<BasProcessStation>().Where(x=>x.process_id==prdMoTask.process_id).ToListAsync();
|
||
List<string> orgIds = processStations.Select(x => x.id).ToList();
|
||
List<OrganizeEntity> orgs = await _db.Queryable<OrganizeEntity>().Where(x=>x.Category==DictConst.RegionCategoryStationCode && x.DeleteMark==null).ToListAsync();
|
||
return await _db.Queryable<PrdMoTask>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.LeftJoin<BasProcess>((a,b,c)=>a.process_id==c.id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_task_id),(a,b,c)=>a.id==mo_task_id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_task_code),(a,b,c)=>a.mo_task_code.Contains(mo_task_code))
|
||
.WhereIF(ids!=null && ids.Count>0,(a,b,c)=>ids.Contains(a.id))
|
||
.Select((a, b, c) =>
|
||
new PrdMoFromThreeListOutput
|
||
{
|
||
id = a.id,
|
||
mo_task_code = a.mo_task_code,
|
||
material_id = a.material_id,
|
||
material_code = b.code,
|
||
workline_id = a.workline_id,
|
||
material_name = b.name,
|
||
process_id = a.process_id,
|
||
process_name = c.process_name,
|
||
}).Mapper(x =>
|
||
{
|
||
List<string> orgId1 = orgs.Where(y => y.OrganizeIdTree.Contains(x.workline_id)).Select(y=>y.Id).ToList();
|
||
string station_id = orgIds.Intersect(orgId1)?.FirstOrDefault();
|
||
if (!string.IsNullOrEmpty(station_id))
|
||
{
|
||
x.station_name = orgs.FirstOrDefault(y => y.Id == station_id)?.FullName;
|
||
}
|
||
}).ToListAsync();
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工单追溯人列表
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoFromManList(PrdMoFromTabQueryInput prdMoFromTabQueryInput)
|
||
{
|
||
string mo_task_id = prdMoFromTabQueryInput.mo_task_id ?? "";
|
||
string barcode = prdMoFromTabQueryInput.barcode ?? "";
|
||
List<string> ids = new List<string>();
|
||
if (!string.IsNullOrEmpty(barcode))
|
||
{
|
||
ids = await _db.Queryable<PrdReport>().Where(x => x.barcode.Contains(barcode)).Select(x=>x.mo_task_id).ToListAsync();
|
||
}
|
||
|
||
return await _db.Queryable<PrdReport>()
|
||
.LeftJoin<UserEntity>((a, b) => a.create_id == b.Id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_task_id), (a, b) => a.mo_task_id == mo_task_id)
|
||
// .WhereIF(ids!=null && ids.Count>0,(a,b)=>ids.Contains(a.mo_task_id))
|
||
.WhereIF(!string.IsNullOrEmpty(barcode),(a,b)=>a.barcode.Contains(barcode))
|
||
.GroupBy((a,b)=>new {a.create_id,employee_name = b.RealName})
|
||
.Select((a, b) => new PrdMoFromManListOutput()
|
||
{
|
||
// id = a.id,
|
||
employee_name = b.RealName,
|
||
start_time = SqlFunc.AggregateMin(a.create_time),
|
||
end_time = SqlFunc.AggregateMax(a.create_time)
|
||
}).Mapper(x =>
|
||
{
|
||
x.work_time = (x.start_time == null ? "" : x.start_time.Value.ToString("yyyy-MM-dd HH:mm:ss")) + "~" + (x.end_time == null ? "" : x.end_time.Value.ToString("yyyy-MM-dd HH:mm:ss"));
|
||
})
|
||
.ToListAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工单追溯机列表
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoFromEquipList(PrdMoFromTabQueryInput prdMoFromTabQueryInput)
|
||
{
|
||
string mo_task_id = prdMoFromTabQueryInput.mo_task_id ?? "";
|
||
string barcode = prdMoFromTabQueryInput.barcode ?? "";
|
||
List<string> ids = new List<string>();
|
||
if (!string.IsNullOrEmpty(barcode))
|
||
{
|
||
ids = await _db.Queryable<PrdReport>().Where(x => x.barcode.Contains(barcode)).Select(x=>x.mo_task_id).ToListAsync();
|
||
}
|
||
|
||
return await _db.Queryable<PrdMoTask>()
|
||
.LeftJoin<EqpEquipment>((a, b) => a.eqp_id == b.id)
|
||
.LeftJoin<ToolMolds>((a,b,c)=>a.mold_id==c.id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_task_id), (a, b) => a.id == mo_task_id)
|
||
.WhereIF(ids!=null && ids.Count>0,(a,b)=>ids.Contains(a.id))
|
||
.Select((a, b,c) => new PrdMoFromEquipListOutput()
|
||
{
|
||
equip_code = b.code,
|
||
mold_code = b.code,
|
||
}).ToListAsync();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工单追溯料列表
|
||
/// </summary>
|
||
/// <param name="input"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoFromMaterialList(PrdMoFromTabQueryInput prdMoFromTabQueryInput)
|
||
{
|
||
string mo_task_id = prdMoFromTabQueryInput.mo_task_id ?? "";
|
||
string barcode = prdMoFromTabQueryInput.barcode ?? "";
|
||
List<string> ids = new List<string>();
|
||
if (!string.IsNullOrEmpty(barcode))
|
||
{
|
||
ids = await _db.Queryable<PrdReport>().Where(x => x.barcode.Contains(barcode)).Select(x=>x.mo_task_id).ToListAsync();
|
||
}
|
||
PrdMoTask prdMoTask = await _db.Queryable<PrdMoTask>().SingleAsync(x => x.id == mo_task_id);
|
||
PrdMo prdMo = await _db.Queryable<PrdMo>().SingleAsync(x => x.id == prdMoTask.mo_id);
|
||
/*
|
||
* 注塑投料记录 1产出物料二维码为精确搜索
|
||
* 2 不填产出物料二维码 则投入物料列表不计算批次等
|
||
* 3 物料二维码为精确搜索时 按照先进先出的规则计算投入物料
|
||
* 4 组装包装可投入物料组成 1)直接从生产线上流转下来的物料 2)投入的物料
|
||
*/
|
||
if (string.IsNullOrEmpty(barcode))
|
||
{
|
||
if (prdMoTask.schedule_type == 1)
|
||
{
|
||
return await _db.Queryable<BasEbomH>()
|
||
.LeftJoin<BasEbomD>((a,b)=>a.id==b.ebom_id)
|
||
.LeftJoin<BasMaterial>((a,b,c)=>b.material_id==c.id)
|
||
.Where((a,b,c)=>a.id==prdMoTask.ebom_id)
|
||
.Select((a,b,c)=>new PrdMoFromMaterialListOutput()
|
||
{
|
||
material_code = c.code,
|
||
material_name = c.name,
|
||
}).ToListAsync();
|
||
}
|
||
else
|
||
{
|
||
return await _db.Queryable<BasMbomInput>()
|
||
.LeftJoin<BasMaterial>((a,b)=>a.material_id==b.id)
|
||
.Where((a,b)=>a.mbom_id==prdMoTask.bom_id)
|
||
.Select((a,b)=>new PrdMoFromMaterialListOutput()
|
||
{
|
||
material_code = b.code,
|
||
material_name = b.name,
|
||
}).ToListAsync();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
PrdReport prdReport = await _db.Queryable<PrdReport>().Where(x => x.barcode == barcode).FirstAsync();
|
||
List<PrdReport> prdReports = await _db.Queryable<PrdReport>().Where(x=>x.create_time<=prdReport.create_time && x.barcode!=barcode && x.mo_task_id==mo_task_id).ToListAsync();
|
||
int? beforeReportNum = prdReports.Sum(x => x.reported_qty);
|
||
List<string> prdFeedingIds = new List<string>();
|
||
if (prdMoTask.schedule_type == 1)
|
||
{
|
||
BasEbomH basEbomH = await _db.Queryable<BasEbomH>().SingleAsync(x => x.id == prdMoTask.ebom_id);
|
||
List<BasEbomD> basEbomDs = await _db.Queryable<BasEbomD>().Where(x => x.ebom_id == prdMoTask.ebom_id).ToListAsync();
|
||
|
||
foreach (var item in basEbomDs)
|
||
{
|
||
decimal? num1 = beforeReportNum / basEbomH.quantity * item.quantity;
|
||
List<PrdFeedingD> prdFeedingDs = await _db.Queryable<PrdFeedingD>()
|
||
.LeftJoin<PrdFeedingH>((a, b) => a.feeding_id == b.id)
|
||
.Where((a, b) => a.material_id == item.material_id && b.mo_task_id == mo_task_id)
|
||
.OrderBy((a,b)=>b.create_time)
|
||
.Select((a, b) => a).ToListAsync();
|
||
decimal sum1 = 0;
|
||
decimal sum2 = 0;
|
||
foreach (var prdFeedingD in prdFeedingDs)
|
||
{
|
||
if (sum1 <= num1)
|
||
{
|
||
sum1 += prdFeedingD.num;
|
||
}
|
||
else
|
||
{
|
||
decimal? num2 = prdReport.reported_qty / basEbomH.quantity * item.quantity;
|
||
if (sum2 <= num2)
|
||
{
|
||
prdFeedingIds.Add(item.id);
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return await _db.Queryable<PrdFeedingD>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.LeftJoin<PrdMaterialReceiptD>((a, b, c) => a.material_receipt_detail_id == c.id)
|
||
.LeftJoin<BasSupplier>((a, b, c, d) => c.supplier_id == d.id)
|
||
.LeftJoin<PrdFeedingH>((a, b, c, d, e) => a.feeding_id == e.id)
|
||
.WhereIF(prdFeedingIds != null && prdFeedingIds.Count > 0, (a, b, c, d, e) => prdFeedingIds.Contains(a.id))
|
||
.Select((a, b, c, d, e) => new PrdMoFromMaterialListOutput()
|
||
{
|
||
material_code = b.code,
|
||
material_name = b.name,
|
||
batch = a.batch,
|
||
supplier_name = d.supplier_name,
|
||
check_conclusion = c.check_conclusion,
|
||
instock_time = c.instock_time.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
feeding_time = e.create_time == null ? "" : e.create_time.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
}).ToListAsync();
|
||
|
||
}
|
||
else
|
||
{
|
||
List<BasMbomInput> basMbomInputs = await _db.Queryable<BasMbomInput>().Where(x=>x.mbom_process_id==prdMoTask.mbom_process_id).ToListAsync();
|
||
BasMbom basMbom = await _db.Queryable<BasMbom>().SingleAsync(x => x.id == prdMoTask.bom_id);
|
||
BasMbomProcess basMbomProcess = await _db.Queryable<BasMbomProcess>().SingleAsync(x => x.id == prdMoTask.mbom_process_id);
|
||
List<string> lastPrdReportIds = new List<string>();
|
||
foreach (var item in basMbomInputs)
|
||
{
|
||
BasMbomOutput basMbomOutput = await _db.Queryable<BasMbomOutput>().Where(x=>x.mbom_process_id==basMbomProcess.id && x.material_id==prdMoTask.material_id).FirstAsync();
|
||
if (basMbomOutput == null) break;
|
||
decimal? num1 = beforeReportNum / Convert.ToDecimal(basMbomOutput.num) * item.num;
|
||
List<PrdFeedingD> prdFeedingDs = await _db.Queryable<PrdFeedingD>()
|
||
.LeftJoin<PrdFeedingH>((a, b) => a.feeding_id == b.id)
|
||
.Where((a, b) => a.material_id == item.material_id && b.mo_task_id == mo_task_id)
|
||
.OrderBy((a,b)=>b.create_time)
|
||
.Select((a, b) => a).ToListAsync();
|
||
|
||
if (prdFeedingDs == null || prdFeedingDs.Count <= 0)
|
||
{
|
||
if (string.IsNullOrEmpty(basMbomProcess.last_process_no)) continue;
|
||
|
||
List<BasMbomProcess> lastBasMbomProcesses = await _db.Queryable<BasMbomProcess>().Where(x=>x.no==basMbomProcess.last_process_no && x.mbom_id==prdMoTask.bom_id).ToListAsync();
|
||
foreach (var lastBasMbomProcess in lastBasMbomProcesses)
|
||
{
|
||
List<PrdReport> lastPrdReports = await _db.Queryable<PrdReport>()
|
||
.Where(x=>x.mbom_process_id==lastBasMbomProcess.id && x.material_id==item.material_id)
|
||
.OrderBy(x=>x.create_time)
|
||
.ToListAsync();
|
||
if (lastPrdReports == null || lastPrdReports.Count <= 0) continue;
|
||
|
||
PrdMoTask lastPrdMoTask = await _db.Queryable<PrdMoTask>().FirstAsync(x=>x.mo_id==prdMo.id && x.mbom_process_id==lastBasMbomProcess.id);
|
||
|
||
decimal sum1 = 0;
|
||
decimal sum2 = 0;
|
||
foreach (var lastPrdReport in lastPrdReports)
|
||
{
|
||
if (sum1 <= num1)
|
||
{
|
||
sum1 += lastPrdReport.reported_qty ?? 0;
|
||
}
|
||
else
|
||
{
|
||
decimal? num2 = lastPrdReport.reported_qty / Convert.ToDecimal(basMbomOutput.num) * item.num;
|
||
if (sum2 <= num2)
|
||
{
|
||
lastPrdReportIds.Add(lastPrdReport.id);
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
decimal sum1 = 0;
|
||
decimal sum2 = 0;
|
||
foreach (var prdFeedingD in prdFeedingDs)
|
||
{
|
||
if (sum1 <= num1)
|
||
{
|
||
sum1 += prdFeedingD.num;
|
||
}
|
||
else
|
||
{
|
||
decimal? num2 = prdReport.reported_qty / Convert.ToDecimal(basMbomOutput.num) * item.num;
|
||
if (sum2 <= num2)
|
||
{
|
||
prdFeedingIds.Add(item.id);
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
var queryable1 = _db.Queryable<PrdFeedingD>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.LeftJoin<PrdMaterialReceiptD>((a, b, c) => a.material_receipt_detail_id == c.id)
|
||
.LeftJoin<BasSupplier>((a, b, c, d) => c.supplier_id == d.id)
|
||
.LeftJoin<PrdFeedingH>((a, b, c, d, e) => a.feeding_id == e.id)
|
||
.WhereIF(!string.IsNullOrEmpty(mo_task_id), (a, b, c, d, e) => e.mo_task_id == mo_task_id)
|
||
.WhereIF(prdFeedingIds != null && prdFeedingIds.Count > 0, (a, b, c, d, e) => prdFeedingIds.Contains(a.id))
|
||
.Select((a, b, c, d, e) => new PrdMoFromMaterialListOutput()
|
||
{
|
||
material_code = b.code,
|
||
material_name = b.name,
|
||
batch = a.batch,
|
||
supplier_name = d.supplier_name,
|
||
check_conclusion = c.check_conclusion,
|
||
instock_time = c.instock_time.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
feeding_time = e.create_time == null ? "" : e.create_time.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
});
|
||
|
||
if (lastPrdReportIds != null && lastPrdReportIds.Count > 0)
|
||
{
|
||
var queryable2 = _db.Queryable<PrdReport>()
|
||
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||
.Where((a, b) => lastPrdReportIds.Contains(a.id))
|
||
.Select((a, b) => new PrdMoFromMaterialListOutput()
|
||
{
|
||
material_code = b.code,
|
||
material_name = b.name,
|
||
batch = a.batch,
|
||
supplier_name = "自制"
|
||
});
|
||
|
||
return await _db.UnionAll(queryable1, queryable2).ToListAsync();
|
||
}
|
||
else
|
||
{
|
||
return await queryable1.ToListAsync();
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 反向工单追溯相关
|
||
|
||
/// <summary>
|
||
/// 物料反向追溯物料信息
|
||
/// </summary>
|
||
/// <param name="dic"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoReverseFromMaterialInfo(PrdMoReverseFromQueryInput prdMoReverseFromQueryInput)
|
||
{
|
||
string barcode = prdMoReverseFromQueryInput.barcode ?? "";
|
||
string domain = (App.HttpContext.Request.IsHttps ? "https://" : "http://") + App.HttpContext.Request.Host;
|
||
Dictionary<string, object> header = new Dictionary<string, object>()
|
||
{
|
||
["Authorization"] = App.HttpContext.Request.Headers["Authorization"]
|
||
};
|
||
Dictionary<string, object> postData = new Dictionary<string, object>()
|
||
{
|
||
["org_id"] = _userManager.GetUserInfo().Result.organizeId,
|
||
["barcode"] = new List<string>() { barcode },
|
||
["currentPage"] = 1,
|
||
["pageSize"] = int.MaxValue,
|
||
};
|
||
var sendResult = HttpUtils.RequestPost(domain + WebApiConst.MES_FETCH_IN_OUT_STOCK_INFO_BY_BAR_CODE,JsonConvert.SerializeObject(postData),header);
|
||
Log.Information(sendResult);
|
||
|
||
AuthResponse authResponse = JsonConvert.DeserializeObject<AuthResponse>(sendResult);
|
||
if (authResponse.code != 200)
|
||
{
|
||
throw Oops.Bah(authResponse.msg);
|
||
}
|
||
else
|
||
{
|
||
PageResult<PrdMoReverseFromMaterialoutput> output = JsonConvert.DeserializeObject<PageResult<PrdMoReverseFromMaterialoutput>>(authResponse.data.ToString(),new Tnb.Common.Utils.DateTimeJsonConverter());
|
||
if (output.list != null && output.list.Count > 0)
|
||
{
|
||
BasMaterial basMaterial = await _db.Queryable<BasMaterial>().SingleAsync(x=>x.id==output.list[0].material_id);
|
||
BasSupplier basSupplier = await _db.Queryable<BasSupplier>().SingleAsync(x=>x.id==output.list[0].supplier_id);
|
||
DictionaryDataEntity unit = await _db.Queryable<DictionaryTypeEntity>()
|
||
.LeftJoin<DictionaryDataEntity>((a,b)=>a.Id==b.DictionaryTypeId)
|
||
.Where((a,b)=>a.EnCode==DictConst.MeasurementUnit && b.EnCode==output.list[0].unit_id)
|
||
.Select((a,b)=>b)
|
||
.FirstAsync();
|
||
output.list[0].feeding_num = await _db.Queryable<PrdMaterialReceiptD>()
|
||
.LeftJoin<PrdFeedingD>((a, b) => a.id == b.material_receipt_detail_id)
|
||
.Where((a, b) => a.barcode == barcode).SumAsync((a, b) => b.num);
|
||
output.list[0].material_name = basMaterial.name;
|
||
output.list[0].material_standard = basMaterial.material_standard;
|
||
output.list[0].supplier_name = basSupplier?.supplier_name ?? "";
|
||
output.list[0].unit_name = unit?.FullName ?? "";
|
||
|
||
return output.list[0];
|
||
}
|
||
}
|
||
|
||
return Array.Empty<string>();
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 物料反向追溯投料信息
|
||
/// </summary>
|
||
/// <param name="dic"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoReverseFromFeedingInfo(PrdMoReverseFromQueryInput prdMoReverseFromQueryInput)
|
||
{
|
||
string barcode = prdMoReverseFromQueryInput.barcode ?? "";
|
||
List<string> ids = await _db.Queryable<PrdMaterialReceiptD>()
|
||
.LeftJoin<PrdFeedingD>((a, b) => a.id == b.material_receipt_detail_id)
|
||
.LeftJoin<PrdFeedingH>((a, b, c) => b.feeding_id == c.id)
|
||
.Where(a => a.barcode == barcode)
|
||
.Select((a, b, c) => c.mo_task_id).ToListAsync();
|
||
|
||
var result = await _db.Queryable<PrdMoTask>()
|
||
.LeftJoin<PrdMo>((a, b) => a.mo_id == b.id)
|
||
.LeftJoin<BasMaterial>((a, b, c) => a.material_id == c.id)
|
||
.Where((a, b, c) => ids.Contains(a.id))
|
||
.Select((a, b, c) => new PrdMoReverseFromFeedingOutput
|
||
{
|
||
mo_task_id = a.id,
|
||
mo_task_code = a.mo_task_code,
|
||
mo_code = b.mo_code,
|
||
material_code = c.code,
|
||
material_name = c.name,
|
||
material_standard = c.material_standard,
|
||
children = SqlFunc.Subqueryable<PrdFeedingD>()
|
||
.LeftJoin<PrdFeedingH>((x, y) => x.feeding_id == y.id)
|
||
.LeftJoin<UserEntity>((x, y, z) => y.create_id == z.Id)
|
||
.LeftJoin<OrganizeEntity>((x, y, z, org) => y.station_id == org.Id)
|
||
.LeftJoin<BasProcess>((x, y, z, org, process) => y.process_id == process.id)
|
||
.LeftJoin<PrdMaterialReceiptD>((x, y, z, org, process, mp) =>
|
||
x.material_receipt_detail_id == mp.id)
|
||
.Where((x, y, z) => y.mo_task_id == a.id).ToList((x, y, z, org, process, mp) =>
|
||
new PrdMoReverseFromFeedingDetailOutput
|
||
{
|
||
feeding_detail_id = x.id,
|
||
feeding_time = y.create_time == null
|
||
? ""
|
||
: y.create_time.Value.ToString("yyyy-MM-dd HH:mm:ss"),
|
||
num = x.num,
|
||
check_conclusion = mp.check_conclusion,
|
||
feeding_name = z.RealName,
|
||
station_name = org.FullName,
|
||
process_name = process.process_name
|
||
}),
|
||
}).ToListAsync();
|
||
return result;
|
||
// return PageResult<PrdMoReverseFromFeedingOutput>.SqlSugarPageResult(result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 物料反向追溯产出信息
|
||
/// </summary>
|
||
/// <param name="dic"></param>
|
||
/// <returns></returns>
|
||
[HttpPost]
|
||
public async Task<dynamic> PrdMoReverseFromOutInfo(PrdMoReverseFromOutInfoQueryInput prdMoReverseFromOutInfoQueryInput)
|
||
{
|
||
string feeding_detail_id = prdMoReverseFromOutInfoQueryInput.feeding_detail_id ?? "";
|
||
PrdFeedingD prdFeedingD = await _db.Queryable<PrdFeedingD>().FirstAsync(x => x.id == feeding_detail_id);
|
||
if(prdFeedingD.use_num<=0) return Array.Empty<string>();
|
||
PrdFeedingH prdFeedingH = await _db.Queryable<PrdFeedingH>().FirstAsync(x => x.id == prdFeedingD.feeding_id);
|
||
PrdMoTask prdMoTask = await _db.Queryable<PrdMoTask>().FirstAsync(x => x.id == prdFeedingH.mo_task_id);
|
||
List<PrdFeedingD> prdFeedingDs = await _db.Queryable<PrdFeedingD>()
|
||
.LeftJoin<PrdFeedingH>((a, b) => a.feeding_id == b.id)
|
||
.Where((a, b) => a.material_id == prdFeedingD.material_id && b.mo_task_id == prdFeedingH.mo_task_id && b.create_time<=prdFeedingH.create_time && a.id!=prdFeedingD.id)
|
||
.Select((a, b) => a).ToListAsync();
|
||
decimal beforeIn = prdFeedingDs.Sum(x => x.num);
|
||
List<string> reportIds = new List<string>();
|
||
if (prdMoTask.schedule_type == 1)
|
||
{
|
||
BasEbomH basEbomH = await _db.Queryable<BasEbomH>().SingleAsync(x => x.id == prdMoTask.ebom_id);
|
||
List<BasEbomD> basEbomDs = await _db.Queryable<BasEbomD>().Where(x => x.ebom_id == prdMoTask.ebom_id).ToListAsync();
|
||
BasEbomD basEbomD = basEbomDs.Where(x => x.material_id == prdFeedingD.material_id).FirstOrDefault();
|
||
if (basEbomD != null)
|
||
{
|
||
List<PrdReport> prdReports = await _db.Queryable<PrdReport>().Where(x => x.mo_task_id == prdMoTask.id).OrderBy(x=>x.create_time).ToListAsync();
|
||
if (prdReports != null && prdReports.Count > 0)
|
||
{
|
||
bool flag = true;
|
||
decimal residueNeed = 0;
|
||
foreach (var prdReport in prdReports)
|
||
{
|
||
var needNum = (prdReport.reported_qty ?? 0) / basEbomH.quantity * basEbomD.quantity;
|
||
if (beforeIn - needNum >= 0)
|
||
{
|
||
beforeIn -= needNum;
|
||
}
|
||
else
|
||
{
|
||
if (flag)
|
||
{
|
||
if (prdFeedingD.num > needNum - beforeIn)
|
||
{
|
||
residueNeed = prdFeedingD.num - (needNum - beforeIn);
|
||
reportIds.Add(prdReport.id);
|
||
}
|
||
else
|
||
{
|
||
reportIds.Add(prdReport.id);
|
||
break;
|
||
}
|
||
|
||
flag = false;
|
||
continue;
|
||
|
||
}
|
||
|
||
if (residueNeed - needNum > 0)
|
||
{
|
||
residueNeed -= needNum;
|
||
reportIds.Add(prdReport.id);
|
||
}else
|
||
{
|
||
reportIds.Add(prdReport.id);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Array.Empty<string>();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Array.Empty<string>();
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
List<PrdReport> prdReports = await _db.Queryable<PrdMoTask>()
|
||
.LeftJoin<BasMbomProcess>((a, b) => a.mbom_process_id == b.id)
|
||
.LeftJoin<PrdReport>((a, b, c) => a.id == c.mo_task_id)
|
||
.Where((a, b, c) => a.mo_id == prdMoTask.mo_id && b.next_process_no == null)
|
||
.OrderBy((a,b,c)=>c.create_time)
|
||
.Select((a, b, c) => c).ToListAsync();
|
||
|
||
if (prdReports != null && prdReports.Count > 0)
|
||
{
|
||
List<string> mbomProcesssIds = new List<string>(){prdMoTask.mbom_process_id};
|
||
BasMbomProcess startMbomProcess = await _db.Queryable<BasMbomProcess>().Where(x=>x.id==prdMoTask.mbom_process_id).FirstAsync();
|
||
List<BasMbomProcess> allMbomProcesses = await _db.Queryable<BasMbomProcess>().Where(x=>x.mbom_id==prdMoTask.bom_id).ToListAsync();
|
||
string startNo = startMbomProcess.next_process_no;
|
||
if (!string.IsNullOrEmpty(startNo))
|
||
{
|
||
while (true)
|
||
{
|
||
BasMbomProcess nextMbomProcess = allMbomProcesses.FirstOrDefault(x=>x.no==startNo);
|
||
|
||
if (nextMbomProcess==null || nextMbomProcess.no==null)
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
startNo = nextMbomProcess.next_process_no;
|
||
mbomProcesssIds.Add(nextMbomProcess.id);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!prdMoTask.mbom_process_id.Contains(prdMoTask.mbom_process_id))
|
||
{
|
||
mbomProcesssIds.Add(startMbomProcess.id);
|
||
}
|
||
}
|
||
|
||
List<BasMbomOutput> outputList = await _db.Queryable<BasMbomProcess>()
|
||
.LeftJoin<BasMbomOutput>((a, b) => a.id == b.mbom_process_id)
|
||
.Where((a, b) => mbomProcesssIds.Contains(a.id))
|
||
.Select((a,b)=>b).ToListAsync();
|
||
|
||
List<BasMbomInput> inputList = await _db.Queryable<BasMbomProcess>()
|
||
.LeftJoin<BasMbomInput>((a, b) => a.id == b.mbom_process_id)
|
||
.Where((a, b) => mbomProcesssIds.Contains(a.id))
|
||
.Select((a,b)=>b).ToListAsync();
|
||
|
||
decimal? needNum = 1;//一个最终物料需要本任务单投入物料的数量
|
||
string tempMaterialId = outputList.FirstOrDefault(x=>x.mbom_process_id==mbomProcesssIds[mbomProcesssIds.Count-1])?.material_id;
|
||
for (int i = mbomProcesssIds.Count - 1; i > 0;i--)
|
||
{
|
||
|
||
List<BasMbomInput> inputs = inputList.Where(x => x.mbom_process_id == mbomProcesssIds[i]).ToList();
|
||
BasMbomOutput output = outputList.FirstOrDefault(x => x.mbom_process_id == mbomProcesssIds[i] && x.material_id==tempMaterialId);
|
||
List<string> inputMaterialIds = inputs.Select(x => x.material_id).ToList();
|
||
List<BasMbomOutput> lastOutputs = outputList.Where(x=>x.mbom_process_id==mbomProcesssIds[i-1]).ToList();
|
||
decimal? inputNum = inputs.FirstOrDefault(x => inputMaterialIds.Contains(x.material_id))?.num;
|
||
if (inputNum == null)
|
||
{
|
||
throw new Exception("生产bom投入产出物料配置错误");
|
||
}
|
||
else
|
||
{
|
||
tempMaterialId = inputs.FirstOrDefault(x => inputMaterialIds.Contains(x.material_id))?.material_id;
|
||
needNum = needNum / Convert.ToDecimal(output.num) * inputNum;
|
||
}
|
||
}
|
||
|
||
bool flag = true;
|
||
decimal residueNeed = 0;
|
||
foreach (var prdReport in prdReports)
|
||
{
|
||
decimal needNumTotal = prdReport.reported_qty * needNum ?? 0;
|
||
if (beforeIn - needNumTotal >= 0)
|
||
{
|
||
beforeIn -= needNumTotal;
|
||
}
|
||
else
|
||
{
|
||
if (flag)
|
||
{
|
||
if (prdFeedingD.num > needNumTotal - beforeIn)
|
||
{
|
||
residueNeed = prdFeedingD.num - (needNumTotal - beforeIn);
|
||
reportIds.Add(prdReport.id);
|
||
}
|
||
else
|
||
{
|
||
reportIds.Add(prdReport.id);
|
||
break;
|
||
}
|
||
|
||
flag = false;
|
||
continue;
|
||
|
||
}
|
||
|
||
if (residueNeed - needNumTotal > 0)
|
||
{
|
||
residueNeed -= needNumTotal;
|
||
reportIds.Add(prdReport.id);
|
||
}else
|
||
{
|
||
reportIds.Add(prdReport.id);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
return Array.Empty<string>();
|
||
}
|
||
}
|
||
|
||
List<string> barCodes = await _db.Queryable<PrdReport>().Where(x=>reportIds.Contains(x.id)).Select(x=>x.barcode).ToListAsync();
|
||
|
||
string domain = (App.HttpContext.Request.IsHttps ? "https://" : "http://") + App.HttpContext.Request.Host;
|
||
Dictionary<string, object> header = new Dictionary<string, object>()
|
||
{
|
||
["Authorization"] = App.HttpContext.Request.Headers["Authorization"]
|
||
};
|
||
Dictionary<string, object> postData = new Dictionary<string, object>()
|
||
{
|
||
["org_id"] = _userManager.GetUserInfo().Result.organizeId,
|
||
["barcode"] = barCodes,
|
||
["currentPage"] = 1,
|
||
["pageSize"] = int.MaxValue,
|
||
};
|
||
var sendResult = HttpUtils.RequestPost(domain + WebApiConst.MES_FETCH_IN_OUT_STOCK_INFO_BY_BAR_CODE,JsonConvert.SerializeObject(postData),header);
|
||
Log.Information(sendResult);
|
||
|
||
AuthResponse authResponse = JsonConvert.DeserializeObject<AuthResponse>(sendResult);
|
||
if (authResponse.code != 200)
|
||
{
|
||
throw Oops.Bah(authResponse.msg);
|
||
}
|
||
else
|
||
{
|
||
BasMaterial basMaterial = await _db.Queryable<BasMaterial>().FirstAsync(x => x.id == prdMoTask.material_id);
|
||
PageResult<PrdMoReverseFromOutput> output = JsonConvert.DeserializeObject<PageResult<PrdMoReverseFromOutput>>(authResponse.data.ToString(),new Tnb.Common.Utils.DateTimeJsonConverter());
|
||
if (output.list != null && output.list.Count > 0)
|
||
{
|
||
foreach (var item in output.list)
|
||
{
|
||
item.material_name = basMaterial.name;
|
||
}
|
||
}
|
||
|
||
return output.list;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
}
|
||
|