221 lines
6.9 KiB
PHP
221 lines
6.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
use App\Http\Resources\Home\AllCategoriesResource;
|
|
use App\Http\Resources\Home\CampaignByOutletResource;
|
|
use App\Http\Resources\Home\CurrentOutletResource;
|
|
use App\Http\Resources\Home\OtherOutletResource;
|
|
use App\Http\Resources\Home\ProductByOutletResource;
|
|
use App\Models\Outlet;
|
|
use App\Models\Campaign;
|
|
use App\Models\Category;
|
|
use App\Models\Product;
|
|
use App\Models\Tenant;
|
|
use App\Traits\Multitenantable;
|
|
|
|
use Carbon\Carbon;
|
|
use function Symfony\Component\Clock\now;
|
|
|
|
class HomeService
|
|
{
|
|
use Multitenantable;
|
|
|
|
public function home($outletId)
|
|
{
|
|
$tenantId = config('app.current_tenant_id');
|
|
|
|
$tenant = Tenant::withoutGlobalScopes()
|
|
->select(
|
|
'online_open_time',
|
|
'online_close_time',
|
|
'is_close_service'
|
|
)
|
|
->where('uuid', $tenantId)
|
|
->first();
|
|
|
|
$currentOutlet = Outlet::select([
|
|
'uuid',
|
|
'name',
|
|
'full_address',
|
|
'latitude',
|
|
'longitude',
|
|
'is_active'
|
|
])
|
|
->where('uuid', $outletId)
|
|
->first();
|
|
|
|
if(!$currentOutlet) {
|
|
$currentOutlet = Outlet::select([
|
|
'uuid',
|
|
'name',
|
|
'full_address',
|
|
'latitude',
|
|
'longitude',
|
|
'is_active'
|
|
])
|
|
->where('is_main_outlet', true)
|
|
->first();
|
|
}
|
|
|
|
$campaigns = Campaign::select([
|
|
'campaigns.uuid',
|
|
'campaigns.action_type',
|
|
'campaigns.action_reference_id',
|
|
'campaigns.server_banner_url'
|
|
|
|
])
|
|
->with('outlet_campaigns')
|
|
->whereHas('outlet_campaigns', function($q) use ($currentOutlet) {
|
|
$q->select('outlet_campaigns.uuid')
|
|
->where('outlet_campaigns.outlet_id', $currentOutlet->uuid);
|
|
})
|
|
->where('campaigns.is_active', true)
|
|
->where(function ($q) {
|
|
$q->where(function ($q2) {
|
|
$q2->where('campaigns.start_date', '<=', Carbon::now()->startOfDay())
|
|
->where('campaigns.end_date', '>=', Carbon::now()->startOfDay());
|
|
})->orWhere(function ($q2) {
|
|
$q2->whereNull('campaigns.start_date')
|
|
->whereNull('campaigns.end_date');
|
|
});
|
|
})
|
|
->get();
|
|
|
|
$categories = Category::select([
|
|
'uuid',
|
|
'name',
|
|
'server_image_url'
|
|
|
|
])
|
|
->get();
|
|
|
|
$otherOutlets = Outlet::select([
|
|
'uuid',
|
|
'name',
|
|
'phone_number',
|
|
'full_address',
|
|
'latitude',
|
|
'longitude',
|
|
'server_banner_url',
|
|
'is_active'
|
|
])
|
|
->whereNot('uuid', $currentOutlet->uuid)
|
|
->get();
|
|
|
|
$productRecommendations = Product::select([
|
|
'products.uuid',
|
|
'products.name',
|
|
'products.server_image_url'
|
|
])
|
|
->whereHas('variants', function($q) use ($currentOutlet) {
|
|
$q->select('product_variants.is_visible_online')
|
|
->whereHas('inventory', function($q2) use ($currentOutlet) {
|
|
$q2->where('outlet_inventories.outlet_id', $currentOutlet->uuid);
|
|
})
|
|
->where('product_variants.is_visible_online', true);
|
|
})
|
|
->withSum(['variants as total_sold'], 'total_sold')
|
|
->withSum(['variants as total_rating'], 'total_rating')
|
|
->selectRaw('
|
|
(SELECT SUM(average_rating * total_rating)
|
|
FROM product_variants
|
|
WHERE product_variants.product_id = products.uuid
|
|
) /
|
|
NULLIF((SELECT SUM(total_rating)
|
|
FROM product_variants
|
|
WHERE product_variants.product_id = products.uuid
|
|
), 0) as average_rating
|
|
')
|
|
->with([
|
|
'variants.inventory' => function ($q) use ($currentOutlet) {
|
|
$q->select('outlet_inventories.item_id', 'selling_price')
|
|
->where('outlet_id', $currentOutlet->uuid);
|
|
}
|
|
])
|
|
->orderByDesc('total_sold')
|
|
->orderByDesc('average_rating')
|
|
->withCount('likes')
|
|
->take(5)
|
|
->get();
|
|
|
|
$products = Product::select([
|
|
'products.uuid',
|
|
'products.name',
|
|
'products.server_image_url'
|
|
])
|
|
->whereHas('variants', function($q) use ($currentOutlet) {
|
|
$q->select('product_variants.is_visible_online')
|
|
->whereHas('inventory', function($q2) use ($currentOutlet) {
|
|
$q2->where('outlet_inventories.outlet_id', $currentOutlet->uuid);
|
|
})
|
|
->where('product_variants.is_visible_online', true);
|
|
})
|
|
->withSum(['variants as total_sold'], 'total_sold')
|
|
->withSum(['variants as total_rating'], 'total_rating')
|
|
->selectRaw('
|
|
(SELECT SUM(average_rating * total_rating)
|
|
FROM product_variants
|
|
WHERE product_variants.product_id = products.uuid
|
|
) /
|
|
NULLIF((SELECT SUM(total_rating)
|
|
FROM product_variants
|
|
WHERE product_variants.product_id = products.uuid
|
|
), 0) as average_rating
|
|
')
|
|
->with([
|
|
'variants.inventory' => function ($q) use ($currentOutlet) {
|
|
$q->select('outlet_inventories.item_id', 'selling_price')
|
|
->where('outlet_id', $currentOutlet->uuid);
|
|
}
|
|
])
|
|
->orderByDesc('total_sold')
|
|
->orderByDesc('average_rating')
|
|
->orderByDesc('created_at')
|
|
->withCount('likes')
|
|
->get();
|
|
|
|
return [
|
|
'operational_service' => $tenant,
|
|
'current_outlet' => new CurrentOutletResource($currentOutlet),
|
|
'campaign_by_outlets' => CampaignByOutletResource::collection($campaigns),
|
|
'all_categories' => AllCategoriesResource::collection($categories),
|
|
'other_outlets' => OtherOutletResource::collection($otherOutlets),
|
|
'product_recommendations' => ProductByOutletResource::collection($productRecommendations),
|
|
'all_products' => ProductByOutletResource::collection($products)
|
|
];
|
|
}
|
|
|
|
public function getOutlets()
|
|
{
|
|
$outlets = Outlet::select([
|
|
'uuid',
|
|
'name',
|
|
'phone_number',
|
|
'full_address',
|
|
'latitude',
|
|
'longitude',
|
|
'server_banner_url',
|
|
'is_active'
|
|
])
|
|
->whereNotNull('full_address')
|
|
->whereNotNull('latitude')
|
|
->whereNotNull('longitude')
|
|
->get();
|
|
|
|
return OtherOutletResource::collection($outlets);
|
|
}
|
|
|
|
public function getMainOutlet()
|
|
{
|
|
return Outlet::select([
|
|
'uuid',
|
|
'name',
|
|
'phone_number',
|
|
'full_address',
|
|
'latitude',
|
|
'longitude',
|
|
])
|
|
->where('is_main_outlet', true)
|
|
->first();
|
|
}
|
|
} |