Functiebeheer

  • 4 minutes to read

Met functiebeheer is het mogelijk om bepaalde functionaliteiten in of uit te schakelen.

Functie maken

Functies kunnen enkel gemaakt worden via code. Om een functie te maken, moeten volgende stappen worden doorlopen:

  1. Maak een codeunit CFL Exmample Feature die de interface "CFL Feature" implementeert.

     codeunit 50000 "CFL Example Feature" implements "CFL Feature"
     {
         Access = Internal;
         procedure CFLEnable()
         begin
             if not CFLCheckCanEnable(true) then
                 exit;
         end;
    
         procedure CFLDisable()
         begin
             if not CFLCheckCanDisable(true) then
                 exit;
         end;
    
         procedure CFLCheckCanEnable(ShowError: boolean): Boolean
         begin
             //place checks on necesary conditions to enable the feature, e.g. check if setup table exists, and fields are filled in
             exit(true);
         end;
    
         procedure CFLCheckCanDisable(ShowError: boolean): Boolean
         begin
             //place checks on necesary conditions to disable the feature
             exit(true);
         end;
    
         procedure CFLGetLearnMoreUrl() Url: text;
         var
             CFLExampleFeatureMgt: codeunit "CFL Example Feature Mgt";
         begin
             exit(CFLExampleFeatureMgt.CFLGetFeatureLink());
         end;
    
         procedure CFLGetDescription() Description: text;
         var
             CFLExampleFeatureMgt: codeunit "CFL Example Feature Mgt";
         begin
             exit(CFLExampleFeatureMgt.CFLGetFeatureDescription());
         end;
    
         procedure CFLDataUpgradeOnEnable()
         begin
             // Data upgrade on enable
         end;
    
         procedure CFLDataUpgradeOnDisable()
         begin
             // Data upgrade on disable
         end;
     }
    
    NOTE

    Deze interface heeft geen bijhorende enum. Er moet dus geen enumextension worden aangemaakt. Enkel de implementatie-codeunit is nodig.

  2. Maak een codeunit CFL Exmample Feature Mgt

    codeunit 50001 "CFL Example Feature Mgt"
    {
        Access = Internal;
    
        internal procedure CFLGetFeatureID(): text[50]
        begin
            exit('Example');
        end;
    
        internal procedure CFLGetFeatureDescription(): text[2048]
        var
            DescriptionLbl: label 'Example feature description';
        begin
            exit(DescriptionLbl);
        end;
    
        internal procedure CFLGetFeatureLink(): text[2048]
        var
            UrlLbl: Label 'https://exmaplefeaturelink/', Locked = true;
        begin
            exit(UrlLbl);
        end;
    
        local procedure CFLIsOneWay(): Boolean
        begin
            //true if the feature can only be enabled, not disabled
            exit(false);
        end;
    
        local procedure CFLCanTry(): Boolean
        begin
            //true if the feature can be tried out
            exit(true);
        end;
    
        local procedure CFLDataUpgradeNeeded(): Boolean
        begin
            //true if the feature needs a data upgrade
            exit(false);
        end;
    
        local procedure CFLSetupPage(): Integer
        begin
            //return the id of the setup page for the feature
            exit(0);
        end;
    
        procedure CFLIsFeatureEnabled(): Boolean
        var
            CFLFeatureMgt: codeunit "CFL Feature Management";
        begin
            exit(CFLFeatureMgt.CFLIsEnabled(CFLGetFeatureID()));
        end;
    
        internal procedure CFLAddFeature()
        var
            CFLFeatureMgt: Codeunit "CFL Feature Management";
            //CFLExample2FeatureMgt: codeunit "CFL Example2 Feature Mgt";
            EnableFor: enum "CFL Feature Enablement";
            AppInfo: ModuleInfo;
        begin
            NavApp.GetCurrentModuleInfo(AppInfo);
            if CFLFeatureMgt.CFLAddFeature(CFLGetFeatureID(), CFLIsOneWay(), AppInfo.id, CFLSetupPage(), CFLDataUpgradeNeeded(), CFLCanTry()) then
                if CFLFeatureMgt.CFLCheckCanEnable(CFLGetFeatureID()) then //this will check if the feature can be enabled, and enable it if possible - usefull for upgrade scenarios
                    //CFLFeatureMgt.CFLAddFeatureDependancy(CFLGetFeatureID(), CFLExample2FeatureMgt.CFLGetFeatureID()); //only if feature is dependant from other feature(s)
                    CFLFeatureMgt.CFLEnable(CFLGetFeatureID(), EnableFor::"CFL All Users");
        end;
    
        [EventSubscriber(ObjectType::Table, database::"CFL Feature", CFLOnAfterGetFeature, '', false, false)]
        local procedure CFLFeatureOnAfterGetFeature(FeatureID: text[50]; var CFLFeature: Interface "CFL Feature"; var IsHandled: Boolean)
        var
            CFLExampleFeature: codeunit "CFL Example Feature";
        begin
            if IsHandled then
                exit;
    
            if FeatureID = CFLGetFeatureID() then begin
                CFLFeature := CFLExampleFeature;
                IsHandled := true;
            end;
        end;
    
    }
    
  3. Voeg de feature toe adhv. een installatie of upgrade codeunit

    codeunit 50000 "CFL Example Install"
    {
        Access = Internal;
        Subtype = Install;
    
        trigger OnInstallAppPerCompany()
        var
            CFLExampleFeatureMgt: codeunit "CFL Example Feature Mgt";
        begin
            CFLExampleFeatureMgt.CFLAddFeature();
        end;
    }
    
  4. Pas de code aan om waar nodig te checken op de feature. Dit kan door de functie CFLExampleFeatureMgt.CFLIsFeatureEnabled() aan te roepen.

     procedure DoSomethingWithinFeature().
     var
         CFLExampleFeatureMgt: codeunit "CFL Example Feature Mgt";
     begin
          if not CFLExampleFeatureMgt.CFLIsFeatureEnabled() then 
             exit;
    
         //do something
     end;
    
  5. Pas de pagina's aan om de nodige componenten te verbergen of tonen. Dit kan de componenten een ApplicationArea mee te geven. De application area is de feature id, voorafgegaan door CFL, bvb: CFLExample.

     page 50000 "CFL Example Page"
     {
         ApplicationArea = CFLExample;
         ...
     }
    
    NOTE

    De CFL prefix is nodig om niet te interfereren met andere extensies die ook de application area gebruiken (zoals bvb Microsoft System of Base Application).

