Files
kunshan-bzfm-mes-backend/DOAN.Service/MES/SmartScreen/Product/ProductSmartScreenService.cs
git_rabbit 9793fdd42f fix(生产管理): 修复工单数量类型及完善出货逻辑
将工单数量字段从可空类型改为非可空类型并添加默认值
添加成品入库数量字段并完善相关业务逻辑
修复出货失败时的错误响应
完善撤销入库/出库操作时的工单数量调整
增加出货数量与成品入库数量的校验
2026-02-10 15:07:59 +08:00

701 lines
29 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 System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DOAN.Model.MES.base_;
using DOAN.Model.MES.product;
using DOAN.Model.MES.SmartScreen;
using DOAN.Model.MES.SmartScreen.Product;
using DOAN.Service.MES.product.IService;
using DOAN.Service.MES.SmartScreen.Product.IService;
using Infrastructure.Attribute;
using MathNet.Numerics;
using Microsoft.Data.SqlClient;
using NPOI.SS.Formula.Atp;
namespace DOAN.Service.MES.SmartScreen.Product
{
/// <summary>
/// 生产智慧屏
/// </summary>
[AppService(
ServiceType = typeof(IProductSmartScreenService),
ServiceLifetime = LifeTime.Transient
)]
public class ProductSmartScreenService : BaseService<ProWorkorder>, IProductSmartScreenService
{
/// <summary>
/// 数字翻牌器
/// </summary>
/// <returns></returns>
public DigitalTurntableModel DigitalTurntable()
{
DigitalTurntableModel digital = new DigitalTurntableModel();
digital.WorkorderQuantity = Context
.Queryable<ProWorkorder>()
.Where(it => it.WorkorderDate == DateTime.Today)
.Count();
//digital.FinishedWorkorderQuantity=Context.Queryable<ProWorkorder>().Where(it => it.WorkorderDate == DateTime.Today)
// .Where(it=>it.Status==2)
// .Count();
//digital.UnFinishedWorkorderQuantity = Context.Queryable<ProWorkorder>().Where(it => it.WorkorderDate == DateTime.Today)
// .Where(it => it.Status <2)
// .Count();
digital.ProductionPlanQuantity = Context
.Queryable<ProWorkorder>()
.Where(it => it.WorkorderDate == DateTime.Today)
.Sum(it => it.PlanNum);
//digital.ProductionFinishQuantity = Context.Queryable<ProReportwork01>().Where(it => it.JobDateTime >= DateTime.Today && it.JobDateTime < DateTime.Today.AddDays(1))
// .Where(it => it.ProcessId == 90).Sum(it => it.FinishNum??0);
// 今日物料领用
digital.MaterialRequisitionQuantity = Context
.Queryable<ProReportwork01>()
.Where(it =>
it.ProcessId == 10
&& it.JobDateTime >= DateTime.Today
&& it.JobDateTime < DateTime.Today.AddDays(1)
)
.Sum(it => it.FinishNum ?? 0);
digital.ShipmentQuantity = Context
.Queryable<ProReportwork01>()
.Where(it =>
it.ProcessId == 90
&& it.JobDateTime >= DateTime.Today
&& it.JobDateTime < DateTime.Today.AddDays(1)
)
.Sum(it => it.FinishNum ?? 0);
digital.GroupQuantity = Context
.Queryable<ProWorkorder>()
.Where(it => it.WorkorderDate == DateTime.Today)
.Select(it => it.GroupCode)
.Distinct()
.Count();
return digital;
}
public EchartsOptions BarProcessProductStatistic()
{
EchartsOptions echartsOptions = new EchartsOptions();
echartsOptions.Title = new EchartsTitle("今日各工序产量统计", "今日各工序产量统计");
EchartsXAxis xAxis = new EchartsXAxis();
xAxis.Data = Context
.Queryable<BaseRelWorkRouteProcesses>()
.LeftJoin<BaseWorkProcesses>((r, p) => r.FkWorkProcesses == p.Id)
.Where((r, p) => p.Status == 1 && r.FkWorkRoute == 32)
.OrderBy((r, p) => p.Id)
.Select((r, p) => p.Name)
.ToList();
echartsOptions.XAxis = xAxis;
//获取各个工序今日累计报工值
EchartsSeries echartsSeries = new EchartsSeries();
echartsSeries.Name = "今日各个工序累计报工数";
List<EchartsSeriesData> Data = Context
.Queryable<ProReportwork01>()
.LeftJoin<BaseWorkProcesses>((it, w) => it.ProcessId == w.Id)
.Where(
(it, w) =>
w.Status == 1
&& it.JobDateTime >= DateTime.Today
&& it.JobDateTime <= DateTime.Today.AddDays(1)
)
.GroupBy((it, w) => new { it.ProcessId, w.Name })
.Select(
(it, w) =>
new EchartsSeriesData()
{
Name = w.Name,
Value = SqlFunc.AggregateSum(it.FinishNum ?? 0),
}
)
.ToList();
List<EchartsSeriesData> NewData = new List<EchartsSeriesData>();
foreach (var item in xAxis.Data)
{
decimal value = Data.Where(it => it.Name == item)
.Select(it => it.Value)
.FirstOrDefault();
if (value == 0)
{
NewData.Add(new EchartsSeriesData() { Name = item, Value = 0 });
}
else
{
NewData.Add(new EchartsSeriesData() { Name = item, Value = value });
}
}
echartsSeries.Data = NewData;
echartsOptions.Series.Add(echartsSeries);
//获取各个工序今日累计计划值
EchartsSeries echartsSeries2 = new EchartsSeries();
echartsSeries2.Name = "今日各个工序累计计划数";
List<EchartsSeriesData> Data2 = Context
.Queryable<ProReportwork01>()
.LeftJoin<BaseWorkProcesses>((it, w) => it.ProcessId == w.Id)
.Where(
(it, w) =>
w.Status == 1
&& it.JobDateTime >= DateTime.Today
&& it.JobDateTime <= DateTime.Today.AddDays(1)
)
.GroupBy((it, w) => new { it.ProcessId, w.Name })
.Select(
(it, w) =>
new EchartsSeriesData()
{
Name = w.Name,
Value = SqlFunc.AggregateSum(it.PlanNum ?? 0),
}
)
.ToList();
// echartsSeries2.Data = Data2;
// echartsOptions.Series.Add(echartsSeries2);
return echartsOptions;
}
public EchartsOptions BarProcessProductStatisticWeek()
{
// 获取当前时间
DateTime now = DateTime.Now;
// 计算到本周一需要减去的天数
int daysToSubtract = ((int)now.DayOfWeek - (int)DayOfWeek.Monday + 7) % 7;
// 获取本周一的日期
DateTime mondayMorning = now.AddDays(-daysToSubtract).Date; // .Date将时间设置为00:00:00
// 获取本周日午夜(实际上是下周一开始时间)
DateTime sundayMidnight = mondayMorning.AddDays(7);
EchartsOptions echartsOptions = new EchartsOptions();
echartsOptions.Title = new EchartsTitle("本周各工序产量统计", "本周各工序产量统计");
EchartsXAxis xAxis = new EchartsXAxis();
xAxis.Data = Context
.Queryable<BaseRelWorkRouteProcesses>()
.LeftJoin<BaseWorkProcesses>((r, p) => r.FkWorkProcesses == p.Id)
.Where((r, p) => r.FkWorkRoute == 32 && p.Status == 1)
.OrderBy((r, p) => p.Id)
.Select((r, p) => p.Name)
.ToList();
echartsOptions.XAxis = xAxis;
//获取各个工序今日累计报工值
EchartsSeries echartsSeries = new EchartsSeries();
echartsSeries.Name = "本周各个工序累计报工数";
List<EchartsSeriesData> Data = Context
.Queryable<ProReportwork01>()
.LeftJoin<BaseWorkProcesses>((it, w) => it.ProcessId == w.Id)
.Where(
(it, w) =>
w.Status == 1
&& it.JobDateTime >= mondayMorning
&& it.JobDateTime <= sundayMidnight
)
.GroupBy((it, w) => new { it.ProcessId, w.Name })
.Select(
(it, w) =>
new EchartsSeriesData()
{
Name = w.Name,
Value = SqlFunc.AggregateSum(it.FinishNum ?? 0),
}
)
.ToList();
List<EchartsSeriesData> NewData = new List<EchartsSeriesData>();
foreach (var item in xAxis.Data)
{
decimal value = Data.Where(it => it.Name == item)
.Select(it => it.Value)
.FirstOrDefault();
if (value == 0)
{
NewData.Add(new EchartsSeriesData() { Name = item, Value = 0 });
}
else
{
NewData.Add(new EchartsSeriesData() { Name = item, Value = value });
}
}
echartsSeries.Data = NewData;
echartsOptions.Series.Add(echartsSeries);
//获取各个工序今日累计计划值
EchartsSeries echartsSeries2 = new EchartsSeries();
echartsSeries2.Name = "本周各个工序累计计划数";
List<EchartsSeriesData> Data2 = Context
.Queryable<ProReportwork01>()
.LeftJoin<BaseWorkProcesses>((it, w) => it.ProcessId == w.Id)
.Where(
(it, w) =>
w.Status == 1
&& it.JobDateTime >= mondayMorning
&& it.JobDateTime <= sundayMidnight
)
.GroupBy((it, w) => new { it.ProcessId, w.Name })
.Select(
(it, w) =>
new EchartsSeriesData()
{
Name = w.Name,
Value = SqlFunc.AggregateSum(it.PlanNum ?? 0),
}
)
.ToList();
// echartsSeries2.Data = Data2;
//echartsOptions.Series.Add(echartsSeries2);
return echartsOptions;
}
public EchartsOptions BarProcessProductStatisticMonth()
{
// 获取当前日期时间
DateTime now = DateTime.Now;
// 获取本月第一天的日期时间(凌晨)
DateTime firstDayOfMonth = new DateTime(now.Year, now.Month, 1, 0, 0, 0);
// 获取本月最后一天的日期时间(午夜)
int daysInMonth = DateTime.DaysInMonth(now.Year, now.Month);
DateTime lastDayOfMonth = new DateTime(now.Year, now.Month, daysInMonth, 23, 59, 59);
EchartsOptions echartsOptions = new EchartsOptions();
echartsOptions.Title = new EchartsTitle("本月各工序产量统计", "本月各工序产量统计");
EchartsXAxis xAxis = new EchartsXAxis();
xAxis.Data = Context
.Queryable<BaseRelWorkRouteProcesses>()
.LeftJoin<BaseWorkProcesses>((r, p) => r.FkWorkProcesses == p.Id)
.Where((r, p) => p.Status == 1 && r.FkWorkRoute == 32)
.OrderBy((r, p) => p.Id)
.Select((r, p) => p.Name)
.ToList();
echartsOptions.XAxis = xAxis;
//获取各个工序今日累计报工值
EchartsSeries echartsSeries = new EchartsSeries();
echartsSeries.Name = "本月各个工序今日累计报工数";
List<EchartsSeriesData> Data = Context
.Queryable<ProReportwork01>()
.LeftJoin<BaseWorkProcesses>((it, w) => it.ProcessId == w.Id)
.Where(
(it, w) =>
w.Status == 1
&& it.JobDateTime >= firstDayOfMonth
&& it.JobDateTime <= lastDayOfMonth
)
.GroupBy((it, w) => new { it.ProcessId, w.Name })
.Select(
(it, w) =>
new EchartsSeriesData()
{
Name = w.Name,
Value = SqlFunc.AggregateSum(it.FinishNum ?? 0),
}
)
.ToList();
List<EchartsSeriesData> NewData = new List<EchartsSeriesData>();
foreach (var item in xAxis.Data)
{
decimal value = Data.Where(it => it.Name == item)
.Select(it => it.Value)
.FirstOrDefault();
if (value == 0)
{
NewData.Add(new EchartsSeriesData() { Name = item, Value = 0 });
}
else
{
NewData.Add(new EchartsSeriesData() { Name = item, Value = value });
}
}
echartsSeries.Data = NewData;
echartsOptions.Series.Add(echartsSeries);
//获取各个工序今日累计计划值
EchartsSeries echartsSeries2 = new EchartsSeries();
echartsSeries2.Name = "本月各个工序今日累计计划数";
List<EchartsSeriesData> Data2 = Context
.Queryable<ProReportwork01>()
.LeftJoin<BaseWorkProcesses>((it, w) => it.ProcessId == w.Id)
.Where(
(it, w) =>
w.Status == 1
&& it.JobDateTime >= firstDayOfMonth
&& it.JobDateTime <= lastDayOfMonth
)
.GroupBy((it, w) => new { it.ProcessId, w.Name })
.Select(
(it, w) =>
new EchartsSeriesData()
{
Name = w.Name,
Value = SqlFunc.AggregateSum(it.PlanNum ?? 0),
}
)
.ToList();
// echartsSeries2.Data = Data2;
// echartsOptions.Series.Add(echartsSeries2);
return echartsOptions;
}
/// <summary>
/// 本月每天产量
/// </summary>
/// <returns></returns>
public EchartsOptions OutputOfCurrentmonth()
{ // 获取当前日期
DateTime today = DateTime.Today;
// 获取当前月的第一天
DateTime firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
// 获取当前月的最后一天
DateTime lastDayOfMonth = new DateTime(
today.Year,
today.Month,
DateTime.DaysInMonth(today.Year, today.Month)
);
EchartsOptions echartsOptions = new EchartsOptions();
EchartsTitle Title = new EchartsTitle("本月每天产量", "本月每天产量");
echartsOptions.Title = Title;
// 横坐标
EchartsXAxis xAxis = new EchartsXAxis();
List<string> xData = new List<string>();
DateTime index = firstDayOfMonth;
do
{
xData.Add(index.ToString("dd"));
index = index.AddDays(1);
} while (index < lastDayOfMonth.AddDays(1));
xAxis.Data = xData;
echartsOptions.XAxis = xAxis;
//折线系列
EchartsSeries LineSeries = new EchartsSeries();
LineSeries.Name = "本月每天产量";
LineSeries.Type = "line";
//var result = Context.Queryable<ProWorkorder>()
// .LeftJoin<ProReportwork01>((w, r) => w.Workorder == r.Workorder)
// .Where((w, r) =>r.ProcessId==70&&w.Status == 1 && w.WorkorderDate >= firstDayOfMonth && w.WorkorderDate <= lastDayOfMonth)
// .GroupBy((w, r) => w.WorkorderDate)
// .Select((w, r) => new EchartsSeriesData()
// {
// Name = w.WorkorderDate.Value.ToString("MM-dd"),
// Value = SqlFunc.AggregateSum(r.FinishNum ?? 0)
// }).ToList();
//var result = Context.Queryable<ProReportwork01>()
// .Where(it=>it.ProcessId == 20 && it.JobDateTime >= firstDayOfMonth && it.JobDateTime <= lastDayOfMonth.AddDays(1))
// .GroupBy(it => SqlFunc.DateDiff(DateType.Day, it.JobDateTime ?? DateTime.MinValue, DateTime.Now)) // 按天分组
// .Select(it => new
// {
// Name = it.JobDateTime.Value.ToString("MM-dd"),// 获取日期部分
// Value = SqlFunc.AggregateSum(it.FinishNum ?? 0) // 聚合求和
// }).ToList();
var result = Context
.Queryable<ProReportwork01>()
.Where(it =>
it.ProcessId == 20
&& it.JobDateTime >= firstDayOfMonth
&& it.JobDateTime <= lastDayOfMonth.AddDays(1)
)
.GroupBy(it => SqlFunc.DateValue(it.JobDateTime ?? DateTime.MinValue, DateType.Day)) // 按天分组
.Select(it => new
{
Name = SqlFunc.DateValue(it.JobDateTime ?? DateTime.MinValue, DateType.Day), // 获取日期部分
Value = SqlFunc.AggregateSum(it.FinishNum ?? 0), // 聚合求和
})
.ToList();
List<EchartsSeriesData> LineSeriesData = new List<EchartsSeriesData>();
foreach (var item in xData)
{
LineSeriesData.Add(
new EchartsSeriesData()
{
Name = item,
Value = result
.Where(it => it.Name == int.Parse(item))
.Select(it => it.Value)
.FirstOrDefault(),
}
);
}
LineSeries.Data = LineSeriesData;
echartsOptions.Series = new List<EchartsSeries>() { LineSeries };
// 各个组的产量系列
string[] groupArray = Context
.Queryable<BaseGroup>()
.Where(it => it.Status == 1)
.OrderBy(it => it.Id)
.Select(it => it.GroupCode)
.ToArray();
if (groupArray.Length > 0)
{
//var GroupresultList = Context.Queryable<ProWorkorder>()
// .RightJoin<ProReportwork01>((w, r) => w.Workorder == r.Workorder)
// .Where((w, r) => groupArray.Contains(w.GroupCode))
// .Where((w, r) => r.ProcessId == 70 && w.Status == 1 && r.JobDateTime >= firstDayOfMonth && r.JobDateTime <= lastDayOfMonth)
// .GroupBy((w, r) => new { w.GroupCode, w.WorkorderDate })
// .Select((w, r) => new
// {
// groupCode = w.GroupCode,
// Name = w.WorkorderDate.Value.ToString("MM-dd"),
// Value = SqlFunc.AggregateSum(r.FinishNum ?? 0)
// }).ToList();
var GroupresultList = Context
.Queryable<ProReportwork01>()
.LeftJoin<ProWorkorder>((r, w) => r.Workorder == w.Workorder)
.Where((r, w) => groupArray.Contains(w.GroupCode))
.Where(
(r, w) =>
r.ProcessId == 20
&& r.JobDateTime >= firstDayOfMonth
&& r.JobDateTime <= lastDayOfMonth.AddDays(1)
)
.GroupBy(
(r, w) =>
new
{
w.GroupCode,
Day = SqlFunc.DateValue(
r.JobDateTime ?? DateTime.MinValue,
DateType.Day
),
}
) // 按天分组
.Select(
(r, w) =>
new
{
groupCode = w.GroupCode,
Name = SqlFunc.DateValue(
r.JobDateTime ?? DateTime.MinValue,
DateType.Day
), // 获取日期部分
Value = SqlFunc.AggregateSum(r.FinishNum ?? 0), // 聚合求和
}
)
.ToList();
foreach (var group in groupArray)
{
EchartsSeries groupSeries = new EchartsSeries();
groupSeries.Name = group + "组";
groupSeries.Type = "bar";
List<EchartsSeriesData> LineSeriesData01 = new List<EchartsSeriesData>();
foreach (var item in xData)
{
LineSeriesData01.Add(
new EchartsSeriesData()
{
Name = item,
Value = GroupresultList
.Where(it => it.Name == int.Parse(item))
.Where(it => it.groupCode == group)
.Select(it => it.Value)
.FirstOrDefault(),
}
);
}
groupSeries.Data = LineSeriesData01;
echartsOptions.Series.Add(groupSeries);
}
}
return echartsOptions;
}
public EchartsOptions AccumulatedReport()
{
EchartsOptions echartsOptions = new EchartsOptions();
echartsOptions.Title = new EchartsTitle(
"昨日-今日各工序实时累计完工数折线图",
"昨日-今日各工序实时累计完工数折线图"
);
//1.查询各个工序
int[] processArray = Context
.Queryable<ProReportwork01>()
.Where(it =>
it.JobDateTime > DateTime.Today && it.JobDateTime < DateTime.Today.AddDays(1)
)
.OrderBy(it => it.ProcessId)
.Select(it => it.ProcessId)
.Distinct()
.ToArray();
//1 X轴
List<DateTime> DateTimeArray = new List<DateTime>();
// 定义起始时间和结束时间
// 获取当前日期和时间
DateTime now = DateTime.Now;
// 获取昨天的日期
DateTime yesterday = now.AddDays(-1);
// 设置时间为 20:00
DateTime startTime = new DateTime(
yesterday.Year,
yesterday.Month,
yesterday.Day,
20,
0,
0
);
//DateTime startTime = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day., 8, 0, 0);
// DateTime startTime = DateTime.Today;
DateTime endTime = new DateTime(
DateTime.Today.Year,
DateTime.Today.Month,
DateTime.Today.Day,
20,
0,
0
); // 8 AM + 12 hours = 8 PM
// 使用循环生成每30分钟的时间戳
for (
DateTime currentTime = startTime;
currentTime <= endTime;
currentTime = currentTime.AddMinutes(30)
)
{
DateTimeArray.Add(currentTime);
}
List<string> DateTimeArrayString = DateTimeArray
.Select(it => it.ToString("dd-HH:mm"))
.ToList();
echartsOptions.XAxis = new EchartsXAxis() { Data = DateTimeArrayString };
//2 系列值-这组 今日实时累计完成数每30分钟
for (int i = 0; i < processArray.Length; i++)
{
string ProcessName = Context
.Queryable<BaseWorkProcesses>()
.Where(it => it.Id == processArray[i])
.Select(it => it.Name)
.First();
EchartsSeries echartsSeries = new EchartsSeries();
//echartsSeries.Name = ProcessName + "工序今日实时累计完成数每10分钟";
echartsSeries.Name = ProcessName;
echartsSeries.Type = "line";
List<EchartsSeriesData> echartsSeriesDatas = new List<EchartsSeriesData>();
string sql =
"SELECT"
+ " FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP(job_datetime) / 600 ) * 600 ) AS time_period,"
+ " SUM( finish_num ) AS count "
+ " FROM"
+ " pro_reportwork "
+ " WHERE"
+ " DATE(job_datetime) = CURDATE() AND @process_id=process_id "
+ " GROUP BY"
+ " FLOOR( UNIX_TIMESTAMP( job_datetime ) / 600 )"
+ " ORDER BY"
+ " time_period";
string sql2 =
"SELECT time_period, SUM(finish_num) AS count\r\nFROM (\r\n SELECT FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP( job_datetime ) / 600 ) * 600 ) AS time_period,\r\n finish_num\r\n FROM pro_reportwork\r\n WHERE DATE(job_datetime) = CURDATE() AND @process_id=process_id\r\n) AS subquery\r\nGROUP BY time_period\r\nORDER BY time_period";
string sql3 =
"SELECT time_period, SUM(finish_num) AS count\r\nFROM (\r\n SELECT FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP( job_datetime ) / 1800 ) * 1800 ) AS time_period,\r\n finish_num\r\n FROM pro_reportwork\r\n WHERE job_datetime>=@SearchDateTime01 AND job_datetime<=@SearchDateTime02 AND process_id=@process_id\r\n) AS subquery\r\nGROUP BY time_period\r\nORDER BY time_period";
DataTable result = Context.Ado.GetDataTable(
sql3,
new
{
SearchDateTime01 = startTime,
SearchDateTime02 = endTime,
process_id = processArray[i],
}
);
int sum = 0;
foreach (DataRow row in result.Rows)
{
// DateTime value =(DateTime)row["time_period"];
DateTime value =
row["time_period"] != DBNull.Value
? Convert.ToDateTime(row["time_period"])
: DateTime.MinValue;
int count = Convert.ToInt32(row["count"]);
sum = sum + count;
EchartsSeriesData echartsSeriesData = new EchartsSeriesData()
{
Name = value.ToString("dd-HH:mm"),
Value = sum,
};
echartsSeriesDatas.Add(echartsSeriesData);
}
// 和X轴一 一对应
int currentNum = Array.IndexOf(
DateTimeArrayString.ToArray(),
echartsSeriesDatas.Select(it => it.Name).LastOrDefault()
);
for (int j = 0; j < currentNum; j++)
{
int point = 0;
foreach (var item in echartsSeriesDatas)
{
if (item.Name == DateTimeArrayString[j])
{
continue;
}
point++;
}
if (point == echartsSeriesDatas.Count())
{
// 获取前一个时间段产量
decimal productNum = 0;
if (j >= 1)
{
productNum = echartsSeriesDatas
.Where(it => it.Name == DateTimeArrayString[j - 1])
.Select(it => it.Value)
.FirstOrDefault();
}
else
{
productNum = 0;
}
echartsSeriesDatas.Add(
new EchartsSeriesData()
{
Name = DateTimeArrayString[j],
Value = productNum,
}
);
}
}
echartsSeries.Data = echartsSeriesDatas.OrderBy(it => it.Name).ToList();
echartsOptions.Series.Add(echartsSeries);
}
return echartsOptions;
}
}
}