@using System.Globalization
@using System.Text.RegularExpressions
@using System.Reflection;
@using Microsoft.JSInterop;
@inject IJSRuntime JSRuntime
@inject IUnitOfWork _unit
@inject ISnackbar Snackbar
@inject ILocalStorageService _localstorage;
@inject IDialogService DialogService
@inject ILocalStorageService _localstorage
@inject ISocketClientService tcpClient
@inject ICTUService CTUService
@inject IExcelExportService _exportExcel
@inject ILogDataService _logService
@inject IMissionUpdateService _missionService
background-color: deepskyblue;
<div class="w-100 h-100 position-absolute top-0 start-0 overflow-hidden d-flex flex-column flex-grow-1 gap-2 p-4">
<MudCard Class="w-100" Elevation="2">
<MudCardHeader class="d-flex flex-row align-items-center justify-content-center">
<MudText Typo="Typo.h4">Kế hoạch cấp hàng ra line</MudText>
<div class="d-flex flex-row-reverse flex-grow-1 gap-4">
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.Transform" Color="Color.Primary" OnClick="AutoMappingClick">Auto Mapping</MudButton>
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.Transform" Color="Color.Secondary" OnClick="OpenLineTransferClick">Cấp line</MudButton>
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.AddBox" Color="Color.Success" OnClick="AddPlanClick">Thêm Plan</MudButton>
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.Diversity1" Color="Color.Warning" OnClick="DivMaterialPlanClick">Cập nhật remain</MudButton>
<MudDivider DividerType="DividerType.Middle" Style="height: 2px" />
<MudGrid Justify="Justify.SpaceBetween">
<MudDatePicker Label="Từ ngày" @bind-Date="PlanDateFromSearch" DateFormat="dd/MM/yyyy" Class="w-100" />
<MudDatePicker Label="Đến ngày" @bind-Date="PlanDateToSearch" DateFormat="dd/MM/yyyy" Class="w-100" />
<MudSelect T="int" @bind-Value="PlanKittingStatusSearch" Label="Kitting Status" AnchorOrigin="Origin.BottomCenter" Class="w-100">
<MudSelectItem Value="0">--All--</MudSelectItem>
<MudSelectItem Value="1">NG</MudSelectItem>
<MudSelectItem Value="2">OK</MudSelectItem>
<MudSelect T="int" @bind-Value="PlanOutputStatusSearch" Label="Transfer Status" AnchorOrigin="Origin.BottomCenter" Class="w-100">
<MudSelectItem Value="0">--All--</MudSelectItem>
<MudSelectItem Value="1">NG</MudSelectItem>
<MudSelectItem Value="2">Ok</MudSelectItem>
<MudSelect T="int" @bind-Value="PlanStatusSearch" Label="Plan Status" AnchorOrigin="Origin.BottomCenter" Class="w-100">
<MudSelectItem Value="LineTransStatus.ALL">--ALL--</MudSelectItem>
<MudSelectItem Value="LineTransStatus.NG">NG</MudSelectItem>
<MudSelectItem Value="LineTransStatus.OK">OK</MudSelectItem>
<MudSelect T="int" @bind-Value="PlanResendCountSearch" Label="Plan Update" AnchorOrigin="Origin.BottomCenter" Class="w-100">
<MudSelectItem Value="LineTransPlanCount.ALL">@LineTransPlanCountText.ALL </MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.KITTINGSOMLAN1">@LineTransPlanCountText.KITTINGSOMLAN1 </MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.KITTINGSOMLAN2">@LineTransPlanCountText.KITTINGSOMLAN2 </MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.KITTINGSOM">@LineTransPlanCountText.KITTINGSOM </MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.CHECKDAILY">@LineTransPlanCountText.CHECKDAILY </MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.KITTINGCADEM">@LineTransPlanCountText.KITTINGCADEM </MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.DEMODAILY">@LineTransPlanCountText.DEMODAILY </MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.DAILY">@LineTransPlanCountText.DAILY </MudSelectItem>
<MudTextField @bind-Value="LineNameSearch" Label="Line Name" Variant="Variant.Text"></MudTextField>
<MudTextField @bind-Value="PCBCodeSearch" Label="PCB Code" Variant="Variant.Text"></MudTextField>
<MudText>Đã tìm được: <b>@PlanDataSearchList.Count()</b> kết quả</MudText>
<div class="d-flex flex-row gap-4 justify-content-start">
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.AddAlarm" Color="Color.Warning" OnClick="ExportToExcel">Xuất Excel</MudButton>
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.Search" Color="Color.Primary" OnClick="PlanSearchClick">Tìm kiếm</MudButton>
<div id="nguyen" class="h-100 w-100">
<MudCard Class="w-100 h-100">
Items="PlanDataSearchList"
HorizontalScrollbar="true"
HeaderClass="table-head-bordered"
RowStyleFunc="SearchRowStyleFunc">
<MudIconButton Variant="Variant.Filled" Color="Color.Success" Icon="@Icons.Material.Filled.SettingsBackupRestore" OnClick="AutoMappingClick"></MudIconButton>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.LineName)">Line cấp</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.PlanDate)">Ngày cấp</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.StartTime)">Giờ chạy</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.PlanPriority)">Ghi chú</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.ModelBasic)">Model basic</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.PCBCode)">Mã PCB</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.PCBRev)">Mã Rev</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.PCBPlanQty)">Số lượng</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.KittingPCBQty)">Đã Kitting</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.KittingRemainQty)">Remain Kiting(@PlanDataSearchList.Sum(p=>p.KittingRemainQty))</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.TransferPCBQty)">Đã Cấp</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.OutputRemainQty)">Remain Cấp(@PlanDataSearchList.Sum(p=>p.OutputRemainQty))</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.PlanCount)">Kế hoạch</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel Style="" SortBy="new Func<MaterialTransPlanDTO, object>(x=>x.ModifiedAt)">Ngày sửa</MudTableSortLabel></MudTh>
<div class="d-flex flex-row gap-1 justify-content-start">
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.RestartAlt" Color="@Color.Success" Disabled="@(context.KittingPCBQty == context.PCBPlanQty)" OnClick="@(() => AutoMappingPlanClick(context))"></MudIconButton>
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.ViewList" Color="@Color.Secondary" Disabled="@(context.KittingPCBQty == context.PCBPlanQty)" OnClick="@(() => ViewListMaterialPlanClick(context))"></MudIconButton>
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.AddShoppingCart" Color="@Color.Primary" Disabled="@(context.KittingPCBQty == context.PCBPlanQty && context.TransferPCBQty == context.PCBPlanQty)" OnClick="@(() => KittingPlanClick(context))"></MudIconButton>
<MudTd Style="" DataLabel="Line cấp">@context.LineName</MudTd>
<MudTd Style="" DataLabel="Ngày cấp">@context.PlanDate.ToString("dd/MM/yyyy")</MudTd>
<MudTd Style="" DataLabel="Giờ chạy">@context.StartTime.ToString("dd/MM HH:mm")</MudTd>
<MudTd Style="" DataLabel="Ghi chú">@(context.PlanPriority.ToString() + context.Remark)</MudTd>
<MudTd Style="" DataLabel="Model basic">@context.ModelBasic</MudTd>
<MudTd Style="" DataLabel="Mã PCB">@context.PCBCode</MudTd>
<MudTd Style="" DataLabel="Mã Rev">@context.PCBRev</MudTd>
<MudTd Style="" DataLabel="Số lượng">@context.PCBPlanQty</MudTd>
<MudTd Style="" DataLabel="Đã Kitting">@(context.KittingPCBQty)</MudTd>
<MudTd Style="" DataLabel="Remain Kitting">@(context.PCBPlanQty - context.KittingPCBQty)</MudTd>
<MudTd Style="" DataLabel="Đã Cấp">@context.TransferPCBQty</MudTd>
<MudTd Style="" DataLabel="Remain Cấp">@(context.PCBPlanQty - context.TransferPCBQty)</MudTd>
<MudTd Style="text-align:center;" DataLabel="Kế hoạch">
LineTransPlanCount.KITTINGSOMLAN1 => LineTransPlanCountText.KITTINGSOMLAN1 ,
LineTransPlanCount.KITTINGSOMLAN2 => LineTransPlanCountText.KITTINGSOMLAN2 ,
LineTransPlanCount.KITTINGSOM => LineTransPlanCountText.KITTINGSOM ,
LineTransPlanCount.CHECKDAILY => LineTransPlanCountText.CHECKDAILY ,
LineTransPlanCount.KITTINGCADEM => LineTransPlanCountText.KITTINGCADEM ,
LineTransPlanCount.DEMODAILY => LineTransPlanCountText.DEMODAILY ,
LineTransPlanCount.DAILY => LineTransPlanCountText.DAILY ,
<MudTd Style="" DataLabel="Ngày sửa">@context.ModifiedAt.ToString("dd/MM HH:mm")</MudTd>
<div class="d-flex flex-row gap-1 justify-content-end">
<MudIconButton Color="@Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.RemoveRedEye" Disabled="@(context.KittingPCBQty == 0)" OnClick="@(() => DetailPlanClick(context))"></MudIconButton>
@* <MudIconButton Color="@Color.Default" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Edit" OnClick="@(() => EditPlanClick(context))"></MudIconButton>*@
<MudIconButton Color="@Color.Error" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Delete" Disabled="@(context.KittingPCBQty != 0)" OnClick="@(() => DeletePlanClick(context))"></MudIconButton>
<MudTablePager PageSizeOptions="new int[] { int.MaxValue, 25, 50, 100}"
RowsPerPageString="Số dòng hiển thị" />
<MudOverlay Visible="PlanAddWindowActive" DarkBackground>
<MudCard Style="@($"width: 1000px;")">
<MudCardHeader Class="d-flex justify-content-between align-items-center" Style="@($"background:{Colors.Green.Lighten5}; height: 60px; border-bottom: 1px solid #BDBDBD; margin-left: 0px; margin-right: 0px; padding-bottom: 8px;")">
<MudText Typo="Typo.h5" Class="">
Thêm kế hoạch cấp vật liệu
<MudIconButton Icon="@Icons.Material.Filled.Close" OnClick="ClosePlanAddWindowClick" />
<MudCardContent Class="d-flex flex-column flex-grow-1 gap-4">
<MudItem xs="12" sm="12">
<MudSelect T="int" @bind-Value="AddPlanSeclected" Label="Chọn Plan" AnchorOrigin="Origin.BottomCenter" Class="w-100">
<MudSelectItem Value="LineTransPlanCount.KITTINGSOMLAN1">@LineTransPlanCountText.KITTINGSOMLAN1</MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.KITTINGSOMLAN2">@LineTransPlanCountText.KITTINGSOMLAN2</MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.KITTINGSOM">@LineTransPlanCountText.KITTINGSOM</MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.CHECKDAILY">@LineTransPlanCountText.CHECKDAILY</MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.KITTINGCADEM">@LineTransPlanCountText.KITTINGCADEM</MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.DEMODAILY">@LineTransPlanCountText.DEMODAILY</MudSelectItem>
<MudSelectItem Value="LineTransPlanCount.DAILY">@LineTransPlanCountText.DAILY</MudSelectItem>
<MudDivider DividerType="DividerType.FullWidth" Style="height: 2px" />
<MudTextField T="string" Label="Dán dữ liệu excel vào đây" Variant="Variant.Text" @bind-Value="@ExcelPlanAddWindow" AutoGrow MaxLines="3" />
<div class="d-flex flex-row-reverse flex-grow-1 gap-4">
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.FileUpload" Color="Color.Warning" OnClick="AddPlanByExcelClick">Tải dữ liệu excel</MudButton>
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.Download" Color="Color.Default" Href="/excel_templates/line_plan_template.xlsx">Mẫu dữ liệu excel</MudButton>
<MudTable T="MaterialTransPlanEntity" Items="@materialSubmitLinePlans" Hover="true" Virtualize="false" FixedHeader="true" Height="230px" SortLabel="Sort By"
RowStyleFunc="AddPlanRowStyleFunc">
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PlanDate)">Ngày cấp</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.LineName)">Line cấp</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.StartTime)">Bắt đầu</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.ModelBasic)">Basic model</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PCBCode)">PCB code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PCBRev)">REV PCB</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PCBPlanQty)">Số lượng</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PlanPriority)">Thứ tự</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.Remark)">Nội dung</MudTableSortLabel></MudTh>
<MudTd DataLabel="Ngày cấp">@context.PlanDate.ToString("dd/MM/yyyy")</MudTd>
<MudTd DataLabel="Line cấp">@context.LineName</MudTd>
<MudTd DataLabel="Bắt đầu">@context.StartTime.ToString("dd/MM HH:mm")</MudTd>
<MudTd DataLabel="Basic model">@context.ModelBasic</MudTd>
<MudTd DataLabel="PCB code">@context.PCBCode</MudTd>
<MudTd DataLabel="REV PCB">@context.PCBRev</MudTd>
<MudTd DataLabel="Số lượng">@context.PCBPlanQty</MudTd>
<MudTd DataLabel="Thứ tự">@context.PlanPriority</MudTd>
<MudTd DataLabel="Nội dung">@context.Remark</MudTd>
<MudIconButton Color="@Color.Error" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Delete" OnClick="@(() => DeletePlanSubmitClick(@context))"></MudIconButton>
<MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.AddBox" Color="Color.Success" OnClick="SubmitPlanClick">Submit</MudButton>
<MudOverlay Visible="PlanKittingWindowActive" VisibleChanged="OnOverlayKittingVisibleChanged" DarkBackground>
<MudCard Style="@($"width: 1000px;")">
<MudCardHeader Class="d-flex justify-content-between align-items-center" Style="@($"background:{Colors.Green.Lighten5}; height: 60px; border-bottom: 1px solid #BDBDBD; margin-left: 0px; margin-right: 0px; padding-bottom: 8px;")">
<MudText Typo="Typo.h5" Class="">
Kitting kế hoạch bằng tay
<MudIconButton Icon="@Icons.Material.Filled.Close" OnClick="@CloseKittingPlanWindow" />
<MudCardContent Class="d-flex flex-column flex-grow-1 gap-2">
<div class="d-flex justify-space-around flex-grow-1 gap-2">
<MudTextField ReadOnly="true" Variant="Variant.Text" T="DateTime" Format="dd/MM/yyyy" Label="Ngày" @bind-Value="@CurrentPlanSelected.PlanDate" />
<MudTextField ReadOnly="true" Variant="Variant.Text" Label="Line" @bind-Value="@CurrentPlanSelected.LineName" />
<MudTextField ReadOnly="true" Variant="Variant.Text" T="DateTime" Format="dd/MM/yyyy HH:mm" Label="Thời gian bắt đầu" @bind-Value="@CurrentPlanSelected.StartTime" />
<MudSelect ReadOnly="true" Variant="Variant.Text" T="int" @bind-Value="@CurrentPlanSelected.PlanPriority" Label="Thứ tự chạy" AnchorOrigin="Origin.BottomCenter">
<MudSelectItem Value="1" />
<MudSelectItem Value="2" />
<MudSelectItem Value="3" />
<MudSelectItem Value="4" />
<MudSelectItem Value="5" />
<MudTextField ReadOnly="true" Variant="Variant.Text" Label="Nội dung" @bind-Value="@CurrentPlanSelected.Remark" />
<div class="d-flex justify-space-around flex-grow-1 gap-2">
<MudTextField @ref="TempFocus" ReadOnly="true" Variant="Variant.Text" Label="Mã Model" @bind-Value="@CurrentPlanSelected.ModelBasic" />
<MudTextField ReadOnly="true" Variant="Variant.Text" Label="Mã PCB" @bind-Value="@CurrentPlanSelected.PCBCode" />
<MudNumericField ReadOnly="true" Variant="Variant.Text" Label="Số lượng kế hoạch" @bind-Value="@CurrentPlanSelected.PCBPlanQty" />
<MudNumericField ReadOnly="true" Variant="Variant.Text" Label="Số lượng remain" @bind-Value="@CurrentPlanSelected.KittingRemainQty" />
<MudDivider DividerType="DividerType.FullWidth" Style="height: 2px" />
<MudTextField @ref="MagazinScanCode" @bind-Value="MagazinKitting" Label="Scan mã magazin" Variant="Variant.Text" Disabled="@(KittingCurrentStockList.Sum(m=>m.PCBQty) == 0)" OnKeyDown="@EnterMagazineScanKittingCodeEvent" />
<div class="d-flex flex-grow-1 gap-4">
<MudText Typo="Typo.h5" Class="flex-grow-1">Stock</MudText>
<MudText Typo="Typo.h5" Class="flex-grow-1" ><b>@KittingCurrentStockList.Sum(m=>m.PCBQty)</b></MudText>
<MudText Typo="Typo.h5" Class="flex-grow-1">Đang kitting</MudText>
<MudText Typo="Typo.h5" Class="flex-grow-1"><b>@MagazineScanList.Sum(p=>p.Quantity)</b></MudText>
<MudText Typo="Typo.h5" Class="flex-grow-1">Còn lại</MudText>
<MudText Typo="Typo.h5" Color="Color.Error" Class="flex-grow-1"><b>@(CurrentPlanSelected.KittingRemainQty - MagazineScanList.Sum(p => p.Quantity))</b></MudText>
<MudTable T="MaterialLinePlanKittingDTO" Items="@MagazineScanList" Hover="true" FixedHeader="true" Dense="true" FixedFooter="true" Height="250px" SortLabel="Sort By">
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLinePlanKittingDTO, object>(x=>x.MagazinCode)">Magazin Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLinePlanKittingDTO, object>(x=>x.PCBCode)">PCB Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLinePlanKittingDTO, object>(x=>x.Quantity)">Kitting Qty</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLinePlanKittingDTO, object>(x=>x.LineName)">Line</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLinePlanKittingDTO, object>(x=>x.PlanDate)">Date</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLinePlanKittingDTO, object>(x=>x.ModelBasic)">Basic Model</MudTableSortLabel></MudTh>
<MudTd DataLabel="Magazin Code">@context.MagazinCode</MudTd>
<MudTd DataLabel="PCB Code">@context.PCBCode</MudTd>
<MudTd DataLabel="Kitting Qty">@context.Quantity</MudTd>
<MudTd DataLabel="Line">@context.LineName</MudTd>
<MudTd DataLabel="Date">@context.PlanDate.ToString("dd/MM/yyyy")</MudTd>
<MudTd DataLabel="Basic Mode">@context.ModelBasic</MudTd>
<MudIconButton Color="@Color.Error" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Delete" OnClick="@(() => DeleteKittingPlanSubmitClick(@context))"></MudIconButton>
<MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.AddBox" Color="Color.Success" OnClick="KittingSubmitPlanClick">Submit</MudButton>
<MudOverlay Visible="PlanOutputWindowActive" DarkBackground>
<MudCard Style="@($"width: 1000px;")">
<MudCardHeader Class="d-flex justify-content-between align-items-center" Style="@($"background:{Colors.Green.Lighten5}; height: 60px; border-bottom: 1px solid #BDBDBD; margin-left: 0px; margin-right: 0px; padding-bottom: 8px;")">
<MudText Typo="Typo.h5" Class="">
List vật liệu phù hợp plan code <b>@planSelectedToDiv.PCBCode</b>
<MudIconButton Icon="@Icons.Material.Filled.Close" OnClick="@(()=>{PlanOutputWindowActive = false; mgzSelectedToDiv = null;})" />
<MudCardContent Class="d-flex flex-column flex-grow-1 gap-2">
<MudTable T="MaterialMgzForPlanDTO" Items="@MaterialMgzEntities" Hover="true" FixedHeader="true" Dense="true" FixedFooter="true" Height="250px" SortLabel="Sort By">
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.MgzCode)">Magazin Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.PCBCode)">PCB Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.PCBRev)">Rev Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.PCBQty)">PCB Quantity</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.PackInBox)">Pack Quantity</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.RackName)">Rack Name</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.BoxName)">Box Name</MudTableSortLabel></MudTh>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")" DataLabel="Magazin Code">@context.MgzCode</MudTd>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")" DataLabel="PCB Code">@context.PCBCode</MudTd>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")" DataLabel="Rev Code">@context.PCBRev</MudTd>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")" DataLabel="PCB Quantity">@context.PCBQty</MudTd>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")" DataLabel="Pack Quantity">@context.PackInBox</MudTd>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")" DataLabel="Rack Number">@context.RackName</MudTd>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")" DataLabel="Rack Code">@context.BoxName</MudTd>
<MudTd Class="@((context == mgzSelectedToDiv) ? "selected-row" : "")">
<div class="d-flex flex-row gap-1 justify-content-start">
<MudIconButton Color="@Color.Default" Variant="Variant.Filled" Icon="@Icons.Material.Filled.RemoveRedEye" OnClick="@(() => ViewLinePlanDivListClick(@context))"></MudIconButton>
@*<MudIconButton Color="@Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Directions" Disabled="@(LineKittingDivList.Count() == 0)" OnClick="@(() => TransferMaterial2DividedBufferClick(@context))"></MudIconButton>*@
<MudTablePager PageSizeOptions="new int[] { 5, 10, 25, 50, 100 }" />
<MudTable T="MaterialTransPlanEntity" Items="@LineKittingDivList" Hover="true" Virtualize="false" FixedHeader="true" Dense="true" FixedFooter="true" Height="200px" SortLabel="Sort By">
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.LineName)">Line (<b>@LineKittingDivList.Count</b>)</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PlanDate)">Plan Date</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PCBCode)">PCB Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.KittingRemainQty)">Remain (<b>@LineKittingDivList.Sum(l=>l.KittingRemainQty)</b>)</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PCBRev)">Rev Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialTransPlanEntity, object>(x=>x.PlanPriority)">Ghi chú</MudTableSortLabel></MudTh>
<MudTd DataLabel="Line">@context.LineName</MudTd>
<MudTd DataLabel="Plan Date">@context.PlanDate.ToString("dd/MM/yyyy")</MudTd>
<MudTd DataLabel="PCB Code">@context.PCBCode</MudTd>
<MudTd DataLabel="PCB Quantity">@context.KittingRemainQty</MudTd>
<MudTd DataLabel="Rev Code">@context.PCBRev</MudTd>
<MudTd DataLabel="Ghi chú">@(context.PlanPriority.ToString() + context.Remark)</MudTd>
<MudTablePager PageSizeOptions="new int[] { 5, 10, 25, 50, 100 }" />
<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.Directions" Color="Color.Primary" Disabled="@(LineKittingDivList.Count() == 0)" OnClick="TransferMgzDivClick">Out chia lẻ</MudButton>
<MudOverlay Visible="LineTransferWindowActive" VisibleChanged="OnOverlayLineTransferVisibleChanged" DarkBackground>
<MudCard Style="@($"width: 800px;")">
<MudCardHeader Class="d-flex justify-content-between align-items-center" Style="@($"background:{Colors.Green.Lighten5}; height: 60px; border-bottom: 1px solid #BDBDBD; margin-left: 0px; margin-right: 0px; padding-bottom: 8px;")">
<MudText Typo="Typo.h5" Class="">
Transfer vật liệu ra line
<MudIconButton Icon="@Icons.Material.Filled.Close" OnClick="@(()=>{LineTransferWindowActive = false;})" />
<MudCardContent Class="d-flex flex-column flex-grow-1 gap-2">
<MudTextField @ref="MagazinLineScanCode" @bind-Value="MagazinLineTransfer" Label="Scan mã magazin" Disabled="LineTransferPrintEnable" Variant="Variant.Text" OnKeyDown="@EnterMagazineScanLineTransferCodeEvent" />
<MudNumericField @ref="TempScanCode" ReadOnly="true" Variant="Variant.Text" Label="Số lượng" @bind-Value="MagazinQtyLineTransfer" Disabled="LineTransferPrintEnable" />
<MudTable T="MaterialLineTransferInfoDTO" Items="@LineTransferList" Hover="true" Virtualize="false" FixedHeader="true" Dense="true" FixedFooter="true" Height="250px" SortLabel="Sort By">
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.Line)">Line cấp</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.PCBCode)">PCB code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.PCBRev)">Rev code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.PCBQty)">Số lượng</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.PCBMode)">Model Basic</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.BoxCode)">Thùng hàng</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.PlanDate)">Ngày plan</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialLineTransferInfoDTO, object>(x=>x.KittingType)">Loại kitting</MudTableSortLabel></MudTh>
<MudTd DataLabel="Line cấp">@context.Line</MudTd>
<MudTd DataLabel="PCB code">@context.PCBCode</MudTd>
<MudTd DataLabel="Rev code">@context.PCBRev</MudTd>
<MudTd DataLabel="Số lượng">@context.PCBQty</MudTd>
<MudTd DataLabel="Model Basic">@context.PCBMode</MudTd>
<MudTd DataLabel="Thùng hàng">@context.BoxCode</MudTd>
<MudTd DataLabel="Ngày plan">@context.PlanDate.ToString("dd/MM/yyyy")</MudTd>
<MudTd DataLabel="Loại kitting">@context.KittingType</MudTd>
<MudIconButton Color="@Color.Error" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Delete" OnClick="@(() => DeleteLineTransferClick(@context))"></MudIconButton>
<MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
<div class="d-flex flex-row">
<MudTextField @bind-Value="PrinterIp" Label="Địa chỉ IP máy In" Variant="Variant.Outlined" Margin="Margin.Dense" Disabled="IpPrinterDisable" />
<MudIconButton Icon="@Icons.Material.Filled.Settings" Color="Color.Primary" OnClick="PrinterIpSaveClick" />
@*<MudButton Variant="Variant.Filled" EndIcon="@Icons.Material.Filled.AddBox" Color="Color.Success" OnClick="TransferSubmitPlanClick">Submit</MudButton>*@
<MudOverlay Visible="PlanDetailWindowActive" DarkBackground>
<MudCard Style="@($"width: 1200px;")">
<MudCardHeader Class="d-flex justify-content-between align-items-center" Style="@($"background:{Colors.Green.Lighten5}; height: 60px; border-bottom: 1px solid #BDBDBD; margin-left: 0px; margin-right: 0px; padding-bottom: 8px;")">
<MudText Typo="Typo.h5" Class="">
<MudIconButton Icon="@Icons.Material.Filled.Close" OnClick="@(()=>{PlanDetailWindowActive = false;})" />
<MudTabs Elevation="2" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pa-6">
<MudTabPanel Icon="@Icons.Material.Filled.AddShoppingCart" Text="Danh sách hàng đã kitting" BadgeData="KittingMgzDetailList.Count()" BadgeColor="Color.Success">
<MudTable T="MaterialMgzForPlanDTO" Items="@KittingMgzDetailList" Hover="true" Virtualize="false" FixedHeader="true" Dense="true" FixedFooter="true" Height="250px" SortLabel="Sort By">
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.MgzCode)">Magazin Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.PCBCode)">PCB Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.PCBQty)">Kitting Qty</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.RackName)">Rack name</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.BoxName)">Box name</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.Status)">Trạng thái</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.Tracking)">Công đoạn</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzForPlanDTO, object>(x=>x.KittingType)">Loại Kitting</MudTableSortLabel></MudTh>
<div class="d-flex flex-row gap-1 justify-content-end">
@*<MudIconButton Color="@Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Directions" Disabled="@(!KittingMgzDetailList.Any(s=>s.Tracking == MagazineTracking.IN_RACK))" OnClick="MoveOutAllKttingMgzPlanClick"></MudIconButton>*@
<MudTd DataLabel="Magazin Code">@context.MgzCode</MudTd>
<MudTd DataLabel="PCB Code">@context.PCBCode</MudTd>
<MudTd DataLabel="Kitting Qty">@context.PCBQty</MudTd>
<MudTd DataLabel="Rack name">@context.RackName</MudTd>
<MudTd DataLabel="Box name">@context.BoxName</MudTd>
<MudTd DataLabel="Trạng thái">@context.StatusText</MudTd>
<MudTd DataLabel="Công đoạn">@context.TrackingText</MudTd>
<MudTd DataLabel="Loại Kitting">@context.KittingType</MudTd>
<div class="d-flex flex-row gap-1 justify-content-end">
<MudIconButton Color="@Color.Error" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Delete" Disabled="@(context.Status != MagazineStatus.KITTING)" OnClick="@(() => DeleteKttingMgzPlanClick(@context))"></MudIconButton>
<MudIconButton Color="@Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Directions" Disabled="@(context.Status != MagazineStatus.KITTING || context.Tracking != MagazineTracking.IN_RACK)" OnClick="@(() => MoveOutKttingMgzPlanClick(@context))"></MudIconButton>
<MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
<MudTabPanel Icon="@Icons.Material.Filled.CallMissedOutgoing" Text="Danh sách hàng đã transfer" BadgeData="TransferMgzDetailList.Count()" BadgeColor="Color.Error">
<MudTable T="MaterialMgzStatusDTO" Items="@TransferMgzDetailList" Hover="true" Virtualize="false" FixedHeader="true" Dense="true" FixedFooter="true" Height="250px" SortLabel="Sort By">
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.MagazineCode)">Magazin Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.PCBCode)">PCB Code</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.PCBQty)">Kitting Qty</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.PCBRev)">Mã Rev</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.PCBPackInBox)">Số box</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.Status)">Trạng thái</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.Tracking)">Công đoạn</MudTableSortLabel></MudTh>
<MudTh><MudTableSortLabel SortBy="new Func<MaterialMgzStatusDTO, object>(x=>x.ControlType)">Loại output</MudTableSortLabel></MudTh>
<MudTd DataLabel="Magazin Code">@context.MagazineCode</MudTd>
<MudTd DataLabel="PCB Code">@context.PCBCode</MudTd>
<MudTd DataLabel="Kitting Qty">@context.PCBQty</MudTd>
<MudTd DataLabel="Mã Rev">@context.PCBRev</MudTd>
<MudTd DataLabel="Số box">@context.PCBPackInBox</MudTd>
<MudTd DataLabel="Trạng thái">@context.StatusText</MudTd>
<MudTd DataLabel="Công đoạn">@context.TrackingText</MudTd>
<MudTd DataLabel="Loại output">@context.ControlType</MudTd>
<MudIconButton Color="@Color.Error" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Delete" Disabled="@(context.Status != MagazineStatus.TRANSFERED)" OnClick="@(() => DeleteTransferMgzPlanClick(@context))"></MudIconButton>
<MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
<MudOverlay Visible="LoadDataActive" DarkBackground="true" ZIndex="9999" AutoClose="false">
<MudProgressCircular Color="Color.Primary" Style="height:70px;width:70px;" Indeterminate="true" />
#region Tính chiều cao của table
protected override async Task OnAfterRenderAsync(bool firstRender)
await JSRuntime.InvokeVoidAsync("updateTableHeight");
private DateTime? PlanDateFromSearch = DateTime.Now.AddDays(1);
private DateTime? PlanDateToSearch = DateTime.Now.AddDays(1);
private int PlanKittingStatusSearch = 0;
private int PlanOutputStatusSearch = 0;
private int PlanStatusSearch = LineTransStatus.ALL;
private int PlanResendCountSearch = LineTransPlanCount.ALL;
private int SearchCountResult = 0;
private string LineNameSearch = "";
private string PCBCodeSearch = "";
private bool LoadDataActive = false;
private List<MaterialTransPlanDTO> PlanDataSearchList = new List<MaterialTransPlanDTO>();
private MaterialTransPlanDTO selectedPlan = null;
private DateTime? PlanDate = DateTime.Now;
private DateTime? PlanTimeStart = DateTime.Now;
private int PlanPriority;
private string PlanRemark;
private string PlanBasicModel;
private string PlanPCBCode;
private string PlanREVCode;
private int PlanQuantity;
private string ExcelPlanAddWindow;
CultureInfo provider = CultureInfo.InvariantCulture;
private string[] formatDate = { "dd/MM/yyyy", "d/M/yyyy", "dd-MM-yyyy", "d-M-yyyy" };
private string[] formatDateTime = { "dd/MM/yyyy HH:mm", "d/M/yyyy H:m", "dd-MM-yyyy HH:mm", "d-M-yyyy H:m" };
private List<MaterialTransPlanEntity> materialSubmitLinePlans = new List<MaterialTransPlanEntity>();
bool PlanAddWindowActive = false;
private bool PlanEditWindowActive = false;
private MaterialTransPlanEntity CurrentPlanSelected = null;
private bool PlanKittingWindowActive = false;
private string MagazinKitting = "";
private List<MaterialLinePlanKittingDTO> MagazineScanList = new List<MaterialLinePlanKittingDTO>();
private List<MaterialLinePlanKittingTransfer> kittingTransferLinePlans = new List<MaterialLinePlanKittingTransfer>();
private List<MaterialMgzEntity> KittingCurrentStockList = new List<MaterialMgzEntity>();
private bool PlanOutputWindowActive = false;
private List<MaterialMgzEntity> TransferCurrentStockList = new List<MaterialMgzEntity>();
private MudTextField<string> MagazinScanCode;
private MudTextField<string> MagazinLineScanCode;
private MudTextField<string> TempFocus;
private MudNumericField<int> TempScanCode;
private bool PlanDetailWindowActive = false;
private List<MaterialMgzForPlanDTO> KittingMgzDetailList = new List<MaterialMgzForPlanDTO>();
private List<MaterialMgzStatusDTO> TransferMgzDetailList = new List<MaterialMgzStatusDTO>();
private bool LineTransferWindowActive = false;
private string MagazinLineTransfer = "";
private int MagazinQtyLineTransfer = 0;
private List<MaterialLineTransferInfoDTO> LineTransferList = new List<MaterialLineTransferInfoDTO>();
private string PrinterIp = "";
private bool IpPrinterDisable = false;
private bool LineTransferPrintEnable = false;
protected override Task OnInitializedAsync()
return base.OnInitializedAsync();
private void OpenDialog(string msg, int status)
var parameters = new DialogParameters<NDialog>();
parameters.Add(x => x.ContentText, msg);
parameters.Add(x => x.Severity, status);
var options = new DialogOptions() { MaxWidth = MaxWidth.ExtraSmall };
DialogService.Show<NDialog>("", parameters, options);
private string SearchRowStyleFunc(MaterialTransPlanDTO plan, int index)
if(plan.Status == LineTransStatus.NG ) return TransferPlanColorStatus.NG;
if (plan.KittingPCBQty == plan.PCBPlanQty && plan.TransferPCBQty != plan.PCBPlanQty) return TransferPlanColorStatus.KIT_DONE;
if (plan.KittingPCBQty == plan.PCBPlanQty && plan.TransferPCBQty == plan.PCBPlanQty) return TransferPlanColorStatus.TRANS_DONE;
return TransferPlanColorStatus.NEW_PLAN;
private async Task PlanSearchClick()
PlanDataSearchList.Clear();
PlanDataSearchList = await _unit.MaterialTransPlans.GetAllPlanAsync1(PlanDateFromSearch.Value, PlanDateToSearch.Value, PlanKittingStatusSearch, PlanOutputStatusSearch, LineNameSearch.Trim(), PCBCodeSearch.Trim(), PlanStatusSearch, PlanResendCountSearch);
SearchCountResult = PlanDataSearchList.Count();
var _listPlanErrorRemain = PlanDataSearchList.Where(p => (p.KittingPCBQty != (p.PCBPlanQty - p.KittingRemainQty) || p.TransferPCBQty != (p.PCBPlanQty - p.OutputRemainQty))).ToList();
foreach (var _plan in _listPlanErrorRemain)
var _p = (await _unit.MaterialTransPlans.GetByIdAsync(_plan.Id));
_p.KittingRemainQty = _plan.PCBPlanQty - _plan.KittingPCBQty;
_p.OutputRemainQty = _plan.PCBPlanQty - _plan.TransferPCBQty;
_p.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(_p);
await _unit.CompleteAsync();
async Task ExportToExcel()
if(PlanDataSearchList.Count == 0) {
Snackbar.Add("Chưa có plan cần xuất",Severity.Error);
var _listmgzLines = PlanDataSearchList
.SelectMany(p => p.KittingList, (p, item) => new
.Select((x, index) => new MaterialKittingTransferDTO
PlanDate = x.PlanData.PlanDate,
LineName = x.PlanData.LineName,
PCBCode = x.PlanData.PCBCode,
PCBRev = x.PlanData.PCBRev,
ModelBasic = x.PlanData.ModelBasic,
PlanPriority = x.PlanData.PlanPriority,
Remark = x.PlanData.Remark,
PCBPlanQty = x.PlanData.PCBPlanQty,
MgzCode = x.KittingItem.MagazineCode,
TransferPCBQty = x.KittingItem.PCBQty,
RemainTransferPCBQty = x.PlanData.RemainTransferPCBQty,
BoxName = x.KittingItem.MagazineCode.Substring(x.KittingItem.MagazineCode.IndexOf('T'), 5)
var content = await _exportExcel.ExportToExcelAsync(_listmgzLines);
var fileName = DateTime.Now.ToString("ddMMyyyy_hhmm") + "_kehoach.xlsx";
await JSRuntime.InvokeVoidAsync("exportToExcel", Convert.ToBase64String(content), fileName);
Snackbar.Add("Đã xuất file thành công!", Severity.Success);
#region Line Transfer Manual
private async Task OpenLineTransferClick()
LineTransferList.Clear();
var ip = await _localstorage.GetItemAsStringAsync("printerIp");
if (!string.IsNullOrEmpty(ip))
PrinterIp = ip.Trim('"');
LineTransferPrintEnable = false;
IpPrinterDisable = false;
LineTransferPrintEnable = true;
LineTransferWindowActive = true;
private async Task EnterMagazineScanLineTransferCodeEvent(KeyboardEventArgs e)
await TempScanCode.FocusAsync();
if (string.IsNullOrEmpty(MagazinLineTransfer))
Snackbar.Add($"Mã scan không được để trống. Kiểm tra lại", Severity.Error);
ChangeFocusLineScanMagazin();
if (MagazinLineTransfer.Length < 15 && MagazinLineTransfer.Length > 18)
Snackbar.Add($"Mã scan không đúng. Kiểm tra lại", Severity.Error);
ChangeFocusLineScanMagazin();
var _magazinExist = await _unit.MaterialTransPlanKitMgzHises.GetMagazinInfo(MagazinLineTransfer.Trim());
if (_magazinExist == null)
Snackbar.Add($"Magazin {MagazinKitting} không có trong stock", Severity.Error);
ChangeFocusLineScanMagazin();
var result = await tcpClient.PrintLabelTransferLine(PrinterIp, _magazinExist.Line, _magazinExist.PCBCode, _magazinExist.PCBQty, _magazinExist.PCBMode, _magazinExist.BoxCode,_magazinExist.PCBRev,_magazinExist.KittingType==KittingTypes.MANUAL?"N/A":"AUTO",_magazinExist.PlanDate.Date.ToString("dd/MM/yyyy"));
LineTransferPrintEnable = true;
OpenDialog("Không in được label", NDialogSeverity.ERROR);
ChangeFocusLineScanMagazin();
LineTransferList.Insert(0, _magazinExist);
MaterialTransPlanOutMgzHisEntity _transferPlanHis = new MaterialTransPlanOutMgzHisEntity();
_transferPlanHis.PlanId = _magazinExist.PlanId;
_transferPlanHis.MagazineId = _magazinExist.MgzId;
_transferPlanHis.UseStatus = UseStatus.USE;
_transferPlanHis.OutputType = KittingTypes.MANUAL;
_transferPlanHis.CreateAt = DateTime.Now;
await _unit.MaterialTransPlanOutMgzHises.AddAsync(_transferPlanHis);
var _magazineExist = await _unit.MaterialMgzes.GetByIdAsync(_magazinExist.MgzId);
_magazineExist.Status = MagazineStatus.TRANSFERED;
_magazineExist.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_magazineExist);
MaterialMgzHisEntity _magazineHis = new MaterialMgzHisEntity();
_magazineHis.CreateAt = DateTime.Now;
_magazineHis.MagazineId = _magazinExist.MgzId;
_magazineHis.Status = MagazineStatus.TRANSFERED;
await _unit.MaterialMgzHises.AddAsync(_magazineHis);
var _box = await _unit.MaterialMagBoxes.GetByIdAsync(_magazinExist.BoxId);
_box.BoxStatus = BoxStatus.NOT_PCB;
_box.MagazineId = Guid.Empty;
_unit.MaterialMagBoxes.Update(_box);
var _planUpdate = await _unit.MaterialTransPlans.GetByIdAsync(_magazinExist.PlanId);
_planUpdate.OutputRemainQty -= _magazinExist.PCBQty;
_planUpdate.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(_planUpdate);
await _unit.CompleteAsync();
Snackbar.Add("Transfer thành công", Severity.Success);
ChangeFocusLineScanMagazin();
private void DeleteLineTransferClick(MaterialLineTransferInfoDTO item)
LineTransferList.Remove(item);
private async Task ChangeFocusLineScanMagazin()
MagazinQtyLineTransfer = 0;
MagazinLineTransfer = "";
await MagazinLineScanCode.FocusAsync();
private async Task OnOverlayLineTransferVisibleChanged(bool visible)
await MagazinLineScanCode.FocusAsync();
private async Task DetailPlanClick(MaterialTransPlanEntity context)
CurrentPlanSelected = null;
var _planDB = await _unit.MaterialTransPlans.GetByIdAsync(context.Id);
if (_planDB != null) CurrentPlanSelected = _planDB;
KittingMgzDetailList = await _unit.MaterialTransPlans.GetListKitingForPlan(context.Id);
TransferMgzDetailList = await _unit.MaterialTransPlanOutMgzHises.GetAllMagazineTransfer(context.Id);
PlanDetailWindowActive = true;
private async Task MoveOutKttingMgzPlanClick(MaterialMgzForPlanDTO context)
var _rack = (await _unit.MaterialMagRacks.FindAsync(s => s.BoxId == context.BoxId)).FirstOrDefault();
OpenDialog("Không tìm thấy rack", NDialogSeverity.ERROR);
var parameters = new DialogParameters<DialogSelectBuffOut>();
parameters.Add(x => x.ContentText, $"Bạn muốn đưa thùng hàng đến đâu?");
parameters.Add(x => x.ButtonText, "Chắc chắn");
parameters.Add(x => x.Color, Color.Error);
if (_rack.RackStatus == RackStatus.HAS_FIXED_BOX)
parameters.Add(x => x.BufferTypeSelect, BufferTypes.OUTPUT);
parameters.Add(x => x.BufferTypeSelect, BufferTypes.BOTH);
var options = new DialogOptions() { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
var dialog = DialogService.Show<DialogSelectBuffOut>("Lấy hàng ra buffer", parameters, options);
var result = await dialog.Result;
var buff = (MaterialMagBuffEntity)result.Data;
var _ctu = await _unit.CTUMissions.CreateMission(_rack.PositionCode, buff.PositionCode, buff.BufferType,"","",_rack.RackStatus);
_logService.SaveUpdateLog(LogType.WRN, "Output kế hoạch mission created");
RunTaskResMsgResult ctuReqResult = null;
if (buff.BufferType == BufferTypes.OUTPUT)
ctuReqResult = await CTUService.RunTask(_ctu.StartPosCode, _ctu.EndPosCode, _ctu.TaskType == BufferTypes.OUTPUT ? false : true);
ctuReqResult = await CTUService.RunTask(_ctu.StartPosCode, _ctu.EndPosCode, _ctu.TaskType == BufferTypes.BOTH ? false : true);
if (!ctuReqResult.result)
_ctu.MissionStatus = MissionStatus.ERROR;
_ctu.CMDReturn = ctuReqResult.TaskResponseInfo.data;
_ctu.ModifiedAt = DateTime.Now;
await _unit.CTUMissions.UpdateMission(_ctu,MissionStatus.ERROR);
_logService.SaveUpdateLog(LogType.WRN, "Output kế hoạch mission error");
if (ctuReqResult.TaskResponseInfo.code != "99")
_rack.MissionId = _ctu.Id;
await _unit.MaterialMagRacks.RackUpdateStatus(_rack, RackStatus.UNDEFINED);
_ctu.CMDReturn = ctuReqResult.TaskResponseInfo.data;
await _unit.CTUMissions.UpdateMission(_ctu,MissionStatus.SEND_CTU_OK);
_logService.SaveUpdateLog(LogType.WRN, "Output kế hoạch mission ok");
_rack.MissionId = _ctu.Id;
await _unit.MaterialMagRacks.RackUpdateStatus(_rack, RackStatus.OUT_WAITING);
private void MoveOutAllKttingMgzPlanClick()
private async Task DeleteKttingMgzPlanClick(MaterialMgzForPlanDTO context)
var parameters = new DialogParameters<DialogYesNo>();
parameters.Add(x => x.ContentText, $"Bạn có chắc chắn muốn xóa magazine {context.MgzCode} này không?");
parameters.Add(x => x.ButtonText, "Ðồnng ý");
parameters.Add(x => x.Color, Color.Error);
var options = new DialogOptions() { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
var dialog = DialogService.Show<DialogYesNo>("Yêu cầu xóa magazine đã kitting", parameters, options);
var result = await dialog.Result;
var returnResult = await _unit.MaterialTransPlans.DeleteMagazineInKittingList(context.MgzId);
OpenDialog("Chưa xóa được magazine",NDialogSeverity.ERROR);
Snackbar.Add("Xóa thành công!", Severity.Success);
KittingMgzDetailList.Remove(context);
private async Task DeleteTransferMgzPlanClick(MaterialMgzStatusDTO context)
var parameters = new DialogParameters<DialogYesNo>();
parameters.Add(x => x.ContentText, $"Bạn có chắc chắn muốn xóa magazine {context.MagazineCode} này không?");
parameters.Add(x => x.ButtonText, "Ðồnng ý");
parameters.Add(x => x.Color, Color.Error);
var options = new DialogOptions() { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
var dialog = DialogService.Show<DialogYesNo>("Yêu cầu xóa magazine đã transfer", parameters, options);
var result = await dialog.Result;
if (context.Status != MagazineStatus.TRANSFERED)
OpenDialog($"Magazine {context.MagazineCode} không thể xóa được vì đã chuyển trạng thái", NDialogSeverity.ERROR);
var _mgzTranHis = (await _unit.MaterialTransPlanOutMgzHises.FindAsync(a => a.MagazineId == context.Id)).FirstOrDefault();
OpenDialog($"Không tìm thấy lịch sử magazine transfer {context.MagazineCode}", NDialogSeverity.ERROR);
_unit.MaterialTransPlanOutMgzHises.Delete(_mgzTranHis);
var _mgzKitHis = (await _unit.MaterialTransPlanKitMgzHises.FindAsync(a => a.MagazineId == context.Id)).FirstOrDefault();
OpenDialog($"Không tìm thấy lịch sử magazine kitting {context.MagazineCode}", NDialogSeverity.ERROR);
_unit.MaterialTransPlanKitMgzHises.Delete(_mgzKitHis);
var _qtyTem = CurrentPlanSelected.OutputRemainQty + context.PCBQty;
if (_qtyTem > CurrentPlanSelected.PCBPlanQty) CurrentPlanSelected.OutputRemainQty = CurrentPlanSelected.PCBPlanQty;
else CurrentPlanSelected.OutputRemainQty += context.PCBQty;
CurrentPlanSelected.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(CurrentPlanSelected);
var _qtyTem1 = CurrentPlanSelected.KittingRemainQty + context.PCBQty;
if (_qtyTem1 > CurrentPlanSelected.PCBPlanQty) CurrentPlanSelected.KittingRemainQty = CurrentPlanSelected.PCBPlanQty;
else CurrentPlanSelected.KittingRemainQty += context.PCBQty;
CurrentPlanSelected.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(CurrentPlanSelected);
var _mgz = await _unit.MaterialMgzes.GetByIdAsync(context.Id);
OpenDialog($"Không tìm thấy magazine {context.MagazineCode}", NDialogSeverity.ERROR);
_mgz.Status = MagazineStatus.STOCK_RETURN;
_mgz.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_mgz);
MaterialMgzHisEntity _mgzHis = new MaterialMgzHisEntity
Status = MagazineStatus.STOCK_RETURN,
await _unit.MaterialMgzHises.AddAsync(_mgzHis);
await _unit.CompleteAsync();
TransferMgzDetailList.Remove(context);
var _kittingMgz = KittingMgzDetailList.Where(k => k.MgzId == context.Id).FirstOrDefault();
if (_kittingMgz != null) KittingMgzDetailList.Remove(_kittingMgz);
private async Task EditPlanClick(MaterialTransPlanEntity context)
CurrentPlanSelected = null;
var _planDB = await _unit.MaterialTransPlans.GetByIdAsync(context.Id);
if (_planDB != null) CurrentPlanSelected = _planDB;
PlanEditWindowActive = true;
private async Task EditSubmitPlanClick()
var planExistEdit = (await _unit.MaterialTransPlans.FindAsync(p =>p.UseStatus == UseStatus.USE && p.PlanDate.Date == CurrentPlanSelected.PlanDate.Date &&
p.LineName == CurrentPlanSelected.LineName.Trim().ToUpper() &&
p.StartTime == CurrentPlanSelected.StartTime && p.PlanPriority == CurrentPlanSelected.PlanPriority &&
p.PCBCode == CurrentPlanSelected.PCBCode.Trim().ToUpper())).FirstOrDefault();
if (planExistEdit != null)
_unit.MaterialTransPlans.UpdatePlan(CurrentPlanSelected);
Snackbar.Add("Đã sửa thành công!", Severity.Success);
PlanEditWindowActive = false;
CurrentPlanSelected = null;
private async Task DeletePlanClick(MaterialTransPlanDTO plan)
var parameters = new DialogParameters<DialogYesNo>();
parameters.Add(x => x.ContentText, $"Bạn có chắc chắn muốn xóa kế hoạch ngày {plan.PlanDate.Date.ToString("dd/MM/yyyy")} line {plan.LineName} này không?");
parameters.Add(x => x.ButtonText, "Ðồnng ý");
parameters.Add(x => x.Color, Color.Error);
var options = new DialogOptions() { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
var dialog = DialogService.Show<DialogYesNo>("Yêu cầu xóa plan", parameters, options);
var result = await dialog.Result;
var _plan = await _unit.MaterialTransPlans.GetByIdAsync(plan.Id);
if (_plan.KittingRemainQty == _plan.PCBPlanQty && _plan.OutputRemainQty == _plan.PCBPlanQty)
_unit.MaterialTransPlans.Delete(_plan);
await _unit.CompleteAsync();
Snackbar.Add($"Đã xóa kế hoạch thành công", Severity.Success);
PlanDataSearchList.Remove(plan);
OpenDialog("Không thể xóa kế hoạch này vì đã chuẩn bị hoặc đã cấp", NDialogSeverity.ERROR);
private async Task KittingPlanClick(MaterialTransPlanEntity context)
CurrentPlanSelected = null;
var _planDB = await _unit.MaterialTransPlans.GetByIdAsync(context.Id);
if (_planDB != null) CurrentPlanSelected = _planDB;
var a = await _unit.MaterialMgzes.GetAllAsync();
KittingCurrentStockList = (await _unit.MaterialMgzes.FindAsync(m=>m.UseStatus == UseStatus.USE &&
m.PCBCode == context.PCBCode &&
m.Status == MagazineStatus.INSTOCK
MagazineScanList.Clear();
PlanKittingWindowActive = true;
private async Task OnOverlayKittingVisibleChanged(bool visible)
await MagazinScanCode.FocusAsync();
private async Task EnterMagazineScanKittingCodeEvent(KeyboardEventArgs e)
await TempFocus.FocusAsync();
if (string.IsNullOrEmpty(MagazinKitting))
Snackbar.Add($"Mã scan không được để trống. Kiểm tra lại", Severity.Error);
await ChangeFocusScanMagazin();
if (MagazinKitting.Length < 15 && MagazinKitting.Length > 18)
Snackbar.Add($"Mã scan không đúng. Kiểm tra lại", Severity.Error);
await ChangeFocusScanMagazin();
if (CurrentPlanSelected == null)
Snackbar.Add("Kế hoạch không tổn tại",Severity.Error);
await ChangeFocusScanMagazin();
var _magazinExist = (await _unit.MaterialMgzes.FindAsync(b =>b.UseStatus == UseStatus.USE &&
b.PCBCode == CurrentPlanSelected.PCBCode &&
b.MagazineCode == MagazinKitting.Trim().ToUpper() && b.Status == MagazineStatus.INSTOCK)).FirstOrDefault();
if (_magazinExist == null)
Snackbar.Add($"Magazin {MagazinKitting} không có trong stock", Severity.Error);
await ChangeFocusScanMagazin();
KittingCurrentStockList.Remove(_magazinExist);
var _currentPlan = await _unit.MaterialTransPlans.GetByIdAsync(CurrentPlanSelected.Id);
Snackbar.Add($"Không tồn tại plan này", Severity.Error);
await ChangeFocusScanMagazin();
if (_currentPlan.KittingRemainQty != CurrentPlanSelected.KittingRemainQty) CurrentPlanSelected = _currentPlan;
if ((_magazinExist.PCBQty + MagazineScanList.Sum(k=>k.Quantity)) > _currentPlan.KittingRemainQty)
Snackbar.Add($"Số lượng vượt quá remain hiện tại", Severity.Error);
await ChangeFocusScanMagazin();
if (MagazineScanList.Where(k => k.MagazinCode == MagazinKitting.Trim().ToUpper()).FirstOrDefault() != null)
Snackbar.Add($"Magazin đã được thêm", Severity.Error);
await ChangeFocusScanMagazin();
MaterialLinePlanKittingDTO _kittingMgz = new MaterialLinePlanKittingDTO();
_kittingMgz.Id = _currentPlan.Id;
_kittingMgz.MagazinCode = _magazinExist.MagazineCode;
_kittingMgz.Quantity = _magazinExist.PCBQty;
_kittingMgz.LineName = _currentPlan.LineName;
_kittingMgz.PlanDate = _currentPlan.PlanDate;
_kittingMgz.ModelBasic = _currentPlan.ModelBasic;
_kittingMgz.PCBCode = _currentPlan.PCBCode;
_kittingMgz.PCBPlanQty = _currentPlan.PCBPlanQty;
_kittingMgz.KittingRemainQty = _currentPlan.KittingRemainQty;
_kittingMgz.OutputRemainQty = _currentPlan.OutputRemainQty;
_kittingMgz.MgzId = _magazinExist.Id;
MagazineScanList.Insert(0, _kittingMgz);
await ChangeFocusScanMagazin();
private async Task ChangeFocusScanMagazin()
await MagazinScanCode.FocusAsync();
private async Task DeleteKittingPlanSubmitClick(MaterialLinePlanKittingDTO item)
MagazineScanList.Remove(item);
var _mgzReturn = await _unit.MaterialMgzes.GetByIdAsync(item.MgzId);
KittingCurrentStockList.Add(_mgzReturn);
private void CloseKittingPlanWindow()
PlanKittingWindowActive = false;
CurrentPlanSelected = null;
MagazineScanList.Clear();
private async Task KittingSubmitPlanClick()
var _planLineUpdate = await _unit.MaterialTransPlans.GetByIdAsync(CurrentPlanSelected.Id);
if (_planLineUpdate == null)
Snackbar.Add("Kế hoạch không tổn tại", Severity.Error);
await ChangeFocusScanMagazin();
foreach (var item in MagazineScanList)
MaterialTransPlanKitMgzHisEntity _kittingPlanHis = new MaterialTransPlanKitMgzHisEntity();
_kittingPlanHis.PlanId = item.Id;
_kittingPlanHis.MagazineId = item.MgzId;
_kittingPlanHis.UseStatus = UseStatus.USE;
_kittingPlanHis.KittingType = KittingTypes.MANUAL;
_kittingPlanHis.CreateAt = DateTime.Now;
await _unit.MaterialTransPlanKitMgzHises.AddAsync(_kittingPlanHis);
var _magazineExist = await _unit.MaterialMgzes.GetByIdAsync(item.MgzId);
_magazineExist.Status = MagazineStatus.KITTING;
_magazineExist.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_magazineExist);
MaterialMgzHisEntity _magazineHis = new MaterialMgzHisEntity();
_magazineHis.CreateAt = DateTime.Now;
_magazineHis.MagazineId = item.MgzId;
_magazineHis.Status = MagazineStatus.KITTING;
await _unit.MaterialMgzHises.AddAsync(_magazineHis);
var _planUpdate = await _unit.MaterialTransPlans.GetByIdAsync(CurrentPlanSelected.Id);
_planUpdate.KittingRemainQty -= MagazineScanList.Sum(m => m.Quantity);
_planUpdate.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(_planUpdate);
await _unit.CompleteAsync();
OpenDialog($"Đã kitting cho kế hoạch thành công", NDialogSeverity.SUCCESS);
PlanKittingWindowActive = false;
CurrentPlanSelected = null;
MagazineScanList.Clear();
List<MaterialMgzForPlanDTO> MaterialMgzEntities = new List<MaterialMgzForPlanDTO>();
private List<MaterialTransPlanEntity> LineKittingDivList = new List<MaterialTransPlanEntity>();
private List<MaterialTransPlanEntity> LineMaterialDivList = new List<MaterialTransPlanEntity>();
private bool LineMaterialDivWindowActive = false;
private MudTextField<string> MagazinLineDivScanCode;
private string MagazinLineDivTransfer = "";
private string DivMagazineCode = "";
private string DivPcbCode = "";
private int DivQuantity = 0;
private string DivRevCode = "";
private int DivBoxQuantity = 0;
private bool ScanDivMagazineDisable = true;
private int InputQtyAdd = 0;
private MudNumericField<int> QuantityMudNumericField;
private MudTextField<string> BoxMudTextField;
private MudTextField<string> BoxDivMudTextField;
private MudTextField<string> MaterialDivMudTextField;
private MudNumericField<int> QuantityDivMudNumericField;
private string InputBoxCodeAdd = "";
private string ScanMaterialDivCodeAdd = "";
private List<MaterialPack> InputTempDataAddList = new List<MaterialPack>();
private MaterialMgzEntity DivCurrentScan = new MaterialMgzEntity();
private MaterialTransPlanEntity PlanDivSelected = null;
private void DeletePlanDivClick(MaterialTransPlanEntity plan)
private async Task CreateMagazineForPlan(MaterialTransPlanEntity plan)
ScanDivMagazineDisable = false;
InputTempDataAddList.Clear();
ScanMaterialDivCodeAdd = "";
await BoxDivMudTextField.FocusAsync();
private void InputTempListDeleteClick(MaterialPack material)
private async Task DivMaterialPlanClick()
foreach (var plan in PlanDataSearchList)
var _kitList = await _unit.MaterialTransPlanKitMgzHises.FindAsync(h=>h.PlanId == plan.Id && h.UseStatus == UseStatus.USE);
if (_kitList.Count() > 0)
foreach(var p in _kitList)
var _mgz = (await _unit.MaterialMgzes.FindAsync(m=>m.Id==p.MagazineId)).FirstOrDefault();
if (_mgz != null) qtyKitting += _mgz.PCBQty;
plan.KittingRemainQty = plan.PCBPlanQty - qtyKitting;
plan.ModifiedAt = DateTime.Now;
var _outList = await _unit.MaterialTransPlanOutMgzHises.FindAsync(h=>h.PlanId == plan.Id && h.UseStatus == UseStatus.USE);
foreach (var p in _outList)
var _mgz = (await _unit.MaterialMgzes.FindAsync(m=>m.Id==p.MagazineId)).FirstOrDefault();
if (_mgz != null) qtyTransfer += _mgz.PCBQty;
plan.OutputRemainQty = plan.PCBPlanQty - qtyTransfer;
plan.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(plan);
await _unit.CompleteAsync();
private async Task EnterBoxScanMaterialDivCodeEvent(KeyboardEventArgs e)
var _box = (await _unit.MaterialMagBoxes.FindAsync(b=>b.BoxName==InputBoxCodeAdd && b.MagazineId == Guid.Empty)).FirstOrDefault();
OpenDialog("Không tìm thấy thùng trống", NDialogSeverity.ERROR);
await MaterialDivMudTextField.FocusAsync();
private async Task EnterMaterialScanDivCodeEvent(KeyboardEventArgs e)
await QuantityDivMudNumericField.FocusAsync();
private async Task EnterQuantityMaterialDivCodeEvent(KeyboardEventArgs e)
OpenDialog("Không có số lượng", NDialogSeverity.ERROR);
InputTempDataAddList.Add(new MaterialPack{
BarCode = ScanMaterialDivCodeAdd,
MaterialCode = DivCurrentScan.PCBCode,
ScanMaterialDivCodeAdd = "";
await MaterialDivMudTextField.FocusAsync();
private async Task EnterMagazineScanMaterialDivCodeEvent(KeyboardEventArgs e)
var _mgz = (await _unit.MaterialMgzes.FindAsync(m => m.MagazineCode == DivMagazineCode && m.Status == MagazineStatus.DIVIDED)).FirstOrDefault();
OpenDialog("Không tìm thấy magazine cần chia lẻ", NDialogSeverity.ERROR);
LineMaterialDivList.Clear();
LineMaterialDivList = (await _unit.MaterialTransPlans.FindAsync(p=>p.UseStatus == UseStatus.USE &&
p.PCBCode == _mgz.PCBCode &&
p.PCBRev == _mgz.PCBRev &&
p.AutoMaping == LineTransAutoMapping.MAPPING &&
p.Status == LineTransStatus.DIV
private async Task OnOverlayMaterialDivVisibleChanged(bool visible)
await MagazinLineDivScanCode.FocusAsync();
private async Task ChialeSearchClick()
private MaterialTransPlanEntity planSelectedToDiv = new MaterialTransPlanEntity();
private async Task ViewListMaterialPlanClick(MaterialTransPlanDTO context)
LineKittingDivList.Clear();
MaterialMgzEntities.Clear();
var _planRefresh = await _unit.MaterialTransPlans.GetByIdAsync(context.Id);
if (_planRefresh == null)
OpenDialog("Không tim thấy kế hoạch update", NDialogSeverity.ERROR);
int _remainKittingVerify = context.PCBPlanQty;
var _listMgzes = await _unit.MaterialTransPlanKitMgzHises.FindAsync(h => h.PlanId == _planRefresh.Id);
if(_listMgzes.Count() > 0)
foreach (var mgz in _listMgzes)
var _mgzInfo = await _unit.MaterialMgzes.FindFirstAsync(m => m.Id == mgz.MagazineId);
_remainKittingVerify = _remainKittingVerify - _mgzInfo.PCBQty;
planSelectedToDiv = _planRefresh;
MaterialMgzEntities = await _unit.MaterialMgzes.GetAllMagazineForPlan(_planRefresh.PCBCode, _planRefresh.PCBRev, _remainKittingVerify);
PlanOutputWindowActive = true;
private MaterialMgzForPlanDTO mgzSelectedToDiv = null;
private async Task ViewLinePlanDivListClick(MaterialMgzForPlanDTO context)
mgzSelectedToDiv = context;
var _planReload = await _unit.MaterialTransPlans.GetAllPlanAsync1(PlanDateFromSearch.Value, PlanDateToSearch.Value, PlanKittingStatusSearch, PlanOutputStatusSearch, LineNameSearch.Trim(), PCBCodeSearch.Trim(), PlanStatusSearch, PlanResendCountSearch);
List<MaterialTransPlanEntity> _planList = _planReload.Cast<MaterialTransPlanEntity>().Where(p =>p.KittingRemainQty > 0 && p.PCBCode == context.PCBCode && p.PCBRev.ToUpper() == context.PCBRev.ToUpper() && p.Status == LineTransStatus.OK).ToList();
var _listPlanOk = await FindOptimalCombination(_planList, context.PCBQty);
if(_listPlanOk.Count() > 0)
LineKittingDivList = _listPlanOk.OrderBy(p=>p.LineName).ToList();
public async Task<List<MaterialTransPlanEntity>> FindOptimalCombination(List<MaterialTransPlanEntity> items, int targetQuantity)
List<MaterialTransPlanEntity> bestCombination = new List<MaterialTransPlanEntity>();
var _planCurrent = await _unit.MaterialTransPlans.FindFirstAsync(p=>p.Id == planSelectedToDiv.Id);
if (_planCurrent == null) return bestCombination;
if (!items.Exists(p=>p.Id == _planCurrent.Id)) return bestCombination;
if (_planCurrent.KittingRemainQty > targetQuantity) return bestCombination;
targetQuantity = targetQuantity - _planCurrent.KittingRemainQty;
var a = items.Where(p=>p.Id==_planCurrent.Id).FirstOrDefault();
if(a==null) return bestCombination;
FindOptimalCombinationHelper(items, targetQuantity, 0, new List<MaterialTransPlanEntity>(), ref bestCombination, ref closestSum);
bestCombination.Add(_planCurrent);
private void FindOptimalCombinationHelper(List<MaterialTransPlanEntity> items, int targetQuantity, int startIndex, List<MaterialTransPlanEntity> currentCombination, ref List<MaterialTransPlanEntity> bestCombination, ref int closestSum)
int currentSum = currentCombination.Sum(i => i.KittingRemainQty);
if (currentSum <= targetQuantity && currentSum > closestSum)
bestCombination = new List<MaterialTransPlanEntity>(currentCombination);
if (currentSum >= targetQuantity)
for (int i = startIndex; i < items.Count; i++)
currentCombination.Add(items[i]);
FindOptimalCombinationHelper(items, targetQuantity, i + 1, currentCombination, ref bestCombination, ref closestSum);
currentCombination.RemoveAt(currentCombination.Count - 1);
public List<MaterialTransPlanEntity> FindClosestCombination(List<MaterialTransPlanEntity> molecules, int target)
molecules = molecules.OrderBy(m => m.KittingRemainQty).ToList();
List<MaterialTransPlanEntity> result = new List<MaterialTransPlanEntity>();
foreach (var molecule in molecules)
if (currentTotal + molecule.KittingRemainQty > target)
var closestMolecule = molecules.Where(m => m.KittingRemainQty <= target - currentTotal).OrderBy(m => Math.Abs(m.KittingRemainQty - (target - currentTotal))).FirstOrDefault();
if (closestMolecule != null)
result.Add(closestMolecule);
currentTotal += closestMolecule.KittingRemainQty;
currentTotal += molecule.KittingRemainQty;
private async Task TransferMgzDivClick()
var _rack = (await _unit.MaterialMagRacks.FindAsync(s => s.BoxId == mgzSelectedToDiv.BoxId)).FirstOrDefault();
OpenDialog("Không tìm thấy rack", NDialogSeverity.ERROR);
if (LineKittingDivList.Count == 0)
OpenDialog("Chưa có list line chia lẻ", NDialogSeverity.ERROR);
if (mgzSelectedToDiv == null)
OpenDialog("Chưa chọn mgz", NDialogSeverity.ERROR);
var parameters = new DialogParameters<DialogSelectBuffOut>();
parameters.Add(x => x.ContentText, $"Bạn muốn đưa thùng hàng đến vị trí chia lẻ nào?");
parameters.Add(x => x.ButtonText, "Chắc chắn");
parameters.Add(x => x.Color, Color.Error);
parameters.Add(x => x.BufferTypeSelect, BufferTypes.BOTH);
var options = new DialogOptions() { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
var dialog = DialogService.Show<DialogSelectBuffOut>("Lấy hàng ra vị trí chia lẻ", parameters, options);
var result = await dialog.Result;
var buff = (MaterialMagBuffEntity)result.Data;
var _ctu = await _unit.CTUMissions.CreateMission(_rack.PositionCode, buff.PositionCode, buff.BufferType,"","",_rack.RackStatus);
_logService.SaveUpdateLog(LogType.WRN, "Chia lẻ mission created");
var ctuReqResult = await CTUService.RunTask(_ctu.StartPosCode, _ctu.EndPosCode, _ctu.TaskType == BufferTypes.BOTH ? false : true);
if (!ctuReqResult.result)
_ctu.CMDReturn = ctuReqResult.TaskResponseInfo.data;
await _unit.CTUMissions.UpdateMission(_ctu, MissionStatus.ERROR);
_logService.SaveUpdateLog(LogType.WRN, "Chia lẻ mission error");
if (ctuReqResult.TaskResponseInfo.code != "99")
_rack.MissionId = _ctu.Id;
await _unit.MaterialMagRacks.RackUpdateStatus(_rack, RackStatus.UNDEFINED);
_ctu.CMDReturn = ctuReqResult.TaskResponseInfo.data;
await _unit.CTUMissions.UpdateMission(_ctu, MissionStatus.SEND_CTU_OK);
_logService.SaveUpdateLog(LogType.WRN, "Chia lẻ mission ok");
_rack.MissionId = _ctu.Id;
await _unit.MaterialMagRacks.RackUpdateStatus(_rack, RackStatus.OUT_WAITING);
foreach (var _plan in LineKittingDivList)
MaterialTransPlanDivMgzHisEntity _hisDiv = new MaterialTransPlanDivMgzHisEntity();
_hisDiv.MgzId = mgzSelectedToDiv.MgzId;
_hisDiv.PlanId = _plan.Id;
_hisDiv.PlanDivQty = _plan.KittingRemainQty;
_hisDiv.Status = MagazineStatusDivHis.WAITING_DIV;
_hisDiv.CreateAt = DateTime.Now;
_hisDiv.ModifiedAt = DateTime.Now;
_hisDiv.UseStatus = UseStatus.USE;
_hisDiv.MagazineCode = mgzSelectedToDiv.MgzCode;
await _unit.MaterialTransPlanDivMgzHises.AddAsync(_hisDiv);
var _planUpdate = await _unit.MaterialTransPlans.GetByIdAsync(_plan.Id);
_planUpdate.Status = LineTransStatus.DIV;
_planUpdate.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(_planUpdate);
var _mgz = await _unit.MaterialMgzes.GetByIdAsync(mgzSelectedToDiv.MgzId);
_mgz.Status = MagazineStatus.DIVIDED;
_mgz.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_mgz);
await _unit.CompleteAsync();
LineKittingDivList.Clear();
MaterialMgzEntities.Remove(mgzSelectedToDiv);
PlanOutputWindowActive = false;
#region Transfer vật liệu
private async Task EnterMagazineScanTransferCodeEvent(KeyboardEventArgs e)
await TempFocus.FocusAsync();
if (string.IsNullOrEmpty(MagazinKitting))
Snackbar.Add($"Mã scan không được để trống. Kiểm tra lại", Severity.Error);
ChangeFocusScanMagazin();
if (MagazinKitting.Length < 15 && MagazinKitting.Length > 18)
Snackbar.Add($"Mã scan không đúng. Kiểm tra lại", Severity.Error);
ChangeFocusScanMagazin();
if (CurrentPlanSelected == null)
Snackbar.Add("Kế hoạch không tổn tại", Severity.Error);
ChangeFocusScanMagazin();
var _magazinExist = (await _unit.MaterialMgzes.FindAsync(b => b.UseStatus == UseStatus.USE &&
b.PCBCode == CurrentPlanSelected.PCBCode &&
b.MagazineCode == MagazinKitting.Trim().ToUpper() && b.Status == MagazineStatus.KITTING)).FirstOrDefault();
if (_magazinExist == null)
Snackbar.Add($"Magazin {MagazinKitting} không có trong stock", Severity.Error);
ChangeFocusScanMagazin();
TransferCurrentStockList.Remove(_magazinExist);
var _currentPlan = await _unit.MaterialTransPlans.GetByIdAsync(CurrentPlanSelected.Id);
if (_currentPlan == null)
Snackbar.Add($"Không tồn tại plan này", Severity.Error);
ChangeFocusScanMagazin();
if (_currentPlan.OutputRemainQty != CurrentPlanSelected.OutputRemainQty) CurrentPlanSelected = _currentPlan;
if ((_magazinExist.PCBQty + MagazineScanList.Sum(k => k.Quantity)) > _currentPlan.OutputRemainQty)
Snackbar.Add($"Số lượng transfer vượt quá remain", Severity.Error);
ChangeFocusScanMagazin();
if (MagazineScanList.Where(k => k.MagazinCode == MagazinKitting.Trim().ToUpper()).FirstOrDefault() != null)
Snackbar.Add($"Magazin đã được thêm", Severity.Error);
ChangeFocusScanMagazin();
MaterialLinePlanKittingDTO _kittingMgz = new MaterialLinePlanKittingDTO();
_kittingMgz.Id = _currentPlan.Id;
_kittingMgz.MagazinCode = _magazinExist.MagazineCode;
_kittingMgz.Quantity = _magazinExist.PCBQty;
_kittingMgz.LineName = _currentPlan.LineName;
_kittingMgz.PlanDate = _currentPlan.PlanDate;
_kittingMgz.ModelBasic = _currentPlan.ModelBasic;
_kittingMgz.PCBCode = _currentPlan.PCBCode;
_kittingMgz.PCBPlanQty = _currentPlan.PCBPlanQty;
_kittingMgz.KittingRemainQty = _currentPlan.KittingRemainQty;
_kittingMgz.OutputRemainQty = _currentPlan.OutputRemainQty;
_kittingMgz.MgzId = _magazinExist.Id;
MagazineScanList.Insert(0, _kittingMgz);
ChangeFocusScanMagazin();
private async Task TransferSubmitPlanClick()
var _planLineUpdate = await _unit.MaterialTransPlans.GetByIdAsync(CurrentPlanSelected.Id);
if (_planLineUpdate == null)
Snackbar.Add("Kế hoạch không tồn tại", Severity.Error);
ChangeFocusScanMagazin();
foreach (var item in MagazineScanList)
MaterialTransPlanOutMgzHisEntity _transferPlanHis = new MaterialTransPlanOutMgzHisEntity();
_transferPlanHis.PlanId = item.Id;
_transferPlanHis.MagazineId = item.MgzId;
_transferPlanHis.UseStatus = UseStatus.USE;
_transferPlanHis.OutputType = KittingTypes.MANUAL;
_transferPlanHis.CreateAt = DateTime.Now;
await _unit.MaterialTransPlanOutMgzHises.AddAsync(_transferPlanHis);
var _magazineExist = await _unit.MaterialMgzes.GetByIdAsync(item.MgzId);
_magazineExist.Status = MagazineStatus.TRANSFERED;
_magazineExist.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_magazineExist);
MaterialMgzHisEntity _magazineHis = new MaterialMgzHisEntity();
_magazineHis.CreateAt = DateTime.Now;
_magazineHis.MagazineId = item.MgzId;
_magazineHis.Status = MagazineStatus.TRANSFERED;
await _unit.MaterialMgzHises.AddAsync(_magazineHis);
var _planUpdate = await _unit.MaterialTransPlans.GetByIdAsync(CurrentPlanSelected.Id);
_planUpdate.OutputRemainQty -= MagazineScanList.Sum(m => m.Quantity);
_planUpdate.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(_planUpdate);
await _unit.CompleteAsync();
OpenDialog($"Đã transfer cho kế hoạch thành công", NDialogSeverity.SUCCESS);
PlanOutputWindowActive = false;
CurrentPlanSelected = null;
MagazineScanList.Clear();
private async Task AutoMappingClick()
var _listPlanMapping = await MappingAllPlan(PlanDataSearchList);
List<MaterialTransPlanDTO> _listPlanUpdate = new List<MaterialTransPlanDTO>();
foreach (MaterialTransPlanDTO p in PlanDataSearchList)
var _planReload = await _unit.MaterialTransPlans.GetPlanForId(p.Id);
_listPlanUpdate.Add(_planReload);
PlanDataSearchList.Clear();
PlanDataSearchList = _listPlanUpdate;
OpenDialog($"Đã mapping thành công", NDialogSeverity.SUCCESS);
private async Task<List<MaterialTransPlanDTO>> MappingAllPlan(List<MaterialTransPlanDTO> listNeedToMapping)
List<MaterialTransPlanDTO> _planMapping = new List<MaterialTransPlanDTO>();
int planCountMapping = -1;
bool mappingFirstTime = true;
while (planCountMapping!=0)
var _plans = listNeedToMapping.OrderBy(p=>p.KittingRemainQty);
foreach (var plan in _plans)
var result = await PlanMappingFunc1Box(plan);
mappingFirstTime = false;
private async Task AutoMappingPlanClick(MaterialTransPlanDTO planMapping)
var resuslt = await PlanMappingFunc(planMapping);
OpenDialog($"Đã mapping thành công kế hoạch!", NDialogSeverity.SUCCESS);
OpenDialog($"Mapping không thành công!", NDialogSeverity.ERROR);
private async Task<bool> PlanMappingFunc1Box(MaterialTransPlanDTO context)
var _mgzList = await _unit.MaterialMgzes.GetMagazineFor(context.PCBCode, context.PCBRev);
List<MaterialMgzEntity> materials = new List<MaterialMgzEntity>();
foreach (var mgz in _mgzList)
var result = await _unit.MaterialTransPlanKitMgzHises.GetExist(h => h.MagazineId == mgz.Id);
if (materials.Count == 0) return false;
var _planReload = await _unit.MaterialTransPlans.GetByIdAsync(context.Id);
var _mgzMappingList = FindClosestItems(materials, _planReload.KittingRemainQty).OrderBy(m => m.PCBQty).ToList();
if (_mgzMappingList.Count == 0)
var _mgzSelected = _mgzMappingList.First();
var _box = (await _unit.MaterialMagBoxes.FindAsync(b => b.MagazineId == _mgzSelected.Id)).FirstOrDefault();
var _racks = (await _unit.MaterialMagRacks.FindAsync(s =>s.RackStatus == RackStatus.HAS_BOX && s.BoxId == _box.Id)).ToList();
if (_racks.Count() > 1 || _racks.Count() == 0) return false;
var _rack = _racks.FirstOrDefault();
if (_rack == null) return false;
_mgzSelected.Tracking = MagazineTracking.IN_RACK;
_mgzSelected.Status = MagazineStatus.KITTING;
_mgzSelected.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(_mgzSelected);
MaterialMgzHisEntity _magazineHis = new MaterialMgzHisEntity();
_magazineHis.CreateAt = DateTime.Now;
_magazineHis.MagazineId = _mgzSelected.Id;
_magazineHis.Status = MagazineStatus.KITTING;
await _unit.MaterialMgzHises.AddAsync(_magazineHis);
_rack.RackStatus = _mgzSelected.Status == MagazineStatus.KITTING ? RackStatus.HAS_FIXED_BOX : RackStatus.HAS_BOX;
_rack.ModifiedAt = DateTime.Now;
_unit.MaterialMagRacks.Update(_rack);
MaterialTransPlanKitMgzHisEntity _kittingPlanHis = new MaterialTransPlanKitMgzHisEntity();
_kittingPlanHis.PlanId = context.Id;
_kittingPlanHis.MagazineId = _mgzSelected.Id;
_kittingPlanHis.UseStatus = UseStatus.USE;
_kittingPlanHis.KittingType = KittingTypes.AUTO;
_kittingPlanHis.CreateAt = DateTime.Now;
await _unit.MaterialTransPlanKitMgzHises.AddAsync(_kittingPlanHis);
_planReload.KittingRemainQty -= _mgzSelected.PCBQty;
_planReload.ModifiedAt = DateTime.Now;
_planReload.AutoMaping = LineTransAutoMapping.MAPPING;
_unit.MaterialTransPlans.Update(_planReload);
var a = await _unit.CompleteAsync();
_logService.SaveUpdateLog(LogType.WRN,$"PlanMappingFunc1Box ok => {a}");
if (!string.IsNullOrEmpty(ex.Message))
_logService.SaveUpdateLog(LogType.ERR, $"PlanMappingFunc1Box Exception => { ex.Message}");
else if (ex.InnerException != null)
_logService.SaveUpdateLog(LogType.ERR, $"PlanMappingFunc1Box Exception => {ex.InnerException.Message}");
private async Task<bool> PlanMappingFunc(MaterialTransPlanDTO context)
var _mgzList = await _unit.MaterialMgzes.GetMagazineFor(context.PCBCode, context.PCBRev);
if (_mgzList.Count == 0) return false;
List<MaterialMgzEntity> materials = new List<MaterialMgzEntity>();
foreach (var mgz in _mgzList)
var result = await _unit.MaterialTransPlanKitMgzHises.GetExist(h => h.MagazineId == mgz.Id);
if (materials.Count == 0) return false;
var _planReload = await _unit.MaterialTransPlans.GetByIdAsync(context.Id);
if (_planReload == null) return false;
var _mgzMappingList = FindClosestItems(materials, _planReload.KittingRemainQty);
if (_mgzMappingList.Count == 0) return false;
if (!(await _unit.MaterialMagBoxes.GetAllAsync()).ToList().Any(b => _mgzMappingList.Any(m => b.MagazineId == m.Id)))
foreach (var mgz in _mgzMappingList)
var _box = (await _unit.MaterialMagBoxes.FindAsync(b => b.MagazineId == mgz.Id)).FirstOrDefault();
var _rack = (await _unit.MaterialMagRacks.FindAsync(s => s.BoxId == _box.Id)).FirstOrDefault();
mgz.Status = MagazineStatus.KITTING;
mgz.Tracking = MagazineTracking.IN_RACK;
mgz.ModifiedAt = DateTime.Now;
_unit.MaterialMgzes.Update(mgz);
_rack.RackStatus = mgz.Status == MagazineStatus.KITTING ? RackStatus.HAS_FIXED_BOX : RackStatus.HAS_BOX;
_rack.ModifiedAt = DateTime.Now;
_unit.MaterialMagRacks.Update(_rack);
MaterialMgzHisEntity _magazineHis = new MaterialMgzHisEntity();
_magazineHis.CreateAt = DateTime.Now;
_magazineHis.MagazineId = mgz.Id;
_magazineHis.Status = MagazineStatus.KITTING;
await _unit.MaterialMgzHises.AddAsync(_magazineHis);
MaterialTransPlanKitMgzHisEntity _kittingPlanHis = new MaterialTransPlanKitMgzHisEntity();
_kittingPlanHis.PlanId = context.Id;
_kittingPlanHis.MagazineId = mgz.Id;
_kittingPlanHis.UseStatus = UseStatus.USE;
_kittingPlanHis.KittingType = KittingTypes.AUTO;
_kittingPlanHis.CreateAt = DateTime.Now;
await _unit.MaterialTransPlanKitMgzHises.AddAsync(_kittingPlanHis);
_qtyTotal = _qtyTotal + mgz.PCBQty;
_planReload.KittingRemainQty = _planReload.KittingRemainQty - _qtyTotal;
_planReload.ModifiedAt = DateTime.Now;
_planReload.AutoMaping = LineTransAutoMapping.MAPPING;
_unit.MaterialTransPlans.Update(_planReload);
await _unit.CompleteAsync();
public List<MaterialMgzEntity> FindClosestItems(List<MaterialMgzEntity> items, int targetQuantity)
items = items.OrderBy(i => i.PCBQty).ToList();
int[,] dp = new int[n + 1, targetQuantity + 1];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= targetQuantity; j++)
if (items[i - 1].PCBQty > j)
dp[i, j] = Math.Max(dp[i - 1, j], dp[i - 1, j - items[i - 1].PCBQty] + items[i - 1].PCBQty);
List<MaterialMgzEntity> result = new List<MaterialMgzEntity>();
int sum = dp[n, targetQuantity];
while (sum > 0 && index > 0)
if (dp[index, sum] != dp[index - 1, sum])
result.Add(items[index - 1]);
sum -= items[index - 1].PCBQty;
private int AddPlanSeclected = LineTransPlanCount.KITTINGSOMLAN1;
private void AddPlanClick()
PlanAddWindowActive = true;
private void ClosePlanAddWindowClick()
PlanAddWindowActive = false;
public static MaterialTransPlanEntity GetChangedProperties(MaterialTransPlanEntity a, MaterialTransPlanEntity b)
MaterialTransPlanEntity result = new MaterialTransPlanEntity();
foreach (PropertyInfo property in typeof(MaterialTransPlanEntity).GetProperties())
var valueA = property.GetValue(a);
var valueB = property.GetValue(b);
if (property.Name == "PlanDate" || property.Name == "LineName" || property.Name == "PCBRev" || property.Name == "PCBCode")
property.SetValue(result, valueA);
if (!object.Equals(valueA, valueB))
property.SetValue(result, valueB);
property.SetValue(result, GetDefaultValue(property.PropertyType));
private static object GetDefaultValue(Type type)
return type.IsValueType ? Activator.CreateInstance(type) : "";
private bool AreAllDatesTheSame(List<MaterialTransPlanEntity> data)
if (data.Count() == 1) return false;
var dates = data.Select(d => d.PlanDate.Date).ToList();
var distinctDates = dates.Distinct().ToList();
return dates.Count == distinctDates.Count;
private async Task SubmitPlanClick()
if(AddPlanSeclected==LineTransPlanCount.ALL)
OpenDialog($"Phải chọn lần sửa kế hoạch trứơc", NDialogSeverity.ERROR);
var countTemp = materialSubmitLinePlans.Count();
OpenDialog($"Phải them kế hoạch trước", NDialogSeverity.ERROR);
if(AreAllDatesTheSame(materialSubmitLinePlans))
OpenDialog($"Ngày kế hoạch không đúng", NDialogSeverity.ERROR);
List<MaterialTransPlanEntity> _planLineList = new List<MaterialTransPlanEntity>(materialSubmitLinePlans);
var _planListOfDate = await _unit.MaterialTransPlans.FindAsync(p => p.PlanDate.Date == materialSubmitLinePlans.First().PlanDate.Date && p.UseStatus == UseStatus.USE);
if (_planListOfDate.Count() > 0){
var _maxUpPlan = _planListOfDate.Max(p => p.PlanCount);
if (_maxUpPlan > AddPlanSeclected)
OpenDialog($"Bạn dã up kế hoạch lần thứ {_maxUpPlan}. Vui lòng chọn up bảng kế hoạch sau", NDialogSeverity.ERROR);
else if(_maxUpPlan == AddPlanSeclected)
var parameters = new DialogParameters<DialogYesNo>();
parameters.Add(x => x.ContentText, $"Lần kế hoạch đã tồn tại: {_maxUpPlan}. Bạn có muốn up thêm line vào kế hoạch không?");
parameters.Add(x => x.ButtonText, "Ðồnng ý");
parameters.Add(x => x.Color, Color.Error);
var options = new DialogOptions() { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
var dialog = DialogService.Show<DialogYesNo>("Xác nhận up kế hoạch", parameters, options);
var result = await dialog.Result;
foreach (var _plan in _planLineList)
if (_plan.UseStatus == UseStatus.USE)
var _planExistDB = _planListOfDate.Where(p =>
p.LineName == _plan.LineName &&
p.PlanPriority == _plan.PlanPriority &&
p.Remark == _plan.Remark &&
p.ModelBasic == _plan.ModelBasic &&
p.PCBCode == _plan.PCBCode &&
p.PCBRev == _plan.PCBRev &&
p.Status != LineTransStatus.NG)
_plan.PlanCount = AddPlanSeclected;
_plan.AutoMaping = LineTransAutoMapping.NO_MAPPING;
_plan.Status = LineTransStatus.OK;
_plan.ModifiedAt = DateTime.Now;
await _unit.MaterialTransPlans.AddAsync(_plan);
_planExistDB.PlanCount = AddPlanSeclected;
_planExistDB.ModifiedAt = DateTime.Now;
_planExistDB.KittingRemainQty = _plan.PCBPlanQty - (_planExistDB.PCBPlanQty-_planExistDB.KittingRemainQty);
_planExistDB.OutputRemainQty = _plan.PCBPlanQty - (_planExistDB.PCBPlanQty - _planExistDB.OutputRemainQty);
_planExistDB.PCBPlanQty = _plan.PCBPlanQty;
_unit.MaterialTransPlans.Update(_planExistDB);
await _unit.CompleteAsync();
materialSubmitLinePlans.Remove(_plan);
foreach (var _plan in _planLineList)
if (_plan.UseStatus == UseStatus.USE)
var _listPlanOKs = _planListOfDate.Where(p =>
p.LineName.Trim() == _plan.LineName.Trim() &&
p.PlanPriority == _plan.PlanPriority &&
p.Remark.Trim() == _plan.Remark.Trim() &&
p.ModelBasic.Trim() == _plan.ModelBasic.Trim() &&
p.PCBCode.Trim() == _plan.PCBCode.Trim() &&
p.PCBRev.Trim() == _plan.PCBRev.Trim() &&
p.Status != LineTransStatus.NG).ToList();
if(_listPlanOKs.Count > 1)
_logService.SaveUpdateLog(LogType.ERR, "Tồn tại nhiều hơn 2 plan");
var _planExistDB = _listPlanOKs.FirstOrDefault();
if (_planExistDB == null)
_plan.PlanCount = AddPlanSeclected;
_plan.AutoMaping = LineTransAutoMapping.NO_MAPPING;
_plan.Status = LineTransStatus.OK;
_plan.ModifiedAt = DateTime.Now;
await _unit.MaterialTransPlans.AddAsync(_plan);
await _unit.CompleteAsync();
_planExistDB.PlanCount = AddPlanSeclected;
_planExistDB.ModifiedAt = DateTime.Now;
_planExistDB.KittingRemainQty = _plan.PCBPlanQty - (_planExistDB.PCBPlanQty - _planExistDB.KittingRemainQty);
_planExistDB.OutputRemainQty = _plan.PCBPlanQty - (_planExistDB.PCBPlanQty - _planExistDB.OutputRemainQty);
_planExistDB.PCBPlanQty = _plan.PCBPlanQty;
_unit.MaterialTransPlans.Update(_planExistDB);
await _unit.CompleteAsync();
materialSubmitLinePlans.Remove(_plan);
_planListOfDate = (await _unit.MaterialTransPlans.FindAsync(p => p.PlanDate.Date == _planLineList.First().PlanDate.Date && p.UseStatus == UseStatus.USE)).ToList();
foreach (var _plan in _planListOfDate)
var _planExistNew = _planLineList.Where(p =>
p.LineName.Trim() == _plan.LineName.Trim() &&
p.PlanPriority == _plan.PlanPriority &&
p.Remark.Trim() == _plan.Remark.Trim() &&
p.ModelBasic.Trim() == _plan.ModelBasic.Trim() &&
p.PCBCode.Trim() == _plan.PCBCode.Trim() &&
p.PCBRev.Trim() == _plan.PCBRev.Trim() &&
p.Status == LineTransStatus.OK)
if (_planExistNew == null)
var _kitHis = await _unit.MaterialTransPlanKitMgzHises.FindFirstAsync(h=>h.PlanId == _plan.Id);
_unit.MaterialTransPlans.Delete(_plan);
_plan.Status = LineTransStatus.NG;
_plan.ModifiedAt = DateTime.Now;
_unit.MaterialTransPlans.Update(_plan);
await _unit.CompleteAsync();
foreach (var _plan in _planLineList)
_plan.PlanCount = AddPlanSeclected;
_plan.AutoMaping = LineTransAutoMapping.NO_MAPPING;
_plan.Status = LineTransStatus.OK;
_plan.ModifiedAt = DateTime.Now;
await _unit.MaterialTransPlans.AddAsync(_plan);
await _unit.CompleteAsync();
materialSubmitLinePlans.Remove(_plan);
private void DeletePlanSubmitClick(MaterialTransPlanEntity item)
materialSubmitLinePlans.Remove(item);
private void ResetValueAddPlan()
PlanTimeStart = DateTime.Now;
materialSubmitLinePlans.Clear();
private async Task AddPlanByExcelClick()
if (string.IsNullOrEmpty(ExcelPlanAddWindow))
Snackbar.Add("Chưa có dữ liệu excel", Severity.Error);
var excelRows = ExcelPlanAddWindow.Split('\n');
var excelHeader = excelRows[0].Split('\t');
excelHeader[0].ToLower() != "date" &&
excelHeader[0].ToLower() != "line" &&
excelHeader[0].ToLower() != "start time" &&
excelHeader[0].ToLower() != "remark" &&
excelHeader[0].ToLower() != "model" &&
excelHeader[0].ToLower() != "code" &&
excelHeader[0].ToLower() != "rev" &&
excelHeader[0].ToLower() != "quantity"
Snackbar.Add("Định dạng excel không đúng header");
excelRows = excelRows.Skip(1).ToArray();
foreach (var excelRow in excelRows)
if (!string.IsNullOrEmpty(excelRow))
var excelColumns = excelRow.Split('\t');
await AddPlanToList(excelColumns[0].Trim(), excelColumns[1].Trim(), excelColumns[2].Trim(), excelColumns[3].Trim(), excelColumns[4].Trim(), excelColumns[5].Trim(), excelColumns[6].Trim(), excelColumns[7].Trim());
var _planErrorCount = materialSubmitLinePlans.Where(p => p.UseStatus == UseStatus.NOT_USE).Count();
OpenDialog($"Có {_planErrorCount} plan lỗi", NDialogSeverity.ERROR);
Snackbar.Add($"Đã thêm thành công {materialSubmitLinePlans.Count()} plan cấp line", Severity.Success);
private async Task AddPlanToList(string planDate, string line, string timeStartPlan, string priorityPlan, string modelPlan, string pcbCode, string rev, string quantityPlan)
MaterialTransPlanEntity _linePlan = new MaterialTransPlanEntity();
DateTime _planDate = DateTime.Now;
DateTime _timeStartPlan = DateTime.Now;
_planDate = DateTime.ParseExact(planDate.Trim(), formatDate, provider);
_timeStartPlan = DateTime.ParseExact(timeStartPlan.Trim(), formatDateTime, provider);
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Định dạng ngày giờ sai;";
string _pcbCode = pcbCode.Trim().ToUpper();
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "PCB Code bị rỗng;";
if (_pcbCode.Length > 14 && _pcbCode.Length < 11)
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Code vật liệu không đúng định dạng;";
var _pcbCodeSplit = pcbCode.Split('_');
var _pcbCodeNoXout = _pcbCodeSplit[0].Trim().ToUpper();
if (_pcbCodeSplit.Count() > 1)
_xout = int.Parse(_pcbCodeSplit[1].Substring(0, 1));
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Xout không thể bằng 0;";
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Định dạng Xout không đúng;";
_quantity = int.Parse(quantityPlan);
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Số lượng phải khác 0;";
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Định dạng số lượng không đúng;";
var _revExist = (await _unit.MaterialMagRevs.FindAsync(r => r.PCBCode == _pcbCodeNoXout && r.PCBRev == rev.Trim().ToUpper())).FirstOrDefault();
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Chưa có Rev cho mã này;";
if (_quantity % _revExist.PCBArr != 0)
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += $"Số lượng chưa đúng với Arr {_revExist.PCBArr};";
if (_quantity % (_revExist.PCBArr - 1) != 0)
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += $"Số lượng chưa đúng với Arr Xout {_revExist.PCBArr};";
_priorityPlan = int.Parse(priorityPlan.Substring(0, 1));
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Số lượng phải khác 0;";
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Định dạng số lượng không đúng;";
var _planExistList = materialSubmitLinePlans.Where(p => p.PlanDate.Date == _planDate.Date && p.LineName == line.Trim().ToUpper() &&
p.StartTime == _timeStartPlan && p.ModelBasic == modelPlan.Trim().ToUpper() && p.PCBCode == pcbCode.Trim().ToUpper()).FirstOrDefault();
if (_planExistList != null)
_linePlan.UseStatus = UseStatus.NOT_USE;
_linePlan.Remark += "Đã có plan này trong list rồi;";
_linePlan.PlanDate = _planDate;
_linePlan.LineName = line.Trim().ToUpper();
_linePlan.StartTime = _timeStartPlan;
_linePlan.PlanPriority = _priorityPlan;
_linePlan.Remark += priorityPlan.Substring(1, priorityPlan.Length - 1);
_linePlan.ModelBasic = modelPlan.Trim().ToUpper();
_linePlan.PCBCode = pcbCode.Trim().ToUpper();
_linePlan.PCBRev = rev.Trim().ToUpper();
_linePlan.PCBPlanQty = _quantity;
_linePlan.KittingRemainQty = _quantity;
_linePlan.OutputRemainQty = _quantity;
_linePlan.CreateAt = DateTime.Now;
_linePlan.ModifiedAt = DateTime.Now;
_linePlan.UseStatus += UseStatus.USE;
materialSubmitLinePlans.Add(_linePlan);
private string AddPlanRowStyleFunc(MaterialTransPlanEntity plan, int index)
return plan.UseStatus == UseStatus.NOT_USE ? "background-color: yellow;" : "";
private void PrinterIpSaveClick()
IpPrinterDisable = false;
LineTransferPrintEnable = true;
_localstorage.SetItemAsync("printerIp", PrinterIp);
LineTransferPrintEnable = false;