This commit is contained in:
Dennis Eichhorn 2023-07-17 01:39:34 +00:00
parent 9950bc0248
commit 16e043a8b6
3751 changed files with 1447 additions and 21 deletions

View File

@ -0,0 +1,9 @@
[
{
"type": "setting",
"name": "1005700001",
"content": "1",
"pattern": "",
"module": "Labeling"
}
]

43
Admin/Install/Admin.php Normal file
View File

@ -0,0 +1,43 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Admin\Install
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Labeling\Admin\Install;
use phpOMS\Application\ApplicationAbstract;
/**
* Admin class.
*
* @package Modules\Labeling\Admin\Install
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class Admin
{
/**
* Install Admin providing
*
* @param ApplicationAbstract $app Application
* @param string $path Module path
*
* @return void
*
* @since 1.0.0
*/
public static function install(ApplicationAbstract $app, string $path) : void
{
\Modules\Admin\Admin\Installer::installExternal($app, ['path' => __DIR__ . '/Admin.install.json']);
}
}

View File

@ -0,0 +1,23 @@
[
{
"type": "collection",
"create_directory": true,
"name": "Labeling",
"virtualPath": "/Modules",
"user": 1
},
{
"type": "collection",
"create_directory": true,
"name": "Templates",
"virtualPath": "/Modules/Labeling",
"user": 1
},
{
"type": "collection",
"create_directory": true,
"name": "Default",
"virtualPath": "/Modules/Billing",
"user": 1
}
]

44
Admin/Install/Media.php Normal file
View File

@ -0,0 +1,44 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Admin\Install
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Labeling\Admin\Install;
use Modules\Labeling\Models\SettingsEnum;
use phpOMS\Application\ApplicationAbstract;
/**
* Media class.
*
* @package Modules\Labeling\Admin\Install
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class Media
{
/**
* Install media providing
*
* @param ApplicationAbstract $app Application
* @param string $path Module path
*
* @return void
*
* @since 1.0.0
*/
public static function install(ApplicationAbstract $app, string $path) : void
{
$media = \Modules\Media\Admin\Installer::installExternal($app, ['path' => __DIR__ . '/Media.install.json']);
}
}

View File

