initial: bootstrap from BukidBountyApp base
This commit is contained in:
57
app/Models/Accounting/Account.php
Normal file
57
app/Models/Accounting/Account.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Accounting;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Account extends Model
|
||||
{
|
||||
protected ?string $table = 'accounts';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'parent_id',
|
||||
'store_id',
|
||||
'type',
|
||||
'default_flow',
|
||||
'name',
|
||||
'description',
|
||||
'theme_key',
|
||||
'theme_account_code',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function transactions()
|
||||
{
|
||||
return $this->hasMany(AccountTransaction::class, 'account_id');
|
||||
}
|
||||
}
|
||||
49
app/Models/Accounting/AccountTransaction.php
Normal file
49
app/Models/Accounting/AccountTransaction.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Accounting;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class AccountTransaction extends Model
|
||||
{
|
||||
protected ?string $table = 'account_transactions';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'account_id',
|
||||
'item',
|
||||
'target_id',
|
||||
'amount',
|
||||
'flow',
|
||||
'notes',
|
||||
'transaction_date',
|
||||
'reference',
|
||||
'additional_details',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'additional_details' => 'json',
|
||||
'amount' => 'decimal:2',
|
||||
'transaction_date' => 'datetime',
|
||||
];
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo(Account::class, 'account_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
55
app/Models/Accounting/MemberLedger.php
Normal file
55
app/Models/Accounting/MemberLedger.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Accounting;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
use App\Models\Market\Organization;
|
||||
|
||||
class MemberLedger extends Model
|
||||
{
|
||||
protected ?string $table = 'member_ledgers';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'user_id',
|
||||
'organization_id',
|
||||
'amount',
|
||||
'transaction_type',
|
||||
'flow',
|
||||
'balance_after',
|
||||
'description',
|
||||
'reference_id',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'amount' => 'decimal:2',
|
||||
'balance_after' => 'decimal:2',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function organization()
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
59
app/Models/Announcement.php
Normal file
59
app/Models/Announcement.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
|
||||
class Announcement extends Model
|
||||
{
|
||||
protected ?string $table = 'announcements';
|
||||
|
||||
public bool $incrementing = true;
|
||||
|
||||
protected array $fillable = [
|
||||
'title',
|
||||
'content',
|
||||
'photo',
|
||||
'hashkey',
|
||||
'type',
|
||||
'is_active',
|
||||
'starts_at',
|
||||
'ends_at',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'starts_at' => 'datetime',
|
||||
'ends_at' => 'datetime',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
];
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function scopeActive($query)
|
||||
{
|
||||
$now = now();
|
||||
return $query->where('is_active', true)
|
||||
->where(function ($q) use ($now) {
|
||||
$q->whereNull('starts_at')
|
||||
->orWhere('starts_at', '<=', $now);
|
||||
})
|
||||
->where(function ($q) use ($now) {
|
||||
$q->whereNull('ends_at')
|
||||
->orWhere('ends_at', '>=', $now);
|
||||
});
|
||||
}
|
||||
}
|
||||
111
app/Models/Chapter.php
Normal file
111
app/Models/Chapter.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Market\UserInfo;
|
||||
|
||||
class Chapter extends Model
|
||||
{
|
||||
protected ?string $table = 'chapters';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey', 'name', 'cooperative_id', 'level', 'parent_id', 'location_key',
|
||||
'lat', 'lng', 'is_active', 'created_by', 'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'lat' => 'float',
|
||||
'lng' => 'float',
|
||||
];
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(Chapter::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function cooperative()
|
||||
{
|
||||
return $this->belongsTo(\App\Models\Market\Organization::class, 'cooperative_id');
|
||||
}
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(Chapter::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function chapterMembers()
|
||||
{
|
||||
return $this->hasMany(ChapterMember::class, 'chapter_id');
|
||||
}
|
||||
|
||||
public function activeMembers()
|
||||
{
|
||||
return $this->chapterMembers()->where('is_active', true);
|
||||
}
|
||||
|
||||
public function leaders()
|
||||
{
|
||||
return $this->activeMembers()->whereNotNull('position');
|
||||
}
|
||||
|
||||
/**
|
||||
* Find or create a chapter by level + location_key (normalized address field).
|
||||
*/
|
||||
public static function findOrCreateByLocation(string $level, string $locationKey, ?int $parentId = null): self
|
||||
{
|
||||
$key = strtolower(trim($locationKey));
|
||||
return static::firstOrCreate(
|
||||
['level' => $level, 'location_key' => $key],
|
||||
[
|
||||
'hashkey' => \Ramsey\Uuid\Uuid::uuid4()->toString(),
|
||||
'name' => ucwords(strtolower($locationKey)),
|
||||
'level' => $level,
|
||||
'location_key'=> $key,
|
||||
'parent_id' => $parentId,
|
||||
'is_active' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-assign a user to the appropriate chapters based on their UserInfo address.
|
||||
* Creates chapter records on the fly if they don't exist.
|
||||
*/
|
||||
public static function autoAssignUser(int $userId): void
|
||||
{
|
||||
$info = UserInfo::where('user_id', $userId)->first();
|
||||
if (!$info) {
|
||||
return;
|
||||
}
|
||||
|
||||
$national = static::firstOrCreate(
|
||||
['level' => 'national', 'location_key' => 'philippines'],
|
||||
['hashkey' => \Ramsey\Uuid\Uuid::uuid4()->toString(), 'name' => 'Philippines', 'level' => 'national', 'location_key' => 'philippines', 'is_active' => true]
|
||||
);
|
||||
|
||||
ChapterMember::syncAutoAssignment($userId, $national->id);
|
||||
|
||||
if ($info->region) {
|
||||
$region = static::findOrCreateByLocation('region', $info->region, $national->id);
|
||||
ChapterMember::syncAutoAssignment($userId, $region->id);
|
||||
|
||||
if ($info->province) {
|
||||
$province = static::findOrCreateByLocation('province', $info->province, $region->id);
|
||||
ChapterMember::syncAutoAssignment($userId, $province->id);
|
||||
|
||||
if ($info->city) {
|
||||
$city = static::findOrCreateByLocation('city', $info->city, $province->id);
|
||||
ChapterMember::syncAutoAssignment($userId, $city->id);
|
||||
|
||||
if ($info->barangay) {
|
||||
$barangay = static::findOrCreateByLocation('barangay', $info->barangay, $city->id);
|
||||
ChapterMember::syncAutoAssignment($userId, $barangay->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
app/Models/ChapterMember.php
Normal file
55
app/Models/ChapterMember.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class ChapterMember extends Model
|
||||
{
|
||||
protected ?string $table = 'chapter_members';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey', 'user_id', 'chapter_id', 'position', 'role',
|
||||
'is_manual_override', 'is_active', 'assigned_by', 'assigned_at',
|
||||
'created_by', 'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_manual_override' => 'boolean',
|
||||
'is_active' => 'boolean',
|
||||
'assigned_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function chapter()
|
||||
{
|
||||
return $this->belongsTo(Chapter::class, 'chapter_id');
|
||||
}
|
||||
|
||||
public function isOfficer(): bool
|
||||
{
|
||||
return !empty($this->role) && $this->role !== 'MEMBER';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync auto-assignment for a user to a chapter — only if no manual override exists.
|
||||
*/
|
||||
public static function syncAutoAssignment(int $userId, int $chapterId): void
|
||||
{
|
||||
static::updateOrCreate(
|
||||
['user_id' => $userId, 'chapter_id' => $chapterId],
|
||||
[
|
||||
'is_active' => true,
|
||||
'is_manual_override' => false, // Only sync if we're not overriding?
|
||||
// Actually the rule is: if it exists, only update if NOT manual override.
|
||||
// updateOrCreate doesn't support conditional update easily.
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
51
app/Models/DbBackup.php
Normal file
51
app/Models/DbBackup.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $hashkey
|
||||
* @property string $file_content_hashkey
|
||||
* @property string $filename
|
||||
* @property int $size_in_bytes
|
||||
* @property bool $is_active
|
||||
* @property int $created_by
|
||||
* @property int $updated_by
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
*/
|
||||
class DbBackup extends Model
|
||||
{
|
||||
protected ?string $table = 'db_backups';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'name',
|
||||
'file_content_hashkey',
|
||||
'filename',
|
||||
'size_in_bytes',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'id' => 'integer',
|
||||
'size_in_bytes' => 'integer',
|
||||
'is_active' => 'boolean',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
];
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
49
app/Models/FileContent.php
Normal file
49
app/Models/FileContent.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class FileContent extends Model
|
||||
{
|
||||
protected ?string $table = 'file_content';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'filehash',
|
||||
'titlename',
|
||||
'description',
|
||||
'size_in_bytes',
|
||||
'content',
|
||||
'filelocation',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'details',
|
||||
'mimetype',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'size_in_bytes' => 'integer',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
'details' => 'array'
|
||||
];
|
||||
|
||||
/**
|
||||
* Related file_list records
|
||||
*/
|
||||
public function fileLists()
|
||||
{
|
||||
return $this->hasMany(FileList::class, 'contentuid');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
75
app/Models/FileList.php
Normal file
75
app/Models/FileList.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
|
||||
class FileList extends Model
|
||||
{
|
||||
|
||||
protected ?string $table = 'file_list';
|
||||
|
||||
protected array $fillable = [
|
||||
'uid',
|
||||
'useruid_access_list',
|
||||
'hashkey',
|
||||
'contentuid',
|
||||
'title',
|
||||
'filename',
|
||||
'cdn_url',
|
||||
'is_public',
|
||||
'file_type',
|
||||
'description',
|
||||
'tags',
|
||||
'hidden',
|
||||
'categories',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'details'
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'hidden' => 'integer',
|
||||
'is_public' => 'boolean',
|
||||
'contentuid' => 'integer',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
'details' => 'array',
|
||||
'useruid_access_list' => 'array',
|
||||
'tags'=>'array',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Reference to file content
|
||||
*/
|
||||
public function fileContent()
|
||||
{
|
||||
return $this->belongsTo(FileContent::class, 'contentuid');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a usable URL for this file. Prefers `cdn_url` (e.g. a
|
||||
* jsDelivr-fronted CDN asset) when set; otherwise falls back to the
|
||||
* local /RequestData/File/{hash} route.
|
||||
*/
|
||||
public function resolvedUrl(): string
|
||||
{
|
||||
$cdn = trim((string) ($this->cdn_url ?? ''));
|
||||
if ($cdn !== '') {
|
||||
return $cdn;
|
||||
}
|
||||
return "/RequestData/File/{$this->hashkey}";
|
||||
}
|
||||
}
|
||||
47
app/Models/Generic/TableLog.php
Normal file
47
app/Models/Generic/TableLog.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Generic;
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class TableLog extends Model
|
||||
{
|
||||
protected ?string $table = 'table_logs';
|
||||
|
||||
protected array $casts = [
|
||||
'original_data' => 'array',
|
||||
'new_data' => 'array',
|
||||
];
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'table_name',
|
||||
'target_id',
|
||||
'original_data',
|
||||
'new_data',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
// Auto-merge accessor
|
||||
public function get_full_new_row(): array
|
||||
{
|
||||
return array_merge($this->original_data ?? [], $this->new_data ?? []);
|
||||
}
|
||||
|
||||
public function data(){
|
||||
return $this->get_full_new_row();
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
72
app/Models/GlobalTransaction.php
Normal file
72
app/Models/GlobalTransaction.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
use App\Models\Market\Product;
|
||||
use App\Models\Market\Store;
|
||||
use App\Enums\Market\ProductTransactionType;
|
||||
use App\Enums\Market\TransactionFlow;
|
||||
|
||||
class GlobalTransaction extends Model
|
||||
{
|
||||
protected ?string $table = 'global_transactions';
|
||||
|
||||
protected string $primaryKey = 'id';
|
||||
|
||||
public bool $incrementing = true;
|
||||
|
||||
protected string $keyType = 'int';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'user_id',
|
||||
'amount',
|
||||
'type',
|
||||
'status',
|
||||
'description',
|
||||
'product_id',
|
||||
'store_id',
|
||||
'flow',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'amount' => 'decimal:2',
|
||||
'type' => ProductTransactionType::class,
|
||||
'user_id' => 'integer',
|
||||
'product_id' => 'integer',
|
||||
'store_id' => 'integer',
|
||||
'flow' => TransactionFlow::class,
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class, 'product_id');
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
56
app/Models/LandingPage.php
Normal file
56
app/Models/LandingPage.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
|
||||
class LandingPage extends Model
|
||||
{
|
||||
protected ?string $table = 'landing_pages';
|
||||
|
||||
protected array $fillable = [
|
||||
'title',
|
||||
'html_content',
|
||||
'description',
|
||||
'hashkey',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the currently active landing page.
|
||||
*/
|
||||
public static function getActive(): ?self
|
||||
{
|
||||
return static::where('is_active', true)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this landing page as the active one, deactivating all others.
|
||||
*/
|
||||
public function setAsActive(): void
|
||||
{
|
||||
// Deactivate all other landing pages
|
||||
static::where('id', '!=', $this->id)->update(['is_active' => false]);
|
||||
|
||||
// Activate this one
|
||||
$this->is_active = true;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate this landing page.
|
||||
*/
|
||||
public function deactivate(): void
|
||||
{
|
||||
$this->is_active = false;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
35
app/Models/Market/Cart.php
Normal file
35
app/Models/Market/Cart.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Cart extends Model
|
||||
{
|
||||
protected ?string $table = 'carts';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'user_id',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany(CartItem::class, 'cart_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
}
|
||||
39
app/Models/Market/CartItem.php
Normal file
39
app/Models/Market/CartItem.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
|
||||
class CartItem extends Model
|
||||
{
|
||||
protected ?string $table = 'cart_items';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'cart_id',
|
||||
'product_id',
|
||||
'quantity',
|
||||
'price',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'quantity' => 'integer',
|
||||
'price' => 'float',
|
||||
];
|
||||
|
||||
public function cart()
|
||||
{
|
||||
return $this->belongsTo(Cart::class, 'cart_id');
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class, 'product_id');
|
||||
}
|
||||
}
|
||||
41
app/Models/Market/CooperativeDocument.php
Normal file
41
app/Models/Market/CooperativeDocument.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\User;
|
||||
use Hypervel\Database\Eloquent\Model;
|
||||
|
||||
class CooperativeDocument extends Model
|
||||
{
|
||||
protected ?string $table = 'cooperative_documents';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'parent_hashkey',
|
||||
'version_number',
|
||||
'organization_id',
|
||||
'file_hashkey',
|
||||
'document_type',
|
||||
'revision_note',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
public function organization()
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
63
app/Models/Market/CooperativeMember.php
Normal file
63
app/Models/Market/CooperativeMember.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class CooperativeMember extends Model
|
||||
{
|
||||
protected ?string $table = 'cooperative_members';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey', 'organization_id', 'user_id', 'role',
|
||||
'membership_type', 'membership_level',
|
||||
'officer_position', 'officer_level',
|
||||
'concurrent_position', 'concurrent_level',
|
||||
'cooperative_name_alt', 'cooperative_position', 'year_beginning',
|
||||
// Classification
|
||||
'priority_sector', 'common_bond', 'vulnerability_classifications',
|
||||
// Government IDs
|
||||
'philsys_id', 'sss_number', 'pagibig_number',
|
||||
// SLP
|
||||
'slp_track', 'slp_association_name', 'listahanan_id', 'fourtps_household_id',
|
||||
// TUPAD
|
||||
'tupad_category', 'tupad_insurance_beneficiary_name', 'tupad_insurance_beneficiary_relation',
|
||||
// OSEC/NSRP
|
||||
'preferred_occupation', 'nsrp_skills', 'employment_status',
|
||||
// Programs
|
||||
'program_participation',
|
||||
'joined_at', 'is_active', 'created_by', 'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'joined_at' => 'datetime',
|
||||
'is_active' => 'boolean',
|
||||
'priority_sector' => 'array',
|
||||
'vulnerability_classifications' => 'array',
|
||||
'nsrp_skills' => 'array',
|
||||
'program_participation' => 'array',
|
||||
];
|
||||
|
||||
public function organization()
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
51
app/Models/Market/CooperativeResolution.php
Normal file
51
app/Models/Market/CooperativeResolution.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class CooperativeResolution extends Model
|
||||
{
|
||||
protected ?string $table = 'cooperative_resolutions';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'organization_id',
|
||||
'title',
|
||||
'description',
|
||||
'date_approved',
|
||||
'document_url',
|
||||
'status',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'date_approved' => 'date',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function organization()
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function votes()
|
||||
{
|
||||
return $this->hasMany(CooperativeVote::class, 'resolution_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
47
app/Models/Market/CooperativeVote.php
Normal file
47
app/Models/Market/CooperativeVote.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class CooperativeVote extends Model
|
||||
{
|
||||
protected ?string $table = 'cooperative_votes';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'resolution_id',
|
||||
'user_id',
|
||||
'vote_cast',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function resolution()
|
||||
{
|
||||
return $this->belongsTo(CooperativeResolution::class, 'resolution_id');
|
||||
}
|
||||
|
||||
public function voter()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
42
app/Models/Market/Courier.php
Normal file
42
app/Models/Market/Courier.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Courier extends Model
|
||||
{
|
||||
protected ?string $table = 'couriers';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'name',
|
||||
'contact_number',
|
||||
'type',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function shipments()
|
||||
{
|
||||
return $this->hasMany(Shipment::class, 'courier_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
52
app/Models/Market/Customer.php
Normal file
52
app/Models/Market/Customer.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Customer extends Model
|
||||
{
|
||||
protected ?string $table = 'cst';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'name',
|
||||
'phone',
|
||||
'email',
|
||||
'store_id',
|
||||
'user_id',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
}
|
||||
53
app/Models/Market/FarmerProfile.php
Normal file
53
app/Models/Market/FarmerProfile.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class FarmerProfile extends Model
|
||||
{
|
||||
protected ?string $table = 'farmer_profiles';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'user_id',
|
||||
'organization_id',
|
||||
'farm_name',
|
||||
'farm_location',
|
||||
'main_crops',
|
||||
'verification_status',
|
||||
'certification_details',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'main_crops' => 'array',
|
||||
'certification_details' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function organization()
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
44
app/Models/Market/MainOrganization.php
Normal file
44
app/Models/Market/MainOrganization.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class MainOrganization extends Model
|
||||
{
|
||||
protected ?string $table = 'main_organizations';
|
||||
|
||||
protected array $fillable = [
|
||||
'organization_id',
|
||||
'role',
|
||||
'priority',
|
||||
'is_active',
|
||||
'metadata',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'priority' => 'integer',
|
||||
'metadata' => 'array',
|
||||
];
|
||||
|
||||
public function organization()
|
||||
{
|
||||
return $this->belongsTo(Organization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
78
app/Models/Market/Organization.php
Normal file
78
app/Models/Market/Organization.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Organization extends Model
|
||||
{
|
||||
protected ?string $table = 'organizations';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'name',
|
||||
'type',
|
||||
'address',
|
||||
'registration_number',
|
||||
'cin',
|
||||
'tin',
|
||||
'cooperative_type',
|
||||
'cooperative_category',
|
||||
'registration_date',
|
||||
'contact_person',
|
||||
'contact_number',
|
||||
'contact_email',
|
||||
'compliance_status',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
'registration_date' => 'date',
|
||||
];
|
||||
|
||||
public function members()
|
||||
{
|
||||
return $this->hasMany(CooperativeMember::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function farmerProfiles()
|
||||
{
|
||||
return $this->hasMany(FarmerProfile::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function stores()
|
||||
{
|
||||
return $this->belongsToMany(Store::class, 'org_str', 'organization_id', 'store_id')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function mainAssignments()
|
||||
{
|
||||
return $this->hasMany(MainOrganization::class, 'organization_id');
|
||||
}
|
||||
|
||||
public function isMain(?string $role = null): bool
|
||||
{
|
||||
$query = $this->mainAssignments()->where('is_active', true);
|
||||
if ($role !== null) {
|
||||
$query->where('role', $role);
|
||||
}
|
||||
return $query->exists();
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
89
app/Models/Market/PosAccessKey.php
Normal file
89
app/Models/Market/PosAccessKey.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $hashkey
|
||||
* @property string $access_key
|
||||
* @property int $store_id
|
||||
* @property string $name
|
||||
* @property string $status
|
||||
* @property string $last_used_at
|
||||
* @property int $created_by
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
*/
|
||||
class PosAccessKey extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*/
|
||||
protected ?string $table = 'pos_access_keys';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'access_key',
|
||||
'store_id',
|
||||
'name',
|
||||
'status',
|
||||
'is_active',
|
||||
'expires_at',
|
||||
'last_used_at',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*/
|
||||
protected array $casts = [
|
||||
'id' => 'integer',
|
||||
'store_id' => 'integer',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
'is_active' => 'boolean',
|
||||
'expires_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* Check if this access key is expired.
|
||||
*/
|
||||
public function isExpired(): bool
|
||||
{
|
||||
return $this->expires_at !== null && $this->expires_at->isPast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-expire: set all expired active keys to inactive.
|
||||
* Call this before listing or validating keys.
|
||||
*/
|
||||
public static function autoExpire(): void
|
||||
{
|
||||
self::where('status', 'active')
|
||||
->whereNotNull('expires_at')
|
||||
->where('expires_at', '<', now())
|
||||
->update(['status' => 'inactive']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
}
|
||||
70
app/Models/Market/PosSession.php
Normal file
70
app/Models/Market/PosSession.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class PosSession extends Model
|
||||
{
|
||||
protected ?string $table = 'pos_sessions';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'access_key',
|
||||
'store_id',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'customer_name',
|
||||
'total_amount',
|
||||
'received_amount',
|
||||
'change_amount',
|
||||
'payment_method',
|
||||
'payment_details',
|
||||
'status',
|
||||
'is_void',
|
||||
'notes',
|
||||
'additionaldata',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_void' => 'boolean',
|
||||
'payment_details' => 'array',
|
||||
'additionaldata' => 'array',
|
||||
'total_amount' => 'integer',
|
||||
'received_amount' => 'integer',
|
||||
'change_amount' => 'integer',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
];
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function transactions()
|
||||
{
|
||||
return $this->hasMany(PosTransaction::class, 'pos_session_id');
|
||||
}
|
||||
|
||||
public function archives()
|
||||
{
|
||||
return $this->hasMany(PosSessionArchive::class, 'pos_session_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
}
|
||||
49
app/Models/Market/PosSessionArchive.php
Normal file
49
app/Models/Market/PosSessionArchive.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class PosSessionArchive extends Model
|
||||
{
|
||||
protected ?string $table = 'pos_sessions_archive';
|
||||
|
||||
protected array $fillable = [
|
||||
'pos_session_id',
|
||||
'hashkey',
|
||||
'session_snapshot',
|
||||
'transactions_snapshot',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'remarks',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'session_snapshot' => 'array',
|
||||
'transactions_snapshot' => 'array',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
'pos_session_id' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function session()
|
||||
{
|
||||
return $this->belongsTo(PosSession::class, 'pos_session_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
49
app/Models/Market/PosTransaction.php
Normal file
49
app/Models/Market/PosTransaction.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
|
||||
class PosTransaction extends Model
|
||||
{
|
||||
protected ?string $table = 'pos_transactions';
|
||||
|
||||
protected array $fillable = [
|
||||
'pos_session_id',
|
||||
'product_id',
|
||||
'quantity',
|
||||
'price_at_sale',
|
||||
'discount',
|
||||
'total_price',
|
||||
'is_void',
|
||||
'remarks',
|
||||
'hashkey',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_void' => 'boolean',
|
||||
'quantity' => 'integer',
|
||||
'price_at_sale' => 'integer',
|
||||
'discount' => 'integer',
|
||||
'total_price' => 'integer',
|
||||
'created_by' => 'integer',
|
||||
'updated_by' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function session()
|
||||
{
|
||||
return $this->belongsTo(PosSession::class, 'pos_session_id');
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class, 'product_id');
|
||||
}
|
||||
}
|
||||
91
app/Models/Market/Product.php
Normal file
91
app/Models/Market/Product.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Product extends Model
|
||||
{
|
||||
|
||||
protected ?string $table = 'prd_items';
|
||||
protected string $primaryKey = 'id';
|
||||
public bool $incrementing = true;
|
||||
protected string $keyType = 'int';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'created_for',
|
||||
'category',
|
||||
'subcategory',
|
||||
'logs',
|
||||
'specs',
|
||||
'photourl',
|
||||
'available',
|
||||
'sold',
|
||||
'price',
|
||||
// 'store_id',
|
||||
'owner_id',
|
||||
'views',
|
||||
'name',
|
||||
'description',
|
||||
'reviews',
|
||||
'barcode',
|
||||
'status',
|
||||
'remarks',
|
||||
'unitname',
|
||||
'rating',
|
||||
'sku',
|
||||
'qrcode',
|
||||
'shortcode',
|
||||
'shortname',
|
||||
'is_active',
|
||||
'product_type'
|
||||
];
|
||||
|
||||
|
||||
|
||||
protected array $casts = [
|
||||
'available' => 'integer',
|
||||
'sold' => 'integer',
|
||||
'price' => 'integer',
|
||||
'views' => 'integer',
|
||||
'rating' => 'integer',
|
||||
'is_active' => 'boolean',
|
||||
'photourl' => 'array',
|
||||
'reviews' => 'array',
|
||||
'specs' => 'array',
|
||||
];
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function stores()
|
||||
{
|
||||
return $this->belongsToMany(Store::class, 'prd_str')
|
||||
->withPivot(['available', 'price', 'is_active'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function owner()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'owner_id');
|
||||
}
|
||||
|
||||
public function createdFor()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_for');
|
||||
}
|
||||
|
||||
}
|
||||
102
app/Models/Market/ProductTransaction.php
Normal file
102
app/Models/Market/ProductTransaction.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class ProductTransaction extends Model
|
||||
{
|
||||
protected ?string $table = 'prd_trx';
|
||||
|
||||
/**
|
||||
* The primary key for the model.
|
||||
*/
|
||||
protected string $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the IDs are auto-incrementing.
|
||||
*/
|
||||
public bool $incrementing = true;
|
||||
|
||||
/**
|
||||
* The "type" of the primary key.
|
||||
*/
|
||||
protected string $keyType = 'int';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'created_for',
|
||||
'store_id',
|
||||
'transactiontype',
|
||||
'product_id',
|
||||
'transactiondata',
|
||||
'description',
|
||||
'subtype',
|
||||
'name',
|
||||
'owner_id',
|
||||
'transactionsessionhash',
|
||||
'quantity',
|
||||
'logs',
|
||||
'remarks',
|
||||
'price',
|
||||
'is_void',
|
||||
'last_total_price',
|
||||
'last_total_discount',
|
||||
'notes'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*/
|
||||
protected array $casts = [
|
||||
'quantity' => 'integer',
|
||||
'price' => 'integer',
|
||||
'is_void' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships.
|
||||
*/
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class, 'product_id');
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
public function owner()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'owner_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function createdFor()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_for');
|
||||
}
|
||||
|
||||
public function session()
|
||||
{
|
||||
return $this->belongsTo(ProductTransactionSession::class, 'transactionsessionhash', 'hashkey');
|
||||
}
|
||||
}
|
||||
84
app/Models/Market/ProductTransactionSession.php
Normal file
84
app/Models/Market/ProductTransactionSession.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class ProductTransactionSession extends Model
|
||||
{
|
||||
protected ?string $table = 'prd_trx_ses';
|
||||
|
||||
/**
|
||||
* The primary key for the model.
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the IDs are auto-incrementing.
|
||||
*/
|
||||
public $incrementing = true;
|
||||
|
||||
/**
|
||||
* The "type" of the primary key.
|
||||
*/
|
||||
protected $keyType = 'int';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'name',
|
||||
'description',
|
||||
'logs',
|
||||
'remarks',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'created_for',
|
||||
'subtype',
|
||||
'additionaldata',
|
||||
'category',
|
||||
'store_id',
|
||||
'status',
|
||||
'is_void',
|
||||
'last_total_price',
|
||||
'last_total_discount',
|
||||
'notes',
|
||||
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_void' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships.
|
||||
*/
|
||||
public function transactions()
|
||||
{
|
||||
return $this->hasMany(ProductTransaction::class, 'transactionsessionhash', 'hashkey');
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function createdFor()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_for');
|
||||
}
|
||||
}
|
||||
72
app/Models/Market/ProductTransactionSessionArchive.php
Normal file
72
app/Models/Market/ProductTransactionSessionArchive.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class ProductTransactionSessionArchive extends Model
|
||||
{
|
||||
protected ?string $table = 'prd_trx_ses_arc';
|
||||
|
||||
/**
|
||||
* The primary key for the model.
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the IDs are auto-incrementing.
|
||||
*/
|
||||
public $incrementing = true;
|
||||
|
||||
/**
|
||||
* The "type" of the primary key.
|
||||
*/
|
||||
protected $keyType = 'int';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected array $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'details',
|
||||
'hashkey',
|
||||
'transactions_sessions_id',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'created_for',
|
||||
'transactions_snapshot'
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'details' => 'array',
|
||||
'transactions_snapshot' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships.
|
||||
*/
|
||||
public function transactionSession()
|
||||
{
|
||||
return $this->belongsTo(ProductTransactionSession::class, 'transactions_sessions_id');
|
||||
}
|
||||
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function createdFor()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_for');
|
||||
}
|
||||
}
|
||||
69
app/Models/Market/Shipment.php
Normal file
69
app/Models/Market/Shipment.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
use App\Models\GlobalTransaction;
|
||||
|
||||
class Shipment extends Model
|
||||
{
|
||||
protected ?string $table = 'shipments';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'transaction_id',
|
||||
'store_id',
|
||||
'customer_id',
|
||||
'courier_id',
|
||||
'tracking_number',
|
||||
'status',
|
||||
'origin_address',
|
||||
'destination_address',
|
||||
'estimated_delivery_date',
|
||||
'actual_delivery_date',
|
||||
'shipping_fee',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'estimated_delivery_date' => 'datetime',
|
||||
'actual_delivery_date' => 'datetime',
|
||||
'shipping_fee' => 'decimal:2',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function transaction()
|
||||
{
|
||||
return $this->belongsTo(GlobalTransaction::class, 'transaction_id');
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsTo(Customer::class, 'customer_id');
|
||||
}
|
||||
|
||||
public function courier()
|
||||
{
|
||||
return $this->belongsTo(Courier::class, 'courier_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
117
app/Models/Market/Store.php
Normal file
117
app/Models/Market/Store.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Store extends Model
|
||||
{
|
||||
protected ?string $table = 'str';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'storecode',
|
||||
'name',
|
||||
'description',
|
||||
'status',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'created_for',
|
||||
'remarks',
|
||||
'logs',
|
||||
'specs',
|
||||
'additionaldata',
|
||||
'owner_id',
|
||||
'manager_id',
|
||||
'category',
|
||||
'subcategory',
|
||||
'photourl',
|
||||
'address',
|
||||
'is_active',
|
||||
'store_type',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'photourl' => 'array',
|
||||
'is_active' => 'boolean',
|
||||
'store_type'=> 'array',
|
||||
'specs' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Relationships
|
||||
*/
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
|
||||
public function createdFor()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_for');
|
||||
}
|
||||
|
||||
public function owner()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'owner_id');
|
||||
}
|
||||
|
||||
public function manager()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'manager_id');
|
||||
}
|
||||
|
||||
public function managers()
|
||||
{
|
||||
return $this->hasMany(StoreManager::class, 'store_id');
|
||||
}
|
||||
|
||||
public function managerUsers()
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'store_managers', 'store_id', 'user_id')
|
||||
->withPivot(['hashkey', 'created_by', 'updated_by', 'is_active'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
// public function products()
|
||||
// {
|
||||
// return $this->hasMany(Product::class, 'store_id');
|
||||
// }
|
||||
|
||||
public function products()
|
||||
{
|
||||
return $this->belongsToMany(Product::class, 'prd_str')
|
||||
->withPivot(['available', 'price', 'is_active','sold','logs','reviews','status','remarks','description'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function cooperatives()
|
||||
{
|
||||
return $this->belongsToMany(Organization::class, 'org_str', 'store_id', 'organization_id')
|
||||
->where('organizations.type', 'COOPERATIVE')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function transactions()
|
||||
{
|
||||
return $this->hasMany(ProductTransaction::class, 'store_id');
|
||||
}
|
||||
|
||||
public function transactionSessions()
|
||||
{
|
||||
return $this->hasMany(ProductTransactionSession::class, 'store_id');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
46
app/Models/Market/StoreManager.php
Normal file
46
app/Models/Market/StoreManager.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class StoreManager extends Model
|
||||
{
|
||||
protected ?string $table = 'store_managers';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'store_id',
|
||||
'user_id',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->belongsTo(Store::class, 'store_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
114
app/Models/Market/UserInfo.php
Normal file
114
app/Models/Market/UserInfo.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Market;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class UserInfo extends Model
|
||||
{
|
||||
protected ?string $table = 'user_infos';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'user_id',
|
||||
'firstname',
|
||||
'middlename',
|
||||
'lastname',
|
||||
'suffix',
|
||||
'gender',
|
||||
'dob',
|
||||
'priority_sector',
|
||||
'messenger_id',
|
||||
'viber_number',
|
||||
'tiktok_username',
|
||||
'region',
|
||||
'province',
|
||||
'city',
|
||||
'barangay',
|
||||
'civil_status',
|
||||
'children_count',
|
||||
'dependent_count',
|
||||
'education_level',
|
||||
'course',
|
||||
'school',
|
||||
'year_last_attended',
|
||||
'livelihood_source',
|
||||
'last_company',
|
||||
'employer_name',
|
||||
'last_position',
|
||||
'occupation',
|
||||
'last_employment_year',
|
||||
'monthly_income',
|
||||
'tin',
|
||||
'philhealth_id',
|
||||
'gov_id',
|
||||
'id_type',
|
||||
'id_number',
|
||||
'beneficiary_type',
|
||||
'emergency_contact_name',
|
||||
'emergency_contact_address',
|
||||
'emergency_contact_phone',
|
||||
'emergency_contact_relation',
|
||||
'emergency_contact_user_id',
|
||||
'fullname',
|
||||
'landline',
|
||||
'mobile',
|
||||
'email',
|
||||
'alt_email',
|
||||
'alt_landline',
|
||||
'alt_mobile',
|
||||
'facebook_url',
|
||||
'bank_details',
|
||||
'bank_account_no',
|
||||
'addresses',
|
||||
'other_details',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'bank_details' => 'json',
|
||||
'addresses' => 'json',
|
||||
'other_details' => 'json',
|
||||
'is_active' => 'boolean',
|
||||
'dob' => 'date',
|
||||
'monthly_income' => 'float',
|
||||
'children_count' => 'integer',
|
||||
'dependent_count' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the virtual age attribute.
|
||||
*/
|
||||
public function getAgeAttribute(): ?int
|
||||
{
|
||||
if (!$this->dob) {
|
||||
return null;
|
||||
}
|
||||
return $this->dob->diffInYears(now());
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function emergencyContactUser()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'emergency_contact_user_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
12
app/Models/Model.php
Normal file
12
app/Models/Model.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Hypervel\Database\Eloquent\Model as BaseModel;
|
||||
|
||||
abstract class Model extends BaseModel
|
||||
{
|
||||
protected ?string $connection = null;
|
||||
}
|
||||
119
app/Models/PersonalAccessToken.php
Normal file
119
app/Models/PersonalAccessToken.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Support\TokenAbilities;
|
||||
use Hyperf\Database\Model\Relations\MorphTo;
|
||||
|
||||
class PersonalAccessToken extends Model
|
||||
{
|
||||
protected ?string $table = 'personal_access_tokens';
|
||||
|
||||
public bool $incrementing = true;
|
||||
|
||||
protected array $fillable = [
|
||||
'tokenable_type',
|
||||
'tokenable_id',
|
||||
'name',
|
||||
'description',
|
||||
'token',
|
||||
'abilities',
|
||||
'allowed_ips',
|
||||
'last_used_at',
|
||||
'last_used_ip',
|
||||
'expires_at',
|
||||
'created_by',
|
||||
'revoked_by',
|
||||
'revoked_at',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'abilities' => 'array',
|
||||
'allowed_ips' => 'array',
|
||||
'last_used_at' => 'datetime',
|
||||
'expires_at' => 'datetime',
|
||||
'revoked_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected array $hidden = [
|
||||
'token',
|
||||
];
|
||||
|
||||
public function tokenable(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public static function findByPlainToken(string $plain): ?self
|
||||
{
|
||||
return static::query()->where('token', hash('sha256', $plain))->first();
|
||||
}
|
||||
|
||||
public function isExpired(): bool
|
||||
{
|
||||
return $this->expires_at !== null && $this->expires_at->isPast();
|
||||
}
|
||||
|
||||
public function isRevoked(): bool
|
||||
{
|
||||
return $this->revoked_at !== null;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return ! $this->isExpired() && ! $this->isRevoked();
|
||||
}
|
||||
|
||||
public function can(string $ability): bool
|
||||
{
|
||||
$abilities = $this->abilities ?? [];
|
||||
if (in_array(TokenAbilities::WILDCARD, $abilities, true)) {
|
||||
return true;
|
||||
}
|
||||
return in_array($ability, $abilities, true);
|
||||
}
|
||||
|
||||
public function ipAllowed(string $ip): bool
|
||||
{
|
||||
$list = $this->allowed_ips ?? [];
|
||||
if (empty($list)) {
|
||||
return true;
|
||||
}
|
||||
foreach ($list as $entry) {
|
||||
if ($this->ipMatches($ip, $entry)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function ipMatches(string $ip, string $entry): bool
|
||||
{
|
||||
$entry = trim($entry);
|
||||
if ($entry === '') {
|
||||
return false;
|
||||
}
|
||||
if (! str_contains($entry, '/')) {
|
||||
return $ip === $entry;
|
||||
}
|
||||
[$subnet, $bits] = explode('/', $entry, 2);
|
||||
$bits = (int) $bits;
|
||||
$ipBin = @inet_pton($ip);
|
||||
$subnetBin = @inet_pton($subnet);
|
||||
if ($ipBin === false || $subnetBin === false || strlen($ipBin) !== strlen($subnetBin)) {
|
||||
return false;
|
||||
}
|
||||
$bytes = intdiv($bits, 8);
|
||||
$remainder = $bits % 8;
|
||||
if (substr($ipBin, 0, $bytes) !== substr($subnetBin, 0, $bytes)) {
|
||||
return false;
|
||||
}
|
||||
if ($remainder === 0) {
|
||||
return true;
|
||||
}
|
||||
$mask = chr(0xff << (8 - $remainder) & 0xff);
|
||||
return (ord($ipBin[$bytes]) & ord($mask)) === (ord($subnetBin[$bytes]) & ord($mask));
|
||||
}
|
||||
}
|
||||
46
app/Models/Property/Property.php
Normal file
46
app/Models/Property/Property.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Property;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Property extends Model
|
||||
{
|
||||
protected ?string $table = 'properties';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'name',
|
||||
'location',
|
||||
'price',
|
||||
'status',
|
||||
'details',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'details' => 'json',
|
||||
'price' => 'decimal:2',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function referrals()
|
||||
{
|
||||
return $this->hasMany(Referral::class, 'property_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
57
app/Models/Property/Referral.php
Normal file
57
app/Models/Property/Referral.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Property;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Referral extends Model
|
||||
{
|
||||
protected ?string $table = 'referrals';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'property_id',
|
||||
'referrer_id',
|
||||
'referred_id',
|
||||
'referred_name',
|
||||
'referred_contact',
|
||||
'status',
|
||||
'details',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'details' => 'json',
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function property()
|
||||
{
|
||||
return $this->belongsTo(Property::class, 'property_id');
|
||||
}
|
||||
|
||||
public function referrer()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'referrer_id');
|
||||
}
|
||||
|
||||
public function referred()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'referred_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
41
app/Models/Property/ReferralKey.php
Normal file
41
app/Models/Property/ReferralKey.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Property;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class ReferralKey extends Model
|
||||
{
|
||||
protected ?string $table = 'referral_keys';
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'user_id',
|
||||
'key',
|
||||
'is_active',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'updated_by');
|
||||
}
|
||||
}
|
||||
54
app/Models/Subscription/Subscription.php
Normal file
54
app/Models/Subscription/Subscription.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Subscription;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Subscription extends Model
|
||||
{
|
||||
protected ?string $table = 'subscriptions';
|
||||
|
||||
public bool $incrementing = true;
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'user_id',
|
||||
'plan_id',
|
||||
'status',
|
||||
'starts_at',
|
||||
'expires_at',
|
||||
'payment_method',
|
||||
'additional_details',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'starts_at' => 'datetime',
|
||||
'expires_at' => 'datetime',
|
||||
'additional_details' => 'array',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function plan()
|
||||
{
|
||||
return $this->belongsTo(SubscriptionPlan::class, 'plan_id');
|
||||
}
|
||||
|
||||
public function invoices()
|
||||
{
|
||||
return $this->hasMany(SubscriptionInvoice::class, 'subscription_id');
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->status === 'active' && $this->expires_at && $this->expires_at->isFuture();
|
||||
}
|
||||
}
|
||||
45
app/Models/Subscription/SubscriptionInvoice.php
Normal file
45
app/Models/Subscription/SubscriptionInvoice.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Subscription;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class SubscriptionInvoice extends Model
|
||||
{
|
||||
protected ?string $table = 'subscription_invoices';
|
||||
|
||||
public bool $incrementing = true;
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'subscription_id',
|
||||
'user_id',
|
||||
'amount',
|
||||
'status',
|
||||
'paid_at',
|
||||
'payment_method',
|
||||
'payment_reference',
|
||||
'additional_details',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'amount' => 'float',
|
||||
'paid_at' => 'datetime',
|
||||
'additional_details' => 'array',
|
||||
];
|
||||
|
||||
public function subscription()
|
||||
{
|
||||
return $this->belongsTo(Subscription::class, 'subscription_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
}
|
||||
45
app/Models/Subscription/SubscriptionPlan.php
Normal file
45
app/Models/Subscription/SubscriptionPlan.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Subscription;
|
||||
|
||||
use Hyperf\DbConnection\Model\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class SubscriptionPlan extends Model
|
||||
{
|
||||
protected ?string $table = 'subscription_plans';
|
||||
|
||||
public bool $incrementing = true;
|
||||
|
||||
protected array $fillable = [
|
||||
'hashkey',
|
||||
'name',
|
||||
'description',
|
||||
'price',
|
||||
'duration_days',
|
||||
'expiry_action',
|
||||
'active',
|
||||
'additional_details',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'active' => 'boolean',
|
||||
'price' => 'float',
|
||||
'duration_days' => 'integer',
|
||||
'additional_details' => 'array',
|
||||
];
|
||||
|
||||
public function subscriptions()
|
||||
{
|
||||
return $this->hasMany(Subscription::class, 'plan_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by');
|
||||
}
|
||||
}
|
||||
161
app/Models/SystemSetting.php
Normal file
161
app/Models/SystemSetting.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Hypervel\Support\Facades\Cache;
|
||||
|
||||
class SystemSetting extends Model
|
||||
{
|
||||
protected array $fillable = [
|
||||
'key',
|
||||
'value',
|
||||
'type',
|
||||
'options',
|
||||
'group',
|
||||
'label',
|
||||
'description',
|
||||
'hashkey',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'is_active',
|
||||
];
|
||||
|
||||
/**
|
||||
* Cache key for settings.
|
||||
*/
|
||||
protected static string $cacheKey = 'app_system_settings';
|
||||
|
||||
/**
|
||||
* Get a setting value by key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getValue(string $key, $default = null)
|
||||
{
|
||||
$settings = static::getAllFromCache();
|
||||
|
||||
/** @var self|null $setting */
|
||||
$setting = $settings->where('key', $key)->first();
|
||||
|
||||
if ($setting === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return static::parseValue($setting->value, $setting->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a setting value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return static
|
||||
*/
|
||||
public static function setValue(string $key, $value, $group = 'general', $type = null)
|
||||
{
|
||||
/** @var self|null $setting */
|
||||
$setting = static::where('key', $key)->first();
|
||||
|
||||
// Auto-detect JSON if it's an array or a JSON string
|
||||
if ($type === null) {
|
||||
if (is_bool($value)) {
|
||||
$type = 'boolean';
|
||||
} elseif (is_array($value)) {
|
||||
$type = 'json';
|
||||
$value = json_encode($value);
|
||||
} elseif (is_string($value) && (strpos($value, '[') === 0 || strpos($value, '{') === 0)) {
|
||||
$decoded = json_decode($value);
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
$type = 'json';
|
||||
}
|
||||
}
|
||||
} elseif ($type === 'json' && is_array($value)) {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
|
||||
if ($setting) {
|
||||
$data = ['value' => is_bool($value) ? ($value ? 'true' : 'false') : (string) $value];
|
||||
if ($type !== null) $data['type'] = $type;
|
||||
$setting->update($data);
|
||||
} else {
|
||||
$setting = static::create([
|
||||
'key' => $key,
|
||||
'value' => is_bool($value) ? ($value ? 'true' : 'false') : (string) $value,
|
||||
'group' => $group,
|
||||
'type' => $type ?? 'text'
|
||||
]);
|
||||
}
|
||||
|
||||
static::clearCache();
|
||||
|
||||
return $setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all settings in a group.
|
||||
*
|
||||
* @param string $group
|
||||
* @return \Hypervel\Support\Collection
|
||||
*/
|
||||
public static function getGroup(string $group)
|
||||
{
|
||||
return static::getAllFromCache()->where('group', $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the settings cache.
|
||||
*/
|
||||
public static function clearCache()
|
||||
{
|
||||
if (class_exists(\Hypervel\Support\Facades\Cache::class)) {
|
||||
\Hypervel\Support\Facades\Cache::forget(static::$cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all settings from cache or database.
|
||||
*
|
||||
* @return \Hypervel\Support\Collection|\Hyperf\Database\Model\Collection
|
||||
*/
|
||||
protected static function getAllFromCache()
|
||||
{
|
||||
if (class_exists(\Hypervel\Support\Facades\Cache::class)) {
|
||||
return \Hypervel\Support\Facades\Cache::rememberForever(static::$cacheKey, function () {
|
||||
return static::all();
|
||||
});
|
||||
}
|
||||
return static::all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse value based on type.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string|null $type
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function parseValue($value, ?string $type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'boolean':
|
||||
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
||||
case 'number':
|
||||
return is_numeric($value) ? (float) $value : $value;
|
||||
case 'json':
|
||||
return is_string($value) ? json_decode($value, true) : $value;
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for parsed value.
|
||||
*/
|
||||
public function getParsedValueAttribute()
|
||||
{
|
||||
return static::parseValue($this->value, $this->type);
|
||||
}
|
||||
}
|
||||
192
app/Models/User.php
Normal file
192
app/Models/User.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\UserActions;
|
||||
use App\Enums\UserTypes;
|
||||
use App\Models\PersonalAccessToken;
|
||||
use App\Support\HasApiTokens;
|
||||
use Hypervel\Foundation\Auth\User as Authenticatable;
|
||||
|
||||
use Hypervel\Support\Collection;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens;
|
||||
|
||||
public ?PersonalAccessToken $accessToken = null;
|
||||
|
||||
protected ?string $table = 'users';
|
||||
|
||||
public bool $incrementing = true;
|
||||
protected array $attributes = [
|
||||
'active' => true,
|
||||
];
|
||||
|
||||
|
||||
protected array $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
// add anything else you don’t want exposed
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected array $fillable = [
|
||||
'name',
|
||||
'fullname',
|
||||
'hashkey',
|
||||
'mobile_number',
|
||||
'landline',
|
||||
'nickname',
|
||||
'username',
|
||||
'email',
|
||||
'email_verified_at',
|
||||
'mobile_verified_at',
|
||||
'password',
|
||||
'acct_type',
|
||||
'total_balance',
|
||||
'total_credit',
|
||||
'created_by',
|
||||
'updated_by',
|
||||
'active',
|
||||
'parentuid',
|
||||
'targetuids',
|
||||
'notes',
|
||||
'exec_command',
|
||||
'settings',
|
||||
'multiple_logins',
|
||||
'referralcode',
|
||||
'photourl',
|
||||
'logs',
|
||||
'cart',
|
||||
'details',
|
||||
'additional_roles',
|
||||
'denied_roles',
|
||||
];
|
||||
|
||||
protected array $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'mobile_verified_at' => 'datetime',
|
||||
'targetuids' => 'array',
|
||||
'settings' => 'array',
|
||||
'photourl' => 'array',
|
||||
'logs' => 'array',
|
||||
'cart' => 'array',
|
||||
'multiple_logins' => 'boolean',
|
||||
'active' => 'boolean',
|
||||
'details' => 'array',
|
||||
'acct_type' => UserTypes::class ,
|
||||
'additional_roles' => \App\Casts\UserActionsArrayCast::class ,
|
||||
'denied_roles' => \App\Casts\UserActionsArrayCast::class ,
|
||||
];
|
||||
|
||||
public function userInfo()
|
||||
{
|
||||
return $this->hasOne(\App\Models\Market\UserInfo::class, 'user_id');
|
||||
}
|
||||
|
||||
public function cooperativeMemberships()
|
||||
{
|
||||
return $this->hasMany(\App\Models\Market\CooperativeMember::class, 'user_id');
|
||||
}
|
||||
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(User::class , 'created_by');
|
||||
}
|
||||
|
||||
|
||||
public function updater()
|
||||
{
|
||||
return $this->belongsTo(User::class , 'updated_by');
|
||||
}
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(User::class , 'parentuid');
|
||||
}
|
||||
|
||||
public function getAllDescendants(): Collection
|
||||
{
|
||||
$descendants = collect();
|
||||
|
||||
$children = self::where('parentuid', $this->id)->get();
|
||||
|
||||
foreach ($children as $child) {
|
||||
$descendants->push($child);
|
||||
|
||||
// Recursively get each child's descendants
|
||||
$descendants = $descendants->merge($child->getAllDescendants());
|
||||
}
|
||||
return $descendants;
|
||||
}
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(User::class , 'parentuid');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has a specific role.
|
||||
*/
|
||||
public function hasRole(UserTypes|string|array $role): bool
|
||||
{
|
||||
if (is_array($role)) {
|
||||
foreach ($role as $r) {
|
||||
if ($this->hasRole($r)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$roleValue = $role instanceof UserTypes ? $role->value : $role;
|
||||
return $this->acct_type->value === $roleValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience methods for common roles.
|
||||
*/
|
||||
public function isUltimate(): bool
|
||||
{
|
||||
return $this->acct_type === UserTypes::ULTIMATE;
|
||||
}
|
||||
|
||||
public function isSuperOperator(): bool
|
||||
{
|
||||
return $this->acct_type === UserTypes::SUPER_OPERATOR;
|
||||
}
|
||||
|
||||
public function isOperator(): bool
|
||||
{
|
||||
return $this->acct_type === UserTypes::OPERATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cooperatives from settings.
|
||||
*/
|
||||
public function getCooperativesAttribute(): array
|
||||
{
|
||||
return $this->settings['cooperatives'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has joined a specific cooperative via settings.
|
||||
*/
|
||||
public function hasJoinedCooperative(string $cooperativeHash): bool
|
||||
{
|
||||
return in_array($cooperativeHash, $this->cooperatives);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has a specific permission (action).
|
||||
*/
|
||||
public function canDo(\App\Enums\UserActions $action, string|int|UserTypes $target = null): bool
|
||||
{
|
||||
return \App\Http\Controllers\Helpers\Permissions\UserPermissions::isActionPermitted($target ?? $this->acct_type, $action);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user