TECH.Mockable %Integer 1180 %Integer 770 %Integer 730 1170 + 3 * 6.7 %Integer 1191 770 + 3 * 6.7 %Integer 791 %Integer 730 %Integer 1165 %String vhLib.Logger 1 %Boolean 1 APPS.Verpakking.BoxDataRepository 1 APPS.Verpakking.SnijDataRepository 1 DOM.PM.impl.ProductAPI 1 DOM.VKP.impl.DataM.DataMOrderAPI 1 %String 1 %Decimal 1 %Decimal 1 %Decimal 1 TECH.DateTime.impl.DateTimeAPI 1 APPS.Verpakking.DoosFactory 1 APPS.Verpakking.Optimizer 1 APPS.Verpakking.DoosAanvuller 1 %String 1 APPS.Verpakking.CubeIQRequestBuilder 1 %ListOfDataTypes 1 DoosFactory:APPS.Verpakking.DoosFactory="",DoosAanvuller:APPS.Verpakking.DoosAanvuller="",Optimizer:APPS.Verpakking.Optimizer="",CubeIQRequestBuilder:APPS.Verpakking.CubeIQRequestBuilder="" 1 1 %Status 1 1 BonId:%String BonId:%String 0) { #dim CubeIQResponse As APPS.Verpakking.dto.CubeIQ.Response = ..GeefBesteStapeling(BoxDataLijstVanTeStapelenDozenVergrootVoorOrgaluxBasisPaketten) Set ..JobId = $Piece(CubeIQResponse.cubeiq.loads.load.GetAt(1).jobid, "-", 1) If $$$Not(..ZijnAfbeeldingenGegenereerdVoorBesteStapeling()) { #dim FoutOmschrijving As %String = "Geen afbeelding gevonden voor optimale stapeling gevonden voor bon "_ ..BonId _" met JobId "_ ..JobId _ ". Indien nodig, probeer manueel de stapeling van de bon opnieuw te optimaliseren via 'Do ##class(BL.PPS.OL.OptiBox).OptimizeBon(BonNr)'." Do ..Logger.Warning("Ontbrekende afbeelding voor bon", FoutOmschrijving) } Do ..SnijDataRepository.VerwijderViaBonId(..BonId) Do ..ProcessCubeIQResponse(CubeIQResponse, BoxDataLijstVanTeMakenKartons, OrigineleBoxDataLijst) Do ..MaakOptiboxQueue() } Else { Do ..Logger.Info("Optimaliseer bon orgalux", "Bon " _ BonId _" heeft geen optimalisatie doorlopen gezien er 0 producten in de overdoos zitten. Dit kan komen doordat er slechts 1 product in de bon zit die dan ook groter is dan een pallet.") } Do ..Logger.Info("Optimaliseer bon orgalux", "Klaar met optimaliseren bon " _ BonId _".") ]]> BoxDataLijstVanTeStapelenDozen:%ListOfObjects APPS.Verpakking.dto.CubeIQ.Response Score) { Set BesteStapeling = CubeIQResponse Set BesteScore = Score } } If $$$Not(BesteStapeling = "") { Set Request = ..CubeIQRequestBuilder.MaakCubeIQRequest(BoxDataLijstVanTeStapelenDozen, BesteStapeling.cubeiq.loadedcontainers.loadedcontainer.GetAt(1).overallwidth, BesteStapeling.cubeiq.loadedcontainers.loadedcontainer.GetAt(1).overalllength, BesteStapeling.cubeiq.loadedcontainers.loadedcontainer.GetAt(1).overallheight,,, $$$True) Set BesteStapeling = ..GeefParsedCubeIQResponse(Request) } } Else { #dim MaxHoogteDoos As %Decimal = 150 While ((BesteStapeling = "") && (MaxHoogteDoos < ..#MaximumVerpakkingHoogteVoorEuropallet)) { Set Request = ..CubeIQRequestBuilder.MaakCubeIQRequest(BoxDataLijstVanTeStapelenDozen, ..#MaximumOverdoosBreedteVoorEuropallet, ..#MaximumOverdoosDiepteVoorEuropallet, MaxHoogteDoos, $$$True) Set Response = ..GeefParsedCubeIQResponse(Request) If ((Response.cubeiq.loadedcontainers.loadedcontainer.Count() = MinimumAantalPallettenVoorBon) && (Response.cubeiq.unloadedproducts.unloadedproduct.Count() = 0)) { Set BesteStapeling = Response } Set MaxHoogteDoos = MaxHoogteDoos + 50 } } } If (BesteStapeling = "") { #dim RequestVolumeVolledigePallet As APPS.Verpakking.dto.CubeIQ.Request = ..CubeIQRequestBuilder.MaakCubeIQRequest(BoxDataLijstVanTeStapelenDozen, ..#MaximumOverdoosBreedteVoorEuropallet, ..#MaximumOverdoosDiepteVoorEuropallet, ..#MaximumOverdoosHoogteVoorEuropallet) Set BesteStapeling = ..GeefParsedCubeIQResponse(RequestVolumeVolledigePallet) If (BesteStapeling = "") { #dim FoutOmschrijving As %String = "Geen optimale stapeling gevonden voor bon "_ ..BonId _"." Do ..Logger.ErrorMail("Optimaliseer bon orgalux", FoutOmschrijving) Set Exception = ##class(TECH.Exceptions.DataNotFoundException).%New(FoutOmschrijving) Do ##class(TECH.ExceptionHandler).Throw(Exception) } } Quit BesteStapeling ]]> BoxDataLijstVanTeStapelenDozen:%ListOfObjects %Integer 0) { #dim FoutOmschrijving As %String = "Er is minstens 1 product van bon " _ ..BonId _ " die niet kon ondergebracht worden in de overdozen ondanks de producten groter dan een pallet al werden uitgefilterd. Dit komt normaal enkel voor als er een lang product is waarbij de langste dimensie + 3*6.7 > dan de toegelaten " _ ..#MaximumOverdoosBreedteVoorEuropallet _ ". Dit dient manueel te worden nagekeken zodat dit kan worden opgelost en dit niet meer voorvalt." Do ..Logger.ErrorMail("Bepaal minimum aantal palletten", FoutOmschrijving) Set Exception = ##class(TECH.Exceptions.InvalidResponseException).%New(FoutOmschrijving) Do ##class(TECH.ExceptionHandler).Throw(Exception) } Set MinimumAantalPallettenVoorBon = CubeIQResponse.cubeiq.loadedcontainers.loadedcontainer.Count() If (MinimumAantalPallettenVoorBon = 0) { Set FoutOmschrijving = "Het minimum aantal palletten voor bon " _ ..BonId _ " is 0. Dit kan niet kloppen en moet manueel worden nagekeken." Do ..Logger.ErrorMail("Bepaal minimum aantal palletten", FoutOmschrijving) Set Exception = ##class(TECH.Exceptions.DataNotFoundException).%New(FoutOmschrijving) Do ##class(TECH.ExceptionHandler).Throw(Exception) } Quit MinimumAantalPallettenVoorBon ]]> CubeIQResponse:APPS.Verpakking.dto.CubeIQ.Response,BoxDataLijstVanTeMakenKartons:%ListOfObjects,OrigineleBoxDataLijst:%ListOfObjects 0) { Set SnijDataDoos = ..MaakMetaDataVoorSnijOpdracht(BoxData, .OptiDataDoos, 1, NummerDoos, BoxData.ObjRef, "", SnijDataOverdoosBodem, OptiDataOverdoosBodem, "", AfbeeldingCodeDoos) #dim DelenVanBoxDataIterator As TECH.Iterator = ..BoxDataRepository.ZoekDeelVanBoxDataViaId(BoxDataId) While DelenVanBoxDataIterator.HasNext() { #dim DeelVanBoxData As DS.Prod.OptiBox.BoxData = DelenVanBoxDataIterator.Next() #dim DeelVanBoxDataBerekend As DS.Prod.OptiBox.BoxDataMetID = ..CopyBoxData(DeelVanBoxData) #dim OptiDataInnerDoos As DS.Prod.OptiBox.OptiData = "" Set Params("PRODAANTAL") = 1 Set Params("AANTAL") = 1 Set DeelVanBoxDataBerekend.Breedte = ..CalcMetDefault(1, DeelVanBoxDataBerekend.BreedteExec, .Params) Set DeelVanBoxDataBerekend.Diepte = ..CalcMetDefault(1, DeelVanBoxDataBerekend.DiepteExec, .Params) Set DeelVanBoxDataBerekend.Hoogte = ..CalcMetDefault(1, DeelVanBoxDataBerekend.HoogteExec, .Params) For Index=1:1:..CalcMetDefault(1, DeelVanBoxData.AantalExec, .Params) { Do ..MaakMetaDataVoorSnijOpdracht(DeelVanBoxDataBerekend, .OptiDataInnerDoos, 1, "", BoxData.ObjRef, SnijDataDoos, OptiDataDoos, OptiDataDoos,SnijDataDoos) } } Set Block.quantity = Block.quantity - 1 Set NummerDoos = NummerDoos + 1 } } Set NummerAfbeelding = NummerAfbeelding + 1 } } Set NummerOverdoos = NummerOverdoos + 1 } ]]> CubeIQResponse:APPS.Verpakking.dto.CubeIQ.Response %Boolean BoxDataLijst:%ListOfObjects,BoxDataID:%String,AantalGenesteProducten:%Integer=0 1 DS.Prod.OptiBox.BoxDataMetID 1) { If ((BoxData.OrigineleBoxDataID = BoxDataID) && (BoxData.AantalProductenGenest = AantalGenesteProducten)) { Set OrigineleBoxData = BoxData } } Else { If (BoxData.OrigineleBoxDataID = BoxDataID) { Set OrigineleBoxData = BoxData } } } Quit OrigineleBoxData ]]> 1 DS.Prod.OptiBox.SnijData ..#MaximumVerpakkingBreedteVoorEuropallet : ..#MaximumVerpakkingBreedteVoorEuropallet, 1: Overdoos.overallwidth) //10 Als extra marge zodat het stapelen goed lukt Set BoxDataOverdoosAangevuld.Diepte = Overdoos.overalllength + 10 //10 Als extra marge zodat het stapelen goed lukt Set BoxDataOverdoosAangevuld.Hoogte = Overdoos.overallheight + 10 //10 Als extra marge zodat het stapelen goed lukt #dim SnijData As DS.Prod.OptiBox.SnijData = ..MaakSnijDataVoorOverdoos(BoxDataOverdoosAangevuld, Overdoos, .OptiData, AfbeeldingCode, SnijDataParent, IsOverdoosNodig) #dim SnijDefOverdoos As DS.Prod.OptiBox.sub.emSnijDef = ..MaakSnijDef(BoxDataOverdoosAangevuld) Do SnijData.SnijDefs.SetAt(SnijDefOverdoos, ##class(APPS.Verpakking.enu.MachineID).VH()) #dim SaveStatus As %Status = SnijData.%Save() Do ##class(TECH.Exceptions.StatusException).ThrowIndienNietOK(SaveStatus,"Het bewaren van SnijData voor de overdozen is niet gelukt.") Quit SnijData ]]> BoxDataLijst:%ListOfObjects,ParentSnijData:DS.Prod.OptiBox.BoxData,OptiDataParent:DS.Prod.OptiBox.OptiData,Groep:%String 1 BoxDataMetID:DS.Prod.OptiBox.BoxDataMetID 1 DS.Prod.OptiBox.sub.emSnijDef BoxDataMetID:DS.Prod.OptiBox.BoxDataMetID 1 APPS.Verpakking.dto.Doos 1 DS.Prod.OptiBox.SnijData BoxDataMetID:DS.Prod.OptiBox.BoxDataMetID,Sequentie:%Integer,OptiData:DS.Prod.OptiBox.OptiData,Product:DOM.PM.Product,SnijDataParent:DS.Prod.OptiBox.SnijData,SnijDataBoxParent:DS.Prod.OptiBox.SnijData,ProductAantal:%Integer,AfbeeldingCode:%String="" 1 DS.Prod.OptiBox.SnijData 1: BoxDataMetID.AantalProductenGenest, 1:ProductAantal) } Else { Set SnijData.ProductAantal = ProductAantal } Set SnijData.PRNr = $Select($$$Not(+BoxDataMetID.ObjRef) = 0 : +BoxDataMetID.ObjRef, 1: "") Set SnijData.Reference = "L." _ ..BonId _ "."_ OptiData.%Id() If (Sequentie > 0) { Set SnijData.Sequentie = Sequentie } Set SnijData.SnijMachineID = ##class(APPS.Verpakking.enu.MachineID).VH() Set SnijData.Simulate = $$$False #dim SaveStatus As %Status = SnijData.%Save() Do ##class(TECH.Exceptions.StatusException).ThrowIndienNietOK(SaveStatus,"Het bewaren van SnijData in MaakSnijData is niet gelukt.") Set SnijData.BoxDeelVan = SnijData Set SaveStatus = SnijData.%Save() Do ##class(TECH.Exceptions.StatusException).ThrowIndienNietOK(SaveStatus,"Het bewaren van SnijData in MaakSnijData is niet gelukt.") Quit SnijData ]]> BoxDataMetID:DS.Prod.OptiBox.BoxDataMetID,Product:DOM.PM.Product="",OptiDataParent:DS.Prod.OptiBox.OptiData="",OptiDataBoxParent:DS.Prod.OptiBox.OptiData="" 1 DS.Prod.OptiBox.OptiData 0 : BoxDataMetID.Aantal, 1:1) Set OptiData.Status = "L" #dim SaveStatus As %Status = OptiData.%Save() Do ##class(TECH.Exceptions.StatusException).ThrowIndienNietOK(SaveStatus,"Het bewaren van OptiData is niet gelukt.") Quit OptiData ]]> 1 CubeIQRequest:APPS.Verpakking.dto.CubeIQ.Request 1 APPS.Verpakking.dto.CubeIQ.Response 1 %Boolean Request:APPS.Verpakking.dto.CubeIQ.Request 1 %Net.HttpRequest BoxDataLijst:%ListOfObjects 1 DS.Prod.OptiBox.BoxDataMetID BoxDataLijst:%ListOfObjects,Groep:%String 1 DS.Prod.OptiBox.BoxDataMetID Overdoos:APPS.Verpakking.dto.CubeIQ.Response.LoadedContainer,MinimumAantalPallettenVoorBon:%Integer 1 %Decimal */ #dim VolumeFactor As %Integer = ##class(TECH.Math).Pow((Overdoos.overallheight * Overdoos.overalllength * Overdoos.overallwidth), 1/3) #dim GrondOppervlakFactor As %Integer = ##class(TECH.Math).Pow((Overdoos.overalllength * Overdoos.overallwidth), 1/2) * 0.1 #dim StabiliteitFactor As %Decimal = Overdoos.overallheight / ##class(TECH.Math).Min(Overdoos.overalllength, Overdoos.overallwidth) * 50 #dim TotaleKartonOppervlakteFactor As %Integer = ##class(TECH.Math).Pow((2 * ((Overdoos.overalllength * Overdoos.overallwidth) + (Overdoos.overalllength * Overdoos.overallheight) + (Overdoos.overallheight * Overdoos.overallwidth))), 1/2) * 3 #dim GrondOppervlakKleinerDanHalvePalletFactor As %Integer = $Select(((..GrootsteDimensieGrondvlak < (..#MaximumOverdoosBreedteVoorEuropallet)) && (..TweedeGrootsteDimensieGrondvlak < (..#MaximumOverdoosDiepteVoorEuropallet / 2))):-200, 1:0) #dim VierkantigheidFactor As %Integer = ##class(TECH.Math).Max(##class(TECH.Math).Max(##class(TECH.Math).Abs(Overdoos.overalllength - Overdoos.overallwidth), ##class(TECH.Math).Abs(Overdoos.overalllength - Overdoos.overallheight)), ##class(TECH.Math).Abs(Overdoos.overallheight - Overdoos.overallwidth)) * 0.5 #dim HoogteKleinerDan33cm As %Integer = $Select(Overdoos.overallheight < 330:-100, 1:0) Quit (VolumeFactor + GrondOppervlakFactor + StabiliteitFactor + TotaleKartonOppervlakteFactor + GrondOppervlakKleinerDanHalvePalletFactor + VierkantigheidFactor + HoogteKleinerDan33cm) ]]> BoxDataLijst:%ListOfObjects 1 BoxDataLijst:%ListOfObjects %ListOfObjects 0) { Set BoxData.Breedte = BoxData.Breedte + BoxData.Params.GetAt("LS").Waarde } Else { //Default Set BoxData.Breedte = BoxData.Breedte + 60 } } If (BoxData.Params.GetAt("RT").WaardeExec = 0) { If (BoxData.Params.GetAt("RS").Waarde > 0) { Set BoxData.Breedte = BoxData.Breedte + BoxData.Params.GetAt("RS").Waarde } Else { //Default Set BoxData.Breedte = BoxData.Breedte + 60 } } } } Do GegroepeerdeBoxDataLijst.Insert(BoxData) } Quit GegroepeerdeBoxDataLijst ]]> BoxDataLijst:%ListOfObjects 1 %ListOfObjects BoxDataLijst:%ListOfObjects %ListOfObjects BoxDataLijst:%ListOfObjects %ListOfObjects 0) { Do GegroepeerdeBoxDataLijst.Insert(BoxDataVoorGegroepeerdeMatten) } #dim GroepenIterator As TECH.Iterator = ##class(TECH.ListIterator).%New(..TeGroeperenVolumes) While GroepenIterator.HasNext() { #dim Groep As %String = GroepenIterator.Next() #dim BoxDataVoorGegroep As DS.Prod.OptiBox.BoxDataMetID = ..GeefBoxDataVoorGroep(BoxDataLijst, Groep) If (BoxDataVoorGegroep.Aantal > 0) { Do GegroepeerdeBoxDataLijst.Insert(BoxDataVoorGegroep) } } While BoxDataIterator.HasNext() { #dim BoxData As DS.Prod.OptiBox.BoxDataMetID = BoxDataIterator.Next() If $$$Not(BoxData.VolumeVan = "") { If ($$$Not(##class(TECH.StringUtils).Equals(BoxData.VolumeVan.%Id(), "OL||Antislipmat groep||1")) && $$$Not(##class(TECH.ListUtils).Contains(..TeGroeperenVolumes, BoxData.VolumeVan.%Id()))) { Do ##class(TECH.ExceptionHandler).Throw(##class(TECH.Exceptions.UnimplementedException).%New("Groepering "_ BoxData.VolumeVan.%Id() _"' is nog niet geïmplementeerd bij de optimalisatie van de verpakking van de orgalux bonnen. Dit zorgt voor problemen bij bon " _..BonId _".")) } } Else { Do GegroepeerdeBoxDataLijst.Insert(BoxData) } } Quit GegroepeerdeBoxDataLijst ]]> BonID:%String %ListOfObjects 0) && $$$Not(BoxData.Aantal = -1)) { If ($$$Not(BoxData.MaxCombinAantal = "") && $$$Not(BoxData.MaxCombinAantal = 1) && (Qty > 1)) { //Verdelen in evenredige stapels #dim GelijkVerdeeldeAantallenLijstIterator As TECH.Iterator = ..GeefGelijkVerdeeldeAantallenLijstIterator(Qty, BoxData.MaxCombinAantal) While GelijkVerdeeldeAantallenLijstIterator.HasNext() { #dim Aantal As %Integer = GelijkVerdeeldeAantallenLijstIterator.Next() Set Params("PRODAANTAL") = Aantal Set Params("AANTAL") = Aantal Set BoxData.AantalProductenGenest = Aantal Set BoxData.Aantal = 1 Set BoxData.Breedte = ..CalcMetDefault(1, BoxData.BreedteExec, .Params) Set BoxData.Diepte = ..CalcMetDefault(1, BoxData.DiepteExec, .Params) Set BoxData.Hoogte = ..CalcMetDefault(1, BoxData.HoogteExec, .Params) If ((##class(TECH.Math).Max(BoxData.Breedte, BoxData.Diepte) >= (..#MaximumVerpakkingBreedteVoorEuropallet )) || (##class(TECH.Math).Min(BoxData.Breedte, BoxData.Diepte) >= ..#MaximumVerpakkingDiepteVoorEuropallet)) { Do ..Logger.Debug("PastProductOpEuropallet", "Genest product "_PRNr_" past niet op een europallet voor bon " _ BonID_". Er zijn " _ Aantal _" producten genest in deze verpakking.") } Else { Do BoxDataLijst.Insert(BoxData) } Set BoxData = ..CopyBoxData(BoxData) } } Else { Set Params("PRODAANTAL") = Qty Set Params("AANTAL") = Qty Set BoxData.Aantal = Qty Set BoxData.Breedte = ..CalcMetDefault(1, BoxData.BreedteExec, .Params) Set BoxData.Diepte = ..CalcMetDefault(1, BoxData.DiepteExec, .Params) Set BoxData.Hoogte = ..CalcMetDefault(1, BoxData.HoogteExec, .Params) If ((##class(TECH.Math).Max(BoxData.Breedte, BoxData.Diepte) >= ..#MaximumVerpakkingBreedteVoorEuropallet) || (##class(TECH.Math).Min(BoxData.Breedte, BoxData.Diepte) >= ..#MaximumVerpakkingDiepteVoorEuropallet)) { Do ..Logger.Debug("PastProductOpEuropallet", "Product "_PRNr_" past niet op een europallet voor bon " _ BonID_".") } Else { Do BoxDataLijst.Insert(BoxData) } } } } } Quit BoxDataLijst ]]> BoxData:DS.Prod.OptiBox.BoxData 1 DS.Prod.OptiBox.BoxDataMetID BonID:%String 1 TECH.Iterator TeVerdelenGetal:%Integer,MaximaleVerdeling:%Integer 1 TECH.Iterator MaximumProductenPerStapel) { Do AantallenLijst.Insert(MaximumProductenPerStapel) Set TeVerdelenGetal = TeVerdelenGetal - MaximumProductenPerStapel } If (TeVerdelenGetal > 0) { Do AantallenLijst.Insert(TeVerdelenGetal) } Quit ##class(TECH.ListIterator).%New(AantallenLijst) ]]> 1 Berekenen van een expressie door gebruik te maken van de waarden in Params 1 0 ",1)_"> "_Expression New msg Set $ECODE="" Set msg="EXECUTE FOUT: "_Expression_$$ArrayToText^vhLib("Params",.Params) Do WLFMT^vhDBG(msg,"B-Red") Set Result="ERR" Quit Result ]]> Status:%Status,HttpRequest:%Net.HttpRequest 1 CubeIQRequest:APPS.Verpakking.dto.CubeIQ.Request 1 %String JsonStream:%Stream,RootObjectClassname:%String 1 TECH.RegisteredObject 1 %TimeStamp Getal:%Integer,TotaleLengteGetal:%Integer 1 %String ProductID:%Integer 1 TECH.Integer ObjRef:%String 1 TECH.Integer