private void addByProduct(dbProduct product, int onboard) {
    try {
      CrashReporter.leaveBreadcrumb("MyStockSummary : addByProduct");

      // Check product is valid.
      if (product == null) {
        return;
      }

      // Attempt to find the table row showing the product
      TableRow row = findProductTableRow(byProductTable, product);

      if (row != null) {
        // Get reference to table cell holding the amount of product onboard
        MyTextView productOnboard =
            (MyTextView) row.findViewById(R.id.stock_summary_by_product_tablerow_onboard);

        // Update quantity onboard.
        int prevOnboard = 0;

        try {
          prevOnboard = formatDecimal.parse(productOnboard.getText().toString()).intValue();
        } catch (ParseException e) {
          e.printStackTrace();
        }

        productOnboard.setText(formatDecimal.format(onboard + prevOnboard));
      } else {
        // If this point is reached then the row containing the product
        // could not be found in the table - therefore create a row for it.
        createByProductRow(product, onboard);
      }
    } catch (Exception e) {
      CrashReporter.logHandledException(e);
    }
  }
  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);
    }
  }