From b07e0fa98df959af65bbbdca5dc0d3eb3a47fd63 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 24 Jul 2023 06:01:31 +0000 Subject: [PATCH] added api functions --- Controller/ApiAttributeController.php | 658 +++++++++++++++++++++++++- Controller/ApiBillController.php | 351 +++++++++++++- Controller/ApiBillTypeController.php | 246 +++++++++- Controller/ApiPriceController.php | 154 ++++++ Controller/ApiTaxController.php | 123 +++++ 5 files changed, 1518 insertions(+), 14 deletions(-) diff --git a/Controller/ApiAttributeController.php b/Controller/ApiAttributeController.php index ac3f6ce..25406fd 100755 --- a/Controller/ApiAttributeController.php +++ b/Controller/ApiAttributeController.php @@ -17,6 +17,7 @@ namespace Modules\Billing\Controller; use Modules\Attribute\Models\Attribute; use Modules\Attribute\Models\AttributeType; use Modules\Attribute\Models\AttributeValue; +use Modules\Attribute\Models\NullAttribute; use Modules\Attribute\Models\NullAttributeType; use Modules\Attribute\Models\NullAttributeValue; use Modules\Billing\Models\Attribute\BillAttributeMapper; @@ -232,7 +233,7 @@ final class ApiAttributeController extends Controller $attrType = new AttributeType($request->getDataString('name') ?? ''); $attrType->datatype = $request->getDataInt('datatype') ?? 0; $attrType->custom = $request->getDataBool('custom') ?? false; - $attrType->isRequired = (bool) ($request->getData('is_required') ?? false); + $attrType->isRequired = $request->getDataBool('is_required') ?? false; $attrType->validationPattern = $request->getDataString('validation_pattern') ?? ''; $attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); $attrType->setFields($request->getDataInt('fields') ?? 0); @@ -414,4 +415,659 @@ final class ApiAttributeController extends Controller return []; } + + /** + * Api method to update BillAttribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var Attribute $old */ + $old = BillAttributeMapper::get() + ->with('type') + ->with('type/defaults') + ->with('value') + ->where('id', (int) $request->getData('id')) + ->execute(); + + $new = $this->updateBillAttributeFromRequest($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, BillAttributeMapper::class, 'bill_attribute', $request->getOrigin()); + + if ($new->value->getValue() !== $old->value->getValue()) { + $this->updateModel($request->header->account, $old->value, $new->value, BillAttributeValueMapper::class, 'attribute_value', $request->getOrigin()); + } + + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillAttribute from request. + * + * @param RequestAbstract $request Request + * @param Attribute $new Model to modify + * + * @return Attribute + * + * @since 1.0.0 + */ + public function updateBillAttributeFromRequest(RequestAbstract $request, Attribute $new) : Attribute + { + if ($request->hasData('value')) { + $new->value = $request->hasData('value') ? new NullAttributeValue((int) $request->getData('value')) : $new->value; + } else { + // @todo: fix by only accepting the value id to be used + // this is a workaround for now because the front end doesn't allow to dynamically show default values. + $value = $new->type->getDefaultByValue($request->getData('value')); + + // Couldn't find matching default value + if ($value->id === 0) { + return new NullAttribute(); + } + + $new->value = $value; + } + + return $new; + } + + /** + * Validate BillAttribute update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateBillAttributeUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + || ($val['value'] = (!$request->hasData('value') && !$request->hasData('custom'))) + ) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillAttribute + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + $billAttribute = BillAttributeMapper::get() + ->with('type') + ->where('id', (int) $request->getData('id')) + ->execute(); + + if ($billAttribute->type->isRequired) { + $this->createInvalidDeleteResponse($request, $response, []); + + return; + } + + $this->deleteModel($request->header->account, $billAttribute, BillAttributeMapper::class, 'bill_attribute', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billAttribute); + } + + /** + * Validate BillAttribute delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateBillAttributeDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to update BillAttributeTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeTypeL11nUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var BaseStringL11n $old */ + $old = BillAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateBillAttributeTypeL11nFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, BillAttributeTypeL11nMapper::class, 'bill_attribute_type_l11n', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillAttributeTypeL11n from request. + * + * @param RequestAbstract $request Request + * @param BaseStringL11n $new Model to modify + * + * @return BaseStringL11n + * + * @todo: consider to move all these FromRequest functions to the attribute module since they are the same in every module! + * + * @since 1.0.0 + */ + public function updateBillAttributeTypeL11nFromRequest(RequestAbstract $request, BaseStringL11n $new) : BaseStringL11n + { + $new->setLanguage( + $request->getDataString('language') ?? $new->language + ); + $new->content = $request->getDataString('title') ?? $new->content; + + return $new; + } + + /** + * Validate BillAttributeTypeL11n update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillAttributeTypeL11nUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillAttributeTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeTypeL11nDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\BillAttributeTypeL11n $billAttributeTypeL11n */ + $billAttributeTypeL11n = BillAttributeTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $billAttributeTypeL11n, BillAttributeTypeL11nMapper::class, 'bill_attribute_type_l11n', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billAttributeTypeL11n); + } + + /** + * Validate BillAttributeTypeL11n delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillAttributeTypeL11nDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to update BillAttributeType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeTypeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeTypeUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var AttributeType $old */ + $old = BillAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateBillAttributeTypeFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, BillAttributeTypeMapper::class, 'bill_attribute_type', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillAttributeType from request. + * + * @param RequestAbstract $request Request + * @param AttributeType $new Model to modify + * + * @return AttributeType + * + * @todo: implement + * + * @since 1.0.0 + */ + public function updateBillAttributeTypeFromRequest(RequestAbstract $request, AttributeType $new) : AttributeType + { + $new->datatype = $request->getDataInt('datatype') ?? $new->datatype; + $new->custom = $request->getDataBool('custom') ?? $new->custom; + $new->isRequired = $request->getDataBool('is_required') ?? $new->isRequired; + $new->validationPattern = $request->getDataString('validation_pattern') ?? $new->validationPattern; + + return $new; + } + + /** + * Validate BillAttributeType update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillAttributeTypeUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillAttributeType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @todo: implement + * + * @since 1.0.0 + */ + public function apiBillAttributeTypeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeTypeDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\BillAttributeType $billAttributeType */ + $billAttributeType = BillAttributeTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $billAttributeType, BillAttributeTypeMapper::class, 'bill_attribute_type', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billAttributeType); + } + + /** + * Validate BillAttributeType delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateBillAttributeTypeDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to update BillAttributeValue + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeValueUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeValueUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var AttributeValue $old */ + $old = BillAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateBillAttributeValueFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, BillAttributeValueMapper::class, 'bill_attribute_value', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillAttributeValue from request. + * + * @param RequestAbstract $request Request + * @param AttributeValue $new Model to modify + * + * @return AttributeValue + * + * @todo: implement + * + * @since 1.0.0 + */ + public function updateBillAttributeValueFromRequest(RequestAbstract $request, AttributeValue $new) : AttributeValue + { + /** @var \Modules\Attribute\Models\Attribute $type */ + $attr = BillAttributeMapper::get() + ->with('type') + ->where('id', $request->getDataInt('attribute') ?? 0) + ->execute(); + + $new->isDefault = $request->getDataBool('default') ?? $new->isDefault; + $new->setValue($request->getDataString('value'), $attr->type->datatype); + + return $new; + } + + /** + * Validate BillAttributeValue update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillAttributeValueUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + || ($val['attribute'] = !$request->hasData('attribute')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillAttributeValue + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeValueDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + return; + + // @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->validateBillAttributeValueDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\BillAttributeValue $billAttributeValue */ + $billAttributeValue = BillAttributeValueMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $billAttributeValue, BillAttributeValueMapper::class, 'bill_attribute_value', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billAttributeValue); + } + + /** + * Validate BillAttributeValue delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillAttributeValueDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to update BillAttributeValueL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeValueL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeValueL11nUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var BaseStringL11n $old */ + $old = BillAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id')); + $new = $this->updateBillAttributeValueL11nFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, BillAttributeValueL11nMapper::class, 'bill_attribute_value_l11n', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillAttributeValueL11n from request. + * + * @param RequestAbstract $request Request + * @param BaseStringL11n $new Model to modify + * + * @return BaseStringL11n + * + * @todo: implement + * + * @since 1.0.0 + */ + public function updateBillAttributeValueL11nFromRequest(RequestAbstract $request, BaseStringL11n $new) : BaseStringL11n + { + $new->setLanguage( + $request->getDataString('language') ?? $new->language + ); + $new->content = $request->getDataString('title') ?? $new->content; + + return $new; + } + + /** + * Validate BillAttributeValueL11n update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillAttributeValueL11nUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillAttributeValueL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillAttributeValueL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillAttributeValueL11nDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\BillAttributeValueL11n $billAttributeValueL11n */ + $billAttributeValueL11n = BillAttributeValueL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $billAttributeValueL11n, BillAttributeValueL11nMapper::class, 'bill_attribute_value_l11n', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billAttributeValueL11n); + } + + /** + * Validate BillAttributeValueL11n delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillAttributeValueL11nDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } } diff --git a/Controller/ApiBillController.php b/Controller/ApiBillController.php index a1a206d..72582ea 100755 --- a/Controller/ApiBillController.php +++ b/Controller/ApiBillController.php @@ -28,6 +28,7 @@ use Modules\Billing\Models\NullBillElement; use Modules\Billing\Models\SettingsEnum; use Modules\ClientManagement\Models\Client; use Modules\ClientManagement\Models\ClientMapper; +use Modules\Editor\Models\EditorDocMapper; use Modules\ItemManagement\Models\Item; use Modules\ItemManagement\Models\ItemMapper; use Modules\Media\Models\CollectionMapper; @@ -84,8 +85,8 @@ final class ApiBillController extends Controller } /** @var \Modules\Billing\Models\Bill $old */ - $old = BillMapper::get()->where('id', (int) $request->getData('bill')); - $new = $this->updateBillFromRequest($request, $response, $data); + $old = BillMapper::get()->where('id', (int) $request->getData('bill'))->execute(); + $new = $this->updateBillFromRequest($request, clone $old); $this->updateModel($request->header->account, $old, $new, BillMapper::class, 'bill', $request->getOrigin()); $this->createStandardUpdateResponse($request, $response, $new); @@ -114,19 +115,15 @@ final class ApiBillController extends Controller * Method to create a bill from request. * * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param mixed $data Generic data + * @param Bill $old Bill * * @return Bill * * @since 1.0.0 */ - public function updateBillFromRequest(RequestAbstract $request, ResponseAbstract $response, $data = null) : Bill + public function updateBillFromRequest(RequestAbstract $request, Bill $old) : Bill { - /** @var Bill $bill */ - $bill = BillMapper::get()->where('id', (int) $request->getData('bill'))->execute(); - - return $bill; + return $old; } /** @@ -380,7 +377,7 @@ final class ApiBillController extends Controller } /** - * Api method to create a bill + * Api method to add Media to a Bill * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -490,6 +487,109 @@ final class ApiBillController extends Controller ]); } + /** + * Api method to remove Media from Bill + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiMediaRemoveFromBill(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + // @todo: check that it is not system generated media! + if (!empty($val = $this->validateMediaRemoveFromBill($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Media\Models\Media $media */ + $media = MediaMapper::get()->where('id', (int) $request->getData('media'))->execute(); + + /** @var \Modules\Billing\Models\Bill $bill */ + $bill = BillMapper::get()->where('id', (int) $request->getData('bill'))->execute(); + + $path = $this->createBillDir($bill); + + $billCollection = CollectionMapper::getAll() + ->where('virtual', $path) + ->execute(); + + if (\count($billCollection) !== 1) { + // For some reason there are multiple collections with the same virtual path? + // @todo: check if this is the correct way to handle it or if we need to make sure that it is a collection + return; + } + + $collection = \reset($billCollection); + + $this->deleteModelRelation( + $request->header->account, + $bill->id, + $media->id, + BillMapper::class, + 'files', + '', + $request->getOrigin() + ); + + $this->deleteModelRelation( + $request->header->account, + $collection->id, + $media->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + + $referenceCount = MediaMapper::countInternalReferences($media->id); + + if ($referenceCount === 0) { + // Is not used anywhere else -> remove from db and file system + + // @todo: remove media types from media + + $this->deleteModel($request->header->account, $media, MediaMapper::class, 'bill_media', $request->getOrigin()); + + if (\is_dir($media->getAbsolutePath())) { + \phpOMS\System\File\Local\Directory::delete($media->getAbsolutePath()); + } else { + \phpOMS\System\File\Local\File::delete($media->getAbsolutePath()); + } + } + + $this->createStandardDeleteResponse($request, $response, $media); + } + + /** + * Validate Media remove from Bill request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateMediaRemoveFromBill(RequestAbstract $request) : array + { + $val = []; + if (($val['media'] = !$request->hasData('media')) + || ($val['bill'] = !$request->hasData('bill')) + ) { + return $val; + } + + return []; + } + /** * Create media directory path * @@ -1079,4 +1179,235 @@ final class ApiBillController extends Controller return []; } + + /** + * Api method to delete Bill + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\Bill $old */ + $old = BillMapper::get()->where('id', (int) $request->getData('id'))->execute(); + + // @todo: check if bill can be deleted + // @todo: adjust stock transfer + + $new = $this->deleteBillFromRequest($request, clone $old); + $this->updateModel($request->header->account, $old, $new, BillMapper::class, 'bill', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $old); + } + + /** + * Method to create a bill from request. + * + * @param RequestAbstract $request Request + * @param Bill $new Bill + * + * @return Bill + * + * @since 1.0.0 + */ + public function deleteBillFromRequest(RequestAbstract $request, Bill $new) : Bill + { + $new->status = BillStatus::DELETED; + + return $new; + } + + /** + * Validate Bill delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to update BillElement + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillElementUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillElementUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var BillElement $old */ + $old = BillElementMapper::get()->where('id', (int) $request->getData('id'))->execute(); + + // @todo: can be edited? + // @todo: adjust transfer protocolls + + $new = $this->updateBillElementFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, BillElementMapper::class, 'bill_element', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillElement from request. + * + * @param RequestAbstract $request Request + * @param BillElement $new Model to modify + * + * @return BillElement + * + * @todo: implement + * + * @since 1.0.0 + */ + public function updateBillElementFromRequest(RequestAbstract $request, BillElement $new) : BillElement + { + return $new; + } + + /** + * Validate BillElement update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillElementUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillElement + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillElementDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillElementDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + // @todo: check if can be deleted + // @todo: handle transactions and bill update + + /** @var \Modules\Billing\Models\BillElement $billElement */ + $billElement = BillElementMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $billElement, BillElementMapper::class, 'bill_element', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billElement); + } + + /** + * Validate BillElement delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateBillElementDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to update Note + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + // @todo: check permissions + $this->app->moduleManager->get('Editor', 'Api')->apiEditorDocUpdate($request, $response, $data); + } + + /** + * Api method to delete Note + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + // @todo: check permissions + $this->app->moduleManager->get('Editor', 'Api')->apiEditorDocDelete($request, $response, $data); + } } diff --git a/Controller/ApiBillTypeController.php b/Controller/ApiBillTypeController.php index 10fd835..e9b6f78 100755 --- a/Controller/ApiBillTypeController.php +++ b/Controller/ApiBillTypeController.php @@ -80,9 +80,9 @@ final class ApiBillTypeController extends Controller { $billType = new BillType($request->getDataString('name') ?? ''); $billType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); - $billType->numberFormat = (string) ($request->getData('number_format') ?? '{id}'); - $billType->transferStock = (bool) ($request->getData('transfer_stock') ?? false); - $billType->isTemplate = (bool) ($request->getData('is_template') ?? false); + $billType->numberFormat = $request->getDataString('number_format') ?? '{id}'; + $billType->transferStock = $request->getDataBool('transfer_stock') ?? false; + $billType->isTemplate = $request->getDataBool('is_template') ?? false; $billType->transferType = $request->getDataInt('transfer_type') ?? BillTransferType::SALES; $billType->defaultTemplate = $request->hasData('template') ? new NullCollection((int) $request->getData('template')) @@ -184,4 +184,244 @@ final class ApiBillTypeController extends Controller return []; } + + /** + * Api method to update BillType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillTypeUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillTypeUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var BillType $old */ + $old = BillTypeMapper::get()->where('id', (int) $request->getData('id')); + $new = $this->updateBillTypeFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, BillTypeMapper::class, 'bill_type', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillType from request. + * + * @param RequestAbstract $request Request + * @param BillType $new Model to modify + * + * @return BillType + * + * @todo: implement + * + * @since 1.0.0 + */ + public function updateBillTypeFromRequest(RequestAbstract $request, BillType $new) : BillType + { + $new->numberFormat = $request->getDataString('number_format') ?? $new->numberFormat; + $new->transferStock = $request->getDataBool('transfer_stock') ?? $new->transferStock; + $new->isTemplate = $request->getDataBool('is_template') ?? $new->isTemplate; + $new->transferType = $request->getDataInt('transfer_type') ?? $new->transferType; + $new->defaultTemplate = $request->hasData('template') + ? new NullCollection((int) $request->getData('template')) + : $new->defaultTemplate; + + return $new; + } + + /** + * Validate BillType update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateBillTypeUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillType + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillTypeDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillTypeDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\BillType $billType */ + $billType = BillTypeMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $billType, BillTypeMapper::class, 'bill_type', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billType); + } + + /** + * Validate BillType delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateBillTypeDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to update BillTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillTypeL11nUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillTypeL11nUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var BaseStringL11n $old */ + $old = BillTypeL11nMapper::get()->where('id', (int) $request->getData('id')); + $new = $this->updateBillTypeL11nFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, BillTypeL11nMapper::class, 'bill_type_l11n', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update BillTypeL11n from request. + * + * @param RequestAbstract $request Request + * @param BaseStringL11n $new Model to modify + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + public function updateBillTypeL11nFromRequest(RequestAbstract $request, BaseStringL11n $new) : BaseStringL11n + { + $new->ref = $request->getDataInt('type') ?? $new->ref; + $new->setLanguage( + $request->getDataString('language') ?? $new->language + ); + $new->content = $request->getDataString('title') ?? $new->content; + + return $new; + } + + /** + * Validate BillTypeL11n update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateBillTypeL11nUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete BillTypeL11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiBillTypeL11nDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateBillTypeL11nDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\BillTypeL11n $billTypeL11n */ + $billTypeL11n = BillTypeL11nMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $billTypeL11n, BillTypeL11nMapper::class, 'bill_type_l11n', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $billTypeL11n); + } + + /** + * Validate BillTypeL11n delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateBillTypeL11nDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } } diff --git a/Controller/ApiPriceController.php b/Controller/ApiPriceController.php index d0e5d6f..58a9fc3 100755 --- a/Controller/ApiPriceController.php +++ b/Controller/ApiPriceController.php @@ -301,6 +301,9 @@ final class ApiPriceController extends Controller * * @return array * + * @todo: consider to prevent name 'base'? + * Might not be possible because it is used internally as well (see apiItemCreate in ItemManagement) + * * @since 1.0.0 */ private function validatePriceCreate(RequestAbstract $request) : array @@ -312,4 +315,155 @@ final class ApiPriceController extends Controller return []; } + + /** + * Api method to update Price + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiPriceUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validatePriceUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\Price\Price $old */ + $old = PriceMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updatePriceFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, PriceMapper::class, 'price', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update Price from request. + * + * @param RequestAbstract $request Request + * @param Price $new Model to modify + * + * @return Price + * + * @since 1.0.0 + */ + public function updatePriceFromRequest(RequestAbstract $request, Price $new) : Price + { + $new->name = $new->name !== 'base' && $request->hasData('name') ? $request->getDataString('name') : $new->name; + $new->promocode = $request->getDataString('promocode') ?? $new->promocode; + + $new->item = $request->hasData('item') ? new NullItem((int) $request->getData('item')) : $new->item; + $new->itemgroup = $request->hasData('itemgroup') ? new NullAttributeValue((int) $request->getData('itemgroup')) : $new->itemgroup; + $new->itemsegment = $request->hasData('itemsegment') ? new NullAttributeValue((int) $request->getData('itemsegment')) : $new->itemsegment; + $new->itemsection = $request->hasData('itemsection') ? new NullAttributeValue((int) $request->getData('itemsection')) : $new->itemsection; + $new->itemtype = $request->hasData('itemtype') ? new NullAttributeValue((int) $request->getData('itemtype')) : $new->itemtype; + + $new->client = $request->hasData('client') ? new NullClient((int) $request->getData('client')) : $new->client; + $new->clientgroup = $request->hasData('clientgroup') ? new NullAttributeValue((int) $request->getData('clientgroup')) : $new->clientgroup; + $new->clientsegment = $request->hasData('clientsegment') ? new NullAttributeValue((int) $request->getData('clientsegment')) : $new->clientsegment; + $new->clientsection = $request->hasData('clientsection') ? new NullAttributeValue((int) $request->getData('clientsection')) : $new->clientsection; + $new->clienttype = $request->hasData('clienttype') ? new NullAttributeValue((int) $request->getData('clienttype')) : $new->clienttype; + + $new->supplier = $request->hasData('supplier') ? new NullSupplier((int) $request->getData('supplier')) : $new->supplier; + $new->unit = $request->getDataInt('unit') ?? $new->unit; + $new->type = $request->getDataInt('type') ?? $new->type; + $new->quantity = $request->getDataInt('quantity') ?? $new->quantity; + $new->price = $request->hasData('price') ? new FloatInt((int) $request->getData('price')) : $new->price; + $new->priceNew = $request->getDataInt('price_new') ?? $new->priceNew; + $new->discount = $request->getDataInt('discount') ?? $new->discount; + $new->discountPercentage = $request->getDataInt('discountPercentage') ?? $new->discountPercentage; + $new->bonus = $request->getDataInt('bonus') ?? $new->bonus; + $new->multiply = $request->getDataBool('multiply') ?? $new->multiply; + $new->currency = $request->getDataString('currency') ?? $new->currency; + $new->start = $request->getDataDateTime('start') ?? $new->start; + $new->end = $request->getDataDateTime('end') ?? $new->end; + + return $new; + } + + /** + * Validate Price update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * @todo: consider to block 'base' name + * + * @since 1.0.0 + */ + private function validatePriceUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete Price + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiPriceDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validatePriceDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\Price\Price $price */ + $price = PriceMapper::get()->where('id', (int) $request->getData('id'))->execute(); + + if ($price->name === 'base') { + // default price cannot be deleted + $this->createInvalidDeleteResponse($request, $response, []); + + return; + } + + $this->deleteModel($request->header->account, $price, PriceMapper::class, 'price', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $price); + } + + /** + * Validate Price delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validatePriceDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } } diff --git a/Controller/ApiTaxController.php b/Controller/ApiTaxController.php index c61e60d..64e3e64 100755 --- a/Controller/ApiTaxController.php +++ b/Controller/ApiTaxController.php @@ -219,4 +219,127 @@ final class ApiTaxController extends Controller return $taxCode; } + + /** + * Api method to update TaxCombination + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiTaxCombinationUpdate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateTaxCombinationUpdate($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\Tax\TaxCombination $old */ + $old = TaxCombinationMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $new = $this->updateTaxCombinationFromRequest($request, clone $old); + + $this->updateModel($request->header->account, $old, $new, TaxCombinationMapper::class, 'tax_combination', $request->getOrigin()); + $this->createStandardUpdateResponse($request, $response, $new); + } + + /** + * Method to update TaxCombination from request. + * + * @param RequestAbstract $request Request + * @param TaxCombination $new Model to modify + * + * @return TaxCombination + * + * @since 1.0.0 + */ + public function updateTaxCombinationFromRequest(RequestAbstract $request, TaxCombination $new) : TaxCombination + { + $new->taxType = $request->getDataInt('tax_type') ?? $new->taxType; + $new->taxCode = $request->getDataString('tax_code') ?? $new->taxCode; + $new->itemCode = $request->hasData('item_code') ? new NullAttributeValue((int) $request->getData('item_code')) : $new->itemCode; + + if ($new->taxType === 1) { + $new->clientCode = $request->hasData('account_code') ? new NullAttributeValue((int) $request->getData('account_code')) : $new->clientCode; + } else { + $new->supplierCode = $request->hasData('account_code') ? new NullAttributeValue((int) $request->getData('account_code')) : $new->supplierCode; + } + + return $new; + } + + /** + * Validate TaxCombination update request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateTaxCombinationUpdate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } + + /** + * Api method to delete TaxCombination + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiTaxCombinationDelete(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void + { + if (!empty($val = $this->validateTaxCombinationDelete($request))) { + $response->data[$request->uri->__toString()] = new FormValidation($val); + $response->header->status = RequestStatusCode::R_400; + + return; + } + + /** @var \Modules\Billing\Models\TaxCombination $taxCombination */ + $taxCombination = TaxCombinationMapper::get()->where('id', (int) $request->getData('id'))->execute(); + $this->deleteModel($request->header->account, $taxCombination, TaxCombinationMapper::class, 'tax_combination', $request->getOrigin()); + $this->createStandardDeleteResponse($request, $response, $taxCombination); + } + + /** + * Validate TaxCombination delete request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @todo: implement + * + * @since 1.0.0 + */ + private function validateTaxCombinationDelete(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id'))) { + return $val; + } + + return []; + } }