This commit is contained in:
Dennis Eichhorn 2024-01-02 23:34:17 +00:00
parent 920fcb0044
commit 2d5608e41f
28 changed files with 1905 additions and 25 deletions

View File

@ -80,11 +80,6 @@
"foreignTable": "investmgmt_investment_type",
"foreignKey": "investmgmt_investment_type_id"
},
"investmgmt_investment_depreciation_type": {
"name": "investmgmt_investment_depreciation_type",
"type": "TINYINT",
"null": false
},
"investmgmt_investment_created_by": {
"name": "investmgmt_investment_created_by",
"type": "INT",
@ -232,6 +227,235 @@
}
}
},
"investmgmt_attr_type": {
"name": "investmgmt_attr_type",
"fields": {
"investmgmt_attr_type_id": {
"name": "investmgmt_attr_type_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"investmgmt_attr_type_name": {
"name": "investmgmt_attr_type_name",
"type": "VARCHAR(255)",
"null": false,
"unique": true
},
"investmgmt_attr_type_datatype": {
"name": "investmgmt_attr_type_datatype",
"type": "INT(11)",
"null": false
},
"investmgmt_attr_type_fields": {
"name": "investmgmt_attr_type_fields",
"type": "INT(11)",
"null": false
},
"investmgmt_attr_type_custom": {
"name": "investmgmt_attr_type_custom",
"type": "TINYINT(1)",
"null": false
},
"investmgmt_attr_type_required": {
"description": "Every item must have this attribute type if set to true.",
"name": "investmgmt_attr_type_required",
"type": "TINYINT(1)",
"null": false
},
"investmgmt_attr_type_pattern": {
"description": "This is a regex validation pattern.",
"name": "investmgmt_attr_type_pattern",
"type": "VARCHAR(255)",
"null": false
}
}
},
"investmgmt_attr_type_l11n": {
"name": "investmgmt_attr_type_l11n",
"fields": {
"investmgmt_attr_type_l11n_id": {
"name": "investmgmt_attr_type_l11n_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"investmgmt_attr_type_l11n_title": {
"name": "investmgmt_attr_type_l11n_title",
"type": "VARCHAR(255)",
"null": false
},
"investmgmt_attr_type_l11n_type": {
"name": "investmgmt_attr_type_l11n_type",
"type": "INT(11)",
"null": false,
"foreignTable": "investmgmt_attr_type",
"foreignKey": "investmgmt_attr_type_id"
},
"investmgmt_attr_type_l11n_lang": {
"name": "investmgmt_attr_type_l11n_lang",
"type": "VARCHAR(2)",
"null": false,
"foreignTable": "language",
"foreignKey": "language_639_1"
}
}
},
"investmgmt_attr_value": {
"name": "investmgmt_attr_value",
"fields": {
"investmgmt_attr_value_id": {
"name": "investmgmt_attr_value_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"investmgmt_attr_value_default": {
"name": "investmgmt_attr_value_default",
"type": "TINYINT(1)",
"null": false
},
"investmgmt_attr_value_valueStr": {
"name": "investmgmt_attr_value_valueStr",
"type": "VARCHAR(255)",
"null": true,
"default": null
},
"investmgmt_attr_value_valueInt": {
"name": "investmgmt_attr_value_valueInt",
"type": "INT(11)",
"null": true,
"default": null
},
"investmgmt_attr_value_valueDec": {
"name": "investmgmt_attr_value_valueDec",
"type": "DECIMAL(19,5)",
"null": true,
"default": null
},
"investmgmt_attr_value_valueDat": {
"name": "investmgmt_attr_value_valueDat",
"type": "DATETIME",
"null": true,
"default": null
},
"investmgmt_attr_value_unit": {
"name": "investmgmt_attr_value_unit",
"type": "VARCHAR(255)",
"null": false
},
"investmgmt_attr_value_deptype": {
"name": "investmgmt_attr_value_deptype",
"type": "INT(11)",
"null": true,
"default": null,
"foreignTable": "investmgmt_attr_type",
"foreignKey": "investmgmt_attr_type_id"
},
"investmgmt_attr_value_depvalue": {
"name": "investmgmt_attr_value_depvalue",
"type": "INT(11)",
"null": true,
"default": null,
"foreignTable": "investmgmt_attr_value",
"foreignKey": "investmgmt_attr_value_id"
}
}
},
"investmgmt_attr_value_l11n": {
"name": "investmgmt_attr_value_l11n",
"fields": {
"investmgmt_attr_value_l11n_id": {
"name": "investmgmt_attr_value_l11n_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"investmgmt_attr_value_l11n_title": {
"name": "investmgmt_attr_value_l11n_title",
"type": "VARCHAR(255)",
"null": false
},
"investmgmt_attr_value_l11n_value": {
"name": "investmgmt_attr_value_l11n_value",
"type": "INT(11)",
"null": false,
"foreignTable": "investmgmt_attr_value",
"foreignKey": "investmgmt_attr_value_id"
},
"investmgmt_attr_value_l11n_lang": {
"name": "investmgmt_attr_value_l11n_lang",
"type": "VARCHAR(2)",
"null": false,
"foreignTable": "language",
"foreignKey": "language_639_1"
}
}
},
"investmgmt_option_attr_default": {
"name": "investmgmt_option_attr_default",
"fields": {
"investmgmt_option_attr_default_id": {
"name": "investmgmt_option_attr_default_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"investmgmt_option_attr_default_type": {
"name": "investmgmt_option_attr_default_type",
"type": "INT(11)",
"null": false,
"foreignTable": "investmgmt_attr_type",
"foreignKey": "investmgmt_attr_type_id"
},
"investmgmt_option_attr_default_value": {
"name": "investmgmt_option_attr_default_value",
"type": "INT(11)",
"null": false,
"foreignTable": "investmgmt_attr_value",
"foreignKey": "investmgmt_attr_value_id"
}
}
},
"investmgmt_option_attr": {
"name": "investmgmt_option_attr",
"fields": {
"investmgmt_option_attr_id": {
"name": "investmgmt_option_attr_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"investmgmt_option_attr_option": {
"name": "investmgmt_option_attr_option",
"type": "INT(11)",
"null": false,
"foreignTable": "investmgmt_option",
"foreignKey": "investmgmt_option_id"
},
"investmgmt_option_attr_type": {
"name": "investmgmt_option_attr_type",
"type": "INT(11)",
"null": false,
"foreignTable": "investmgmt_attr_type",
"foreignKey": "investmgmt_attr_type_id"
},
"investmgmt_option_attr_value": {
"name": "investmgmt_option_attr_value",
"type": "INT(11)",
"null": true,
"default": null,
"foreignTable": "investmgmt_attr_value",
"foreignKey": "investmgmt_attr_value_id"
}
}
},
"investmgmt_option_media": {
"name": "investmgmt_option_media",
"fields": {

132
Admin/Routes/Web/Api.php Normal file
View File

@ -0,0 +1,132 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use Modules\InvestmentManagement\Controller\ApiController;
use Modules\InvestmentManagement\Models\PermissionCategory;
use phpOMS\Account\PermissionType;
use phpOMS\Router\RouteVerb;
return [
'^.*/finance/investment/find.*$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiController:apiInvestmentFind',
'verb' => RouteVerb::GET,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
],
'^.*/finance/investment/attribute$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeUpdate',
'verb' => RouteVerb::SET,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
],
'^.*/finance/investment/attribute/type$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeTypeCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeTypeUpdate',
'verb' => RouteVerb::SET,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
],
'^.*/finance/investment/attribute/type/l11n$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeTypeL11nCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeTypeL11nUpdate',
'verb' => RouteVerb::SET,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
],
'^.*/finance/investment/attribute/value$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeValueCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeValueUpdate',
'verb' => RouteVerb::SET,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
],
'^.*/finance/investment/attribute/value$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeValueL11nCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
[
'dest' => '\Modules\InvestmentManagement\Controller\ApiAttributeController:apiInvestmentAttributeValueL11nUpdate',
'verb' => RouteVerb::SET,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
],
];

