I just copied the payroll module into my testing FrontAccounting site and it had problems with the SQL update.  Specifically, it had problems adding the payroll_tax_type table.  When I changed all the commented sections from "--" to "/* .... */" it went through fine.  Ironically, it did not have any problems with the payroll_tax_rate or the payroll_pay_type table which have similar comments?

My test site is on blue host and here are the mysql info:
Server: Localhost via UNIX socket
Server version: 5.1.66-community-log
Protocol version: 10

Let me know if you need any other info.

Also, I would like to help with this module.  I am a tax accountant in the US and I can code a bit.  I could start testing the tax  calculations on various US payroll taxes and various State payroll taxes if you think it is ready for that.

Would what was done Here:
     https://frontaccounting.com/punbb/viewtopic.php?id=1128

Get you where you want?

Otherwise, maybe you can see what was changed to help you implement what you want?

Cool, this is actually my first contribution to an open source project....feels good. Thanks for the taking the time to look at it.

I was able to hide menu items that were inaccessible by altering the renderer.php file in the theme folder(s).  These changes are intended to keep the HTML out of the page if the user does not have access, not just simply hide them from view.

Also, i added a theme_config.php file to the theme directory to keep the new config option out of the main config file.

I have briefly tested this on FrontAccounting 2.3.11 on a WAMP server.

I think it is valuable to be able to hide menu entries because there might be a user (e.g. employee self service for a HR/Payroll module) that you don't want to see the rest of the system.

I am still learning php, so I am open to suggestions on how to clean up what I have accomplished, etc.   Let me know what you think and if you encounter any errors! Thanks.

Also, it would be nice to be able to define certain security roles that hide inaccessible menus rather than having a simple on/off config option...have not even attempted to figure this out yet.

Here is my theme_config.php file:

<?php


/*  Should FA hide menu items (Applications, Modules, and Actions) from the user if they don't have access to them? 
    1 for no       0 for yes
*/

global $show_inaccessible_menu_items;

$show_inaccessible_menu_items = 0;

?>

Here is my modified renderer.php file...my changes are preceded by a //BP:

