Browse Source
- Introduced Billing-specific models (Invoice, Product, Discount) and DTOs for catalog, discount, and invoicing functionalities. - Implemented runtime relationships using RelationshipServiceProvider. - Refactored `DataPayloadMapper` to `DataPayloadMapper` under `Contract` for improved consistency. - Added `AcademicProductGenerator` for dynamic product identifiers. - Streamlined API registry and mapper dependencies across domains. - Enhanced `AdmissionFeeRateWasSetUp` event to dispatch enriched product data.master
68 changed files with 847 additions and 272 deletions
@ -0,0 +1,60 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Academic\Support\Generator; |
||||
|
|
||||
|
use App\Domains\Admission\Models\FeeRate; |
||||
|
use App\Domains\Billing\DTOs\Products\ProductIdentifierDTO; |
||||
|
use App\Domains\Billing\Support\Contract\ProductIdentifierGenerator; |
||||
|
|
||||
|
class AcademicProductGenerator implements ProductIdentifierGenerator |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @param object $source |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function supports(object $source): bool |
||||
|
{ |
||||
|
return $source instanceof FeeRate; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param object $source |
||||
|
* @return ProductIdentifierDTO |
||||
|
*/ |
||||
|
public function generate(object $source): ProductIdentifierDTO |
||||
|
{ |
||||
|
/** @var FeeRate $rate */ |
||||
|
$rate = $source; |
||||
|
|
||||
|
$rate->loadMissing([ |
||||
|
'admissionSchedule.admissionTrack', |
||||
|
'admissionSchedule.term', |
||||
|
'academicProgram', |
||||
|
'feeType', |
||||
|
]); |
||||
|
|
||||
|
$code = sprintf( |
||||
|
'%s-%s-%s-%s', |
||||
|
str($rate->admissionSchedule->admissionTrack->name)->initials(), |
||||
|
'AC'.$rate->academicProgram->code, |
||||
|
'FT'.$rate->feeType->code, |
||||
|
$rate->admissionSchedule->term->year_study |
||||
|
); |
||||
|
|
||||
|
$name = sprintf( |
||||
|
'%s %s %s %s', |
||||
|
$rate->admissionSchedule->admissionTrack->name, |
||||
|
$rate->academicProgram->name, |
||||
|
$rate->feeType->name, |
||||
|
$rate->admissionSchedule->term->year_study |
||||
|
); |
||||
|
|
||||
|
return new ProductIdentifierDTO( |
||||
|
code: $code, |
||||
|
name: $name, |
||||
|
feeRateType: $rate->getMorphClass(), |
||||
|
feeRateId: $rate->id |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Actions\Catalog; |
||||
|
|
||||
|
class ProvisionProductFromFeeRate |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Actions\Discounts; |
||||
|
|
||||
|
class DefineDiscount |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Actions\Invoicing; |
||||
|
|
||||
|
class DraftInvoice |
||||
|
{ |
||||
|
public function execute(): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\DTOs\Catalog; |
||||
|
|
||||
|
readonly class ProvisionProductDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $code, |
||||
|
public string $pricingType, |
||||
|
public string $pricingId, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\DTOs\Discounts; |
||||
|
|
||||
|
readonly class DefineDiscountDTO |
||||
|
{ |
||||
|
/** |
||||
|
* @param string $name |
||||
|
* @param string $type |
||||
|
* @param string $value |
||||
|
* @param array<int, array{context: string, condition_type: string, operator: string, value: string}> $rules |
||||
|
*/ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $type, |
||||
|
public string $value, |
||||
|
public array $rules, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\DTOs\Invoicing; |
||||
|
|
||||
|
readonly class DraftInvoiceDTO |
||||
|
{ |
||||
|
public function __construct( |
||||
|
public string $name, |
||||
|
public string $clientId, |
||||
|
public string $clientRefId, |
||||
|
public array $items, |
||||
|
public array $metadata, |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\DTOs\Products; |
||||
|
|
||||
|
/** |
||||
|
* Readonly Data Transfer Object containing generated product credentials. |
||||
|
*/ |
||||
|
readonly class ProductIdentifierDTO |
||||
|
{ |
||||
|
/** |
||||
|
* Construct the identifier result instance. |
||||
|
* |
||||
|
* @param string $code Short deterministic business code (e.g. PMDK-UKT-PRK-SI-25G). |
||||
|
* @param string $name Full descriptive name for UI and invoice documents. |
||||
|
* @param string $feeRateType relation map |
||||
|
* @param string|int $feeRateId relation identifier to fee rate |
||||
|
*/ |
||||
|
public function __construct( |
||||
|
public string $code, |
||||
|
public string $name, |
||||
|
public string $feeRateType, |
||||
|
public string|int $feeRateId |
||||
|
) {} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Enums\Catalog; |
||||
|
|
||||
|
enum AccountBalance: string |
||||
|
{ |
||||
|
case CREDIT = 'credit'; |
||||
|
case DEBIT = 'debit'; |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Enums\Catalog; |
||||
|
|
||||
|
enum AccountClassification: string |
||||
|
{ |
||||
|
case LIABILITY = 'liability'; |
||||
|
case ASSET = 'asset'; |
||||
|
case EQUITY = 'equity'; |
||||
|
case REVENUE = 'revenue'; |
||||
|
case EXPENSE = 'expense'; |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Enums\Discounts; |
||||
|
|
||||
|
enum DiscountOperator: string |
||||
|
{ |
||||
|
case GREATER = '>'; |
||||
|
case GREATER_OR_EQUAL = '>='; |
||||
|
case LESS = '<'; |
||||
|
case LESS_OR_EQUAL = '<='; |
||||
|
case EQUAL = '='; |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Enums\Discounts; |
||||
|
|
||||
|
enum DiscountType: string |
||||
|
{ |
||||
|
case PERCENTAGE = 'percentage'; |
||||
|
case FIXED = 'fixed'; |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Enums\Invoicing; |
||||
|
|
||||
|
enum InvoiceStatus: string |
||||
|
{ |
||||
|
case PENDING = 'pending'; |
||||
|
case PARTIALLY_PAID = 'partially_paid'; |
||||
|
case PAID = 'paid'; |
||||
|
case VOID = 'void'; |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Enums\Invoicing; |
||||
|
|
||||
|
enum InvoiceType: string |
||||
|
{ |
||||
|
case STUDENT_INVOICE = 'student_invoice'; |
||||
|
case VENDOR_BILL = 'vendor_bill'; |
||||
|
case CREDIT_NOTE = 'credit_note'; |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Models; |
||||
|
|
||||
|
use Database\Factories\Billing\ChartOfAccountFactory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UseFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'code', |
||||
|
'name', |
||||
|
'classification', |
||||
|
'normal_balance' |
||||
|
])] |
||||
|
#[UseFactory(ChartOfAccountFactory::class)] |
||||
|
class ChartOfAccount extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Models; |
||||
|
|
||||
|
use Database\Factories\Billing\DiscountFactory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UseFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'name', |
||||
|
'type', |
||||
|
'value', |
||||
|
'rules', |
||||
|
'is_active', |
||||
|
'chart_of_account_id' |
||||
|
])] |
||||
|
#[UseFactory(DiscountFactory::class)] |
||||
|
class Discount extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
|
||||
|
public function chartOfAccount(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(ChartOfAccount::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Models; |
||||
|
|
||||
|
use Database\Factories\Billing\DiscountSnapshotFactory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UseFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'name', |
||||
|
'type', |
||||
|
'value', |
||||
|
'amount', |
||||
|
'chart_of_account_id', |
||||
|
'discount_id', |
||||
|
'invoice_id', |
||||
|
'invoice_item_id' |
||||
|
])] |
||||
|
#[UseFactory(DiscountSnapshotFactory::class)] |
||||
|
class DiscountSnapshot extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
|
||||
|
public function chartOfAccount(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(ChartOfAccount::class); |
||||
|
} |
||||
|
|
||||
|
public function discount(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(Discount::class); |
||||
|
} |
||||
|
|
||||
|
public function invoice(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(Invoice::class); |
||||
|
} |
||||
|
|
||||
|
public function invoiceItem(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(InvoiceItem::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Models; |
||||
|
|
||||
|
use Database\Factories\Billing\InvoiceFactory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UseFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'code', |
||||
|
'name', |
||||
|
'client_detail', |
||||
|
'client_ref_id', |
||||
|
'type', |
||||
|
'gross_amount', |
||||
|
'discount_amount', |
||||
|
'net_amount', |
||||
|
'status', |
||||
|
'client_id' |
||||
|
])] |
||||
|
#[UseFactory(InvoiceFactory::class)] |
||||
|
class Invoice extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Models; |
||||
|
|
||||
|
use Database\Factories\Billing\InvoiceItemFactory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UseFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'code', |
||||
|
'name', |
||||
|
'quantity', |
||||
|
'unit_price', |
||||
|
'gross_amount', |
||||
|
'discount_amount', |
||||
|
'net_amount', |
||||
|
'invoice_id', |
||||
|
'product_id', |
||||
|
'chart_of_account_id' |
||||
|
])] |
||||
|
#[UseFactory(InvoiceItemFactory::class)] |
||||
|
class InvoiceItem extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
|
||||
|
public function product(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(Product::class); |
||||
|
} |
||||
|
|
||||
|
public function chartOfAccount(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(ChartOfAccount::class); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Models; |
||||
|
|
||||
|
use Database\Factories\Billing\ProductFactory; |
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Attributes\Fillable; |
||||
|
use Illuminate\Database\Eloquent\Attributes\UseFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||
|
use Illuminate\Database\Eloquent\Relations\MorphTo; |
||||
|
|
||||
|
#[Fillable([ |
||||
|
'code', |
||||
|
'name', |
||||
|
'chart_of_account_id' |
||||
|
])] |
||||
|
#[UseFactory(ProductFactory::class)] |
||||
|
class Product extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
|
||||
|
public function chartOfAccount(): BelongsTo |
||||
|
{ |
||||
|
return $this->belongsTo(ChartOfAccount::class); |
||||
|
} |
||||
|
|
||||
|
public function pricing(): MorphTo |
||||
|
{ |
||||
|
return $this->morphTo(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Providers; |
||||
|
|
||||
|
use App\Domains\System\Traits\Provider\RegistersDomainEvents; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class BillingServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
use RegistersDomainEvents; |
||||
|
|
||||
|
protected array $listen = []; |
||||
|
|
||||
|
public function register(): void |
||||
|
{ |
||||
|
$this->app->register(RelationshipServiceProvider::class); |
||||
|
} |
||||
|
|
||||
|
public function boot(): void |
||||
|
{ |
||||
|
$this->registerEvents(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Providers; |
||||
|
|
||||
|
use App\Domains\Billing\Models\Invoice; |
||||
|
use App\Domains\Channel\Models\Client; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
|
||||
|
class RelationshipServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
/** |
||||
|
* Boot cross-domain runtime relationships. |
||||
|
* |
||||
|
* This provider is strictly dedicated to runtime, decoupled cross-domain |
||||
|
* relationship definitions. Use Model::resolveRelationUsing() here to wire |
||||
|
* explicit polymorphic or foreign-key macros between models that live in |
||||
|
* different domains — without introducing a hard compile-time dependency |
||||
|
* between those domains. |
||||
|
* |
||||
|
* Do NOT add route registrations, bindings, event listeners, or any other |
||||
|
* bootstrapping logic here. Keep this file focused on relationships only. |
||||
|
* |
||||
|
* Example: |
||||
|
* |
||||
|
* Order::resolveRelationUsing('customer', fn (Order $order) => |
||||
|
* $order->belongsTo(Customer::class, 'customer_id') |
||||
|
* ); |
||||
|
*/ |
||||
|
public function boot(): void |
||||
|
{ |
||||
|
Invoice::resolveRelationUsing('client', function (Invoice $invoice) { |
||||
|
return $invoice->belongsTo(Client::class, 'client_id'); |
||||
|
}); |
||||
|
Client::resolveRelationUsing('invoices', function (Client $client) { |
||||
|
return $client->hasMany(Invoice::class, 'client_id'); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Billing\Support\Contract; |
||||
|
|
||||
|
use App\Domains\Billing\DTOs\Products\ProductIdentifierDTO; |
||||
|
|
||||
|
/** |
||||
|
* Contract interface for generating product codes and display names. |
||||
|
*/ |
||||
|
interface ProductIdentifierGenerator |
||||
|
{ |
||||
|
/** |
||||
|
* Determine if this generator supports the given pricing source entity. |
||||
|
* |
||||
|
* @param object $source The pricing source model instance (e.g., FeeRate, RentalRate). |
||||
|
* @return bool True if supported, false otherwise. |
||||
|
*/ |
||||
|
public function supports(object $source): bool; |
||||
|
|
||||
|
/** |
||||
|
* Generate product code and descriptive name from a pricing source entity. |
||||
|
* |
||||
|
* @param object $source The pricing source model containing context attributes. |
||||
|
* @return ProductIdentifierDTO Typed DTO holding generated code and name. |
||||
|
*/ |
||||
|
public function generate(object $source): ProductIdentifierDTO; |
||||
|
} |
||||
@ -1,9 +1,9 @@ |
|||||
<?php |
<?php |
||||
|
|
||||
namespace App\Domains\Channel\Support\Mapper; |
namespace App\Domains\Channel\Support\Registry; |
||||
|
|
||||
use App\Domains\Channel\Enums\Api\ApiType; |
use App\Domains\Channel\Enums\Api\ApiType; |
||||
use App\Domains\System\Support\Integration\DataPayloadMapper; |
use App\Domains\System\Support\Contract\DataPayloadMapper; |
||||
use InvalidArgumentException; |
use InvalidArgumentException; |
||||
|
|
||||
class ApiMapperRegistry |
class ApiMapperRegistry |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Domains\Payment\Listeners\VirtualAccount; |
||||
|
|
||||
|
class InitializeVirtualAccountForPublishedInvoice |
||||
|
{ |
||||
|
public function handle(object $event): void |
||||
|
{ |
||||
|
// |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,6 @@ |
|||||
<?php |
<?php |
||||
|
|
||||
namespace App\Domains\System\Support\Integration; |
namespace App\Domains\System\Support\Contract; |
||||
|
|
||||
use Illuminate\Database\Eloquent\Model; |
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Database\Factories\Billing; |
||||
|
|
||||
|
use App\Domains\Billing\Models\Discount; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
|
||||
|
/** |
||||
|
* @extends Factory<Discount> |
||||
|
*/ |
||||
|
class DiscountFactory extends Factory |
||||
|
{ |
||||
|
protected $model = Discount::class; |
||||
|
|
||||
|
public function definition(): array |
||||
|
{ |
||||
|
return []; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Database\Factories\Billing; |
||||
|
|
||||
|
use App\Domains\Billing\Models\DiscountRules; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
|
||||
|
/** |
||||
|
* @extends Factory<DiscountRules> |
||||
|
*/ |
||||
|
class DiscountRulesFactory extends Factory |
||||
|
{ |
||||
|
protected $model = DiscountRules::class; |
||||
|
|
||||
|
public function definition(): array |
||||
|
{ |
||||
|
return []; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Database\Factories\Billing; |
||||
|
|
||||
|
use App\Domains\Billing\Models\DiscountSnapshot; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
|
||||
|
/** |
||||
|
* @extends Factory<DiscountSnapshot> |
||||
|
*/ |
||||
|
class DiscountSnapshotFactory extends Factory |
||||
|
{ |
||||
|
protected $model = DiscountSnapshot::class; |
||||
|
|
||||
|
public function definition(): array |
||||
|
{ |
||||
|
return []; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Database\Factories\Billing; |
||||
|
|
||||
|
use App\Domains\Billing\Models\InvoiceItem; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
|
||||
|
/** |
||||
|
* @extends Factory<InvoiceItem> |
||||
|
*/ |
||||
|
class InvoiceItemFactory extends Factory |
||||
|
{ |
||||
|
protected $model = InvoiceItem::class; |
||||
|
|
||||
|
public function definition(): array |
||||
|
{ |
||||
|
return []; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Database\Factories\Billing; |
||||
|
|
||||
|
use App\Domains\Billing\Models\Product; |
||||
|
use Illuminate\Database\Eloquent\Factories\Factory; |
||||
|
|
||||
|
/** |
||||
|
* @extends Factory<Product> |
||||
|
*/ |
||||
|
class ProductFactory extends Factory |
||||
|
{ |
||||
|
protected $model = Product::class; |
||||
|
|
||||
|
public function definition(): array |
||||
|
{ |
||||
|
return []; |
||||
|
} |
||||
|
} |
||||
@ -1,19 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Database\Factories\Finance; |
|
||||
|
|
||||
use App\Domains\Finance\Models\Payment; |
|
||||
use Illuminate\Database\Eloquent\Factories\Factory; |
|
||||
|
|
||||
/** |
|
||||
* @extends Factory<Payment> |
|
||||
*/ |
|
||||
class PaymentFactory extends Factory |
|
||||
{ |
|
||||
protected $model = Payment::class; |
|
||||
|
|
||||
public function definition(): array |
|
||||
{ |
|
||||
return []; |
|
||||
} |
|
||||
} |
|
||||
@ -1,19 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Database\Factories\System; |
|
||||
|
|
||||
use App\Domains\System\Models\File; |
|
||||
use Illuminate\Database\Eloquent\Factories\Factory; |
|
||||
|
|
||||
/** |
|
||||
* @extends Factory<File> |
|
||||
*/ |
|
||||
class FileFactory extends Factory |
|
||||
{ |
|
||||
protected $model = File::class; |
|
||||
|
|
||||
public function definition(): array |
|
||||
{ |
|
||||
return []; |
|
||||
} |
|
||||
} |
|
||||
@ -1,35 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
use Illuminate\Database\Migrations\Migration; |
|
||||
use Illuminate\Database\Schema\Blueprint; |
|
||||
use Illuminate\Support\Facades\Schema; |
|
||||
|
|
||||
return new class extends Migration |
|
||||
{ |
|
||||
/** |
|
||||
* Run the migrations. |
|
||||
*/ |
|
||||
public function up(): void |
|
||||
{ |
|
||||
Schema::create('payments', function (Blueprint $table) { |
|
||||
$table->id(); |
|
||||
$table->ulid(); |
|
||||
$table->integer('virtual_account'); |
|
||||
$table->string('bank_ref_id'); |
|
||||
$table->string('bank'); |
|
||||
$table->string('nominal'); |
|
||||
$table->date('valid_until'); |
|
||||
$table->string('status'); |
|
||||
$table->foreignId('invoice_id')->constrained()->restrictOnDelete(); |
|
||||
$table->timestamps(); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Reverse the migrations. |
|
||||
*/ |
|
||||
public function down(): void |
|
||||
{ |
|
||||
Schema::dropIfExists('payments'); |
|
||||
} |
|
||||
}; |
|
||||
@ -1,43 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
use Illuminate\Database\Migrations\Migration; |
|
||||
use Illuminate\Database\Schema\Blueprint; |
|
||||
use Illuminate\Support\Facades\Schema; |
|
||||
|
|
||||
return new class extends Migration |
|
||||
{ |
|
||||
/** |
|
||||
* Run the migrations. |
|
||||
*/ |
|
||||
public function up(): void |
|
||||
{ |
|
||||
Schema::create('student_invoice_reports', function (Blueprint $table) { |
|
||||
$table->id(); |
|
||||
$table->foreignId('invoice_id') |
|
||||
->constrained('invoices') |
|
||||
->restrictOnDelete(); |
|
||||
$table->string('invoice_name'); |
|
||||
$table->string('student_name'); |
|
||||
$table->string('faculty_id'); |
|
||||
$table->string('faculty_name'); |
|
||||
$table->string('study_program_id'); |
|
||||
$table->string('study_program_name'); |
|
||||
$table->string('term_id'); |
|
||||
$table->string('term_name'); |
|
||||
$table->integer('amount'); |
|
||||
$table->integer('paid_amount'); |
|
||||
$table->dateTime('issued_at'); |
|
||||
$table->dateTime('paid_at'); |
|
||||
$table->string('status'); |
|
||||
$table->timestamps(); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Reverse the migrations. |
|
||||
*/ |
|
||||
public function down(): void |
|
||||
{ |
|
||||
Schema::dropIfExists('student_invoice_reports'); |
|
||||
} |
|
||||
}; |
|
||||
@ -1,38 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
use Illuminate\Database\Migrations\Migration; |
|
||||
use Illuminate\Database\Schema\Blueprint; |
|
||||
use Illuminate\Support\Facades\Schema; |
|
||||
|
|
||||
return new class extends Migration |
|
||||
{ |
|
||||
/** |
|
||||
* Run the migrations. |
|
||||
*/ |
|
||||
public function up(): void |
|
||||
{ |
|
||||
Schema::create('invoice_reports', function (Blueprint $table) { |
|
||||
$table->id(); |
|
||||
$table->foreignId('invoice_id') |
|
||||
->constrained('invoices') |
|
||||
->restrictOnDelete(); |
|
||||
$table->string('invoice_name'); |
|
||||
$table->string('customer_name'); |
|
||||
$table->string('customer_id'); |
|
||||
$table->integer('amount'); |
|
||||
$table->integer('paid_amount'); |
|
||||
$table->dateTime('issued_at'); |
|
||||
$table->dateTime('paid_at'); |
|
||||
$table->string('status'); |
|
||||
$table->timestamps(); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Reverse the migrations. |
|
||||
*/ |
|
||||
public function down(): void |
|
||||
{ |
|
||||
Schema::dropIfExists('invoice_reports'); |
|
||||
} |
|
||||
}; |
|
||||
@ -0,0 +1,31 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Database\Migrations\Migration; |
||||
|
use Illuminate\Database\Schema\Blueprint; |
||||
|
use Illuminate\Support\Facades\Schema; |
||||
|
|
||||
|
return new class extends Migration |
||||
|
{ |
||||
|
/** |
||||
|
* Run the migrations. |
||||
|
*/ |
||||
|
public function up(): void |
||||
|
{ |
||||
|
Schema::create('products', function (Blueprint $table) { |
||||
|
$table->id(); |
||||
|
$table->string('code')->unique(); |
||||
|
$table->string('name'); |
||||
|
$table->morphs('pricing'); |
||||
|
$table->foreignId('chart_of_account_id')->nullable(); |
||||
|
$table->timestamps(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
*/ |
||||
|
public function down(): void |
||||
|
{ |
||||
|
Schema::dropIfExists('products'); |
||||
|
} |
||||
|
}; |
||||
@ -0,0 +1,37 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Database\Migrations\Migration; |
||||
|
use Illuminate\Database\Schema\Blueprint; |
||||
|
use Illuminate\Support\Facades\Schema; |
||||
|
|
||||
|
return new class extends Migration |
||||
|
{ |
||||
|
/** |
||||
|
* Run the migrations. |
||||
|
*/ |
||||
|
public function up(): void |
||||
|
{ |
||||
|
Schema::create('invoice_items', function (Blueprint $table) { |
||||
|
$table->id(); |
||||
|
$table->string('code'); |
||||
|
$table->string('name'); |
||||
|
$table->integer('quantity'); |
||||
|
$table->integer('unit_price'); |
||||
|
$table->integer('gross_amount'); |
||||
|
$table->integer('discount_amount'); |
||||
|
$table->integer('net_amount'); |
||||
|
$table->foreignId('invoice_id')->constrained(); |
||||
|
$table->foreignId('product_id')->constrained(); |
||||
|
$table->foreignId('chart_of_account_id')->constrained(); |
||||
|
$table->timestamps(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
*/ |
||||
|
public function down(): void |
||||
|
{ |
||||
|
Schema::dropIfExists('invoice_items'); |
||||
|
} |
||||
|
}; |
||||
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Database\Migrations\Migration; |
||||
|
use Illuminate\Database\Schema\Blueprint; |
||||
|
use Illuminate\Support\Facades\Schema; |
||||
|
|
||||
|
return new class extends Migration |
||||
|
{ |
||||
|
/** |
||||
|
* Run the migrations. |
||||
|
*/ |
||||
|
public function up(): void |
||||
|
{ |
||||
|
Schema::create('discount_snapshots', function (Blueprint $table) { |
||||
|
$table->id(); |
||||
|
$table->string('name'); |
||||
|
$table->string('type'); |
||||
|
$table->integer('value'); |
||||
|
$table->integer('amount'); |
||||
|
$table->foreignId('chart_of_account_id')->constrained(); |
||||
|
$table->foreignId('discount_id')->constrained(); |
||||
|
$table->foreignId('invoice_id')->constrained(); |
||||
|
$table->foreignId('invoice_item_id')->nullable()->constrained()->nullOnDelete(); |
||||
|
$table->timestamps(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
*/ |
||||
|
public function down(): void |
||||
|
{ |
||||
|
Schema::dropIfExists('discount_snapshots'); |
||||
|
} |
||||
|
}; |
||||
@ -1,3 +1,5 @@ |
|||||
@props(['id' => md5(microtime(true))]) |
@props(['id' => 'accordion-' . md5(microtime(true))]) |
||||
|
|
||||
<div class="accordion" id="{{ $id }}">{{ $slot }}</div> |
<div {{ $attributes->merge(['class' => 'accordion accordion-flush d-flex flex-column', 'id' => $id]) }} wire:ignore.self> |
||||
|
{{ $slot }} |
||||
|
</div> |
||||
|
|||||
Loading…
Reference in new issue