Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
f68326f
Add PHP Enums for QC business logic and QualityControlSeeder
SezginYurdakul Dec 28, 2025
f31aee6
Refactor SettingsSeeder: remove enum-like values, keep config only
SezginYurdakul Dec 28, 2025
833cc12
Use PHP Enums in QC services and controller validation
SezginYurdakul Dec 29, 2025
ce5c529
Standardize Auth facade usage in Services and Models
SezginYurdakul Dec 29, 2025
082876c
Add PHP Enums for PurchaseOrder and GoodsReceivedNote status
SezginYurdakul Dec 29, 2025
217c672
Complete QC module: QC zones, supplier quality scoring, transfer-to-qc
SezginYurdakul Dec 30, 2025
01264c0
Add Manufacturing module database migrations
SezginYurdakul Dec 30, 2025
36d78d8
Add Manufacturing module enums
SezginYurdakul Dec 30, 2025
8219b96
Add Manufacturing module models
SezginYurdakul Dec 30, 2025
8e87e83
Add Manufacturing module services
SezginYurdakul Dec 30, 2025
7f2394f
Add Manufacturing module API resources
SezginYurdakul Dec 30, 2025
902e64e
Add Manufacturing module controllers
SezginYurdakul Dec 30, 2025
36eb08d
Add Manufacturing routes, permissions, and seeders
SezginYurdakul Dec 30, 2025
7e08456
Update SYSTEM_DESIGN.md for Manufacturing module
SezginYurdakul Dec 30, 2025
384ad8f
Fix Manufacturing module bugs
SezginYurdakul Dec 31, 2025
7c0e6f5
Phase 5.1: Fix Manufacturing module bugs and add constraints
SezginYurdakul Jan 1, 2026
8749ca2
Add Sales module foundation - migrations, models, enums, and permissions
SezginYurdakul Jan 1, 2026
6ee070f
Make QC an independent module separate from Procurement/Manufacturing
SezginYurdakul Jan 2, 2026
bc6cc98
Add Sales module - controllers, services, resources, and seeder
SezginYurdakul Jan 2, 2026
2d50d95
Add REJECTED status to SalesOrderStatus enum
SezginYurdakul Jan 2, 2026
4eaa537
Add color() method to SalesOrderStatus enum
SezginYurdakul Jan 2, 2026
10a2a44
Register SalesSeeder in DatabaseSeeder
SezginYurdakul Jan 2, 2026
3a74ba2
Add seeder mode support and update demo data for Agricultural Machinery
SezginYurdakul Jan 4, 2026
b090fd6
Convert uom_type from DB enum to string with PHP Enum
SezginYurdakul Jan 4, 2026
35b8612
Add product-specific UOM conversions (MRP II best practice)
SezginYurdakul Jan 4, 2026
6130261
Remove deprecated NCR constants, use enums in model scopes
SezginYurdakul Jan 4, 2026
55f37a0
refactor(migrations): merge add_ migrations into create_ migrations
SezginYurdakul Jan 5, 2026
8ccec75
feat(mrp): add MRP enums
SezginYurdakul Jan 5, 2026
b237587
feat(mrp): add MRP models and migration
SezginYurdakul Jan 5, 2026
9519eb0
feat(mrp): add Redis-based cache service for MRP
SezginYurdakul Jan 5, 2026
da6306b
feat(mrp): implement comprehensive MRP service
SezginYurdakul Jan 5, 2026
0b98d00
feat(mrp): add MRP API endpoints and resources
SezginYurdakul Jan 5, 2026
aad738e
feat(mrp): add queue jobs for async MRP processing
SezginYurdakul Jan 5, 2026
d40500b
test(mrp): add comprehensive MRP service tests
SezginYurdakul Jan 5, 2026
4235d3e
feat(calendar): add company calendar system for working days
SezginYurdakul Jan 5, 2026
22b9ee2
feat(manufacturing): add work center calendar for capacity planning
SezginYurdakul Jan 5, 2026
f4ed192
feat(manufacturing): add capacity planning (CRP) service and controller
SezginYurdakul Jan 5, 2026
0dc1f31
feat(mrp): add observers for automatic cache invalidation
SezginYurdakul Jan 5, 2026
fd6b50e
feat(settings): add MRP working days configuration and admin-only sys…
SezginYurdakul Jan 5, 2026
1db8781
refactor(routes): organize API routes into modular files
SezginYurdakul Jan 5, 2026
401d496
exclude markdown documentation files in backend/docs
SezginYurdakul Jan 5, 2026
306e146
fix: Phase 6 - Customer and CustomerGroup fixes
SezginYurdakul Jan 6, 2026
a3eb596
fix: Phase 6 - DeliveryNote and SalesOrder fixes
SezginYurdakul Jan 6, 2026
1fc3174
feat(mrp): add warnings summary system and warehouse filter improvements
SezginYurdakul Jan 6, 2026
a99579c
feat(bom): enhance explodeBom with tree structure and aggregation
SezginYurdakul Jan 6, 2026
7f3631c
feat(models): add MRP recommendation relationships
SezginYurdakul Jan 6, 2026
16f116d
refactor(ncr): migrate from constants to enums
SezginYurdakul Jan 6, 2026
e3f168d
fix(purchase-order): handle nullable supplier_id gracefully
SezginYurdakul Jan 6, 2026
66e4025
chore: various improvements and fixes
SezginYurdakul Jan 6, 2026
a025f17
chore(mrp): minor controller improvements
SezginYurdakul Jan 6, 2026
ae70c6f
feat: Add automatic stock reservation on sales order confirmation
SezginYurdakul Jan 7, 2026
75c221c
feat: Add over-delivery tolerance for Purchase Orders
SezginYurdakul Jan 8, 2026
0796278
refactor: Remove Auth facade dependency from models
SezginYurdakul Jan 8, 2026
04e7cd2
refactor: Consolidate over-delivery tolerance migrations into origina…
SezginYurdakul Jan 8, 2026
0f37411
feat: Implement over-delivery tolerance system for sales and purchase…
SezginYurdakul Jan 8, 2026
1da1469
fix: Use UserResource in AuthController and add auth middleware to au…
SezginYurdakul Jan 8, 2026
c634f62
feat: Implement negative stock policy system with stock debt tracking
SezginYurdakul Jan 8, 2026
7a48b98
feat: Add reservation policy system and automatic material reservatio…
SezginYurdakul Jan 8, 2026
34fc108
Remove system-level over-delivery tolerance (SaaS architecture)
SezginYurdakul Jan 8, 2026
9e10a9b
Update SYSTEM_DESIGN.md to version 5.9
SezginYurdakul Jan 8, 2026
ca32e22
Implement company isolation security with platform admin support
SezginYurdakul Jan 8, 2026
0262e62
Fix: SalesSeeder company variable error and revert ProductPriceObserv…
SezginYurdakul Jan 8, 2026
39ec550
fix: Update company_id validation in AuthController to require intege…
SezginYurdakul Jan 8, 2026
03d90c0
feat: Update invitation system - make role_ids required and update em…
SezginYurdakul Jan 9, 2026
daed847
feat: Improve user creation validation and add Mailpit for email testing
SezginYurdakul Jan 9, 2026
475552a
feat: implement comprehensive audit logging system with Blameable trait
SezginYurdakul Jan 11, 2026
06d7bad
Fix MRP Work Order recommendations and sales order delivery date hand…
SezginYurdakul Jan 12, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Thumbs.db
*.pdf
!docs/*.pdf

# Exclude markdown documentation files in backend/docs
backend/docs/*.md

# Backup files
*.backup
*.bak
Expand Down
1,742 changes: 1,678 additions & 64 deletions SYSTEM_DESIGN.md

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions SmartStockManagement.postman_environment.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@
"value": "",
"type": "default",
"enabled": true
},
{
"key": "company_id",
"value": "",
"type": "default",
"enabled": true
},
{
"key": "is_platform_admin",
"value": "false",
"type": "default",
"enabled": true
},
{
"key": "invitation_token",
"value": "",
"type": "secret",
"enabled": true,
"description": "Invitation token from email. Used for testing accept invitation endpoints."
}
],
"_postman_variable_scope": "environment"
Expand Down
64 changes: 64 additions & 0 deletions backend/app/Console/Commands/SeedDatabaseCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;

class SeedDatabaseCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'db:seed-fresh
{--demo : Include demo/sample data}
{--minimal : Run in minimal mode (default)}
{--force : Force the operation when in production}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Drop all tables and re-run all migrations with optional demo data';

/**
* Execute the console command.
*/
public function handle(): int
{
$mode = $this->option('demo') ? 'demo' : 'minimal';

$this->components->info("Running database fresh with seeding in {$mode} mode...");

// Set the environment variable for seeder mode
putenv("SEED_MODE={$mode}");
$_ENV['SEED_MODE'] = $mode;

// Build migrate:fresh command options
$options = ['--seed' => true];

if ($this->option('force')) {
$options['--force'] = true;
}

// Run migrate:fresh with seed
$exitCode = Artisan::call('migrate:fresh', $options, $this->output);

if ($exitCode === 0) {
$this->newLine();
$this->components->info('Database seeded successfully!');

if ($mode === 'minimal') {
$this->components->info('Minimal mode: Only system essentials were seeded.');
$this->components->info('To include demo data, use: php artisan db:seed-fresh --demo');
} else {
$this->components->info('Demo mode: All sample data has been seeded.');
}
}

return $exitCode;
}
}
82 changes: 82 additions & 0 deletions backend/app/Enums/BomStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace App\Enums;

