> ## Documentation Index
> Fetch the complete documentation index at: https://aletyx.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Your First Decision Table in Aletyx Enterprise Build of Kogito and Drools 10.1.0-aletyx

> Walk through creating a decision table for a shipping charges calculation system, ideal for business rules managed by business analysts and subject matter experts.

This guide walks you through creating a decision table for a shipping charges calculation system. This approach is ideal for business rules that need to be managed by business analysts and subject matter experts without requiring programming knowledge.

## Example Use Case: Enterprise Shipping Charges

Our enterprise shipping system has the following pricing rules:

* Free shipping when:
  * The order has 4+ items AND the total is \$300+
  * Standard shipping is selected (4-5 business days)
* Otherwise, shipping charges vary based on:
  * Number of items
  * Delivery speed (Next day, 2nd day, or Standard)
  * Order total (less than $300 or $300+)

## Version 1: Using Aletyx Playground

### Step 1: Access Aletyx Playground

1. Navigate to [playground.aletyx.ai](https://playground.aletyx.ai) or run locally:

```bash theme={null}
curl -sL https://raw.githubusercontent.com/aletyx-labs/kie-10.0.0-sandbox/refs/heads/main/docker-compose.yaml | docker compose -f - up
```

2. From the welcome screen, click New Decision to create an empty DMN Decision (even if we're not using it, this will be a quick way to incorporate project dependencies consistent for decisions.
3. Click  **Apply Accelerator**
4. Select the Decisions Accelerator
5. Now you can either download the project that would be configured for decisions or use Aletyx Playground to synchronize with Git. If you do the synchronization, you will be able to either Open with VSCode directly from Aletyx Playground or clone it from the created repository link.

### Step 2: Create and Edit the Decision Table

1. Create a new spreadsheet with the name `ShippingCharges.drl` and save it as the type `xls`. The reason for using `xls` over `xlsx` is that the default settings for the Maven build will include the temporary file that Microsoft Office creates when a spreadsheet is actively opened.
2. In the new spreadsheet start adding the following starting in cell A1:

| A       | B                                                                                            | C |
| ------- | -------------------------------------------------------------------------------------------- | - |
| RuleSet | ai.aletyx.shipping                                                                           |   |
| Unit    | ShippingUnit                                                                                 |   |
| Import  | ai.aletyx.model.Order, ai.aletyx.model.Charge                                                |   |
| Queries | query FindShippingCharge(Order order, Charge charge) order := /orders charge := /charges end |   |

1. Review and modify the first RuleTable for orders under \$300:

| A                      | B                 | C                                  | D                                 |                                                                                                                          |
| ---------------------- | ----------------- | ---------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| RuleTable ShippingRule |                   |                                    |                                   |                                                                                                                          |
| CONDITION              | CONDITION         | ACTION                             | ACTION                            |                                                                                                                          |
| \$order : /orders      | \$order : /orders |                                    |                                   |                                                                                                                          |
|                        | total \< 300      | itemsCount $1, deliverInDays == $2 | charges.add(new Charge(\$param)); | System.out.println("The Decision Table fired rule " + "$param2" + "and the order count was: " + $order.getItemsCount()); |
|                        | Under \$300       | Items & Delivery                   | Shipping Charge                   | Shipping Charge                                                                                                          |
|                        |                   | \< 3, 1                            | 35                                | 35                                                                                                                       |
|                        |                   | \< 3, 2                            | 15                                | 15                                                                                                                       |
|                        |                   | \< 3, 5                            | 10                                | 10                                                                                                                       |
|                        |                   | >= 4, 1                            | \$order.getItemsCount() \* 7.50   | \$order.getItemsCount() \* 7.50                                                                                          |
|                        |                   | >= 4, 2                            | \$order.getItemsCount() \* 3.50   | \$order.getItemsCount() \* 3.50                                                                                          |
|                        |                   | >= 4, 5                            | \$order.getItemsCount() \* 2.50   | \$order.getItemsCount() \* 2.50                                                                                          |

1. Review and modify the second RuleTable for orders of \$300 or more:

| A | B                           | C                                  | D                                 |
| - | --------------------------- | ---------------------------------- | --------------------------------- |
|   | RuleTable Shipping Over 300 |                                    |                                   |
|   | CONDITION                   | CONDITION                          | ACTION                            |
|   | \$order : /orders           | \$order : /orders                  |                                   |
|   | total >= 300                | itemsCount $1, deliverInDays == $2 | charges.add(new Charge(\$param)); |
|   | \$300 or more               | Items & Delivery                   | Shipping Charge                   |
|   |                             | \< 3, 1                            | 25                                |
|   |                             | \< 3, 2                            | 10                                |
|   |                             | \< 3, 5                            | \$order.getItemsCount() \* 1.50   |
|   |                             | >= 4, 1                            | \$order.getItemsCount() \* 5      |
|   |                             | >= 4, 2                            | \$order.getItemsCount() \* 2      |
|   |                             | >= 4, 5                            | 0                                 |

### Step 4: Create Required Java Classes

Create two Java files in your project:

**Order.java**

```java theme={null}
package ai.aletyx.model;

public class Order {
	private int itemsCount;
	private double total;
	private int deliverInDays;

	public Order() {
	}

	public Order(int itemsCount, double total, int deliverInDays) {
		this.itemsCount = itemsCount;
		this.total = total;
		this.deliverInDays = deliverInDays;
	}

	// Getters and setters
	public int getItemsCount() {
		return itemsCount;
	}

	public void setItemsCount(int itemsCount) {
		this.itemsCount = itemsCount;
	}

	public double getTotal() {
		return total;
	}

	public void setTotal(double total) {
		this.total = total;
	}

	public int getDeliverInDays() {
		return deliverInDays;
	}

	public void setDeliverInDays(int deliverInDays) {
		this.deliverInDays = deliverInDays;
	}
}
```

**Charge.java**

```java theme={null}
package ai.aletyx.model;

public class Charge {
	private double amount;

	public Charge() {
	}

	public Charge(double amount) {
		this.amount = amount;
	}

	public double getAmount() {
		return amount;
	}

	public void setAmount(double amount) {
		this.amount = amount;
	}

	@Override
	public String toString() {
		return "Shipping charge: $" + amount;
	}
}
```

### Step 5: Test Your Decision Table

1. Click **Deploy** to create a dev deployment
2. Once deployed, use the test interface to submit test orders:
   * Order 1: 2 items, $150 total, 1-day delivery (Expected charge: $35)
   * Order 2: 5 items, $400 total, 5-day delivery (Expected charge: $0 - free shipping)

## Version 2: Java 17 Project with Maven

### Step 1: Create a Maven Project

1. Create a new Maven project with the following structure:

```
shipping-rules-app/
├── pom.xml
└── src/
	└── main/
		├── java/
		│   └── ai/
		│       └── aletyx/
		│           ├── model/
		│           │   ├── Order.java
		│           │   └── Charge.java
		│           └── ShippingChargesApp.java
		└── resources/
			└── rules/
				└── ShippingCharges.drl.xlsx
```

2. Set up your `pom.xml`:

```xml theme={null}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>ai.aletyx</groupId>
	<artifactId>shipping-rules-app</artifactId>
	<version>1.0.0</version>

	<properties>
		<maven.compiler.source>17</maven.compiler.source>
		<maven.compiler.target>17</maven.compiler.target>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<drools.version>10.0.0</drools.version>
	</properties>

	<dependencies>
		<!-- Drools Dependencies -->
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-engine</artifactId>
			<version>${drools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-xml-support</artifactId>
			<version>${drools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-ruleunits-engine</artifactId>
			<version>${drools.version}</version>
		</dependency>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-decisiontables</artifactId>
			<version>${drools.version}</version>
		</dependency>

		<!-- Logging -->
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.11</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
				<configuration>
					<descriptorRefs>
						<descriptorRef>jar-with-dependencies</descriptorRef>
					</descriptorRefs>
					<archive>
						<manifest>
							<mainClass>ai.aletyx.ShippingChargesApp</mainClass>
						</manifest>
					</archive>
				</configuration>
				<executions>
					<execution>
						<id>make-assembly</id>
						<phase>package</phase>
						<goals>
							<goal>single</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>
```

### Step 2: Create the Model Classes

Create the Order and Charge classes in the `ai.aletyx.model` package as shown in the Playground version.

### Step 3: Create the Decision Table

Create the Excel decision table as described above and save it to `src/main/resources/rules/ShippingCharges.drl.xlsx`.

### Step 4: Create the Application Class

Create `ShippingChargesApp.java`:

```java theme={null}
package ai.aletyx;

import ai.aletyx.model.Charge;
import ai.aletyx.model.Order;
import org.drools.ruleunits.api.RuleUnitInstance;
import org.drools.ruleunits.api.RuleUnitProvider;
import org.drools.ruleunits.api.conf.RuleConfig;
import org.kie.api.resource.ResourceType;
import org.kie.internal.io.ResourceFactory;
import org.drools.io.ResourceFactoryService;
import org.kie.api.io.ResourceType;
import org.drools.ruleunits.api.RuleUnitInstance;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ShippingChargesApp {
	public static void main(String[] args) {
		// Create a rule unit provider
		RuleUnitProvider ruleUnitProvider = RuleUnitProvider.get();

		// Create a rule unit data store
		ShippingUnit shippingUnit = new ShippingUnit();

		// Create a rule unit instance
		try (RuleUnitInstance<ShippingUnit> instance = ruleUnitProvider.createRuleUnitInstance(shippingUnit)) {
			// Load the decision table
			instance.getKieSession().getKieBase().newKieBuilder()
					.add(ResourceFactory.newClassPathResource("rules/ShippingCharges.drl.xlsx"), ResourceType.DTABLE)
					.build();

			// Interactive command line interface
			Scanner scanner = new Scanner(System.in);
			boolean running = true;

			while (running) {
				System.out.println("\n=== Shipping Charge Calculator ===");
				System.out.println("1. Calculate shipping charge");
				System.out.println("2. Exit");
				System.out.print("Enter choice: ");

				int choice = scanner.nextInt();
				scanner.nextLine(); // Consume newline

				switch (choice) {
					case 1:
						calculateShipping(scanner, shippingUnit, instance);
						break;
					case 2:
						running = false;
						break;
					default:
						System.out.println("Invalid choice!");
				}
			}

			System.out.println("Thank you for using the Shipping Charge Calculator!");
		}
	}

	private static void calculateShipping(Scanner scanner, ShippingUnit shippingUnit, RuleUnitInstance<ShippingUnit> instance) {
		System.out.print("Enter number of items: ");
		int itemsCount = scanner.nextInt();

		System.out.print("Enter order total: $");
		double total = scanner.nextDouble();

		System.out.println("Select delivery speed:");
		System.out.println("1. Next Day (1)");
		System.out.println("2. Second Day (2)");
		System.out.println("3. Standard (5)");
		System.out.print("Enter choice (1-3): ");
		int deliveryChoice = scanner.nextInt();

		int deliverInDays;
		switch (deliveryChoice) {
			case 1: deliverInDays = 1; break;
			case 2: deliverInDays = 2; break;
			case 3: deliverInDays = 5; break;
			default: deliverInDays = 5;
		}

		// Create the order
		Order order = new Order(itemsCount, total, deliverInDays);
		shippingUnit.getOrders().add(order);

		// Fire rules
		instance.fire();

		// Get results
		List<Charge> charges = new ArrayList<>(shippingUnit.getCharges());
		if (!charges.isEmpty()) {
			System.out.println("\nShipping charge: $" + charges.get(charges.size() - 1).getAmount());
		} else {
			System.out.println("\nNo shipping charge calculated.");
		}

		// Clear data for next calculation
		shippingUnit.getOrders().clear();
		shippingUnit.getCharges().clear();
	}

	// Rule Unit class
	public static class ShippingUnit {
		private final List<Order> orders = new ArrayList<>();
		private final List<Charge> charges = new ArrayList<>();

		public List<Order> getOrders() {
			return orders;
		}

		public List<Charge> getCharges() {
			return charges;
		}
	}
}
```

### Step 5: Build and Run the Application

1. Build the project:

```bash theme={null}
mvn clean package
```

2. Run the application:

```bash theme={null}
java -jar target/shipping-rules-app-1.0.0-jar-with-dependencies.jar
```

3. Follow the interactive prompts to test different orders:
   * Try an order with 2 items, \$150 total, Next Day delivery
   * Try an order with 5 items, \$350 total, Standard delivery

## Benefits of Excel Decision Tables

* **Decision Analyst Friendly**: Non-technical stakeholders can understand and modify rules
* **Centralized Rule Management**: All business rules in one visible location
* **Easy Maintenance**: Rules can be updated without code changes
* **Version Control**: Excel files can be versioned alongside code
* **Rapid Iteration**: Quick updates to business rules without recompilation