<?php
/**********************************************************************
    Copyright (C) FrontAccounting, LLC.
    Released under the terms of the GNU General Public License, GPL, 
    as published by the Free Software Foundation, either version 3 
    of the License, or (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
    See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************/
    
    //BP include
    include_once (dirname(__FILE__).'/theme_config.php');
    
    //BP add call
    add_access_extensions();  //had to add this...otherwise errors would go crazy with extension security additions when clicking on functions
    
    class renderer
    {
        
        
        function get_icon($category)
        {
            global  $path_to_root, $show_menu_category_icons;

            if ($show_menu_category_icons)
                $img = $category == '' ? 'right.gif' : $category.'.png';
            else    
                $img = 'right.gif';
            return "<img src='$path_to_root/themes/default/images/$img' style='vertical-align:middle;' border='0'>&nbsp;&nbsp;";
        }

        function wa_header()
        {
            page(_($help_context = "Main Menu"), false, true);
        }

        function wa_footer()
        {
            end_page(false, true);
        }

        function menu_header($title, $no_menu, $is_index)
        {
            global $path_to_root, $help_base_url, $db_connections;
            echo "<table class='callout_main' border='0' cellpadding='0' cellspacing='0'>\n";
            echo "<tr>\n";
            echo "<td colspan='2' rowspan='2'>\n";

            echo "<table class='main_page' border='0' cellpadding='0' cellspacing='0'>\n";
            echo "<tr>\n";
            echo "<td>\n";
            echo "<table width='100%' border='0' cellpadding='0' cellspacing='0'>\n";
            echo "<tr>\n";
            echo "<td class='quick_menu'>\n";
            if (!$no_menu)
            {
                $applications = $_SESSION['App']->applications;
                $local_path_to_root = $path_to_root;
                $img = "<img src='$local_path_to_root/themes/default/images/login.gif' width='14' height='14' border='0' alt='"._('Logout')."'>&nbsp;&nbsp;";
                $himg = "<img src='$local_path_to_root/themes/default/images/help.gif' width='14' height='14' border='0' alt='"._('Help')."'>&nbsp;&nbsp;";
                $sel_app = $_SESSION['sel_app'];
                echo "<table cellpadding=0 cellspacing=0 width='100%'><tr><td>";
                echo "<div class=tabs>";
                foreach($applications as $app)
                {
                    //BP if stmt
                    if ($this->check_application_access($app))
                    {
                        $acc = access_string($app->name);
                        echo "<a class='".($sel_app == $app->id ? 'selected' : 'menu_tab')
                            ."' href='$local_path_to_root/index.php?application=".$app->id
                            ."'$acc[1]>" .$acc[0] . "</a>";
                    }
                }
                echo "</div>";
                echo "</td></tr></table>";

                echo "<table class=logoutBar>";
                echo "<tr><td class=headingtext3>" . $db_connections[$_SESSION["wa_current_user"]->company]["name"] . " | " . $_SERVER['SERVER_NAME'] . " | " . $_SESSION["wa_current_user"]->name . "</td>";
                $indicator = "$path_to_root/themes/".user_theme(). "/images/ajax-loader.gif";
                echo "<td class='logoutBarRight'><img id='ajaxmark' src='$indicator' align='center' style='visibility:hidden;'></td>";
                echo "  <td class='logoutBarRight'><a class='shortcut' href='$path_to_root/admin/display_prefs.php?'>" . _("Preferences") . "</a>&nbsp;&nbsp;&nbsp;\n";
                echo "  <a class='shortcut' href='$path_to_root/admin/change_current_user_password.php?selected_id=" . $_SESSION["wa_current_user"]->username . "'>" . _("Change password") . "</a>&nbsp;&nbsp;&nbsp;\n";

                if ($help_base_url != null)
                {
                    echo "$himg<a target = '_blank' onclick=" .'"'."javascript:openWindow(this.href,this.target); return false;".'" '. "href='". help_url()."'>" . _("Help") . "</a>&nbsp;&nbsp;&nbsp;";
                }
                echo "$img<a class='shortcut' href='$local_path_to_root/access/logout.php?'>" . _("Logout") . "</a>&nbsp;&nbsp;&nbsp;";
                echo "</td></tr><tr><td colspan=3>";
                echo "</td></tr></table>";
            }
            echo "</td></tr></table>";

            if ($no_menu)
                echo "<br>";
            elseif ($title && !$is_index)
            {
                echo "<center><table id='title'><tr><td width='100%' class='titletext'>$title</td>"
                ."<td align=right>"
                .(user_hints() ? "<span id='hints'></span>" : '')
                ."</td>"
                ."</tr></table></center>";
            }
        }

        function menu_footer($no_menu, $is_index)
        {
            global $version, $allow_demo_mode, $app_title, $power_url, 
                $power_by, $path_to_root, $Pagehelp, $Ajax;
            include_once($path_to_root . "/includes/date_functions.inc");

            if ($no_menu == false)
            {
                if ($is_index)
                    echo "<table class=bottomBar>\n";
                else
                    echo "<table class=bottomBar2>\n";
                echo "<tr>";
                if (isset($_SESSION['wa_current_user'])) {
                    $phelp = implode('; ', $Pagehelp);
                    echo "<td class=bottomBarCell>" . Today() . " | " . Now() . "</td>\n";
                    $Ajax->addUpdate(true, 'hotkeyshelp', $phelp);
                    echo "<td id='hotkeyshelp'>".$phelp."</td>";
                }
                echo "</tr></table>\n";
            }
            echo "</td></tr></table></td>\n";
            echo "</table>\n";
            if ($no_menu == false)
            {
                echo "<table align='center' id='footer'>\n";
                echo "<tr>\n";
                echo "<td align='center' class='footer'><a target='_blank' href='$power_url' tabindex='-1'><font color='#ffffff'>$app_title $version - " . _("Theme:") . " " . user_theme() . " - ".show_users_online()."</font></a></td>\n";
                echo "</tr>\n";
                echo "<tr>\n";
                echo "<td align='center' class='footer'><a target='_blank' href='$power_url' tabindex='-1'><font color='#ffff00'>$power_by</font></a></td>\n";
                echo "</tr>\n";
                if ($allow_demo_mode==true)
                {
                    echo "<tr>\n";
                    //echo "<td><br><div align='center'><a href='https:/sourceforge.net'><img src='https:/sourceforge.net/sflogo.php?group_id=89967&amp;type=5' alt='SourceForge.net Logo' width='210' height='62' border='0' align='middle' /></a></div></td>\n";
                    echo "</tr>\n";
                }
                echo "</table><br><br>\n";
            }
        }

        function display_applications(&$waapp)
        {
            global $path_to_root;

            $selected_app = $waapp->get_selected_application();

            foreach ($selected_app->modules as $module)
            {
                //BP if stmt
                if ($this->check_module_access($module))
                {
                    // image
                    echo "<tr>";
                    // values
                    echo "<td valign='top' class='menu_group'>";
                    echo "<table border=0 width='100%'>";
                    echo "<tr><td class='menu_group'>";
                    echo $module->name;
                    echo "</td></tr><tr>";
                    echo "<td class='menu_group_items'>";

                    foreach ($module->lappfunctions as $appfunction)
                    {
                        $img = $this->get_icon($appfunction->category);
                        if ($appfunction->label == "")
                            echo "&nbsp;<br>";
                        elseif ($_SESSION["wa_current_user"]->can_access_page($appfunction->access)) 
                        {
                                echo $img.menu_link($appfunction->link, $appfunction->label)."<br>\n";
                        }
                        else 
                        {
                                if ($this->check_menu_items_config_option())
                                {
                                    echo $img.'<span class="inactive">'
                                        .access_string($appfunction->label, true)
                                        ."</span><br>\n";
                                }
                        
                        }
                    }
                    echo "</td>";
                    if (sizeof($module->rappfunctions) > 0)
                    {
                        echo "<td width='50%' class='menu_group_items'>";
                        foreach ($module->rappfunctions as $appfunction)
                        {
                            $img = $this->get_icon($appfunction->category);
                            if ($appfunction->label == "")
                                echo "&nbsp;<br>";
                            elseif ($_SESSION["wa_current_user"]->can_access_page($appfunction->access)) 
                            {
                                    echo $img.menu_link($appfunction->link, $appfunction->label)."<br>\n";
                            }
                            else 
                            {
                                if ($this->check_menu_items_config_option())
                                {
                                    echo $img.'<span class="inactive">'
                                        .access_string($appfunction->label, true)
                                        ."</span><br>\n";
                                }
                            
                            }
                        }
                        echo "</td>";
                    }

                    echo "</tr></table></td></tr>";
                }
            }

            echo "</table>";
        }
        
        //BP Function
        function check_application_access(&$waapp)
        {
            global $path_to_root;
            
            if ($this->check_menu_items_config_option())
            {
                return true;
            }
            
            foreach ($waapp->modules as $module)
            {
                if ($this->check_module_access($module))
                {
                    return true;
                }
            }
            
            return false;
                    
        }
        
        //BP Function
        function check_module_access(&$module)
        {
            
            if ($this->check_menu_items_config_option())
            {
                return true;
            }
            
            if (sizeof($module->lappfunctions) > 0)
            {
                foreach ($module->lappfunctions as $appfunction)
                {
                    if ($appfunction->label != "" && $_SESSION["wa_current_user"]->can_access_page($appfunction->access))
                    {
                        return true;
                    }
                }
            }
            
            if (sizeof($module->rappfunctions) > 0)
            {
                foreach ($module->rappfunctions as $appfunction)
                {
                    if ($appfunction->label != "" && $_SESSION["wa_current_user"]->can_access_page($appfunction->access))
                    {
                        return true;
                    }
                }
            }
            
            return false;
            
        }
        
        //BP function
        function check_menu_items_config_option()
        {
            global $show_inaccessible_menu_items;
            
            if (!isset($show_inaccessible_menu_items))
            {
                echo "<script>alert('not set')</script>";
            }
            
            if ($show_inaccessible_menu_items)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

?>