/**
* BOM Status Enum
*
* Manages BOM lifecycle states.
*/
enum BomStatus: string
{
case DRAFT = 'draft';
case ACTIVE = 'active';
case OBSOLETE = 'obsolete';

/**
* Get human-readable label
*/
public function label(): string
{
return match ($this) {
self::DRAFT => 'Draft',
self::ACTIVE => 'Active',
self::OBSOLETE => 'Obsolete',
};
}

/**
* Get allowed status transitions
*/
public function allowedTransitions(): array
{
return match ($this) {
self::DRAFT => [self::ACTIVE],
self::ACTIVE => [self::OBSOLETE, self::DRAFT],
self::OBSOLETE => [self::DRAFT], // Can reactivate by going back to draft
};
}

/**
* Check if transition to target status is allowed
*/
public function canTransitionTo(self $target): bool
{
return in_array($target, $this->allowedTransitions());
}

/**
* Check if BOM can be edited
*/
public function canEdit(): bool
{
return $this === self::DRAFT;
}

/**
* Check if BOM can be used for production
*/
public function canUseForProduction(): bool
{
return $this === self::ACTIVE;
}

/**
* Get all values as array
*/
public static function values(): array
{
return array_column(self::cases(), 'value');
}

/**
* Get all as options for dropdown
*/
public static function options(): array
{
return array_map(
fn(self $case) => ['value' => $case->value, 'label' => $case->label()],
self::cases()
);
}
}
66 changes: 66 additions & 0 deletions backend/app/Enums/BomType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace App\Enums;