View File

@ -17,9 +17,9 @@ return [
],
],
],
'^.*/finance/investment/single.*$' => [
'^.*/finance/investment/profile.*$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\BackendController:viewInvestmentSingle',
'dest' => '\Modules\InvestmentManagement\Controller\BackendController:viewInvestmentProfile',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
@ -39,6 +39,17 @@ return [
],
],
],
'^.*/finance/investment/object.*$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\BackendController:viewInvestmentObjectProfile',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
'type' => PermissionType::READ,
'state' => PermissionCategory::INVESTMENT,
],
],
],
'^.*/private/investment/list.*$' => [
[
@ -51,9 +62,9 @@ return [
],
],
],
'^.*/private/investment/single.*$' => [
'^.*/private/investment/profile.*$' => [
[
'dest' => '\Modules\InvestmentManagement\Controller\BackendController:viewInvestmentSingle',
'dest' => '\Modules\InvestmentManagement\Controller\BackendController:viewInvestmentProfile',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,

View File

@ -0,0 +1,524 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Controller;
use Modules\Attribute\Models\Attribute;
use Modules\Attribute\Models\AttributeType;
use Modules\Attribute\Models\AttributeValue;
use Modules\InvestmentManagement\Models\Attribute\InvestmentObjectAttributeMapper;
use Modules\InvestmentManagement\Models\Attribute\InvestmentObjectAttributeTypeL11nMapper;
use Modules\InvestmentManagement\Models\Attribute\InvestmentObjectAttributeTypeMapper;
use Modules\InvestmentManagement\Models\Attribute\InvestmentObjectAttributeValueL11nMapper;
use Modules\InvestmentManagement\Models\Attribute\InvestmentObjectAttributeValueMapper;
use phpOMS\Localization\BaseStringL11n;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
/**
* InvestmentManagement class.
*
* @package Modules\InvestmentManagement
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
final class ApiAttributeController extends Controller
{
use \Modules\Attribute\Controller\ApiAttributeTraitController;
/**
* Api method to create option attribute
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
$type = InvestmentObjectAttributeTypeMapper::get()->with('defaults')->where('id', (int) $request->getData('type'))->execute();
$attribute = $this->createAttributeFromRequest($request, $type);
$this->createModel($request->header->account, $attribute, InvestmentObjectAttributeMapper::class, 'attribute', $request->getOrigin());
$this->createStandardCreateResponse($request, $response, $attribute);
}
/**
* Api method to create option attribute l11n
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeTypeL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeTypeL11nCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
$attrL11n = $this->createAttributeTypeL11nFromRequest($request);
$this->createModel($request->header->account, $attrL11n, InvestmentObjectAttributeTypeL11nMapper::class, 'attr_type_l11n', $request->getOrigin());
$this->createStandardCreateResponse($request, $response, $attrL11n);
}
/**
* Api method to create option attribute type
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeTypeCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeTypeCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
$attrType = $this->createAttributeTypeFromRequest($request);
$this->createModel($request->header->account, $attrType, InvestmentObjectAttributeTypeMapper::class, 'attr_type', $request->getOrigin());
$this->createStandardCreateResponse($request, $response, $attrType);
}
/**
* Api method to create option attribute value
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeValueCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeValueCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
/** @var \Modules\Attribute\Models\AttributeType $type */
$type = InvestmentObjectAttributeTypeMapper::get()
->where('id', $request->getDataInt('type') ?? 0)
->execute();
$attrValue = $this->createAttributeValueFromRequest($request, $type);
$this->createModel($request->header->account, $attrValue, InvestmentObjectAttributeValueMapper::class, 'attr_value', $request->getOrigin());
if ($attrValue->isDefault) {
$this->createModelRelation(
$request->header->account,
(int) $request->getData('type'),
$attrValue->id,
InvestmentObjectAttributeTypeMapper::class, 'defaults', '', $request->getOrigin()
);
}
$this->createStandardCreateResponse($request, $response, $attrValue);
}
/**
* Api method to create option attribute l11n
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeValueL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeValueL11nCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
$attrL11n = $this->createAttributeValueL11nFromRequest($request);
$this->createModel($request->header->account, $attrL11n, InvestmentObjectAttributeValueL11nMapper::class, 'attr_value_l11n', $request->getOrigin());
$this->createStandardCreateResponse($request, $response, $attrL11n);
}
/**
* Api method to update InvestmentObjectAttribute
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeUpdate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidUpdateResponse($request, $response, $val);
return;
}
/** @var Attribute $old */
$old = InvestmentObjectAttributeMapper::get()
->with('type')
->with('type/defaults')
->with('value')
->where('id', (int) $request->getData('id'))
->execute();
$new = $this->updateAttributeFromRequest($request, clone $old);
if ($new->id === 0) {
// Set response header to invalid request because of invalid data
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidUpdateResponse($request, $response, $new);
return;
}
$this->updateModel($request->header->account, $old, $new, InvestmentObjectAttributeMapper::class, 'option_attribute', $request->getOrigin());
if ($new->value->getValue() !== $old->value->getValue()
&& $new->type->custom
) {
$this->updateModel($request->header->account, $old->value, $new->value, InvestmentObjectAttributeValueMapper::class, 'attribute_value', $request->getOrigin());
}
$this->createStandardUpdateResponse($request, $response, $new);
}
/**
* Api method to delete InvestmentObjectAttribute
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeDelete($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidDeleteResponse($request, $response, $val);
return;
}
$optionAttribute = InvestmentObjectAttributeMapper::get()
->with('type')
->where('id', (int) $request->getData('id'))
->execute();
if ($optionAttribute->type->isRequired) {
$this->createInvalidDeleteResponse($request, $response, []);
return;
}
$this->deleteModel($request->header->account, $optionAttribute, InvestmentObjectAttributeMapper::class, 'option_attribute', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $optionAttribute);
}
/**
* Api method to update InvestmentObjectAttributeTypeL11n
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeTypeL11nUpdate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidUpdateResponse($request, $response, $val);
return;
}
/** @var BaseStringL11n $old */
$old = InvestmentObjectAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute();
$new = $this->updateAttributeTypeL11nFromRequest($request, clone $old);
$this->updateModel($request->header->account, $old, $new, InvestmentObjectAttributeTypeL11nMapper::class, 'option_attribute_type_l11n', $request->getOrigin());
$this->createStandardUpdateResponse($request, $response, $new);
}
/**
* Api method to delete InvestmentObjectAttributeTypeL11n
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeTypeL11nDelete($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidDeleteResponse($request, $response, $val);
return;
}
/** @var BaseStringL11n $optionAttributeTypeL11n */
$optionAttributeTypeL11n = InvestmentObjectAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $optionAttributeTypeL11n, InvestmentObjectAttributeTypeL11nMapper::class, 'option_attribute_type_l11n', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $optionAttributeTypeL11n);
}
/**
* Api method to update InvestmentObjectAttributeType
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeTypeUpdate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidUpdateResponse($request, $response, $val);
return;
}
/** @var AttributeType $old */
$old = InvestmentObjectAttributeTypeMapper::get()->with('defaults')->where('id', (int) $request->getData('id'))->execute();
$new = $this->updateAttributeTypeFromRequest($request, clone $old);
$this->updateModel($request->header->account, $old, $new, InvestmentObjectAttributeTypeMapper::class, 'option_attribute_type', $request->getOrigin());
$this->createStandardUpdateResponse($request, $response, $new);
}
/**
* Api method to delete InvestmentObjectAttributeType
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @todo Implement API function
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeTypeDelete($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidDeleteResponse($request, $response, $val);
return;
}
/** @var AttributeType $optionAttributeType */
$optionAttributeType = InvestmentObjectAttributeTypeMapper::get()->with('defaults')->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $optionAttributeType, InvestmentObjectAttributeTypeMapper::class, 'option_attribute_type', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $optionAttributeType);
}
/**
* Api method to update InvestmentObjectAttributeValue
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeValueUpdate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidUpdateResponse($request, $response, $val);
return;
}
/** @var AttributeValue $old */
$old = InvestmentObjectAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute();
/** @var \Modules\Attribute\Models\Attribute $attr */
$attr = InvestmentObjectAttributeMapper::get()
->with('type')
->where('id', $request->getDataInt('attribute') ?? 0)
->execute();
$new = $this->updateAttributeValueFromRequest($request, clone $old, $attr);
$this->updateModel($request->header->account, $old, $new, InvestmentObjectAttributeValueMapper::class, 'option_attribute_value', $request->getOrigin());
$this->createStandardUpdateResponse($request, $response, $new);
}
/**
* Api method to delete InvestmentObjectAttributeValue
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
// @todo I don't think values can be deleted? Only Attributes
// However, It should be possible to remove UNUSED default values
// either here or other function?
// if (!empty($val = $this->validateAttributeValueDelete($request))) {
// $response->header->status = RequestStatusCode::R_400;
// $this->createInvalidDeleteResponse($request, $response, $val);
// return;
// }
// /** @var \Modules\InvestmentManagement\Models\InvestmentObjectAttributeValue $optionAttributeValue */
// $optionAttributeValue = InvestmentObjectAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute();
// $this->deleteModel($request->header->account, $optionAttributeValue, InvestmentObjectAttributeValueMapper::class, 'option_attribute_value', $request->getOrigin());
// $this->createStandardDeleteResponse($request, $response, $optionAttributeValue);
}
/**
* Api method to update InvestmentObjectAttributeValueL11n
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeValueL11nUpdate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidUpdateResponse($request, $response, $val);
return;
}
/** @var BaseStringL11n $old */
$old = InvestmentObjectAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'));
$new = $this->updateAttributeValueL11nFromRequest($request, clone $old);
$this->updateModel($request->header->account, $old, $new, InvestmentObjectAttributeValueL11nMapper::class, 'option_attribute_value_l11n', $request->getOrigin());
$this->createStandardUpdateResponse($request, $response, $new);
}
/**
* Api method to delete InvestmentObjectAttributeValueL11n
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiInvestmentObjectAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateAttributeValueL11nDelete($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidDeleteResponse($request, $response, $val);
return;
}
/** @var BaseStringL11n $optionAttributeValueL11n */
$optionAttributeValueL11n = InvestmentObjectAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->deleteModel($request->header->account, $optionAttributeValueL11n, InvestmentObjectAttributeValueL11nMapper::class, 'option_attribute_value_l11n', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $optionAttributeValueL11n);
}
}

