Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 0 additions & 64 deletions .env.example

This file was deleted.

14 changes: 8 additions & 6 deletions app/Enums/CompanySettingsEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;

enum CompanySettingsEnum: string
{
Expand Down Expand Up @@ -54,8 +55,8 @@ public static function getTimezones(): array
$zones = \DateTimeZone::listIdentifiers($mask);
foreach ($zones as $timezone) {
// Lets sample the time there right now
$time = new \DateTime(null, new \DateTimeZone($timezone));
$utcTime = new \DateTime(null, new \DateTimeZone('UTC'));
$time = new \DateTime('now', new \DateTimeZone($timezone));
$utcTime = new \DateTime('now', new \DateTimeZone('UTC'));

// Us Americans can't handle millitary time
$ampm = $time->format('H') > 12 ? ' (' . $time->format('g:i a') . ')' : '';
Expand Down Expand Up @@ -126,15 +127,16 @@ public function getNextDocNumber(): int
throw new \Exception($this . ' setting is not allowed to get the next number');
}

$number = auth()->user()->company->settings()
$user = Auth::user();
$number = $user->company->settings()
->get(
$this->value,
0
);

$number++;

auth()->user()->company->settings()
$user->company->settings()
->set(
$this->value,
$number
Expand All @@ -150,8 +152,8 @@ private function formatDocNumer(string $number): string

$setting = str_replace('LAST', 'FORMAT', $this->name);

if (auth()->user()) {
$result = auth()->user()->company->settings()
if (Auth::user()) {
$result = Auth::user()->company->settings()
->get(
$setting,
'ym000'
Expand Down
23 changes: 20 additions & 3 deletions app/Enums/InvoiceStatusEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,41 @@
namespace App\Enums;

use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasDescription;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Contracts\HasLabel;
use Illuminate\Support\Str;

enum InvoiceStatusEnum: string implements HasLabel, HasColor, HasIcon
enum InvoiceStatusEnum: string implements HasLabel, HasColor, HasIcon, HasDescription
{
case DRAFT = 'draft';
case SENT = 'sent';
case UNPAID = 'unpaid';
case PARTIALLY_PAID = 'partially_paid';
case PAID = 'paid';
case CANCELED = 'canceled';

public function getLabel(): string
{
return ucwords(__($this->value));
return __(
Str::ucfirst(
Str::replace('_', ' ', $this->value)
)
);
}

public function getDescription(): ?string
{
return $this->getLabel();
}

public function getColor(): string
{
return match ($this) {
self::DRAFT => 'gray',
self::SENT => 'info',
self::UNPAID => 'warning',
self::PARTIALLY_PAID => 'warning',
self::PAID => 'success',
self::CANCELED => 'danger',
};
Expand All @@ -33,8 +48,10 @@ public function getIcon(): ?string
return match ($this) {
self::DRAFT => 'heroicon-o-document-duplicate',
self::SENT => 'heroicon-o-document',
self::UNPAID => 'heroicon-o-x-circle',
self::PARTIALLY_PAID => 'heroicon-o-clipboard-document-check',
self::PAID => 'heroicon-o-check',
self::CANCELED => 'heroicon-o-x-circle',
self::CANCELED => 'heroicon-o-exclamation-circle',
};
}

Expand Down
74 changes: 74 additions & 0 deletions app/Filament/App/Pages/InventoryDashboard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace App\Filament\App\Pages;

use App\Models\Material;
use App\Models\StockMovement;
use App\Models\Branch;
use Filament\Pages\Page;
use Illuminate\Support\Collection;

class InventoryDashboard extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-chart-bar';

protected static string $view = 'filament.app.pages.inventory-dashboard';

protected static ?string $navigationGroup = 'Inventory';

protected static ?string $navigationLabel = 'Inventory Dashboard';

protected static ?int $navigationSort = 0;

public function getLowStockMaterials(): Collection
{
return Material::all()->filter(function ($material) {
return $material->stock_level <= $material->reorder_point;
});
}

public function getTotalMaterials(): int
{
return Material::count();
}

public function getTotalBranches(): int
{
return Branch::where('is_active', true)->count();
}

public function getRecentMovements(): Collection
{
return StockMovement::with(['material', 'fromBranch', 'toBranch'])
->orderBy('created_at', 'desc')
->limit(10)
->get();
}

public function getStockByBranch(): Collection
{
$branches = Branch::where('is_active', true)->get();

return $branches->map(function ($branch) {
$stockIn = StockMovement::where('to_branch_id', $branch->id)
->whereIn('type', ['in', 'transfer', 'adjustment_add'])
->sum('qty');

$stockOut = StockMovement::where('from_branch_id', $branch->id)
->whereIn('type', ['out', 'transfer', 'adjustment_subtract'])
->sum('qty');

return [
'name' => $branch->name,
'stock' => $stockIn - $stockOut,
];
});
}

public function getTotalStockValue(): float
{
return Material::all()->sum(function ($material) {
return $material->stock_level * ($material->cost_price ?? 0);
});
}
}
84 changes: 62 additions & 22 deletions app/Filament/App/Pages/MyCompany.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
use App\Enums\MenuGroupsEnum;
use App\Enums\MenuSortEnum;
use App\Models\Company;
use App\Models\User;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
Expand All @@ -19,6 +16,7 @@
use Filament\Pages\Page;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Js;
use Illuminate\Support\Facades\Auth;

class MyCompany extends Page implements HasForms
{
Expand All @@ -27,7 +25,7 @@ class MyCompany extends Page implements HasForms

public ?array $data = [];

public Company $company;
public ?Company $company = null;

protected static ?string $navigationIcon = 'heroicon-o-home';

Expand Down Expand Up @@ -57,7 +55,36 @@ public static function getNavigationGroup(): ?string

public function mount(): void
{
$this->company = auth()->user()->company;
/** @var User $user */
$user = Auth::user();

if (!$user instanceof User) {
return;
}

// Check if user has a company assigned
if ($user->company_id) {
$this->company = Company::find($user->company_id);
}

// If no company assigned, check if user has one via user_id
if (!$this->company) {
$this->company = Company::where('user_id', $user->id)->first();

// If found, assign it to user
if ($this->company) {
User::where('id', $user->id)->update(['company_id' => $this->company->id]);
}
}

// If still no company, create a new empty one for the form
if (!$this->company) {
$this->company = new Company([
'name' => $user->name,
'email' => $user->email,
]);
}

$this->form->fill($this->company->toArray());
}

Expand All @@ -68,34 +95,47 @@ public function form(Form $form): Form
TextInput::make('name')
->label(__('Name'))
->required(),

TextInput::make('email')
->label(__('Email'))
->email(),
->email()
->required(),

TextInput::make('phone')
->label(__('Phone'))
->tel(),

TextInput::make('website'),
SpatieMediaLibraryFileUpload::make('logo')
->translateLabel()
->disk('companies-logo')
->image()
->imageEditor()
->imageEditorAspectRatios([
'16:9',
'4:3',
'1:1',
])
])
->statePath('data')
->model($this->company);
->statePath('data');
}

public function save(): void
{
$this->company->update($this->form->getState());
$data = $this->form->getState();

/** @var User $user */
$user = Auth::user();

if ($this->company && $this->company->exists) {
// Update existing company
$this->company->update($data);
} else {
// Create new company
$data['user_id'] = $user->id;
$this->company = Company::create($data);
}

// Assign company to user if not already assigned
if ($user->company_id !== $this->company->id) {
User::where('id', $user->id)->update(['company_id' => $this->company->id]);

// Refresh the auth user session
Auth::setUser(User::find($user->id));
}

Notification::make()
->title(__('Company updated'))
->title(__('Company saved successfully'))
->success()
->send();
}
Expand Down Expand Up @@ -128,4 +168,4 @@ protected function getCancelFormAction(): Action
->alpineClickHandler('document.referrer ? window.history.back() : (window.location.href = ' . Js::from($this->previousUrl ?? \Filament\Pages\Dashboard::getUrl()) . ')')
->color('gray');
}
}
}
Loading