@ -0,0 +1,244 @@
<?php
use Modules\Labeling\Models\Label;
use Modules\Labeling\Models\Text;
use Modules\Labeling\Models\Shape;
use Modules\Labeling\Models\Image;
use phpOMS\Utils\Barcode\Datamatrix;
use phpOMS\Utils\Barcode\QR;
$margin = 50;
$l = new Label();
// top
$text = new Text();
$text->text = 'Product Name';
$text->size = 80;
$text->x = $margin;
$text->y = 80 + $margin;
$l->elements[] = $text;
// sub
$text = new Text();
$text->text = 'Second Product Name';
$text->size = 50;
$text->x = $margin;
$text->y = 170 + $margin;
$l->elements[] = $text;
$line = new Shape();
$line->type = 1;
$line->borderThickness = 5;
$line->x = $margin;
$line->y = 200 + $margin;
$line->x2 = (int) ((37.8 * $l->width) - $margin);
$line->y2 = $line->y;
$l->elements[] = $line;
// facts
// REF
$image = new Image();
$image->src = '/Modules/Labeling/Theme/icons/iso/2493.png';
$image->x = $margin - 15;
$image->y = 250 + $margin - 50;
$image->x2 = $image->x + 150;
$image->y2 = 75 + $image->y;
$l->elements[] = $image;
$text = new Text();
$text->text = '0123-4567-8910';
$text->size = 40;
$text->x = 150 + $margin;
$text->y = 290 + $margin;
$l->elements[] = $text;
// LOT
$image = new Image();
$image->src = '/Modules/Labeling/Theme/icons/iso/2492.png';
$image->x = $margin - 15;
$image->y = 350 + $margin - 50;
$image->x2 = $image->x + 150;
$image->y2 = 75 + $image->y;
$l->elements[] = $image;
$text = new Text();
$text->text = '0123-4567-8910';
$text->size = 40;
$text->x = 150 + $margin;
$text->y = 390 + $margin;
$l->elements[] = $text;
// SN
$image = new Image();
$image->src = '/Modules/Labeling/Theme/icons/iso/2498.png';
$image->x = $margin - 15;
$image->y = 450 + $margin - 50;
$image->x2 = $image->x + 150;
$image->y2 = 75 + $image->y;
$l->elements[] = $image;
$text = new Text();
$text->text = '0123-4567-8910';
$text->size = 40;
$text->x = 150 + $margin;
$text->y = 490 + $margin;
$l->elements[] = $text;
// manufactured
$image = new Image();
$image->src = '/Modules/Labeling/Theme/icons/iso/2497.png';
$image->x = $margin - 15;
$image->y = 560 + $margin - 50;
$image->x2 = $image->x + 150;
$image->y2 = 75 + $image->y;
$l->elements[] = $image;
$text = new Text();
$text->text = 'YYYY-MM-DD';
$text->size = 40;
$text->x = 150 + $margin;
$text->y = 610 + $margin;
$l->elements[] = $text;
$text = new Text();
$text->text = 'DE';
$text->size = 20;
$text->x = $margin + 40;
$text->y = 625 + $margin;
$l->elements[] = $text;
// use by date
$image = new Image();
$image->src = '/Modules/Labeling/Theme/icons/iso/2607.png';
$image->x = $margin + 500;
$image->y = 540 + $margin;
$image->x2 = $image->x + 100;
$image->y2 = 75 + $image->y;
$l->elements[] = $image;
$text = new Text();
$text->text = 'YYYY-MM-DD';
$text->size = 40;
$text->x = 600 + $margin;
$text->y = 610 + $margin;
$l->elements[] = $text;
// QR
$qr = new Datamatrix('https://jingga.app', 200, 200);
$image = new Image();
$image->resource = $qr->get();
$image->x = 1000 + $margin;
$image->y = 280 + $margin - 50;
$image->x2 = $image->x + 200;
$image->y2 = 75 + $image->y;
$l->elements[] = $image;
$text = new Text();
$text->text = "(01)00000000000000\n(11)000000\n(17)000000\n(10)A000B0\n(21)0000";
$text->size = 40;
$text->x = 1230 + $margin;
$text->y = 280 + $margin;
$l->elements[] = $text;
// Footer
// line
$line = new Shape();
$line->type = 1;
$line->borderThickness = 5;
$line->x = $margin;
$line->y = 660 + $margin;
$line->x2 = (int) ((37.8 * $l->width) - $margin);
$line->y2 = $line->y;
$l->elements[] = $line;
// manufacturer
$image = new Image();
$image->src = '/Modules/Labeling/Theme/icons/iso/3082.png';
$image->x = $margin - 15;
$image->y = 660 + $margin;
$image->x2 = $image->x + 150;
$image->y2 = 75 + $image->y;
$l->elements[] = $image;
// address
$text = new Text();
$text->text = 'Jingga e. K.';
$text->size = 30;
$text->x = 150 + $margin;
$text->y = 710 + $margin;
$l->elements[] = $text;
$text = new Text();
$text->text = 'Kirchstr. 33';
$text->size = 30;
$text->x = 150 + $margin;
$text->y = 760 + $margin;
$l->elements[] = $text;
$text = new Text();
$text->text = '61191 Rosbach';
$text->size = 30;
$text->x = 150 + $margin;
$text->y = 810 + $margin;
$l->elements[] = $text;
$text = new Text();
$text->text = 'Germany';
$text->size = 30;
$text->x = 150 + $margin;
$text->y = 860 + $margin;
$l->elements[] = $text;
// contact
$text = new Text();
$text->text = 'www.jingga.app';
$text->size = 30;
$text->x = 600 + $margin;
$text->y = 710 + $margin;
$l->elements[] = $text;
$text = new Text();
$text->text = 'info@jingga.app';
$text->size = 30;
$text->x = 600 + $margin;
$text->y = 760 + $margin;
$l->elements[] = $text;
$text = new Text();
$text->text = '+49 0123 456789';
$text->size = 30;
$text->x = 600 + $margin;
$text->y = 810 + $margin;
$l->elements[] = $text;
// ce
$image = new Image();
$image->src = '/Modules/Labeling/Theme/icons/iso/ce_mark.png';
$image->x = 1400 + $margin;
$image->y = 680 + $margin;
$image->x2 = $image->x + 200;
$image->y2 = 200 + $image->y;
$l->elements[] = $image;
$text = new Text();
$text->text = '0123';
$text->size = 45;
$text->x = 1430 + $margin;
$text->y = 850 + $margin;
$l->elements[] = $text;
// qr
$qr = new QR('https://jingga.app', 200, 200);
$image = new Image();
$image->resource = $qr->get();
$image->x = 1620 + $margin;
$image->y = 680 + $margin;
$image->x2 = $image->x + 180;
$image->y2 = 180 + $image->y;
$l->elements[] = $image;
return $l;

