From fa53b7205883e174516141e91993b4ecdccd6115 Mon Sep 17 00:00:00 2001 From: Jitendra Singh Date: Fri, 14 Feb 2020 11:40:12 +0530 Subject: [PATCH] Booking product type added --- composer.json | 3 +- config/app.php | 1 + config/concord.php | 3 +- packages/Webkul/BookingProduct/.gitignore | 3 + packages/Webkul/BookingProduct/package.json | 22 ++ .../assets/css/booking-product.css | 1 + .../publishable/assets/images/arrow-down.svg | 10 + .../publishable/assets/images/arrow-up.svg | 10 + .../publishable/assets/images/location.svg | 11 + .../publishable/assets/images/phone.svg | 18 + .../publishable/assets/images/slot.svg | 15 + .../publishable/assets/mix-manifest.json | 3 + .../src/Config/product_types.php | 10 + .../src/Contracts/BookingProduct.php | 7 + .../BookingProductAppointmentSlot.php | 7 + .../Contracts/BookingProductDefaultSlot.php | 7 + .../src/Contracts/BookingProductEventSlot.php | 7 + .../Contracts/BookingProductRentalSlot.php | 7 + .../src/Contracts/BookingProductTableSlot.php | 7 + ...2_180307_create_booking_products_table.php | 37 +++ ...te_booking_product_default_slots_table.php | 39 +++ ...ooking_product_appointment_slots_table.php | 41 +++ ...eate_booking_product_event_slots_table.php | 36 ++ ...ate_booking_product_rental_slots_table.php | 42 +++ ...eate_booking_product_table_slots_table.php | 43 +++ .../src/Helpers/AppointmentSlot.php | 13 + .../BookingProduct/src/Helpers/Booking.php | 276 ++++++++++++++++ .../src/Helpers/DefaultSlot.php | 154 +++++++++ .../BookingProduct/src/Helpers/EventSlot.php | 60 ++++ .../BookingProduct/src/Helpers/RentalSlot.php | 94 ++++++ .../BookingProduct/src/Helpers/TableSlot.php | 13 + .../Shop/BookingProductController.php | 78 +++++ .../src/Http/Controllers/Shop/Controller.php | 12 + .../BookingProduct/src/Http/front-routes.php | 5 + .../BookingProduct/src/Listeners/Product.php | 53 +++ .../src/Models/BookingProduct.php | 54 +++ .../Models/BookingProductAppointmentSlot.php | 15 + .../BookingProductAppointmentSlotProxy.php | 10 + .../src/Models/BookingProductDefaultSlot.php | 25 ++ .../Models/BookingProductDefaultSlotProxy.php | 10 + .../src/Models/BookingProductEventSlot.php | 15 + .../Models/BookingProductEventSlotProxy.php | 10 + .../src/Models/BookingProductProxy.php | 10 + .../src/Models/BookingProductRentalSlot.php | 15 + .../Models/BookingProductRentalSlotProxy.php | 10 + .../src/Models/BookingProductTableSlot.php | 15 + .../Models/BookingProductTableSlotProxy.php | 10 + .../BookingProductServiceProvider.php | 42 +++ .../src/Providers/EventServiceProvider.php | 23 ++ .../src/Providers/ModuleServiceProvider.php | 17 + ...ookingProductAppointmentSlotRepository.php | 24 ++ .../BookingProductDefaultSlotRepository.php | 24 ++ .../BookingProductEventSlotRepository.php | 24 ++ .../BookingProductRentalSlotRepository.php | 24 ++ .../Repositories/BookingProductRepository.php | 135 ++++++++ .../BookingProductTableSlotRepository.php | 24 ++ .../Resources/assets/images/arrow-down.svg | 10 + .../src/Resources/assets/images/arrow-up.svg | 10 + .../src/Resources/assets/images/location.svg | 11 + .../src/Resources/assets/images/phone.svg | 18 + .../src/Resources/assets/images/slot.svg | 15 + .../src/Resources/assets/sass/app.scss | 213 ++++++++++++ .../src/Resources/assets/sass/icons.scss | 17 + .../src/Resources/lang/en/app.php | 109 ++++++ .../products/accordians/booking.blade.php | 84 +++++ .../accordians/booking/appointment.blade.php | 131 ++++++++ .../accordians/booking/default.blade.php | 311 ++++++++++++++++++ .../accordians/booking/event.blade.php | 186 +++++++++++ .../accordians/booking/rental.blade.php | 151 +++++++++ .../accordians/booking/slots.blade.php | 211 ++++++++++++ .../accordians/booking/table.blade.php | 150 +++++++++ .../shop/products/view/booking.blade.php | 60 ++++ .../view/booking/appointment.blade.php | 55 ++++ .../products/view/booking/default.blade.php | 10 + .../products/view/booking/event.blade.php | 80 +++++ .../products/view/booking/rental.blade.php | 153 +++++++++ .../products/view/booking/slots.blade.php | 58 ++++ .../products/view/booking/table.blade.php | 69 ++++ .../BookingProduct/src/Type/Booking.php | 169 ++++++++++ packages/Webkul/BookingProduct/webpack.mix.js | 31 ++ 80 files changed, 3994 insertions(+), 2 deletions(-) create mode 100755 packages/Webkul/BookingProduct/.gitignore create mode 100644 packages/Webkul/BookingProduct/package.json create mode 100644 packages/Webkul/BookingProduct/publishable/assets/css/booking-product.css create mode 100644 packages/Webkul/BookingProduct/publishable/assets/images/arrow-down.svg create mode 100644 packages/Webkul/BookingProduct/publishable/assets/images/arrow-up.svg create mode 100644 packages/Webkul/BookingProduct/publishable/assets/images/location.svg create mode 100644 packages/Webkul/BookingProduct/publishable/assets/images/phone.svg create mode 100644 packages/Webkul/BookingProduct/publishable/assets/images/slot.svg create mode 100644 packages/Webkul/BookingProduct/publishable/assets/mix-manifest.json create mode 100644 packages/Webkul/BookingProduct/src/Config/product_types.php create mode 100644 packages/Webkul/BookingProduct/src/Contracts/BookingProduct.php create mode 100644 packages/Webkul/BookingProduct/src/Contracts/BookingProductAppointmentSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Contracts/BookingProductDefaultSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Contracts/BookingProductEventSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Contracts/BookingProductRentalSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Contracts/BookingProductTableSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_02_180307_create_booking_products_table.php create mode 100644 packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154415_create_booking_product_default_slots_table.php create mode 100644 packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154429_create_booking_product_appointment_slots_table.php create mode 100644 packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154440_create_booking_product_event_slots_table.php create mode 100644 packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154451_create_booking_product_rental_slots_table.php create mode 100644 packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154502_create_booking_product_table_slots_table.php create mode 100644 packages/Webkul/BookingProduct/src/Helpers/AppointmentSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Helpers/Booking.php create mode 100644 packages/Webkul/BookingProduct/src/Helpers/DefaultSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Helpers/EventSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Helpers/TableSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Http/Controllers/Shop/BookingProductController.php create mode 100644 packages/Webkul/BookingProduct/src/Http/Controllers/Shop/Controller.php create mode 100644 packages/Webkul/BookingProduct/src/Http/front-routes.php create mode 100644 packages/Webkul/BookingProduct/src/Listeners/Product.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProduct.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlotProxy.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductDefaultSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductDefaultSlotProxy.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductEventSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductEventSlotProxy.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductProxy.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductRentalSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductRentalSlotProxy.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductTableSlot.php create mode 100644 packages/Webkul/BookingProduct/src/Models/BookingProductTableSlotProxy.php create mode 100644 packages/Webkul/BookingProduct/src/Providers/BookingProductServiceProvider.php create mode 100644 packages/Webkul/BookingProduct/src/Providers/EventServiceProvider.php create mode 100644 packages/Webkul/BookingProduct/src/Providers/ModuleServiceProvider.php create mode 100644 packages/Webkul/BookingProduct/src/Repositories/BookingProductAppointmentSlotRepository.php create mode 100644 packages/Webkul/BookingProduct/src/Repositories/BookingProductDefaultSlotRepository.php create mode 100644 packages/Webkul/BookingProduct/src/Repositories/BookingProductEventSlotRepository.php create mode 100644 packages/Webkul/BookingProduct/src/Repositories/BookingProductRentalSlotRepository.php create mode 100644 packages/Webkul/BookingProduct/src/Repositories/BookingProductRepository.php create mode 100644 packages/Webkul/BookingProduct/src/Repositories/BookingProductTableSlotRepository.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-down.svg create mode 100644 packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-up.svg create mode 100644 packages/Webkul/BookingProduct/src/Resources/assets/images/location.svg create mode 100644 packages/Webkul/BookingProduct/src/Resources/assets/images/phone.svg create mode 100644 packages/Webkul/BookingProduct/src/Resources/assets/images/slot.svg create mode 100644 packages/Webkul/BookingProduct/src/Resources/assets/sass/app.scss create mode 100644 packages/Webkul/BookingProduct/src/Resources/assets/sass/icons.scss create mode 100644 packages/Webkul/BookingProduct/src/Resources/lang/en/app.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/appointment.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/default.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/event.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/rental.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/slots.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/table.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/appointment.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/default.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/event.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/rental.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/slots.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/table.blade.php create mode 100644 packages/Webkul/BookingProduct/src/Type/Booking.php create mode 100644 packages/Webkul/BookingProduct/webpack.mix.js diff --git a/composer.json b/composer.json index 74f093097..9675be01a 100755 --- a/composer.json +++ b/composer.json @@ -101,7 +101,8 @@ "Webkul\\CartRule\\": "packages/Webkul/CartRule/src", "Webkul\\Rule\\": "packages/Webkul/Rule/src", "Webkul\\CMS\\": "packages/Webkul/CMS/src", - "Webkul\\Velocity\\": "packages/Webkul/Velocity/src" + "Webkul\\Velocity\\": "packages/Webkul/Velocity/src", + "Webkul\\BookingProduct\\": "packages/Webkul/BookingProduct/src" } }, diff --git a/config/app.php b/config/app.php index 33129e719..e617fc79f 100755 --- a/config/app.php +++ b/config/app.php @@ -265,6 +265,7 @@ return [ Webkul\Rule\Providers\RuleServiceProvider::class, Webkul\CMS\Providers\CMSServiceProvider::class, Webkul\Velocity\Providers\VelocityServiceProvider::class, + Webkul\BookingProduct\Providers\BookingProductServiceProvider::class, ], /* diff --git a/config/concord.php b/config/concord.php index 24c40b47a..e7ec5845e 100755 --- a/config/concord.php +++ b/config/concord.php @@ -21,6 +21,7 @@ return [ \Webkul\User\Providers\ModuleServiceProvider::class, \Webkul\CatalogRule\Providers\ModuleServiceProvider::class, \Webkul\CartRule\Providers\ModuleServiceProvider::class, - \Webkul\CMS\Providers\ModuleServiceProvider::class + \Webkul\CMS\Providers\ModuleServiceProvider::class, + \Webkul\BookingProduct\Providers\ModuleServiceProvider::class ] ]; \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/.gitignore b/packages/Webkul/BookingProduct/.gitignore new file mode 100755 index 000000000..6376db975 --- /dev/null +++ b/packages/Webkul/BookingProduct/.gitignore @@ -0,0 +1,3 @@ +/node_modules +/package-lock.json +npm-debug.log \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/package.json b/packages/Webkul/BookingProduct/package.json new file mode 100644 index 000000000..16e824391 --- /dev/null +++ b/packages/Webkul/BookingProduct/package.json @@ -0,0 +1,22 @@ +{ + "private": true, + "scripts": { + "dev": "npm run development", + "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch-poll": "cross-env npm run watch -- --watch-poll --progress", + "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", + "prod": "npm run production", + "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" + }, + "devDependencies": { + "axios": "^0.19.0", + "cross-env": "^6.0.3", + "jquery": "^3.4.1", + "laravel-mix": "^5.0.0", + "laravel-mix-merge-manifest": "^0.1.2", + "sass": "^1.25.0", + "sass-loader": "^8.0.2", + "vue": "^2.6.10" + } +} diff --git a/packages/Webkul/BookingProduct/publishable/assets/css/booking-product.css b/packages/Webkul/BookingProduct/publishable/assets/css/booking-product.css new file mode 100644 index 000000000..aea2997d8 --- /dev/null +++ b/packages/Webkul/BookingProduct/publishable/assets/css/booking-product.css @@ -0,0 +1 @@ +.bp-location-icon{background-image:url(../images/location.svg);width:32px;height:32px}.bp-slot-icon{background-image:url(../images/slot.svg);width:32px;height:32px}.bp-phone-icon{background-image:url(../images/phone.svg);width:32px;height:32px}.booking-information{margin-bottom:15px;border-top:1px solid #e8e8e8;padding-top:15px}.booking-information .booking-info-row{padding-left:32px;margin-bottom:20px;position:relative}.booking-information .booking-info-row .icon{position:absolute;left:0;top:-4px}.booking-information .booking-info-row .title{color:#5e5e5e;display:block;margin-bottom:5px}.booking-information .booking-info-row .value{display:block;margin-bottom:5px}.booking-information .booking-info-row .value .text-danger{color:#ff5656}.booking-information .booking-info-row .toggle{color:#0041ff;cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.booking-information .booking-info-row .toggle .icon{position:relative;width:10px;height:10px;margin-left:5px;top:0}.booking-information .booking-info-row .toggle .icon.arrow-down-icon{background-image:url(../images/arrow-down.svg)!important}.booking-information .booking-info-row .toggle .icon.arrow-up-icon{background-image:url(../images/arrow-up.svg)!important}.booking-information .booking-info-row .days-availability table{margin-top:10px;border-collapse:collapse}.booking-information .booking-info-row .days-availability table tr td{padding:5px;vertical-align:top}.booking-information .booking-info-row .days-availability table tr td:first-child{padding-left:0}.booking-information .booking-info-row .days-availability table tr td:last-child{font-size:14px;padding-left:15px;padding-right:0;color:#5e5e5e}.booking-information .booking-info-row .days-availability table tr td .text-danger{color:#ff5656}.booking-information .book-slots{padding-top:25px;display:inline-block;width:100%;border-top:1px solid #e8e8e8}.booking-information .book-slots h3{font-weight:600;font-size:16px;color:#242424;margin-top:0}.booking-information .book-slots label{color:#3a3a3a}.booking-information .book-slots .control-group label{font-size:16px}.booking-information .book-slots .control-group .radio{display:inline-block}.booking-information .book-slots .control-group-container{width:100%;float:left}.booking-information .book-slots .control-group-container .control-group:not(.quantity){width:50%;float:left}.booking-information .book-slots .control-group-container .control-group:not(.quantity) .control{width:100%}.booking-information .book-slots .control-group-container .control-group:not(.quantity).date{padding-right:5px}.booking-information .book-slots .control-group-container .control-group:not(.quantity).date:after{position:absolute;top:14px;right:10px}.booking-information .book-slots .control-group-container .control-group:not(.quantity).slots:first-child{padding-right:5px}.booking-information .book-slots .control-group-container .control-group:not(.quantity).slots:last-child{padding-left:5px}.booking-information .book-slots .ticket-list .ticket-item{width:100%;display:inline-block;padding:16px 0;border-bottom:1px solid #e8e8e8}.booking-information .book-slots .ticket-list .ticket-item .ticket-info{width:50%;float:left}.booking-information .book-slots .ticket-list .ticket-item .ticket-info .ticket-name{color:#242424;margin-bottom:12px}.booking-information .book-slots .ticket-list .ticket-item .ticket-info .ticket-price{color:#5e5e5e}.booking-information .book-slots .ticket-list .ticket-item .ticket-quantity{width:50%;display:inline-block}.booking-information .book-slots .ticket-list .ticket-item .ticket-quantity .control-group{margin:0}.booking-information .book-slots .ticket-list .ticket-item p{color:#242424;margin-bottom:0;font-weight:400}.booking-information .book-slots .ticket-total{font-size:16px;font-weight:600;color:#242424;padding-top:16px}.booking-information .book-slots .ticket-total>div{margin-bottom:12px}.booking-information .book-slots .ticket-total>div:last-child{margin-bottom:0}.booking-information .book-slots .ticket-total>div p{color:#242424;font-weight:400;margin-top:4px} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/publishable/assets/images/arrow-down.svg b/packages/Webkul/BookingProduct/publishable/assets/images/arrow-down.svg new file mode 100644 index 000000000..dd459433e --- /dev/null +++ b/packages/Webkul/BookingProduct/publishable/assets/images/arrow-down.svg @@ -0,0 +1,10 @@ + + + + icon-dropdown + Created with Sketch. + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/publishable/assets/images/arrow-up.svg b/packages/Webkul/BookingProduct/publishable/assets/images/arrow-up.svg new file mode 100644 index 000000000..4ebba93f5 --- /dev/null +++ b/packages/Webkul/BookingProduct/publishable/assets/images/arrow-up.svg @@ -0,0 +1,10 @@ + + + + icon-dropdown-up + Created with Sketch. + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/publishable/assets/images/location.svg b/packages/Webkul/BookingProduct/publishable/assets/images/location.svg new file mode 100644 index 000000000..19fd55a0d --- /dev/null +++ b/packages/Webkul/BookingProduct/publishable/assets/images/location.svg @@ -0,0 +1,11 @@ + + + + tab/heading/icon/address + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/publishable/assets/images/phone.svg b/packages/Webkul/BookingProduct/publishable/assets/images/phone.svg new file mode 100644 index 000000000..e132e7b15 --- /dev/null +++ b/packages/Webkul/BookingProduct/publishable/assets/images/phone.svg @@ -0,0 +1,18 @@ + + + + icon-menu copy + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/publishable/assets/images/slot.svg b/packages/Webkul/BookingProduct/publishable/assets/images/slot.svg new file mode 100644 index 000000000..18d00bd75 --- /dev/null +++ b/packages/Webkul/BookingProduct/publishable/assets/images/slot.svg @@ -0,0 +1,15 @@ + + + + tab/heading/icon/calender + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/publishable/assets/mix-manifest.json b/packages/Webkul/BookingProduct/publishable/assets/mix-manifest.json new file mode 100644 index 000000000..8fb05dd91 --- /dev/null +++ b/packages/Webkul/BookingProduct/publishable/assets/mix-manifest.json @@ -0,0 +1,3 @@ +{ + "/css/booking-product.css": "/css/booking-product.css?id=083d9215be8e5552a0e7" +} diff --git a/packages/Webkul/BookingProduct/src/Config/product_types.php b/packages/Webkul/BookingProduct/src/Config/product_types.php new file mode 100644 index 000000000..c7520c39e --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Config/product_types.php @@ -0,0 +1,10 @@ + [ + 'key' => 'booking', + 'name' => 'Booking', + 'class' => 'Webkul\BookingProduct\Type\Booking', + 'sort' => 7 + ] +]; \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Contracts/BookingProduct.php b/packages/Webkul/BookingProduct/src/Contracts/BookingProduct.php new file mode 100644 index 000000000..73a55d322 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Contracts/BookingProduct.php @@ -0,0 +1,7 @@ +increments('id'); + $table->string('type'); + $table->string('location')->nullable(); + $table->boolean('show_location')->default(0); + + $table->integer('product_id')->unsigned(); + $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('booking_products'); + } +} diff --git a/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154415_create_booking_product_default_slots_table.php b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154415_create_booking_product_default_slots_table.php new file mode 100644 index 000000000..77ac24993 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154415_create_booking_product_default_slots_table.php @@ -0,0 +1,39 @@ +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(); + + $table->integer('booking_product_id')->unsigned(); + $table->foreign('booking_product_id')->references('id')->on('booking_products')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('booking_product_default_slots'); + } +} diff --git a/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154429_create_booking_product_appointment_slots_table.php b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154429_create_booking_product_appointment_slots_table.php new file mode 100644 index 000000000..3a3190f8a --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154429_create_booking_product_appointment_slots_table.php @@ -0,0 +1,41 @@ +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(); + + $table->integer('booking_product_id')->unsigned(); + $table->foreign('booking_product_id')->references('id')->on('booking_products')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('booking_product_appointment_slots'); + } +} diff --git a/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154440_create_booking_product_event_slots_table.php b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154440_create_booking_product_event_slots_table.php new file mode 100644 index 000000000..5857c5a89 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154440_create_booking_product_event_slots_table.php @@ -0,0 +1,36 @@ +increments('id'); + $table->datetime('available_from')->nullable(); + $table->datetime('available_to')->nullable(); + $table->json('slots')->nullable(); + + $table->integer('booking_product_id')->unsigned(); + $table->foreign('booking_product_id')->references('id')->on('booking_products')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('booking_product_event_slots'); + } +} diff --git a/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154451_create_booking_product_rental_slots_table.php b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154451_create_booking_product_rental_slots_table.php new file mode 100644 index 000000000..c48a332f4 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154451_create_booking_product_rental_slots_table.php @@ -0,0 +1,42 @@ +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->boolean('slot_has_quantity')->nullable(); + $table->boolean('same_slot_all_days')->nullable(); + $table->json('slots')->nullable(); + + $table->integer('booking_product_id')->unsigned(); + $table->foreign('booking_product_id')->references('id')->on('booking_products')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('booking_product_rental_slots'); + } +} diff --git a/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154502_create_booking_product_table_slots_table.php b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154502_create_booking_product_table_slots_table.php new file mode 100644 index 000000000..2ca99a88e --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Database/Migrations/2019_07_05_154502_create_booking_product_table_slots_table.php @@ -0,0 +1,43 @@ +increments('id'); + $table->string('price_type'); + $table->integer('guest_limit')->default(0); + $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(); + + $table->integer('booking_product_id')->unsigned(); + $table->foreign('booking_product_id')->references('id')->on('booking_products')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('booking_product_table_slots'); + } +} diff --git a/packages/Webkul/BookingProduct/src/Helpers/AppointmentSlot.php b/packages/Webkul/BookingProduct/src/Helpers/AppointmentSlot.php new file mode 100644 index 000000000..82a522c5e --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Helpers/AppointmentSlot.php @@ -0,0 +1,13 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class AppointmentSlot extends Booking +{ +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Helpers/Booking.php b/packages/Webkul/BookingProduct/src/Helpers/Booking.php new file mode 100644 index 000000000..0e52a2d9f --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Helpers/Booking.php @@ -0,0 +1,276 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class Booking +{ + /** + * @return array + */ + protected $typeRepositories = []; + + /** + * @return array + */ + protected $daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + + /** + * Create a new helper instance. + * + * @param Webkul\BookingProduct\Repositories\BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductEventSlotRepository $bookingProductEventSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductRentalSlotRepository $bookingProductRentalSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductTableSlotRepository $bookingProductTableSlotRepository + * @return void + */ + public function __construct( + BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository, + BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository, + BookingProductEventSlotRepository $bookingProductEventSlotRepository, + BookingProductRentalSlotRepository $bookingProductRentalSlotRepository, + BookingProductTableSlotRepository $bookingProductTableSlotRepository + ) + { + $this->typeRepositories['default'] = $bookingProductDefaultSlotRepository; + + $this->typeRepositories['appointment'] = $bookingProductAppointmentSlotRepository; + + $this->typeRepositories['event'] = $bookingProductEventSlotRepository; + + $this->typeRepositories['rental'] = $bookingProductRentalSlotRepository; + + $this->typeRepositories['table'] = $bookingProductTableSlotRepository; + } + + /** + * Returns the booking information + * + * @param BookingProduct $bookingProduct + * @return array + */ + public function getWeekSlotDurations($bookingProduct) + { + $slotsByDays = []; + + $bookingProductSlot = $this->typeRepositories[$bookingProduct->type]->findOneByField('booking_product_id', $bookingProduct->id); + + $availabileDays = $this->getAvailableWeekDays($bookingProductSlot); + + foreach ($this->daysOfWeek as $index => $isOpen) { + $slots = []; + + if ($isOpen) + $slots = $bookingProductSlot->same_slot_all_days ? $bookingProductSlot->slots : ($bookingProductSlot->slots[$index] ?? []); + + $slotsByDays[] = [ + 'name' => trans($this->daysOfWeek[$index]), + 'slots' => isset($availabileDays[$index]) ? $this->conver24To12Hours($slots) : [] + ]; + } + + return $slotsByDays; + } + + /** + * Returns html of slots for a current day + * + * @param BookingProduct $bookingProduct + * @return string + */ + public function getTodaySlotsHtml($bookingProduct) + { + $slots = []; + + foreach ($this->getTodaySlots($bookingProduct) as $slot) { + $slots[] = $slot['from'] . ' - ' . $slot['to']; + } + + return count($slots) + ? implode(' | ', $slots) + : '' . trans('bookingproduct::app.shop.products.closed') . ''; + } + + /** + * Returns slots for a current day + * + * @param BookingProduct $bookingProduct + * @return array + */ + public function getTodaySlots($bookingProduct) + { + $weekSlots = $this->getWeekSlotDurations($bookingProduct); + + return $weekSlots[Carbon::now()->format('w')]['slots']; + } + + /** + * Returns the available week days + * + * @param Object $bookingProductSlot + * @return array + */ + public function getAvailableWeekDays($bookingProductSlot) + { + if ($bookingProductSlot->available_every_week) + return $this->daysOfWeek; + + $days = []; + + $currentTime = Carbon::now(); + + $availableFrom = Carbon::createFromTimeString($bookingProductSlot->available_from . " 00:00:01"); + + $availableTo = Carbon::createFromTimeString($bookingProductSlot->available_to . " 23:59:59"); + + for ($i = 0; $i < 7; $i++) { + $date = clone $currentTime; + $date->addDays($i); + + if ($date >= $availableFrom && $date <= $availableTo) + $days[$i] = $date->format('l'); + } + + return $this->sortDaysOfWeek($days); + } + + /** + * Sort days + * + * @param array $days + * @return array + */ + public function sortDaysOfWeek($days) + { + $daysAux = []; + + foreach ($days as $day) { + $key = array_search($day, $this->daysOfWeek); + + if ($key !== FALSE) { + $daysAux[$key] = $day; + } + } + + ksort($daysAux); + + return $daysAux; + } + + /** + * Convert time from 24 to 12 hour format + * + * @param array $slots + * @return array + */ + public function conver24To12Hours($slots) + { + if (! $slots) + return []; + + foreach ($slots as $index => $slot) { + $slots[$index]['from'] = Carbon::createFromTimeString($slot['from'])->format("h:i a"); + $slots[$index]['to'] = Carbon::createFromTimeString($slot['to'])->format("h:i a"); + } + + return $slots; + } + + /** + * Returns slots for a perticular day + * + * @param BookingProduct $bookingProduct + * @param string $date + * @return array + */ + public function getSlotsByDate($bookingProduct, $date) + { + $bookingProductSlot = $this->typeRepositories[$bookingProduct->type]->findOneByField('booking_product_id', $bookingProduct->id); + + if (! is_array($bookingProductSlot->slots) || ! count($bookingProductSlot->slots)) + return []; + + $requestedDate = Carbon::createFromTimeString($date . " 00:00:00"); + + $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'); + + $availableTo = ! $bookingProductSlot->available_every_week + ? Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59') + : Carbon::createFromTimeString('2080-01-01 00:00:00'); + + $timeDurations = $bookingProductSlot->same_slot_all_days + ? $bookingProductSlot->slots + : ($bookingProductSlot->slots[$requestedDate->format('w')] ?? []); + + $slots = []; + + foreach ($timeDurations as $timeDuration) { + $fromChunks = explode(':', $timeDuration['from']); + $toChunks = explode(':', $timeDuration['to']); + + $startDayTime = Carbon::createFromTimeString($requestedDate->format('Y-m-d') . ' 00:00:00'); + $startDayTime->addMinutes(($fromChunks[0] * 60) + $fromChunks[1]); + $tempStartDayTime = clone $startDayTime; + + $endDayTime = Carbon::createFromTimeString($requestedDate->format('Y-m-d') . ' 00:00:00'); + $endDayTime->addMinutes(($toChunks[0] * 60) + $toChunks[1]); + + $isFirstIteration = true; + + while (1) { + $from = clone $tempStartDayTime; + $tempStartDayTime->addMinutes($bookingProductSlot->duration); + + if ($isFirstIteration) { + $isFirstIteration = false; + } else { + $from->modify('+' . $bookingProductSlot->break_time . ' minutes'); + $tempStartDayTime->modify('+' . $bookingProductSlot->break_time . ' minutes'); + } + + $to = clone $tempStartDayTime; + + if (($startDayTime <= $from && $from <= $availableTo) + && ($availableTo >= $to && $to >= $startDayTime) + && ($startDayTime <= $from && $from <= $endDayTime) + && ($endDayTime >= $to && $to >= $startDayTime)) { + + // Get already ordered qty for this slot + $orderedQty = 0; + + $qty = isset($timeDuration['qty']) ? ( $timeDuration['qty'] - $orderedQty ) : 1; + + if ($qty && $currentTime <= $from) { + $slots[] = [ + 'from' => $from->format('h:i A'), + 'to' => $to->format('h:i A'), + 'timestamp' => $from->getTimestamp() . '-' . $to->getTimestamp(), + 'qty' => $qty, + ]; + } + } else { + break; + } + } + } + + return $slots; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Helpers/DefaultSlot.php b/packages/Webkul/BookingProduct/src/Helpers/DefaultSlot.php new file mode 100644 index 000000000..26f9f1253 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Helpers/DefaultSlot.php @@ -0,0 +1,154 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class DefaultSlot extends Booking +{ + /** + * @return array + */ + protected $daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + + /** + * Returns slots for a perticular day + * + * @param BookingProduct $bookingProduct + * @param string $date + * @return array + */ + public function getSlotsByDate($bookingProduct, $date) + { + $bookingProductSlot = $this->typeRepositories[$bookingProduct->type]->findOneByField('booking_product_id', $bookingProduct->id); + + if (! is_array($bookingProductSlot->slots) || ! count($bookingProductSlot->slots)) + return []; + + $requestedDate = Carbon::createFromTimeString($date . " 00:00:00"); + + $currentTime = Carbon::now(); + + $availableFrom = Carbon::createFromTimeString($bookingProductSlot->available_from . " 00:00:00"); + + $availableTo = Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59'); + + if ($requestedDate < $currentTime + || $requestedDate < $availableFrom + || $requestedDate > $availableTo) + return []; + + $slots = []; + + return $bookingProductSlot->booking_type == 'one' + ? $this->getOneBookingForManyDaysSlots($bookingProductSlot, $requestedDate) + : $this->getManyBookingsforOneDaySlots($bookingProductSlot, $requestedDate); + } + + /** + * Returns slots for One Booking For Many Days + * + * @param BookingProductSlot $bookingProductSlot + * @param string $requestedDate + * @return array + */ + public function getOneBookingForManyDaysSlots($bookingProductSlot, $requestedDate) + { + $slots = []; + + foreach ($bookingProductSlot->slots as $timeDuration) { + if ($requestedDate->dayOfWeek != $timeDuration['from_day']) + continue; + + $startDate = clone $requestedDate->modify('this ' . $this->daysOfWeek[$timeDuration['from_day']]); + $endDate = clone $requestedDate->modify('this ' . $this->daysOfWeek[$timeDuration['to_day']]); + + $slots[] = [ + 'from' => $startDate->format('d F, Y h:i A'), + 'to' => $endDate->format('d F, Y h:i A'), + 'timestamp' => $startDate->getTimestamp() . '-' . $endDate->getTimestamp(), + ]; + } + + return $slots; + } + + /** + * Returns slots for Many Bookings for One Day + * + * @param BookingProductSlot $bookingProductSlot + * @param string $requestedDate + * @return array + */ + public function getManyBookingsforOneDaySlots($bookingProductSlot, $requestedDate) + { + $currentTime = Carbon::now(); + + $availableFrom = Carbon::createFromTimeString($bookingProductSlot->available_from . ' 00:00:00'); + + $availableTo = Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59'); + + $timeDuration = $bookingProductSlot->slots[$requestedDate->format('w')] ?? []; + + if (! count($timeDuration) || ! $timeDuration['status']) + return []; + + $slots = []; + + $fromChunks = explode(':', $timeDuration['from']); + $toChunks = explode(':', $timeDuration['to']); + + $startDayTime = Carbon::createFromTimeString($requestedDate->format('Y-m-d') . ' 00:00:00'); + $startDayTime->addMinutes(($fromChunks[0] * 60) + $fromChunks[1]); + $tempStartDayTime = clone $startDayTime; + + $endDayTime = Carbon::createFromTimeString($requestedDate->format('Y-m-d') . ' 00:00:00'); + $endDayTime->addMinutes(($toChunks[0] * 60) + $toChunks[1]); + + $isFirstIteration = true; + + while (1) { + $from = clone $tempStartDayTime; + $tempStartDayTime->addMinutes($bookingProductSlot->duration); + + if ($isFirstIteration) { + $isFirstIteration = false; + } else { + $from->modify('+' . $bookingProductSlot->break_time . ' minutes'); + $tempStartDayTime->modify('+' . $bookingProductSlot->break_time . ' minutes'); + } + + $to = clone $tempStartDayTime; + + if (($startDayTime <= $from && $from <= $availableTo) + && ($availableTo >= $to && $to >= $startDayTime) + && ($startDayTime <= $from && $from <= $endDayTime) + && ($endDayTime >= $to && $to >= $startDayTime)) { + + // Get already ordered qty for this slot + $orderedQty = 0; + + $qty = isset($timeDuration['qty']) ? ( $timeDuration['qty'] - $orderedQty ) : 1; + + if ($qty && $currentTime <= $from) { + $slots[] = [ + 'from' => $from->format('h:i A'), + 'to' => $to->format('h:i A'), + 'timestamp' => $from->getTimestamp() . '-' . $to->getTimestamp(), + 'qty' => $qty, + ]; + } + } else { + break; + } + } + + return $slots; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Helpers/EventSlot.php b/packages/Webkul/BookingProduct/src/Helpers/EventSlot.php new file mode 100644 index 000000000..064f9dc3d --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Helpers/EventSlot.php @@ -0,0 +1,60 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class EventSlot extends Booking +{ + /** + * Returns event date + * + * @param BookingProduct $bookingProduct + * @return string + */ + public function getEventDate($bookingProduct) + { + $from = Carbon::createFromTimeString($bookingProduct->event_slot->available_from)->format('d F, Y h:i A'); + + $to = Carbon::createFromTimeString($bookingProduct->event_slot->available_to)->format('d F, Y h:i A'); + + return $from . ' - ' . $to; + } + + /** + * Returns tickets + * + * @param BookingProduct $bookingProduct + * @return array + */ + public function getTickets($bookingProduct) + { + if (! $bookingProduct->event_slot) + return; + + return $this->formatPrice($bookingProduct->event_slot->slots); + } + + /** + * Format ticket price + * + * @param array $tickets + * @return array + */ + 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]['formated_price_text'] = trans('bookingproduct::app.shop.products.per-ticket-price', ['price' => $formatedPrice]); + } + + return $tickets; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php b/packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php new file mode 100644 index 000000000..2e04cfb90 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Helpers/RentalSlot.php @@ -0,0 +1,94 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class RentalSlot extends Booking +{ + /** + * Returns slots for a perticular day + * + * @param BookingProduct $bookingProduct + * @param string $date + * @return array + */ + public function getSlotsByDate($bookingProduct, $date) + { + $bookingProductSlot = $this->typeRepositories[$bookingProduct->type]->findOneByField('booking_product_id', $bookingProduct->id); + + if (! is_array($bookingProductSlot->slots) || ! count($bookingProductSlot->slots)) + return []; + + $requestedDate = Carbon::createFromTimeString($date . " 00:00:00"); + + $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'); + + $availableTo = ! $bookingProductSlot->available_every_week + ? Carbon::createFromTimeString($bookingProductSlot->available_to . ' 23:59:59') + : Carbon::createFromTimeString('2080-01-01 00:00:00'); + + $timeDurations = $bookingProductSlot->same_slot_all_days + ? $bookingProductSlot->slots + : $bookingProductSlot->slots[$requestedDate->format('w')]; + + $slots = []; + + foreach ($timeDurations as $index => $timeDuration) { + $fromChunks = explode(':', $timeDuration['from']); + $toChunks = explode(':', $timeDuration['to']); + + $startDayTime = Carbon::createFromTimeString($requestedDate->format('Y-m-d') . ' 00:00:00'); + $startDayTime->addMinutes(($fromChunks[0] * 60) + $fromChunks[1]); + $tempStartDayTime = clone $startDayTime; + + $endDayTime = Carbon::createFromTimeString($requestedDate->format('Y-m-d') . ' 00:00:00'); + $endDayTime->addMinutes(($toChunks[0] * 60) + $toChunks[1]); + + while (1) { + $from = clone $tempStartDayTime; + $tempStartDayTime->addMinutes(60); + + $to = clone $tempStartDayTime; + + if (($startDayTime <= $from && $from <= $availableTo) + && ($availableTo >= $to && $to >= $startDayTime) + && ($startDayTime <= $from && $from <= $endDayTime) + && ($endDayTime >= $to && $to >= $startDayTime)) { + + // Get already ordered qty for this slot + $orderedQty = 0; + + $qty = isset($timeDuration['qty']) ? ( $timeDuration['qty'] - $orderedQty ) : 1; + + if ($qty && $currentTime <= $from) { + if (! isset($slots[$index])) + $slots[$index]['time'] = $startDayTime->format('h:i A') . ' - ' . $endDayTime->format('h:i A'); + + $slots[$index]['slots'][] = [ + 'from' => $from->format('h:i A'), + 'to' => $to->format('h:i A'), + 'from_timestamp' => $from->getTimestamp(), + 'to_timestamp' => $to->getTimestamp(), + 'qty' => $qty + ]; + } + } else { + break; + } + } + } + + return $slots; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Helpers/TableSlot.php b/packages/Webkul/BookingProduct/src/Helpers/TableSlot.php new file mode 100644 index 000000000..3fc5ebb56 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Helpers/TableSlot.php @@ -0,0 +1,13 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class TableSlot extends Booking +{ +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Http/Controllers/Shop/BookingProductController.php b/packages/Webkul/BookingProduct/src/Http/Controllers/Shop/BookingProductController.php new file mode 100644 index 000000000..15ef0c984 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Http/Controllers/Shop/BookingProductController.php @@ -0,0 +1,78 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class BookingProductController extends Controller +{ + /** + * Booking object + * + * @var Object + */ + protected $bookingHelper; + + /** + * @return array + */ + protected $bookingHelpers = []; + + /** + * Create a new helper instance. + * + * @param Webkul\BookingProduct\Repositories\BookingProductRepository $bookingProductRepository + * @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\TableSlot $tableSlotHelper + * @return void + */ + public function __construct( + BookingProductRepository $bookingProductRepository, + DefaultSlotHelper $defaultSlotHelper, + AppointmentSlotHelper $appointmentSlotHelper, + RentalSlotHelper $rentalSlotHelper, + EventSlotHelper $eventSlotHelper, + TableSlotHelper $tableSlotHelper + ) + { + $this->bookingProductRepository = $bookingProductRepository; + + $this->bookingHelpers['default'] = $defaultSlotHelper; + + $this->bookingHelpers['appointment'] = $appointmentSlotHelper; + + $this->bookingHelpers['rental'] = $rentalSlotHelper; + + $this->bookingHelpers['event'] = $eventSlotHelper; + + $this->bookingHelpers['table'] = $tableSlotHelper; + } + + /** + * Display the specified resource. + * + * @return \Illuminate\Http\Response + */ + public function index() + { + $bookingProduct = $this->bookingProductRepository->find(request('id')); + + return response()->json([ + 'data' => $this->bookingHelpers[$bookingProduct->type]->getSlotsByDate($bookingProduct, request()->get('date')) + ]); + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Http/Controllers/Shop/Controller.php b/packages/Webkul/BookingProduct/src/Http/Controllers/Shop/Controller.php new file mode 100644 index 000000000..0209a71dc --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Http/Controllers/Shop/Controller.php @@ -0,0 +1,12 @@ + ['web', 'theme', 'locale', 'currency']], function () { + Route::get('/booking-slots/{id}', 'Webkul\BookingProduct\Http\Controllers\Shop\BookingProductController@index')->name('booking_product.slots.index'); +}); \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Listeners/Product.php b/packages/Webkul/BookingProduct/src/Listeners/Product.php new file mode 100644 index 000000000..094280dd3 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Listeners/Product.php @@ -0,0 +1,53 @@ + + * @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 + ])); + } + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProduct.php b/packages/Webkul/BookingProduct/src/Models/BookingProduct.php new file mode 100644 index 000000000..6c54592c3 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Models/BookingProduct.php @@ -0,0 +1,54 @@ +hasOne(BookingProductDefaultSlotProxy::modelClass()); + } + + /** + * The Product Appointment Booking that belong to the product booking. + */ + public function appointment_slot() + { + return $this->hasOne(BookingProductAppointmentSlotProxy::modelClass()); + } + + /** + * The Product Event Booking that belong to the product booking. + */ + public function event_slot() + { + return $this->hasOne(BookingProductEventSlotProxy::modelClass()); + } + + /** + * The Product Rental Booking that belong to the product booking. + */ + public function rental_slot() + { + return $this->hasOne(BookingProductRentalSlotProxy::modelClass()); + } + + /** + * The Product Table Booking that belong to the product booking. + */ + public function table_slot() + { + return $this->hasOne(BookingProductTableSlotProxy::modelClass()); + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlot.php b/packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlot.php new file mode 100644 index 000000000..1766d3bbf --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlot.php @@ -0,0 +1,15 @@ + 'array']; + + protected $fillable = ['duration', 'break_time', 'available_every_week', 'slot_has_quantity', 'same_slot_all_days', 'slots', 'booking_product_id']; +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlotProxy.php b/packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlotProxy.php new file mode 100644 index 000000000..a33d0f368 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Models/BookingProductAppointmentSlotProxy.php @@ -0,0 +1,10 @@ + 'array']; + + protected $fillable = ['booking_type', 'duration', 'break_time', 'available_from', 'available_to', 'slots', 'booking_product_id']; + + /** + * Get the product that owns the attribute value. + */ + public function booking_product() + { + return $this->belongsTo(BookingProductProxy::modelClass()); + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProductDefaultSlotProxy.php b/packages/Webkul/BookingProduct/src/Models/BookingProductDefaultSlotProxy.php new file mode 100644 index 000000000..67ee768c8 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Models/BookingProductDefaultSlotProxy.php @@ -0,0 +1,10 @@ + 'array']; + + protected $fillable = ['available_from', 'available_to', 'slots', 'booking_product_id']; +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProductEventSlotProxy.php b/packages/Webkul/BookingProduct/src/Models/BookingProductEventSlotProxy.php new file mode 100644 index 000000000..ec05e5f54 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Models/BookingProductEventSlotProxy.php @@ -0,0 +1,10 @@ + 'array']; + + protected $fillable = ['renting_type', 'daily_price', 'hourly_price', 'available_every_week', 'slot_has_quantity', 'same_slot_all_days', 'slots', 'booking_product_id']; +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProductRentalSlotProxy.php b/packages/Webkul/BookingProduct/src/Models/BookingProductRentalSlotProxy.php new file mode 100644 index 000000000..1191761bf --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Models/BookingProductRentalSlotProxy.php @@ -0,0 +1,10 @@ + 'array']; + + protected $fillable = ['price_type', 'guest_limit', 'duration', 'break_time', 'prevent_scheduling_before', 'available_every_week', 'available_from', 'available_to', 'same_slot_all_days', 'slots', 'booking_product_id']; +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Models/BookingProductTableSlotProxy.php b/packages/Webkul/BookingProduct/src/Models/BookingProductTableSlotProxy.php new file mode 100644 index 000000000..2d5acb217 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Models/BookingProductTableSlotProxy.php @@ -0,0 +1,10 @@ +loadRoutesFrom(__DIR__ . '/../Http/front-routes.php'); + + $this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations'); + + $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'bookingproduct'); + + $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'bookingproduct'); + + $this->publishes([ + __DIR__ . '/../../publishable/assets' => public_path('themes/default/assets'), + ], 'public'); + + $this->app->register(EventServiceProvider::class); + } + + /** + * Register services. + * + * @return void + */ + public function register() + { + $this->mergeConfigFrom( + dirname(__DIR__) . '/Config/product_types.php', 'product_types' + ); + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Providers/EventServiceProvider.php b/packages/Webkul/BookingProduct/src/Providers/EventServiceProvider.php new file mode 100644 index 000000000..98d66d424 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Providers/EventServiceProvider.php @@ -0,0 +1,23 @@ +addTemplate('bookingproduct::shop.products.view.booking'); + }); + + Event::listen('catalog.product.update.after', 'Webkul\BookingProduct\Listeners\Product@afterProductUpdated'); + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Providers/ModuleServiceProvider.php b/packages/Webkul/BookingProduct/src/Providers/ModuleServiceProvider.php new file mode 100644 index 000000000..8e0692a64 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Providers/ModuleServiceProvider.php @@ -0,0 +1,17 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class BookingProductAppointmentSlotRepository extends Repository +{ + /** + * Specify Model class name + * + * @return mixed + */ + function model() + { + return 'Webkul\BookingProduct\Contracts\BookingProductAppointmentSlot'; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Repositories/BookingProductDefaultSlotRepository.php b/packages/Webkul/BookingProduct/src/Repositories/BookingProductDefaultSlotRepository.php new file mode 100644 index 000000000..440803e13 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Repositories/BookingProductDefaultSlotRepository.php @@ -0,0 +1,24 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class BookingProductDefaultSlotRepository extends Repository +{ + /** + * Specify Model class name + * + * @return mixed + */ + function model() + { + return 'Webkul\BookingProduct\Contracts\BookingProductDefaultSlot'; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Repositories/BookingProductEventSlotRepository.php b/packages/Webkul/BookingProduct/src/Repositories/BookingProductEventSlotRepository.php new file mode 100644 index 000000000..b2e44336c --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Repositories/BookingProductEventSlotRepository.php @@ -0,0 +1,24 @@ + + * @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'; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Repositories/BookingProductRentalSlotRepository.php b/packages/Webkul/BookingProduct/src/Repositories/BookingProductRentalSlotRepository.php new file mode 100644 index 000000000..e4c2185fa --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Repositories/BookingProductRentalSlotRepository.php @@ -0,0 +1,24 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class BookingProductRentalSlotRepository extends Repository +{ + /** + * Specify Model class name + * + * @return mixed + */ + function model() + { + return 'Webkul\BookingProduct\Contracts\BookingProductRentalSlot'; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Repositories/BookingProductRepository.php b/packages/Webkul/BookingProduct/src/Repositories/BookingProductRepository.php new file mode 100644 index 000000000..3dfbe4e50 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Repositories/BookingProductRepository.php @@ -0,0 +1,135 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class BookingProductRepository extends Repository +{ + /** + * @return array + */ + protected $typeRepositories = []; + + /** + * Create a new repository instance. + * + * @param Webkul\BookingProduct\Repositories\BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductEventSlotRepository $bookingProductEventSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductRentalSlotRepository $bookingProductRentalSlotRepository + * @param Webkul\BookingProduct\Repositories\BookingProductTableSlotRepository $bookingProductTableSlotRepository + * @return void + */ + public function __construct( + BookingProductDefaultSlotRepository $bookingProductDefaultSlotRepository, + BookingProductAppointmentSlotRepository $bookingProductAppointmentSlotRepository, + BookingProductEventSlotRepository $bookingProductEventSlotRepository, + BookingProductRentalSlotRepository $bookingProductRentalSlotRepository, + BookingProductTableSlotRepository $bookingProductTableSlotRepository, + App $app + ) + { + parent::__construct($app); + + $this->typeRepositories['default'] = $bookingProductDefaultSlotRepository; + + $this->typeRepositories['appointment'] = $bookingProductAppointmentSlotRepository; + + $this->typeRepositories['event'] = $bookingProductEventSlotRepository; + + $this->typeRepositories['rental'] = $bookingProductRentalSlotRepository; + + $this->typeRepositories['table'] = $bookingProductTableSlotRepository; + } + + /** + * Specify Model class name + * + * @return mixed + */ + function model() + { + return 'Webkul\BookingProduct\Contracts\BookingProduct'; + } + + /** + * @param array $data + * @return mixed + */ + public function create(array $data) + { + $bookingProduct = parent::create($data); + + $this->typeRepositories[$data['type']]->create(array_merge($data, ['booking_product_id' => $bookingProduct->id])); + + return $bookingProduct; + } + + /** + * @param array $data + * @param integer $id + * @param string $attribute + * @return mixed + */ + public function update(array $data, $id, $attribute = "id") + { + parent::update($data, $id, $attribute); + + foreach ($this->typeRepositories as $type => $repository) { + if ($type == $data['type']) + continue; + + $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])); + } else { + $this->typeRepositories[$data['type']]->update($data, $bookingProductTypeSlot->id); + } + } + + /** + * @param array $data + * @return array + */ + public function formatSlots($data) + { + if (isset($data['slots']) && isset($data['same_slot_all_days']) && ! $data['same_slot_all_days']) { + for ($i = 0; $i < 7; $i++) { + if (! isset($data['slots'][$i])) { + $data['slots'][$i] = []; + } else { + $count = 0; + + $slots = []; + + foreach ($data['slots'][$i] as $slot) { + $slots[] = array_merge($slot, ['id' => $i . '_slot_' . $count]); + + $count++; + } + + $data['slots'][$i] = $slots; + } + } + + ksort($data['slots']); + } + + return $data['slots']; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Repositories/BookingProductTableSlotRepository.php b/packages/Webkul/BookingProduct/src/Repositories/BookingProductTableSlotRepository.php new file mode 100644 index 000000000..634d264d1 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Repositories/BookingProductTableSlotRepository.php @@ -0,0 +1,24 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class BookingProductTableSlotRepository extends Repository +{ + /** + * Specify Model class name + * + * @return mixed + */ + function model() + { + return 'Webkul\BookingProduct\Contracts\BookingProductTableSlot'; + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-down.svg b/packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-down.svg new file mode 100644 index 000000000..dd459433e --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-down.svg @@ -0,0 +1,10 @@ + + + + icon-dropdown + Created with Sketch. + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-up.svg b/packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-up.svg new file mode 100644 index 000000000..4ebba93f5 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/assets/images/arrow-up.svg @@ -0,0 +1,10 @@ + + + + icon-dropdown-up + Created with Sketch. + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/assets/images/location.svg b/packages/Webkul/BookingProduct/src/Resources/assets/images/location.svg new file mode 100644 index 000000000..19fd55a0d --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/assets/images/location.svg @@ -0,0 +1,11 @@ + + + + tab/heading/icon/address + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/assets/images/phone.svg b/packages/Webkul/BookingProduct/src/Resources/assets/images/phone.svg new file mode 100644 index 000000000..e132e7b15 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/assets/images/phone.svg @@ -0,0 +1,18 @@ + + + + icon-menu copy + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/assets/images/slot.svg b/packages/Webkul/BookingProduct/src/Resources/assets/images/slot.svg new file mode 100644 index 000000000..18d00bd75 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/assets/images/slot.svg @@ -0,0 +1,15 @@ + + + + tab/heading/icon/calender + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/assets/sass/app.scss b/packages/Webkul/BookingProduct/src/Resources/assets/sass/app.scss new file mode 100644 index 000000000..cee8ee29f --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/assets/sass/app.scss @@ -0,0 +1,213 @@ +@import "icons"; + +.booking-information { + margin-bottom: 15px; + border-top: 1px solid #E8E8E8; + padding-top: 15px; + + .booking-info-row { + padding-left: 32px; + margin-bottom: 20px; + position: relative; + + .icon { + position: absolute; + left: 0; + top: -4px; + } + + .title { + color: #5E5E5E; + display: block; + margin-bottom: 5px; + } + + .value { + display: block; + margin-bottom: 5px; + + .text-danger { + color: #ff5656; + } + } + + .toggle { + color: #0041FF; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + .icon { + position: relative; + width: 10px; + height: 10px; + margin-left: 5px; + top: 0; + + &.arrow-down-icon { + background-image: url(../images/arrow-down.svg) !important; + } + + &.arrow-up-icon { + background-image: url(../images/arrow-up.svg) !important; + } + } + } + + .days-availability { + table { + margin-top: 10px; + border-collapse: collapse; + + tr { + td { + padding: 5px; + vertical-align: top; + + &:first-child { + padding-left: 0; + } + + &:last-child { + font-size: 14px; + padding-left: 15px; + padding-right: 0; + color: #5E5E5E; + } + + .text-danger { + color: #ff5656; + } + } + } + } + } + } + + .book-slots { + padding-top: 25px; + display: inline-block; + width: 100%; + border-top: solid 1px #e8e8e8; + + h3 { + font-weight: 600; + font-size: 16px; + color: #242424; + margin-top: 0; + } + + label { + color: #3a3a3a; + } + + .control-group { + label { + font-size: 16px; + } + + .radio { + display: inline-block; + } + } + + .control-group-container { + width: 100%; + float: left; + + .control-group:not(.quantity) { + width: 50%; + float: left; + + .control { + width: 100%; + } + + &.date { + padding-right: 5px; + + &::after { + position: absolute; + top: 14px; + right: 10px; + } + } + + &.slots { + &:first-child { + padding-right: 5px; + } + + &:last-child { + padding-left: 5px; + } + } + } + } + + .ticket-list { + + .ticket-item { + width: 100%; + display: inline-block; + padding: 16px 0; + border-bottom: solid 1px #e8e8e8; + + .ticket-info { + width: 50%; + float: left; + + .ticket-name { + color: #242424; + margin-bottom: 12px; + } + + .ticket-price { + color: #5E5E5E; + } + } + + .ticket-quantity { + width: 50%; + display: inline-block; + + .control-group { + margin: 0; + } + } + + p { + color: #242424; + margin-bottom: 0; + font-weight: 400; + } + } + } + + .ticket-total { + font-size: 16px; + font-weight: 600; + color: #242424; + padding-top: 16px; + // border-top: solid 1px #e8e8e8; + + > div { + margin-bottom: 12px; + + &:last-child { + margin-bottom: 0; + } + + p { + color: #242424; + font-weight: 400; + margin-top: 4px; + } + } + } + } +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/assets/sass/icons.scss b/packages/Webkul/BookingProduct/src/Resources/assets/sass/icons.scss new file mode 100644 index 000000000..77c4d1be1 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/assets/sass/icons.scss @@ -0,0 +1,17 @@ +.bp-location-icon { + background-image: url("../images/location.svg"); + width: 32px; + height: 32px; +} + +.bp-slot-icon { + background-image: url("../images/slot.svg"); + width: 32px; + height: 32px; +} + +.bp-phone-icon { + background-image: url("../images/phone.svg"); + width: 32px; + height: 32px; +} \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/lang/en/app.php b/packages/Webkul/BookingProduct/src/Resources/lang/en/app.php new file mode 100644 index 000000000..1d6d63b7d --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/lang/en/app.php @@ -0,0 +1,109 @@ + [ + 'catalog' => [ + 'products' => [ + 'booking' => 'Booking Information', + 'booking-type' => 'Booking Type', + 'default' => 'Default', + 'appointment-booking' => 'Appointment Booking', + 'event-booking' => 'Event Booking', + 'rental-booking' => 'Rental Booking', + 'table-booking' => 'Table Booking', + 'slot-duration' => 'Slot Duration (Mins)', + 'break-time' => 'Break Time b/w Slots (Mins)', + 'available-every-week' => 'Available Every Week', + 'yes' => 'Yes', + 'no' => 'No', + 'available-from' => 'Available From', + 'available-to' => 'Available To', + 'same-slot-all-days' => 'Same Slot All Days', + 'slot-has-quantity' => 'Slot has Quantity', + 'slots' => 'Slots', + 'from' => 'From', + 'to' => 'To', + 'qty' => 'Qty', + 'add-slot' => 'Add Slot', + 'sunday' => 'Sunday', + 'monday' => 'Monday', + 'tuesday' => 'Tuesday', + 'wednesday' => 'Wednesday', + 'thursday' => 'Thursday', + 'friday' => 'Friday', + 'saturday' => 'Saturday', + 'renting-type' => 'Renting Type', + 'daily' => 'Daily Basis', + 'hourly' => 'Hourly Basis', + 'daily-hourly' => 'Both (Daily and Hourly Basis)', + 'daily-price' => 'Daily Price', + 'hourly-price' => 'Hourly Price', + 'location' => 'Location', + 'show-location' => 'Show Location', + 'event-start-date' => 'Event Start Date', + 'event-end-date' => 'Event End Date', + 'tickets' => 'Tickets', + 'add-ticket' => 'Add Ticket', + 'name' => 'Name', + 'price' => 'Price', + 'quantity' => 'Quantity', + 'description' => 'Description', + 'charged-per' => 'Charged Per', + 'guest' => 'Guest', + 'table' => 'Table', + 'prevent-scheduling-before' => 'Prevent Scheduling Before', + 'guest-limit' => 'Guest Limit', + 'type' => 'Type', + 'many-bookings-for-one-day' => 'Many Bookings for One Day', + 'one-booking-for-many-days' => 'One Booking for Many Days', + 'day' => 'Day', + 'status' => 'Status', + 'open' => 'Open', + 'close' => 'Close' + ] + ] + ], + + 'shop' => [ + 'products' => [ + 'location' => 'Location', + 'contact' => 'Contact', + 'email' => 'Email', + 'slot-duration' => 'Slot Duration', + 'slot-duration-in-minutes' => ':minutes Minutes', + 'today-availability' => 'Today Availability', + 'sunday' => 'Sunday', + 'monday' => 'Monday', + 'tuesday' => 'Tuesday', + 'wednesday' => 'Wednesday', + 'thursday' => 'Thursday', + 'friday' => 'Friday', + 'saturday' => 'Saturday', + 'closed' => 'Closed', + 'book-an-appointment' => 'Book an Appointment', + 'date' => 'Date', + 'slot' => 'Slot', + 'rent-an-item' => 'Rent an Item', + 'choose-rent-option' => 'Choose Rent Option', + 'daily-basis' => 'Daily Basis', + 'hourly-basis' => 'Hourly Basis', + 'select-time-slot'=> 'Select time slot', + 'select-slot' => 'Select Slot', + 'select-date' => 'Select date', + 'select-rent-time' => 'Select Rent Time', + 'from' => 'From', + 'to' => 'To', + 'book-a-table' => 'Book a Table', + 'number-of-tables' => 'Number of Tables', + 'special-notes' => 'Special Request/Notes', + 'event-on' => 'Event On', + 'book-your-ticket' => 'Book Your Ticket', + 'per-ticket-price' => ':price Per Ticket', + 'number-of-tickets' => 'Number of Tickets', + 'total-tickets' => 'Total Tickets', + 'base-price' => 'Base Price', + 'total-price' => 'Total Price', + 'base-price-info' => '(This will be apply to each type of ticket for each quantity)' + ] + ] +]; \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking.blade.php new file mode 100644 index 000000000..d667982b3 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking.blade.php @@ -0,0 +1,84 @@ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.before', ['product' => $product]) !!} + + +
+ + + +
+
+ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.after', ['product' => $product]) !!} + +@push('scripts') + findOneByField('product_id', $product->id) ?> + + @parent + + + + + + @include ('bookingproduct::admin.catalog.products.accordians.booking.slots') + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/appointment.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/appointment.blade.php new file mode 100644 index 000000000..5d885c644 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/appointment.blade.php @@ -0,0 +1,131 @@ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.appointment.before', ['product' => $product]) !!} + + + +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.appointment.after', ['product' => $product]) !!} + +@push('scripts') + @parent + + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/default.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/default.blade.php new file mode 100644 index 000000000..07e0610a9 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/default.blade.php @@ -0,0 +1,311 @@ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.table.before', ['product' => $product]) !!} + + + +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.table.after', ['product' => $product]) !!} + + +@section('css') + +@stop + +@push('scripts') + @parent + + + + + + +@endpush \ No newline at end of file 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 new file mode 100644 index 000000000..99d9cc579 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/event.blade.php @@ -0,0 +1,186 @@ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.event.before', ['product' => $product]) !!} + + + +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.event.after', ['product' => $product]) !!} + +@push('scripts') + @parent + + + + + + + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/rental.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/rental.blade.php new file mode 100644 index 000000000..9abce359e --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/rental.blade.php @@ -0,0 +1,151 @@ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.rental.before', ['product' => $product]) !!} + + + +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.rental.after', ['product' => $product]) !!} + +@push('scripts') + @parent + + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/slots.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/slots.blade.php new file mode 100644 index 000000000..2edfc8fe0 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/slots.blade.php @@ -0,0 +1,211 @@ + + + + + \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/table.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/table.blade.php new file mode 100644 index 000000000..db57aa9d4 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/admin/catalog/products/accordians/booking/table.blade.php @@ -0,0 +1,150 @@ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.table.before', ['product' => $product]) !!} + + + +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.booking.table.after', ['product' => $product]) !!} + +@push('scripts') + @parent + + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking.blade.php new file mode 100644 index 000000000..77196fe48 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking.blade.php @@ -0,0 +1,60 @@ +@if ($product->type == 'booking') + + @if ($bookingProduct = app('\Webkul\BookingProduct\Repositories\BookingProductRepository')->findOneByField('product_id', $product->product_id)) + + @push('css') + + @endpush + + + + @push('scripts') + + + + + + @endpush + + @endif + +@endif \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/appointment.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/appointment.blade.php new file mode 100644 index 000000000..cc1e5ecd7 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/appointment.blade.php @@ -0,0 +1,55 @@ +
+ + + {{ __('bookingproduct::app.shop.products.slot-duration') }} : + + {{ __('bookingproduct::app.shop.products.slot-duration-in-minutes', ['minutes' => 30]) }} + +
+ +@inject ('bookingSlotHelper', 'Webkul\BookingProduct\Helpers\AppointmentSlot') + +
+ + + {{ __('bookingproduct::app.shop.products.today-availability') }} + + + + + {!! $bookingSlotHelper->getTodaySlotsHtml($bookingProduct) !!} + + + +
+ Show for all days + + +
+ +
+ + + + @foreach ($bookingSlotHelper->getWeekSlotDurations($bookingProduct) as $day) + + + + + + @endforeach + +
{{ $day['name'] }} + @if ($day['slots'] && count($day['slots'])) + @foreach ($day['slots'] as $slot) + {{ $slot['from'] . ' - ' . $slot['to'] }}
+ @endforeach + @else + {{ __('bookingproduct::app.shop.products.closed') }} + @endif +
+ +
+
+ +@include ('bookingproduct::shop.products.view.booking.slots', ['bookingProduct' => $bookingProduct]) \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/default.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/default.blade.php new file mode 100644 index 000000000..992374a3c --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/default.blade.php @@ -0,0 +1,10 @@ +
+ + + {{ __('bookingproduct::app.shop.products.slot-duration') }} : + + {{ __('bookingproduct::app.shop.products.slot-duration-in-minutes', ['minutes' => 30]) }} + +
+ +@include ('bookingproduct::shop.products.view.booking.slots', ['bookingProduct' => $bookingProduct]) \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/event.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/event.blade.php new file mode 100644 index 000000000..d018d298a --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/event.blade.php @@ -0,0 +1,80 @@ +@inject ('bookingSlotHelper', 'Webkul\BookingProduct\Helpers\EventSlot') + +
+ + + {{ __('bookingproduct::app.shop.products.event-on') }} + + + {!! $bookingSlotHelper->getEventDate($bookingProduct) !!} + +
+ + + +@push('scripts') + + + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/rental.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/rental.blade.php new file mode 100644 index 000000000..8de8a1d53 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/rental.blade.php @@ -0,0 +1,153 @@ + + +@push('scripts') + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/slots.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/slots.blade.php new file mode 100644 index 000000000..1be8e2e89 --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/slots.blade.php @@ -0,0 +1,58 @@ + + +@push('scripts') + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/table.blade.php b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/table.blade.php new file mode 100644 index 000000000..2c1dd395d --- /dev/null +++ b/packages/Webkul/BookingProduct/src/Resources/views/shop/products/view/booking/table.blade.php @@ -0,0 +1,69 @@ +
+ + + {{ __('bookingproduct::app.shop.products.slot-duration') }} : + + {{ __('bookingproduct::app.shop.products.slot-duration-in-minutes', ['minutes' => 30]) }} + +
+ +@inject ('bookingSlotHelper', 'Webkul\BookingProduct\Helpers\TableSlot') + +
+ + + {{ __('bookingproduct::app.shop.products.today-availability') }} + + + + + {!! $bookingSlotHelper->getTodaySlotsHtml($bookingProduct) !!} + + + +
+ Show for all days + + +
+ +
+ + + + @foreach ($bookingSlotHelper->getWeekSlotDurations($bookingProduct) as $day) + + + + + + @endforeach + +
{{ $day['name'] }} + @if ($day['slots'] && count($day['slots'])) + @foreach ($day['slots'] as $slot) + {{ $slot['from'] . ' - ' . $slot['to'] }}
+ @endforeach + @else + {{ __('bookingproduct::app.shop.products.closed') }} + @endif +
+ +
+
+ +@include ('bookingproduct::shop.products.view.booking.slots', [ + 'bookingProduct' => $bookingProduct, + 'title' => __('bookingproduct::app.shop.products.book-a-table') + ]) + +
+ + + @{{ errors.first('booking[qty]') }} +
+ +
+ +