View File

@ -478,7 +478,7 @@ final class ApiController extends Controller
$investment->investment = (int) $request->getData('investment');
$investment->parent = $request->getDataInt('parent');
$investment->supplier = $request->getDataInt('supplier');
$investment->supplierName = $request->getDataString('supplierName') ?? '';
$investment->supplierName = $request->getDataString('suppliername') ?? '';
$investment->item = $request->getDataInt('item');
// @todo reconsider the following lines. This seems rather complicated.

View File

@ -14,8 +14,16 @@ declare(strict_types=1);
namespace Modules\InvestmentManagement\Controller;
use Modules\Admin\Models\LocalizationMapper;
use Modules\Admin\Models\SettingsEnum;
use Modules\InvestmentManagement\Models\InvestmentMapper;
use Modules\InvestmentManagement\Models\InvestmentObjectMapper;
use Modules\InvestmentManagement\Models\InvestmentTypeMapper;
use Modules\Media\Models\MediaMapper;
use Modules\Media\Models\MediaTypeMapper;
use Modules\Organization\Models\UnitMapper;
use phpOMS\Contract\RenderableInterface;
use phpOMS\DataStorage\Database\Query\Builder;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Views\View;
@ -31,7 +39,7 @@ use phpOMS\Views\View;
final class BackendController extends Controller
{
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -59,7 +67,7 @@ final class BackendController extends Controller
}
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -70,17 +78,105 @@ final class BackendController extends Controller
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewInvestmentSingle(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
public function viewInvestmentObjectProfile(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/InvestmentManagement/Theme/Backend/investment-create');
$view->setTemplate('/Modules/InvestmentManagement/Theme/Backend/investment-object-profile');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1007101001, $request, $response);
$object = InvestmentObjectMapper::get()
->with('files')
->with('notes')
->with('amountGroups')
->with('amountGroups/type')
->with('amountGroups/amounts')
->where('id', (int) $request->getData('id'))
->execute();
$view->data['object'] = $object;
/** @var \Model\Setting $settings */
$settings = $this->app->appSettings->get(null, [
SettingsEnum::DEFAULT_LOCALIZATION,
]);
$view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response);
$view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute();
$view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response);
return $view;
}
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return RenderableInterface
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewInvestmentProfile(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/InvestmentManagement/Theme/Backend/investment-profile');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1007101001, $request, $response);
$investment = InvestmentMapper::get()
->with('notes')
->with('files')
->with('supplier')
->with('supplier/account')
->with('item')
->with('createdBy')
->with('options')
->with('options/files')
->with('options/notes')
->with('options/amountGroups')
->with('options/amountGroups/type')
->with('options/amountGroups/amounts')
->with('options/attributes')
->with('options/attributes/type')
->with('options/attributes/type/l11n')
->with('options/attributes/value')
->where('id', (int) $request->getData('id'))
->where('options/attributes/type/l11n/language', $response->header->l11n->language)
->execute();
$view->data['investment'] = $investment;
/** @var \Model\Setting $settings */
$settings = $this->app->appSettings->get(null, [
SettingsEnum::DEFAULT_LOCALIZATION,
]);
$view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response);
$view->data['attributeView']->data['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute();
$investmentTypes = InvestmentTypeMapper::getAll()
->with('l11n')
->where('l11n/language', $response->header->l11n->language)
->execute();
$view->data['types'] = $investmentTypes;
$units = UnitMapper::getAll()
->execute();
$view->data['units'] = $units;
$view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response);
$view->data['note'] = new \Modules\Editor\Theme\Backend\Components\Note\BaseView($this->app->l11nManager, $request, $response);
return $view;
}
/**
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response

3
Docs/Dev/en/SUMMARY.md Normal file
View File

@ -0,0 +1,3 @@
# Developer Content
* [Structure]({%}&page=Dev/structure)

5
Docs/Dev/en/structure.md Normal file
View File

@ -0,0 +1,5 @@
# Structure
## ER
![ER](Modules/InvestmentManagement/Docs/Dev/img/er.png)

BIN
Docs/Dev/img/er.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

1
Docs/introduction.md Normal file
View File

@ -0,0 +1 @@
# Introduction

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace Modules\InvestmentManagement\Models;
use phpOMS\Localization\BaseStringL11nType;
use phpOMS\Stdlib\Base\FloatInt;
/**
* Costs/Earnings.
@ -30,6 +31,12 @@ class AmountGroup
public string $name = '';
/**
* Amounts
*
* @var Amount[]
* @since 1.0.0
*/
public array $amounts = [];
public BaseStringL11nType $type;
@ -45,4 +52,14 @@ class AmountGroup
{
$this->type = new BaseStringL11nType();
}
public function sum() : FloatInt
{
$sum = new FloatInt();
foreach ($this->amounts as $value) {
$sum->add($value->amount);
}
return $sum;
}
}

