# Validate Order Details When Back Office Submits

In the Order Management App, when a **Back Office user** submits an order request, the system must ensure that **all order units have been fully assigned to suppliers**.

Specifically, for each **Order Request Item**, the sum of **Order Unit assigned to suppliers** must be **equal to the total Unit of the order item**.\
If any order item still has unassigned units, the submission must be blocked.

This section explains how to implement **data‑level validation using DAO (JDBC)** and integrate the validation into the **Back Office submit action**.

***

### Requirement

For all Order Request Items in a request:

```
SUM(Unit assigned to suppliers)
= Unit of Order Request Item
```

If any item does not satisfy this condition, the system must display:

```
Please verify un-assign order unit.
```

and prevent submission.

***

### Objective

By completing this section, you will learn how to:

* Validate business rules using direct database queries
* Implement DAO and JDBC access in ONEWEB
* Perform cross‑table validation before submit
* Block workflow continuation when validation fails

***

### Step 1: Create JDBC Service Locator

Create the following Java class in **MasterWeb**.

#### Class Name

```
com.manual.service.ManualJDBCServiceLocator
```

#### Purpose

* Centralized JDBC connection handling
* Supports both **Master DB** and **Application DB**

#### Java Code

```
package com.manual.service;

import java.sql.Connection;
import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

public class ManualJDBCServiceLocator {

    private final static transient Logger log =
            LogManager.getLogger(ManualJDBCServiceLocator.class);

    public static ManualJDBCServiceLocator serviceLocator;

    public final static int MASTER_DB = 0;
    public final static int ONEWEB_DB = 1;

    public final static String MASTER_DATA_SOURCE = "jdbc/master";
    public final static String APPLICATION_DATA_SOURCE = "jdbc/application";

    public static synchronized ManualJDBCServiceLocator getInstance() {
        if (serviceLocator == null) {
            serviceLocator = new ManualJDBCServiceLocator();
        }
        return serviceLocator;
    }

    private ManualJDBCServiceLocator() {
    }

    public Connection getConnection(int dbType) throws Exception {
        DataSource ds = null;
        InitialContext ctx = new InitialContext();
        switch (dbType) {
            case MASTER_DB:
                ds = (DataSource) ctx.lookup(MASTER_DATA_SOURCE);
                break;
            case ONEWEB_DB:
                ds = (DataSource) ctx.lookup(APPLICATION_DATA_SOURCE);
                break;
            default:
                return null;
        }
        return ds.getConnection();
    }

    public Connection getConnection(String jndiName) throws Exception {
        InitialContext ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup(jndiName);
        return ds.getConnection();
    }
}
```

***

### Step 2: Create Base DAO Class

#### Class Name

```
com.manual.doc.order.dao.ManualDocObjectDAO
```

#### Purpose

* Common DAO utility for closing JDBC resources

```
package com.manual.doc.order.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class ManualDocObjectDAO {

    public void closeConnection(Connection conn, PreparedStatement ps, ResultSet rs) {

        if (rs != null) {
            try { rs.close(); } catch (Exception e) {}
        }
        if (ps != null) {
            try { ps.close(); } catch (Exception e) {}
        }
        if (conn != null) {
            try { conn.commit(); } catch (Exception e) {}
            try { conn.close(); } catch (Exception e) {}
        }
    }
}
```

***

### Step 3: Create DAO Interface

#### Class Name

```
com.manual.doc.order.dao.ManualDocOrderDAO
```

```
package com.manual.doc.order.dao;

public interface ManualDocOrderDAO {

    int countInCompleteOrderUnit(String requestID) throws Exception;
}
```

***

### Step 4: Implement DAO Logic

#### Class Name

```
com.manual.doc.order.dao.ManualDocOrderDAOImpl
```

#### Business Logic

* Counts order items where:

  ```
  order_item.unit - SUM(supplier.unit_by_back_office) != 0
  ```

