¨4.0.1¨
This commit is contained in:
@@ -14,6 +14,7 @@ class FlashSaleTabs extends Tabs
|
||||
*/
|
||||
protected $buttonOffset = false;
|
||||
|
||||
|
||||
public function make()
|
||||
{
|
||||
$this->group('flash_sale_information', trans('flashsale::flash_sales.tabs.group.flash_sale_information'))
|
||||
@@ -22,6 +23,7 @@ class FlashSaleTabs extends Tabs
|
||||
->add($this->settings());
|
||||
}
|
||||
|
||||
|
||||
private function products()
|
||||
{
|
||||
return tap(new Tab('products', trans('flashsale::flash_sales.tabs.products')), function (Tab $tab) {
|
||||
@@ -39,6 +41,7 @@ class FlashSaleTabs extends Tabs
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private function settings()
|
||||
{
|
||||
return tap(new Tab('settings', trans('flashsale::flash_sales.tabs.settings')), function (Tab $tab) {
|
||||
|
||||
@@ -19,6 +19,7 @@ class CreateFlashSalesTable extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@ class CreateFlashSaleTranslationsTable extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
|
||||
@@ -27,6 +27,7 @@ class CreateFlashSaleProductsTable extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,7 @@ class CreateFlashSaleProductOrdersTable extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
|
||||
@@ -15,7 +15,6 @@ class FlashSaleDatabaseSeeder extends Seeder
|
||||
public function run()
|
||||
{
|
||||
Model::unguard();
|
||||
|
||||
// $this->call("OthersTableSeeder");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,18 @@ class FlashSale extends Model
|
||||
* @var self
|
||||
*/
|
||||
private static $active;
|
||||
|
||||
/**
|
||||
* The attributes that are translatable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $translatedAttributes = ['campaign_name'];
|
||||
/**
|
||||
* The relations to eager load on every query.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $with = ['translations'];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
@@ -33,46 +37,12 @@ class FlashSale extends Model
|
||||
*/
|
||||
protected $fillable = ['id'];
|
||||
|
||||
/**
|
||||
* The attributes that are translatable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $translatedAttributes = ['campaign_name'];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::saved(function ($flashSale) {
|
||||
if (! empty(request()->has('products'))) {
|
||||
$flashSale->saveProducts(request('products'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active flash sale.
|
||||
*
|
||||
* @param int $id
|
||||
* @return self
|
||||
*/
|
||||
public static function active()
|
||||
{
|
||||
if (is_callable(self::$active)) {
|
||||
return call_user_func(self::$active);
|
||||
}
|
||||
|
||||
return new self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an active flash sale campaign.
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function activeCampaign($id)
|
||||
@@ -84,16 +54,30 @@ class FlashSale extends Model
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static function contains(Product $product)
|
||||
{
|
||||
return self::active()->products->contains($product);
|
||||
}
|
||||
|
||||
public static function pivot(Product $product)
|
||||
|
||||
/**
|
||||
* Get the active flash sale.
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function active()
|
||||
{
|
||||
return self::active()->products->find($product)->pivot;
|
||||
if (is_callable(self::$active)) {
|
||||
return call_user_func(self::$active);
|
||||
}
|
||||
|
||||
return new self;
|
||||
}
|
||||
|
||||
|
||||
public static function remainingQty(Product $product)
|
||||
{
|
||||
$flashSaleProduct = self::pivot($product);
|
||||
@@ -101,13 +85,36 @@ class FlashSale extends Model
|
||||
return $flashSaleProduct->qty - $flashSaleProduct->sold;
|
||||
}
|
||||
|
||||
public function scopeWithEligibleProducts($query)
|
||||
|
||||
public static function pivot(Product $product)
|
||||
{
|
||||
$query->with(['products' => function ($query) {
|
||||
$query->forCard()->wherePivot('end_date', '>', now());
|
||||
}]);
|
||||
return self::active()->products->find($product)->pivot;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
static::saved(function ($flashSale) {
|
||||
if (!empty(request()->has('products'))) {
|
||||
$flashSale->saveProducts(request('products'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function saveProducts($products)
|
||||
{
|
||||
$this->products()->sync(
|
||||
$this->buildProductPivots($products)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function products()
|
||||
{
|
||||
return $this->belongsToMany(Product::class, 'flash_sale_products')
|
||||
@@ -116,18 +123,27 @@ class FlashSale extends Model
|
||||
->orderBy('position');
|
||||
}
|
||||
|
||||
|
||||
public function scopeWithEligibleProducts($query)
|
||||
{
|
||||
$query->with(['products' => function ($query) {
|
||||
$query->forCard()->wherePivot('end_date', '<>', null);
|
||||
}]);
|
||||
}
|
||||
|
||||
|
||||
public function getPriceAttribute($price)
|
||||
{
|
||||
return Money::inDefaultCurrency($price);
|
||||
}
|
||||
|
||||
public function saveProducts($products)
|
||||
|
||||
public function table()
|
||||
{
|
||||
$this->products()->sync(
|
||||
$this->buildProductPivots($products)
|
||||
);
|
||||
return new AdminTable($this->query());
|
||||
}
|
||||
|
||||
|
||||
private function buildProductPivots($products)
|
||||
{
|
||||
return collect($products)->values()->mapWithKeys(function ($attributes, $index) {
|
||||
@@ -139,9 +155,4 @@ class FlashSale extends Model
|
||||
]];
|
||||
});
|
||||
}
|
||||
|
||||
public function table()
|
||||
{
|
||||
return new AdminTable($this->query());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,19 +38,22 @@ class FlashSaleProduct extends Pivot
|
||||
*/
|
||||
protected $appends = ['sold'];
|
||||
|
||||
|
||||
public function getSoldAttribute()
|
||||
{
|
||||
return $this->orders()->sum('qty');
|
||||
}
|
||||
|
||||
public function getPriceAttribute($price)
|
||||
{
|
||||
return Money::inDefaultCurrency($price);
|
||||
}
|
||||
|
||||
public function orders()
|
||||
{
|
||||
return $this->belongsToMany(Order::class, 'flash_sale_product_orders', 'flash_sale_product_id')
|
||||
->withPivot('qty');
|
||||
}
|
||||
|
||||
|
||||
public function getPriceAttribute($price)
|
||||
{
|
||||
return Money::inDefaultCurrency($price);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class SaveFlashSaleRequest extends Request
|
||||
*/
|
||||
protected $availableAttributes = 'flashsale::attributes';
|
||||
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
|
||||
namespace Modules\FlashSale\Providers;
|
||||
|
||||
use Modules\Support\Traits\AddsAsset;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Admin\Ui\Facades\TabManager;
|
||||
use Modules\FlashSale\Admin\FlashSaleTabs;
|
||||
|
||||
class FlashSaleServiceProvider extends ServiceProvider
|
||||
{
|
||||
use AddsAsset;
|
||||
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
@@ -19,7 +16,5 @@ class FlashSaleServiceProvider extends ServiceProvider
|
||||
public function boot()
|
||||
{
|
||||
TabManager::register('flash_sales', FlashSaleTabs::class);
|
||||
|
||||
$this->addAdminAssets('admin.flash_sales.(create|edit)', ['admin.media.js', 'admin.flashsale.js']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import FlashSaleProduct from './FlashSaleProduct';
|
||||
import FlashSaleProduct from "./FlashSaleProduct";
|
||||
|
||||
export default class {
|
||||
constructor() {
|
||||
this.productCount = 0;
|
||||
|
||||
this.addFlashSaleProducts(FleetCart.data['flash_sale.products']);
|
||||
this.addFlashSaleProducts(FleetCart.data["flash_sale.products"]);
|
||||
|
||||
if (this.productCount === 0) {
|
||||
this.addProduct();
|
||||
}
|
||||
|
||||
this.addFlashSaleProductsError(FleetCart.errors['flash_sale.products']);
|
||||
this.addFlashSaleProductsError(FleetCart.errors["flash_sale.products"]);
|
||||
|
||||
this.attachEventListeners();
|
||||
this.makeProductPanelsSortable();
|
||||
@@ -23,9 +23,12 @@ export default class {
|
||||
}
|
||||
|
||||
addProduct(attributes = {}) {
|
||||
let productTemplate = new FlashSaleProduct({ productPanelNumber: this.productCount++, product: attributes });
|
||||
let productTemplate = new FlashSaleProduct({
|
||||
productPanelNumber: this.productCount++,
|
||||
product: attributes,
|
||||
});
|
||||
|
||||
$('#products-wrapper').append(productTemplate.render());
|
||||
$("#products-wrapper").append(productTemplate.render());
|
||||
|
||||
window.admin.selectize();
|
||||
}
|
||||
@@ -34,31 +37,31 @@ export default class {
|
||||
for (let key in errors) {
|
||||
let parent = this.getInputFieldForKey(key).parent();
|
||||
|
||||
parent.addClass('has-error');
|
||||
parent.addClass("has-error");
|
||||
parent.append(`<span class="help-block">${errors[key][0]}</span>`);
|
||||
}
|
||||
}
|
||||
|
||||
getInputFieldForKey(key) {
|
||||
let keyParts = key.split('.');
|
||||
let keyParts = key.split(".");
|
||||
|
||||
// Replace all "_" to "-".
|
||||
keyParts = keyParts.map(k => {
|
||||
return k.split('_').join('-');
|
||||
keyParts = keyParts.map((k) => {
|
||||
return k.split("_").join("-");
|
||||
});
|
||||
|
||||
return $(`#${keyParts.join('-')}`);
|
||||
return $(`#${keyParts.join("-")}`);
|
||||
}
|
||||
|
||||
attachEventListeners() {
|
||||
$('.add-product').on('click', () => {
|
||||
$(".add-product").on("click", () => {
|
||||
this.addProduct();
|
||||
});
|
||||
}
|
||||
|
||||
makeProductPanelsSortable() {
|
||||
Sortable.create(document.getElementById('products-wrapper'), {
|
||||
handle: '.drag-icon',
|
||||
Sortable.create(document.getElementById("products-wrapper"), {
|
||||
handle: ".drag-handle",
|
||||
animation: 150,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ return [
|
||||
'quantity' => 'Quantity',
|
||||
'campaign_name' => 'Campaign Name',
|
||||
|
||||
// validation
|
||||
# validation
|
||||
'products.*.product_id' => 'Product',
|
||||
'products.*.end_date' => 'End Date',
|
||||
'products.*.price' => 'Price',
|
||||
|
||||
@@ -16,3 +16,9 @@
|
||||
@endsection
|
||||
|
||||
@include('flashsale::admin.flash_sales.partials.shortcuts')
|
||||
|
||||
@push('globals')
|
||||
@vite([
|
||||
'Modules/FlashSale/Resources/assets/admin/js/main.js',
|
||||
])
|
||||
@endpush
|
||||
@@ -18,3 +18,9 @@
|
||||
@endsection
|
||||
|
||||
@include('flashsale::admin.flash_sales.partials.shortcuts')
|
||||
|
||||
@push('globals')
|
||||
@vite([
|
||||
'Modules/FlashSale/Resources/assets/admin/js/main.js',
|
||||
])
|
||||
@endpush
|
||||
@@ -25,7 +25,7 @@
|
||||
@endcomponent
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
<script type="module">
|
||||
new DataTable('#flash_sales-table .table', {
|
||||
columns: [
|
||||
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
@endpush
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
<script type="module">
|
||||
keypressAction([
|
||||
{ key: 'b', route: "{{ route('admin.flash_sales.index') }}" }
|
||||
]);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script type="text/html" id="flash-sale-product-template">
|
||||
<div class="panel">
|
||||
<div class="panel-header clearfix">
|
||||
<span class="drag-icon pull-left">
|
||||
<span class="drag-handle pull-left">
|
||||
<i class="fa"></i>
|
||||
<i class="fa"></i>
|
||||
</span>
|
||||
@@ -48,8 +48,10 @@
|
||||
{{ trans('flashsale::attributes.end_date') }}<span class="m-l-5 text-red">*</span>
|
||||
</label>
|
||||
|
||||
<input type="text"
|
||||
<input
|
||||
type="text"
|
||||
name="products[<%- productPanelNumber %>][end_date]"
|
||||
data-time
|
||||
class="form-control datetime-picker"
|
||||
id="products-<%- productPanelNumber %>-campaign-end"
|
||||
value="<%- product.pivot.end_date %>"
|
||||
|
||||
@@ -8,6 +8,12 @@ Route::get('flash-sales', [
|
||||
'middleware' => 'can:admin.flash_sales.index',
|
||||
]);
|
||||
|
||||
Route::get('flash-sales/index/table', [
|
||||
'as' => 'admin.flash_sales.table',
|
||||
'uses' => 'FlashSaleController@table',
|
||||
'middleware' => 'can:admin.flash_sales.index',
|
||||
]);
|
||||
|
||||
Route::get('flash-sales/create', [
|
||||
'as' => 'admin.flash_sales.create',
|
||||
'uses' => 'FlashSaleController@create',
|
||||
|
||||
Reference in New Issue
Block a user