View File

@ -63,7 +63,7 @@ final class AmountGroupMapper extends DataMapperFactory
*/
public const HAS_MANY = [
'amounts' => [
'mapper' => self::class,
'mapper' => AmountMapper::class,
'table' => 'investmgmt_amount',
'self' => 'investmgmt_amount_group',
'external' => null,

View File

@ -0,0 +1,86 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement\Models\Attribute
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Models\Attribute;
use Modules\Attribute\Models\Attribute;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Investment mapper class.
*
* @package Modules\InvestmentManagement\Models\Attribute
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of Attribute
* @extends DataMapperFactory<T>
*/
final class InvestmentObjectAttributeMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'investmgmt_option_attr_id' => ['name' => 'investmgmt_option_attr_id', 'type' => 'int', 'internal' => 'id'],
'investmgmt_option_attr_option' => ['name' => 'investmgmt_option_attr_option', 'type' => 'int', 'internal' => 'ref'],
'investmgmt_option_attr_type' => ['name' => 'investmgmt_option_attr_type', 'type' => 'int', 'internal' => 'type'],
'investmgmt_option_attr_value' => ['name' => 'investmgmt_option_attr_value', 'type' => 'int', 'internal' => 'value'],
];
/**
* Has one relation.
*
* @var array<string, array{mapper:class-string, external:string, by?:string, column?:string, conditional?:bool}>
* @since 1.0.0
*/
public const OWNS_ONE = [
'type' => [
'mapper' => InvestmentObjectAttributeTypeMapper::class,
'external' => 'investmgmt_option_attr_type',
],
'value' => [
'mapper' => InvestmentObjectAttributeValueMapper::class,
'external' => 'investmgmt_option_attr_value',
],
];
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = Attribute::class;
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'investmgmt_option_attr';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'investmgmt_option_attr_id';
}

