ilscipio/scipio-erp

View on GitHub
framework/common/webcommon/WEB-INF/actions/includes/scipio/DeriveComplexMenuItems.groovy

Summary

Maintainability
Test Coverage
/**
 * SCIPIO: Applies the active activeSubMenu/activeSubMenuItem menu item specified in context to a
 * complex menu identified by menuCfg.name/location (usually the MainSideBarMenu in standard
 * Scipio backend) to automatically derive other menu item selection information.
 * 
 * This uses the same menuCfg parameters as CommonScreens ComplexMenu widget, EXCEPT there is an extra
 * menuCfg.menuType currently supporting either values: "Menu" or "SideBar".
 * This selects the default values/config for all the other menuCfg parameters.
 * 
 * Currently determines (if not explicitly set):
 * * activeMainMenuItem - required for main non-complex menus (e.g. regular/legacy MainAppBar)
 * 
 * Outputs the following:
 * * context.activeMainMenuItem - only if not already set
 * * globalContext.activeMainMenuItem - TENTATIVELY (see WARN below), transferred from local context if needed
 * * context.activeMainMenuItem_auto
 * * globalContext.activeMainMenuItem_auto
 * 
 * 2016-11-11: Added for 1.14.3.
 */

import org.ofbiz.base.util.Debug;

final module = "DeriveComplexMenuItems.groovy";

// GET SCRIPT PARAMETERS
activeMainMenuItem = context.activeMainMenuItem; // may already be manually set
activeMainMenuItem_auto = null;

menuCfg = context.menuCfg ?: [:];

cplxLoc = menuCfg.location;
cplxName = menuCfg.name;

cplxSuffix = menuCfg.nameSuffix ?: "Menu";
cplxAddSuffix = menuCfg.addNameSuffix; if (cplxAddSuffix == null) { cplxAddSuffix = false; };
cplxStripSuffix = menuCfg.stripNameSuffix; if (cplxStripSuffix == null) { cplxStripSuffix = true; };

cplxLocal = menuCfg.local;
if (cplxLocal == null) {
    cplxLocal = true;
}
cplxGlobal = menuCfg.global;
if (cplxGlobal == null) {
    cplxGlobal = true;
}

// CLEAR SCRIPT PARAMETERS
context.remove("menuCfg");

def appendSuffix(name, suffix) {
    if (name && suffix) {
        if (!name.endsWith(suffix)) {
            name += suffix;
        }
    }
    return name;
}

def stripSuffix(name, suffix) {
    if (name && suffix) {
        if (name.endsWith(suffix)) {
            name = name.substring(0, name.length() - suffix.length());
        }
    }
    return name;
}

// NOTE: we run everything even if activeMainMenuItem is already set, so caller can still
// use activeMainMenuItem_auto for other purpose

// LOAD THE COMPLEX MENU
cplxMenuModel = null;
if (cplxLoc && cplxName) {
    cplxMenuModel = null;
    try {
        cplxMenuModel = org.ofbiz.widget.model.MenuFactory.getMenuFromLocation(
            cplxLoc, cplxName);
        if (cplxMenuModel == null) {
            throw new IllegalArgumentException("Could not find menu with name [" + cplxName
                + "] in location [" + cplxLoc + "]");
        }
    } catch (Exception e) {
        Debug.logError(e, "Error loading complex menu model", module);
    }
} else {
    if (!activeMainMenuItem) {
        Debug.logWarning("Could not find mainSideBarMenu.location/name context variables; " +
            "unable to auto-determine activeMainMenuItem", module);
    }
}

activeSubMenu = context.activeSubMenu;
activeSubMenuItem = context.activeSubMenuItem;
if (activeSubMenu && activeSubMenu.contains("#")) {
    parts = context.activeSubMenu.split("#", 2);
    if (parts.length >= 2) {
        activeSubMenuLoc = parts[0];
        activeSubMenuName = parts[1];
    } else {
        activeSubMenuName = parts[0];
    }
} else {
    activeSubMenuName = activeSubMenu;
}

// append menu name suffix if needed
if (cplxAddSuffix) {
    activeSubMenuName = appendSuffix(activeSubMenuName, cplxSuffix);
    // ignore cplxStripSuffix
} else {
    if (cplxStripSuffix) {
        activeSubMenuName = stripSuffix(activeSubMenuName, cplxSuffix);
    }
}

if (cplxMenuModel != null && ((activeSubMenuName) || (activeSubMenuItem))) { // NOTE: don't attempt if both fields null
    // Perform the main lookup. This is effectively a preview of the resolution that happens when 
    // menu is actually rendered. 
    // for this reason we pass logWarnings=false here because they will (almost surely) be printed in double
    // when the actual menu render happens. only need the one below.
    // NOTE: this lookup takes into account errors, such that our activeMainMenuItem will be based
    // on the _result_ of failed lookups. that is generally what is wanted although it won't make a difference
    // in properly written screens.
    menuAndItem = cplxMenuModel.getSelectedMenuAndItem(activeSubMenuItem, activeSubMenuName, false);
    if (menuAndItem.getMenuItem() != null) {
        topItem = menuAndItem.getMenuItem().getTopAncestorMenuItem();
        activeMainMenuItem_auto = topItem.getName();
    } else if (menuAndItem.getSubMenu() != null) {
        topItem = menuAndItem.getSubMenu().getTopAncestorMenuItem();
        activeMainMenuItem_auto = topItem.getName();
    } else {
        Debug.logWarning("Unable to determine activeMainMenuItem: could not find sufficient sub menu item [" + activeSubMenuName + "/" + activeSubMenuItem + 
            "] from activeSubMenu(Name)/activeSubMenuItem in menu [" + cplxMenuModel.getFullLocationAndName() 
            + "]", module);
    }
}

// STORE IN LOCAL CONTEXT
if (cplxLocal) {
    context.activeMainMenuItem_auto = activeMainMenuItem_auto;
    if (!activeMainMenuItem) { // store activeMainMenuItem only if not set
        if (Debug.verboseOn()) {
            Debug.logVerbose("Automatically determined activeMainMenuItem: " + activeMainMenuItem_auto, module);
        }
        context.activeMainMenuItem = activeMainMenuItem_auto;
    }
}

if (cplxGlobal) {
    // STORE IN GLOBAL CONTEXT (underneath / in addition to the local context)
    // NOTE/WARN: traditionally this caused context problems in stock ofbiz, but this may be the only way to handle the
    // case where a screen decides to include a main menu in its widgets outside the scope of the decorators
    // TODO?: investigate deeper, possible screen renderer patches involved if old issues surface
    if (context.globalContext != null) {
        if (!globalContext.activeMainMenuItem) {
            context.globalContext.activeMainMenuItem = context.activeMainMenuItem;
        }
        context.globalContext.activeMainMenuItem_auto = context.activeMainMenuItem_auto;
    }
}

//Debug.logInfo("activeMainMenuItem_auto: " + activeMainMenuItem_auto, module);