Files
tnb.server/ProductionMgr/Tnb.ProductionMgr/PrdMoService.cs
2023-11-07 11:29:51 +08:00

1240 lines
63 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.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)
{
ISqlSugarClient 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() : "";
SqlSugarPagedList<PrdMoListOuput> 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 dynamic GetReportRecord(string icmoCode)
{
_ = _repository.AsSugarClient();
PrdMoTaskDefectOutput output = new();
//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");
}
ISqlSugarClient db = _repository.AsSugarClient();
//获取同组工单的Id一起下发
List<string?> combineMoCodes = await db.Queryable<PrdMo>().Where(it => input.WorkOrderIds.Contains(it.id)).Select(it => it.combine_mo_code).ToListAsync();
if (combineMoCodes?.Count > 0)
{
List<string> 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();
}
static string getMoStatus(MoBehavior behavior)
{
string status = "";
switch (behavior)
{
case MoBehavior.Release:
status = DictConst.IssueId;
break;
case MoBehavior.Closed:
status = DictConst.MoCloseId;
break;
}
return status!;
}
MoBehavior behavior = input.Behavior.ToEnum<MoBehavior>();
string status = getMoStatus(behavior);
int 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,
c.mold_code,
}).ToListAsync();
bool planDateAll = true;
bool moldIdAll = true;
if (list?.Count > 0)
{
DateTime? planDate = list.FirstOrDefault()?.planDate;
string? 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)
{
string 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)
{
SqlSugarPagedList<PrdMoStatisticsOutput> 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(DbTimeFormat.SS),
estimated_end_date = x.estimated_end_date == null ? "" : x.estimated_end_date.Value.ToString(DbTimeFormat.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> ids1 = new();
List<string> ids2 = new();
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();
}
SqlSugarPagedList<PrdMoFromOneListOutput> 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(DbTimeFormat.SS),
act_end_date = a.act_end_date == null ? "" : a.act_end_date.Value.ToString(DbTimeFormat.SS)
}).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult<PrdMoFromOneListOutput>.SqlSugarPageResult(result);
}
/// <summary>
/// 工单追溯二级列表
/// </summary>
/// <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();
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);
return prdMo.mo_type is DictConst.PrdMoTypeZS or DictConst.PrdMoTypeJC
? 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(DbTimeFormat.SS),
act_end_date = a.act_end_date == null ? "" : a.act_end_date.Value.ToString(DbTimeFormat.SS),
workshop_name = e.FullName,
station_name = d.FullName,
equip_code = f.code
}).ToListAsync()
: (dynamic)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(DbTimeFormat.SS),
act_end_date = a.act_end_date == null ? "" : a.act_end_date.Value.ToString(DbTimeFormat.SS),
workline_name = c.FullName,
mbom_version = d.version
}).ToListAsync();
}
/// <summary>
/// 工单追溯三级级列表
/// </summary>
/// <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();
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>
/// <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();
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>
/// <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();
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>
/// <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();
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))
{
return prdMoTask.schedule_type == 1
? 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()
: (dynamic)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();
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 (BasEbomD 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 (PrdFeedingD 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==null ? "" : c.instock_time.Value.ToString(DbTimeFormat.SS),
feeding_time = e.create_time == null ? "" : e.create_time.Value.ToString(DbTimeFormat.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();
foreach (BasMbomInput 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 (BasMbomProcess 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 (PrdReport 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 (PrdFeedingD 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;
}
}
}
}
}
ISugarQueryable<PrdMoFromMaterialListOutput> 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==null ? "" : c.instock_time.Value.ToString(DbTimeFormat.SS),
feeding_time = e.create_time == null ? "" : e.create_time.Value.ToString(DbTimeFormat.SS),
});
if (lastPrdReportIds != null && lastPrdReportIds.Count > 0)
{
ISugarQueryable<PrdMoFromMaterialListOutput> 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>
/// <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()
{
["Authorization"] = App.HttpContext.Request.Headers["Authorization"]
};
Dictionary<string, object> postData = new()
{
["org_id"] = _userManager.GetUserInfo().Result.organizeId,
["barcode"] = new List<string>() { barcode },
["currentPage"] = 1,
["pageSize"] = int.MaxValue,
};
string 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>
/// <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();
List<PrdMoReverseFromFeedingOutput> 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(DbTimeFormat.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>
/// <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();
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 (PrdReport prdReport in prdReports)
{
decimal 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() { 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[^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 (PrdReport 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()
{
["Authorization"] = App.HttpContext.Request.Headers["Authorization"]
};
Dictionary<string, object> postData = new()
{
["org_id"] = _userManager.GetUserInfo().Result.organizeId,
["barcode"] = barCodes,
["currentPage"] = 1,
["pageSize"] = int.MaxValue,
};
string 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 (PrdMoReverseFromOutput item in output.list)
{
item.material_name = basMaterial.name;
}
}
return output.list;
}
}
#endregion
}
}