QueenFruits/Backend/app/Services/HomeService.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();
}
}