diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index adb8716..75cb759 100755 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -9,5 +9,5 @@ jobs: - uses: actions/first-interaction@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-message: 'Thank you for createing this issue. We will check it as soon as possible.' + issue-message: 'Thank you for creating this issue. We will check it as soon as possible.' pr-message: 'Thank you for your pull request. We will check it as soon as possible.' diff --git a/Admin/Install/Media.install.json b/Admin/Install/Media.install.json index 9f59e9c..3f2a9e0 100755 --- a/Admin/Install/Media.install.json +++ b/Admin/Install/Media.install.json @@ -19,47 +19,5 @@ "name": "Bills", "virtualPath": "/Modules/Billing", "user": 1 - }, - { - "type": "type", - "name": "preview", - "l11n": [ - { - "title": "Preview", - "lang": "en" - }, - { - "title": "Vorschau", - "lang": "de" - } - ] - }, - { - "type": "type", - "name": "internal", - "l11n": [ - { - "title": "Internal", - "lang": "en" - }, - { - "title": "Intern", - "lang": "de" - } - ] - }, - { - "type": "type", - "name": "external", - "l11n": [ - { - "title": "External", - "lang": "en" - }, - { - "title": "Extern", - "lang": "de" - } - ] } ] \ No newline at end of file diff --git a/Admin/Install/Media.php b/Admin/Install/Media.php index 2b24a4b..0cdee03 100755 --- a/Admin/Install/Media.php +++ b/Admin/Install/Media.php @@ -40,34 +40,5 @@ class Media public static function install(ApplicationAbstract $app, string $path) : void { $media = \Modules\Media\Admin\Installer::installExternal($app, ['path' => __DIR__ . '/Media.install.json']); - - \Modules\Admin\Admin\Installer::installExternal( - $app, - [ - 'data' => [ - [ - 'type' => 'setting', - 'name' => SettingsEnum::PREVIEW_MEDIA_TYPE, - 'content' => (string) $media['type'][0]['id'], - 'pattern' => '\\d+', - 'module' => 'Billing', - ], - [ - 'type' => 'setting', - 'name' => SettingsEnum::INTERNAL_MEDIA_TYPE, - 'content' => (string) $media['type'][1]['id'], - 'pattern' => '\\d+', - 'module' => 'Billing', - ], - [ - 'type' => 'setting', - 'name' => SettingsEnum::EXTERNAL_MEDIA_TYPE, - 'content' => (string) $media['type'][2]['id'], - 'pattern' => '\\d+', - 'module' => 'Billing', - ], - ], - ] - ); } } diff --git a/Admin/Install/Tag.install.json b/Admin/Install/Tag.install.json new file mode 100644 index 0000000..93412be --- /dev/null +++ b/Admin/Install/Tag.install.json @@ -0,0 +1,23 @@ +[ + { + "name": "bill_preview", + "l11n": { + "en": "Bill Preview", + "de": "Belegvorschau" + } + }, + { + "name": "internal_bill", + "l11n": { + "en": "Internal Bill", + "de": "Interner Beleg" + } + }, + { + "name": "external_bill", + "l11n": { + "en": "External Bill", + "de": "Externer Beleg" + } + } +] \ No newline at end of file diff --git a/Admin/Install/Tag.php b/Admin/Install/Tag.php new file mode 100644 index 0000000..9553481 --- /dev/null +++ b/Admin/Install/Tag.php @@ -0,0 +1,43 @@ + __DIR__ . '/Tag.install.json']); + } +} diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 4fb2fe3..a927ec7 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -603,6 +603,14 @@ "foreignTable": "billing_type", "foreignKey": "billing_type_id" }, + "billing_bill_tag": { + "name": "billing_bill_tag", + "type": "INT", + "null": true, + "default": null, + "foreignTable": "tag", + "foreignKey": "tag_id" + }, "billing_bill_template": { "name": "billing_bill_template", "type": "TINYINT(1)", diff --git a/Controller/ApiAttributeController.php b/Controller/ApiAttributeController.php index 8e36469..092907f 100755 --- a/Controller/ApiAttributeController.php +++ b/Controller/ApiAttributeController.php @@ -66,7 +66,7 @@ final class ApiAttributeController extends Controller ->where('id', (int) $request->getData('type')) ->execute(); - if (!$type->repeatable) { + if (!$type->isRepeatable) { $attr = BillAttributeMapper::count() ->with('type') ->where('type/id', $type->id) diff --git a/Controller/ApiBillController.php b/Controller/ApiBillController.php index b48bf25..b404132 100755 --- a/Controller/ApiBillController.php +++ b/Controller/ApiBillController.php @@ -47,6 +47,7 @@ use Modules\Messages\Models\EmailMapper; use Modules\SupplierManagement\Models\NullSupplier; use Modules\SupplierManagement\Models\Supplier; use Modules\SupplierManagement\Models\SupplierMapper; +use Modules\Tag\Models\TagMapper; use phpOMS\Account\PermissionType; use phpOMS\Application\ApplicationAbstract; use phpOMS\Autoloader; @@ -132,11 +133,11 @@ final class ApiBillController extends Controller $bill = $data['bill'] ?? BillMapper::get() ->with('type') ->with('files') - ->with('files/types') + ->with('files/tags') ->where('id', $request->getDataInt('bill') ?? 0) ->execute(); - $media = $data['media'] ?? $bill->getFileByTypeName('internal'); + $media = $data['media'] ?? $bill->getFileByTagName('internal_bill'); if ($bill->status === BillStatus::ARCHIVED && $bill->type->email @@ -798,7 +799,7 @@ final class ApiBillController extends Controller pathSettings: PathSettings::FILE_PATH, hasAccountRelation: false, readContent: $request->getDataBool('parse_content') ?? false, - type: $request->getDataInt('type'), + tag: $request->getDataInt('tag'), rel: $bill->id, mapper: BillMapper::class, field: 'files' @@ -1320,7 +1321,7 @@ final class ApiBillController extends Controller /** @var \Modules\Billing\Models\Bill $bill */ $bill = BillMapper::get() ->with('files') - ->with('files/types') + ->with('files/tags') ->with('elements') ->with('elements/container') ->with('type') @@ -1415,14 +1416,12 @@ final class ApiBillController extends Controller // @codeCoverageIgnoreEnd } - /** @var \Model\Setting $internalType */ - $internalType = $this->app->appSettings->get( - names: SettingsEnum::INTERNAL_MEDIA_TYPE, - module: self::NAME - ); + $tag = TagMapper::get() + ->where('name', 'internal_bill') + ->execute(); // @todo Check if old file exists -> update media - $oldFile = $bill->getFileByType((int) $internalType->content); + $oldFile = $bill->getFileByTag($tag->id); $billFileName = ($bill->billDate?->format('Y-m-d') ?? '0') . '_' . $bill->number . '.pdf'; @@ -1466,9 +1465,9 @@ final class ApiBillController extends Controller $this->createModelRelation( $request->header->account, $media->id, - (int) $internalType->content, + $tag->id, MediaMapper::class, - 'types', + 'tags', '', $request->getOrigin() ); diff --git a/Controller/ApiBillTypeController.php b/Controller/ApiBillTypeController.php index b5fc81d..7f1f86f 100755 --- a/Controller/ApiBillTypeController.php +++ b/Controller/ApiBillTypeController.php @@ -37,7 +37,7 @@ use phpOMS\Message\ResponseAbstract; final class ApiBillTypeController extends Controller { /** - * Api method to create item bill type + * Api method to create bill type * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response diff --git a/Controller/ApiPriceController.php b/Controller/ApiPriceController.php index 4ef1f0c..435bc45 100755 --- a/Controller/ApiPriceController.php +++ b/Controller/ApiPriceController.php @@ -74,6 +74,21 @@ final class ApiPriceController extends Controller $client ??= new NullClient(); $supplier ??= new NullSupplier(); + if ($item->id !== 0 && ($client->id !== 0 || $supplier->id !== 0)) { + $json = $this->app->cachePool->get()->get( + 'price:' . $item->id . ':' . $client->id . ':' . $supplier->id . ':' . ($request->getDataInt('price_quantity') ?? '') + ); + + if (!empty($json)) { + $json['bestActualPrice'] = FloatInt::fromJson($json['bestActualPrice']); + $json['discountPercent'] = FloatInt::fromJson($json['discountPercent']); + $json['discountAmount'] = FloatInt::fromJson($json['discountAmount']); + $json['bonus'] = FloatInt::fromJson($json['bonus']); + + return $json; + } + } + // Get item if ($item->id === 0 && $request->hasData('price_item')) { /** @var \Modules\ItemManagement\Models\Item $item */ @@ -334,7 +349,7 @@ final class ApiPriceController extends Controller $bestActualPriceValue -= $discountAmount; $bestActualPriceValue = (int) \round(((FloatInt::DIVISOR * 100) - $discountPercentage) / (FloatInt::DIVISOR * 100) * $bestActualPriceValue, 0); - return [ + $response = [ 'basePrice' => $basePrice->priceNew, 'bestPrice' => $bestPrice->priceNew, 'supplier' => $bestPrice->supplier->id, @@ -344,6 +359,14 @@ final class ApiPriceController extends Controller 'discountAmount' => new FloatInt($discountAmount), 'bonus' => new FloatInt($bonus), ]; + + $this->app->cachePool->get()->set( + 'price:' . $item->id . ':' . $client->id . ':' . $supplier->id . ':' . ($request->getDataInt('price_quantity') ?? ''), + $response, + 36000 + ); + + return $response; } /** @@ -466,6 +489,10 @@ final class ApiPriceController extends Controller $old = PriceMapper::get()->where('id', (int) $request->getData('id'))->execute(); $new = $this->updatePriceFromRequest($request, clone $old); + $this->app->cachePool->get()->delete( + 'price:' . $new->item->id . ':' . $new->client->id . ':' . $new->supplier->id . ':' . ($request->getDataInt('quantity') ?? '') + ); + if ($new->name === 'default' && $old->priceNew->value !== $new->priceNew->value ) { diff --git a/Controller/ApiPurchaseController.php b/Controller/ApiPurchaseController.php index cc1d840..1fcf1e4 100755 --- a/Controller/ApiPurchaseController.php +++ b/Controller/ApiPurchaseController.php @@ -19,6 +19,7 @@ use Modules\Billing\Models\BillStatus; use Modules\Billing\Models\BillTransferType; use Modules\Billing\Models\BillTypeMapper; use Modules\Billing\Models\SettingsEnum; +use Modules\Tag\Models\TagMapper; use phpOMS\Message\Http\HttpRequest; use phpOMS\Message\Http\HttpResponse; use phpOMS\Message\Http\RequestStatusCode; @@ -97,13 +98,9 @@ final class ApiPurchaseController extends Controller */ private function createSupplierBillUploadFromRequest(RequestAbstract $request, ResponseAbstract $response, $data) : array { - /** @var \Model\Setting $setting */ - $setting = $this->app->appSettings->get( - names: SettingsEnum::EXTERNAL_MEDIA_TYPE, - module: self::NAME - ); - - $internalType = $request->getDataInt('type') ?? ((int) $setting->content); + $tag = TagMapper::get() + ->where('name', 'external_bill') + ->execute(); /** @var \Modules\Billing\Models\BillType $purchaseTransferType */ $purchaseTransferType = BillTypeMapper::get() @@ -181,7 +178,7 @@ final class ApiPurchaseController extends Controller } $mediaRequest->setData('bill', $billId); - $mediaRequest->setData('type', $internalType); + $mediaRequest->setData('tag', $tag->id); $mediaRequest->setData('parse_content', true, true); $this->app->moduleManager->get('Billing', 'ApiBill')->apiMediaAddToBill($mediaRequest, $mediaResponse, $data); diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 442bedc..9a294ba 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -23,7 +23,6 @@ use Modules\Billing\Models\BillTypeMapper; use Modules\Billing\Models\PaymentTermL11nMapper; use Modules\Billing\Models\PaymentTermMapper; use Modules\Billing\Models\PermissionCategory; -use Modules\Billing\Models\SettingsEnum; use Modules\Billing\Models\ShippingTermL11nMapper; use Modules\Billing\Models\ShippingTermMapper; use Modules\Billing\Models\Tax\TaxCombinationMapper; @@ -31,6 +30,7 @@ use Modules\ClientManagement\Models\Attribute\ClientAttributeTypeMapper; use Modules\Finance\Models\TaxCodeMapper; use Modules\ItemManagement\Models\Attribute\ItemAttributeTypeMapper; use Modules\SupplierManagement\Models\Attribute\SupplierAttributeTypeMapper; +use Modules\Tag\Models\TagMapper; use phpOMS\Account\PermissionType; use phpOMS\Contract\RenderableInterface; use phpOMS\DataStorage\Database\Query\OrderType; @@ -239,28 +239,23 @@ final class BackendController extends Controller $view->setTemplate('/Modules/Billing/Theme/Backend/bill-create'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005104001, $request, $response); - /** @var \Modules\Billing\Models\Bill $bill */ - $bill = BillMapper::get() + $view->data['bill'] = BillMapper::get() ->with('client') ->with('elements') ->with('elements/container') ->with('files') - ->with('files/types') + ->with('files/tags') ->with('notes') ->where('id', (int) $request->getData('id')) ->execute(); - $view->data['bill'] = $bill; - - $billTypes = BillTypeMapper::getAll() + $view->data['billtypes'] = BillTypeMapper::getAll() ->with('l11n') ->where('isTemplate', false) ->where('transferType', BillTransferType::SALES) ->where('l11n/language', $request->header->l11n->language) ->executeGetArray(); - $view->data['billtypes'] = $billTypes; - $logs = []; if ($this->app->accountManager->get($request->header->account)->hasPermission( PermissionType::READ, @@ -275,16 +270,16 @@ final class BackendController extends Controller ->with('createdBy') ->where('module', 'Billing') ->where('type', StringUtils::intHash(BillMapper::class)) - ->where('ref', $bill->id) + ->where('ref', $view->data['bill']->id) ->executeGetArray(); - if (!empty($bill->elements)) { + if (!empty($view->data['bill']->elements)) { /** @var \Modules\Auditor\Models\Audit[] $logsElements */ $logsElements = AuditMapper::getAll() ->with('createdBy') ->where('module', 'Billing') ->where('type', StringUtils::intHash(BillElementMapper::class)) - ->where('ref', \array_keys($bill->elements), 'IN') + ->where('ref', \array_keys($view->data['bill']->elements), 'IN') ->executeGetArray(); $logs = \array_merge($logs, $logsElements); @@ -435,7 +430,7 @@ final class BackendController extends Controller ->with('elements') ->with('elements/container') ->with('files') - ->with('files/types') + ->with('files/tags') ->with('notes') ->where('id', (int) $request->getData('id')) ->execute(); @@ -637,31 +632,26 @@ final class BackendController extends Controller $view->setTemplate('/Modules/Billing/Theme/Backend/purchase-bill'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1005109001, $request, $response); - $bill = BillMapper::get() + $view->data['bill'] = BillMapper::get() ->with('elements') ->with('files') - ->with('files/types') + ->with('files/tags') ->with('notes') ->where('id', (int) $request->getData('id')) ->execute(); - $view->data['bill'] = $bill; + $tags = TagMapper::getAll() + ->where('name', ['bill_preview', 'external_bill']) + ->executeGetArray(); - /** @var \Model\Setting $previewType */ - $previewType = $this->app->appSettings->get( - names: SettingsEnum::PREVIEW_MEDIA_TYPE, - module: self::NAME - ); + foreach ($tags as $tag) { + if ($tag->name === 'bill_preview') { + $view->data['previewType'] = $tag; + } else { + $view->data['externalType'] = $tag; + } + } - $view->data['previewType'] = (int) $previewType->content; - - /** @var \Model\Setting $externalType */ - $externalType = $this->app->appSettings->get( - names: SettingsEnum::EXTERNAL_MEDIA_TYPE, - module: self::NAME - ); - - $view->data['externalType'] = (int) $externalType->content; $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); return $view; diff --git a/Controller/CliController.php b/Controller/CliController.php index 2c8b743..23b03e7 100755 --- a/Controller/CliController.php +++ b/Controller/CliController.php @@ -25,6 +25,7 @@ use Modules\Payment\Models\PaymentType; use Modules\SupplierManagement\Models\NullSupplier; use Modules\SupplierManagement\Models\Supplier; use Modules\SupplierManagement\Models\SupplierMapper; +use Modules\Tag\Models\TagMapper; use phpOMS\Contract\RenderableInterface; use phpOMS\Localization\ISO4217CharEnum; use phpOMS\Localization\ISO4217DecimalEnum; @@ -63,22 +64,23 @@ final class CliController extends Controller $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/Billing/Theme/Cli/bill-parsed'); - /** @var \Model\Setting $setting */ - $setting = $this->app->appSettings->get( - names: SettingsEnum::EXTERNAL_MEDIA_TYPE, - module: self::NAME - ); + $tag = null; + if (!$request->hasData('-t')) { + $tag = TagMapper::get() + ->where('name', 'external_bill') + ->execute(); + } - $externalType = $request->getDataInt('-t') ?? (int) $setting->content; + $externalType = $request->getDataInt('-t') ?? (int) ($tag?->id); /** @var \Modules\Billing\Models\Bill $bill */ $bill = BillMapper::get() ->with('elements') ->with('files') - ->with('files/types') + ->with('files/tags') ->with('files/content') ->where('id', (int) $request->getData('-i')) - ->where('files/types', $externalType) + ->where('files/tags', $externalType) ->execute(); if ($bill->id === 0) { @@ -87,7 +89,7 @@ final class CliController extends Controller $old = clone $bill; - $content = \strtolower($bill->getFileByType($externalType)->content->content ?? ''); + $content = \strtolower($bill->getFileByTag($externalType)->content->content ?? ''); $lines = \explode("\n", $content); foreach ($lines as $line => $value) { if (empty(\trim($value))) { diff --git a/Models/Attribute/BillAttributeTypeMapper.php b/Models/Attribute/BillAttributeTypeMapper.php index 17b6e7b..11b97f0 100755 --- a/Models/Attribute/BillAttributeTypeMapper.php +++ b/Models/Attribute/BillAttributeTypeMapper.php @@ -42,7 +42,7 @@ final class BillAttributeTypeMapper extends DataMapperFactory 'billing_attr_type_datatype' => ['name' => 'billing_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'], 'billing_attr_type_fields' => ['name' => 'billing_attr_type_fields', 'type' => 'int', 'internal' => 'fields'], 'billing_attr_type_custom' => ['name' => 'billing_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'], - 'billing_attr_type_repeatable' => ['name' => 'billing_attr_type_repeatable', 'type' => 'bool', 'internal' => 'repeatable'], + 'billing_attr_type_repeatable' => ['name' => 'billing_attr_type_repeatable', 'type' => 'bool', 'internal' => 'isRepeatable'], 'billing_attr_type_internal' => ['name' => 'billing_attr_type_internal', 'type' => 'bool', 'internal' => 'isInternal'], 'billing_attr_type_pattern' => ['name' => 'billing_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'], 'billing_attr_type_required' => ['name' => 'billing_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'], diff --git a/Models/Bill.php b/Models/Bill.php index 994ab0b..889a5ac 100755 --- a/Models/Bill.php +++ b/Models/Bill.php @@ -719,4 +719,5 @@ class Bill implements \JsonSerializable use \Modules\Attribute\Models\AttributeHolderTrait; use \Modules\Editor\Models\EditorDocListTrait; use \Modules\Media\Models\MediaListTrait; + use \Modules\Tag\Models\TagListTrait; } diff --git a/Models/SettingsEnum.php b/Models/SettingsEnum.php index a15288b..6ed7f93 100755 --- a/Models/SettingsEnum.php +++ b/Models/SettingsEnum.php @@ -26,12 +26,6 @@ use phpOMS\Stdlib\Base\Enum; */ abstract class SettingsEnum extends Enum { - public const PREVIEW_MEDIA_TYPE = '1005100001'; // internally generated preview - - public const INTERNAL_MEDIA_TYPE = '1005100002'; // original document (client = invoice sent to client, supplier = invoice from supplier) - - public const EXTERNAL_MEDIA_TYPE = '1005100006'; // original document (client = invoice sent to client, supplier = invoice from supplier) - public const VALID_BILL_LANGUAGES = '1005100003'; // List of valid languages for bills public const BILLING_CUSTOMER_EMAIL_TEMPLATE = '1005100004'; // Email template for customer billing diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php index 92340ea..b75dc73 100755 --- a/Theme/Backend/Lang/de.lang.php +++ b/Theme/Backend/Lang/de.lang.php @@ -79,7 +79,7 @@ return ['Billing' => [ 'Type' => 'Typ', 'Types' => 'Typen', 'Upload' => 'Hochladen', - 'Zip' => 'Zip', + 'Postal' => 'Postal', 'Files' => 'Files', 'TaxCode' => 'Steuerkz.', 'PL' => 'GuV', diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 7d10a7d..e34f8b8 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -79,7 +79,7 @@ return ['Billing' => [ 'Type' => 'Type', 'Types' => 'Types', 'Upload' => 'Upload', - 'Zip' => 'Zip', + 'Postal' => 'Postal', 'Files' => 'Files', 'TaxCode' => 'Tax Code', 'PL' => 'PL', diff --git a/Theme/Backend/bill-create.tpl.php b/Theme/Backend/bill-create.tpl.php index db88531..7d1a338 100755 --- a/Theme/Backend/bill-create.tpl.php +++ b/Theme/Backend/bill-create.tpl.php @@ -36,7 +36,7 @@ $elements = $bill->elements; $billTypes = $this->data['billtypes'] ?? []; -$archive = $bill->getFileByTypeName('internal'); +$archive = $bill->getFileByTagName('internal_bill'); /** @var \Modules\Auditor\Models\Audit */ $logs = $this->data['logs'] ?? []; @@ -216,7 +216,7 @@ echo $this->data['nav']->render(); ?>