#include PRGACNTs #include %occInclude /* s obj=##class(Prod.GAData.Template).%OpenId(29) s sc=obj.BuildMetaDef("IL=CB","F") w $S(sc>0:sc, 1:$$ParseStatus^vhLib(sc)) */ BuildMetaDef() ; (DItemVia,MetaFormat,lbMetaClass,lbFlags) #define NodeIC "IC" #define NodeIL "IL" #define NodePLItem "PLItem" #define mdCreated 1 #define mdUpdated 2 #define mdOverwrited 3 New Via,MDef,MDefClass,MGroepClass,lbProgLabels,Kenm,sc New blnExistMDef,blnUpdatedMDef Set Via=$P(DItemVia,"=",1) Set DItem=$$bmdGetDItem(Via,$P(DItemVia,"=",2)) ;d WL^vhDBG("DItem via "_DItemVia_" --> DItem: "_DItem.Code _" - "_DItem) Quit:('$IsObject(DItem)) $$$ERROR($$$GeneralError,"DItem kan niet gevonden") If Via="PL" Do . Set Kenm=$P(DItemVia,"=",2) Else Do . Set lbProgLabels=$$bmdGetProgLabels . Set Kenm=$LG(lbProgLabels,1) ; First ProgLabel . ;d WL^vhDBG("DItem ProgLabels="_$$$LCVT(lbProgLabels)) Quit:(Kenm="") $$$ERROR($$$GeneralError,"Geen Kenm via ProgLabel via DItem") Set MDefClass=$LG(lbMetaClass,1) Set MGroepClass=$LG(lbMetaClass,2) Quit:(MDefClass="")||(MGroepClass="") $$$ERROR($$$GeneralError,"Klasse naam voor MetaGroep of MetaDef niet opgegeven") Set MDef=$$bmdGetMDefObj(Kenm) Quit:('$IsObject(MDef)) $$$ERROR($$$GeneralError,"MetaDef kan niet geïnstantieerd worden voor Kenm "_GroepID_"||"_Kenm) Do MDef.GroepSetObjectId(GroepID) Set MDef.Kenmerk=Kenm Set MDef.VolgNr=$$bmdVolgNrAutoInc(GroepID,Kenm) Set MDef.Format=$S($L($G(MetaFormat)):MetaFormat,1:"T") Set MDef.Multiple=1 Set MDef.MultipleDisplay=1 Set MDef.Omschrijving=DItem.Get("Oms") Set MDef.SubGroep=DItem.SubGroepCode Set MDef.ToelatenEC=0 Set MDef.Verplicht=0 Set MDef.SortType="M" Set sc=MDef.%Save() If $$$ISERR(sc) Do Quit sc . Set MDef="" . ;d WL^vhDBG("Fout "_$$ParseStatus^vhLib(sc)) ; Else ; If $$$ISOK(sc) Do Set blnUpdatedMDef=1 ;d WL^vhDBG("Voor groep "_$S(MDef.Groep:MDef.Groep.Code, 1:"?")_" : Kenmerk "_MDef.Kenmerk_" aangemaakt/ge-update") ;d WL^vhDBG("DumpObject:"_$$$CRLF_$$ObjToText^vhLib(MDef)) Quit $S($G(blnExistMDef):$S($G(blnUpdatedMDef):$$$mdUpdated, 1:$$$mdOverwrited),1:$$$mdCreated) Quit $$$OK bmdGetDItem(Via,Key) Do:(Via="IL")&&('$$$aHasData(GAProd.LookUp($$$NodeIL))) GAProd.BuildLookUp($LB("ICode")) Do:(Via="PL")&&('$$$aHasData(GAProd.LookUp($$$NodePLItem))) GAProd.BuildLookUp($LB("ICode")) ;d WL^vhDBG("Via="_Via_" Key="_Key_$$$CRLF_$$$ArrayTT("Lu",GAProd,"LookUp")) Quit:(Via="IC") GAProd.DataItemsGetChildAt(Key) ; DItem.Code Quit:(Via="IL") $G(GAProd.LookUp($$$NodeIL,Key)) ; ItemLabel Quit:(Via="PL") $G(GAProd.LookUp($$$NodePLItem,Key,"IOref")) ; ProgLabel Quit "" bmdGetProgLabels() New PL,tmpLB Set (PL,tmpLB)="" For Set PL=$O(GAProd.LookUp($$$NodeIC,DItem.Code,"PL",PL)) Quit:(PL="") Set tmpLB=tmpLB_$LB(PL) Quit tmpLB bmdVolgNrAutoInc(GroepID,Kenm) New SortedKenm,MaxVolgNr &SQL(SELECT Kenmerk,VolgNr INTO :SortedKenm, :MaxVolgNr FROM Prod_Kenmerk.MetaDefinitie WHERE (Groep = :GroepID) ORDER BY VolgNr DESC) Quit:($G(MaxVolgNr)<1) 1 Quit $S($G(SortedKenm)=$G(Kenm):MaxVolgNr ,1:MaxVolgNr+1) bmdGetMDefObj(Kenm) New GrpObj,SaveGrp Set SaveGrp=$$$OK If '$zobjclassmethod(MGroepClass,"%ExistsId",GroepID) Do . ;Set GrpObj=$zobjnew(MGroepClass) . Set GrpObj=$zobjclassmethod(MGroepClass,"%New") . ;Set GrpObj=##class(Prod.Kenmerk.MetaGroep).%New() . Set GrpObj.Code=GroepID . Set GrpObj.Omschrijving=$S($L(..MetaStruct.Omschrijving):..MetaStruct.Omschrijving ,1:"Oms. "_Groep) . Set GrpObj.VertalingsGroep="" . ;d WL^vhDBG("GrpObj :"_GrpObj_" voor GroepID:"_$G(GroepID,"?")) . ;d WL^vhDBG("DumpObject:"_$$$CRLF_$$ObjToText^vhLib(GrpObj)) . Set SaveGrp=GrpObj.%Save() . ;d WL^vhDBG("SaveGrp :"_$$ParseStatus^vhLib(SaveGrp)) . Set GrpObj="" Quit:($$$ISERR(SaveGrp)) "" ;d WL^vhDBG("Groep OK") Set blnExistMDef=($zobjclassmethod(MDefClass,"%ExistsId",GroepID_"||"_Kenm)) ;d WL^vhDBG("KenmExists "_Kenm_" ? "_(blnExistMDef)) Quit:('blnExistMDef) $zobjclassmethod(MDefClass,"%New") ; $zobjnew(MDefClass) Quit $zobjclassmethod(MDefClass,"%OpenId",GroepID_"||"_Kenm) /* TPConsistencyCheck() ; Parameters: CheckArray ; CheckArray als .local doorgeven) New ChkOK Set ChkOK=..Product.ConsistencyCheck(.CheckArray) n msg If ChkOK s msg="Alle Checks zijn OK. ("_$ZT($P($H,",",2),1)_")" Else Set msg="Inconsistente gegevens:"_$$$CRLF_$$ArrayToText^vhLib("CheckArray") d ..Product.TTrace(msg) Quit ChkOK */ TPConsistencyCheckVB() ; Parameters: (geen) New CheckArray,msg,TPProd Set TPProd=$S(..SchaduwActief:..SchaduwProduct, 1:..Product) Set msg=$$tpcVBCheckDItemCodes(TPProd) Quit:($L(msg)) msg ; Else If TPProd.ConsistencyCheck(.CheckArray) Set msg="" Else Do . New CheckArrayOut . Do ##class(Prod.GAData.Product).CheckArrayTranslate(.CheckArray,.CheckArrayOut,1) . Set msg="Inconsistente gegevens in de Template: "_$$$CRLF_$G(CheckArrayOut) Quit msg tpcVBCheckDItemCodes(TPProd) // DItem codes moeten uniek zijn over de hele template New tmpAr,Key,msg Set msg="" Set Key="" For Set DItem=TPProd.DataItems.GetNext(.Key) Quit:(Key="") Do . Set DItemCode=DItem.Code . If '$D(tmpAr(DItemCode)) Do .. Set tmpAr(DItemCode)=DItem . Else Do .. Set msg=msg_$$tpcBuildText(tmpAr(DItemCode),DItem)_$$$CRLF Quit msg tpcBuildText(DIFirst,DIDouble) New msgFirst,msgDbl Set msgFirst="SG:"_DIFirst.SubGroepCode_" - VNr:"_DIFirst.VolgNr_" - Meta:"_DIFirst.MetaItemGetObjectId()_" - Lbl:"_DIFirst.Label Set msgDbl="SG:"_DIDouble.SubGroepCode_" - VNr:"_DIDouble.VolgNr_" - Meta:"_DIDouble.MetaItemGetObjectId()_" - Lbl:"_DIDouble.Label Quit "Conflict Code: '"_DIDouble.Code_"' tussen DItems ("_msgFirst_") en ("_msgDbl_")." MakeVCompatible() ; Parameters: ProdID New Prod,Templ,CVResult Set Templ=##class(Prod.GAData.Template).GetTemplFromProdID($G(ProdID),.Prod) Quit:('Templ) "No Template object" Quit:(Templ.SchaduwActief) "Schaduw is Actief. MakeVCompatible() is niet mogelijk." Set CVResult=Templ.CheckVersion(.Prod,$LB(1,1,0)) If CVResult=1 Do Quit "Version OK" . Set Prod="" Else Do . Do mvcSyncProd Quit "1" mvcSyncProd ; Het Prod-object wordt altijd gesloten (Prod="") New SyncStat,NewVersion,sc,SyncResult,KPRProductID Set KPRProductID=Prod.ProductGetObjectId() Set NewVersion=Templ.Product.TemplateVersion Set Prod.TemplateVersion=NewVersion Set sc=Prod.%Save() Set Prod="" Set SyncResult=Templ.SyncProd(ProdID,ProdID,.SyncStat,$LB(0,1,0)) If (SyncResult=0) Do . ; TO DO: . ; Reset TemplateVersion Else Do . If $$IsVersienummerIngevuld^PRBS(KPRProductID) Do ZetVersienummer^PRBS(KPRProductID,"v"_NewVersion) Quit SyncProd() ; Parameters: ProdID,NewProdID,SyncStat,lbFlags #define StorageGAProd ^Prod.GAData.ProductD #define StorageDItems(%v) $$$StorageGAProd(%v,"I") #define ndNoLabel "##NoLbl" s:('$D(%ClientIP)) %ClientIP="192.168.1.97" Quit:($G(ProdID)="") 1 New TemplID Set TemplID=$S((..SchaduwActief)&&($G(%CheckWithSchaduwTProduct,0)):..SchaduwProductGetObjectId() , 1:..ProductGetObjectId()) Quit:(TemplID="")||(TemplID=ProdID) 1 New arProd,arTempl,arNew,arComp,arSync,DestID New blnRemoveLostDItems,blnDoNotSave,blnForceSyncAll New DItemsTP,DItemsPR,DItemsNew,ProdPR Set NewProdID=$G(NewProdID,"New"_ProdID) ; Flags Set blnDoNotSave=$LG(lbFlags,1,1) ; Alleen analyse van het te synchroniseren product Set blnRemoveLostDItems=$LG(lbFlags,2,0) ; De DItems die niet meer voorkomen in Template, niet mee kopiëren Set blnForceSyncAll=$LG(lbFlags,3,0) ; Forceren om alle DItems te synchroniseren Kill SyncStat ; Build LookUps Do sypLabelsFromObj(TemplID,.arTempl) Do sypLabelsFromObj(ProdID,.arProd) ; Sync-tabel opstellen Do sypBuildSyncTabel /* zw arComp w ! zw arSync w ! w $$ArrayToText^vhLib("SyncStat") If RetVal Do . k SyncStat("SAME") . If $D(SyncStat) Do .. w " niet alle items synchroon:"_$$ArrayToText^vhLib("SyncStat"),! . Else Do .. w " Alle items lopen synchroon met de Template." Else Do . w " SyncProd is mislukt.",! */ Quit:(blnDoNotSave) 1 ; Storage/Globals to Locals Merge DItemsTP=$$$StorageDItems(TemplID) Merge DItemsPR=$$$StorageDItems(ProdID) Set ProdPR=$$$StorageGAProd(ProdID) ; Syncronize via Item Label Do sypSyncDItems Do sypResetKostItems ; Create/Save (new) synchronised Product Do sypCleanUpData Set $$$StorageGAProd(NewProdID)=ProdPR Merge $$$StorageDItems(NewProdID)=DItemsNew /*** DEBUG-Version *** / /*** ============= *** / ;New OutF,scF,WrAttrib,FilePath ;Set FilePath="C:\Temp\GAProd.Data.Debug.txt" ;Set WrAttrib=$G(WrAttrib,"WSN") ;Set OutF=##class(%Library.File).%New(FilePath) ;Set scF=OutF.Open(WrAttrib) ; "WSN" ; ;q:('scF) ;d ArrayToTextW^vhLib($Na($$$StorageDItems(ProdID)),OutF) ;d WL^vhDBG("DItems before ALL: "_$$ArrayToText^vhLib($Na($$$StorageDItems(ProdID)))) ; Syncronize via Item Label Do sypSyncDItems ;d ArrayToTextW^vhLib("DItemsNew",OutF) ;d WL^vhDBG($$$CRLF_$$$CRLF_$$$CRLF_"DItemsNew: "_$$ArrayToText^vhLib("DItemsNew")) Do sypResetKostItems ;d ArrayToTextW^vhLib("DItemsNew",OutF) ;d WL^vhDBG($$$CRLF_$$$CRLF_$$$CRLF_"DItemsNew: after ResetKost: "_$$ArrayToText^vhLib("DItemsNew")) ; Create/Save (new) synchronised Product Do sypCleanUpData ;d ArrayToTextW^vhLib($Na($$$StorageDItems(ProdID)),OutF) ;d WL^vhDBG($$$CRLF_$$$CRLF_$$$CRLF_"DItems after CleanUpData: "_$$ArrayToText^vhLib($Na($$$StorageDItems(ProdID)))) Set $$$StorageGAProd(NewProdID)=ProdPR Merge $$$StorageDItems(NewProdID)=DItemsNew ;d ArrayToTextW^vhLib($Na($$$StorageDItems(ProdID)),OutF) ;d WL^vhDBG($$$CRLF_$$$CRLF_$$$CRLF_"DItems after Merge New: "_$$ArrayToText^vhLib($Na($$$StorageDItems(ProdID)))) ;Set OutF="" /*** ============= ***/ Do sypSyncItemsVolgNr(TemplID,NewProdID) d WL^vhDBG("SyncProd Update ("_..MetaStruct.Code_"/"_TemplID_"): ProdID="_ProdID) New objPR Set objPR=##class(Prod.GAData.Product).%OpenId(NewProdID) ;Do sypConsistencyCheck(NewProdID) Quit:('$$sypConsistencyCheckObj(objPR)) 1 Do sypSetDataDefaults(objPR) Set objPR="" Quit 1 sypSyncItemsVolgNr(TemplID,ProdID) #define liSGCode 3 #define liVolgNr 4 #define liCompare 4 New ID,tmpLB,liCompare Set ID="" Set liCompare=$$$Max($$$liSGCode,$$$liVolgNr) ; d WL^vhDBG("SyncItemsVolgNr $LI: 1 - "_liCompare) For Set ID=$O($$$StorageGAProd(TemplID,"I",ID)) Quit:(ID="") Do . If '$$$aHasData($$$StorageGAProd(ProdID,"I",ID)) Do Quit ; niet consistente data . . d WL^vhDBG("!!! No data on "_$Na($$$StorageGAProd(ProdID,"I",ID))_" !!!") . ; Else . Set tmpLB=$$$StorageGAProd(TemplID,"I",ID) . ;d:($LI($$$StorageGAProd(ProdID,"I",ID),1,liCompare)=$LI(tmpLB,1,liCompare)) WL^vhDBG("Data OK") . Quit:($LI($$$StorageGAProd(ProdID,"I",ID),1,liCompare)=$LI(tmpLB,1,liCompare)) ; data OK . ;d:($LI($$$StorageGAProd(ProdID,"I",ID),$$$liSGCode)=$LG(tmpLB,$$$liSGCode)) WL^vhDBG("Update VolgNr: "_$LI($$$StorageGAProd(ProdID,"I",ID),$$$liVolgNr)_" --> "_$LG(tmpLB,$$$liVolgNr)) . Set:($LI($$$StorageGAProd(ProdID,"I",ID),$$$liSGCode)=$LG(tmpLB,$$$liSGCode)) $LI($$$StorageGAProd(ProdID,"I",ID),$$$liVolgNr)=$LG(tmpLB,$$$liVolgNr) Quit sypLabelsFromObj(ObjID,arObj) New ID,Lbl Kill arObj Set SQLCODE="" &sql(DECLARE crsGA1 CURSOR FOR SELECT Code,Label INTO :ID, :Lbl FROM Prod_GAData.Item WHERE (Product=:ObjID)) &sql(OPEN crsGA1) For &sql(FETCH crsGA1) Quit:(SQLCODE) Set:($L(Lbl)) arObj(Lbl,"ID")=ID Set:('$L(Lbl)) arObj($$$ndNoLabel,"ID",ID)="" ;d WL^vhDBG(ObjID_". "_ID_" "_Lbl) ; W ID_" "_Lbl,! &sql(CLOSE crsGA1) Quit sypBuildSyncTabel New Key,TPID,PRID,tmpAr,Compare Merge tmpAr=arProd ; tmpAr systematisch opkuisen totdat enkel DItems overblijven die niet meer in Templ-Prod voorkomen. Dit geeft een lijst van "LostID" Set Key="" For Set Key=$O(arTempl(Key)) Quit:(Key="") Do . Quit:(Key=$$$ndNoLabel) . Set TPID=arTempl(Key,"ID") . Set PRID=$G(arProd(Key,"ID")) . Set arComp("ID",TPID)=PRID . Set Compare=$S(TPID=PRID:"SAME", PRID="":"NEW", 1:"DIFF") ; , TPID="":"LOST" ; TPID kan niet leeg zijn, want For Loop arTempl() . Set:(Compare'="SAME")||(blnForceSyncAll) arSync("ID",TPID)=PRID . Set SyncStat(Compare)=$G(SyncStat(Compare))_$LB(TPID) . Kill:($L(PRID))&&($D($$$StorageGAProd(TemplID,"I",PRID))) tmpAr(Key) Set Compare="LOST" Set Key="" For Set Key=$O(tmpAr(Key)) Quit:(Key="") Do ; loopt door de overgebleven DItems; ID's in een lijst "LostID" bijhouden . If Key=$$$ndNoLabel Do Quit .. ;Merge arSync($$$ndNoLabel)=tmpAr($$$ndNoLabel,"ID") . Set PRID=$G(arProd(Key,"ID")) . Set arComp("LostID",PRID)="" . ;Set arSync("LostID",PRID)="" . Set SyncStat(Compare)=$G(SyncStat(Compare))_$LB(PRID) Merge arSync("LostID")=arComp("LostID") Quit sypSyncDItems #define liFixedKeys 6 New liFixedKeys Set liFixedKeys=$$$liFixedKeys ; Hard-coded positie in de $LB() - altern.: get storage-position from ^oddDef() Set DestID="" For Set DestID=$O(arSync("ID",DestID)) Quit:(DestID="") Do . If $L($G(arSync("ID",DestID))) Do .. Merge DItemsNew(DestID)=DItemsPR(arSync("ID",DestID)) ; Values overnemen v/h oorspronkelijke product .. Set DItemsNew(DestID)=DItemsTP(DestID) ; DataItem-properties overschrijven met de waarden v/h Template-DItem .. Set $LI(DItemsNew(DestID),liFixedKeys)=$LG(DItemsPR(arSync("ID",DestID)),liFixedKeys) ; list-item FixedKeys overnemen v/h oorspronkelijke product . Else Do .. ;w "DItem met ID """_DestID_""" werd toegevoegd (gekopieerd van Template-DItem)",! .. Merge DItemsNew(DestID)=DItemsTP(DestID) ; Values overnemen v/h Template-DItem .. Kill DItemsNew(DestID,"AU") ; "Autos" alleen in template Do:('blnRemoveLostDItems) sypSyncStorageLostDItems Quit sypSyncStorageLostDItems ; De DItems komen niet meer voor in Template, maar kunnen toch gekopieerd worden. New ID Set ID="" For Set ID=$O(arSync("LostID",ID)) Quit:(ID="") Do . Merge:('$D(DItemsNew(ID))) DItemsNew(ID)=DItemsPR(ID) ; Values overnemen v/h oorspronkelijke product, alleen als deze node nog niet bezet is. Quit sypResetKostItems ; Overschrijven van de Kost-Items: ; - via LostID's zullen de Kost-items eerst verwijderd worden (in sypCleanUpData() ) ; - dan zullen de nieuwe Kost-items toegevoegd worden via "Merge $$$StorageDItems(NewProdID)=DItemsNew" New ID Set ID="" For Set ID=$O(DItemsPR(ID)) Quit:(ID="") Do:(ID?1"KST".E) . Set arSync("LostID",ID)="" For Set ID=$O(DItemsTP(ID)) Quit:(ID="") Do:(ID?1"KST".E) . Merge DItemsNew(ID)=DItemsTP(ID) ; Values overnemen v/h Template-DItem . Kill DItemsNew(ID,"AU") ; "Autos" alleen in template Quit sypCleanUpData ;k $$$StorageDItems(NewProdID) New ID Set ID="" For Set ID=$O(arSync("ID",ID)) Quit:(ID="") Do . Kill $$$StorageGAProd(NewProdID,"I",ID) Set ID="" For Set ID=$O(arSync("LostID",ID)) Quit:(ID="") Do . Kill $$$StorageGAProd(NewProdID,"I",ID) Quit sypConsistencyCheck(ProdID) New objPR,blnOK Set objPR=##class(Prod.GAData.Product).%OpenId(ProdID) Set blnOK=$$sypConsistencyCheckObj(objPR) Set objPR="" Quit blnOK sypConsistencyCheckObj(objPR) New arCC,arCCOut,DevObj Quit:(objPR.ConsistencyCheck(.arCC)=1) 1 ; Else Do ##class(Prod.GAData.Product).CheckArrayTranslate(.arCC,.arCCOut) d WL^vhDBG("Consistency errors for product (ID="_objPR.%Id()_") : "_$$$ArrayTT("arCC")) d WL^vhDBG(" > in words:"_$$$ArrayTT("arCCOut")) Quit 0 sypSetDataDefaults(objPR) ; De routines onder SetDataDefaults() zijn zeer specifiek geschreven en zijn dus grotendeels hard-coded. #define NOT(%v) '(%v) #define DItemVal(%v) $$$StorageGAProd(PRID,"I",%v,"P","Val") New blnSave,PRID Set blnSave=0 Set PRID=objPR.%Id() ;Do objPR.BuildLookUp($LB("PL")) Do sypSetDFLBinnenGreep Set:(blnSave) sc=objPR.%Save() Quit sypSetDFLBinnenGreep ;Quit $D(SyncStat(SAME,"BGRP")) New CodeBGRP,tmpCode Set CodeBGRP=$G(arTempl("BGRP","ID")) Quit:(CodeBGRP="")||($L($G($$$DItemVal(CodeBGRP)))) Quit:($G(arTempl("LT","ID"))="")||($G($$$DItemVal(arTempl("LT","ID")))'="B") Quit:($G(arTempl("RH","ID"))="")||($G($$$DItemVal(arTempl("RH","ID")))'?1(1"D",1"C")) ;d WL^vhDBG("SetDFLBinnenGreep LT:"_($$$DItemVal(arTempl("LT","ID")))_" RH:"_($$$DItemVal(arTempl("RH","ID")))) ; Else BGRP (leeg) moet ge-default worden voor de D/Z of C/Z lade Set $$$DItemVal(CodeBGRP)="H" d WL^vhDBG("BGRP set to ""H""") ;Set blnSave=1 Quit