Verwerking van de optimisatie van een doos. De metadefinitie definieert de BoxSelect van de Optimizer en geeft defaults voor de BoxData BL.Prod.OptiBox,Prod.Product 1 %RegisteredObject 0 192.168.1.15 8888 0 %String WS.Prod.PanOpti.q1.OPTIREQ %Boolean %Integer Bijhouden van de referenties (ObjType.ObjRef) tijdens opbouw van de optimisationrequest %String 1 Als dit ingevuld is dan wordt de MachineID onthouden in de OptiData zodanig dat bij ontvangst van een optimalisation result het snijden onmiddellijk wordt gestart %String Als dit ingevuld is dan wordt de PPSOutput onthouden in de OptiData 0 = rechtdoor, 1 = rechts, 2 = links %String Als dit ingevuld is dan wordt de SnijPrioriteit onthouden in de OptiData If de SnijPrioriteit is NEGATIEF dan wordt er SNIJSIMULATIE uitgevoerd en wordt de doos niet echt gesneden %String Onthouden welke dozen onmiddellijk moeten gesneden worden bij ontvangst van een optimalisation result waarbij in de OptiData de machineID is ingevuld %String 1 %String 1 1 expression BoxDataObjType:%String %String D ##class(BL.Prod.OptiBox.Optimize).GetStatus() 1 Hierachische structuur serialiseren met parentlinks OptiRes:BL.Prod.OptiBox.sub.pxOptiResult 1 Do ; Callback . . ;Do WL^vhDBG("ProcessOptiResult:Called CallBack") . . Set (Msg,Ref)="" For Set Ref=$O(arErrors(Ref)) Quit:Ref="" Set Msg=Msg_$S($L(Msg):"; ",1:"")_arErrors(Ref) . . Set Status=$S($L(Msg):$$$qsError,1:$$$qsFinished) . . Do $zobjclassmethod($LI(CallBack), $LI(CallBack,2) ,oQ.ObjType, oQ.ObjRef, $LG(CallBack,3), OptiRes.OptiID,$$$qtOptimizer, Status, Msg) . Else ;Do WL^vhDBG("ProcessOptiResult:No CallBack") If $D(..SnijRefs) Do ; Direct snijden van de ontvangen optimalisatie . ;Do WL^vhDBG("ProcessOptiResult:Direct Snijden") . Set MachineID="" . For MachineID=$O(..SnijRefs(MachineID)) Quit:MachineID="" Do . . Set SnijPrioriteit=$G(..SnijRefs(MachineID),5) . . Kill SnijRefs . . Merge SnijRefs=..SnijRefs(MachineID) . . Set MachineID2=MachineID . . If MachineID="?" Do ; Bepalen aan de hand van snijdef . . . Set VolgNr="" . . . For Set VolgNr=$O(SnijRefs(VolgNr)) Quit:VolgNr="" Do . . . . Set oSnijData=SnijRefs(VolgNr) . . . . Set MaID="" . . . . For Set MaID=oSnijData.SnijDefs.Next(MaID) Quit:MaID="" Do . . . . . Set MaID(MaID)=$G(MaID(MaID))+1 ; aantal keer dat MaID voorkomt . . . Set MachineID2="",Max=0,MaID="" . . . For Set MaID=$O(MaID(MaID)) Quit:MaID="" Set:Max pxBox,OptiID oSnijData,BoxUsage,arSnijDefs oSnijParent,oSnijData,BoxUsage 0 splits in meerdere snijdefs Set oOptiData.UpdateTijdStip=$$$TimeStamp($H) Do oOptiData.%Save() Do ..MarkParentOptiData(oOptiData.Parent) If $L(oOptiData.MachineID)&&(oSnijData.Errors="") Do ; Onmiddellijk snijden indien er geen errors zijn . Set ..SnijRefs(oOptiData.MachineID,$O(..SnijRefs(oOptiData.MachineID,""),-1)+1)=oSnijData . Set ..SnijRefs(oOptiData.MachineID)=oOptiData.SnijPrioriteit ]]> sommige parent hebben geen optimalisatie zijn alleen bedoeld voor groeping daarom worden deze gemarkeerd van uit de parent link van een child oOptiData D ##class(BL.Prod.OptiBox.Optimize).TestOneBox() 1 W ##class(BL.Prod.OptiBox.Optimize).HasOptiData("PR",435361) 1 ObjType,ObjRef 0 ;&SQL(DECLARE HasOptiData CURSOR FOR ;SELECT ID INTO :Key FROM Prod.OptiBox_BoxData WHERE ObjType= :ObjType and ObjRef= :ObjRef and (Aantal<>-99 AND AantalExec<>-99) and (OptiType='BOX' OR OptiType='FILLER' OR Meta->OptiType='BOX' OR Meta->OptiType='FILLER' OR VolumeVan IS NOT NULL)) ;&sql(OPEN HasOptiData) ;&sql(FETCH HasOptiData) ;Quit:SQLCODE "" ;&sql(CLOSE HasOptiData) ;Quit 1 ]]> 1 ObjType,ObjRef -99 AND AantalExec<>-99) and (OptiType='BOX' OR OptiType='FILLER' OR Meta->OptiType='BOX' OR Meta->OptiType='FILLER' OR VolumeVan IS NOT NULL)) Quit Aantal ]]> d ##class(BL.Prod.OptiBox.Optimize).%New().GetVolume(403427,1,.B,.D,.H) 1 Do ;aantal verdelen overmeerdere dozen . . Set lbQty=..SplitQty(Qty,oData.MaxCombinAantal) . Else Do ; Geen meerdere aantallen van het zelfde product in 1 doos . . Set lbQty=$LB($LB(Qty,0)) . . For LoopCnt=1:1:$LL(lbQty) Do . . Set ProdQty=$LG($LI(lbQty,LoopCnt),2) . . Set Qty=$LG($LI(lbQty,LoopCnt),1) . . Set Params("PRODAANTAL")=ProdQty . . Set Params("AANTAL")=Qty . . Set Breedte=..Calc(oData.BreedteExec,.Params) . . Set Diepte=..Calc(oData.DiepteExec,.Params) . . Set Hoogte=..Calc(oData.HoogteExec,.Params) &sql(CLOSE GetVolume) ]]> 1 PRNr,Qty 1 BL.Sys.Proxy.pxStatus 1 KLNr,ObjType,ObjRef,DebugInfo 1 ObjType,ObjRef KlantNaam,Priority:%Integer,CallBack:%List,SnijPrioriteit:%Integer,PPSOutput:%Integer,MachineID:%String %String InSync WS.Prod.PanOpti.q1.STATUSRES wordt opgevangen worden door een errortrap ! . Do oLog.Update("E",,,,,"NO STATUS") Quit Status ]]> pxParent,Ref,Product,Breedte,Diepte,Hoogte Vanuit de verpakkings definitie van een product wordt de doos of dozen gedefinieerd volgende de cutvolgorde WS.Prod.PanOpti.q1.BOXDEF Vanuit de verpakkingsdefinitie wordt de te optimizeren doos of dozen gedefinieerd volgende de cutvolgorde WS.Prod.PanOpti.q1.BOXDEF OrigQty,Combin Lowlevel : Invullen van een te optimiseren box WS.Prod.PanOpti.q1.BOXDEF 1 Do ;aantal verdelen overmeerdere dozen . Set lbQty=..SplitQty(Qty,oData.MaxCombinAantal) Else Do ; Geen meerdere aantallen van het zelfde product in 1 doos . Set lbQty=$LB($LB(Qty,0)) If $isObject(oData.VolumeVan) Do ; De verzameldoos wordt gekoppeld aan de parent, en oData (meestal een volume) wordt onderdeel van de verzameldoos . Set pxParent=..DefineVolumeVan(pxParent,oData,BasisRef) . Set IsSubBox=1 Set ParamsAantalExist=$D(Params("AANTAL")) For LoopCnt=1:1:$LL(lbQty) Do . Set ProdQty=$LG($LI(lbQty,LoopCnt),2) . Set Qty=$LG($LI(lbQty,LoopCnt),1) . Set Params("PRODAANTAL")=ProdQty . Set Params("AANTAL")=Qty . Set pxBox=##class(WS.Prod.PanOpti.q1.BOXDEF).%New() . ; BoxSelect afhankelijk van klant . If $L(oData.BoxSelect) Do . . Set BoxSelectID=oData.BoxSelect . Else Do . . Set Key="",AlgBoxSelectID="" . . For Set oBoxSelect=oMeta.BoxSelect.GetNext(.Key) Quit:Key="" Do:$isObject(oBoxSelect) . . . Set:oBoxSelect.Klanten="" AlgBoxSelectID=oBoxSelect.Naam . . . Set:(..KLNr?4.6N)&&$LF(oBoxSelect.Klanten,..KLNr) BoxSelectID=oBoxSelect.Naam . . Set:$G(BoxSelectID)="" BoxSelectID=AlgBoxSelectID . Set pxBox.BOXSELECT=BoxSelectID . ;Do WL^vhDBG("BoxSelectID"_BoxSelectID) . Set pxBox.QTY=..Calc(oData.AantalExec,.Params) . ;Do WL^vhDBG("Qty"_pxBox.QTY) . If ..SnijPrioriteit<0 Quit:+pxBox.QTY=-99 Set:pxBox.QTY<0 pxBox.QTY=-pxBox.QTY ; Bij SIMULATIE wordt alle aantallen met -99 niet toegevoegd de negatieve aantallen die niet gesneden worden worden wel opgenomen als pos. getallen . Else Quit:+pxBox.QTY<0 ; Negatief of 0 aantal, dan niet toevoegen . . Set pxBox.OPTITYPE=$ZCVT($S(oData.OptiType'="":oData.OptiType,oMeta.OptiType'="":oMeta.OptiType,1:"VOLUME"),"U") ; eerst bij Data, dan Meta en dan default . Set pxBox.PLACE=$ZCVT($S(oData.Plaatsing'="":oData.Plaatsing,1:oMeta.Plaatsing),"U") . Set pxBox.ROTATE=$TR($ZCVT($S(oData.Rotatie'="":oData.Rotatie,oMeta.Rotatie'="":oMeta.Rotatie,1:""),"U"),";","") . Set pxBox.LEVEL=$TR($ZCVT($S(oData.Positie'="":oData.Positie,oMeta.Positie'="":oMeta.Positie,1:"OIB"),"U"),"OIB;","BIT") ; Onder->Bottom, BinnenIn->Inside, Boven->Top . Set pxBox.REF=$G(BasisRef) . If $L($G(ProductRef)) Do . . Set pxBox.PRODUCT=$TR(ProductRef,"/\"," ") . Else If $G(PRNr)?4.7N Do . . Set pxBox.PRODUCT=$TR($P(^KPR(PRNr,0),"\"),"/\"," ") . If (VerpakkingVolgnummer > 1) Do . . Set pxBox.PRODUCT = pxBox.PRODUCT _ " deel " _ VerpakkingVolgnummer . ;d WL^vhDBG(oData.BreedteExec) . ;d WL^vhDBG(oData.DiepteExec) . Set pxBox.WIDTH=..Calc(oData.BreedteExec,.Params) . Set pxBox.DEPTH=..Calc(oData.DiepteExec,.Params) . Set pxBox.HEIGHT=..Calc(oData.HoogteExec,.Params) . Set:(BoxSelectID="OL SEPARATOR")&&('pxBox.HEIGHT) pxBox.HEIGHT=99 ; Heigth moet ingevuld zijn ook voor een separator . Set pxBox.WEIGHT=+$J($S($G(Gewicht):$J(Gewicht,0,0),1:"")/1000,0,2) ; in grammen . ;De properties : PassThrough, NestedWidth, Overhangsize, Overhangtickness, ... zijn speciale properties die indirect via de params gedefinieerd worden . . ; Koppelen van meta met data om extra properties voor de optimizer of extra params voor het snijrecept te bekomen . Set Key="" . For Set oMetaParam=oMeta.Params.GetNext(.Key) Quit:Key="" Do . . ;Do WL^vhDBG("MetaParam "_Key_" type:"_oMetaParam.Type) . . Set oDataParam=oData.Params.GetAt(Key) . . Quit:'$isObject(oDataParam) . . ;D WL^vhDBG("DataParam "_Key_" "_oDataParam.WaardeExec) . . Set Type=$S($E(Key,1,2)="O;":"X",1:oMetaParam.Type) . . If Type="O" Do ;Extra property voor optimizer . . . Set $zobjproperty(pxBox,Key)=..Calc(oDataParam.WaardeExec,.Params) . . Else If Type="X" Do ;Special OPTIONS voor optimizer . . . Set Val=..Calc(oDataParam.WaardeExec,.Params) . . . Quit:Val="" . . . Set $zobjproperty(pxBox,"OPTIONS")=$zobjproperty(pxBox,"OPTIONS")_$S($L($zobjproperty(pxBox,"OPTIONS")):";",1:"")_$P(Key,";",$L(Key,";"))_":"_Val . . . ;d WL^vhDBG("options property"_Key_" "_$zobjproperty(pxBox,"OPTIONS")) . . Else If Type="S" Do ;Extra property voor snijrecept . . . If '$IsObject(pxBox.PARAM) Set pxBox.PARAM=##class(WS.Prod.PanOpti.q1.ArrayOfBOXDEFPARAM).%New() . . . Set pxParam=##class(WS.Prod.PanOpti.q1.BOXDEFPARAM).%New() . . . Set pxParam.Key=Key . . . Set pxParam.Value=..Calc(oDataParam.WaardeExec,.Params) . . . Do pxBox.PARAM.BOXDEFPARAM.Insert(pxParam) . . ;. d WL^vhDBG(Key_"="_..Calc(oDataParam.WaardeExec,.Params)) . Set pxBox.ParentBox=pxParent . Do ..AddBox2OptiData(pxBox, oData, .Opties, .LijnRef,.ProdQty, .PRNr, .ProductRef,.IsSubBox) . Set:$L($P(pxBox.REF,".",1,2)) ..QueueRefs($P(pxBox.REF,".",1,2))="" ; onthouden voor opbouw van de queue . . Set:'$isObject(pxParent.BOX) pxParent.BOX=##class(WS.Prod.PanOpti.q1.ArrayOfBOXDEF).%New() . Do pxParent.BOX.BOXDEF.Insert(pxBox) . ;Do pxParent.BOX.Insert(pxBox) Quit $G(pxBox) ]]> pxParent,oData,BasisRef 0:ProdQty,1:1) Set oOptiData.DoosAantal=pxBox.QTY Set:$D(Opties("PPSGROEP")) oOptiData.PPSGroep=Opties("PPSGROEP") Set:$D(Opties("PPSSUBGROEP")) oOptiData.PPSSubgroep=Opties("PPSSUBGROEP") Set:$D(Opties("PPSOUTPUT")) oOptiData.PPSOutput=Opties("PPSOUTPUT") Set oOptiData.PPSPrioriteit=oData.PPSPrioriteit Set Status=oOptiData.%Save() Do:Status'=$$$OK WL^vhDBG($$ParseStatus^vhLib(Status)),WO^vhDBG(oOptiData) Set pxBox.OptiData=oOptiData ; om het OptiQueue object terug te vinden vanuit het resultaat Set Ref3=pxBox.REF,$P(Ref3,".",3)=oOptiData.%Id(),pxBox.REF=Ref3 ; om het OptiQueue object terug te vinden vanuit het resultaat ]]> Vertaling van een pseudo functie naar een objectscript functie String,aParams:BL.Prod.OptiBox.sub.pxemSnijParamList=$$$NULLOREF %String (Start-1) Result=Result_$E(String,LastPoint,Start-1) . . Set ULabel=$ZCVT(Label,"U") . . Set Result=Result_"Params("""_ULabel_""")" . . Do:($IsObject(aParams)) aParams.Add(ULabel,Label) . . Set LastPoint=Point . Else Set Point=Point+1 Set:LastPoint'>(Point-1) Result=Result_$E(String,LastPoint,Point-1) Quit Result ]]> Berekenen van een expressie door gebruik te maken van de waarden in Params 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 ]]> ObjType,ObjRef Do ##class(BL.Prod.OptiBox.Snijden).CleanOld($H) 1 Datum:%Date