/**
   * Generate an Explosion for this BOM
   *
   * @param PP_Product_BOMLine_ID ID BOM Line
   */
  public void parentExplotion(int PP_Product_BOM_ID, BigDecimal qtyRequiered) throws Exception {
    ArrayList<Object> parameters = new ArrayList<Object>();
    parameters.add(PP_Product_BOM_ID);

    final StringBuilder whereClause =
        new StringBuilder(MPPProductBOMLine.COLUMNNAME_PP_Product_BOM_ID).append("=?");

    if (p_BackflushGroup != null) {
      whereClause
          .append(" AND ")
          .append(MPPProductBOMLine.COLUMNNAME_BackflushGroup)
          .append("LIKE ?");
      parameters.add(p_BackflushGroup);
    }

    List<MPPProductBOMLine> bomLines =
        new Query(getCtx(), MPPProductBOMLine.Table_Name, whereClause.toString(), get_TrxName())
            .setClient_ID()
            .setOnlyActiveRecords(true)
            .setParameters(parameters)
            .setOrderBy(MPPProductBOMLine.COLUMNNAME_Line)
            .list();

    for (MPPProductBOMLine line : bomLines) {
      if (line.isValidFromTo(p_DateTrx)) {
        SeqNo += 1;
        MProduct product = new MProduct(getCtx(), line.getM_Product_ID(), get_TrxName());
        X_T_BOMLine tboml = new X_T_BOMLine(ctx, 0, null);
        tboml.setAD_Org_ID(product.getAD_Org_ID());
        tboml.setPP_Product_BOM_ID(PP_Product_BOM_ID);
        tboml.setPP_Product_BOMLine_ID(line.get_ID());
        tboml.setM_Product_ID(line.getM_Product_ID());
        tboml.setLevelNo(LevelNo);
        tboml.setDateTrx(p_DateTrx);
        tboml.setLevels(levels.substring(0, LevelNo) + LevelNo);
        tboml.setSeqNo(SeqNo);
        tboml.setAD_PInstance_ID(AD_PInstance_ID);
        tboml.setSel_Product_ID(p_M_Product_ID);
        tboml.setQtyBOM(line.getQty(true));
        tboml.setQtyRequired(qtyRequiered.multiply(line.getQty(true)));
        tboml.setM_Warehouse_ID(p_M_Warehouse_ID);
        tboml.setImplosion(false);
        tboml.saveEx();
        component(line.getM_Product_ID(), tboml.getQtyBOM());
      }
    }
  }
  /** Action: Fill Tree with all nodes */
  private void loadBOM() throws Exception {
    int count = 0;
    if (p_M_Product_ID == 0) raiseError("Error: ", "Product ID not found");

    MProduct product = new MProduct(getCtx(), p_M_Product_ID, get_TrxName());
    X_T_BOMLine tboml = new X_T_BOMLine(ctx, 0, null);
    tboml.setAD_Org_ID(product.getAD_Org_ID());
    tboml.setPP_Product_BOM_ID(0);
    tboml.setPP_Product_BOMLine_ID(0);
    tboml.setSel_Product_ID(p_M_Product_ID);
    tboml.setM_Product_ID(p_M_Product_ID);
    tboml.setSel_Product_ID(p_M_Product_ID);
    tboml.setDateTrx(p_DateTrx);
    tboml.setImplosion(false);
    tboml.setLevelNo(0);
    tboml.setLevels("0");
    tboml.setQtyBOM(Env.ONE);
    tboml.setQtyRequired(p_QtyRequiered);
    tboml.setM_Warehouse_ID(p_M_Warehouse_ID);
    tboml.setSeqNo(0);
    tboml.setAD_PInstance_ID(AD_PInstance_ID);
    tboml.saveEx();

    final String whereClause = MPPProductBOM.COLUMNNAME_M_Product_ID + "=?";
    List<MPPProductBOM> boms =
        new Query(getCtx(), X_PP_Product_BOM.Table_Name, whereClause, get_TrxName())
            .setClient_ID()
            .setOnlyActiveRecords(true)
            .setParameters(p_M_Product_ID)
            .list();

    for (MPPProductBOM bom : boms) {
      if (bom.isValidFromTo(p_DateTrx)) {
        parentExplotion(bom.get_ID(), p_QtyRequiered);
        ++count;
      }
    }

    if (count == 0) raiseError("Error: ", "Product is not a BOM");
  }