Updated event booking system

This commit is contained in:
Jitendra Singh 2020-02-21 19:13:15 +05:30
parent 521fc4b6b6
commit 2e24c2e2e5
38 changed files with 338 additions and 373 deletions

View File

@ -203,9 +203,9 @@
computed: {
inputName: function () {
if (this.groupedProduct.id)
return "links[" + this.groupedProduct.id + "]";
return 'links[' + this.groupedProduct.id + ']';
return "links[link_" + this.index + "]";
return 'links[link_' + this.index + ']';
}
},

View File

@ -77,23 +77,23 @@
@foreach ($customAttributes as $attribute)
<?php
if ($attribute->code == 'guest_checkout' && ! core()->getConfigData('catalog.products.guest-checkout.allow-guest-checkout')) {
continue;
}
if ($attribute->code == 'guest_checkout' && ! core()->getConfigData('catalog.products.guest-checkout.allow-guest-checkout')) {
continue;
}
$validations = [];
$validations = [];
if ($attribute->is_required) {
array_push($validations, 'required');
}
if ($attribute->is_required) {
array_push($validations, 'required');
}
if ($attribute->type == 'price') {
array_push($validations, 'decimal');
}
if ($attribute->type == 'price') {
array_push($validations, 'decimal');
}
array_push($validations, $attribute->validation);
array_push($validations, $attribute->validation);
$validations = implode('|', array_filter($validations));
$validations = implode('|', array_filter($validations));
?>
@if (view()->exists($typeView = 'admin::catalog.products.field-types.' . $attribute->type))

View File

@ -2,6 +2,6 @@
namespace Webkul\BookingProduct\Contracts;
interface BookingProductEventSlot
interface BookingProductEventTicket
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace Webkul\BookingProduct\Contracts;
interface BookingProductEventTicketTranslation
{
}

View File

@ -18,6 +18,9 @@ class CreateBookingProductsTable extends Migration
$table->string('type');
$table->string('location')->nullable();
$table->boolean('show_location')->default(0);
$table->boolean('available_every_week')->nullable();
$table->date('available_from')->nullable();
$table->date('available_to')->nullable();
$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');

View File

