private static TableRow findProductTableRow(TableLayout tableLayout, dbProduct product) {
    // Get the number of rows in the table
    int rowCount = tableLayout.getChildCount();

    // Loop through the rows in the table searching for the one
    // with the matching product
    for (int rowIndex = 1; rowIndex < rowCount; rowIndex++) {
      // Get the row at the index
      TableRow row = (TableRow) tableLayout.getChildAt(rowIndex);

      // Test if the tag matches - if it does return the row
      if (row.getTag().equals(product)) {
        return row;
      }
    }

    // Row was not found therefore return null
    return null;
  }
  public void updateStock() {
    try {
      CrashReporter.leaveBreadcrumb("MyStockSummary : updateStock");

      //
      // Step 1 - Clear existing data.
      //

      clearTable(byProductTable);
      clearTable(tlByCompartmentTable);

      //
      // Step 2 - Add any compartment stock.
      //

      if (Active.vehicle.StockByCompartment) {
        tvByCompartment.setVisibility(View.VISIBLE);
        tlByCompartmentTable.setVisibility(View.VISIBLE);

        // Add hosereel product.
        if (Active.vehicle.getHasHosereel()) {
          dbProduct product = Active.vehicle.getHosereelProduct();

          int capacity = Active.vehicle.getHosereelCapacity();

          // Add product to 'by product' table.
          addByProduct(product, capacity);

          // Add product to 'by compartment' table.
          addByCompartment(product, 0, capacity, capacity);
        }

        // Set number of compartments on tanker image.
        tanker.setCompartmentCount(Active.vehicle.getCompartmentCount());

        // Set product types and levels on tanker image.
        for (int tankerIdx = 0, compartmentIdx = Active.vehicle.getCompartmentStartIdx();
            compartmentIdx < Active.vehicle.getCompartmentEndIdx();
            tankerIdx++, compartmentIdx++) {
          dbProduct product = Active.vehicle.getCompartmentProduct(compartmentIdx);
          int no = Active.vehicle.getCompartmentNo(compartmentIdx);
          int capacity = Active.vehicle.getCompartmentCapacity(compartmentIdx);
          int onboard = Active.vehicle.getCompartmentOnboard(compartmentIdx);
          int colour = Active.vehicle.getCompartmentColour(compartmentIdx);

          // Update compartment on vehicle image.
          tanker.setCompartmentNo(tankerIdx, no);
          tanker.setCompartmentCapacity(tankerIdx, capacity);
          tanker.setCompartmentOnboard(tankerIdx, onboard);
          tanker.setCompartmentColour(tankerIdx, colour);

          // Add product to 'by product' table.
          addByProduct(product, onboard);

          // Add product to 'by compartment' table.
          if (Active.vehicle.StockByCompartment) {
            addByCompartment(product, no, capacity, onboard);
          }
        }
      }

      //
      // Step 3 - Add any non-compartment stock.
      //

      for (dbVehicleStock vs : dbVehicleStock.findAllNonCompartmentStock(Active.vehicle)) {
        addByProduct(vs.Product, vs.CurrentStock);
      }

      if (!Active.vehicle.StockByCompartment) {
        tvByCompartment.setVisibility(View.GONE);
        tlByCompartmentTable.setVisibility(View.GONE);

        if (Active.vehicle.getHasHosereel()) {
          // Add product to 'by product' table.
          addByProduct(Active.vehicle.getHosereelProduct(), Active.vehicle.getHosereelCapacity());
        }
      }

      //
      // Step 4 - find orders on this trip, and updated required.
      //

      // Find all undelivered orders on this trip.
      if (Active.trip != null) {
        for (dbTripOrder order : Active.trip.getUndelivered()) {
          // Find all order lines.
          for (dbTripOrderLine orderLine : order.getTripOrderLines()) {
            TableRow myTr = null;

            // Skip null products.
            // Skip non-deliverable products. e.g. credit card fees
            if (orderLine.Product == null || orderLine.Product.MobileOil == 3) {
              continue;
            }

            // Check if product already exists.
            for (int row = 1; row < byProductTable.getChildCount(); row++) {
              TableRow tr = (TableRow) byProductTable.getChildAt(row);

              if (tr.getTag().equals(orderLine.Product)) {
                myTr = tr;

                break;
              }
            }

            // Create new row, if not exists.
            if (myTr == null) {
              myTr = createByProductRow(orderLine.Product, 0);
            }

            // Find previous required.
            MyTextView tvRequired =
                (MyTextView) myTr.findViewById(R.id.stock_summary_by_product_tablerow_required);

            int prevRequired = 0;

            try {
              String text = tvRequired.getText().toString();

              if (text.length() > 0) {
                prevRequired = formatDecimal.parse(text).intValue();
              }
            } catch (ParseException e) {
              e.printStackTrace();
            }

            // Update required to include this order line.
            int required = prevRequired + orderLine.OrderedQty;
            tvRequired.setText(formatDecimal.format(required));

            // Find total onboard.
            MyTextView tvOnboard =
                (MyTextView) myTr.findViewById(R.id.stock_summary_by_product_tablerow_onboard);

            int onboard = 0;

            try {
              onboard = formatDecimal.parse((String) tvOnboard.getText()).intValue();
            } catch (ParseException e) {
              e.printStackTrace();
            }

            // Update the 'To Load' column.
            MyTextView toLoad =
                (MyTextView) myTr.findViewById(R.id.stock_summary_by_product_tablerow_to_load);

            if (required > onboard) {
              toLoad.setText(formatDecimal.format(required - onboard));
            } else {
              toLoad.setText(formatDecimal.format(0));
            }
          }
        }
      }
    } catch (Exception e) {
      CrashReporter.logHandledException(e);
    }
  }