Explorar el Código

Company e resources

Luca Parisio hace 3 meses
padre
commit
3efa5fd57c

+ 180 - 0
app/Livewire/Customer.php

@@ -0,0 +1,180 @@
+<?php
+
+namespace App\Livewire;
+
+use Livewire\Component;
+use Livewire\Attributes\Validate;
+
+class Customer extends Component
+{
+
+    public $customers;
+
+    #[Validate('required')] 
+    public $name;
+    public $business_name;
+    public $code;
+    public $group_id;
+    public $address;
+    public $zip;
+    public $city_id;
+    public $country_id;
+    public $fiscal_code;
+    public $vat;
+    public $sdi;
+    public $ateco;
+    public $channel;
+    public $website = '';
+    public $email = '';
+    public $pec = '';
+    public $phone = '';
+    public $referent_first_name = '';
+    public $referent_last_name = '';
+    public $referent_email = '';
+    public $referent_phone = '';
+    public $enabled;
+
+    public $current_customer = null;
+
+    public $is_edit = false;
+
+    public function resetFields(){
+        $this->name = '';
+        $this->business_name = '';
+        $this->code = '';
+        $this->group_id = null;
+        $this->address = '';
+        $this->zip = '';
+        $this->city_id = null;
+        $this->country_id = null;
+        $this->fiscal_code = '';
+        $this->vat = '';
+        $this->sdi = '';
+        $this->ateco = '';
+        $this->channel = '';
+        $this->website = '';
+        $this->email = '';
+        $this->pec = '';
+        $this->phone = '';    
+        $this->referent_first_name = '';
+        $this->referent_last_name = '';
+        $this->referent_email = '';
+        $this->referent_phone = '';    
+        $this->enabled = true;
+    }
+
+    public function render()
+    {
+        // Get Customers
+        $this->customers = \App\Models\Customer::all();
+        return view('livewire.customer');
+    }
+
+    public function add()
+    {
+        $this->resetFields();
+        $this->is_edit = true;
+        $this->current_customer = null;
+    }
+
+    public function edit($id)
+    {
+        $this->resetFields();
+        $this->is_edit = true;
+        $this->current_customer = \App\Models\Customer::findOrFail($id);
+        $this->name = $this->current_customer->name;
+        $this->business_name = $this->current_customer->business_name;
+        $this->code = $this->current_customer->code;
+        $this->group_id = $this->current_customer->group_id;
+        $this->address = $this->current_customer->address;
+        $this->zip = $this->current_customer->zip;
+        $this->city_id = $this->current_customer->city_id;
+        $this->country_id = $this->current_customer->country_id;
+        $this->fiscal_code = $this->current_customer->fiscal_code;
+        $this->vat = $this->current_customer->vat;
+        $this->sdi = $this->current_customer->sdi;
+        $this->ateco = $this->current_customer->ateco;
+        $this->website = $this->current_customer->website;
+        $this->email = $this->current_customer->email;
+        $this->pec = $this->current_customer->pec;
+        $this->phone = $this->current_customer->phone;
+        $this->referent_first_name = $this->current_customer->referent_first_name;
+        $this->referent_last_name = $this->current_customer->referent_last_name;
+        $this->referent_email = $this->current_customer->referent_email;
+        $this->referent_phone = $this->current_customer->referent_phone;
+        $this->enabled = $this->current_customer->enabled;
+    }
+
+    public function save()
+    {
+        $this->validate();
+        try 
+        {
+            if ($this->current_customer == null)
+            {
+                \App\Models\Customer::create([
+                    'name' => $this->name,
+                    'business_name' => $this->business_name,
+                    'code' => $this->code,
+                    'group_id' => $this->group_id,
+                    'address' => $this->address,
+                    'zip' => $this->zip,
+                    'city_id' => $this->city_id,
+                    'country_id' => $this->country_id,
+                    'fiscal_code' => $this->fiscal_code,
+                    'vat' => $this->vat,
+                    'sdi' => $this->sdi,
+                    'ateco' => $this->ateco,
+                    'website' => $this->website,
+                    'email' => $this->email,
+                    'pec' => $this->pec,
+                    'phone' => $this->phone,
+                    'referent_first_name' => $this->referent_first_name,
+                    'referent_last_name' => $this->referent_last_name,
+                    'referent_email' => $this->referent_email,                    
+                    'referent_phone' => $this->referent_phone,
+                    'enabled' => $this->enabled
+                ]);
+            }
+            else
+            {
+                $this->current_company->update([
+                    'name' => $this->name,
+                    'business_name' => $this->business_name,
+                    'code' => $this->code,
+                    'group_id' => $this->group_id,
+                    'address' => $this->address,
+                    'zip' => $this->zip,
+                    'city_id' => $this->city_id,
+                    'country_id' => $this->country_id,
+                    'fiscal_code' => $this->fiscal_code,
+                    'vat' => $this->vat,
+                    'sdi' => $this->sdi,
+                    'ateco' => $this->ateco,
+                    'website' => $this->website,
+                    'email' => $this->email,
+                    'pec' => $this->pec,
+                    'phone' => $this->phone,
+                    'referent_first_name' => $this->referent_first_name,
+                    'referent_last_name' => $this->referent_last_name,
+                    'referent_email' => $this->referent_email,                    
+                    'referent_phone' => $this->referent_phone,
+                    'enabled' => $this->enabled,
+                ]);
+            }
+            session()->flash('success','Dati salvati con successo');
+            $this->resetFields();
+            $this->is_edit = false;
+        } catch (\Exception $ex) {
+            session()->flash('error','Errore (' . $ex->getMessage() . ')');
+        }
+    }
+
+    public function cancel()
+    {
+        $this->resetFields();
+        $this->is_edit = false;
+        $this->current_company = null;
+    }
+
+}

