56 lines
1.7 KiB
PHP
56 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Actions\Discounts;
|
|
|
|
use App\Contracts\Action;
|
|
use App\Contracts\ActionInput;
|
|
use App\Models\Discount;
|
|
use App\Models\Product;
|
|
use Illuminate\Support\Carbon;
|
|
use Webmozart\Assert\Assert;
|
|
|
|
/**
|
|
* @implements \App\Contracts\Action<\App\Actions\Discounts\CreateDiscountInput, \App\Models\Discount>
|
|
*/
|
|
final class CreateDiscount implements Action
|
|
{
|
|
/**
|
|
* @param \App\Actions\Discounts\CreateDiscountInput $input
|
|
*/
|
|
public function __invoke(ActionInput $input): Discount
|
|
{
|
|
Assert::isInstanceOf($input, CreateDiscountInput::class);
|
|
|
|
$discount = new Discount();
|
|
$discount->type = $input->type;
|
|
$discount->value = $input->value;
|
|
$discount->is_old_price_displayed = $input->is_old_price_displayed;
|
|
$discount->date_start = $input->period->start !== null ? Carbon::instance($input->period->start) : null;
|
|
$discount->date_end = $input->period->end !== null ? Carbon::instance($input->period->end) : null;
|
|
|
|
$discount->saveOrFail();
|
|
|
|
$this->syncAssociatedProducts($discount, $input->associatedProductsIds);
|
|
|
|
return $discount;
|
|
}
|
|
|
|
/**
|
|
* @param array<string> $productIdList
|
|
*/
|
|
private function syncAssociatedProducts(Discount $discount, array $productIdList): void
|
|
{
|
|
Product::query()
|
|
->where('discount_id', $discount->id)
|
|
->whereNotIn('id', $productIdList)
|
|
->update(['discount_id' => null]);
|
|
|
|
if (! empty($productIdList)) {
|
|
Product::query()
|
|
->whereIn('id', $productIdList)
|
|
->update(['discount_id' => $discount->id]);
|
|
}
|
|
}
|
|
}
|