title: Business Rule Split among two classes
body: <p>I have a project allocation domain with the following business rules</p>
  <ol>
  <li>When a new employee is getting allocated to a project the total expenditure should not exceed the Budget Amount.</li>
  <li>For an employee the total allocation percentage should not exceed 100%</li>
  </ol>
  <p>I have created entities as shown below created in <code>C#</code>.</p>
  <p><strong>QUESTION</strong></p>
  <p>The <code>Allocate</code> logic is split across two classes – Project and Employee..The <code>List&lt;Allocation&gt;</code> is passed as a parameter to the Allocate method rather than adding as property of the class... Is it correct approach or do I need to add <code>List&lt;Allocation&gt;</code> as property in these two classes?</p>
  <p>Note:</p>
  <p><strong>Database</strong></p>
  <p><img src="https://i.stack.imgur.com/c27VX.png" alt="enter image description here" /></p>
  <p><strong>Entitles</strong></p>
  <p><img src="https://i.stack.imgur.com/2cEyL.png" alt="enter image description here" /></p>
  <p><strong>Code</strong></p>
  <p><em>Project</em></p>
  <pre><code> public class Project
      {
          public int ProjectID { get; set; }
          public int BudgetAmount { get; set; }
          public string ProjectName { get; set; }
  
          public void Allocate(Role newRole, int newPercentage, Employee newEmployee, List&lt;Allocation&gt; existingAllocationsInProject)
          {
              int currentTotalExpenditure = 0;
              if (existingAllocationsInProject != null)
              {
                  foreach (Allocation alloc in existingAllocationsInProject)
                  {
                      int allocationExpenditure = alloc.Role.BillRate * alloc.PercentageAllocation / 100;
                      currentTotalExpenditure = currentTotalExpenditure + allocationExpenditure;
                  }
              }
  
              int newAllocationExpenditure = newRole.BillRate * newPercentage / 100;
              if (currentTotalExpenditure + newAllocationExpenditure &lt;= BudgetAmount)
              {
                  List&lt;Allocation&gt; existingAllocationsOfEmployee = GetAllocationsForEmployee(newEmployee.EmployeeID);
                  bool isValidAllocation= newEmployee.Allocate(newRole, newPercentage, existingAllocationsOfEmployee);
  
                  if (isValidAllocation)
                  {
                      //Do allocation
                  }
                  else
                  {
                      throw new Exception(&quot;Employee is not avaiable for allocation&quot;);
                  }
  
              }
              else
              {
                  throw new Exception(&quot;Budget Exceeded&quot;);
              }
  
          }
      }
  </code></pre>
  <p><em>Employee</em></p>
  <pre><code>public class Employee
  {
      public int EmployeeID { get; set; }
      public string EmployeeName { get; set; }
  
  
      public bool Allocate(Role newRole, int newPercentage, List&lt;Allocation&gt; existingAllocationsOfEmployee)
      {
          int currentTotalAllocation = 0;
          if (existingAllocationsOfEmployee != null)
          {
              foreach (Allocation alloc in existingAllocationsOfEmployee)
              {
                  currentTotalAllocation = currentTotalAllocation + alloc.PercentageAllocation;
              }
          }
  
          if (currentTotalAllocation + newPercentage &lt;= 100)
          {
              return true;
          }
  
          return false;
      }
  
      }
  </code></pre>
  <p><strong>References</strong></p>
  <p>Following is from <a href="https://stackoverflow.com/questions/5017969/repository-pattern-without-an-orm">Repository Pattern without an ORM</a></p>
  <blockquote>
  <p>What behaviour is there that requires the customer to have a list of orders? When you give more thought to the behaviour of your domain (i.e. what data is required at what point) you can model your aggregates based around use cases and things become much clearer and much easier as you are only change tracking for a small set of objects in the aggregate boundary.</p>
  <p>I suspect that Customer should be a separate aggregate without a list of orders, and Order should be an aggregate with a list of order lines. If you need to perform operations on each order for a customer then use orderRepository.GetOrdersForCustomer(customerID); make your changes then use orderRespository.Save(order);</p>
  </blockquote>