Как использовать AOP или любое другое решение в Laravel для автоматического вызова другого контроллера изнутри - PullRequest
1 голос
/ 09 марта 2019

Я работаю над бухгалтерским программным обеспечением, где мне нужно создать ваучер, после чего этот ваучер должен быть оплачен сразу после создания, то есть транзакция по этому ваучеру должна быть сделана как дебет с одного счета и зачисление на другой счет.

Итак, я сделал две таблицы как.

  1. ваучеры -> id, сумма, from_account_id, to_account_id
  2. транзакции -> id, account_id, дебет, кредит.

Я создал модель, контроллер для каждого и добавил методы работы CRUD.

Я создал API как для, так и для использования API для операций CRUD.

Итак, настоящая проблема начинается сейчас.

Против одного ваучера произойдут две транзакции. Пример как.

Запись ваучера:

id = auto_generated, сумма = 500, from_account_id = 8, to_account_id = 9

Итак, против этого ваучера я должен записать две транзакции, как показано ниже.

Запись транзакции:

id = auto_generated, дебет = 500, credit = 0, account_id = 8

id = auto_generated, дебет = 0, кредит = 500, account_id = 9.

Теперь я обрабатываю все вышеперечисленное полностью вручную, то есть сначала добавляю ваучер, затем создаю объект двух транзакций и присваиваю значение на основе данных.

Итак, я пишу код для 3 моделей в store методе ваучера. поэтому я должен переписать весь код для добавления транзакции в методе ваучера store. Так есть ли какой-нибудь удобный и менее подверженный коду / ошибкам автоматический вызов обеих транзакций с этим ваучером?

Мне также нужен тот же процесс при обновлении, предположим, я позже обновил свой ваучер, поэтому транзакция за ним должна автоматически обновляться.

1 Ответ

2 голосов
/ 10 марта 2019

Вы должны рассматривать свой контроллер как один из множества интерфейсов, в идеале ваш контроллер должен только заботиться обо всем, что специфично для HTTP.Когда вы пишете код на своем контроллере, подумайте: «Мне когда-нибудь понадобятся эти функции вне этого контроллера?»и если ответ «да», то функциональность принадлежит другому.

В этом случае вы говорите о поведении вашей модели, вы говорите: «Ваучеры (ваша модель) должны быть оплачены (поведение)».Это хороший признак того, что поведение принадлежит вашей модели как методу, который вы можете вызывать либо при создании (с использованием событий), либо по требованию извне.Например, в App\Voucher.php:

/**
* Account that is debited by the voucher.
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function from(): HasOne
{
    return $this->hasOne(Account::class, 'id', 'from_account_id');
}

/**
* Account that is credited by the voucher.
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function to(): HasOne
{
    return $this->hasOne(Account::class, 'id', 'to_account_id');
}

/**
* Credit the voucher amount.
*
* @return void
*/
public function pay(): void
{
    $this->from()->transactions()->create([
        'debit' => $this->amount,
        'credit' => 0,
    ]);

    $this->to()->transactions()->create([
        'debit' => 0,
        'credit' => $this->amount,
    ]);
}

Тогда ваш метод контроллера будет выглядеть примерно так:

/**
* Create the Voucher and pay it out.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request): RedirectResponse
{
    $voucher = Voucher::create([
        'from_account_id' => $request->from,
        'to_account_id' => $request->to,
        'amount' => $request->amount,
    ]);

    $voucher->pay();

    return redirect()->route('vouchers.index')->with([
        'success' => "{$request->amount} has been credited to your recipient."
    ]);
}

Тогда в любой другой момент, когда вам нужно оплатить ваучер, вы можете просто позвонитьметод pay на нем.Если вы хотите, чтобы ваучер выплачивался только при создании, вы можете установить для метода pay значение protected вместо public, а затем использовать прослушиватель событий Eloquent, чтобы вызвать событие created и предотвратить его.от использования в любое другое время.

Что касается обновления ваучеров в дальнейшем: было бы ошибкой допускать, чтобы ваучеры были изменяемыми, но если вы должны это сделать, вы все равно должны рассматривать транзакции как неизменяемые, что означает любое изменение вваучер должен создавать новые транзакции с получателем и отправителем, которые бы равнялись суммам, вы никогда не должны изменять исторические данные транзакции в системе учета.


Примечание: если бы я разрабатывал это, я почти наверняка неЯ делаю это таким образом, но мне нужно лучше понять назначение и функциональность ваших приложений, чтобы правильно их спроектировать, поэтому то, что я привел здесь, - это лучшее усилие, основанное на том, чем вы поделились, но не идеальное решение.

...