diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 65944ab..e28795a 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -57,21 +57,6 @@ "permission": { "permission": 2, "type": null, "element": null }, "parent": 1008301001, "children": [] - }, - { - "id": 1008305001, - "pid": "/finance/loan", - "type": 3, - "subtype": 1, - "name": "Entries", - "uri": "{/base}/finance/loan/entry/list?{?}", - "target": "self", - "icon": null, - "order": 15, - "from": "LoanManagement", - "permission": { "permission": 2, "type": null, "element": null }, - "parent": 1008301001, - "children": [] } ] } diff --git a/Admin/Install/costtypes.json b/Admin/Install/costtypes.json index b8ec469..0aefbca 100755 --- a/Admin/Install/costtypes.json +++ b/Admin/Install/costtypes.json @@ -1,6 +1,17 @@ [ + { + "name": "loan", + "sign": 1, + "isLoan": true, + "l11n": { + "en": "Loan", + "de": "Darlehen" + } + }, { "name": "disagio", + "sign": -1, + "isLoan": true, "l11n": { "en": "Disagio", "de": "Disagio" @@ -8,6 +19,7 @@ }, { "name": "interest", + "sign": -1, "l11n": { "en": "Interest", "de": "Zinsen" @@ -15,6 +27,8 @@ }, { "name": "repayment", + "sign": -1, + "isLoan": true, "l11n": { "en": "Repayment", "de": "Tilgung" @@ -22,6 +36,8 @@ }, { "name": "unscheduled_repayment", + "sign": -1, + "isLoan": true, "l11n": { "en": "Unscheduled repayment", "de": "Sondertilgung" @@ -29,6 +45,7 @@ }, { "name": "commitment_fee", + "sign": -1, "l11n": { "en": "Commitment fee", "de": "Bereitstellungsgebühr" @@ -36,6 +53,7 @@ }, { "name": "taxes", + "sign": -1, "l11n": { "en": "Taxes", "de": "Steuern" @@ -43,6 +61,7 @@ }, { "name": "other", + "sign": -1, "l11n": { "en": "Others", "de": "Sonstige" diff --git a/Admin/Install/db.json b/Admin/Install/db.json index ffd11ea..f68f988 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -14,6 +14,16 @@ "type": "VARCHAR(255)", "null": false, "unique": true + }, + "loanmgmt_cost_type_sign": { + "name": "loanmgmt_cost_type_sign", + "type": "TINYINT(1)", + "null": false + }, + "loanmgmt_cost_type_loan": { + "name": "loanmgmt_cost_type_loan", + "type": "TINYINT(1)", + "null": false } } }, @@ -59,13 +69,8 @@ "primary": true, "autoincrement": true }, - "loanmgmt_loan_start": { - "name": "loanmgmt_loan_start", - "type": "DATETIME", - "null": true - }, - "loanmgmt_loan_title": { - "name": "loanmgmt_loan_title", + "loanmgmt_loan_name": { + "name": "loanmgmt_loan_name", "type": "VARCHAR(255)", "null": false }, @@ -74,58 +79,47 @@ "type": "TEXT", "null": false }, - "loanmgmt_loan_payout_date": { - "name": "loanmgmt_loan_payout_date", + "loanmgmt_loan_status": { + "name": "loanmgmt_loan_status", + "type": "INT", + "null": false + }, + "loanmgmt_loan_borrowing_rate": { + "name": "loanmgmt_loan_borrowing_rate", + "type": "INT", + "null": false + }, + "loanmgmt_loan_post_rate": { + "name": "loanmgmt_loan_post_rate", + "type": "INT", + "null": false + }, + "loanmgmt_loan_special_payment": { + "name": "loanmgmt_loan_special_payment", + "type": "INT", + "null": false + }, + "loanmgmt_loan_supplier": { + "name": "loanmgmt_loan_supplier", + "type": "INT", + "null": false, + "foreignTable": "suppliermgmt_supplier", + "foreignKey": "suppliermgmt_supplier_id" + }, + "loanmgmt_loan_start": { + "name": "loanmgmt_loan_start", "type": "DATETIME", "null": true }, - "loanmgmt_loan_amount": { - "name": "loanmgmt_loan_amount", - "type": "BIGINT", - "null": false - }, - "loanmgmt_loan_disagio": { - "name": "loanmgmt_loan_disagio", - "type": "BIGINT", - "null": false - }, - "loanmgmt_loan_provision": { - "description": "Bereitstellungsgebuehr", - "name": "loanmgmt_loan_provision", - "type": "BIGINT", - "null": false - }, - "loanmgmt_loan_provision_rate": { - "description": "Bereitstellungsgebuehr", - "name": "loanmgmt_loan_provision_rate", - "type": "BIGINT", - "null": false - }, - "loanmgmt_loan_interest_start": { - "name": "loanmgmt_loan_interest_start", + "loanmgmt_loan_end": { + "name": "loanmgmt_loan_end", "type": "DATETIME", "null": true }, - "loanmgmt_loan_interest_rate": { - "name": "loanmgmt_loan_interest_rate", - "type": "INT", - "null": false - }, - "loanmgmt_loan_interest_rate_post": { - "description": "Interest rate after binding period", - "name": "loanmgmt_loan_interest_rate_post", - "type": "INT", - "null": false - }, - "loanmgmt_loan_rate_binding": { - "name": "loanmgmt_loan_rate_binding", - "type": "INT", - "null": false - }, - "loanmgmt_loan_repayment_type": { - "name": "loanmgmt_loan_repayment_type", - "type": "TINYINT", - "null": false + "loanmgmt_loan_created_at": { + "name": "loanmgmt_loan_created_at", + "type": "DATETIME", + "null": true }, "loanmgmt_loan_created_by": { "name": "loanmgmt_loan_created_by", @@ -143,5 +137,48 @@ "foreignKey": "unit_id" } } + }, + "loanmgmt_loan_element": { + "name": "loanmgmt_loan_element", + "fields": { + "loanmgmt_loan_element_id": { + "name": "loanmgmt_loan_element_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "loanmgmt_loan_description": { + "name": "loanmgmt_loan_description", + "type": "TEXT", + "null": false + }, + "loanmgmt_loan_element_amount": { + "name": "loanmgmt_loan_element_amount", + "type": "BIGINT", + "null": false + }, + "loanmgmt_loan_element_date": { + "name": "loanmgmt_loan_element_date", + "type": "DATETIME", + "null": true + }, + "loanmgmt_loan_element_type": { + "name": "loanmgmt_loan_element_type", + "type": "INT", + "default": null, + "null": true, + "foreignTable": "loanmgmt_cost_type", + "foreignKey": "loanmgmt_cost_type_id" + }, + "loanmgmt_loan_element_loan": { + "name": "loanmgmt_loan_element_loan", + "type": "INT", + "default": null, + "null": true, + "foreignTable": "loanmgmt_loan", + "foreignKey": "loanmgmt_loan_id" + } + } } } \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php index 5be743e..3c4a51a 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -83,6 +83,8 @@ final class Installer extends InstallerAbstract $request->header->account = 1; $request->setData('name', $type['name'] ?? ''); $request->setData('title', \reset($type['l11n'])); + $request->setData('sign', $type['sign'] ?? -1); + $request->setData('is_loan', $type['isLoan'] ?? false); $module->apiLoanCostTypeCreate($request, $response); diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index cf9daf9..22281bf 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -10,6 +10,7 @@ return [ [ 'dest' => '\Modules\LoanManagement\Controller\BackendController:viewLoanList', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::MODULE_NAME, 'type' => PermissionType::READ, @@ -21,6 +22,7 @@ return [ [ 'dest' => '\Modules\LoanManagement\Controller\BackendController:viewLoanView', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::MODULE_NAME, 'type' => PermissionType::READ, @@ -32,6 +34,7 @@ return [ [ 'dest' => '\Modules\LoanManagement\Controller\BackendController:viewLoanCreate', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::MODULE_NAME, 'type' => PermissionType::CREATE, @@ -43,28 +46,7 @@ return [ [ 'dest' => '\Modules\LoanManagement\Controller\BackendController:viewLoanTable', 'verb' => RouteVerb::GET, - 'permission' => [ - 'module' => BackendController::MODULE_NAME, - 'type' => PermissionType::READ, - 'state' => PermissionCategory::LOAN, - ], - ], - ], - '^/finance/loan/entry/list(\?.*$|$)' => [ - [ - 'dest' => '\Modules\LoanManagement\Controller\BackendController:viewLoanEntryList', - 'verb' => RouteVerb::GET, - 'permission' => [ - 'module' => BackendController::MODULE_NAME, - 'type' => PermissionType::READ, - 'state' => PermissionCategory::LOAN, - ], - ], - ], - '^/finance/loan/entry/view(\?.*$|$)' => [ - [ - 'dest' => '\Modules\LoanManagement\Controller\BackendController:viewLoanEntryView', - 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::MODULE_NAME, 'type' => PermissionType::READ, diff --git a/Controller/ApiController.php b/Controller/ApiController.php index fe6b6af..2c37f41 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -14,14 +14,23 @@ declare(strict_types=1); namespace Modules\LoanManagement\Controller; +use Modules\LoanManagement\Models\CostType; use Modules\LoanManagement\Models\CostTypeL11nMapper; use Modules\LoanManagement\Models\CostTypeMapper; +use Modules\LoanManagement\Models\Loan; +use Modules\LoanManagement\Models\LoanElement; +use phpOMS\Business\Finance\Loan as FinanceLoan; +use Modules\LoanManagement\Models\LoanMapper; +use Modules\LoanManagement\Models\LoanStatus; +use Modules\LoanManagement\Models\NullCostType; +use Modules\SupplierManagement\Models\NullSupplier; use phpOMS\Localization\BaseStringL11n; -use phpOMS\Localization\BaseStringL11nType; use phpOMS\Localization\ISO639x1Enum; use phpOMS\Message\Http\RequestStatusCode; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; +use phpOMS\Stdlib\Base\FloatInt; +use phpOMS\Stdlib\Base\SmartDateTime; /** * LoanManagement class. @@ -34,7 +43,7 @@ use phpOMS\Message\ResponseAbstract; final class ApiController extends Controller { /** - * Api method to create tag + * Api method to create loan * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -48,10 +57,135 @@ final class ApiController extends Controller */ public function apiLoanCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void { + if (!empty($val = $this->validateLoanCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + $costType = $this->createLoanFromRequest($request); + $this->createModel($request->header->account, $costType, LoanMapper::class, 'loan', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $costType); } /** - * Api method to create tag + * Validate cost type create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateLoanCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['name'] = !$request->hasData('name')) + || ($val['supplier'] = !$request->hasData('supplier')) + || ($val['start'] = !$request->hasData('start')) + || ($val['duration'] = !$request->hasData('duration')) + || ($val['amount'] = !$request->hasData('amount')) + || ($val['interest_rate'] = !$request->hasData('interest_rate')) + ) { + return $val; + } + + return []; + } + + /** + * Method to create cost type from request. + * + * @param RequestAbstract $request Request + * + * @return Loan + * + * @since 1.0.0 + */ + private function createLoanFromRequest(RequestAbstract $request) : Loan + { + $loan = new Loan(); + + $loan->createdBy = $request->header->account; + $loan->name = $request->getDataString('name'); + $loan->description = $request->getDataString('description'); + $loan->loanProvider = new NullSupplier((int) $request->getDataInt('supplier')); + $loan->status = LoanStatus::tryFromValue($request->getData('status')) ?? LoanStatus::ACTIVE; + $loan->nominalBorrowingRate = new FloatInt($request->getDataString('interest_rate') ?? 0); + $loan->interestRateAfterDuration = new FloatInt($request->getDataString('post_interest_rate') ?? 0); + $loan->start = $request->getDataDateTime('start') ?? new \DateTime('now'); + $loan->end = SmartDateTime::createFromDateTime($loan->start)->smartModify(0, (int) $request->getDataInt('duration')); + $loan->isSpecialPaymentAllowed = $request->getDataBool('special_payment_allowed') ?? false; + $loan->unit = $request->getDataInt('unit') ?? $this->app->unitId; + + $paymentInterval = $request->getDataInt('payment_interval') ?? 12; + + /** @var CostType[] $types */ + $types = CostTypeMapper::getAll()->executeGetArray(); + + $loanType = new NullCostType(); + $repaymentType = new NullCostType(); + $interestType = new NullCostType(); + + foreach ($types as $type) { + if ($type->name === 'loan') { + $loanType = $type; + } elseif ($type->name === 'repayment') { + $repaymentType = $type; + } elseif ($type->name === 'interest') { + $interestType = $type; + } + } + + // Loan + $element = new LoanElement(); + $element->amount = new FloatInt($request->getDataString('amount') ?? 0); + $element->date = $loan->start; + $element->type = $loanType; + + $loan->elements[] = $element; + + $currentDate = SmartDateTime::createFromDateTime($loan->start); + $currentDate->smartModify(0, (int) (12 / $paymentInterval), -1); + + // @feature Handle different loan types + $schedule = FinanceLoan::getAmortizationSchedule( + $element->amount->getNormalizedValue(), + $loan->nominalBorrowingRate->getNormalizedValue() / 100, + (int) $request->getDataInt('duration'), + $paymentInterval + ); + + foreach ($schedule as $idx => $e) { + if ($idx === 0) { + continue; + } + + // Repayment + $element = new LoanElement(); + $element->amount = new FloatInt($e['principal']); + $element->date = clone $currentDate; + $element->type = $repaymentType; + + $loan->elements[] = $element; + + // Interest + $element = new LoanElement(); + $element->amount = new FloatInt($e['interest']); + $element->date = clone $currentDate; + $element->type = $interestType; + + $loan->elements[] = $element; + + $currentDate->smartModify(0, (int) (12 / $paymentInterval)); + } + + return $loan; + } + + /** + * Api method to calculate loan timeline based on definitions * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -68,7 +202,7 @@ final class ApiController extends Controller } /** - * Api method to create tag + * Api method to create loan elements * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -85,7 +219,7 @@ final class ApiController extends Controller } /** - * Api method to create item cost type + * Api method to create loan cost type * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -112,7 +246,7 @@ final class ApiController extends Controller } /** - * Validate cost create request + * Validate cost type create request * * @param RequestAbstract $request Request * @@ -133,17 +267,20 @@ final class ApiController extends Controller } /** - * Method to create cost from request. + * Method to create cost type from request. * * @param RequestAbstract $request Request * - * @return BaseStringL11nType + * @return CostType * * @since 1.0.0 */ - private function createCostTypeFromRequest(RequestAbstract $request) : BaseStringL11nType + private function createCostTypeFromRequest(RequestAbstract $request) : CostType { - $costType = new BaseStringL11nType($request->getDataString('name') ?? ''); + $costType = new CostType(); + $costType->name = $request->getDataString('name'); + $costType->sign = $request->getDataInt('sign') ?? -1; + $costType->isLoan = $request->getDataBool('is_loan') ?? false; $costType->setL11n( $request->getDataString('title') ?? '', ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? ISO639x1Enum::_EN @@ -153,7 +290,7 @@ final class ApiController extends Controller } /** - * Api method to create item cost l11n + * Api method to create loan cost l11n * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response diff --git a/Models/CostType.php b/Models/CostType.php new file mode 100755 index 0000000..d58f73d --- /dev/null +++ b/Models/CostType.php @@ -0,0 +1,103 @@ +l11n instanceof BaseStringL11n ? $this->l11n->content : $this->l11n; + } + + /** + * Set l11n + * + * @param string|BaseStringL11n $l11n Tag article l11n + * @param string $lang Language + * + * @return void + * + * @since 1.0.0 + */ + public function setL11n(string | BaseStringL11n $l11n, string $lang = ISO639x1Enum::_EN) : void + { + if ($l11n instanceof BaseStringL11n) { + $this->l11n = $l11n; + } elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) { + $this->l11n->content = $l11n; + } else { + $this->l11n = new BaseStringL11n(); + $this->l11n->content = $l11n; + $this->l11n->language = $lang; + } + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + 'l11n' => $this->l11n, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/CostTypeL11nMapper.php b/Models/CostTypeL11nMapper.php index f0d2cde..f22e591 100755 --- a/Models/CostTypeL11nMapper.php +++ b/Models/CostTypeL11nMapper.php @@ -18,7 +18,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; use phpOMS\Localization\BaseStringL11n; /** - * Item mapper class. + * CostTypeL11n mapper class. * * @package Modules\LoanManagement\Models * @license OMS License 2.0 diff --git a/Models/CostTypeMapper.php b/Models/CostTypeMapper.php index a48b95e..c95783f 100755 --- a/Models/CostTypeMapper.php +++ b/Models/CostTypeMapper.php @@ -15,17 +15,16 @@ declare(strict_types=1); namespace Modules\LoanManagement\Models; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; -use phpOMS\Localization\BaseStringL11nType; /** - * Item mapper class. + * CostType mapper class. * * @package Modules\LoanManagement\Models * @license OMS License 2.0 * @link https://jingga.app * @since 1.0.0 * - * @template T of BaseStringL11nType + * @template T of CostType * @extends DataMapperFactory */ final class CostTypeMapper extends DataMapperFactory @@ -38,7 +37,9 @@ final class CostTypeMapper extends DataMapperFactory */ public const COLUMNS = [ 'loanmgmt_cost_type_id' => ['name' => 'loanmgmt_cost_type_id', 'type' => 'int', 'internal' => 'id'], - 'loanmgmt_cost_type_name' => ['name' => 'loanmgmt_cost_type_name', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], + 'loanmgmt_cost_type_name' => ['name' => 'loanmgmt_cost_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'loanmgmt_cost_type_sign' => ['name' => 'loanmgmt_cost_type_sign', 'type' => 'int', 'internal' => 'sign'], + 'loanmgmt_cost_type_loan' => ['name' => 'loanmgmt_cost_type_loan', 'type' => 'bool', 'internal' => 'isLoan'], ]; /** @@ -63,7 +64,7 @@ final class CostTypeMapper extends DataMapperFactory * @var class-string * @since 1.0.0 */ - public const MODEL = BaseStringL11nType::class; + public const MODEL = CostType::class; /** * Primary table. diff --git a/Models/Loan.php b/Models/Loan.php index a3c27d2..276102a 100755 --- a/Models/Loan.php +++ b/Models/Loan.php @@ -16,6 +16,7 @@ namespace Modules\LoanManagement\Models; use Modules\SupplierManagement\Models\NullSupplier; use Modules\SupplierManagement\Models\Supplier; +use phpOMS\Stdlib\Base\FloatInt; /** * Loan model. @@ -37,40 +38,10 @@ class Loan public int $status = LoanStatus::DRAFT; - public int $amount = 0; + public FloatInt $nominalBorrowingRate; - public int $acquisitionFee = 0; - - public int $disagio = 0; - - public int $nominalBorrowingRate = 0; - - public int $startingRepaymentRate = 0; - - public int $startingRepayment = 0; - - // 0 = end of month - public int $dayOfRepayment = 0; - - // monthly, quarterly, annually, end of duration - public int $interestInterval = 0; - - public int $interestTaxRate = 0; - - // monthly, quarterly, annually, end of duration - public int $repaymentInterval = 0; - - // months - public int $duration = 0; - - public int $repaymentFreeTime = 0; - - // Either separate (during the repayment free time) or during the repayment time - public int $repaymentFreeInterest = 1; - - public int $residualAmountAfterDuration = 0; - - public int $annualSpecialPayment = 0; + // 0 = not possible + public FloatInt $interestRateAfterDuration; public bool $isSpecialPaymentAllowed = false; @@ -78,24 +49,13 @@ class Loan public \DateTime $end; - public \DateTime $payout; + public \DateTimeImmutable $createdAt; - // 0 = not possible - public int $interestRateAfterDuration = 0; + public int $createdBy = 0; - // used to indicate if the interests/payments/taxes are manually adjusted - public bool $hasManualInterestAmounts = false; + public int $unit = 0; - public array $interests = []; - - // in and out - public array $payments = []; - - public bool $hasManualPaymentAmounts = false; - - public array $taxes = []; - - public bool $hasManualTaxAmounts = false; + public array $elements = []; /** * Constructor. @@ -104,9 +64,13 @@ class Loan */ public function __construct() { + $this->createdAt = new \DateTimeImmutable(); + $this->loanProvider = new NullSupplier(); $this->start = new \DateTime(); $this->end = $this->start->modify('+1 year'); - $this->payout = $this->start; + + $this->nominalBorrowingRate = new FloatInt(); + $this->interestRateAfterDuration = new FloatInt(); } } diff --git a/Models/LoanElement.php b/Models/LoanElement.php new file mode 100644 index 0000000..0773980 --- /dev/null +++ b/Models/LoanElement.php @@ -0,0 +1,47 @@ +amount = new FloatInt(); + $this->date = new \DateTime(); + $this->type = new NullCostType(); + } +} diff --git a/Models/LoanElementMapper.php b/Models/LoanElementMapper.php new file mode 100644 index 0000000..8544090 --- /dev/null +++ b/Models/LoanElementMapper.php @@ -0,0 +1,84 @@ + + */ +final class LoanElementMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'loanmgmt_loan_element_id' => ['name' => 'loanmgmt_loan_element_id', 'type' => 'int', 'internal' => 'id'], + 'loanmgmt_loan_element_description' => ['name' => 'loanmgmt_loan_element_description', 'type' => 'string', 'internal' => 'description'], + 'loanmgmt_loan_element_date' => ['name' => 'loanmgmt_loan_element_date', 'type' => 'DateTime', 'internal' => 'date'], + 'loanmgmt_loan_element_type' => ['name' => 'loanmgmt_loan_element_type', 'type' => 'int', 'internal' => 'type'], + 'loanmgmt_loan_element_loan' => ['name' => 'loanmgmt_loan_element_loan', 'type' => 'int', 'internal' => 'loan'], + 'loanmgmt_loan_element_amount' => ['name' => 'loanmgmt_loan_element_amount', 'type' => 'Serializable', 'internal' => 'amount'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'type' => [ + 'mapper' => CostTypeMapper::class, + 'external' => 'loanmgmt_loan_element_type', + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = LoanElement::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'loanmgmt_loan'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'loanmgmt_loan_element_id'; +} diff --git a/Models/LoanMapper.php b/Models/LoanMapper.php new file mode 100644 index 0000000..2a80244 --- /dev/null +++ b/Models/LoanMapper.php @@ -0,0 +1,106 @@ + + */ +final class LoanMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'loanmgmt_loan_id' => ['name' => 'loanmgmt_loan_id', 'type' => 'int', 'internal' => 'id'], + 'loanmgmt_loan_name' => ['name' => 'loanmgmt_loan_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'loanmgmt_loan_description' => ['name' => 'loanmgmt_loan_description', 'type' => 'string', 'internal' => 'description'], + 'loanmgmt_loan_start' => ['name' => 'loanmgmt_loan_start', 'type' => 'DateTime', 'internal' => 'start'], + 'loanmgmt_loan_end' => ['name' => 'loanmgmt_loan_end', 'type' => 'DateTime', 'internal' => 'end'], + 'loanmgmt_loan_created_at' => ['name' => 'loanmgmt_loan_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt'], + 'loanmgmt_loan_created_by' => ['name' => 'loanmgmt_loan_created_by', 'type' => 'int', 'internal' => 'createdBy'], + 'loanmgmt_loan_unit' => ['name' => 'loanmgmt_loan_unit', 'type' => 'int', 'internal' => 'unit'], + 'loanmgmt_loan_supplier' => ['name' => 'loanmgmt_loan_supplier', 'type' => 'int', 'internal' => 'supplier'], + 'loanmgmt_loan_status' => ['name' => 'loanmgmt_loan_status', 'type' => 'int', 'internal' => 'status'], + 'loanmgmt_loan_borrowing_rate' => ['name' => 'loanmgmt_loan_borrowing_rate', 'type' => 'Serializable', 'internal' => 'nominalBorrowingRate'], + 'loanmgmt_loan_post_rate' => ['name' => 'loanmgmt_loan_post_rate', 'type' => 'Serializable', 'internal' => 'interestRateAfterDuration'], + 'loanmgmt_loan_special_payment' => ['name' => 'loanmgmt_loan_special_payment', 'type' => 'bool', 'internal' => 'isSpecialPaymentAllowed'], + ]; + + /** + * Has one relation. + * + * @var array + * @since 1.0.0 + */ + public const OWNS_ONE = [ + 'supplier' => [ + 'mapper' => SupplierMapper::class, + 'external' => 'loanmgmt_loan_supplier', + ], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'elements' => [ + 'mapper' => LoanElementMapper::class, + 'table' => 'loanmgmt_loan_element', + 'self' => 'loanmgmt_loan_element_loan', + 'external' => null, + ], + ]; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = Loan::class; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'loanmgmt_loan'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'loanmgmt_loan_id'; +} diff --git a/Models/LoanStatus.php b/Models/LoanStatus.php index b93e856..213d84d 100755 --- a/Models/LoanStatus.php +++ b/Models/LoanStatus.php @@ -17,7 +17,7 @@ namespace Modules\LoanManagement\Models; use phpOMS\Stdlib\Base\Enum; /** - * Loanment status enum. + * Loan status enum. * * @package Modules\LoanManagement\Models * @license OMS License 2.0 diff --git a/Models/LoanType.php b/Models/LoanType.php new file mode 100644 index 0000000..b5835df --- /dev/null +++ b/Models/LoanType.php @@ -0,0 +1,34 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/NullLoan.php b/Models/NullLoan.php new file mode 100644 index 0000000..bbb48aa --- /dev/null +++ b/Models/NullLoan.php @@ -0,0 +1,47 @@ +id = $id; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/NullLoanElement.php b/Models/NullLoanElement.php new file mode 100644 index 0000000..14ab450 --- /dev/null +++ b/Models/NullLoanElement.php @@ -0,0 +1,47 @@ +id = $id; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/info.json b/info.json index c726a62..9aa4631 100755 --- a/info.json +++ b/info.json @@ -22,8 +22,7 @@ }, "providing": { "Admin": "*", - "Navigation": "*", - "Organization": "*" + "Navigation": "*" }, "load": [ {