View File

@ -0,0 +1,69 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement\Models\Attribute
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Models\Attribute;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
use phpOMS\Localization\BaseStringL11n;
/**
* Investment mapper class.
*
* @package Modules\InvestmentManagement\Models\Attribute
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of BaseStringL11n
* @extends DataMapperFactory<T>
*/
final class InvestmentObjectAttributeTypeL11nMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'investmgmt_attr_type_l11n_id' => ['name' => 'investmgmt_attr_type_l11n_id', 'type' => 'int', 'internal' => 'id'],
'investmgmt_attr_type_l11n_title' => ['name' => 'investmgmt_attr_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true],
'investmgmt_attr_type_l11n_type' => ['name' => 'investmgmt_attr_type_l11n_type', 'type' => 'int', 'internal' => 'ref'],
'investmgmt_attr_type_l11n_lang' => ['name' => 'investmgmt_attr_type_l11n_lang', 'type' => 'string', 'internal' => 'language'],
];
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'investmgmt_attr_type_l11n';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'investmgmt_attr_type_l11n_id';
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = BaseStringL11n::class;
}

View File

@ -0,0 +1,94 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement\Models\Attribute
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Models\Attribute;
use Modules\Attribute\Models\AttributeType;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Investment mapper class.
*
* @package Modules\InvestmentManagement\Models\Attribute
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of AttributeType
* @extends DataMapperFactory<T>
*/
final class InvestmentObjectAttributeTypeMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'investmgmt_attr_type_id' => ['name' => 'investmgmt_attr_type_id', 'type' => 'int', 'internal' => 'id'],
'investmgmt_attr_type_name' => ['name' => 'investmgmt_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true],
'investmgmt_attr_type_datatype' => ['name' => 'investmgmt_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'],
'investmgmt_attr_type_fields' => ['name' => 'investmgmt_attr_type_fields', 'type' => 'int', 'internal' => 'fields'],
'investmgmt_attr_type_custom' => ['name' => 'investmgmt_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'],
'investmgmt_attr_type_pattern' => ['name' => 'investmgmt_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'],
'investmgmt_attr_type_required' => ['name' => 'investmgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'],
];
/**
* Has many relation.
*
* @var array<string, array{mapper:class-string, table:string, self?:?string, external?:?string, column?:string}>
* @since 1.0.0
*/
public const HAS_MANY = [
'l11n' => [
'mapper' => InvestmentObjectAttributeTypeL11nMapper::class,
'table' => 'investmgmt_attr_type_l11n',
'self' => 'investmgmt_attr_type_l11n_type',
'column' => 'content',
'external' => null,
],
'defaults' => [
'mapper' => InvestmentObjectAttributeValueMapper::class,
'table' => 'investmgmt_option_attr_default',
'self' => 'investmgmt_option_attr_default_type',
'external' => 'investmgmt_option_attr_default_value',
],
];
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = AttributeType::class;
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'investmgmt_attr_type';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'investmgmt_attr_type_id';
}

View File

@ -0,0 +1,69 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement\Models\Attribute
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Models\Attribute;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
use phpOMS\Localization\BaseStringL11n;
/**
* Investment mapper class.
*
* @package Modules\InvestmentManagement\Models\Attribute
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of BaseStringL11n
* @extends DataMapperFactory<T>
*/
final class InvestmentObjectAttributeValueL11nMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'investmgmt_attr_value_l11n_id' => ['name' => 'investmgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'],
'investmgmt_attr_value_l11n_title' => ['name' => 'investmgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true],
'investmgmt_attr_value_l11n_value' => ['name' => 'investmgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'],
'investmgmt_attr_value_l11n_lang' => ['name' => 'investmgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'],
];
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'investmgmt_attr_value_l11n';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'investmgmt_attr_value_l11n_id';
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = BaseStringL11n::class;
}