@ -16,8 +16,6 @@ class CreateBookingProductDefaultSlotsTable extends Migration
Schema::create('booking_product_default_slots', function (Blueprint $table) {
$table->increments('id');
$table->string('booking_type');
$table->date('available_from')->nullable();
$table->date('available_to')->nullable();
$table->integer('duration')->nullable();
$table->integer('break_time')->nullable();
$table->json('slots')->nullable();

View File

@ -17,9 +17,6 @@ class CreateBookingProductAppointmentSlotsTable extends Migration
$table->increments('id');
$table->integer('duration')->nullable();
$table->integer('break_time')->nullable();
$table->boolean('available_every_week')->nullable();
$table->date('available_from')->nullable();
$table->date('available_to')->nullable();
$table->boolean('slot_has_quantity')->nullable();
$table->boolean('same_slot_all_days')->nullable();
$table->json('slots')->nullable();

View File

@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBookingProductEventSlotsTable extends Migration
class CreateBookingProductEventTicketsTable extends Migration
{
/**
* Run the migrations.
@ -13,11 +13,10 @@ class CreateBookingProductEventSlotsTable extends Migration
*/
public function up()
{
Schema::create('booking_product_event_slots', function (Blueprint $table) {
Schema::create('booking_product_event_tickets', function (Blueprint $table) {
$table->increments('id');
$table->datetime('available_from')->nullable();
$table->datetime('available_to')->nullable();
$table->json('slots')->nullable();
$table->decimal('price', 12, 4)->default(0)->nullable();
$table->integer('qty')->default(0)->nullable();
$table->integer('booking_product_id')->unsigned();
$table->foreign('booking_product_id')->references('id')->on('booking_products')->onDelete('cascade');
@ -31,6 +30,6 @@ class CreateBookingProductEventSlotsTable extends Migration
*/
public function down()
{
Schema::dropIfExists('booking_product_event_slots');
Schema::dropIfExists('booking_product_event_tickets');
}
}

View File

@ -16,11 +16,8 @@ class CreateBookingProductRentalSlotsTable extends Migration
Schema::create('booking_product_rental_slots', function (Blueprint $table) {
$table->increments('id');
$table->string('renting_type');
$table->decimal('daily_price', 12, 4)->default(0)->nullable();;
$table->decimal('hourly_price', 12, 4)->default(0)->nullable();;
$table->boolean('available_every_week')->nullable();
$table->date('available_from')->nullable();
$table->date('available_to')->nullable();
$table->decimal('daily_price', 12, 4)->default(0)->nullable();
$table->decimal('hourly_price', 12, 4)->default(0)->nullable();
$table->boolean('slot_has_quantity')->nullable();
$table->boolean('same_slot_all_days')->nullable();
$table->json('slots')->nullable();

View File

@ -21,9 +21,6 @@ class CreateBookingProductTableSlotsTable extends Migration
$table->integer('duration');
$table->integer('break_time');
$table->integer('prevent_scheduling_before');
$table->boolean('available_every_week')->nullable();
$table->date('available_from')->nullable();
$table->date('available_to')->nullable();
$table->boolean('same_slot_all_days')->nullable();
$table->json('slots')->nullable();

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBookingProductEventTicketTranslationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('booking_product_event_ticket_translations', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('locale');
$table->text('name')->nullable();
$table->text('description')->nullable();
$table->integer('booking_product_event_ticket_id')->unsigned();
$table->unique(['booking_product_event_ticket_id', 'locale'], 'booking_product_event_ticket_translations_locale_unique');
$table->foreign('booking_product_event_ticket_id', 'booking_product_event_ticket_translations_locale_foreign')->references('id')->on('booking_product_event_tickets')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('booking_product_event_ticket_translations');
}
}

View File

@ -6,7 +6,7 @@ use Carbon\Carbon;
use Webkul\BookingProduct\Repositories\BookingProductRepository;
use Webkul\BookingProduct\Repositories\BookingProductDefaultSlotRepository;
use Webkul\BookingProduct\Repositories\BookingProductAppointmentSlotRepository;
use Webkul\BookingProduct\Repositories\BookingProductEventSlotRepository;
use Webkul\BookingProduct\Repositories\BookingProductEventTicketRepository;
use Webkul\BookingProduct\Repositories\BookingProductRentalSlotRepository;
use Webkul\BookingProduct\Repositories\BookingProductTableSlotRepository;
@ -36,7 +36,7 @@ class Booking
protected $typeHelpers = [
'default' => DefaultSlot::class,
'appointment' => AppointmentSlot::class,
'event' => EventSlot::class,
'event' => EventTicket::class,
'rental' => RentalSlot::class,
'table' => TableSlot::class,
];
@ -52,7 +52,7 @@ class Booking
* @param Webkul\BookingProduct\Repositories\BookingProductRepository $bookingProductRepository
* @param Webkul\BookingProduct\Repositories\BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductEventSlotRepository $bookingProductEventSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductEventTicketRepository $bookingProductEventTicketRepository
* @param Webkul\BookingProduct\Repositories\BookingProductRentalSlotRepository $bookingProductRentalSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductTableSlotRepository $bookingProductTableSlotRepository
* @return void
@ -61,7 +61,7 @@ class Booking
BookingProductRepository $bookingProductRepository,
BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository,
BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository,
BookingProductEventSlotRepository $bookingProductEventSlotRepository,
BookingProductEventTicketRepository $bookingProductEventTicketRepository,
BookingProductRentalSlotRepository $bookingProductRentalSlotRepository,
BookingProductTableSlotRepository $bookingProductTableSlotRepository
)
@ -72,7 +72,7 @@ class Booking
$this->typeRepositories['appointment'] = $bookingProductAppointmentSlotRepository;
$this->typeRepositories['event'] = $bookingProductEventSlotRepository;
$this->typeRepositories['event'] = $bookingProductEventTicketRepository;
$this->typeRepositories['rental'] = $bookingProductRentalSlotRepository;
@ -102,7 +102,7 @@ class Booking
$bookingProductSlot = $this->typeRepositories[$bookingProduct->type]->findOneByField('booking_product_id', $bookingProduct->id);
$availabileDays = $this->getAvailableWeekDays($bookingProductSlot);
$availabileDays = $this->getAvailableWeekDays($bookingProduct);
foreach ($this->daysOfWeek as $index => $isOpen) {
$slots = [];
@ -155,12 +155,12 @@ class Booking
/**
* Returns the available week days
*
* @param Object $bookingProductSlot
* @param Object $bookingProduct
* @return array
*/
public function getAvailableWeekDays($bookingProductSlot)
public function getAvailableWeekDays($bookingProduct)
{
if ($bookingProductSlot->available_every_week) {
if ($bookingProduct->available_every_week) {
return $this->daysOfWeek;
}
@ -168,9 +168,9 @@ class Booking
$currentTime = Carbon::now();
$availableFrom = Carbon::createFromTimeString($bookingProductSlot->available_from . " 00:00:01");
$availableFrom = Carbon::createFromTimeString($bookingProduct->available_from . " 00:00:01");
$availableTo = Carbon::createFromTimeString($bookingProductSlot->available_to . " 23:59:59");
$availableTo = Carbon::createFromTimeString($bookingProduct->available_to . " 23:59:59");
for ($i = 0; $i < 7; $i++) {
$date = clone $currentTime;
@ -246,13 +246,13 @@ class Booking
$currentTime = Carbon::now();
$availableFrom = ! $bookingProductSlot->available_every_week
? Carbon::createFromTimeString($bookingProductSlot->available_from . " 00:00:00")
: Carbon::createFromTimeString($currentTime->format('Y-m-d') . ' 00:00:00');
$availableFrom = ! $bookingProduct->available_every_week && $bookingProduct->available_from
? Carbon::createFromTimeString($bookingProduct->available_from . " 00:00:00")
: Carbon::createFromTimeString($currentTime->format('Y-m-d') . ' 00:00:00');
$availableTo = ! $bookingProductSlot->available_every_week
? Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59')
: Carbon::createFromTimeString('2080-01-01 00:00:00');
$availableTo = ! $bookingProduct->available_every_week && $bookingProduct->available_from
? Carbon::createFromTimeString($bookingProduct->available_to . ' 23:59:59')
: Carbon::createFromTimeString('2080-01-01 00:00:00');
$timeDurations = $bookingProductSlot->same_slot_all_days
? $bookingProductSlot->slots
@ -328,6 +328,12 @@ class Booking
}
switch ($bookingProduct->type) {
case 'event':
dd($data, $bookingProduct->event_tickets);
break;
case 'rental':
$rentingType = $data['booking']['renting_type'] ?? $bookingProduct->rental_slot->renting_type;

View File

@ -32,13 +32,17 @@ class DefaultSlot extends Booking
return [];
}
$requestedDate = Carbon::createFromTimeString($date . " 00:00:00");
$requestedDate = Carbon::createFromTimeString($date . ' 00:00:00');
$currentTime = Carbon::now();
$availableFrom = Carbon::createFromTimeString($bookingProductSlot->available_from . " 00:00:00");
$availableFrom = ! $bookingProduct->available_from && $bookingProduct->available_from
? Carbon::createFromTimeString($bookingProduct->available_from . ' 00:00:00')
: clone $currentTime;
$availableTo = Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59');
$availableTo = ! $bookingProduct->available_from && $bookingProduct->available_to
? Carbon::createFromTimeString($bookingProduct->available_to . ' 23:59:59')
: Carbon::createFromTimeString('2080-01-01 00:00:00');
if ($requestedDate < $currentTime
|| $requestedDate < $availableFrom
@ -91,11 +95,17 @@ class DefaultSlot extends Booking
*/
public function getManyBookingsforOneDaySlots($bookingProductSlot, $requestedDate)
{
$bookingProduct = $bookingProductSlot->booking_product;
$currentTime = Carbon::now();
$availableFrom = Carbon::createFromTimeString($bookingProductSlot->available_from . ' 00:00:00');
$availableFrom = ! $bookingProduct->available_from && $bookingProduct->available_from
? Carbon::createFromTimeString($bookingProduct->available_from . ' 00:00:00')
: clone $currentTime;
$availableTo = Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59');
$availableTo = ! $bookingProduct->available_from && $bookingProduct->available_to
? Carbon::createFromTimeString($bookingProduct->available_to . ' 23:59:59')
: Carbon::createFromTimeString('2080-01-01 00:00:00');
$timeDuration = $bookingProductSlot->slots[$requestedDate->format('w')] ?? [];

View File

@ -5,12 +5,12 @@ namespace Webkul\BookingProduct\Helpers;
use Carbon\Carbon;
/**
* EventSlot Helper
* EventTicket Helper
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class EventSlot extends Booking
class EventTicket extends Booking
{
/**
* Returns event date
@ -20,9 +20,9 @@ class EventSlot extends Booking
*/
public function getEventDate($bookingProduct)
{
$from = Carbon::createFromTimeString($bookingProduct->event_slot->available_from)->format('d F, Y h:i A');
$from = Carbon::createFromTimeString($bookingProduct->available_from)->format('d F, Y h:i A');
$to = Carbon::createFromTimeString($bookingProduct->event_slot->available_to)->format('d F, Y h:i A');
$to = Carbon::createFromTimeString($bookingProduct->available_to)->format('d F, Y h:i A');
return $from . ' - ' . $to;
}
@ -35,11 +35,11 @@ class EventSlot extends Booking
*/
public function getTickets($bookingProduct)
{
if (! $bookingProduct->event_slot) {
if (! $bookingProduct->event_tickets()->count()) {
return;
}
return $this->formatPrice($bookingProduct->event_slot->slots);
return $this->formatPrice($bookingProduct->event_tickets);
}
/**
@ -51,8 +51,8 @@ class EventSlot extends Booking
public function formatPrice($tickets)
{
foreach ($tickets as $index => $ticket) {
$tickets[$index]['converted_price'] = core()->convertPrice($ticket['price']);
$tickets[$index]['formated_price'] = $formatedPrice = core()->currency($ticket['price']);
$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]);
}

View File

@ -31,13 +31,13 @@ class RentalSlot extends Booking
$currentTime = Carbon::now();
$availableFrom = ! $bookingProductSlot->available_every_week
? Carbon::createFromTimeString($bookingProductSlot->available_from . ' 00:00:00')
: Carbon::createFromTimeString($currentTime->format('Y-m-d') . ' 00:00:00');
$availableFrom = ! $bookingProduct->available_every_week && $bookingProduct->available_from
? Carbon::createFromTimeString($bookingProduct->available_from . ' 00:00:00')
: Carbon::createFromTimeString($currentTime->format('Y-m-d') . ' 00:00:00');
$availableTo = ! $bookingProductSlot->available_every_week
? Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59')
: Carbon::createFromTimeString('2080-01-01 00:00:00');
$availableTo = ! $bookingProduct->available_every_week && $bookingProduct->available_from
? Carbon::createFromTimeString($bookingProduct->available_to . ' 23:59:59')
: Carbon::createFromTimeString('2080-01-01 00:00:00');
$timeDurations = $bookingProductSlot->same_slot_all_days
? $bookingProductSlot->slots

View File

@ -6,7 +6,7 @@ use Webkul\BookingProduct\Repositories\BookingProductRepository;
use Webkul\BookingProduct\Helpers\DefaultSlot as DefaultSlotHelper;
use Webkul\BookingProduct\Helpers\AppointmentSlot as AppointmentSlotHelper;
use Webkul\BookingProduct\Helpers\RentalSlot as RentalSlotHelper;
use Webkul\BookingProduct\Helpers\EventSlot as EventSlotHelper;
use Webkul\BookingProduct\Helpers\EventTicket as EventTicketHelper;
use Webkul\BookingProduct\Helpers\TableSlot as TableSlotHelper;
/**
@ -36,7 +36,7 @@ class BookingProductController extends Controller
* @param Webkul\BookingProduct\Helpers\DefaultSlot $defaultSlotHelper
* @param Webkul\BookingProduct\Helpers\AppointmentSlot $appointmentSlotHelper
* @param Webkul\BookingProduct\Helpers\RentalSlot $rentalSlotHelper
* @param Webkul\BookingProduct\Helpers\EventSlot $eventSlotHelper
* @param Webkul\BookingProduct\Helpers\EventTicket $EventTicketHelper
* @param Webkul\BookingProduct\Helpers\TableSlot $tableSlotHelper
* @return void
*/
@ -45,7 +45,7 @@ class BookingProductController extends Controller
DefaultSlotHelper $defaultSlotHelper,
AppointmentSlotHelper $appointmentSlotHelper,
RentalSlotHelper $rentalSlotHelper,
EventSlotHelper $eventSlotHelper,
EventTicketHelper $eventTicketHelper,
TableSlotHelper $tableSlotHelper
)
{
@ -57,7 +57,7 @@ class BookingProductController extends Controller
$this->bookingHelpers['rental'] = $rentalSlotHelper;
$this->bookingHelpers['event'] = $eventSlotHelper;
$this->bookingHelpers['event'] = $eventTicketHelper;
$this->bookingHelpers['table'] = $tableSlotHelper;
}

View File

@ -1,54 +0,0 @@
<?php
namespace Webkul\BookingProduct\Listeners;
use Webkul\BookingProduct\Repositories\BookingProductRepository;
/**
* Product Event handler
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class Product
{
/**
* BookingProductRepository Object
*
* @var Object
*/
protected $bookingProductRepository;
/**
* Create a new listener instance.
*
* @param Webkul\BookingProduct\Repositories\BookingProductRepository $bookingProductRepository
* @return void
*/
public function __construct(BookingProductRepository $bookingProductRepository)
{
$this->bookingProductRepository = $bookingProductRepository;
}
/**
* After the product is updated
*
* @return void
*/
public function afterProductUpdated($product)
{
if ($product->type != 'booking' || ! request('booking')) {
return;
}
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $product->id);
if ($bookingProduct) {
$this->bookingProductRepository->update(request('booking'), $bookingProduct->id);
} else {
$this->bookingProductRepository->create(array_merge(request('booking'), [
'product_id' => $product->id
]));
}
}
}

View File

@ -8,9 +8,9 @@ use Webkul\BookingProduct\Contracts\BookingProduct as BookingProductContract;
class BookingProduct extends Model implements BookingProductContract
{
protected $fillable = ['location', 'show_location', 'type', 'product_id'];
protected $fillable = ['location', 'show_location', 'type', 'available_every_week', 'available_from', 'available_to', 'product_id'];
protected $with = ['default_slot', 'appointment_slot', 'event_slot', 'rental_slot', 'table_slot'];
protected $with = ['default_slot', 'appointment_slot', 'event_tickets', 'rental_slot', 'table_slot'];
/**
* The Product Default Booking that belong to the product booking.
@ -31,9 +31,9 @@ class BookingProduct extends Model implements BookingProductContract
/**
* The Product Event Booking that belong to the product booking.
*/
public function event_slot()
public function event_tickets()
{
return $this->hasOne(BookingProductEventSlotProxy::modelClass());
return $this->hasMany(BookingProductEventTicketProxy::modelClass());
}
/**

View File

@ -13,7 +13,7 @@ class BookingProductDefaultSlot extends Model implements BookingProductDefaultSl
protected $casts = ['slots' => 'array'];
protected $fillable = ['booking_type', 'duration', 'break_time', 'available_from', 'available_to', 'slots', 'booking_product_id'];
protected $fillable = ['booking_type', 'duration', 'break_time', 'slots', 'booking_product_id'];
/**
* Get the product that owns the attribute value.

View File

@ -1,15 +0,0 @@
<?php
namespace Webkul\BookingProduct\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\BookingProduct\Contracts\BookingProductEventSlot as BookingProductEventSlotContract;
class BookingProductEventSlot extends Model implements BookingProductEventSlotContract
{
public $timestamps = false;
protected $casts = ['slots' => 'array'];
protected $fillable = ['available_from', 'available_to', 'slots', 'booking_product_id'];
}

View File

@ -0,0 +1,15 @@
<?php
namespace Webkul\BookingProduct\Models;
use Webkul\Core\Eloquent\TranslatableModel;
use Webkul\BookingProduct\Contracts\BookingProductEventTicket as BookingProductEventTicketContract;
class BookingProductEventTicket extends TranslatableModel implements BookingProductEventTicketContract
{
public $timestamps = false;
public $translatedAttributes = ['name', 'description'];
protected $fillable = ['price', 'qty', 'booking_product_id'];
}

View File

@ -4,7 +4,7 @@ namespace Webkul\BookingProduct\Models;
use Konekt\Concord\Proxies\ModelProxy;
class BookingProductEventSlotProxy extends ModelProxy
class BookingProductEventTicketProxy extends ModelProxy
{
}

View File

@ -0,0 +1,13 @@
<?php
namespace Webkul\BookingProduct\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\BookingProduct\Contracts\BookingProductEventTicketTranslation as BookingProductEventTicketTranslationContract;
class BookingProductEventTicketTranslation extends Model implements BookingProductEventTicketTranslationContract
{
public $timestamps = false;
protected $fillable = ['name', 'description'];
}

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\BookingProduct\Models;
use Konekt\Concord\Proxies\ModelProxy;
class BookingProductEventTicketTranslationProxy extends ModelProxy
{
}

View File

@ -11,5 +11,5 @@ class BookingProductTableSlot extends Model implements BookingProductTableSlotCo
protected $casts = ['slots' => 'array'];
protected $fillable = ['price_type', 'guest_limit', 'guest_capacity', 'duration', 'break_time', 'prevent_scheduling_before', 'available_every_week', 'available_from', 'available_to', 'same_slot_all_days', 'slots', 'booking_product_id'];
protected $fillable = ['price_type', 'guest_limit', 'guest_capacity', 'duration', 'break_time', 'prevent_scheduling_before', 'available_every_week', 'same_slot_all_days', 'slots', 'booking_product_id'];
}

View File

@ -17,7 +17,5 @@ class EventServiceProvider extends ServiceProvider
Event::listen('bagisto.shop.products.view.short_description.after', function($viewRenderEventManager) {
$viewRenderEventManager->addTemplate('bookingproduct::shop.products.view.booking');
});
Event::listen('catalog.product.update.after', 'Webkul\BookingProduct\Listeners\Product@afterProductUpdated');
}
}

View File

@ -10,7 +10,8 @@ class ModuleServiceProvider extends BaseModuleServiceProvider
\Webkul\BookingProduct\Models\BookingProduct::class,
\Webkul\BookingProduct\Models\BookingProductDefaultSlot::class,
\Webkul\BookingProduct\Models\BookingProductAppointmentSlot::class,
\Webkul\BookingProduct\Models\BookingProductEventSlot::class,
\Webkul\BookingProduct\Models\BookingProductEventTicket::class,
\Webkul\BookingProduct\Models\BookingProductEventTicketTranslation::class,
\Webkul\BookingProduct\Models\BookingProductRentalSlot::class,
\Webkul\BookingProduct\Models\BookingProductTableSlot::class,
\Webkul\BookingProduct\Models\Booking::class

View File

@ -1,24 +0,0 @@
<?php
namespace Webkul\BookingProduct\Repositories;
use Webkul\Core\Eloquent\Repository;
/**
* BookingProductEventSlot Repository
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class BookingProductEventSlotRepository extends Repository
{
/**
* Specify Model class name
*
* @return mixed
*/
function model()
{
return 'Webkul\BookingProduct\Contracts\BookingProductEventSlot';
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Webkul\BookingProduct\Repositories;
use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Str;
/**
* BookingProductEventTicket Repository
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class BookingProductEventTicketRepository extends Repository
{
/**
* Specify Model class name
*
* @return mixed
*/
function model()
{
return 'Webkul\BookingProduct\Contracts\BookingProductEventTicket';
}
/**
* @param array $data
* @param BookingProduct $bookingProduct
* @return void
*/
public function saveEventTickets($data, $bookingProduct)
{
$previousTicketIds = $bookingProduct->event_tickets()->pluck('id');
if (isset($data['tickets'])) {
foreach ($data['tickets'] as $ticketId => $ticketInputs) {
if (Str::contains($ticketId, 'ticket_')) {
$this->create(array_merge([
'booking_product_id' => $bookingProduct->id,
], $ticketInputs));
} else {
if (is_numeric($index = $previousTicketIds->search($ticketId))) {
$previousTicketIds->forget($index);
}
$this->update($ticketInputs, $ticketId);
}
}
}
foreach ($previousTicketIds as $previousTicketId) {
$this->delete($previousTicketId);
}
}
}

View File

@ -23,7 +23,7 @@ class BookingProductRepository extends Repository
*
* @param Webkul\BookingProduct\Repositories\BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductEventSlotRepository $bookingProductEventSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductEventTicketRepository $bookingProductEventTicketRepository
* @param Webkul\BookingProduct\Repositories\BookingProductRentalSlotRepository $bookingProductRentalSlotRepository
* @param Webkul\BookingProduct\Repositories\BookingProductTableSlotRepository $bookingProductTableSlotRepository
* @return void
@ -31,7 +31,7 @@ class BookingProductRepository extends Repository
public function __construct(
BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository,
BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository,
BookingProductEventSlotRepository $bookingProductEventSlotRepository,
BookingProductEventTicketRepository $bookingProductEventTicketRepository,
BookingProductRentalSlotRepository $bookingProductRentalSlotRepository,
BookingProductTableSlotRepository $bookingProductTableSlotRepository,
App $app
@ -43,7 +43,7 @@ class BookingProductRepository extends Repository
$this->typeRepositories['appointment'] = $bookingProductAppointmentSlotRepository;
$this->typeRepositories['event'] = $bookingProductEventSlotRepository;
$this->typeRepositories['event'] = $bookingProductEventTicketRepository;
$this->typeRepositories['rental'] = $bookingProductRentalSlotRepository;
@ -68,7 +68,11 @@ class BookingProductRepository extends Repository
{
$bookingProduct = parent::create($data);
$this->typeRepositories[$data['type']]->create(array_merge($data, ['booking_product_id' => $bookingProduct->id]));
if ($bookingProduct->type == 'event') {
$this->typeRepositories[$data['type']]->saveEventTickets($data, $bookingProduct);
} else {
$this->typeRepositories[$data['type']]->create(array_merge($data, ['booking_product_id' => $bookingProduct->id]));
}
return $bookingProduct;
}
@ -81,7 +85,7 @@ class BookingProductRepository extends Repository
*/
public function update(array $data, $id, $attribute = "id")
{
parent::update($data, $id, $attribute);
$bookingProduct = parent::update($data, $id, $attribute);
foreach ($this->typeRepositories as $type => $repository) {
if ($type == $data['type']) {
@ -91,16 +95,20 @@ class BookingProductRepository extends Repository
$repository->deleteWhere(['booking_product_id' => $id]);
}
$bookingProductTypeSlot = $this->typeRepositories[$data['type']]->findOneByField('booking_product_id', $id);
if (isset($data['slots'])) {
$data['slots'] = $this->formatSlots($data);
}
if (! $bookingProductTypeSlot) {
$this->typeRepositories[$data['type']]->create(array_merge($data, ['booking_product_id' => $id]));
if ($bookingProduct->type == 'event') {
$this->typeRepositories[$data['type']]->saveEventTickets($data, $bookingProduct);
} else {
$this->typeRepositories[$data['type']]->update($data, $bookingProductTypeSlot->id);
$bookingProductTypeSlot = $this->typeRepositories[$data['type']]->findOneByField('booking_product_id', $id);
if (isset($data['slots'])) {
$data['slots'] = $this->formatSlots($data);
}
if (! $bookingProductTypeSlot) {
$this->typeRepositories[$data['type']]->create(array_merge($data, ['booking_product_id' => $id]));
} else {
$this->typeRepositories[$data['type']]->update($data, $bookingProductTypeSlot->id);
}
}
}

View File

@ -37,6 +37,41 @@
<input type="text" name="booking[location]" v-model="location" class="control"/>
</div>
<div v-if="booking_type == 'appointment' || booking_type == 'event' || booking_type == 'rental' || booking_type == 'table'">
<div class="control-group" v-if="booking_type != 'event'" :class="[errors.has('booking[available_every_week]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}</label>
<select v-validate="'required'" name="booking[available_every_week]" v-model="available_every_week" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}&quot;">
<option value="1">{{ __('bookingproduct::app.admin.catalog.products.yes') }}</option>
<option value="0">{{ __('bookingproduct::app.admin.catalog.products.no') }}</option>
</select>
<span class="control-error" v-if="errors.has('booking[available_every_week]')">@{{ errors.first('booking[available_every_week]') }}</span>
</div>
<div v-if="! parseInt(available_every_week)">
<div class="control-group" :class="[errors.has('booking[available_from]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-from') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_from]" v-model="available_from" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-from') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_from]')">@{{ errors.first('booking[available_from]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_to]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-to') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_to]" v-model="available_to" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-to') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_to]')">@{{ errors.first('booking[available_to]') }}</span>
</div>
</div>
</div>
<div class="default-booking-section" v-if="booking_type == 'default'">
@include ('bookingproduct::admin.catalog.products.accordians.booking.default', ['bookingProduct' => $bookingProduct])
</div>
@ -73,7 +108,13 @@
return {
booking_type: bookingProduct ? bookingProduct.type : 'default',
location: ''
location: '',
available_every_week: bookingProduct.available_every_week,
available_from: bookingProduct.available_from,
available_to: bookingProduct.available_to
}
}
});

View File

@ -25,39 +25,6 @@
<span class="control-error" v-if="errors.has('booking[break_time]')">@{{ errors.first('booking[break_time]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_every_week]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}</label>
<select v-validate="'required'" name="booking[available_every_week]" v-model="appointment_booking.available_every_week" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}&quot;">
<option value="1">{{ __('bookingproduct::app.admin.catalog.products.yes') }}</option>
<option value="0">{{ __('bookingproduct::app.admin.catalog.products.no') }}</option>
</select>
<span class="control-error" v-if="errors.has('booking[available_every_week]')">@{{ errors.first('booking[available_every_week]') }}</span>
</div>
<div v-if="! parseInt(appointment_booking.available_every_week)">
<div class="control-group" :class="[errors.has('booking[available_from]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-from') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_from]" v-model="appointment_booking.available_from" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-from') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_from]')">@{{ errors.first('booking[available_from]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_to]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-to') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_to]" v-model="appointment_booking.available_to" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-to') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_to]')">@{{ errors.first('booking[available_to]') }}</span>
</div>
</div>
<div class="control-group" :class="[errors.has('booking[slot_has_quantity]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.slot-has-quantity') }}</label>
@ -112,12 +79,6 @@
break_time: 15,
available_every_week: 1,
available_from: '',
available_to: '',
same_slot_all_days: 1,
slot_has_quantity: 1,

View File

@ -37,26 +37,6 @@
<span class="control-error" v-if="errors.has('booking[booking_type]')">@{{ errors.first('booking[booking_type]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_from]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-from') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_from]" v-model="default_booking.available_from" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-from') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_from]')">@{{ errors.first('booking[available_from]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_to]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-to') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_to]" v-model="default_booking.available_to" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-to') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_to]')">@{{ errors.first('booking[available_to]') }}</span>
</div>
<div v-if="default_booking.booking_type == 'many'">
<div class="control-group" :class="[errors.has('booking[duration]') ? 'has-error' : '']">
@ -238,10 +218,6 @@
break_time: 15,
available_from: '',
available_to: '',
slots: []
},

View File

@ -9,26 +9,6 @@
<script type="text/x-template" id="event-booking-template">
<div>
<div class="control-group" :class="[errors.has('booking[available_from]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.event-start-date') }}</label>
<datetime>
<input type="text" v-validate="'required'" name="booking[available_from]" v-model="event_booking.available_from" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.event-start-date') }}&quot;"/>
</datetime>
<span class="control-error" v-if="errors.has('booking[available_from]')">@{{ errors.first('booking[available_from]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_to]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.event-end-date') }}</label>
<datetime>
<input type="text" v-validate="'required'" name="booking[available_to]" v-model="event_booking.available_to" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.event-end-date') }}&quot;"/>
</datetime>
<span class="control-error" v-if="errors.has('booking[available_to]')">@{{ errors.first('booking[available_to]') }}</span>
</div>
<div class="section">
<div class="secton-title">
<span>{{ __('bookingproduct::app.admin.catalog.products.tickets') }}</span>
@ -36,7 +16,7 @@
<div class="section-content">
<ticket-list :tickets="event_booking.slots"></ticket-list>
<ticket-list :tickets="tickets"></ticket-list>
</div>
</div>
@ -60,8 +40,8 @@
<ticket-item
v-for="(ticket, index) in tickets"
:key="index"
:index="index"
:ticket-item="ticket"
:control-name="'booking[slots][' + index + ']'"
@onRemoveTicket="removeTicket($event)"
></ticket-item>
</tbody>
@ -76,11 +56,11 @@
<script type="text/x-template" id="ticket-item-template">
<tr>
<td>
<div class="control-group" :class="[errors.has(controlName + '[name]') ? 'has-error' : '']">
<input type="text" v-validate="'required'" :name="controlName + '[name]'" v-model="ticketItem.name" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.name') }}&quot;">
<div class="control-group" :class="[errors.has(controlName + '[{{$locale}}][name]') ? 'has-error' : '']">
<input type="text" v-validate="'required'" :name="controlName + '[{{$locale}}][name]'" v-model="ticketItem.name" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.name') }}&quot;">
<span class="control-error" v-if="errors.has(controlName + '[name]')">
@{{ errors.first(controlName + '[name]') }}
<span class="control-error" v-if="errors.has(controlName + '[{{$locale}}][name]')">
@{{ errors.first(controlName + '[{!!$locale!!}][name]') }}
</span>
</div>
</td>
@ -106,11 +86,11 @@
</td>
<td>
<div class="control-group" :class="[errors.has(controlName + '[description]') ? 'has-error' : '']">
<textarea type="text" v-validate="'required'" :name="controlName + '[description]'" v-model="ticketItem.description" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.description') }}&quot;"></textarea>
<div class="control-group" :class="[errors.has(controlName + '[{{$locale}}][description]') ? 'has-error' : '']">
<textarea type="text" v-validate="'required'" :name="controlName + '[{{$locale}}][description]'" v-model="ticketItem.description" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.description') }}&quot;"></textarea>
<span class="control-error" v-if="errors.has(controlName + '[description]')">
@{{ errors.first(controlName + '[description]') }}
<span class="control-error" v-if="errors.has(controlName + '[{{$locale}}][description]')">
@{{ errors.first(controlName + '[{!!$locale!!}][description]') }}
</span>
</div>
</td>
@ -130,13 +110,7 @@
data: function() {
return {
event_booking: bookingProduct && bookingProduct.event_slot ? bookingProduct.event_slot : {
available_from: '',
available_to: '',
slots: []
}
tickets: @json($bookingProduct->event_tickets()->get())
}
}
});
@ -171,10 +145,19 @@
template: '#ticket-item-template',
props: ['ticketItem', 'controlName'],
props: ['index', 'ticketItem'],
inject: ['$validator'],
computed: {
controlName: function () {
if (this.ticketItem.id)
return 'booking[tickets][' + this.ticketItem.id + ']';
return 'booking[tickets][ticket_' + this.index + ']';
}
},
methods: {
removeTicket: function() {
this.$emit('onRemoveTicket', this.ticketItem)

View File

@ -41,39 +41,6 @@
</div>
</div>
<div class="control-group" :class="[errors.has('booking[available_every_week]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}</label>
<select v-validate="'required'" name="booking[available_every_week]" v-model="rental_booking.available_every_week" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}&quot;">
<option value="1">{{ __('bookingproduct::app.admin.catalog.products.yes') }}</option>
<option value="0">{{ __('bookingproduct::app.admin.catalog.products.no') }}</option>
</select>
<span class="control-error" v-if="errors.has('booking[available_every_week]')">@{{ errors.first('booking[available_every_week]') }}</span>
</div>
<div v-if="! parseInt(rental_booking.available_every_week)">
<div class="control-group" :class="[errors.has('booking[available_from]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-from') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_from]" v-model="rental_booking.available_from" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-from') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_from]')">@{{ errors.first('booking[available_from]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_to]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-to') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_to]" v-model="rental_booking.available_to" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-to') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_to]')">@{{ errors.first('booking[available_to]') }}</span>
</div>
</div>
<div v-if="rental_booking.renting_type == 'hourly' || rental_booking.renting_type == 'daily_hourly'">
<div class="control-group" :class="[errors.has('booking[slot_has_quantity]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.slot-has-quantity') }}</label>
@ -132,12 +99,6 @@
hourly_price: '',
available_every_week: 1,
available_from: '',
available_to: '',
same_slot_all_days: 1,
slot_has_quantity: 1,

View File

@ -60,39 +60,6 @@
<span class="control-error" v-if="errors.has('booking[prevent_scheduling_before]')">@{{ errors.first('booking[prevent_scheduling_before]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_every_week]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}</label>
<select v-validate="'required'" name="booking[available_every_week]" v-model="table_booking.available_every_week" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-every-week') }}&quot;">
<option value="1">{{ __('bookingproduct::app.admin.catalog.products.yes') }}</option>
<option value="0">{{ __('bookingproduct::app.admin.catalog.products.no') }}</option>
</select>
<span class="control-error" v-if="errors.has('booking[available_every_week]')">@{{ errors.first('booking[available_every_week]') }}</span>
</div>
<div v-if="! parseInt(table_booking.available_every_week)">
<div class="control-group" :class="[errors.has('booking[available_from]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-from') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_from]" v-model="table_booking.available_from" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-from') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_from]')">@{{ errors.first('booking[available_from]') }}</span>
</div>
<div class="control-group" :class="[errors.has('booking[available_to]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.available-to') }}</label>
<date>
<input type="text" v-validate="'required'" name="booking[available_to]" v-model="table_booking.available_to" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.available-to') }}&quot;"/>
</date>
<span class="control-error" v-if="errors.has('booking[available_to]')">@{{ errors.first('booking[available_to]') }}</span>
</div>
</div>
<div class="control-group" :class="[errors.has('booking[same_slot_all_days]') ? 'has-error' : '']">
<label class="required">{{ __('bookingproduct::app.admin.catalog.products.same-slot-all-days') }}</label>
@ -143,12 +110,6 @@
prevent_scheduling_before: 0,
available_every_week: 1,
available_from: '',
available_to: '',
same_slot_all_days: 1,
slots: []

View File

@ -1,4 +1,4 @@
@inject ('bookingSlotHelper', 'Webkul\BookingProduct\Helpers\EventSlot')
@inject ('bookingSlotHelper', 'Webkul\BookingProduct\Helpers\EventTicket')
<div class="booking-info-row">
<span class="icon bp-slot-icon"></span>

View File

@ -84,6 +84,31 @@ class Booking extends Virtual
$this->bookingHelper = $bookingHelper;
}
/**
* @param array $data
* @param $id
* @param string $attribute
* @return Product
*/
public function update(array $data, $id, $attribute = "id")
{
$product = parent::update($data, $id, $attribute);
if (request()->route()->getName() != 'admin.catalog.products.massupdate') {
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $id);
if ($bookingProduct) {
$this->bookingProductRepository->update(request('booking'), $bookingProduct->id);
} else {
$this->bookingProductRepository->create(array_merge(request('booking'), [
'product_id' => $id
]));
}
}
return $product;
}
/**
* Returns additional views
*
@ -118,7 +143,7 @@ class Booking extends Virtual
{
$bookingProduct = $this->getBookingProduct($this->product->id);
if ($bookingProduct->type != 'default') {
if ($bookingProduct->type != 'default' && $bookingProduct->type != 'rental') {
unset($this->additionalViews[0]);
}