user2559108
user2559108

Reputation:

Frequent design issue in Symfony, model calculation logic in entity

I frequently experience a design issue in Symfony, i am not sure if i am solving it optimally.

Let me give an example:

Entity Merchant Account
property $dailyProcessingLimitation // Int
property $orders // ArrayCollection

An entity named Merchant account has a daily processing limitation, set to X euro's.

I want to check if a specific merchant account has reached its processing limitation, to do this i do the following:

I fetch all orders for today, and convert them all to a single currency, to do this, i need some stuff like a currency converter, so i cannot do this inside of the entity, since i should not be injecting the container into the entity.

So i have to create a "MerchantAccountManager", and do something like this:

$merchantAccountManager = $this->container->get('merchant_account_manager');
$totalForAccount = $this->getTotalProcessedForMerchantAccount($merchantAccount);

Is there any proper way to be able to call this directly on the entity, rather then adding this which feels like ugly coding.

Reason as to why i feel it feels like bad design, is that the other developer has to know that the service exists, rather then being able to inspect the entity methods.

Upvotes: 0

Views: 58

Answers (2)

E.K.
E.K.

Reputation: 1055

What if some MerchantAccount is reached limitation? It can't receive new orders? I this case, just place into your MerchantAccount methods and use it.

public function addOrder(Order $newOrder)
{
    if (($order->getAmount() + $this->getOrdersAmount()) <= $this->dailyProcessingLimitation) {
        throw new Exception('The limit has been reached');
    } else {
        $this->orders->add($order);
    }

    return $this;
}

public function getOrdersAmount()
{
    $result = 0;
    foreach ($this->orders as $order) {
        $result += $order->getAmount();
    }

    return $result;
}

Upvotes: 1

StackOverflowUser
StackOverflowUser

Reputation: 125

You simply could use the entity to get all orders and calculate based on certain conditions whether the daily processing limit is breached:

<?php
namespace AppBundle\Entity

class MerchantAccount {
...
public function getTotalForAccount()
{
    $sum = 0;

    foreach($this->getMerchant()->getOrders() as $order)
    {
        if(//WHATEVER CONDITIONS YOU NEED) {
            $sum += $order->getAmount();
        }
    }

    return $sum;
}
...

Have a look at: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/aggregate-fields.html

Or you could just write DQL to aggregate using a query directly!

Upvotes: 1

Related Questions