예제 #1
0
modulePD::modulePD(OpenMFGGUIClient *Pparent) :
 QObject(Pparent, "pdModule")
{
  parent = Pparent;

  toolBar = new QToolBar(tr("P/D Tools"));
  toolBar->setObjectName("P/D Tools");
  toolBar->setIconSize(QSize(32, 32));
  if (_preferences->boolean("ShowPDToolbar"))
    parent->addToolBar(toolBar);

//  I/M | Items
  itemsMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.enterNewItem", tr("Enter New Item..."),
                                      this, SLOT(sNewItem()),
                                      itemsMenu, _privleges->check("MaintainItemMasters") ) );
  //                                    QPixmap(":/images/newItem.xpm"), toolBar ) );

  parent->actions.append( new Action( parent, "pd.listItems", tr("List Items..."),
                                      this, SLOT(sItems()),
                                      itemsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")),
                                      QPixmap(":/images/items.png"), toolBar ) );

  parent->actions.append( new Action( parent, "pd.searchForItems", tr("Search for Items..."),
                                      this, SLOT(sSearchForItems()),
                                      itemsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  parent->actions.append( new Action( parent, "pd.copyItem", tr("Copy Item..."),
                                      this, SLOT(sCopyItem()),
                                      itemsMenu, _privleges->check("MaintainItemMasters") ) );

  itemsMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.itemAvailabilityWorkbench", tr("Item Availability Workbench..."),
                                      this, SLOT(sDspItemAvailabilityWorkbench()),
                                      itemsMenu, _privleges->check("ViewItemAvailabilityWorkbench") ) );

  itemsMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.itemGroups", tr("Item Groups..."),
                                      this, SLOT(sItemGroups()),
                                      itemsMenu, (_privleges->check("MaintainItemGroups") || _privleges->check("ViewItemGroups")) ) );

  parent->actions.append( new Action( parent, "pd.itemImages", tr("Item Images..."),
                                      this, SLOT(sItemImages()),
                                      itemsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );


//  P/D | Bills of Materials
  bomMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.enterNewBOM", tr("Enter New Bill of Materials..."),
                                      this, SLOT(sNewBOM()),
                                      bomMenu, _privleges->check("MaintainBOMs") ) );
//                                               QPixmap(":/images/newBOM.xpm"), toolBar ) );

  parent->actions.append( new Action( parent, "pd.listBOMs", tr("List Bills of Materials..."),
                                      this, SLOT(sBOMs()),
                                      bomMenu, (_privleges->check("MaintainBOMs") || _privleges->check("ViewBOMs")),
                                      QPixmap(":/images/boms.png"), toolBar ) );

  parent->actions.append( new Action( parent, "pd.copyBOM", tr("Copy Bill of Materials..."),
                                      this, SLOT(sCopyBOM()),
                                      bomMenu, _privleges->check("MaintainBOMs") ) );

  bomMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.massReplaceComponentItem", tr("Mass Replace Component Item..."),
                                      this, SLOT(sMassReplaceComponent()),
                                      bomMenu, _privleges->check("MaintainBOMs") ) );

  parent->actions.append( new Action( parent, "pd.massExpireComponentItem", tr("Mass Expire Component Item..."),
                                      this, SLOT(sMassExpireComponent()),
                                      bomMenu, _privleges->check("MaintainBOMs") ) );


//  P/D | Bills of Operations...

  booMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.enterNewBOO", tr("Enter New Bill of Operations..."),
                                      this, SLOT(sNewBOO()),
                                      booMenu, (_privleges->check("MaintainBOOs") && _metrics->boolean("Routings")) ) );

  parent->actions.append( new Action( parent, "pd.listBOOs", tr("List Bills of Operations..."),
                                      this, SLOT(sBOOs()),
                                      booMenu, ((_privleges->check("MaintainBOOs") || _privleges->check("ViewBOOs")) && _metrics->boolean("Routings")),
                                      QPixmap(":/images/boos.png"), toolBar ) );

  parent->actions.append( new Action( parent, "pd.copyBOO", tr("Copy Bill of Operations..."),
                                      this, SLOT(sCopyBOO()),
                                      booMenu, (_privleges->check("MaintainBOOs") && _metrics->boolean("Routings")) ) );


//  P/D | Breeder Bills of Materials

  breederBOMMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.enterNewBreederBOM", tr("Enter New Breeder Bill of Materials..."),
                                      this, SLOT(sNewBreederBOM()),
                                      breederBOMMenu, (_privleges->check("MaintainBBOMs") && _metrics->boolean("BBOM")) ) );

  parent->actions.append( new Action( parent, "pd.listBreederBOMs", tr("List Breeder Bills of Materials..."),
                                      this, SLOT(sBreederBOMs()),
                                      breederBOMMenu, ((_privleges->check("MaintainBBOMs") || _privleges->check("ViewBBOMs")) && _metrics->boolean("BBOM")) ) );