View File

@ -0,0 +1,90 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement\Models\Attribute
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Models\Attribute;
use Modules\Attribute\Models\AttributeValue;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Investment mapper class.
*
* @package Modules\InvestmentManagement\Models\Attribute
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of AttributeValue
* @extends DataMapperFactory<T>
*/
final class InvestmentObjectAttributeValueMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'investmgmt_attr_value_id' => ['name' => 'investmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'],
'investmgmt_attr_value_default' => ['name' => 'investmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'],
'investmgmt_attr_value_valueStr' => ['name' => 'investmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'],
'investmgmt_attr_value_valueInt' => ['name' => 'investmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'],
'investmgmt_attr_value_valueDec' => ['name' => 'investmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'],
'investmgmt_attr_value_valueDat' => ['name' => 'investmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'],
'investmgmt_attr_value_unit' => ['name' => 'investmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'],
'investmgmt_attr_value_deptype' => ['name' => 'investmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'],
'investmgmt_attr_value_depvalue' => ['name' => 'investmgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'],
];
/**
* Has many relation.
*
* @var array<string, array{mapper:class-string, table:string, self?:?string, external?:?string, column?:string}>
* @since 1.0.0
*/
public const HAS_MANY = [
'l11n' => [
'mapper' => InvestmentObjectAttributeValueL11nMapper::class,
'table' => 'investmgmt_attr_value_l11n',
'self' => 'investmgmt_attr_value_l11n_value',
'column' => 'content',
'external' => null,
],
];
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = AttributeValue::class;
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'investmgmt_attr_value';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'investmgmt_attr_value_id';
}

View File

@ -35,8 +35,6 @@ class Investment
public string $description = '';
public int $depreciationType = DepreciationType::NONE;
public int $status = InvestmentStatus::DRAFT;
public ?BaseStringL11nType $type = null;

View File

@ -43,7 +43,6 @@ final class InvestmentMapper extends DataMapperFactory
'investmgmt_investment_name' => ['name' => 'investmgmt_investment_name', 'type' => 'string', 'internal' => 'name'],
'investmgmt_investment_description' => ['name' => 'investmgmt_investment_description', 'type' => 'string', 'internal' => 'description'],
'investmgmt_investment_status' => ['name' => 'investmgmt_investment_status', 'type' => 'int', 'internal' => 'status'],
'investmgmt_investment_depreciation_type' => ['name' => 'investmgmt_investment_depreciation_type', 'type' => 'int', 'internal' => 'depreciationType'],
'investmgmt_investment_unit' => ['name' => 'investmgmt_investment_unit', 'type' => 'int', 'internal' => 'unit'],
'investmgmt_investment_created_by' => ['name' => 'investmgmt_investment_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true],
'investmgmt_investment_performance' => ['name' => 'investmgmt_investment_performance', 'type' => 'DateTime', 'internal' => 'performanceDate'],
@ -84,8 +83,8 @@ final class InvestmentMapper extends DataMapperFactory
],
'options' => [
'mapper' => InvestmentObjectMapper::class,
'table' => 'investmgmt_investment_option',
'self' => 'investmgmt_investment_option_investment',
'table' => 'investmgmt_option',
'self' => 'investmgmt_option_investment',
'external' => null,
],
];

View File