View File

@ -5,11 +5,11 @@
"type": 2,
"subtype": 1,
"name": "Labeling",
"uri": "{/base}warehouse/labeling/list?{?}",
"uri": "{/base}/warehouse/labeling/label/list?{?}",
"target": "self",
"icon": null,
"order": 1,
"from": "Labelling",
"from": "Labeling",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 1001301001,
"children": [
@ -19,7 +19,7 @@
"type": 3,
"subtype": 1,
"name": "List",
"uri": "{/base}warehouse/labeling/list?{?}",
"uri": "{/base}/warehouse/labeling/label/list?{?}",
"target": "self",
"icon": null,
"order": 1,

80
Admin/Install/db.json Normal file
View File

@ -0,0 +1,80 @@
{
"labeling_layout": {
"name": "labeling_layout",
"fields": {
"labeling_layout_id": {
"name": "labeling_layout_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"labeling_layout_template": {
"name": "labeling_layout_template",
"type": "INT",
"null": true,
"default": null,
"foreignTable": "media",
"foreignKey": "media_id"
}
}
},
"labeling_layout_l11n": {
"name": "labeling_layout_l11n",
"fields": {
"labeling_layout_l11n_id": {
"name": "labeling_layout_l11n_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"labeling_layout_l11n_name": {
"name": "labeling_layout_l11n_name",
"type": "VARCHAR(255)",
"null": false
},
"labeling_layout_l11n_type": {
"name": "labeling_layout_l11n_type",
"type": "INT",
"null": false,
"foreignTable": "labeling_layout",
"foreignKey": "labeling_layout_id"
},
"labeling_layout_l11n_language": {
"name": "labeling_layout_l11n_language",
"type": "VARCHAR(2)",
"default": null,
"null": true,
"foreignTable": "language",
"foreignKey": "language_639_1"
}
}
},
"labeling_layout_item": {
"name": "labeling_layout_item",
"fields": {
"labeling_layout_item_id": {
"name": "labeling_layout_item_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"labeling_layout_item_src": {
"name": "labeling_layout_item_src",
"type": "INT",
"null": false,
"foreignTable": "labeling_layout",
"foreignKey": "labeling_layout_id"
},
"labeling_layout_item_dst": {
"name": "labeling_layout_item_dst",
"type": "INT",
"null": false,
"foreignTable": "itemmgmt_item",
"foreignKey": "itemmgmt_item_id"
}
}
}
}

View File

@ -0,0 +1,12 @@
[
{
"type": "layout",
"files": [
"/Modules/Labeling/Admin/Install/Media/layout01.php"
],
"l11n": {
"en": "Default 01",
"de": "Standard 01"
}
}
]

View File

@ -14,7 +14,15 @@ declare(strict_types=1);
namespace Modules\Labeling\Admin;
use phpOMS\Application\ApplicationAbstract;
use phpOMS\Config\SettingsInterface;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\HttpResponse;
use phpOMS\Module\InstallerAbstract;
use phpOMS\Module\ModuleInfo;
use phpOMS\System\MimeType;
use phpOMS\Uri\HttpUri;
use phpOMS\Utils\TestUtils;
/**
* Installer class.
@ -33,4 +41,101 @@ final class Installer extends InstallerAbstract
* @since 1.0.0
*/
public const PATH = __DIR__;
/**
* {@inheritdoc}
*/
public static function install(ApplicationAbstract $app, ModuleInfo $info, SettingsInterface $cfgHandler) : void
{
parent::install($app, $info, $cfgHandler);
/* Bill types */
$fileContent = \file_get_contents(__DIR__ . '/Install/layouts.json');
if ($fileContent === false) {
return;
}
/** @var array $types */
$layouts = \json_decode($fileContent, true);
if ($layouts === false) {
return;
}
self::createLabelLayouts($app, $layouts);
}
/**
* Install default bill types
*
* @param ApplicationAbstract $app Application
* @param array $layouts Default layouts
*
* @return array
*
* @since 1.0.0
*/
private static function createLabelLayouts(ApplicationAbstract $app, array $layouts) : array
{
$layoutModels = [];
/** @var \Modules\Labeling\Controller\ApiController $module */
$module = $app->moduleManager->getModuleInstance('Labeling');
$tempPath = __DIR__ . '/../../../temp/';
foreach ($layouts as $layout) {
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('title', \reset($layout['l11n']));
$request->setData('template', $layout);
foreach ($layout['files'] as $file) {
$filePath = __DIR__ . '/../../..' . $file;
\copy($filePath, $tempPath . \basename($file));
$request->addFile([
'size' => \filesize($tempPath . \basename($file)),
'name' => \basename($file),
'tmp_name' => $tempPath . \basename($file),
'error' => \UPLOAD_ERR_OK,
]);
}
$module->apiLabelLayoutCreate($request, $response);
$responseData = $response->get('');
if (!\is_array($responseData)) {
continue;
}
$layoutModel = !\is_array($responseData['response'])
? $responseData['response']->toArray()
: $responseData['response'];
$layoutModels[] = $layoutModel;
$isFirst = true;
foreach ($layout['l11n'] as $language => $l11n) {
if ($isFirst) {
$isFirst = false;
continue;
}
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('title', $l11n);
$request->setData('language', $language);
$request->setData('type', $layoutModel['id']);
$module->apiLabelLayoutL11nCreate($request, $response);
}
}
return $layoutModels;
}
}