//  P/D | Costing
  costingDisplaysMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.dspCostedSingleLevelBOM", tr("Costed Single Level BOM..."),
                                      this, SLOT(sDspCostedSingleLevelBOM()),
                                      costingDisplaysMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.dspCostedIndentedBOM", tr("Costed Indented BOM..."),
                                      this, SLOT(sDspCostedIndentedBOM()),
                                      costingDisplaysMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.dspCostedSummarizedBOM", tr("Costed Summarized BOM..."),
                                      this, SLOT(sDspCostedSummarizedBOM()),
                                      costingDisplaysMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.dspItemCostsByClassCode", tr("Item Costs by Class Code..."),
                                      this, SLOT(sDspItemCostsByClassCode()),
                                      costingDisplaysMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.dspItemCostsSummary", tr("Item Costs Summary..."),
                                      this, SLOT(sDspItemCostSummary()),
                                      costingDisplaysMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.dspItemCostsHistory", tr("Item Costs History..."),
                                      this, SLOT(sDspItemCostHistory()),
                                      costingDisplaysMenu, _privleges->check("ViewCosts") ) );

  costingReportsMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.rptCostedSingleLevelBOM", tr("Costed Single Level BOM..."),
                                      this, SLOT(sRptCostedSingleLevelBOM()),
                                      costingReportsMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.rptCostedIndentedBOM", tr("Costed Indented BOM..."),
                                      this, SLOT(sRptCostedIndentedBOM()),
                                      costingReportsMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.rptCostedSummarizedBOM", tr("Costed Summarized BOM..."),
                                      this, SLOT(sRptCostedSummarizedBOM()),
                                      costingReportsMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.rptItemCostsByClassCode", tr("Item Costs by Class Code..."),
                                      this, SLOT(sRptItemCostsByClassCode()),
                                      costingReportsMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.rptItemCostsSummary", tr("Item Costs Summary..."),
                                      this, SLOT(sRptItemCostSummary()),
                                      costingReportsMenu, _privleges->check("ViewCosts") ) );

  parent->actions.append( new Action( parent, "pd.rptItemCostsHistory", tr("Item Costs History..."),
                                      this, SLOT(sRptItemCostHistory()),
                                      costingReportsMenu, _privleges->check("ViewCosts") ) );

  costingMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.maintainItemCosts", tr("Maintain Item Costs..."),
                                      this, SLOT(sMaintainItemCosts()),
                                      costingMenu, _privleges->check("ViewCosts") ) );

  costingMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.updateActualCostsByItem", tr("Update Actual Costs by Item..."),
                                      this, SLOT(sUpdateActualCostsByItem()),
                                      costingMenu, _privleges->check("UpdateActualCosts") ) );

  parent->actions.append( new Action( parent, "pd.updateActualCostsByClassCode", tr("Update Actual Costs by Class Code..."),
                                      this, SLOT(sUpdateActualCostsByClassCode()),
                                      costingMenu, _privleges->check("UpdateActualCosts") ) );

  costingMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.postActualCostsByItem", tr("Post Actual Costs by Item..."),
                                      this, SLOT(sPostActualCostsByItem()),
                                      costingMenu, _privleges->check("PostActualCosts") ) );

  parent->actions.append( new Action( parent, "pd.postActualCostsByClassCode", tr("Post Actual Costs by Class Code..."),
                                      this, SLOT(sPostActualCostsByClassCode()),
                                      costingMenu, _privleges->check("PostActualCosts") ) );

  costingMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.updateStandardCostsByItem", tr("Post Standard Costs by Item..."),
                                      this, SLOT(sUpdateStandardCostsByItem()),
                                      costingMenu, _privleges->check("PostStandardCosts") ) );

  parent->actions.append( new Action( parent, "pd.updateStandardCostsByClassCode", tr("Post Standard Costs by Class Code..."),
                                      this, SLOT(sUpdateStandardCostsByClassCode()),
                                      costingMenu, _privleges->check("PostStandardCosts") ) );


  costingMenu->insertSeparator();

  costingMenu->insertItem(tr("&Displays"), costingDisplaysMenu );
  costingMenu->insertItem(tr("&Reports"),  costingReportsMenu  );

  costingMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.userDefinedCostingElements", tr("User-Defined Costing Elements..."),
                                      this, SLOT(sUserCostingElements()),
                                      costingMenu, _privleges->check("MaintainUserCostingElements") ) );


