first commit
This commit is contained in:
30
app/Models/Category.php
Normal file
30
app/Models/Category.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the products for the category.
|
||||
*/
|
||||
public function products(): HasMany
|
||||
{
|
||||
return $this->hasMany(Product::class);
|
||||
}
|
||||
}
|
||||
55
app/Models/Inventory.php
Normal file
55
app/Models/Inventory.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Inventory extends Model
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\InventoryFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'warehouse_id',
|
||||
'product_id',
|
||||
'quantity',
|
||||
'safety_stock',
|
||||
'location',
|
||||
];
|
||||
|
||||
public function warehouse(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Warehouse::class);
|
||||
}
|
||||
|
||||
public function product(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
|
||||
public function transactions(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(InventoryTransaction::class);
|
||||
}
|
||||
|
||||
public function lastOutgoingTransaction()
|
||||
{
|
||||
return $this->hasOne(InventoryTransaction::class)->ofMany([
|
||||
'actual_time' => 'max',
|
||||
'id' => 'max',
|
||||
], function ($query) {
|
||||
$query->where('quantity', '<', 0);
|
||||
});
|
||||
}
|
||||
|
||||
public function lastIncomingTransaction()
|
||||
{
|
||||
return $this->hasOne(InventoryTransaction::class)->ofMany([
|
||||
'actual_time' => 'max',
|
||||
'id' => 'max',
|
||||
], function ($query) {
|
||||
$query->where('quantity', '>', 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
46
app/Models/InventoryTransaction.php
Normal file
46
app/Models/InventoryTransaction.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Models\Inventory;
|
||||
use App\Models\User;
|
||||
|
||||
class InventoryTransaction extends Model
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\InventoryTransactionFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'inventory_id',
|
||||
'type',
|
||||
'quantity',
|
||||
'balance_before',
|
||||
'balance_after',
|
||||
'reason',
|
||||
'reference_type',
|
||||
'reference_id',
|
||||
'user_id',
|
||||
'actual_time',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'actual_time' => 'datetime',
|
||||
];
|
||||
|
||||
public function inventory(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Inventory::class);
|
||||
}
|
||||
|
||||
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function reference(): \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
||||
54
app/Models/Product.php
Normal file
54
app/Models/Product.php
Normal file
@@ -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\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Product extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'category_id',
|
||||
'brand',
|
||||
'specification',
|
||||
'base_unit',
|
||||
'large_unit',
|
||||
'conversion_rate',
|
||||
'purchase_unit',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'conversion_rate' => 'decimal:4',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the category that owns the product.
|
||||
*/
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function vendors(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Vendor::class)->withPivot('last_price')->withTimestamps();
|
||||
}
|
||||
|
||||
public function inventories(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Inventory::class);
|
||||
}
|
||||
|
||||
public function warehouses(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Warehouse::class, 'inventories')
|
||||
->withPivot(['quantity', 'safety_stock', 'location'])
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
104
app/Models/PurchaseOrder.php
Normal file
104
app/Models/PurchaseOrder.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class PurchaseOrder extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'vendor_id',
|
||||
'warehouse_id',
|
||||
'user_id',
|
||||
'status',
|
||||
'expected_delivery_date',
|
||||
'total_amount',
|
||||
'tax_amount',
|
||||
'grand_total',
|
||||
'remark',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'expected_delivery_date' => 'date',
|
||||
'total_amount' => 'decimal:2',
|
||||
'tax_amount' => 'decimal:2',
|
||||
'grand_total' => 'decimal:2',
|
||||
];
|
||||
|
||||
protected $appends = [
|
||||
'poNumber',
|
||||
'supplierId',
|
||||
'supplierName',
|
||||
'expectedDate',
|
||||
'totalAmount',
|
||||
'createdBy',
|
||||
'warehouse_name',
|
||||
'createdAt',
|
||||
];
|
||||
|
||||
public function getCreatedAtAttribute()
|
||||
{
|
||||
return $this->attributes['created_at'];
|
||||
}
|
||||
|
||||
public function getPoNumberAttribute(): string
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function getSupplierIdAttribute(): string
|
||||
{
|
||||
return (string) $this->vendor_id;
|
||||
}
|
||||
|
||||
public function getSupplierNameAttribute(): string
|
||||
{
|
||||
return $this->vendor ? $this->vendor->name : '';
|
||||
}
|
||||
|
||||
public function getExpectedDateAttribute(): ?string
|
||||
{
|
||||
return $this->expected_delivery_date ? $this->expected_delivery_date->format('Y-m-d') : null;
|
||||
}
|
||||
|
||||
public function getTotalAmountAttribute(): float
|
||||
{
|
||||
return (float) ($this->attributes['total_amount'] ?? 0);
|
||||
}
|
||||
|
||||
public function getCreatedByAttribute(): string
|
||||
{
|
||||
return $this->user ? $this->user->name : '系統';
|
||||
}
|
||||
|
||||
public function getWarehouseNameAttribute(): string
|
||||
{
|
||||
return $this->warehouse ? $this->warehouse->name : '';
|
||||
}
|
||||
|
||||
public function vendor(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Vendor::class);
|
||||
}
|
||||
|
||||
public function warehouse(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Warehouse::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(PurchaseOrderItem::class);
|
||||
}
|
||||
}
|
||||
65
app/Models/PurchaseOrderItem.php
Normal file
65
app/Models/PurchaseOrderItem.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class PurchaseOrderItem extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'purchase_order_id',
|
||||
'product_id',
|
||||
'quantity',
|
||||
'unit_price',
|
||||
'subtotal',
|
||||
'received_quantity',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'quantity' => 'decimal:2',
|
||||
'unit_price' => 'decimal:2',
|
||||
'subtotal' => 'decimal:2',
|
||||
'received_quantity' => 'decimal:2',
|
||||
];
|
||||
|
||||
protected $appends = [
|
||||
'productName',
|
||||
'unit',
|
||||
'productId',
|
||||
'unitPrice',
|
||||
];
|
||||
|
||||
public function getProductIdAttribute(): string
|
||||
{
|
||||
return (string) $this->attributes['product_id'];
|
||||
}
|
||||
|
||||
public function getUnitPriceAttribute(): float
|
||||
{
|
||||
return (float) $this->attributes['unit_price'];
|
||||
}
|
||||
|
||||
public function getProductNameAttribute(): string
|
||||
{
|
||||
return $this->product ? $this->product->name : '';
|
||||
}
|
||||
|
||||
public function getUnitAttribute(): string
|
||||
{
|
||||
return $this->product ? $this->product->base_unit : '';
|
||||
}
|
||||
|
||||
public function purchaseOrder(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(PurchaseOrder::class);
|
||||
}
|
||||
|
||||
public function product(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
}
|
||||
48
app/Models/User.php
Normal file
48
app/Models/User.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
}
|
||||
35
app/Models/Vendor.php
Normal file
35
app/Models/Vendor.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Vendor extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'short_name',
|
||||
'tax_id',
|
||||
'owner',
|
||||
'contact_name',
|
||||
'tel',
|
||||
'phone',
|
||||
'email',
|
||||
'address',
|
||||
'remark'
|
||||
];
|
||||
public function products(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Product::class, 'product_vendor')
|
||||
->withPivot('last_price')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function purchaseOrders(): HasMany
|
||||
{
|
||||
return $this->hasMany(PurchaseOrder::class);
|
||||
}
|
||||
}
|
||||
36
app/Models/Warehouse.php
Normal file
36
app/Models/Warehouse.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Warehouse extends Model
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\WarehouseFactory> */
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'name',
|
||||
'address',
|
||||
'description',
|
||||
];
|
||||
|
||||
public function inventories(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Inventory::class);
|
||||
}
|
||||
|
||||
public function purchaseOrders(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(PurchaseOrder::class);
|
||||
}
|
||||
|
||||
public function products(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Product::class, 'inventories')
|
||||
->withPivot(['quantity', 'safety_stock', 'location'])
|
||||
->withTimestamps();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user