+ 138 - 0
app/Livewire/Project.php

@@ -0,0 +1,138 @@
+<?php
+
+namespace App\Livewire;
+
+use Livewire\Component;
+use Livewire\Attributes\Validate;
+
+class Project extends Component
+{
+
+    public $projects;
+
+    #[Validate('required')] 
+    public $name = '';
+    public $code = '';
+    public $customer_id = null;
+    public $company_service_id = null;
+    public $description = '';
+    public $start_date = null;
+    public $end_date = null;
+    public $project_manager_id = null;
+    public $project_value = 0;
+    public $hours = 0;
+    public $status = 0;
+    public $billable = 0;
+    public $enabled;
+
+    public $current_project = null;
+
+    public $is_edit = false;
+
+    public function resetFields(){
+        $this->name = '';
+        $this->code = '';
+        $this->customer_id = null;
+        $this->company_service_id = null;
+        $this->description = '';
+        $this->start_date = null;
+        $this->end_date = null;
+        $this->project_manager_id = null;
+        $this->project_value = 0;
+        $this->hours = 0;
+        $this->status = 0;
+        $this->billable = 0;
+        $this->enabled = true;
+    }
+
+    public function render()
+    {
+        // Get Customers
+        $this->projects = \App\Models\Project::all();
+        return view('livewire.project');
+    }
+
+    public function add()
+    {
+        $this->resetFields();
+        $this->is_edit = true;
+        $this->current_project = null;
+    }
+
+    public function edit($id)
+    {
+        $this->resetFields();
+        $this->is_edit = true;
+        $this->current_project = \App\Models\Project::findOrFail($id);
+        $this->name = $this->current_project->name;
+        $this->code = $this->current_project->code;
+        $this->customer_id = $this->current_project->customer_id;
+        $this->company_service_id = $this->current_project->company_service_id;
+        $this->description = $this->current_project->description;
+        $this->start_date = $this->current_project->start_date;
+        $this->end_date = $this->current_project->end_date;
+        $this->project_manager_id = $this->current_project->project_manager_id;
+        $this->project_value = $this->current_project->project_value;
+        $this->hours = $this->current_project->hours;
+        $this->status = $this->current_project->status;
+        $this->billable = $this->current_project->billable;
+        $this->enabled = $this->current_customer->enabled;
+    }
+
+    public function save()
+    {
+        $this->validate();
+        try 
+        {
+            if ($this->current_project == null)
+            {
+                \App\Models\Project::create([
+                    'name' => $this->name,
+                    'code' => $this->code,
+                    'customer_id' => $this->customer_id,
+                    'company_service_id' => $this->company_service_id,
+                    'description' => $this->description,
+                    'start_date' => $this->start_date,
+                    'end_date' => $this->end_date,
+                    'project_manager_id' => $this->project_manager_id,
+                    'project_value' => $this->project_value,
+                    'hours' => $this->hours,
+                    'status' => $this->status,
+                    'billable' => $this->billable,
+                    'enabled' => $this->enabled
+                ]);
+            }
+            else
+            {
+                $this->current_project->update([
+                    'name' => $this->name,
+                    'code' => $this->code,
+                    'customer_id' => $this->customer_id,
+                    'company_service_id' => $this->company_service_id,
+                    'description' => $this->description,
+                    'start_date' => $this->start_date,
+                    'end_date' => $this->end_date,
+                    'project_manager_id' => $this->project_manager_id,
+                    'project_value' => $this->project_value,
+                    'hours' => $this->hours,
+                    'status' => $this->status,
+                    'billable' => $this->billable,
+                    'enabled' => $this->enabled,
+                ]);
+            }
+            session()->flash('success','Dati salvati con successo');
+            $this->resetFields();
+            $this->is_edit = false;
+        } catch (\Exception $ex) {
+            session()->flash('error','Errore (' . $ex->getMessage() . ')');
+        }
+    }
+
+    public function cancel()
+    {
+        $this->resetFields();
+        $this->is_edit = false;
+        $this->current_company = null;
+    }
+
+}