//  P/D | Displays
  displaysMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.dspItemsByClassCode", tr("Items by Class Code..."),
                                      this, SLOT(sDspItemsByClassCode()),
                                      displaysMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  parent->actions.append( new Action( parent, "pd.dspItemsByProductCategory", tr("Items by Product Category..."),
                                      this, SLOT(sDspItemsByProductCategory()),
                                      displaysMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  parent->actions.append( new Action( parent, "pd.dspItemsByCharacteristic", tr("Items by Characteristic..."),
                                      this, SLOT(sDspItemsByCharacteristic()),
                                      displaysMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  displaysMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.dspSingleLevelBOM", tr("Single Level Bill of Materials..."),
                                      this, SLOT(sDspSingleLevelBOM()),
                                      displaysMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.dspIndentedBOM", tr("Indented Bill of Materials..."),
                                      this, SLOT(sDspIndentedBOM()),
                                      displaysMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.dspSummarizedBOM", tr("Summarized Bill of Materials..."),
                                      this, SLOT(sDspSummarizedBOM()),
                                      displaysMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.dspSequencedBOM", tr("Sequenced Bill of Materials..."),
                                      this, SLOT(sDspSequencedBOM()),
                                      displaysMenu, _privleges->check("ViewBOMs") ) );

  displaysMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.dspSingleLevelWhereUsed", tr("Single Level Where Used..."),
                                      this, SLOT(sDspSingleLevelWhereUsed()),
                                      displaysMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.dspIndentedWhereUsed", tr("Indented Where Used..."),
                                      this, SLOT(sDspIndentedWhereUsed()),
                                      displaysMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.dspPendingBOMChanges", tr("Pending BOM Changes..."),
                                      this, SLOT(sDspPendingBOMChanges()),
                                      displaysMenu, _privleges->check("ViewBOMs") ) );

 if (_metrics->boolean("Routings") )
 {
      displaysMenu->insertSeparator();

      parent->actions.append( new Action( parent, "pd.dspOperationsByWorkCenter", tr("Operations by Work Center..."),
                                          this, SLOT(sDspOperationsByWorkCenter()),
                                          displaysMenu,((_privleges->check("ViewBOOs")) && (_metrics->boolean("Routings"))) ) );

      parent->actions.append( new Action( parent, "pd.dspStandardOperationsByWorkCenter", tr("Standard Operations by Work Center..."),
                                          this, SLOT(sDspStandardOperByWorkCenter()),
                                          displaysMenu, ((_privleges->check("ViewStandardOperations")) && (_metrics->boolean("Routings"))) ) );

      displaysMenu->insertSeparator();

      parent->actions.append( new Action( parent, "pd.dspCapacityUOMsByClassCode", tr("Capacity UOMs by Class Code..."),
                                          this, SLOT(sDspCapacityUOMsByClassCode()),
                                          displaysMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

      parent->actions.append( new Action( parent, "pd.dspCapacityUOMsByProductCategory", tr("Capacity UOMs by Product Category..."),
                                          this, SLOT(sDspCapacityUOMsByProductCategory()),
                                          displaysMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );
  }

//  P/D | Reports
  reportsMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.rptItemsByClassCode", tr("Items by Class Code..."),
                                      this, SLOT(sRptItemsByClassCode()),
                                      reportsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  parent->actions.append( new Action( parent, "pd.rptItemsByProductCategory", tr("Items by Product Category..."),
                                      this, SLOT(sRptItemsByProductCategory()),
                                      reportsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  parent->actions.append( new Action( parent, "pd.rptItemsByCharacteristic", tr("Items by Characteristic..."),
                                      this, SLOT(sRptItemsByCharacteristic()),
                                      reportsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  reportsMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.rptSingleLevelBOM", tr("Single Level Bill of Materials..."),
                                      this, SLOT(sRptSingleLevelBOM()),
                                      reportsMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.rptIndentedBOM", tr("Indented Bill of Materials..."),
                                      this, SLOT(sRptIndentedBOM()),
                                      reportsMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.rptSummarizedBOM", tr("Summarized Bill of Materials..."),
                                      this, SLOT(sRptSummarizedBOM()),
                                      reportsMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.rptSequencedBOM", tr("Sequenced Bill of Materials..."),
                                      this, SLOT(sRptSequencedBOM()),
                                      reportsMenu, _privleges->check("ViewBOMs") ) );

  reportsMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.rptSingleLevelWhereUsed", tr("Single Level Where Used..."),
                                      this, SLOT(sRptSingleLevelWhereUsed()),
                                      reportsMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.rptIndentedWhereUsed", tr("Indented Where Used..."),
                                      this, SLOT(sRptIndentedWhereUsed()),
                                      reportsMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.rptPendingBOMChanges", tr("Pending BOM Changes..."),
                                      this, SLOT(sRptPendingBOMChanges()),
                                      reportsMenu, _privleges->check("ViewBOMs") ) );

 if (_metrics->boolean("Routings") )
 {
      reportsMenu->insertSeparator();

      parent->actions.append( new Action( parent, "pd.rptOperationsByWorkCenter", tr("Operations by Work Center..."),
                                          this, SLOT(sRptOperationsByWorkCenter()),
                                          reportsMenu, ((_privleges->check("ViewBOOs")) && (_metrics->boolean("Routings"))) ) );

      parent->actions.append( new Action( parent, "pd.rptStandardOperationsByWorkCenter", tr("Standard Operations by Work Center..."),
                                          this, SLOT(sRptStandardOperByWorkCenter()),
                                          reportsMenu, ((_privleges->check("ViewStandardOperations")) && (_metrics->boolean("Routings"))) ) );
  }
  
      reportsMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.rptCapacityUOMsByClassCode", tr("Capacity UOMs by Class Code..."),
                                      this, SLOT(sRptCapacityUOMsByClassCode()),
                                      reportsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

  parent->actions.append( new Action( parent, "pd.rptCapacityUOMsByProductCategory", tr("Capacity UOMs by Product Category..."),
                                      this, SLOT(sRptCapacityUOMsByProductCategory()),
                                      reportsMenu, (_privleges->check("MaintainItemMasters") || _privleges->check("ViewItemMasters")) ) );

//  P/D | Master Information
  masterInfoMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.unitsOfMeasure", tr("Units of Measure..."),
                                      this, SLOT(sUnitsOfMeasure()),
                                      masterInfoMenu, (_privleges->check("MaintainUOMs") || _privleges->check("ViewUOMs")) ) );

  parent->actions.append( new Action( parent, "pd.classCodes", tr("Class Codes..."),
                                      this, SLOT(sClassCodes()),
                                      masterInfoMenu, (_privleges->check("MaintainClassCodes") || _privleges->check("ViewClassCodes")) ) );

  parent->actions.append( new Action( parent, "pd.productCategories", tr("Product Categories..."),
                                      this, SLOT(sProductCategories()),
                                      masterInfoMenu, (_privleges->check("MaintainProductCategories") || _privleges->check("ViewProductCategories")) ) );

  parent->actions.append( new Action( parent, "pd.characteristics", tr("Characteristics..."),
                                      this, SLOT(sCharacteristics()),
                                      masterInfoMenu, (_privleges->check("MaintainCharacteristics") || _privleges->check("ViewCharacteristics")) ) );

 if (_metrics->boolean("Routings") )
 {
      masterInfoMenu->insertSeparator();

      parent->actions.append( new Action( parent, "pd.standardLaborRates", tr("Standard Labor Rates..."),
                                          this, SLOT(sStandardLaborRates()),
                                          masterInfoMenu, ((_privleges->check("MaintainLaborRates") || _privleges->check("ViewLaborRates")) && _metrics->boolean("Routings")) ) );

      parent->actions.append( new Action( parent, "pd.workCenters", tr("Work Centers..."),
                                          this, SLOT(sWorkCenters()),
                                          masterInfoMenu, ((_privleges->check("MaintainWorkCenters") || _privleges->check("ViewWorkCenters")) && _metrics->boolean("Routings")) ) );

      parent->actions.append( new Action( parent, "pd.standardOperations", tr("Standard Operations..."),
                                          this, SLOT(sStandardOperations()),
                                          masterInfoMenu, ((_privleges->check("MaintainStandardOperations") || _privleges->check("ViewStandardOperations")) && _metrics->boolean("Routings")) ) );
  }


//  P/D | Utilies
  utilitiesMenu = new QMenu();

  parent->actions.append( new Action( parent, "pd.dspUnusedPurchasedItems", tr("Unused Purchased Items..."),
                                      this, SLOT(sDspUnusedPurchasedItems()),
                                      utilitiesMenu, _privleges->check("ViewBOMs") ) );

  parent->actions.append( new Action( parent, "pd.dspUndefinedManufacturedItems", tr("Undefined Manufactured Items..."),
                                      this, SLOT(sDspUndefinedManufacturedItems()),
                                      utilitiesMenu, (_privleges->check("ViewBOMs") || _privleges->check("ViewBOOs")) ) );

  parent->actions.append( new Action( parent, "pd.dspBillsOfMaterialsWithoutComponentItemSites", tr("Bills of Materials without Component Item Sites..."),
                                      this, SLOT(sDspInvalidBillsOfMaterials()),
                                      utilitiesMenu, _privleges->check("ViewBOMs") ) );

  utilitiesMenu->insertSeparator();

  parent->actions.append( new Action( parent, "pd.reassignClassCodeByClassCode", tr("Reassign Class Code by Class Code..."),
                                      this, SLOT(sReassignClassCodeByClassCode()),
                                      utilitiesMenu, _privleges->check("MaintainItemMasters") ) );

  parent->actions.append( new Action( parent, "pd.reassignProductCategoryByProductCategory", tr("Reassign Product Category by Product Category..."),
                                      this, SLOT(sReassignProductCategoryByProductCategory()),
                                      utilitiesMenu, _privleges->check("MaintainItemMasters") ) );

  mainMenu = new QMenu();
  mainMenu->insertItem(tr("&Items"),                      itemsMenu      );
  mainMenu->insertItem(tr("&Bills of Materials"),         bomMenu        );
  if (_metrics->boolean("Routings"))
    mainMenu->insertItem(tr("Bills of &Operations"),        booMenu        );
  if (_metrics->boolean("BBOM"))
    mainMenu->insertItem(tr("Br&eeder Bills of Materials"), breederBOMMenu );
  mainMenu->insertItem(tr("&Costing"),                    costingMenu    );
  mainMenu->insertItem(tr("&Displays"),                   displaysMenu   );
  mainMenu->insertItem(tr("&Reports"),                    reportsMenu    );
  mainMenu->insertItem(tr("&Master Information"),         masterInfoMenu );
  mainMenu->insertItem(tr("&Utilities"),                  utilitiesMenu  );
  parent->populateCustomMenu(mainMenu, "P/D");	
  parent->menuBar()->insertItem(tr("P/&D"), mainMenu);
}
예제 #2
0
menuProducts::menuProducts(GUIClient *Pparent) :
 QObject(Pparent)
{
  setObjectName("productMenu");

  parent = Pparent;

  toolBar = new QToolBar(tr("Products Tools"));
  toolBar->setObjectName("Products Tools");
  toolBar->setIconSize(QSize(32, 32));
  if (_preferences->boolean("ShowPDToolbar"))
    parent->addToolBar(toolBar);
    
  mainMenu	= new QMenu(parent);
  itemsMenu	= new QMenu(parent);
  bomMenu	= new QMenu(parent);
  booMenu = new QMenu(parent);
  breederBOMMenu = new QMenu(parent);
  costingMenu = new QMenu(parent);
  costingUpdActMenu = new QMenu(parent);
  costingPostActMenu = new QMenu(parent);
  costingUpdStdMenu = new QMenu(parent);
  costingReportsMenu = new QMenu(parent);
  costingReportsCostedMenu = new QMenu(parent);
  costingReportsItemCostsMenu = new QMenu(parent);
  reportsMenu = new QMenu(parent);
  reportsItemsMenu = new QMenu(parent);
  reportsBomsMenu = new QMenu(parent);
  reportsWhereUsdMenu = new QMenu(parent);
  reportsCapUomMenu = new QMenu(parent);
  masterInfoMenu = new QMenu(parent);
  utilitiesMenu = new QMenu(parent);

  mainMenu->setObjectName("menu.prod");
  itemsMenu->setObjectName("menu.prod.items");
  bomMenu->setObjectName("menu.prod.bom");
  booMenu->setObjectName("menu.prod.boo");
  breederBOMMenu->setObjectName("menu.prod.breeder");
  costingMenu->setObjectName("menu.prod.costing");
  costingUpdActMenu->setObjectName("menu.prod.costingupdact");
  costingPostActMenu->setObjectName("menu.prod.costingpostact");
  costingUpdStdMenu->setObjectName("menu.prod.costingupdstd");
  costingReportsMenu->setObjectName("menu.prod.costingreports");
  costingReportsCostedMenu->setObjectName("menu.prod.costingreportscosted");
  costingReportsItemCostsMenu->setObjectName("menu.prod.costingreportsitemcosts");
  reportsMenu->setObjectName("menu.prod.reports");
  reportsItemsMenu->setObjectName("menu.prod.reportsitems");
  reportsBomsMenu->setObjectName("menu.prod.reportsboms");
  reportsWhereUsdMenu->setObjectName("menu.prod.reportswhereusd");
  reportsCapUomMenu->setObjectName("menu.prod.reportscapuom");
  masterInfoMenu->setObjectName("menu.prod.masterinfo");
  utilitiesMenu->setObjectName("menu.prod.utilities");

  actionProperties acts[] = {
  
  // Product | Reports
  { "menu",	tr("&Reports"), (char*)reportsMenu,	mainMenu, "true", NULL, NULL, true , NULL },
  
  // Product | Reports | Items
  { "menu",	tr("&Items"), (char*)reportsItemsMenu,	reportsMenu, "true", NULL, NULL, true , NULL },
  { "pd.dspItemsByProductCategory", tr("by &Product Category..."), SLOT(sDspItemsByProductCategory()), reportsItemsMenu, "MaintainItemMasters ViewItemMasters", NULL, NULL, true , NULL },
  { "pd.dspItemsByClassCode", tr("by &Class Code..."), SLOT(sDspItemsByClassCode()), reportsItemsMenu, "MaintainItemMasters ViewItemMasters", NULL, NULL, true , NULL },
  { "pd.dspItemsByCharacteristic", tr("by C&haracteristic..."), SLOT(sDspItemsByCharacteristic()),  reportsItemsMenu, "MaintainItemMasters ViewItemMasters", NULL, NULL, true , NULL },
  { "separator", NULL, NULL, reportsMenu,	"true", NULL, NULL, true , NULL },
  
  // Product | Reports | BOMs
  { "menu",	tr("&Bills of Materials"), (char*)reportsBomsMenu,	reportsMenu, "true", NULL, NULL, true , NULL },
  { "pd.dspSingleLevelBOM", tr("&Single Level..."), SLOT(sDspSingleLevelBOM()), reportsBomsMenu, "ViewBOMs", NULL, NULL, true , NULL },
  { "pd.dspIndentedBOM", tr("&Indented..."), SLOT(sDspIndentedBOM()), reportsBomsMenu, "ViewBOMs", NULL, NULL, true , NULL },
  { "pd.dspSummarizedBOM", tr("Summari&zed..."), SLOT(sDspSummarizedBOM()), reportsBomsMenu, "ViewBOMs", NULL, NULL, true , NULL },
  { "pd.dspSequencedBOM", tr("Se&quenced..."), SLOT(sDspSequencedBOM()), reportsBomsMenu, "ViewBOMs", NULL, NULL,  _metrics->boolean("Routings") , NULL },
  
  // Product | Reports | Where Used
  { "menu",	tr("&Where Used"), (char*)reportsWhereUsdMenu,	reportsMenu, "true", NULL, NULL, true , NULL },
  { "pd.dspSingleLevelWhereUsed", tr("&Single Level..."), SLOT(sDspSingleLevelWhereUsed()), reportsWhereUsdMenu, "ViewBOMs", NULL, NULL, true , NULL },
  { "pd.dspIndentedWhereUsed", tr("&Indented..."), SLOT(sDspIndentedWhereUsed()), reportsWhereUsdMenu, "ViewBOMs", NULL, NULL, true , NULL },

  { "pd.dspPendingBOMChanges", tr("&Pending BOM Changes..."), SLOT(sDspPendingBOMChanges()), reportsMenu, "ViewBOMs", NULL, NULL, true , NULL },
  { "separator", NULL, NULL, reportsMenu,	"true", NULL, NULL, true , NULL },
  { "pd.dspOperationsByWorkCenter", tr("&Operations..."), SLOT(sDspOperationsByWorkCenter()), reportsMenu, "ViewBOOs", NULL, NULL, _metrics->boolean("Routings") , NULL },
  { "pd.dspStandardOperationsByWorkCenter", tr("&Standard Operations..."), SLOT(sDspStandardOperByWorkCenter()), reportsMenu, "ViewStandardOperations", NULL, NULL, _metrics->boolean("Routings") , NULL },
  { "separator", NULL, NULL, reportsMenu,	"true", NULL, NULL,  _metrics->boolean("Routings") , NULL },

  // Product | Reports | Capacity UOMs
  { "menu",	tr("Capacity &UOMs"), (char*)reportsCapUomMenu,	reportsMenu, "true", NULL, NULL, true , NULL },
  { "pd.dspCapacityUOMsByProductCategory", tr("by &Product Category..."), SLOT(sDspCapacityUOMsByProductCategory()), reportsCapUomMenu, "MaintainItemMasters ViewItemMasters", NULL, NULL, true , NULL },
  { "pd.dspCapacityUOMsByClassCode", tr("by &Class Code..."), SLOT(sDspCapacityUOMsByClassCode()), reportsCapUomMenu, "MaintainItemMasters ViewItemMasters", NULL, NULL, true , NULL },
  
  {  "separator", NULL, NULL, mainMenu,	"true", NULL, NULL, true , NULL },

  // Product | Items
  { "menu",	tr("&Item"), (char*)itemsMenu,	mainMenu, "true", NULL, NULL, true , NULL },
  { "pd.enterNewItem", tr("&New..."), SLOT(sNewItem()), itemsMenu, "MaintainItemMasters", NULL, NULL, true , NULL },
  { "pd.listItems", tr("&List..."), SLOT(sItems()), itemsMenu, "MaintainItemMasters ViewItemMasters", QPixmap(":/images/items.png"), toolBar, true , tr("List Items") },
  { "pd.searchForItems", tr("&Search..."),SLOT(sSearchForItems()), itemsMenu, "MaintainItemMasters ViewItemMasters", NULL, NULL, true , NULL },
  { "pd.copyItem", tr("&Copy..."), SLOT(sCopyItem()), itemsMenu, "MaintainItemMasters" , NULL, NULL, true, NULL },
  { "separator", NULL, NULL, itemsMenu,	"true", NULL, NULL, true , NULL },
  { "pd.itemAvailabilityWorkbench", tr("&Workbench..."), SLOT(sDspItemAvailabilityWorkbench()), itemsMenu, "ViewItemAvailabilityWorkbench", NULL, NULL, true , NULL },
  { "separator", NULL, NULL, itemsMenu,	"true", NULL, NULL, true , NULL },
  { "pd.itemGroups", tr("&Groups..."), SLOT(sItemGroups()), itemsMenu, "MaintainItemGroups ViewItemGroups", NULL, NULL, true , NULL },
  { "pd.itemImages", tr("&Images..."), SLOT(sItemImages()), itemsMenu, "MaintainItemMasters ViewItemMasters", NULL, NULL, true , NULL },

  // Product | Bill of Materials
  { "menu",	tr("Bill Of Ma&terials"), (char*)bomMenu,	mainMenu, "true", NULL, NULL, true , NULL },
  { "pd.enterNewBOM", tr("&New..."), SLOT(sNewBOM()), bomMenu, "MaintainBOMs", NULL, NULL, true , NULL },
  { "pd.listBOMs", tr("&List..."), SLOT(sBOMs()), bomMenu, "MaintainBOMs ViewBOMs", QPixmap(":/images/boms.png"), toolBar, true , tr("List Bill of Materials") },
  { "pd.copyBOM", tr("&Copy..."), SLOT(sCopyBOM()), bomMenu, "MaintainBOMs", NULL, NULL, true , NULL },
  { "separator", NULL, NULL, bomMenu,	"true", NULL, NULL, true , NULL },
  { "pd.massReplaceComponentItem", tr("Mass &Replace..."), SLOT(sMassReplaceComponent()), bomMenu, "MaintainBOMs", NULL, NULL, true , NULL },
  { "pd.massExpireComponentItem", tr("Mass E&xpire..."), SLOT(sMassExpireComponent()),  bomMenu, "MaintainBOMs", NULL, NULL, true , NULL },

  // Product | Bill of Operations...
  { "menu",	tr("Bill Of &Operations"), (char*)booMenu,	mainMenu, "true", NULL, NULL,  _metrics->boolean("Routings") , NULL },
  { "pd.enterNewBOO", tr("&New..."), SLOT(sNewBOO()), booMenu, "MaintainBOOs", NULL, NULL,  _metrics->boolean("Routings") , NULL },
  { "pd.listBOOs", tr("&List..."), SLOT(sBOOs()), booMenu, "MaintainBOOs ViewBOOs", QPixmap(":/images/boos.png"), toolBar, _metrics->boolean("Routings") , tr("List Bill of Operations") },
  { "pd.copyBOO", tr("&Copy..."), SLOT(sCopyBOO()), booMenu, "MaintainBOOs", NULL, NULL, _metrics->boolean("Routings") , NULL },

  // Product | Breeder Bill of Materials
  { "menu",	tr("&Breeder Bill Of Materials"), (char*)breederBOMMenu,	mainMenu, "true", NULL, NULL,  _metrics->boolean("BBOM") , NULL },
  { "pd.enterNewBreederBOM", tr("&New..."), SLOT(sNewBreederBOM()), breederBOMMenu, "MaintainBBOMs", NULL, NULL, _metrics->boolean("BBOM") , NULL },
  { "pd.listBreederBOMs", tr("&List..."), SLOT(sBreederBOMs()), breederBOMMenu, "MaintainBBOMs ViewBBOMs", NULL, NULL, _metrics->boolean("BBOM") , NULL },
  
  // Product | Costing
  { "menu",	tr("&Costing"), (char*)costingMenu,	mainMenu, "true", NULL, NULL, true , NULL },
  { "pd.maintainItemCosts", tr("&Maintain Item Costs..."), SLOT(sMaintainItemCosts()), costingMenu, "ViewCosts", NULL, NULL, true , NULL },
  
  // Product | Lot Serial
  { "pd.lotSerial", tr("&Lot/Serial..."), SLOT(sLotSerial()), mainMenu, "true", NULL, NULL, _metrics->boolean("LotSerialControl"), NULL }, 

  { "separator", NULL, NULL, costingMenu,	"true", NULL, NULL, true , NULL },
  
  // Product | Costing | Update Actual Costs
  { "menu",	tr("Update &Actual Costs"), (char*)costingUpdActMenu,	costingMenu, "true", NULL, NULL, true , NULL },
  { "pd.updateActualCostsByItem", tr("by &Item..."), SLOT(sUpdateActualCostsByItem()), costingUpdActMenu, "UpdateActualCosts", NULL, NULL, true , NULL },
  { "pd.updateActualCostsByClassCode", tr("by &Class Code..."), SLOT(sUpdateActualCostsByClassCode()), costingUpdActMenu, "UpdateActualCosts", NULL, NULL, true , NULL },

  // Product | Costing | Post Actual Costs
  { "menu",	tr("&Post Actual Costs"), (char*)costingPostActMenu,	costingMenu, "true", NULL, NULL, true , NULL },
  { "pd.postActualCostsByItem", tr("by &Item..."), SLOT(sPostActualCostsByItem()), costingPostActMenu, "PostActualCosts", NULL, NULL, true , NULL },
  { "pd.postActualCostsByClassCode", tr("by &Class Code..."), SLOT(sPostActualCostsByClassCode()), costingPostActMenu, "PostActualCosts", NULL, NULL, true , NULL },

  // Product | Costing | Post Standard Costs
  { "menu",	tr("Post &Standard Costs"), (char*)costingUpdStdMenu,	costingMenu, "true", NULL, NULL, true , NULL },
  { "pd.postStandardCostsByItem", tr("by &Item..."), SLOT(sUpdateStandardCostsByItem()), costingUpdStdMenu, "PostStandardCosts", NULL, NULL, true , NULL },
  { "pd.postStandardCostsByClassCode", tr("by &Class Code..."), SLOT(sUpdateStandardCostsByClassCode()), costingUpdStdMenu, "PostStandardCosts", NULL, NULL, true , NULL },

  { "separator", NULL, NULL, costingMenu,	"true", NULL, NULL, true , NULL },

  //  Product | Costing | Reports
  { "menu",	tr("&Reports"), (char*)costingReportsMenu,	costingMenu, "true", NULL, NULL, true , NULL },
  
  //  Product | Costing | Reports | Costed BOM
  { "menu",	tr("&Costed BOM"), (char*)costingReportsCostedMenu,	costingReportsMenu, "true", NULL, NULL, true , NULL },
  { "pd.dspCostedSingleLevelBOM", tr("&Single Level..."), SLOT(sDspCostedSingleLevelBOM()),costingReportsCostedMenu, "ViewCosts", NULL, NULL, true , NULL },
  { "pd.dspCostedIndentedBOM", tr("&Indented..."), SLOT(sDspCostedIndentedBOM()), costingReportsCostedMenu, "ViewCosts", NULL, NULL, true , NULL },
  { "pd.dspCostedSummarizedBOM", tr("Summari&zed..."), SLOT(sDspCostedSummarizedBOM()), costingReportsCostedMenu, "ViewCosts", NULL, NULL, true , NULL },
  
  //  Product | Costing | Reports | Item Costs
  { "menu",	tr("&Item Costs"), (char*)costingReportsItemCostsMenu,	costingReportsMenu, "true", NULL, NULL, true , NULL },
  { "pd.dspItemCostsByClassCode", tr("by &Class Code..."), SLOT(sDspItemCostsByClassCode()), costingReportsItemCostsMenu, "ViewCosts", NULL, NULL, true , NULL },
  { "pd.dspItemCostsSummary", tr("&Summary..."), SLOT(sDspItemCostSummary()), costingReportsItemCostsMenu, "ViewCosts", NULL, NULL, true , NULL },
  { "pd.dspItemCostsHistory", tr("&History..."), SLOT(sDspItemCostHistory()), costingReportsItemCostsMenu, "ViewCosts", NULL, NULL, true , NULL },

  { "separator", NULL, NULL, costingMenu,	"true", NULL, NULL, true , NULL },
  { "pd.userDefinedCostingElements", tr("&User-Defined Costing Elements..."), SLOT(sUserCostingElements()), costingMenu, "MaintainUserCostingElements", NULL, NULL, true , NULL },

  { "separator", NULL, NULL, mainMenu,	"true", NULL, NULL, true , NULL },

  //  Produt | Master Information
  { "menu",	tr("&Master Information"), (char*)masterInfoMenu, mainMenu, "true", NULL, NULL, true , NULL },
  { "pd.unitsOfMeasure", tr("&Units of Measure..."), SLOT(sUnitsOfMeasure()), masterInfoMenu, "MaintainUOMs ViewUOMs", NULL, NULL, true , NULL },
  { "pd.classCodes", tr("&Class Codes..."), SLOT(sClassCodes()), masterInfoMenu, "MaintainClassCodes ViewClassCodes", NULL, NULL, true , NULL },
  { "pd.productCategories", tr("&Product Categories..."), SLOT(sProductCategories()), masterInfoMenu, "MaintainProductCategories ViewProductCategories", NULL, NULL, true , NULL },
  { "pd.freightClasses", tr("&Freight Classes..."), SLOT(sFreightClasses()), masterInfoMenu, "MaintainFreightClasses ViewFreightClasses", NULL, NULL, true , NULL },
  { "pd.characteristics", tr("C&haracteristics..."), SLOT(sCharacteristics()), masterInfoMenu, "MaintainCharacteristics ViewCharacteristics", NULL, NULL, true , NULL },
  { "separator", NULL, NULL, masterInfoMenu,	"true", NULL, NULL, _metrics->boolean("Routings")  , NULL },
  { "pd.standardLaborRates", tr("Standard &Labor Rates..."), SLOT(sStandardLaborRates()), masterInfoMenu, "MaintainLaborRates ViewLaborRates", NULL, NULL, _metrics->boolean("Routings") , NULL },
  { "pd.workCenters", tr("&Work Centers..."), SLOT(sWorkCenters()), masterInfoMenu, "MaintainWorkCenters ViewWorkCenters", NULL, NULL,  _metrics->boolean("Routings") , NULL },
  { "pd.standardOperations", tr("Standard &Operations..."), SLOT(sStandardOperations()), masterInfoMenu, "MaintainStandardOperations ViewStandardOperations", NULL, NULL, _metrics->boolean("Routings") , NULL },

  //  Produt | Utilies
  { "menu",	tr("&Utilities"), (char*)utilitiesMenu, mainMenu, "true", NULL, NULL, true , NULL },
  { "pd.dspUnusedPurchasedItems", tr("Unused &Purchased Items..."), SLOT(sDspUnusedPurchasedItems()), utilitiesMenu, "ViewBOMs", NULL, NULL, true , NULL },
  { "pd.dspUndefinedManufacturedItems", tr("Undefined &Manufactured Items..."), SLOT(sDspUndefinedManufacturedItems()), utilitiesMenu, "ViewBOMs ViewBOOs", NULL, NULL, true , NULL },
  { "pd.dspBillsOfMaterialsWithoutComponentItemSites", tr("Bills of Ma&terials without Component Item Sites..."), SLOT(sDspInvalidBillsOfMaterials()), utilitiesMenu, "ViewBOMs", NULL, NULL, true , NULL },
  { "separator", NULL, NULL, utilitiesMenu,	"true", NULL, NULL, true , NULL },
  { "pd.reassignClassCodeByClassCode", tr("Reassign &Class Codes..."), SLOT(sReassignClassCodeByClassCode()), utilitiesMenu, "MaintainItemMasters", NULL, NULL, true , NULL },
  { "pd.reassignProductCategoryByProductCategory", tr("&Reassign Product Categories..."), SLOT(sReassignProductCategoryByProductCategory()), utilitiesMenu, "MaintainItemMasters", NULL, NULL, true , NULL },
  };

  addActionsToMenu(acts, sizeof(acts) / sizeof(acts[0]));

  parent->populateCustomMenu(mainMenu, "Products");
  QAction * m = parent->menuBar()->addMenu(mainMenu);
  if(m)
    m->setText(tr("&Products"));
}