/**
* BOM Type Enum
*
* Defines types of Bill of Materials.
*/
enum BomType: string
{
case MANUFACTURING = 'manufacturing';
case ENGINEERING = 'engineering';
case PHANTOM = 'phantom';

/**
* Get human-readable label
*/
public function label(): string
{
return match ($this) {
self::MANUFACTURING => 'Manufacturing',
self::ENGINEERING => 'Engineering',
self::PHANTOM => 'Phantom',
};
}

/**
* Get description
*/
public function description(): string
{
return match ($this) {
self::MANUFACTURING => 'Standard production BOM used for manufacturing',
self::ENGINEERING => 'Engineering BOM for design/development purposes',
self::PHANTOM => 'Phantom BOM - components pass through to parent',
};
}

/**
* Check if BOM is used for production
*/
public function isProduction(): bool
{
return $this === self::MANUFACTURING;
}

/**
* Get all values as array
*/
public static function values(): array
{
return array_column(self::cases(), 'value');
}

/**
* Get all as options for dropdown
*/
public static function options(): array
{
return array_map(
fn(self $case) => ['value' => $case->value, 'label' => $case->label()],
self::cases()
);
}
}
52 changes: 52 additions & 0 deletions backend/app/Enums/CalendarDayType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace App\Enums;

/**
* Calendar Day Type Enum (for CRP)
*/
enum CalendarDayType: string
{
case WORKING = 'working';
case HOLIDAY = 'holiday';
case MAINTENANCE = 'maintenance';
case SHUTDOWN = 'shutdown';

public function label(): string
{
return match ($this) {
self::WORKING => 'Working Day',
self::HOLIDAY => 'Holiday',
self::MAINTENANCE => 'Maintenance',
self::SHUTDOWN => 'Shutdown',
};
}

public function color(): string
{
return match ($this) {
self::WORKING => 'green',
self::HOLIDAY => 'blue',
self::MAINTENANCE => 'orange',
self::SHUTDOWN => 'red',
};
}

public function isAvailable(): bool
{
return $this === self::WORKING;
}

public static function values(): array
{
return array_column(self::cases(), 'value');
}

public static function options(): array
{
return array_map(
fn(self $case) => ['value' => $case->value, 'label' => $case->label()],
self::cases()
);
}
}
Loading