View File

@ -6,9 +6,9 @@ use phpOMS\Account\PermissionType;
use phpOMS\Router\RouteVerb;
return [
'^.*/controlling/budget/dashboard.*$' => [
'^.*/warehouse/labeling/label/list.*$' => [
[
'dest' => '\Modules\Labeling\Controller\BackendController:viewBudgetingDashboard',
'dest' => '\Modules\Labeling\Controller\BackendController:viewLabelLayoutList',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,

View File

@ -0,0 +1,213 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Labeling\Controller;
use Modules\Labeling\Models\LabelLayoutMapper;
use Modules\Labeling\Models\LabelLayout;
use Modules\Labeling\Models\LabelLayoutL11nMapper;
use Modules\Media\Models\CollectionMapper;
use phpOMS\Localization\BaseStringL11n;
use phpOMS\Localization\ISO639x1Enum;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\NotificationLevel;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Model\Message\FormValidation;
/**
* Labeling class.
*
* @package Modules\Labeling
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
final class ApiController extends Controller
{
/**
* Api method to create layout article
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiLabelLayoutCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void
{
if (!empty($val = $this->validateLabelLayoutCreate($request))) {
$response->data['layout_create'] = new FormValidation($val);
$response->header->status = RequestStatusCode::R_400;
return;
}
$layout = $this->createLabelLayoutFromRequest($request);
$this->createModel($request->header->account, $layout, LabelLayoutMapper::class, 'layout', $request->getOrigin());
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'LabelLayout', 'LabelLayout successfully created', $layout);
}
/**
* Validate layout create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateLabelLayoutCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['title'] = !$request->hasData('title'))
) {
return $val;
}
return [];
}
/**
* Method to create item attribute from request.
*
* @param RequestAbstract $request Request
*
* @return LabelLayout
*
* @since 1.0.0
*/
private function createLabelLayoutFromRequest(RequestAbstract $request) : LabelLayout
{
$labelLayout = new LabelLayout();
$labelLayout->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN);
$path = '/Modules/Labeling/Templates/' . $request->getDataString('title');
$uploadedFiles = $request->files;
$uploaded = $this->app->moduleManager->get('Media')->uploadFiles(
names: [],
fileNames: [],
files: $uploadedFiles,
account: $request->header->account,
basePath: __DIR__ . '/../../../Modules/Media/Files' . $path,
virtualPath: $path,
);
$collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection(
$path,
$request->header->account,
__DIR__ . '/../../../Modules/Media/Files' . $path
);
// @todo: I think we need to add the uploaded files to the collection.
// The frontend should work without it because of some "smart" corrections (virtualPath), but it is not correct.
// In the db there should be a relationship defined, no?
// If that is the case, maybe we also need to adjust the api. Either the uploadFiles should create the collection (if specified)
// or the createRecursiveMediaCollection should have another parameter with all the files it should include.
// If that is the case we also need to fix many modules who are not creating a specifc collection/upload relation (News, Kanban, ....).
foreach ($uploaded as $file) {
$this->createModelRelation(
$request->header->account,
$collection->id,
$file->id,
CollectionMapper::class,
'sources',
'',
$request->getOrigin()
);
}
$labelLayout->template = $collection;
return $labelLayout;
}
/**
* Api method to create item attribute l11n
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiLabelLayoutL11nCreate(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : void
{
if (!empty($val = $this->validateLabelLayoutL11nCreate($request))) {
$response->data['label_layout_l11n_create'] = new FormValidation($val);
$response->header->status = RequestStatusCode::R_400;
return;
}
$labelLayoutL11n = $this->createLabelLayoutL11nFromRequest($request);
$this->createModel($request->header->account, $labelLayoutL11n, LabelLayoutL11nMapper::class, 'label_layout_l11n', $request->getOrigin());
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Localization successfully created', $labelLayoutL11n);
}
/**
* Method to create item attribute l11n from request.
*
* @param RequestAbstract $request Request
*
* @return BaseStringL11n
*
* @since 1.0.0
*/
private function createLabelLayoutL11nFromRequest(RequestAbstract $request) : BaseStringL11n
{
$labelLayoutL11n = new BaseStringL11n();
$labelLayoutL11n->ref = $request->getDataInt('layout') ?? 0;
$labelLayoutL11n->setLanguage(
$request->getDataString('language') ?? $request->header->l11n->language
);
$labelLayoutL11n->content = $request->getDataString('title') ?? '';
return $labelLayoutL11n;
}
/**
* Validate item attribute l11n create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateLabelLayoutL11nCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['title'] = !$request->hasData('title'))
|| ($val['layout'] = !$request->hasData('layout'))
) {
return $val;
}
return [];
}
}

View File

@ -14,6 +14,12 @@ declare(strict_types=1);
namespace Modules\Labeling\Controller;
use Modules\Labeling\Models\LabelLayoutMapper;
use phpOMS\Contract\RenderableInterface;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Views\View;
/**
* Budgeting controller class.
*
@ -24,4 +30,34 @@ namespace Modules\Labeling\Controller;
*/
final class BackendController extends Controller
{
/**
* Routing end-point for application behaviour.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return RenderableInterface
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewLabelLayoutList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/Labeling/Theme/Backend/layout-list');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response);
/** @var \Modules\Attribute\Models\AttributeType[] $attributes */
$layouts = LabelLayoutMapper::getAll()
->with('l11n')
->with('template')
->with('template/sources')
->where('l11n/language', $response->header->l11n->language)
->execute();
$view->data['layouts'] = $layouts;
return $view;
}
}

29
Models/Image.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
class Image
{
public int $x = 0;
public int $y = 0;
public float $ratio = 0.0;
public int $x2 = 0;
public int $y2 = 0;
public string $src = '';
public $resource = null;
public int $color = 0;
}

142
Models/Label.php Normal file
View File

@ -0,0 +1,142 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
class Label
{
public int $width = 50;
public int $height = 25;
public int $fillColor = -1;
public string $unit = 'cm';
public array $elements = [];
public function render()
{
$im = \imagecreatetruecolor((int) (37.8 * $this->width), (int) (37.8 * $this->height));
$bg = \imagecolorallocatealpha($im, 255, 255, 255, 0);
\imagefill($im, 0, 0, $bg);
/*
$black = \imagecolorallocate($im, 0, 0, 0);
\imagecolortransparent($im, $black);
\imagealphablending($im, false);
\imagesavealpha($im, true);
*/
foreach ($this->elements as $element) {
$color = 0;
if ($element instanceof Shape) {
if ($element->type === 1) {
// Line
if ($element->borderThickness === 1) {
\imageline($im, $element->x, $element->y, $element->x2, $element->y2, $color);
} else {
\imagefilledrectangle(
$im,
$element->x, $element->y,
$element->x2 + $element->borderThickness - 1, $element->y2 + $element->borderThickness - 1,
$color
);
}
} elseif ($element->type === 2) {
// Rectangle
\imagefilledrectangle(
$im,
$element->x, $element->y,
$element->x2 + $element->borderThickness, $element->y2 + $element->borderThickness,
$color
);
if ($element->fillColor === -1) {
\imagefilledrectangle(
$im,
$element->x + $element->borderThickness, $element->y + $element->borderThickness,
$element->x2, $element->y2,
$bg
);
}
} elseif ($element->type === 3) {
} elseif ($element->type === 4) {
}
} elseif ($element instanceof Text) {
\imagettftext($im, $element->size, 0, $element->x, $element->y, $color, $element->font, $element->text);
} elseif ($element instanceof Image) {
$in = $element->resource === null ? \imagecreatefrompng(__DIR__ . '/../../..' . $element->src) : $element->resource;
$srcW = \imagesx($in);
$srcH = \imagesy($in);
// should resize
// @todo: impl. skewing
if ($element->ratio !== 0.0 || $element->x2 !== 0 || $element->y2 !== 0) {
$ratio = $element->ratio;
if ($ratio === 0.0) {
$ratio = ($element->x2 - $element->x) / $srcW;
}
$newW = (int) ($srcW * $ratio);
$newH = (int) ($srcH * $ratio);
$newIn = \imagecreatetruecolor($newW, $newH);
\imagecolortransparent($newIn, \imagecolorallocatealpha($newIn, 0, 0, 0, 127));
\imagealphablending($newIn, false);
\imagesavealpha($newIn, true);
\imagecopyresampled(
$newIn, $in,
0, 0,
0, 0,
$newW, $newH,
$srcW, $srcH
);
$srcW = $newW;
$srcH = $newH;
\imagedestroy($in);
$in = $newIn;
}
$cut = \imagecreatetruecolor($srcW, $srcH);
\imagecopy($cut, $im, 0, 0, $element->x, $element->y, $srcW, $srcH);
\imagecopy($cut, $in, 0, 0, 0, 0, $srcW, $srcH);
\imagecopymerge(
$im, $cut,
$element->x, $element->y,
0, 0,
$srcW, $srcH,
100
);
\imagedestroy($in);
\imagedestroy($cut);
} else {
}
}
return $im;
}
}

104
Models/LabelLayout.php Normal file
View File

@ -0,0 +1,104 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
use Modules\Media\Models\Collection;
use phpOMS\Localization\BaseStringL11n;
use phpOMS\Localization\ISO639x1Enum;
/**
* Bill type enum.
*
* @package Modules\Labeling\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class LabelLayout implements \JsonSerializable
{
/**
* Id
*
* @var int
* @since 1.0.0
*/
public int $id = 0;
public ?Collection $template = null;
/**
* Localization
*
* @var string|BaseStringL11n
*/
protected string | BaseStringL11n $l11n;
/**
* Set l11n
*
* @param string|BaseStringL11n $l11n Tag article l11n
* @param string $lang Language
*
* @return void
*
* @since 1.0.0
*/
public function setL11n(string | BaseStringL11n $l11n, string $lang = ISO639x1Enum::_EN) : void
{
if ($l11n instanceof BaseStringL11n) {
$this->l11n = $l11n;
} elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) {
$this->l11n->content = $l11n;
$this->l11n->setLanguage($lang);
} else {
$this->l11n = new BaseStringL11n();
$this->l11n->content = $l11n;
$this->l11n->ref = $this->id;
$this->l11n->setLanguage($lang);
}
}
/**
* @return string
*
* @since 1.0.0
*/
public function getL11n() : string
{
if (!isset($this->l11n)) {
return '';
}
return $this->l11n instanceof BaseStringL11n ? $this->l11n->content : $this->l11n;
}
/**
* {@inheritdoc}
*/
public function toArray() : array
{
return [
'id' => $this->id,
];
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() : mixed
{
return $this->toArray();
}
}

View File

@ -0,0 +1,69 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
use phpOMS\Localization\BaseStringL11n;
/**
* Bill type mapper class.
*
* @package Modules\Labeling\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of BaseStringL11n
* @extends DataMapperFactory<T>
*/
final class LabelLayoutL11nMapper 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 = [
'labeling_layout_l11n_id' => ['name' => 'labeling_layout_l11n_id', 'type' => 'int', 'internal' => 'id'],
'labeling_layout_l11n_name' => ['name' => 'labeling_layout_l11n_name', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true],
'labeling_layout_l11n_type' => ['name' => 'labeling_layout_l11n_type', 'type' => 'int', 'internal' => 'ref'],
'labeling_layout_l11n_language' => ['name' => 'labeling_layout_l11n_language', 'type' => 'string', 'internal' => 'language'],
];
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'labeling_layout_l11n';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'labeling_layout_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,96 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
use Modules\Media\Models\CollectionMapper;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Labeling mapper class.
*
* @package Modules\Labeling\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of LabelLayout
* @extends DataMapperFactory<T>
*/
final class LabelLayoutMapper 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 = [
'labeling_layout_id' => ['name' => 'labeling_layout_id', 'type' => 'int', 'internal' => 'id'],
'labeling_layout_template' => ['name' => 'labeling_layout_template', 'type' => 'int', 'internal' => 'template'],
];
/**
* 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' => LabelLayoutL11nMapper::class,
'table' => 'labeling_layout_l11n',
'self' => 'labeling_layout_l11n_type',
'column' => 'content',
'external' => null,
],
];
/**
* 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 = [
'template' => [
'mapper' => CollectionMapper::class,
'external' => 'labeling_layout_template',
],
];
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = LabelLayout::class;
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'labeling_layout';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'labeling_layout_id';
}

30
Models/SettingsEnum.php Normal file
View File

@ -0,0 +1,30 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
use phpOMS\Stdlib\Base\Enum;
/**
* Module settings enum.
*
* @package Modules\Labeling\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
abstract class SettingsEnum extends Enum
{
public const DEFAULT_LABEL = '1005100001';
}

30
Models/Shape.php Normal file
View File

@ -0,0 +1,30 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
class Shape
{
public int $x = 0;
public int $y = 0;
public int $x2 = 0;
public int $y2 = 0;
public int $type = ShapeType::RECTANGLE;
public int $color = 0;
public int $borderThickness = 1;
public int $fillColor = -1;
}

36
Models/ShapeType.php Normal file
View File

@ -0,0 +1,36 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
use phpOMS\Stdlib\Base\Enum;
/**
* Shape type enum.
*
* @package Modules\Labeling\Models
* @license OMS License 2.0
* @link https://orange-management.org
* @since 1.0.0
*/
abstract class ShapeType extends Enum
{
public const LINE = 1;
public const RECTANGLE = 2;
public const CIRCLE = 3;
public const TRIANGLE = 4;
}

38
Models/Text.php Normal file
View File

@ -0,0 +1,38 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Labeling\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\Labeling\Models;
class Text
{
public int $x = 0;
public int $y = 0;
public int $x2 = 0;
public int $y2 = 0;
public int $size = 11;
public string $font = __DIR__ . '/../../../Resources/fonts/lato/Lato-Regular.ttf';
public string $text = '';
public int $color = 0;
// align (-1 = start, 0 = middle, 1 = end)
public int $alignX = -1;
public int $alignY = -1;
public bool $bold = false;
public bool $underline = false;
public bool $italic = false;
}

View File

@ -0,0 +1,12 @@
<?php
$layout = $this->data['layout'];
$template = \reset($layout->template->sources);
$label = include_once $template->getAbsolutePath();
if (isset($this->data['path'])) {
\imagepng($label->render(), $this->data['path']);
} else {
\imagepng($label->render());
}

View File

@ -0,0 +1,42 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\StockTaking
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
echo $this->data['nav']->render();
$layout = \reset($this->data['layouts']);
$media = $layout->template;
$template = \reset($media->sources);
$layout = include_once $template->getAbsolutePath();
ob_start();
\imagepng($layout->render());
$imageData = ob_get_clean();
$imageBase64 = base64_encode($imageData);
// Get the image MIME type
$imageType = 'image/png'; // Assuming JPEG format in this example
// Generate the data URI for the inline image
$inlineImage = 'data:' . $imageType . ';base64,' . $imageBase64;
?>
<div class="row">
<div class="col-xs-12 col-md-6">
<div class="portlet">
<img style="width: 100%" src="<?php echo $inlineImage; ?>" alt="Inline Image">
</div>
</div>
</div>

View File

@ -1,15 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\StockTaking
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
echo $this->data['nav']->render();

BIN
Theme/icons/iso/0001.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
Theme/icons/iso/0002.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
Theme/icons/iso/0003.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
Theme/icons/iso/0004.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
Theme/icons/iso/0005.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Theme/icons/iso/0006.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
Theme/icons/iso/0007.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
Theme/icons/iso/0008.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
Theme/icons/iso/0009.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
Theme/icons/iso/0010.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
Theme/icons/iso/0011.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
Theme/icons/iso/0012.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
Theme/icons/iso/0013.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
Theme/icons/iso/0014.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
Theme/icons/iso/0015.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

BIN
Theme/icons/iso/0016.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
Theme/icons/iso/0017.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
Theme/icons/iso/0018.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
Theme/icons/iso/0019.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
Theme/icons/iso/0020.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
Theme/icons/iso/0021.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
Theme/icons/iso/0022.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
Theme/icons/iso/0023.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
Theme/icons/iso/0024.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
Theme/icons/iso/0025.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Theme/icons/iso/0026.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
Theme/icons/iso/0027.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
Theme/icons/iso/0028.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
Theme/icons/iso/0029.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
Theme/icons/iso/0030.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Theme/icons/iso/0031.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
Theme/icons/iso/0032.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Theme/icons/iso/0033.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
Theme/icons/iso/0034.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
Theme/icons/iso/0034A.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
Theme/icons/iso/0034B.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
Theme/icons/iso/0035.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
Theme/icons/iso/0036.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
Theme/icons/iso/0037.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
Theme/icons/iso/0038.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
Theme/icons/iso/0039.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
Theme/icons/iso/0040.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
Theme/icons/iso/0041.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Theme/icons/iso/0042.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Theme/icons/iso/0043.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
Theme/icons/iso/0044.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
Theme/icons/iso/0045.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
Theme/icons/iso/0046.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
Theme/icons/iso/0047.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
Theme/icons/iso/0048.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
Theme/icons/iso/0049.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
Theme/icons/iso/0050.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
Theme/icons/iso/0051.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
Theme/icons/iso/0052.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

BIN
Theme/icons/iso/0053.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Theme/icons/iso/0054.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
Theme/icons/iso/0055.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
Theme/icons/iso/0056.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

BIN
Theme/icons/iso/0057.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
Theme/icons/iso/0058.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Theme/icons/iso/0059.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Theme/icons/iso/0060.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Theme/icons/iso/0061.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
Theme/icons/iso/0062.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
Theme/icons/iso/0063.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Theme/icons/iso/0064.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
Theme/icons/iso/0065.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
Theme/icons/iso/0066.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Theme/icons/iso/0067.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
Theme/icons/iso/0068.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
Theme/icons/iso/0069.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
Theme/icons/iso/0070.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
Theme/icons/iso/0071.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
Theme/icons/iso/0072.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
Theme/icons/iso/0073.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Some files were not shown because too many files have changed in this diff Show More