diff --git a/AppData/ComLib.cs b/AppData/ComLib.cs index 55ad501..7006225 100644 --- a/AppData/ComLib.cs +++ b/AppData/ComLib.cs @@ -1411,23 +1411,26 @@ namespace AppData /// public static Dictionary OrdersExtByBatch(int BatchId, string PlaceCod) { - DataLayer DLMan = new DataLayer(); - string redKey = $"{redOrders}:BYBATCH:{BatchId}"; - string rawData = ""; Dictionary answ = new Dictionary(); - - // cerco in redis - if (memLayer.ML.redKeyPresent(redKey)) + if (BatchId > 0) { - rawData = memLayer.ML.getRSV(redKey); - if (!string.IsNullOrEmpty(rawData)) + DataLayer DLMan = new DataLayer(); + string redKey = $"{redOrders}:BYBATCH:{BatchId}"; + string rawData = ""; + + // cerco in redis + if (memLayer.ML.redKeyPresent(redKey)) { - try + rawData = memLayer.ML.getRSV(redKey); + if (!string.IsNullOrEmpty(rawData)) { - answ = JsonConvert.DeserializeObject>(rawData); + try + { + answ = JsonConvert.DeserializeObject>(rawData); + } + catch + { } } - catch - { } } // se vuoto rileggo if (answ.Count == 0) diff --git a/Jenkinsfile b/Jenkinsfile index ac19a4b..a67882d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,8 +12,8 @@ pipeline { /* calcolo numero versione... diverso x branch MASTER/DEVELOP */ script { withEnv(['NEXT_BUILD_NUMBER=393']) { - // env.versionNumber = VersionNumber(versionNumberString : '1.3.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2019-07-01', skipFailedBuilds: true) - env.versionNumber = VersionNumber(versionNumberString : '1.3.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2019-07-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}') + // env.versionNumber = VersionNumber(versionNumberString : '2.0.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2019-07-01', skipFailedBuilds: true) + env.versionNumber = VersionNumber(versionNumberString : '2.0.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2019-07-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}') env.versionNumberBeta = VersionNumber(versionNumberString : '1.3.${BUILD_DATE_FORMATTED, "yyMM"}-beta.${BUILDS_ALL_TIME}', projectStartDate : '2019-07-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}') env.APP_NAME = 'NKC' } diff --git a/NKC_SDK/Objects.cs b/NKC_SDK/Objects.cs index edc2075..851603f 100644 --- a/NKC_SDK/Objects.cs +++ b/NKC_SDK/Objects.cs @@ -604,6 +604,48 @@ namespace NKC_SDK #endregion Public Properties } + /// + /// Classe simulazione di un assegnazione di un set di ordini (compreso score) + /// + public class OrderSetSim + { + #region Public Properties + + /// + /// Valore attuale (somma dei punteggi degli elementi) + /// + public double ActualValue + { + get + { + return OrderSet.Sum(x => x.Value); + } + } + + /// + /// Valore score (scostamento target/actual) + /// + public double IndexScore + { + get + { + return Math.Abs(TargetValue - ActualValue); + } + } + + /// + /// Vettore Ordini + durate + /// + public Dictionary OrderSet { get; set; } = new Dictionary(); + + /// + /// Valore target durate desiderate + /// + public double TargetValue { get; set; } = 0; + + #endregion Public Properties + } + /// /// Classe che rappresenta stato ordine ricevuto via REDIS da NESTING /// diff --git a/NKC_WF/WebUserControls/cmp_batchDetail.ascx b/NKC_WF/WebUserControls/cmp_batchDetail.ascx index cfc9285..fe8c3f1 100644 --- a/NKC_WF/WebUserControls/cmp_batchDetail.ascx +++ b/NKC_WF/WebUserControls/cmp_batchDetail.ascx @@ -106,15 +106,22 @@ NE02 % -
+
+ +
+
+
+
+ +
ORD LIST NE01 - summary - +
ORD LIST NE02- summary - +
\ No newline at end of file diff --git a/NKC_WF/WebUserControls/cmp_batchDetail.ascx.cs b/NKC_WF/WebUserControls/cmp_batchDetail.ascx.cs index 84014b5..382397e 100644 --- a/NKC_WF/WebUserControls/cmp_batchDetail.ascx.cs +++ b/NKC_WF/WebUserControls/cmp_batchDetail.ascx.cs @@ -19,6 +19,20 @@ namespace NKC_WF.WebUserControls #region Protected Properties + protected bool needSave + { + get + { + bool answ = true; + bool.TryParse(hfNeedSave.Value, out answ); + return answ; + } + set + { + hfNeedSave.Value = $"{value}"; + } + } + /// /// Tabella dei batch Descendant di quello corrente /// @@ -30,7 +44,7 @@ namespace NKC_WF.WebUserControls } } - protected Dictionary TabOrders + protected Dictionary TabOrdersFromDb { get { @@ -39,6 +53,19 @@ namespace NKC_WF.WebUserControls } } + protected int valRatio + { + get + { + int answ = 50; + if (!string.IsNullOrEmpty(txtRatio.Text)) + { + int.TryParse(txtRatio.Text, out answ); + } + return answ; + } + } + #endregion Protected Properties #region Public Properties @@ -222,8 +249,11 @@ namespace NKC_WF.WebUserControls lblTestJson.Text = "
" + sbDebug.Replace("\r\n", "
").ToString(); } } - checkCreateDescendant(); - showBatchDescendant(); + if (BatchId > 0) + { + checkCreateDescendant(); + showBatchDescendant(); + } } get { @@ -263,11 +293,110 @@ namespace NKC_WF.WebUserControls } } + /// + /// effettua ribilanciamento ordini partendo da elenco completo e poi assegnando a impianti + /// + private void rebalanceOrder() + { + // costruisco vettore durata ordini + OrderSetSim FullSet = new OrderSetSim(); + OrderSetSim SetNe01 = new OrderSetSim(); + OrderSetSim SetNe02 = new OrderSetSim(); + + // creo liste x i valori da processare... + Dictionary RawList = new Dictionary(); + Dictionary OrderedList = new Dictionary(); + + Dictionary TabOrders = new Dictionary(TabOrdersFromDb); + + if (TabOrders.ContainsKey("VIRTNE")) + { + foreach (var item in TabOrders["VIRTNE"]) + { + RawList.Add(item.OrdID, item.EstProcTime); + } + } + if (TabOrders.ContainsKey("NE01")) + { + foreach (var item in TabOrders["NE01"]) + { + RawList.Add(item.OrdID, item.EstProcTime); + } + } + if (TabOrders.ContainsKey("NE02")) + { + foreach (var item in TabOrders["NE02"]) + { + RawList.Add(item.OrdID, item.EstProcTime); + } + } + + // ordino la lista x processing successivo + OrderedList = RawList.OrderBy(x => x.Value).ToDictionary(t => t.Key, t => t.Value); + + // salvo i set + FullSet.OrderSet = OrderedList; + // IndexScore = errore di stima corrente + double IScoreCurr = FullSet.ActualValue; + + // lavoro sull'ottimizzare il MINORE + double ValRatio = (double)valRatio / 100; + if (ValRatio <= 0.5) + { + SetNe01.TargetValue = FullSet.ActualValue * ValRatio; + SetNe01.OrderSet = findLocalMin(OrderedList, SetNe01.TargetValue, IScoreCurr); + // l'altro è la differenza + SetNe02.OrderSet = OrderedList; + foreach (var item in SetNe01.OrderSet) + { + SetNe02.OrderSet.Remove(item.Key); + } + } + else + { + SetNe02.TargetValue = FullSet.ActualValue * (1 - ValRatio); + SetNe02.OrderSet = findLocalMin(OrderedList, SetNe02.TargetValue, IScoreCurr); + // l'altro è la differenza + SetNe01.OrderSet = OrderedList; + foreach (var item in SetNe02.OrderSet) + { + SetNe01.OrderSet.Remove(item.Key); + } + } + + // riorganizzo tabOrders... + List OrdersNe01 = new List(); + List OrdersNe02 = new List(); + foreach (var groupItem in TabOrders) + { + // ora guardo gli ordini... + foreach (var orderItem in groupItem.Value) + { + if (SetNe01.OrderSet.ContainsKey(orderItem.OrdID)) + { + OrdersNe01.Add(new OrderPrev() { OrderId = orderItem.OrdID, OrderExtCode = orderItem.OrderExtCode, NumBin = orderItem.EstNumBin, NumCart = orderItem.EstNumCart, TotTime = orderItem.EstProcTime }); + } + else + { + OrdersNe02.Add(new OrderPrev() { OrderId = orderItem.OrdID, OrderExtCode = orderItem.OrderExtCode, NumBin = orderItem.EstNumBin, NumCart = orderItem.EstNumCart, TotTime = orderItem.EstProcTime }); + } + } + } + + // ...e poi mostro + cmp_orderExtListNE01.CurrOrders = OrdersNe01; + cmp_orderExtListNE02.CurrOrders = OrdersNe02; + + // --> richiede salvataggio + needSave = true; + } + /// /// Mostro dati dei Batch descendant /// private void showBatchDescendant() { + Dictionary TabOrders = new Dictionary(TabOrdersFromDb); // se ho qualcosa aggiorno visualizzazione... if (TabOrders.Count > 0) { @@ -275,10 +404,14 @@ namespace NKC_WF.WebUserControls if (TabOrders["VIRTNE"].Count > 0) { // suddivido + rebalanceOrder(); + } + else + { + //// ...e poi mostro + //cmp_orderExtListNE01.CurrOrders = TabOrders["NE01"]; + //cmp_orderExtListNE02.CurrOrders = TabOrders["NE02"]; } - // ...e poi mostro - cmp_orderExtListNE01.CurrOrders = TabOrders["NE01"]; - cmp_orderExtListNE02.CurrOrders = TabOrders["NE02"]; } } @@ -286,6 +419,94 @@ namespace NKC_WF.WebUserControls #region Protected Methods + /// + /// Cerca il set con lo score migliore calcolando x subset della lista ordinata + /// + /// Lista ordinata oggetti (INT) + valore + /// Valore desiderato (comeSOMMA) + /// Indice score = errore minimo da migliorare + /// + protected Dictionary findLocalMin(Dictionary OrderedList, double TargetVal, double CurrIndexScore) + { + Dictionary answ = new Dictionary(); + List Candidates = new List(); + OrderSetSim CurrSimSet = new OrderSetSim(); + + // parte dal valore (singolo) più piccolo tra quelli maggiori del target... se c'è... + var OrdSup = OrderedList.Where(x => x.Value > TargetVal).OrderBy(x => x.Value); + if (OrdSup != null && OrdSup.Any()) + { + var currOrder = OrdSup.FirstOrDefault(); + CurrSimSet = new OrderSetSim(); + CurrSimSet.TargetValue = TargetVal; + CurrSimSet.OrderSet.Add(currOrder.Key, currOrder.Value); + // se lo score è migliorativo... + if (CurrSimSet.IndexScore < CurrIndexScore) + { + Candidates.Add(CurrSimSet); + CurrIndexScore = CurrSimSet.IndexScore; + } + } + + // ora guardo gli elementi restanti.. se ci sono + var OrdInf = OrderedList.Where(x => x.Value <= TargetVal).OrderByDescending(x => x.Value).ToDictionary(t => t.Key, t => t.Value); + if (OrdInf != null && OrdInf.Any()) + { + var currOrder = OrdInf.FirstOrDefault(); + CurrSimSet = new OrderSetSim(); + CurrSimSet.TargetValue = TargetVal; + CurrSimSet.OrderSet.Add(currOrder.Key, currOrder.Value); + // se lo score è migliorativo... + if (CurrSimSet.IndexScore < CurrIndexScore) + { + Candidates.Add(CurrSimSet); + CurrIndexScore = CurrSimSet.IndexScore; + } + // prendo i restanti tranne il primo + OrdInf.Remove(currOrder.Key); + // se rimane qualcosa... + if (OrdInf != null && OrdInf.Any()) + { + // calcolo il minimo locale nei 2 casi, da soli + Dictionary TestOrderSet01 = findLocalMin(OrdInf, TargetVal, CurrIndexScore); + if (TestOrderSet01.Count > 0) + { + OrderSetSim CurrSet = new OrderSetSim(); + CurrSet.TargetValue = TargetVal; + CurrSet.OrderSet = TestOrderSet01; + if (CurrSet.IndexScore < CurrIndexScore) + { + Candidates.Add(CurrSimSet); + CurrIndexScore = CurrSimSet.IndexScore; + } + } + // ...e con il primo valore... + Dictionary TestOrderSet02 = findLocalMin(OrdInf, TargetVal - currOrder.Value, CurrIndexScore); + TestOrderSet02.Add(currOrder.Key, currOrder.Value); + // verifico se migliorativo... + if (TestOrderSet02.Count > 0) + { + OrderSetSim CurrSet = new OrderSetSim(); + CurrSet.TargetValue = TargetVal - currOrder.Value; + CurrSet.OrderSet = TestOrderSet02; + if (CurrSet.IndexScore < CurrIndexScore) + { + Candidates.Add(CurrSimSet); + CurrIndexScore = CurrSimSet.IndexScore; + } + } + } + } + // cerco il minimo... + if (Candidates != null && Candidates.Count > 0) + { + answ = Candidates.OrderBy(x => x.IndexScore).FirstOrDefault().OrderSet; + } + + // calcolo il minimo e lo restituisco... + return answ; + } + protected void lbtAccept_Click(object sender, EventArgs e) { // registro accettazione Nesting @@ -293,6 +514,14 @@ namespace NKC_WF.WebUserControls raiseEvent(); } + protected void lbtCancel_Click(object sender, EventArgs e) + { + } + + protected void lbtSave_Click(object sender, EventArgs e) + { + } + protected void lbtSendEstim_Click(object sender, EventArgs e) { // invia a redis una richiesta... @@ -358,20 +587,9 @@ namespace NKC_WF.WebUserControls return num / den; } - /// - /// Elenco ordini dato BatchID - /// - /// - /// - protected DS_App.OrderListDataTable tabOrdersByBatch(int BatchId) - { - return ComLib.OrdersByBatch(BatchId); - } - protected void txtRatio_TextChanged(object sender, EventArgs e) { - int valRatio = 0; - int.TryParse(txtRatio.Text, out valRatio); + rebalanceOrder(); lblRatio01.Text = $"{valRatio}"; lblRatio02.Text = $"{100 - valRatio}"; } diff --git a/NKC_WF/WebUserControls/cmp_batchDetail.ascx.designer.cs b/NKC_WF/WebUserControls/cmp_batchDetail.ascx.designer.cs index 89acaa7..6f31710 100644 --- a/NKC_WF/WebUserControls/cmp_batchDetail.ascx.designer.cs +++ b/NKC_WF/WebUserControls/cmp_batchDetail.ascx.designer.cs @@ -86,6 +86,24 @@ namespace NKC_WF.WebUserControls /// protected global::System.Web.UI.WebControls.Label lblRatio02; + /// + /// lbtSave control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.LinkButton lbtSave; + + /// + /// hfNeedSave control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.HiddenField hfNeedSave; + /// /// txtRatio control. /// @@ -95,6 +113,15 @@ namespace NKC_WF.WebUserControls /// protected global::System.Web.UI.WebControls.TextBox txtRatio; + /// + /// lbtCancel control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.LinkButton lbtCancel; + /// /// cmp_orderExtListNE01 control. /// diff --git a/NKC_WF/WebUserControls/cmp_orderExtList.ascx b/NKC_WF/WebUserControls/cmp_orderExtList.ascx index 3e39959..215679e 100644 --- a/NKC_WF/WebUserControls/cmp_orderExtList.ascx +++ b/NKC_WF/WebUserControls/cmp_orderExtList.ascx @@ -1,4 +1,4 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="cmp_orderExtList.ascx.cs" Inherits="NKC_WF.WebUserControls.cmp_orderExtList" %> - + \ No newline at end of file diff --git a/NKC_WF/WebUserControls/cmp_orderExtList.ascx.cs b/NKC_WF/WebUserControls/cmp_orderExtList.ascx.cs index 5870a4c..9d95bd2 100644 --- a/NKC_WF/WebUserControls/cmp_orderExtList.ascx.cs +++ b/NKC_WF/WebUserControls/cmp_orderExtList.ascx.cs @@ -1,6 +1,8 @@ using AppData; +using NKC_SDK; using System; using System.Collections.Generic; +using System.Data; using System.Linq; using System.Web; using System.Web.UI; @@ -12,7 +14,21 @@ namespace NKC_WF.WebUserControls { #region Public Properties - public DS_App.OrderListDataTable CurrOrders { get; set; } + public List _CurrOrders { get; set; } = new List(); + + public List CurrOrders + { + get + { + return _CurrOrders; + } + set + { + _CurrOrders = value; + grView.DataSource = value; + grView.DataBind(); + } + } #endregion Public Properties