@ -14,6 +14,9 @@ declare(strict_types=1);
namespace Modules\InvestmentManagement\Models;
use Modules\ItemManagement\Models\Item;
use Modules\SupplierManagement\Models\Supplier;
/**
* Investment object.
*
@ -30,7 +33,7 @@ class InvestmentObject
public string $description = '';
public ?int $supplier = null;
public ?Supplier $supplier = null;
public string $supplierName = '';
@ -38,6 +41,9 @@ class InvestmentObject
/**
* Costs / Revenue
*
* @var AmountGroup[]
* @since 1.0.0
*/
public array $amountGroups = [];
@ -49,8 +55,20 @@ class InvestmentObject
public int $investment = 0;
public ?int $item = null;
public ?Item $item = null;
public function getAmountByTypeName(string $type) : AmountGroup
{
foreach ($this->amountGroups as $group) {
if ($group->type->title === $type) {
return $group;
}
}
return new NullAmountGroup();
}
use \Modules\Media\Models\MediaListTrait;
use \Modules\Editor\Models\EditorDocListTrait;
use \Modules\Attribute\Models\AttributeHolderTrait;
}

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace Modules\InvestmentManagement\Models;
use Modules\Editor\Models\EditorDocMapper;
use Modules\InvestmentManagement\Models\Attribute\InvestmentObjectAttributeMapper;
use Modules\ItemManagement\Models\ItemMapper;
use Modules\Media\Models\MediaMapper;
use Modules\SupplierManagement\Models\SupplierMapper;
@ -93,6 +94,12 @@ final class InvestmentObjectMapper extends DataMapperFactory
'self' => 'investmgmt_amount_group_option',
'external' => null,
],
'attributes' => [
'mapper' => InvestmentObjectAttributeMapper::class,
'table' => 'investmgmt_option_attr',
'self' => 'investmgmt_option_attr_item',
'external' => null,
],
];
/**

46
Models/NullAmount.php Normal file
View File

@ -0,0 +1,46 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Models;
/**
* Null model
*
* @package Modules\InvestmentManagement\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
final class NullAmount extends Amount
{
/**
* Constructor
*
* @param int $id Model id
*
* @since 1.0.0
*/
public function __construct(int $id = 0)
{
$this->id = $id;
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() : mixed
{
return ['id' => $this->id];
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\InvestmentManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\InvestmentManagement\Models;
/**
* Null model
*
* @package Modules\InvestmentManagement\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
final class NullAmountGroup extends AmountGroup
{
/**
* Constructor
*
* @param int $id Model id
*
* @since 1.0.0
*/
public function __construct(int $id = 0)
{
$this->id = $id;
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() : mixed
{
return ['id' => $this->id];
}
}

View File

@ -17,7 +17,7 @@ namespace Modules\InvestmentManagement\Models;
use phpOMS\Stdlib\Base\Enum;
/**
* Permision state enum.
* Permission category enum.
*
* @package Modules\InvestmentManagement\Models
* @license OMS License 2.0

View File

@ -23,4 +23,20 @@ return ['InvestmentManagement' => [
'Name' => 'Name',
'Status' => 'Status',
'Title' => 'Titel',
'Files' => 'Dateien',
'Notes' => 'Notizen',
'Options' => 'Optionen',
'Option' => 'Option',
'Description' => 'Beschreibung',
'Link' => 'Link',
'Amounts' => 'Beträge',
'Amount' => 'Betrag',
'Quantity' => 'Menge',
'Attributes' => 'Attribute',
'Type' => 'Typ',
'Purchase' => 'Kauf',
'Price' => 'Preis',
'Supplier' => 'Lieferant',
'Approved' => 'Genehmigt',
'Approve' => 'Genehmigen',
]];

View File

@ -22,5 +22,21 @@ return ['InvestmentManagement' => [
'Investments' => 'Investments',
'Name' => 'Name',
'Status' => 'Status',
'Title' => 'Titel',
'Title' => 'Title',
'Files' => 'Files',
'Notes' => 'Notes',
'Options' => 'Options',
'Option' => 'Option',
'Description' => 'Description',
'Link' => 'Link',
'Amounts' => 'Amounts',
'Amount' => 'Amount',
'Quantity' => 'Quantity',
'Attributes' => 'Attributes',
'Type' => 'Type',
'Purchase' => 'Purchase',
'Price' => 'Price',
'Supplier' => 'Supplier',
'Approved' => 'Approved',
'Approve' => 'Approve',
]];

View File

@ -0,0 +1,67 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\HumanResourceTimeRecording
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use phpOMS\Localization\ISO639Enum;
/** @var \phpOMS\Views\View $this */
$object = $this->data['object'] ?? null;
$attributeView = $this->data['attributeView'];
$languages = ISO639Enum::getConstants();
echo $this->data['nav']->render(); ?>
<div class="tabview tab-2">
<div class="box">
<ul class="tab-links">
<li><label for="c-tab-1"><?= $this->getHtml('Object'); ?></label>
<li><label for="c-tab-2"><?= $this->getHtml('Attributes'); ?></label>
<li><label for="c-tab-3"><?= $this->getHtml('Amounts'); ?></label>
<li><label for="c-tab-4"><?= $this->getHtml('Files'); ?></label>
<li><label for="c-tab-5"><?= $this->getHtml('Notes'); ?></label>
</ul>
</div>
<div class="tab-content">
<input type="radio" id="c-tab-1" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
<div class="tab">
</div>
<input type="radio" id="c-tab-2" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>>
<div class="tab">
<div class="row">
<?= $attributeView->render(
$object->attributes,
$this->data['attributeTypes'] ?? [],
$this->data['units'] ?? [],
'{/api}finance/investment/object',
$object->id
);
?>
</div>
</div>
<input type="radio" id="c-tab-3" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>>
<div class="tab">
</div>
<input type="radio" id="c-tab-4" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>>
<div class="tab col-simple">
<?= $this->data['media-upload']->render('object-file', 'files', '', $object->files); ?>
</div>
<input type="radio" id="c-tab-5" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-5' ? ' checked' : ''; ?>>
<div class="tab col-simple">
<?= $this->data['note']->render('object-note', 'notes', $object->notes); ?>
</div>
</div>
</div>

View File

@ -0,0 +1,246 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\HumanResourceTimeRecording
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use Modules\InvestmentManagement\Models\InvestmentStatus;
use phpOMS\Uri\UriFactory;
/** @var \phpOMS\Views\View $this */
$investment = $this->data['investment'] ?? null;
$investmentStatus = InvestmentStatus::getConstants();
$files = $investment->files;
$investmentTypes = $this->data['types'] ?? [];
echo $this->data['nav']->render(); ?>
<div class="tabview tab-2">
<div class="box">
<ul class="tab-links">
<li><label for="c-tab-1"><?= $this->getHtml('Investment'); ?></label>
<li><label for="c-tab-2"><?= $this->getHtml('Files'); ?></label>
<li><label for="c-tab-3"><?= $this->getHtml('Notes'); ?></label>
<li><label for="c-tab-4"><?= $this->getHtml('Options'); ?></label>
</ul>
</div>
<div class="tab-content">
<input type="radio" id="c-tab-1" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>>
<div class="tab">
<div class="row">
<div class="col-xs-12 col-md-6">
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Investment'); ?></div>
<div class="portlet-body">
<div class="form-group">
<label for="iInvestmentName"><?= $this->getHtml('Name'); ?></label>
<input type="text" id="iInvestmentName" name="name" value="<?= $this->printHtml($investment->name); ?>">
</div>
<div class="form-group">
<label for="iInvestmentDescription"><?= $this->getHtml('Description'); ?></label>
<textarea id="iInvestmentDescription" name="description"><?= $this->printHtml($investment->description); ?></textarea>
</div>
<div class="form-group">
<label for="iInvestmentStatus"><?= $this->getHtml('Status'); ?></label>
<select id="iInvestmentStatus" name="investment_status" disabled>
<?php foreach ($investmentStatus as $status) : ?>
<option value="<?= $status; ?>"<?= $status === $investment->status ? ' selected' : ''; ?>><?= $this->getHtml(':status' . $status); ?>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label for="iInvestmentType"><?= $this->getHtml('Type'); ?></label>
<select id="iInvestmentType" name="investment_type">
<?php foreach ($investmentTypes as $type) : ?>
<option value="<?= $type->id; ?>"<?= $investment->type->id === $type->id ? ' selected' : ''; ?>><?= $this->printHtml($type->getL11n()); ?>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label for="iInvestmentPurchase"><?= $this->getHtml('Purchase'); ?></label>
<input type="date" id="iInvestmentPurchase" name="purchaseDate" value="<?= $investment->performanceDate->format('Y-m-d'); ?>">
</div>
</div>
<div class="portlet-foot">
<?php if ($investment->id === 0) : ?>
<input id="iCreateSubmit" type="Submit" value="<?= $this->getHtml('Create', '0', '0'); ?>">
<?php else : ?>
<input id="iSaveSubmit" type="Submit" value="<?= $this->getHtml('Save', '0', '0'); ?>">
<?php endif; ?>
</div>
</section>
</div>
<div class="col-xs-12 col-md-6">
<section class="portlet">
<div class="portlet-head">
<?= $this->getHtml('Options'); ?>
<i class="g-icon download btn end-xs">download</i>
</div>
<div class="slider">
<table id="iSalesClientList" class="default sticky">
<thead>
<tr>
<td>
<td><?= $this->getHtml('Name'); ?>
<td><?= $this->getHtml('Supplier'); ?>
<td><?= $this->getHtml('Price'); ?>
<td><?= $this->getHtml('Link'); ?>
<tbody>
<?php foreach ($investment->options as $option) : ?>
<tr>
<td><?php if ($option->approved) : ?><i class="g-icon">check</i><?php endif; ?>
<td><?= $this->printHtml($option->name); ?>
<td><?= $option->supplier === null
? $this->printHtml($option->supplierName)
: $option->supplier->account->name1;
?>
<td><?= $this->getCurrency($option->getAmountByTypeName('costs')->sum(), '', 'medium'); ?>
<td><?php if (!empty($option->link)) : ?>
<a class="content" target="_blank" href="<?= $option->link; ?>"><?= $this->printHtml($option->link); ?></a>
<?php endif; ?>
<?php endforeach; ?>
</table>
</div>
</section>
</div>
</div>
</div>
<input type="radio" id="c-tab-2" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-2' ? ' checked' : ''; ?>>
<div class="tab col-simple">
<?= $this->data['media-upload']->render('investment-file', 'files', '', $investment->files); ?>
</div>
<input type="radio" id="c-tab-3" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-3' ? ' checked' : ''; ?>>
<div class="tab">
<?= $this->data['note']->render('investment-notes', '', $investment->notes); ?>
</div>
<input type="radio" id="c-tab-4" name="tabular-2"<?= $this->request->uri->fragment === 'c-tab-4' ? ' checked' : ''; ?>>
<div class="tab">
<div class="row">
<?php
$count = 0;
foreach ($investment->options as $option) :
if ($option->parent !== null) {
continue;
}
++$count;
?>
<div class="col-xs-12 col-md-6 col-lg-4">
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Option'); ?> <?= $count; ?></div>
<div class="portlet-body">
<div class="form-group">
<label for="iObjectName-<?= $count; ?>"><?= $this->getHtml('Name'); ?></label>
<input type="text" id="iObjectName-<?= $count; ?>" name="name" value="<?= $this->printHtml($option->name); ?>" disabled>
</div>
<div class="form-group">
<label for="iObjectDescription-<?= $count; ?>"><?= $this->getHtml('Description'); ?></label>
<textarea id="iObjectDescription-<?= $count; ?>" name="description" disabled><?= $this->printHtml($option->description); ?></textarea>
</div>
<div class="form-group">
<label for="iObjectLink-<?= $count; ?>"><?= $this->getHtml('Link'); ?></label>
<input type="text" id="iObjectLink-<?= $count; ?>" name="link" value="<?= $this->printHtml($option->link); ?>" disabled>
</div>
<div class="form-group">
<span class="checkbox">
<label class="checkbox" for="iApproved-<?= $count; ?>">
<input id="iApproved-<?= $count; ?>" type="checkbox" name="approved" value="1" disabled>
<span class="checkmark"></span>
<?= $this->getHtml('Approved'); ?>
</label>
</span>
</div>
<div class="form-group">
<table class="default">
<thead>
<tr>
<td><?= $this->getHtml('Attributes'); ?>
<tbody>
<?php foreach ($option->attributes as $attribute) : ?>
<tr>
<td>
<?php endforeach; ?>
<?php if (empty($option->attributes)) : ?>
<tr><td colspan="1" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>
<div class="form-group">
<table class="default">
<thead>
<tr>
<td><?= $this->getHtml('Amounts'); ?>
<tbody>
<?php foreach ($option->amountGroups as $group) : ?>
<tr>
<td><?= $this->getCurrency($group->sum(), '', 'medium'); ?>
<?php endforeach; ?>
<?php if (empty($option->files)) : ?>
<tr><td colspan="1" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>
<div class="form-group">
<table class="default">
<thead>
<tr>
<td><?= $this->getHtml('Files'); ?>
<tbody>
<?php foreach ($option->files as $file) : ?>
<tr>
<td>
<?php endforeach; ?>
<?php if (empty($option->files)) : ?>
<tr><td colspan="1" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>
<div class="form-group">
<table class="default">
<thead>
<tr>
<td><?= $this->getHtml('Notes'); ?>
<tbody>
<?php foreach ($option->notes as $note) : ?>
<tr>
<td>
<?php endforeach; ?>
<?php if (empty($option->notes)) : ?>
<tr><td colspan="1" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>
</div>
<div class="portlet-foot">
<a class="button edit" href="<?= UriFactory::build('{/base}/finance/investment/object?id=' . $option->id) ?>"><?= $this->getHtml('Edit', '0', '0'); ?></a>
</div>
</section>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>