Functie Obsoleten

Indien functies niet meer van toepassing zijn, niet meer worden gebruikt, kunnen deze obsolete gemaakt worden.
De obsolete status kan volgende waarden hebben:

  • None: De functie is niet obsolete.
  • Pending: De functie is obsolete, maar kan nog worden ingeschakeld.
  • Removed: De functie is niet meer bruikbaar, en kan niet meer worden ingeschakeld.
NOTE

Een obsolete Removed functie zal automatisch worden uitgeschakeld en zal niet meer kunnen worden ingeschakeld.

NOTE

Een obsoleted functie blijft zichtbaar in de lijst van features.

Functies kunnen enkel obsolete gemaakt worden via code. Om een functie te obsolete te maken, moeten volgende stappen worden doorlopen:

  1. Obsolete de feature toe adhv. een upgrade codeunit
    codeunit 50000 "CFL Example Upgrade"
    {
        Access = Internal;
        Subtype = Upgrade;
    
        trigger OnUpgradeAppPerCompany()
        var
            CFLFeatureMgt: codeunit "CFL Feature Management";
            CFLExampleFeatureMgt: codeunit "CFL Example Feature Mgt";
            State: enum "CFL Obsolete State";
        begin
            CFLFeatureMgt.CFLObsoleteFeature(CFLExampleFeatureMgt.CFLGetFeatureID,State::Pending);
        end;
    }
    
NOTE

Zorg ervoor dat bij obsolete removed zetten van een functie, ook alle applicationarea's zijn aangepast een alle checks naar enabled zijn aangepast.

Functie verwijderen

Indien functies niet meer van toepassing zijn, niet meer worden gebruikt, kunnen deze verwijderd worden.
Na verwijdering is de functie niet meer zichtbaar in de lijst van features.

Functies kunnen enkel verwijderd worden via code. Om een functie te verwijderen, moeten volgende stappen worden doorlopen:

  1. Verwijder de feature toe adhv. een upgrade codeunit
    codeunit 50000 "CFL Example Upgrade"
    {
        Access = Internal;
        Subtype = Upgrade;
    
        trigger OnUpgradeAppPerCompany()
        var
            CFLFeatureMgt: codeunit "CFL Feature Management";
            CFLExampleFeatureMgt: codeunit "CFL Example Feature Mgt";
            State: enum "CFL Obsolete State";
        begin
            CFLFeatureMgt.CFLRemoveFeature(CFLExampleFeatureMgt.CFLGetFeatureID);
        end;
    }
    
NOTE

Zorg ervoor dat bij verwijderen van een functie, ook alle applicationarea's zijn aangepast een alle checks naar enabled zijn aangepast.