/**
     * Creates the transaction.
     * If a DB\Transaction has been explicitly set, adds the Transaction to the
     * DB\Transaction. Otherwise commits $_query.
     *
     * @param  Transaction $transaction transaction to be created
     *
     * @return Transaction              if transaction wasn't overridden
     *                                  re-loaded $transaction, otherwise just
     *                                  $transaction
     */
    public function create(Transaction $transaction)
    {
        // Set create authorship data if not already set
        if (!$transaction->authorship->createdAt()) {
            $transaction->authorship->create(new DateTimeImmutable(), $this->_currentUser->id);
        }
        $event = new Event\TransactionalEvent($transaction);
        $event->setDbTransaction($this->_query);
        $transaction = $this->_eventDispatcher->dispatch(Events::CREATE_START, $event)->getTransaction();
        $this->_validate($transaction);
        $this->_query->run('
			INSERT INTO
				transaction
			SET
				created_at     = :createdAt?d,
				created_by     = :createdBy?in,
				type           = :type?s
		', array('createdAt' => $transaction->authorship->createdAt(), 'createdBy' => $transaction->authorship->createdBy(), 'type' => $transaction->type));
        $sqlVariable = 'TRANSACTION_ID_' . uniqid();
        $this->_query->setIDVariable($sqlVariable);
        $transaction->id = '@' . $sqlVariable;
        $this->_createRecords($transaction);
        $this->_createAttributes($transaction);
        $loader = $this->_loader;
        $this->_query->attachEvent(Events::CREATE_COMPLETE, function ($dbTrans) use($loader, $sqlVariable) {
            return new Event\Event($loader->getByID($dbTrans->getIDVariable($sqlVariable)));
        });
        if (!$this->_transOverridden) {
            $this->_query->commit();
        }
        return $transaction;
    }
    /**
     * Voids the given transaction.
     *
     * @param  Transaction $transaction Transaction to be voided
     *
     * @return Transaction              The voided transaction
     *
     * @throws \InvalidArgumentException If transaction is already voided
     */
    public function void(Transaction $transaction)
    {
        if ($transaction->isVoided()) {
            throw new \InvalidArgumentException('Transaction has already been voided.');
        }
        $transaction->voidedAt = new DateTimeImmutable();
        $transaction->voidedBy = $this->_user->id;
        $result = $this->_query->run('
			UPDATE
				transaction
			SET
				voided_at = :at?d,
				voided_by = :by?in
			WHERE
				transaction_id = :id?i
		', ['at' => $transaction->voidedAt, 'by' => $transaction->voidedBy, 'id' => $transaction->id]);
        $event = new Event\TransactionalEvent($transaction);
        $event->setDbTransaction($this->_query);
        $transaction = $this->_eventDispatcher->dispatch(Events::VOID, $event)->getTransaction();
        if (!$this->_transOverridden) {
            $this->_query->commit();
        }
        return $transaction;
    }