+ 91 - 38
app/Livewire/Resource.php

@@ -8,6 +8,8 @@ use Livewire\Attributes\Validate;
 class Resource extends Component
 {
 
+    public $resources;
+
     #[Validate('required')] 
     public $first_name = '';
     public $last_name = '';
@@ -27,57 +29,101 @@ class Resource extends Component
 
     public $is_edit = false;
 
-    public function render()
+    public function resetFields()
     {
+        $this->first_name = '';
+        $this->last_name = '';
+        $this->birth_day = null;
+        $this->birth_place_id = null;
+        $this->fiscal_code = '';
+        $this->phone = '';
+        $this->email = '';
+        $this->address = '';
+        $this->zip = '';
+        $this->city_id = null;
+        $this->country_id = null;
+        $this->domicile = '';
+        $this->enabled = true;
+    }
 
+    public function render()
+    {
         // Get Resource
-        $this->current_resource = \App\Models\Resource::first();
-
-        if ($this->current_resource != null)
-        {
-
-            $this->first_name = $this->current_resource->first_name;
-            $this->last_name = $this->current_resource->last_name;
-            $this->birth_day = $this->current_resource->birth_day;
-            $this->birth_place_id = $this->current_resource->birth_place_id;
-            $this->fiscal_code = $this->current_resource->fiscal_code;
-            $this->phone = $this->current_resource->phone;
-            $this->email = $this->current_resource->email;
-            $this->address = $this->current_resource->address;
-            $this->zip = $this->current_resource->zip;
-            $this->city_id = $this->current_resource->city_id;
-            $this->country_id = $this->current_resource->country_id;
-            $this->domicile = $this->current_resource->domicile;
-            $this->enabled = $this->current_resource->enabled;
+        $this->resources = \App\Models\Resource::all();
+        return view('livewire.resource');
+    }
 
-        }
+    public function add()
+    {
+        $this->resetFields();
+        $this->is_edit = true;
+        $this->current_resource = null;
+    }
 
-        return view('livewire.resource');
+    public function edit($id)
+    {
+        $this->resetFields();
+        $this->is_edit = true;
+        $this->current_resource = \App\Models\Recource::findOrFail($id);
+        $this->first_name = $this->current_resource->first_name;
+        $this->last_name = $this->current_resource->last_name;
+        $this->birth_day = $this->current_resource->birth_day;
+        $this->birth_place_id = $this->current_resource->birth_place_id;
+        $this->fiscal_code = $this->current_resource->fiscal_code;
+        $this->phone = $this->current_resource->phone;
+        $this->email = $this->current_resource->email;
+        $this->address = $this->current_resource->address;
+        $this->zip = $this->current_resource->zip;
+        $this->city_id = $this->current_resource->city_id;
+        $this->country_id = $this->current_resource->country_id;
+        $this->domicile = $this->current_resource->domicile;
+        $this->enabled = $this->current_resource->enabled;
     }
 
-    public function update()
+    public function save()
     {
 
         $this->validate();
 
         try {
-            $this->current_resource->update([
-                'first_name' => $this->first_name,
-                'last_name' => $this->last_name,
-                'birth_day' => $this->birth_day,
-                'birth_place_id' => $this->birth_place_id,
-                'fiscal_code' => $this->fiscal_code,
-                'phone' => $this->phone,
-                'email' => $this->email,
-                'address' => $this->address,
-                'zip' => $this->zip,
-                'city_id' => $this->city_id,
-                'country_id' => $this->country_id,
-                'domicile' => $this->domicile,
-                'enabled' => $this->enabled,
-            ]);
+            if ($this->current_customer == null)
+            {
+                \App\Models\Resource::create([
+                    'first_name' => $this->first_name,
+                    'last_name' => $this->last_name,
+                    'birth_day' => $this->birth_day,
+                    'birth_place_id' => $this->birth_place_id,
+                    'fiscal_code' => $this->fiscal_code,
+                    'phone' => $this->phone,
+                    'email' => $this->email,
+                    'address' => $this->address,
+                    'zip' => $this->zip,
+                    'city_id' => $this->city_id,
+                    'country_id' => $this->country_id,
+                    'domicile' => $this->domicile,
+                    'enabled' => $this->enabled
+                ]);
+            }
+            else
+            {
+                $this->current_resource->update([
+                    'first_name' => $this->first_name,
+                    'last_name' => $this->last_name,
+                    'birth_day' => $this->birth_day,
+                    'birth_place_id' => $this->birth_place_id,
+                    'fiscal_code' => $this->fiscal_code,
+                    'phone' => $this->phone,
+                    'email' => $this->email,
+                    'address' => $this->address,
+                    'zip' => $this->zip,
+                    'city_id' => $this->city_id,
+                    'country_id' => $this->country_id,
+                    'domicile' => $this->domicile,
+                    'enabled' => $this->enabled,
+                ]);
+            }
             session()->flash('success','Dato aggiornato');
-            //$this->resetFields();
+            $this->resetFields();
             $this->is_edit = false;
         } catch (\Exception $ex) {
             session()->flash('error','Errore (' . $ex->getMessage() . ')');
@@ -85,4 +131,11 @@ class Resource extends Component
 
     }
 
+    public function cancel()
+    {
+        $this->resetFields();
+        $this->is_edit = false;
+        $this->current_company = null;
+    }
+
 }

+ 54 - 0
app/Models/Customer.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+
+class Customer extends Model
+{
+    use HasFactory;
+    use SoftDeletes;
+
+    public function __construct()
+    {
+        setTenant();
+    }
+
+    protected $fillable = [
+        'name',
+        'business_name',
+        'code',
+        'group_id',
+        'address',
+        'zip',
+        'city_id',
+        'country_id',        
+        'fiscal_code',
+        'vat',
+        'sdi',
+        'ateco',
+        'channel',
+        'enabled',
+    ];
+
+    public function group()
+    {
+        return $this->belongsTo(\App\Models\CustomerGroup::class);
+    }
+
+    public function contacts()
+    {
+        return $this->hasMany(\App\Models\CustomerContact::class);
+    }
+
+    public function referents()
+    {
+        return $this->hasMany(\App\Models\CustomerReferent::class);
+    }
+
+}

+ 19 - 0
app/Models/CustomerGroup.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class CustomerGroup extends Model
+{
+    use HasFactory;
+    use SoftDeletes;
+
+    protected $fillable = [
+        'name',
+        'enabled',
+    ];
+
+}

+ 48 - 0
app/Models/Project.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\DB;
+
+
+class Project extends Model
+{
+    use HasFactory;
+    use SoftDeletes;
+
+    public function __construct()
+    {
+        setTenant();
+    }
+
+    protected $fillable = [
+        'name',
+        'code',
+        'customer_id',
+        'company_service_id',
+        'description',
+        'start_date',
+        'end_date',
+        'project_manager_id',
+        'project_value',
+        'hours',
+        'status',
+        'billable',
+        'enabled',
+    ];
+
+    public function company_service()
+    {
+        return $this->belongsTo(\App\Models\CompanyService::class);
+    }
+
+    public function customer()
+    {
+        return $this->belongsTo(\App\Models\Customer::class);
+    }
+
+}

+ 39 - 0
app/Models/ProjectBudget.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class ProjectBudget extends Model
+{
+    use HasFactory;
+    use SoftDeletes;
+
+    protected $fillable = [
+        'resource_id',
+        'hours',
+        'company_activity_id',
+        'company_rate_id',
+        'cost',
+        'revenue',
+        'margin'
+    ];
+
+    public function resource()
+    {
+        return $this->belongsTo(\App\Models\Resource::class);
+    }
+
+    public function company_activity()
+    {
+        return $this->belongsTo(\App\Models\CompanyActivity::class);
+    }
+
+    public function company_rate()
+    {
+        return $this->belongsTo(\App\Models\CompanyRate::class);
+    }
+
+}

+ 30 - 0
app/Models/ProjectTeam.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class ProjectTeam extends Model
+{
+    use HasFactory;
+    use SoftDeletes;
+
+    protected $fillable = [
+        'resource_id',
+        'role_id',
+        'hours',
+        'hours_inserted',
+    ];
+
+    public function resource()
+    {
+        return $this->belongsTo(\App\Models\Resource::class);
+    }
+
+    public function role()
+    {
+        return $this->belongsTo(\App\Models\Role::class);
+    }
+}

+ 19 - 0
app/Models/Role.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class Role extends Model
+{
+    use HasFactory;
+    use SoftDeletes;
+
+    protected $fillable = [
+        'name',
+        'enabled',
+    ];
+
+}

+ 31 - 0
database/migrations/2025_09_15_155000_create_customer_groups_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use App\Database\Migrations\TenantMigration;
+
+return new class extends TenantMigration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('customer_groups', function (Blueprint $table) {
+            $table->id();
+            $table->string('name');
+            $table->boolean('enabled')->default(1);
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('customer_groups');
+    }
+};

+ 67 - 0
database/migrations/2025_09_15_155200_create_customers_table.php

@@ -0,0 +1,67 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use App\Database\Migrations\TenantMigration;
+
+return new class extends TenantMigration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('customers', function (Blueprint $table) {
+            $table->id();
+            $table->string('name')->nullable();
+            $table->string('business_name')->nullable();
+            $table->string('code')->nullable();
+
+            $table->unsignedBigInteger('group_id')->nullable();
+            $table->foreign('group_id')->nullable()->references('id')->on('company_groups')->onUpdate('cascade')->onDelete('cascade');
+
+            /*$table->unsignedBigInteger('activity_id')->nullable();
+            $table->foreign('activity_id')->nullable()->references('id')->on('company_activities')->onUpdate('cascade')->onDelete('cascade');
+
+            $table->unsignedBigInteger('activity_id')->nullable();
+            $table->foreign('activity_id')->nullable()->references('id')->on('company_activities')->onUpdate('cascade')->onDelete('cascade');*/
+
+            $table->string('address')->nullable();
+            $table->string('zip')->nullable();
+            $table->unsignedBigInteger('city_id')->nullable();
+            $table->foreign('city_id')->nullable()->references('id')->on('cities')->onUpdate('cascade')->onDelete('cascade');
+            $table->unsignedBigInteger('country_id')->nullable();
+            $table->foreign('country_id')->nullable()->references('id')->on('countries')->onUpdate('cascade')->onDelete('cascade');
+
+            $table->string('fiscal_code')->nullable();
+            $table->string('vat')->nullable();
+            $table->string('sdi')->nullable();
+            $table->string('ateco')->nullable();
+
+            $table->string('channel')->nullable();
+
+            $table->string('website')->nullable();
+            $table->string('email')->nullable();
+            $table->string('pec')->nullable();
+            $table->string('phone')->nullable();
+
+            $table->string('first_name')->nullable();
+            $table->string('last_name')->nullable();
+            $table->string('email')->nullable();
+            $table->string('phone')->nullable();
+
+            $table->boolean('enabled')->default(1);
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('customers');
+    }
+};

+ 31 - 0
database/migrations/2025_09_25_100000_create_roles_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use App\Database\Migrations\TenantMigration;
+
+return new class extends TenantMigration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('roles', function (Blueprint $table) {
+            $table->id();
+            $table->string('name');
+            $table->boolean('enabled')->default(1);
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('roles');
+    }
+};

+ 45 - 0
database/migrations/2025_09_26_103000_create_projects_table.php

@@ -0,0 +1,45 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use App\Database\Migrations\TenantMigration;
+
+return new class extends TenantMigration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('projects', function (Blueprint $table) {
+            $table->id();
+            $table->string('name')->nullable();
+            $table->string('code')->nullable();
+            $table->unsignedBigInteger('customer_id')->nullable();
+            $table->foreign('customer_id')->nullable()->references('id')->on('customers')->onUpdate('cascade')->onDelete('cascade');            
+            $table->unsignedBigInteger('company_service_id')->nullable();
+            $table->foreign('company_service_id')->nullable()->references('id')->on('company_services')->onUpdate('cascade')->onDelete('cascade');
+            $table->text('description')->nullable();
+            $table->date('start_date')->nullable();  
+            $table->date('end_date')->nullable();
+            $table->unsignedBigInteger('project_manager_id')->nullable();
+            //$table->foreign('customer_id')->nullable()->references('id')->on('customers')->onUpdate('cascade')->onDelete('cascade');            
+            $table->decimal('project_value', total: 8, places: 2);
+            $table->float('hours')->nullable();  
+            $table->integer('status')->nullable();  
+            $table->boolean('billable')->default(1);
+            $table->boolean('enabled')->default(1);
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('projects');
+    }
+};

+ 40 - 0
database/migrations/2025_09_26_103100_create_project_budgets_table.php

@@ -0,0 +1,40 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use App\Database\Migrations\TenantMigration;
+
+return new class extends TenantMigration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('project_budgets', function (Blueprint $table) {
+            $table->id();
+            $table->unsignedBigInteger('resource_id')->nullable();
+            $table->foreign('resource_id')->nullable()->references('id')->on('resources')->onUpdate('cascade')->onDelete('cascade');            
+            $table->float('hours')->nullable();  
+            $table->unsignedBigInteger('company_activity_id')->nullable();
+            $table->foreign('company_activity_id')->nullable()->references('id')->on('company_activities')->onUpdate('cascade')->onDelete('cascade');            
+            $table->unsignedBigInteger('company_rate_id')->nullable();
+            $table->foreign('company_rate_id')->nullable()->references('id')->on('company_rates')->onUpdate('cascade')->onDelete('cascade');            
+            $table->decimal('cost', total: 8, places: 2);
+            $table->decimal('revenue', total: 8, places: 2);
+            $table->decimal('margin', total: 8, places: 2);
+            // $table->boolean('enabled')->default(1);
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('project_budgets');
+    }
+};

+ 36 - 0
database/migrations/2025_09_26_103100_create_project_teams_table.php

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+use App\Database\Migrations\TenantMigration;
+
+return new class extends TenantMigration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('project_teams', function (Blueprint $table) {
+            $table->id();
+            $table->unsignedBigInteger('resource_id')->nullable();
+            $table->foreign('resource_id')->nullable()->references('id')->on('resources')->onUpdate('cascade')->onDelete('cascade');            
+            $table->unsignedBigInteger('role_id')->nullable();
+            $table->foreign('role_id')->nullable()->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade');            
+            $table->float('hours')->nullable();  
+            $table->float('hours_inserted')->nullable();  
+            // $table->boolean('enabled')->default(1);
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('project_teams');
+    }
+};

+ 32 - 1
resources/views/livewire/company.blade.php

@@ -1,7 +1,38 @@
 <div>
     COMPANY
     <br>
-    {{$name}}
+    @if($is_edit)
+        Nome<br>
+        <input type="text" wire:model="name"><br>
+        @error('name')
+            {{ $message }}
+        @enderror
+        <br>
+        Business name<br>
+        <input type="text" wire:model="business_name"><br><br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>Business name</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($companies as $c)
+                <tr>
+                    <td>{{$c->name}}</td>
+                    <td>{{$c->business_name}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
     <br><br>
     <livewire:company-service :company="$current_company"/>
     <br><br>

+ 31 - 0
resources/views/livewire/company_rate.blade.php

@@ -1,4 +1,35 @@
 <div>
     COMPANY rate
     <br>    
+    @if($is_edit)
+        Amount<br>
+        <input type="text" wire:model="amount"><br>
+        @error('amount')
+            {{ $message }}
+        @enderror
+        <br>
+        Type<br>
+        <input type="text" wire:model="type"><br><br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Amount</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($company_rates as $c)
+                <tr>
+                    <td>{{$c->amount}}</td>
+                    <td>{{$c->type}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
 </div>

+ 31 - 1
resources/views/livewire/company_service.blade.php

@@ -1,4 +1,34 @@
 <div>
-    COMPANY service
+    COMPANY activity
     <br>    
+    @if($is_edit)
+        Nome<br>
+        <input type="text" wire:model="name"><br>
+        @error('name')
+            {{ $message }}
+        @enderror
+        <br>
+        Descrizione<br>
+        <input type="text" wire:model="description"><br><br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($company_services as $c)
+                <tr>
+                    <td>{{$c->name}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
 </div>

+ 37 - 0
resources/views/livewire/customer.blade.php

@@ -0,0 +1,37 @@
+<div>
+    Cliente
+    <br>
+    @if($is_edit)
+        Nome<br>
+        <input type="text" wire:model="name"><br>
+        @error('name')
+            {{ $message }}
+        @enderror
+        <br>
+        Business name<br>
+        <input type="text" wire:model="business_name"><br><br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>Business name</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($customers as $c)
+                <tr>
+                    <td>{{$c->name}}</td>
+                    <td>{{$c->business_name}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
+    <br><br>
+</div>

+ 32 - 1
resources/views/livewire/resource.blade.php

@@ -1,7 +1,38 @@
 <div>
     Resource
     <br>
-    {{$first_name}}
+    @if($is_edit)
+        Nome<br>
+        <input type="text" wire:model="first_name"><br>
+        @error('first_name')
+            {{ $message }}
+        @enderror
+        <br>
+        Cognome<br>
+        <input type="text" wire:model="last_name"><br><br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>Cognome</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($resources as $r)
+                <tr>
+                    <td>{{$r->first_name}}</td>
+                    <td>{{$r->last_name}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
     <br><br>
     <livewire:resource-contract :recource="$current_resource"/>
     <br><br>

+ 28 - 0
resources/views/livewire/resource_contract.blade.php

@@ -1,4 +1,32 @@
 <div>
     RESOURCE contract
     <br>    
+    @if($is_edit)
+        Number<br>
+        <input type="text" wire:model="contract_number"><br>
+        @error('contract_number')
+            {{ $message }}
+        @enderror
+        <br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($resource_contracts as $c)
+                <tr>
+                    <td>{{$c->contract_number}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
 </div>

+ 28 - 0
resources/views/livewire/resource_document.blade.php

@@ -1,4 +1,32 @@
 <div>
     RESOURCE document
     <br>    
+    @if($is_edit)
+        Name<br>
+        <input type="text" wire:model="name"><br>
+        @error('name')
+            {{ $message }}
+        @enderror
+        <br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($resource_documents as $d)
+                <tr>
+                    <td>{{$d->name}}</td>
+                    <td><a wire:click="edit({{$d->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
 </div>

+ 28 - 0
resources/views/livewire/resource_equipment.blade.php

@@ -1,4 +1,32 @@
 <div>
     RESOURCE equipment
     <br>    
+    @if($is_edit)
+        Name<br>
+        <input type="text" wire:model="name"><br>
+        @error('name')
+            {{ $message }}
+        @enderror
+        <br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($resource_equipments as $e)
+                <tr>
+                    <td>{{$e->name}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
 </div>

+ 28 - 0
resources/views/livewire/resource_rate.blade.php

@@ -1,4 +1,32 @@
 <div>
     RESOURCE rate
     <br>    
+    @if($is_edit)
+        Cost<br>
+        <input type="text" wire:model="cost"><br>
+        @error('cost')
+            {{ $message }}
+        @enderror
+        <br>
+        Enable<br>
+        <input type="checkbox" wire:model="enabled"><br><br>
+        <a wire:click="save()">Salva</a>
+        <a wire:click="cancel()">Annulla</a>
+    @else
+        <table border="1">
+            <tr>
+                <td>Nome</td>
+                <td>
+
+                </td>
+            </tr>
+            @foreach($resource_rates as $c)
+                <tr>
+                    <td>{{$c->cost}}</td>
+                    <td><a wire:click="edit({{$c->id}})">Modifica</a></td>
+                </tr>
+            @endforeach
+        </table>
+        <a wire:click="add()">Aggiungi</a>
+    @endif
 </div>