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