diff --git a/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php b/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php index 8f3664cf9..d172ce65b 100644 --- a/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php +++ b/packages/Webkul/Admin/src/DataGrids/ProductDataGrid.php @@ -53,6 +53,10 @@ class ProductDataGrid extends DataGrid $queryBuilder->where('channel', $this->channel); } + if ($currentLocale = app()->getLocale()) { + $queryBuilder->where('product_flat.locale', $currentLocale); + } + $queryBuilder->groupBy('product_flat.product_id'); $this->addFilter('product_id', 'product_flat.product_id'); diff --git a/packages/Webkul/BookingProduct/src/Database/Migrations/2020_06_08_161708_add_sale_prices_to_booking_product_event_tickets.php b/packages/Webkul/BookingProduct/src/Database/Migrations/2020_06_08_161708_add_sale_prices_to_booking_product_event_tickets.php new file mode 100644 index 000000000..3632937cd --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Database/Migrations/2020_06_08_161708_add_sale_prices_to_booking_product_event_tickets.php @@ -0,0 +1,36 @@ +decimal('special_price', 12,4)->after('qty')->nullable(); + $table->dateTime('special_price_from')->after('special_price')->nullable(); + $table->dateTime('special_price_to')->after('special_price_from')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('booking_product_event_tickets', function (Blueprint $table) { + $table->dropColumn('special_price'); + $table->dropColumn('special_price_from'); + $table->dropColumn('special_price_to'); + }); + } +} diff --git a/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php b/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php index d7bda887e..f1116614f 100644 --- a/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php +++ b/packages/Webkul/BookingProduct/src/Helpers/EventTicket.php @@ -47,10 +47,19 @@ class EventTicket extends Booking public function formatPrice($tickets) { foreach ($tickets as $index => $ticket) { + $price = $ticket->price; + + if ($this->isInSale($ticket)) { + $price = $ticket->special_price; + + $tickets[$index]['original_converted_price'] = core()->convertPrice($ticket->price); + $tickets[$index]['original_formated_price'] = core()->currency($ticket->price); + } + $tickets[$index]['id'] = $ticket->id; - $tickets[$index]['converted_price'] = core()->convertPrice($ticket->price); - $tickets[$index]['formated_price'] = $formatedPrice = core()->currency($ticket->price); - $tickets[$index]['formated_price_text'] = trans('bookingproduct::app.shop.products.per-ticket-price', ['price' => $formatedPrice]); + $tickets[$index]['converted_price'] = core()->convertPrice($price); + $tickets[$index]['formated_price'] = $formatedPrice = core()->currency($price); + $tickets[$index]['formated_price_text'] = __('bookingproduct::app.shop.products.per-ticket-price', ['price' => $formatedPrice]); } return $tickets; @@ -102,10 +111,15 @@ class EventTicket extends Booking $ticket = $bookingProduct->event_tickets()->find($product['additional']['booking']['ticket_id']); - $products[$key]['price'] += core()->convertPrice($ticket->price); - $products[$key]['base_price'] += $ticket->price; - $products[$key]['total'] += (core()->convertPrice($ticket->price) * $products[$key]['quantity']); - $products[$key]['base_total'] += ($ticket->price * $products[$key]['quantity']); + $price = $ticket->price; + if ($this->isInSale($ticket)) { + $price = $ticket->special_price; + } + + $products[$key]['price'] += core()->convertPrice($price); + $products[$key]['base_price'] += $price; + $products[$key]['total'] += (core()->convertPrice($price) * $products[$key]['quantity']); + $products[$key]['base_total'] += ($price * $products[$key]['quantity']); } return $products; @@ -131,9 +145,13 @@ class EventTicket extends Booking return true; } - $price += $ticket->price; + if ($this->isInSale($ticket)) { + $price += $ticket->special_price; + } else { + $price += $ticket->price; + } - if ($price == $item->base_price) { + if ($price === $item->base_price) { return; } @@ -145,4 +163,17 @@ class EventTicket extends Booking $item->save(); } + + /** + * Determines whether a single ticket is in Sale, i.e. has a valid sale price + * + * @return bool + */ + public function isInSale($ticket): bool + { + return $ticket->special_price !== null + && $ticket->special_price > 0.0 + && ($ticket->special_price_from === null || $ticket->special_price_from === '0000-00-00 00:00:00' || $ticket->special_price_from <= Carbon::now()) + && ($ticket->special_price_to === null || $ticket->special_price_to === '0000-00-00 00:00:00' || $ticket->special_price_to > Carbon::now()); + } } \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProductEventTicket.php b/packages/Webkul/BookingProduct/src/Models/BookingProductEventTicket.php index 45be2194b..ec35a5788 100644 --- a/packages/Webkul/BookingProduct/src/Models/BookingProductEventTicket.php +++ b/packages/Webkul/BookingProduct/src/Models/BookingProductEventTicket.php @@ -10,10 +10,13 @@ class BookingProductEventTicket extends TranslatableModel implements BookingProd public $timestamps = false; public $translatedAttributes = ['name', 'description']; - + protected $fillable = [ 'price', 'qty', + 'special_price', + 'special_price_from', + 'special_price_to', 'booking_product_id', ]; } \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Repositories/BookingProductEventTicketRepository.php b/packages/Webkul/BookingProduct/src/Repositories/BookingProductEventTicketRepository.php index cbb19109c..ce0a1a7f2 100644 --- a/packages/Webkul/BookingProduct/src/Repositories/BookingProductEventTicketRepository.php +++ b/packages/Webkul/BookingProduct/src/Repositories/BookingProductEventTicketRepository.php @@ -28,6 +28,31 @@ class BookingProductEventTicketRepository extends Repository if (isset($data['tickets'])) { foreach ($data['tickets'] as $ticketId => $ticketInputs) { + + if ( + ! array_key_exists('special_price', $ticketInputs) + || empty($ticketInputs['special_price']) + || $ticketInputs['special_price'] === '0.0000' + ) { + $ticketInputs['special_price'] = null; + } + + if ( + ! array_key_exists('special_price_from', $ticketInputs) + || empty($ticketInputs['special_price_from']) + || $ticketInputs['special_price_from'] === '0000-00-00 00:00:00' + ) { + $ticketInputs['special_price_from'] = null; + } + + if ( + ! array_key_exists('special_price_to', $ticketInputs) + || empty($ticketInputs['special_price_to']) + || $ticketInputs['special_price_to'] === '0000-00-00 00:00:00' + ) { + $ticketInputs['special_price_to'] = null; + } + if (Str::contains($ticketId, 'ticket_')) { $this->create(array_merge([ 'booking_product_id' => $bookingProduct->id, diff --git a/packages/Webkul/BookingProduct/src/Resources/lang/ar/app.php b/packages/Webkul/BookingProduct/src/Resources/lang/ar/app.php index 836fd1f56..7a841de75 100644 --- a/packages/Webkul/BookingProduct/src/Resources/lang/ar/app.php +++ b/packages/Webkul/BookingProduct/src/Resources/lang/ar/app.php @@ -48,6 +48,9 @@ return [ 'price' => 'السعر', 'quantity' => 'كمية', 'description' => 'وصف', + 'special-price' => 'Special Price', + 'special-price-from' => 'Valid From', + 'special-price-to' => 'Valid Until', 'charged-per' => 'اتهم لكل', 'guest' => 'زائر', 'table' => 'الطاولة', diff --git a/packages/Webkul/BookingProduct/src/Resources/lang/en/app.php b/packages/Webkul/BookingProduct/src/Resources/lang/en/app.php index 34d2f8641..034010f55 100644 --- a/packages/Webkul/BookingProduct/src/Resources/lang/en/app.php +++ b/packages/Webkul/BookingProduct/src/Resources/lang/en/app.php @@ -48,6 +48,9 @@ return [ 'price' => 'Price', 'quantity' => 'Quantity', 'description' => 'Description', + 'special-price' => 'Special Price', + 'special-price-from' => 'Valid From', + 'special-price-to' => 'Valid Until', 'charged-per' => 'Charged Per', 'guest' => 'Guest', 'table' => 'Table', diff --git a/packages/Webkul/BookingProduct/src/Resources/lang/fa/app.php b/packages/Webkul/BookingProduct/src/Resources/lang/fa/app.php index a504d439a..629a375ee 100644 --- a/packages/Webkul/BookingProduct/src/Resources/lang/fa/app.php +++ b/packages/Webkul/BookingProduct/src/Resources/lang/fa/app.php @@ -48,6 +48,9 @@ return [ 'price' => 'قیمت', 'quantity' => 'تعداد', 'description' => 'شرح', + 'special-price' => 'Special Price', + 'special-price-from' => 'Valid From', + 'special-price-to' => 'Valid Until', 'charged-per' => 'به اتهام در هر', 'guest' => 'مهمان', 'table' => 'جدول', diff --git a/packages/Webkul/BookingProduct/src/Resources/lang/it/app.php b/packages/Webkul/BookingProduct/src/Resources/lang/it/app.php index 924a89c5b..657b49db9 100644 --- a/packages/Webkul/BookingProduct/src/Resources/lang/it/app.php +++ b/packages/Webkul/BookingProduct/src/Resources/lang/it/app.php @@ -48,6 +48,9 @@ return [ 'price' => 'Prezzo', 'quantity' => 'Quantità', 'description' => 'Descrizione', + 'special-price' => 'Special Price', + 'special-price-from' => 'Valid From', + 'special-price-to' => 'Valid Until', 'charged-per' => 'Charged Per', 'guest' => 'Ospite', 'table' => 'Tavolo', diff --git a/packages/Webkul/BookingProduct/src/Resources/lang/nl/app.php b/packages/Webkul/BookingProduct/src/Resources/lang/nl/app.php index 59703e11a..a557dc9bf 100644 --- a/packages/Webkul/BookingProduct/src/Resources/lang/nl/app.php +++ b/packages/Webkul/BookingProduct/src/Resources/lang/nl/app.php @@ -48,6 +48,9 @@ return [ 'price' => 'Prijs', 'quantity' => 'Aantal stuks', 'description' => 'Beschrijving', + 'special-price' => 'Special Price', + 'special-price-from' => 'Valid From', + 'special-price-to' => 'Valid Until', 'charged-per' => 'In rekening gebracht per', 'guest' => 'Gast', 'table' => 'Tafel', diff --git a/packages/Webkul/BookingProduct/src/Resources/lang/pt_BR/app.php b/packages/Webkul/BookingProduct/src/Resources/lang/pt_BR/app.php index 69dfc7525..afdf84266 100755 --- a/packages/Webkul/BookingProduct/src/Resources/lang/pt_BR/app.php +++ b/packages/Webkul/BookingProduct/src/Resources/lang/pt_BR/app.php @@ -48,6 +48,9 @@ return [ 'price' => 'Preço', 'quantity' => 'Quantidade', 'description' => 'Descrição', + 'special-price' => 'Special Price', + 'special-price-from' => 'Valid From', + 'special-price-to' => 'Valid Until', 'charged-per' => 'Cobrado por', 'guest' => 'Hóspede', 'table' => 'Mesa', diff --git a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/event.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/event.blade.php index d56467c58..c06ebdb23 100644 --- a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/event.blade.php +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/event.blade.php @@ -17,7 +17,7 @@
- +
@@ -26,16 +26,6 @@ -@endpush \ No newline at end of file + +@endpush diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/default/products/view/booking/event.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/default/products/view/booking/event.blade.php index a50adda53..37a1791f8 100644 --- a/packages/Webkul/BookingProduct/src/Resources/views/shop/default/products/view/booking/event.blade.php +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/default/products/view/booking/event.blade.php @@ -25,7 +25,11 @@ @{{ ticket.name }} -
+
+ @{{ ticket.original_formated_price }} + @{{ ticket.formated_price_text }} +
+
@{{ ticket.formated_price_text }}
@@ -62,4 +66,15 @@ + @endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/velocity/products/view/booking/event.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/velocity/products/view/booking/event.blade.php index a50adda53..37a1791f8 100644 --- a/packages/Webkul/BookingProduct/src/Resources/views/shop/velocity/products/view/booking/event.blade.php +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/velocity/products/view/booking/event.blade.php @@ -25,7 +25,11 @@ @{{ ticket.name }} -
+
+ @{{ ticket.original_formated_price }} + @{{ ticket.formated_price_text }} +
+
@{{ ticket.formated_price_text }}
@@ -62,4 +66,15 @@ + @endpush \ No newline at end of file diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index ba234fcea..012379ee8 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -20,10 +20,11 @@ modules: connection_timeout: 60 request_timeout: 60 log_js_errors: true - - Laravel5: + - Webkul\Core\Helpers\Laravel5Helper: part: ORM cleanup: false environment_file: .env database_seeder_class: DatabaseSeeder url: http://nginx + step_decorators: ~ \ No newline at end of file diff --git a/tests/acceptance/BookingProduct/BookingProductEventTicketCest.php b/tests/acceptance/BookingProduct/BookingProductEventTicketCest.php new file mode 100644 index 000000000..be5f61de4 --- /dev/null +++ b/tests/acceptance/BookingProduct/BookingProductEventTicketCest.php @@ -0,0 +1,49 @@ +faker = Factory::create(); + } + + public function testSpecialPricesAreShown(AcceptanceTester $I): void + { + $product = $I->haveProduct(Laravel5Helper::VIRTUAL_PRODUCT); + Product::query()->where('id', $product->id)->update(['type' => 'booking']); + + $bookingProduct = $I->have(BookingProduct::class, [ + 'type' => 'event', + 'available_to' => Carbon::now()->addMinutes($this->faker->numberBetween(2, 59))->toDateTimeString(), + 'product_id' => $product->id, + ]); + + $scenario['ticket'] = [ + 'price' => 10, + 'special_price' => 5 + ]; + + $ticket = $I->have(BookingProductEventTicket::class, array_merge( + ['booking_product_id' => $bookingProduct->id], $scenario['ticket']) + ); + + $I->amOnPage($product->url_key); + + $I->see(core()->currency($ticket->price), '//span[@class="regular-price"]'); + $I->see(__('bookingproduct::app.shop.products.per-ticket-price', ['price' => core()->currency($ticket->special_price)]), + '//span[@class="special-price"]'); + + } +} \ No newline at end of file diff --git a/tests/unit/BookingProduct/BookingProductEventTicketCest.php b/tests/unit/BookingProduct/BookingProductEventTicketCest.php new file mode 100644 index 000000000..3c7d413f7 --- /dev/null +++ b/tests/unit/BookingProduct/BookingProductEventTicketCest.php @@ -0,0 +1,358 @@ +typeHelper = app(EventTicket::class); + + $product = $I->haveProduct(Laravel5Helper::VIRTUAL_PRODUCT); + Product::query()->where('id', $product->id)->update(['type' => 'booking']); + + $availableTo = Carbon::now()->addMinutes($I->fake()->numberBetween(2, 59)); + + $this->bookingProduct = $I->have(BookingProduct::class, [ + 'type' => 'event', + 'available_to' => $availableTo->toDateTimeString(), + 'product_id' => $product->id, + ]); + } + + /** + * @param UnitTester $I + * @param Example $scenario + * + * @dataProvider getTestDataForFormatPrice + */ + public function testFormatPrice(UnitTester $I, Example $scenario): void + { + $tickets[] = $I->have(BookingProductEventTicket::class, array_merge( + ['booking_product_id' => $this->bookingProduct->id], $scenario['ticket']) + ); + + $formattedTickets = $this->typeHelper->formatPrice($tickets); + + foreach ($scenario['expectFields'] as $field) { + $I->assertEquals($scenario['expectFields']['converted_price'], $formattedTickets[0]['converted_price']); + } + + } + + /** + * @param UnitTester $I + * @param Example $scenario + * + * @dataProvider getTestDataForAddAdditionalPrices + */ + public function testAddAdditionalPrices(UnitTester $I, Example $scenario): void + { + $ticket = $I->have(BookingProductEventTicket::class, array_merge( + ['booking_product_id' => $this->bookingProduct->id], $scenario['ticket']) + ); + + $inputData = $scenario['inputData']; + $inputData['product_id'] = $this->bookingProduct->product_id; + $inputData['additional']['product_id'] = $this->bookingProduct->product_id; + $inputData['additional']['booking']['ticket_id'] = $ticket->id; + + $addTicketPrices = $this->typeHelper->addAdditionalPrices([$inputData]); + + $I->assertEquals($scenario['expected']['price'], $addTicketPrices[0]['price']); + $I->assertEquals($scenario['expected']['base_price'], $addTicketPrices[0]['base_price']); + $I->assertEquals($scenario['expected']['total'], $addTicketPrices[0]['total']); + $I->assertEquals($scenario['expected']['base_total'], $addTicketPrices[0]['base_total']); + } + + /** + * @param UnitTester $I + * @param Example $scenario + * + * @dataProvider getTestDataForValidateCartItem + */ + public function testValidateCartItem(UnitTester $I, Example $scenario): void + { + $ticket = $I->have(BookingProductEventTicket::class, array_merge( + ['booking_product_id' => $this->bookingProduct->id], $scenario['ticket']) + ); + + $product = Product::query()->find($this->bookingProduct->product_id); + + $data = [ + 'is_buy_now' => 0, + 'product_id' => $product->id, + 'quantity' => $scenario['qty'], + "booking" => [ + "qty" => [ + $ticket->id => $scenario['qty'], + ] + ] + ]; + + $cart = cart()->addProduct($product->id, $data); + $I->assertEquals('booking', $cart->items[0]->type); + + $product->getTypeInstance()->validateCartItem($cart->items[0]); + + $finalPrice = $product->price + $scenario['expected']; + $finalTotal = ($product->price + $scenario['expected']) * $scenario['qty']; + + $I->seeRecord(CartItem::class, [ + 'id' => $cart->items[0]->id, + 'price' => core()->convertPrice($finalPrice), + 'base_price' => $finalPrice, + 'total' => core()->convertPrice($finalTotal), + 'base_total' => $finalTotal, + ]); + } + + /** + * @param UnitTester $I + * @param Example $scenario + * + * @dataProvider getTestDataForHasSalePrice + */ + public function testHasSalePrice(UnitTester $I, Example $scenario): void + { + $ticket = $I->have(BookingProductEventTicket::class, array_merge( + ['booking_product_id' => $this->bookingProduct->id], $scenario['ticket']) + ); + + $I->assertEquals($scenario['expect'], $this->typeHelper->isInSale($ticket)); + } + + /* Data Providers */ + + private function getTestDataForFormatPrice(): array + { + return [ + [ + 'ticket' => ['price' => 10], + 'expectFields' => [ + 'converted_price' => 10, + 'formated_price' => '$10.00', + 'formated_price_text' => '$10.00 Per Ticket' + ] + ], + [ + 'ticket' => ['price' => 20, 'special_price' => 10], + 'expectFields' => [ + 'converted_price' => 10, + 'formated_price' => '$10.00', + 'formated_price_text' => '$10.00 Per Ticket', + 'original_converted_price' => 20, + 'original_formated_price' => '$20.00', + ] + ], + [ + 'ticket' => [ + 'price' => 20, + 'special_price' => 10, + 'special_price_from' => '0000-00-00 00:00:00', + 'special_price_to' => '0000-00-00 00:00:00', + ], + 'expectFields' => [ + 'converted_price' => 10, + 'formated_price' => '$10.00', + 'formated_price_text' => '$10.00 Per Ticket', + 'original_converted_price' => 20, + 'original_formated_price' => '$20.00', + ] + ], + [ + 'ticket' => [ + 'price' => 10, + 'special_price' => 7, + 'special_price_from' => Carbon::yesterday(), + 'special_price_to' => Carbon::now(), + ], + 'expectFields' => [ + 'converted_price' => 10, + 'formated_price' => '$10.00', + 'formated_price_text' => '$10.00 Per Ticket', + ] + ], + ]; + } + + private function getTestDataForAddAdditionalPrices(): array + { + return [ + [ + 'ticket' => ['price' => 5], + 'inputData' => [ + 'quantity' => 1, + 'price' => 10.0, + 'base_price' => 10.0, + 'total' => 10.0, + 'base_total' => 10.0, + 'additional' => [ + 'quantity' => 1, + ] + ], + 'expected' => [ + 'price' => 15.0, + 'base_price' => 15.0, + 'total' => 15.0, + 'base_total' => 15.0, + ] + ], + [ + 'ticket' => ['price' => 20, 'special_price' => 10], + 'inputData' => [ + 'quantity' => 1, + 'price' => 20.0, + 'base_price' => 20.0, + 'total' => 20.0, + 'base_total' => 20.0, + 'additional' => [ + 'quantity' => 1, + ] + ], + 'expected' => [ + 'price' => 30.0, + 'base_price' => 30.0, + 'total' => 30.0, + 'base_total' => 30.0, + ] + ], + [ + 'ticket' => ['price' => 20, 'special_price' => 10], + 'inputData' => [ + 'quantity' => 2, + 'price' => 20.0, + 'base_price' => 20.0, + 'total' => 20.0, + 'base_total' => 20.0, + 'additional' => [ + 'quantity' => 2, + ] + ], + 'expected' => [ + 'price' => 30.0, + 'base_price' => 30.0, + 'total' => 40.0, + 'base_total' => 40.0, + ] + ], + ]; + } + + private function getTestDataForValidateCartItem(): array + { + return [ + [ + 'ticket' => ['price' => 10], + 'qty' => 1, + 'expected' => 10, + ], + [ + 'ticket' => ['price' => 20, 'special_price' => 10], + 'qty' => 1, + 'expected' => 10, + ], + [ + 'ticket' => ['price' => 20, 'special_price' => 10], + 'qty' => 2, + 'expected' => 10 + ], + [ + 'ticket' => [ + 'price' => 20, + 'special_price' => 10, + 'special_price_from' => '0000-00-00 00:00:00', + 'special_price_to' => '0000-00-00 00:00:00', + ], + 'qty' => 2, + 'expected' => 10 + ], + [ + 'ticket' => [ + 'price' => 10, + 'special_price' => 7, + 'special_price_from' => Carbon::yesterday(), + 'special_price_to' => Carbon::now(), + ], + 'qty' => 2, + 'expected' => 10 + ], + ]; + } + + private function getTestDataForHasSalePrice(): array + { + return [ + [ + 'ticket' => [ + 'price' => '10.0000', + 'special_price' => null + ], + 'expect' => false + ], + [ + 'ticket' => [ + 'price' => '10.0000', + 'special_price' => '5.0000' + ], + 'expect' => true + ], + [ + 'ticket' => [ + 'price' => '10.0000', + 'special_price' => '5.0000', + 'special_price_from' => null, + 'special_price_to' => null, + ], + 'expect' => true + ], + [ + 'ticket' => [ + 'price' => '10.0000', + 'special_price' => '5.0000', + 'special_price_from' => '0000-00-00 00:00:00', + 'special_price_to' => '0000-00-00 00:00:00', + ], + 'expect' => true + ], + [ + 'ticket' => [ + 'price' => '10.0000', + 'special_price' => '5.0000', + 'special_price_from' => Carbon::yesterday(), + 'special_price_to' => Carbon::tomorrow(), + ], + 'expect' => true + ], + [ + 'ticket' => [ + 'price' => '10.0000', + 'special_price' => '5.0000', + 'special_price_from' => Carbon::yesterday(), + 'special_price_to' => Carbon::now(), + ], + 'expect' => false + ], + [ + 'ticket' => [ + 'price' => '10.0000', + 'special_price' => '5.0000', + 'special_price_from' => Carbon::now(), + 'special_price_to' => Carbon::tomorrow(), + ], + 'expect' => true + ], + ]; + } + + +}