```
package com.manual.doc.order.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.apache.log4j.Logger;

import com.manual.service.ManualJDBCServiceLocator;

public class ManualDocOrderDAOImpl
        extends ManualDocObjectDAO
        implements ManualDocOrderDAO {

    private Logger logger = Logger.getLogger(ManualDocOrderDAOImpl.class);

    @Override
    public int countInCompleteOrderUnit(String requestID) throws Exception {

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        int result = 0;

        try {
            conn = ManualJDBCServiceLocator.getInstance()
                    .getConnection(ManualJDBCServiceLocator.ONEWEB_DB);

            StringBuilder sql = new StringBuilder();
            sql.append("SELECT COUNT(1) AS in_complete_amt ");
            sql.append("FROM ( ");
            sql.append("  SELECT oi.request_id, oi.unit, ");
            sql.append("         SUM(ois.unit_by_back_office) AS order_unit ");
            sql.append("  FROM wf_order_req_item oi ");
            sql.append("  JOIN wf_order_req_item_supplier ois ");
            sql.append("    ON oi.order_item_id = ois.order_item_id ");
            sql.append("  WHERE oi.request_id = ? ");
            sql.append("  GROUP BY oi.request_id, oi.unit ");
            sql.append(") tmp ");
            sql.append("WHERE tmp.unit - tmp.order_unit <> 0 ");

            ps = conn.prepareStatement(sql.toString());
            ps.setString(1, requestID);

            rs = ps.executeQuery();
            if (rs.next()) {
                result = rs.getInt("in_complete_amt");
            }
            return result;

        } finally {
            closeConnection(conn, ps, rs);
        }
    }
}
```

***

### Step 5: Create DAO Factory

#### Class Name

```
com.manual.service.ManualDAOFactory
```

```
package com.manual.service;

import com.manual.doc.order.dao.ManualDocOrderDAO;
import com.manual.doc.order.dao.ManualDocOrderDAOImpl;

public class ManualDAOFactory {

    public static ManualDocOrderDAO getManualDocOrderDAO() {
        return new ManualDocOrderDAOImpl();
    }
}
```

***

### Step 6: Implement Back Office Validation Logic

#### Class Name

```
com.manual.doc.order.java.OrderRequestBackOfficeUpdateMode
```

#### Validation Trigger

* Executed during Back Office submit / update
* Blocks submit when incomplete order unit exists

```
package com.manual.doc.order.java;

import java.util.HashMap;
import java.util.Vector;

import org.apache.log4j.Logger;

import com.manual.service.ManualDAOFactory;
import com.master.form.EntityFormHandler;
import com.master.util.EAFManualUtil;
import com.master.util.ProcessAction;
import com.master.util.ProcessHelper;

public class OrderRequestBackOfficeUpdateMode
        extends ProcessHelper
        implements ProcessAction {

    private static Logger logger =
            Logger.getLogger(OrderRequestBackOfficeUpdateMode.class);

    @Override
    public boolean validateResult() {

        String nextEntity = request.getParameter("goEntity");
        logger.debug("@@@@@ nextEntity :" + nextEntity);

        if (nextEntity == null || "".equals(nextEntity)) {

            String entityID =
                    (String) request.getSession().getAttribute("entityID");

            EntityFormHandler entityForm =
                    (EntityFormHandler)
                            request.getSession()
                                   .getAttribute(entityID + "_session");

            Vector errorVect = entityForm.getFormErrors();
            String moduleID = entityForm.getMainModuleID();

            HashMap mainRequestData =
                    EAFManualUtil.getDataHashMapFromSession(moduleID, request);

            String requestID =
                    (String) mainRequestData.get("REQUEST_ID");

            try {
                int inCompleteAmt =
                        ManualDAOFactory
                                .getManualDocOrderDAO()
                                .countInCompleteOrderUnit(requestID);

                if (inCompleteAmt > 0) {
                    errorVect.add(
                      "Please verify un-assign order unit.");
                    return false;
                }

            } catch (Exception e) {
                errorVect.add(e.getMessage());
                return false;
            }
        }
        return super.validateResult();
    }
}
```

***

### Step 7: Deploy Java Classes

1. Export `EafMasterEar.ear`
2. Deploy to the server

All classes from **Step 1–6** are now active.

***

### Step 8: Test Validation

1. Log in to **FrontWeb** as **Back Office user**
2. Go to **To Do List**
3. Claim a job
4. Click **Save** or **Submit**

#### Expected Result

* If any Order Item has incomplete supplier allocation
* Submission is blocked
* Error message is displayed:

  ```
  Please verify un-assign order unit.
  ```

***

### Summary

In this section, you have:

* Implemented DAO‑based validation using JDBC
* Enforced critical business rules at submit time
* Integrated deep data validation with App Designer flow
* Ensured data consistency across Order Request, Item, and Supplier

This validation completes the **Back Office data integrity layer** of the **Order Management App (Web)** and demonstrates how **DAO‑level customization** can be used to enforce enterprise‑grade business rules.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.onewebstack.com/oneweb-platform-th/tutorials-examples/order-management-app-web/app-designer-customize/validate-order-details-when-back-office-submits.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
