feat: add cashier role checks to filter data in analysis and dashboard services
This commit is contained in:
parent
05707aad7d
commit
097b7f7192
@ -9,7 +9,6 @@
|
||||
use App\Enums\PaymentType;
|
||||
use App\Enums\PayrollStatus;
|
||||
use App\Enums\PriceType;
|
||||
use App\Enums\ProductStockQuality;
|
||||
use App\Enums\RawMaterialUnit;
|
||||
use App\Enums\Role;
|
||||
use App\Models\Attendance;
|
||||
@ -21,13 +20,13 @@
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Payroll;
|
||||
use App\Models\ProductPrice;
|
||||
use App\Models\ProductVariant;
|
||||
use App\Models\Purchase;
|
||||
use App\Models\RawMaterialPrice;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AnalysisService
|
||||
@ -88,14 +87,14 @@ public function getAttendanceStats(?string $startDate, ?string $endDate, ?User $
|
||||
|
||||
$employees = Employee::whereHas(
|
||||
'user',
|
||||
fn($q) => $q
|
||||
fn ($q) => $q
|
||||
->where('is_active', true)
|
||||
->whereHas(
|
||||
'roles',
|
||||
fn($r) => $r
|
||||
fn ($r) => $r
|
||||
->whereHas(
|
||||
'permissions',
|
||||
fn($p) => $p
|
||||
fn ($p) => $p
|
||||
->where('name', 'attendances.create')
|
||||
)
|
||||
)
|
||||
@ -265,6 +264,10 @@ public function getRevenueByStockType(?string $startDate, ?string $endDate, ?Use
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$stockQualitySubquery = OrderItem::select('order_id')
|
||||
->selectRaw('MIN(stock_quality) as stock_quality')
|
||||
->groupBy('order_id');
|
||||
@ -323,6 +326,10 @@ public function getRevenueSummary(?string $startDate, ?string $endDate, ?User $u
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$stats = (clone $query)
|
||||
->selectRaw('COUNT(*) as total_orders')
|
||||
->selectRaw('COALESCE(SUM(total_amount), 0) as total_revenue')
|
||||
@ -367,6 +374,10 @@ public function getMonthlyRevenue(?string $startDate, ?string $endDate, ?User $u
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$monthly = (clone $query)
|
||||
->selectRaw("DATE_FORMAT(created_at, '%b %Y') as month")
|
||||
->selectRaw('COALESCE(SUM(total_amount), 0) as total')
|
||||
@ -443,6 +454,10 @@ public function getMonthlyRevenueByChannel(?string $startDate, ?string $endDate,
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$monthly = (clone $query)
|
||||
->selectRaw("DATE_FORMAT(created_at, '%b %Y') as month")
|
||||
->selectRaw("COALESCE(SUM(CASE WHEN channel = 'store' THEN total_amount ELSE 0 END), 0) as store")
|
||||
@ -451,7 +466,7 @@ public function getMonthlyRevenueByChannel(?string $startDate, ?string $endDate,
|
||||
->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m')"), DB::raw("DATE_FORMAT(created_at, '%b %Y')"))
|
||||
->orderBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m')"))
|
||||
->get()
|
||||
->map(fn($item) => [
|
||||
->map(fn ($item) => [
|
||||
'month' => $item->month,
|
||||
'store' => (int) $item->store,
|
||||
'shopee' => (int) $item->shopee,
|
||||
@ -470,12 +485,16 @@ public function getRevenueByPaymentType(?string $startDate, ?string $endDate, ?U
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$data = (clone $query)
|
||||
->select('payment_type')
|
||||
->selectRaw('COALESCE(SUM(total_amount), 0) as total')
|
||||
->groupBy('payment_type')
|
||||
->get()
|
||||
->map(fn($item) => [
|
||||
->map(fn ($item) => [
|
||||
'payment_type' => $item->payment_type,
|
||||
'label' => $item->payment_type->label(),
|
||||
'total' => (int) $item->total,
|
||||
@ -514,6 +533,10 @@ public function getExpenseSummary(?string $startDate, ?string $endDate, ?User $u
|
||||
$expenseQuery = Expense::query();
|
||||
$this->applyDateFilter($expenseQuery, $startDate, $endDate, 'expenses.created_at');
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$expenseQuery->whereIn('created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$advanceQuery = EmployeeAdvance::where('status', EmployeeAdvanceStatus::REPAID);
|
||||
$this->applyDateFilter($advanceQuery, $startDate, $endDate, 'employee_advances.created_at');
|
||||
|
||||
@ -589,6 +612,10 @@ public function getMonthlyExpense(?string $startDate, ?string $endDate, ?User $u
|
||||
$expenseMonthly = Expense::query();
|
||||
$this->applyDateFilter($expenseMonthly, $startDate, $endDate, 'expenses.created_at');
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$expenseMonthly->whereIn('created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$expenseByMonth = (clone $expenseMonthly)->toBase()
|
||||
->selectRaw("DATE_FORMAT(created_at, '%b %Y') as month")
|
||||
->selectRaw('COALESCE(SUM(amount), 0) as expense')
|
||||
@ -650,6 +677,10 @@ public function getBusyHours(?string $startDate, ?string $endDate, ?User $user =
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$hours = range(0, 23);
|
||||
$hourCounts = (clone $query)
|
||||
->selectRaw('HOUR(created_at) as hour')
|
||||
@ -675,6 +706,10 @@ public function getProfitMetrics(?string $startDate, ?string $endDate, ?User $us
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$stats = (clone $query)
|
||||
->selectRaw('COUNT(*) as total_orders')
|
||||
->selectRaw('COALESCE(SUM(total_amount), 0) as total_revenue')
|
||||
@ -739,6 +774,10 @@ public function getTopCustomers(?string $startDate, ?string $endDate, ?User $use
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
return (clone $query)->toBase()
|
||||
->join('customers', 'orders.customer_id', '=', 'customers.id')
|
||||
->select('customers.name')
|
||||
@ -760,6 +799,10 @@ public function getTopProducts(?string $startDate, ?string $endDate, ?User $user
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
return (clone $query)->toBase()
|
||||
->join('order_items', 'orders.id', '=', 'order_items.order_id')
|
||||
->join('product_variants', 'order_items.product_variant_id', '=', 'product_variants.id')
|
||||
@ -783,6 +826,10 @@ public function getRevenueTrend(?string $startDate, ?string $endDate, ?User $use
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
return (clone $query)
|
||||
->join('order_items', 'orders.id', '=', 'order_items.order_id')
|
||||
->selectRaw('DATE(orders.created_at) as date')
|
||||
@ -790,7 +837,7 @@ public function getRevenueTrend(?string $startDate, ?string $endDate, ?User $use
|
||||
->groupBy(DB::raw('DATE(orders.created_at)'))
|
||||
->orderBy(DB::raw('DATE(orders.created_at)'))
|
||||
->get()
|
||||
->map(fn($item) => [
|
||||
->map(fn ($item) => [
|
||||
'date' => $item->date,
|
||||
'qty' => (int) $item->qty,
|
||||
])
|
||||
@ -807,6 +854,10 @@ public function getMarketingSales(?string $startDate, ?string $endDate, ?User $u
|
||||
$query->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$query->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$orders = (clone $query)
|
||||
->join('users', 'orders.marketing_id', '=', 'users.id')
|
||||
->leftJoin('user_profiles', 'users.id', '=', 'user_profiles.user_id')
|
||||
@ -850,6 +901,10 @@ public function getOrderStats(?string $startDate, ?string $endDate, ?User $user
|
||||
$baseQuery->where('orders.marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$baseQuery->whereIn('orders.created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$byChannel = collect(OrderChannel::values())->map(function ($channel) use ($baseQuery) {
|
||||
$count = (clone $baseQuery)->where('channel', $channel)->count();
|
||||
$label = OrderChannel::from($channel)->label();
|
||||
@ -882,7 +937,7 @@ public function getOrderStats(?string $startDate, ?string $endDate, ?User $user
|
||||
->groupBy('marketing_id')
|
||||
->with('marketing:id')
|
||||
->get()
|
||||
->map(fn($item) => [
|
||||
->map(fn ($item) => [
|
||||
'name' => $item->marketing?->userProfile->full_name ?? '-',
|
||||
'count' => $item->count,
|
||||
'total' => (int) $item->total,
|
||||
@ -925,6 +980,16 @@ private function isMarketingUser(User $user): bool
|
||||
]);
|
||||
}
|
||||
|
||||
private function isCashierUser(User $user): bool
|
||||
{
|
||||
return $user->hasRole(Role::CASHIER->value);
|
||||
}
|
||||
|
||||
private function getCashierUserIds(): Collection
|
||||
{
|
||||
return User::whereHas('roles', fn ($q) => $q->where('name', Role::CASHIER->value))->pluck('id');
|
||||
}
|
||||
|
||||
private function isPurchaseVisible(User $user): bool
|
||||
{
|
||||
return $user->hasAnyRole([
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class DashboardService
|
||||
{
|
||||
@ -129,6 +130,10 @@ public function getRevenueSummary(?User $user = null): array
|
||||
$baseQuery->where('marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$baseQuery->whereIn('created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$stats = (clone $baseQuery)
|
||||
->selectRaw('COUNT(*) as total_orders')
|
||||
->selectRaw('COALESCE(SUM(total_amount), 0) as total_revenue')
|
||||
@ -194,12 +199,24 @@ public function getExpenseSummary(?User $user = null): array
|
||||
];
|
||||
}
|
||||
|
||||
$expenseTotal = Expense::whereDate('created_at', $today)
|
||||
$expenseQuery = Expense::whereDate('created_at', $today);
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$expenseQuery->whereIn('created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$expenseTotal = $expenseQuery
|
||||
->selectRaw('COALESCE(SUM(amount), 0) as total')
|
||||
->first();
|
||||
|
||||
$advanceTotal = EmployeeAdvance::whereDate('created_at', $today)
|
||||
->disbursed()
|
||||
$advanceQuery = EmployeeAdvance::whereDate('created_at', $today)
|
||||
->disbursed();
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$advanceQuery->whereHas('employee.user', fn ($q) => $q->whereIn('id', $this->getCashierUserIds()));
|
||||
}
|
||||
|
||||
$advanceTotal = $advanceQuery
|
||||
->selectRaw('COALESCE(SUM(amount), 0) as total')
|
||||
->first();
|
||||
|
||||
@ -219,6 +236,10 @@ public function getOrderStats(?User $user = null): array
|
||||
$baseQuery->where('marketing_id', $user->id);
|
||||
}
|
||||
|
||||
if ($user && $this->isCashierUser($user)) {
|
||||
$baseQuery->whereIn('created_by_id', $this->getCashierUserIds());
|
||||
}
|
||||
|
||||
$byChannel = collect(OrderChannel::values())->map(function ($channel) use ($baseQuery) {
|
||||
$count = (clone $baseQuery)->where('channel', $channel)->count();
|
||||
$label = OrderChannel::from($channel)->label();
|
||||
@ -330,6 +351,16 @@ private function isMarketingUser(User $user): bool
|
||||
]);
|
||||
}
|
||||
|
||||
private function isCashierUser(User $user): bool
|
||||
{
|
||||
return $user->hasRole(Role::CASHIER->value);
|
||||
}
|
||||
|
||||
private function getCashierUserIds(): Collection
|
||||
{
|
||||
return User::whereHas('roles', fn ($q) => $q->where('name', Role::CASHIER->value))->pluck('id');
|
||||
}
|
||||
|
||||
private function applyMarketingFilter(Builder $query, User $user, string $column = 'marketing_id'): Builder
|
||||
{
|
||||
if ($this->isMarketingUser($user)) {
|
||||
|
||||
@ -564,6 +564,10 @@ export default function Analysis({
|
||||
return { statCards: 1, revenue: 4, revenueByChannel: 5, orderPie: 6, expense: 7, totalOrder: 8, revenueTrend: 9, marketingSales: 10, topSuppliers: 11, topProducts: 12, topCustomers: 13, busyHours: 14 };
|
||||
}
|
||||
|
||||
if (hasRole('cashier')) {
|
||||
return { statCards: 1, revenue: 2, revenueByChannel: 3, orderPie: 4, totalOrder: 5, topProducts: 6, topCustomers: 7 };
|
||||
}
|
||||
|
||||
if (hasRole('marketing')) {
|
||||
return { statCards: 1, revenue: 2, revenueByChannel: 3, orderPie: 4, totalOrder: 5, revenueTrend: 6, topProducts: 7, topCustomers: 8 };
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user