0

I have an accounting app in Symfony 2.7.x.

When creating a new transaction, the total amount in the transaction may be split across multiple categories but I need to validate that the total of the category amounts is not greater than the total of the transaction.

ie- Transaction:

Payee: Exxon

Amount: $100.00

Categories:


Name: Snacks

Amount: $45.00


Name: Gasoline

Amount: $55.00

Each category is a separate entity in the database as well.

So if the user changed Gasoline to $65.00, the form should fail validation.

I've researched Symfony 2 form validation but everything I find seems to revolve around Constraint Annotations on single properties of an object and not across multiple entities.

I'm assuming I need to set up a validation service, but I'm struggling with how to set it up and to get it to trigger on the appropriate form.

2 Answers 2

1

You can also use the Expression validation constraint to spare a few lines of code. It can be as easy to validate as:

YML:

AppBundle\Entity\Transaction:
constraints:
    - Expression:
        expression: "this.getAmount() >= this.getCategorySum()"
        message: "Amount should be greater then or equal to the sum of amounts."

Or with annotations:

/**
 * @Assert\Expression(
 *     "this.getAmount() >= this.getCategorySum()",
 *     message="Amount should be greater then or equal to the sum of amounts."
 * )
 */
 class Transaction{
   ...
   public function getCategorySum(){
   ...

Where the getCategorySum() method of the Transaction object would return the sum of amounts of the categories.

Sign up to request clarification or add additional context in comments.

Comments

0

In your case, yes, all the primitive validators do not work. You need a to write a custom callback. From symfony documentation CallBack:

Callback

The purpose of the Callback constraint is to create completely custom validation rules and to assign any validation errors to specific fields on your object. If you're using validation with forms, this means that you can make these custom errors display next to a specific field, instead of simply at the top of your form.

So, in your case it would be as following:

class Transaction
{
    //...
    private $amount;
    //...

    /**
     * @Assert\Callback
     */
    public function validate(ExecutionContextInterface $context)
    {
        // ...
        //Get your total category price here.
        $totalCategoryPrice = ...;
        if($this->amount<$totalCategoryPrice)
        {
            $context->buildViolation('Total amount can not be greater than the total amount of each category.')
            ->atPath('amount')
            ->addViolation();
        }

    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.