Skip to content

Commit e219b1e

Browse files
init supplier
1 parent be4036b commit e219b1e

20 files changed

Lines changed: 1059 additions & 0 deletions

packages/supplier/.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
# Composer
3+
/vendor
4+
composer.lock
5+
auth.json
6+
7+
# NPM / Node
8+
/node_modules
9+
npm-debug.log
10+
package-lock.json
11+
12+
# Laravel
13+
/public/hot
14+
/public/storage
15+
/storage/*.key
16+
17+
# PHPUnit
18+
.phpunit.result.cache
19+
20+
# PHPStan
21+
/build
22+
phpstan.neon
23+
24+
# Testbench
25+
testbench.yaml
26+
/workbench/*
27+
28+
# PHP CS Fixer
29+
.php-cs-fixer.cache
30+
31+
# Homestead
32+
Homestead.json
33+
Homestead.yaml
34+
35+
# IDEs
36+
/.idea
37+
/.vscode
38+
39+
# MacOS
40+
.DS_Store
41+
42+
# Windows
43+
Thumbs.db

packages/supplier/composer.json

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"name": "moox/supplier",
3+
"description": "Supplier is a Moox Entity for ERP supplier profiles linked to companies.",
4+
"keywords": [
5+
"Moox",
6+
"Laravel",
7+
"Filament",
8+
"Moox package",
9+
"Laravel package",
10+
"ERP",
11+
"Supplier"
12+
],
13+
"homepage": "https://moox.org/docs/supplier",
14+
"license": "MIT",
15+
"authors": [
16+
{
17+
"name": "Moox Developer",
18+
"email": "dev@moox.org",
19+
"role": "Developer"
20+
}
21+
],
22+
"require": {
23+
"moox/company": "dev-main",
24+
"moox/core": "dev-main",
25+
"moox/data": "dev-main"
26+
},
27+
"autoload": {
28+
"psr-4": {
29+
"Moox\\Supplier\\": "src",
30+
"Moox\\Supplier\\Database\\Factories\\": "database/factories"
31+
}
32+
},
33+
"autoload-dev": {
34+
"psr-4": {
35+
"Moox\\Supplier\\Tests\\": "tests/"
36+
}
37+
},
38+
"extra": {
39+
"laravel": {
40+
"providers": [
41+
"Moox\\Supplier\\SupplierServiceProvider"
42+
]
43+
},
44+
"moox": {
45+
"stability": "stable"
46+
}
47+
},
48+
"minimum-stability": "stable",
49+
"prefer-stable": true,
50+
"require-dev": {
51+
"moox/devtools": "dev-main",
52+
"pestphp/pest": "^4.7",
53+
"pestphp/pest-plugin-livewire": "^4.0"
54+
},
55+
"scripts": {
56+
"test": [
57+
"@php ../../vendor/bin/pest --configuration=phpunit.xml tests/Unit tests/Feature"
58+
],
59+
"test:arch": [
60+
"@php ../../vendor/bin/pest --configuration=phpunit.xml tests/ArchTest.php"
61+
]
62+
},
63+
"config": {
64+
"allow-plugins": {
65+
"pestphp/pest-plugin": true
66+
}
67+
}
68+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
use Moox\Company\Models\Company;
4+
use Moox\Company\Resources\CompanyResource;
5+
use Moox\Supplier\Models\Supplier;
6+
use Moox\Supplier\Models\SupplierAssignment;
7+
use Moox\Supplier\Resources\SupplierResource;
8+
9+
/*
10+
|--------------------------------------------------------------------------
11+
| Moox Configuration
12+
|--------------------------------------------------------------------------
13+
|
14+
| Supplier profiles extend company master data with procurement fields.
15+
| Wire the company relation in the published application config (config/supplier.php).
16+
|
17+
*/
18+
return [
19+
'readonly' => false,
20+
21+
'statuses' => [
22+
'draft',
23+
'active',
24+
'inactive',
25+
'approved',
26+
'archived',
27+
],
28+
29+
/*
30+
|--------------------------------------------------------------------------
31+
| Legacy Comwork mapping
32+
|--------------------------------------------------------------------------
33+
|
34+
| Lieferantenstamm.ID_Lieferant → external_reference
35+
| Lieferantenstamm.Kreditorennummer → supplier_number
36+
| Lieferantenstamm.Rabatt → discount_percent
37+
| Lieferantenstamm.delivery_period → lead_time_days
38+
| Lieferantenstamm.is_main_supplier → is_preferred
39+
|
40+
| Payment terms, currency, tax and shipping belong in moox/payment (future).
41+
|
42+
*/
43+
'company_roles' => [
44+
'general',
45+
'account_manager',
46+
],
47+
48+
'resources' => [
49+
'supplier' => [
50+
'single' => 'trans//supplier::supplier.supplier',
51+
'plural' => 'trans//supplier::supplier.suppliers',
52+
53+
'tabs' => [
54+
'all' => [
55+
'label' => 'trans//core::core.all',
56+
'icon' => 'gmdi-filter-list',
57+
'query' => [
58+
[
59+
'field' => 'deleted_at',
60+
'operator' => '=',
61+
'value' => null,
62+
],
63+
],
64+
],
65+
'active' => [
66+
'label' => 'trans//supplier::fields.active',
67+
'icon' => 'gmdi-check-circle-o',
68+
'query' => [
69+
[
70+
'field' => 'is_active',
71+
'operator' => '=',
72+
'value' => true,
73+
],
74+
[
75+
'field' => 'deleted_at',
76+
'operator' => '=',
77+
'value' => null,
78+
],
79+
],
80+
],
81+
'deleted' => [
82+
'label' => 'trans//core::core.deleted',
83+
'icon' => 'gmdi-delete',
84+
'query' => [
85+
[
86+
'field' => 'deleted_at',
87+
'operator' => '!=',
88+
'value' => null,
89+
],
90+
],
91+
],
92+
],
93+
94+
'scopes' => [
95+
'registry' => [
96+
'sources' => [
97+
'supplier' => Supplier::class,
98+
],
99+
],
100+
],
101+
],
102+
],
103+
104+
'related_morph_defaults' => [
105+
'display_columns' => ['supplier_number', 'status', 'lead_time_days'],
106+
'translation_prefix' => 'supplier::fields',
107+
'related_resource' => SupplierResource::class,
108+
'record_select_search_columns' => ['supplier_number', 'external_reference'],
109+
],
110+
111+
'relations' => [
112+
'supplier_assignments' => [
113+
'kind' => 'morph_pivot',
114+
'perspective' => 'related',
115+
'presentation' => 'tab',
116+
'label' => 'trans//supplier::fields.companies',
117+
'inverse_label' => 'trans//supplier::fields.suppliers',
118+
'translation_prefix' => 'supplier::fields',
119+
'relationship' => 'companies',
120+
'inverse_relationship' => 'suppliers',
121+
'model' => Company::class,
122+
'related_resource' => CompanyResource::class,
123+
'pivot_model' => SupplierAssignment::class,
124+
'pivot_table' => 'supplier_assignments',
125+
'morph_name' => 'assignable',
126+
'related_key' => 'supplier_id',
127+
'pivot_columns' => [
128+
'is_primary',
129+
'role',
130+
],
131+
'actions' => [
132+
'header' => ['attach', 'create'],
133+
'record' => ['edit_pivot', 'detach'],
134+
'toolbar' => ['detach_bulk'],
135+
],
136+
],
137+
],
138+
139+
'taxonomies' => [
140+
],
141+
142+
'navigation_group' => 'Portal',
143+
];
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Moox\Supplier\Database\Factories;
6+
7+
use Illuminate\Database\Eloquent\Factories\Factory;
8+
use Moox\Supplier\Models\Supplier;
9+
10+
/**
11+
* @extends Factory<Supplier>
12+
*/
13+
class SupplierFactory extends Factory
14+
{
15+
protected $model = Supplier::class;
16+
17+
/**
18+
* @return array<string, mixed>
19+
*/
20+
public function definition(): array
21+
{
22+
return [
23+
'status' => fake()->randomElement(config('supplier.statuses', ['draft', 'active'])),
24+
'supplier_number' => strtoupper(fake()->unique()->bothify('S-#####')),
25+
'external_reference' => fake()->optional(0.3)->numerify('#####'),
26+
'search_terms' => fake()->optional(0.3)->words(3, true),
27+
'discount_percent' => fake()->optional(0.4)->randomFloat(2, 0, 15),
28+
'lead_time_days' => fake()->optional(0.7)->numberBetween(1, 60),
29+
'minimum_order_value' => fake()->optional(0.4)->randomFloat(2, 100, 5000),
30+
'language_id' => null,
31+
'is_preferred' => fake()->boolean(20),
32+
'note' => fake()->optional(0.2)->sentence(),
33+
'sort' => fake()->optional(0.2)->numberBetween(1, 100),
34+
'is_active' => true,
35+
'approved_at' => null,
36+
'data' => null,
37+
];
38+
}
39+
40+
public function inactive(): static
41+
{
42+
return $this->state(fn (): array => [
43+
'is_active' => false,
44+
'status' => 'inactive',
45+
]);
46+
}
47+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Database\Migrations\Migration;
6+
use Illuminate\Database\Schema\Blueprint;
7+
use Illuminate\Support\Facades\Schema;
8+
9+
return new class extends Migration
10+
{
11+
public function up(): void
12+
{
13+
Schema::create('supplier_assignments', function (Blueprint $table): void {
14+
$table->id();
15+
$table->uuidMorphs('assignable');
16+
$table->foreignUuid('supplier_id')->constrained('suppliers')->cascadeOnDelete();
17+
$table->boolean('is_primary')->default(false)->index();
18+
$table->string('role', 30)->default('general')->index();
19+
$table->timestamps();
20+
21+
$table->unique(
22+
['assignable_type', 'assignable_id', 'supplier_id'],
23+
'supplier_assignments_owner_supplier_unique',
24+
);
25+
});
26+
}
27+
28+
public function down(): void
29+
{
30+
Schema::dropIfExists('supplier_assignments');
31+
}
32+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Database\Migrations\Migration;
6+
use Illuminate\Database\Schema\Blueprint;
7+
use Illuminate\Support\Facades\Schema;
8+
9+
return new class extends Migration
10+
{
11+
public function up(): void
12+
{
13+
Schema::create('suppliers', function (Blueprint $table): void {
14+
$table->uuid('id')->primary();
15+
$table->string('status', 30)->default('draft')->index();
16+
$table->string('supplier_number', 40)->nullable()->unique();
17+
$table->string('external_reference', 100)->nullable()->index();
18+
$table->text('search_terms')->nullable();
19+
$table->decimal('discount_percent', 5, 2)->nullable();
20+
$table->unsignedSmallInteger('lead_time_days')->nullable();
21+
$table->decimal('minimum_order_value', 15, 2)->nullable();
22+
$table->foreignId('language_id')->nullable()->constrained('static_languages')->nullOnDelete();
23+
$table->boolean('is_preferred')->default(false);
24+
$table->text('note')->nullable();
25+
$table->integer('sort')->nullable();
26+
$table->boolean('is_active')->default(true)->index();
27+
$table->timestamp('approved_at')->nullable();
28+
$table->nullableMorphs('approved_by');
29+
$table->json('data')->nullable();
30+
$table->softDeletes();
31+
$table->timestamps();
32+
});
33+
}
34+
35+
public function down(): void
36+
{
37+
Schema::dropIfExists('suppliers');
38+
}
39+
};

0 commit comments

Comments
 (0)