Backup
Some checks failed
Gitea Actions / Run-Tests-On-Amd64 (push) Failing after 39m16s
Gitea Actions / Merge (push) Successful in 6m32s
Gitea Actions / Run-Tests-On-Arm64 (push) Has been cancelled

This commit is contained in:
Thomas Peterson 2026-01-27 09:33:52 +01:00
parent a2187a48b8
commit a2fc107f26
53 changed files with 2076 additions and 1944 deletions

View File

@ -31,5 +31,3 @@ JWT_PASSPHRASE=f7754c7a99638fe7162a144825ddaea7
# postgresql+advisory://db_user:db_password@localhost/db_name
LOCK_DSN=flock
###< symfony/lock ###
MAILER_DSN=smtp://smtp4dev:25

2
src/new/.env.dev Normal file
View File

@ -0,0 +1,2 @@
MAILER_DSN=smtp://smtp4dev:25

View File

@ -50,6 +50,7 @@
"nicolab/php-ftp-client": "^1.4",
"oneup/uploader-bundle": "^5",
"oyejorge/less.php": "~1.5",
"paypal/paypal-checkout-sdk": "^1.0",
"paypal/paypal-server-sdk": "^2",
"phenx/php-font-lib": "^1.0",
"phpoffice/phpspreadsheet": "^1.28",

99
src/new/composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "6c648aadd2d1a32e81bdc58fd18f23cc",
"content-hash": "59f5c6fa85a2165c7a1dccb2f12e1e60",
"packages": [
{
"name": "apimatic/core",
@ -6288,6 +6288,59 @@
},
"time": "2025-09-24T15:06:41+00:00"
},
{
"name": "paypal/paypal-checkout-sdk",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/paypal/Checkout-PHP-SDK.git",
"reference": "19992ce7051ff9e47e643f28abb8cc1b3e5f1812"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paypal/Checkout-PHP-SDK/zipball/19992ce7051ff9e47e643f28abb8cc1b3e5f1812",
"reference": "19992ce7051ff9e47e643f28abb8cc1b3e5f1812",
"shasum": ""
},
"require": {
"paypal/paypalhttp": "1.0.1"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Sample\\": "samples/",
"PayPalCheckoutSdk\\": "lib/PayPalCheckoutSdk"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"https://github.com/paypal/Checkout-PHP-SDK/blob/master/LICENSE"
],
"authors": [
{
"name": "PayPal",
"homepage": "https://github.com/paypal/Checkout-PHP-SDK/contributors"
}
],
"description": "PayPal's PHP SDK for Checkout REST APIs",
"homepage": "http://github.com/paypal/Checkout-PHP-SDK/",
"keywords": [
"checkout",
"orders",
"payments",
"paypal",
"rest",
"sdk"
],
"support": {
"source": "https://github.com/paypal/Checkout-PHP-SDK/tree/1.0.2"
},
"abandoned": "paypal/paypal-server-sdk",
"time": "2021-09-21T20:57:38+00:00"
},
{
"name": "paypal/paypal-server-sdk",
"version": "2.1.0",
@ -6332,6 +6385,50 @@
},
"time": "2025-12-04T21:51:20+00:00"
},
{
"name": "paypal/paypalhttp",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/paypal/paypalhttp_php.git",
"reference": "7b09c89c80828e842c79230e7f156b61fbb68d25"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paypal/paypalhttp_php/zipball/7b09c89c80828e842c79230e7f156b61fbb68d25",
"reference": "7b09c89c80828e842c79230e7f156b61fbb68d25",
"shasum": ""
},
"require": {
"ext-curl": "*"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"wiremock-php/wiremock-php": "1.43.2"
},
"type": "library",
"autoload": {
"psr-4": {
"PayPalHttp\\": "lib/PayPalHttp"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PayPal",
"homepage": "https://github.com/paypal/paypalhttp_php/contributors"
}
],
"support": {
"issues": "https://github.com/paypal/paypalhttp_php/issues",
"source": "https://github.com/paypal/paypalhttp_php/tree/1.0.1"
},
"abandoned": true,
"time": "2021-09-14T21:35:26+00:00"
},
{
"name": "phenx/php-font-lib",
"version": "1.0.1",

View File

@ -474,7 +474,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
* datetime?: array{
* default_format?: scalar|null, // Default: "Y-m-d\\TH:i:sP"
* default_deserialization_formats?: list<scalar|null>,
* default_timezone?: scalar|null, // Default: "UTC"
* default_timezone?: scalar|null, // Default: "Europe/Berlin"
* cdata?: scalar|null, // Default: true
* },
* array_collection?: array{
@ -574,7 +574,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
* datetime?: array{
* default_format?: scalar|null, // Default: "Y-m-d\\TH:i:sP"
* default_deserialization_formats?: list<scalar|null>,
* default_timezone?: scalar|null, // Default: "UTC"
* default_timezone?: scalar|null, // Default: "Europe/Berlin"
* cdata?: scalar|null, // Default: true
* },
* array_collection?: array{

View File

@ -42,6 +42,7 @@ class ProductProductgroup
#[ORM\Id]
#[ORM\Column(name: 'articlegroup_id', type: 'integer')]
protected $group;
/**
* @return int
*/

View File

@ -1,4 +1,5 @@
<?php
namespace Plugin\Custom\PSC\Formular\Controller\Backend;
use Doctrine\ODM\MongoDB\DocumentManager;
@ -6,20 +7,19 @@ use Doctrine\ORM\EntityManagerInterface;
use Plugin\Custom\PSC\Formular\Document\Formular;
use Plugin\Custom\PSC\Formular\Form\Backend\Formular as WebForm;
use PSC\Shop\EntityBundle\Entity\Domain;
use PSC\Shop\ShippingBundle\Form\Backend\DeleteType;
use PSC\System\PluginBundle\Form\Chain\Field;
use PSC\System\SettingsBundle\Document\LogEntry;
use PSC\System\SettingsBundle\Service\Log;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use PSC\Shop\ShippingBundle\Form\Backend\DeleteType;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use PSC\System\SettingsBundle\Document\LogEntry;
use PSC\System\SettingsBundle\Service\Log;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Attribute\Route;
class SettingsController extends AbstractController
{
#[Template()]
#[Template('@PluginCustomPSCFormular/backend/settings/create.html.twig')]
#[Route('/formular', name: 'plugin_custom_psc_formular_backend_create')]
public function createAction(
Request $request,
@ -28,10 +28,8 @@ class SettingsController extends AbstractController
EntityManagerInterface $entityManager,
Field $fieldService,
SessionInterface $session,
Log $logService
)
{
Log $logService,
) {
$selectedShop = $shopService->getSelectedShop();
$formular = new Formular();
@ -45,33 +43,38 @@ class SettingsController extends AbstractController
$documentManager->flush();
$session->getFlashBag()->add(
'success',
'Formular \'' . $formular->getFormularname() . '\' has been created!'
'Formular \'' . $formular->getFormularname() . '\' has been created!',
);
$logService->createLogEntry(
$selectedShop,
$this->getUser(),
LogEntry::INFO,
SettingsController::class,
$formular->getFormularname(),
'Formular created',
);
$logService->createLogEntry($selectedShop, $this->getUser(), LogEntry::INFO, SettingsController::class, $formular->getFormularname(), "Formular created");
return $this->redirectToRoute('plugin_custom_psc_formular_backend_list');
}
return array('form' => $form->createView());
}
#[Template()]
#[Template('@PluginCustomPSCFormular/backend/settings/list.html.twig')]
#[Route('/list', name: 'plugin_custom_psc_formular_backend_list')]
public function listAction(
Request $request,
\PSC\System\SettingsBundle\Service\Shop $shopService,
DocumentManager $documentManager,
EntityManagerInterface $entityManager,
Field $fieldService
)
{
Field $fieldService,
) {
$selectedShop = $shopService->getSelectedShop();
/** @var Plugin\Custom\PSC\Formular\Document\Formular $formular */
$formular = $documentManager
->getRepository('Plugin\Custom\PSC\Formular\Document\Formular')
->findBy(array("shop" => (string)$selectedShop->getUid()));
->findBy(array('shop' => (string) $selectedShop->getUid()));
$domains = $entityManager
->getRepository(Domain::class)->getAllByShopId($selectedShop);
$domains = $entityManager->getRepository(Domain::class)->getAllByShopId($selectedShop);
if (count($domains) > 0) {
$domain = array_pop($domains)->getHost();
} else {
@ -81,7 +84,7 @@ class SettingsController extends AbstractController
return array('formular' => $formular, 'domain' => $domain);
}
#[Template()]
#[Template('@PluginCustomPSCFormular/backend/settings/edit.html.twig')]
#[Route('/edit/{id}', name: 'plugin_custom_psc_formular_backend_edit')]
public function editAction(
Request $request,
@ -91,14 +94,13 @@ class SettingsController extends AbstractController
Field $fieldService,
SessionInterface $session,
Log $logService,
$id
)
{
$id,
) {
$selectedShop = $shopService->getSelectedShop();
/** @var Plugin\Custom\PSC\Formular\Document\Formular $formular */
$formular = $documentManager
->getRepository('Plugin\Custom\PSC\Formular\Document\Formular')
->findOneBy(array("shop" => (string)$selectedShop->getUid(), "id" => $id));
->findOneBy(array('shop' => (string) $selectedShop->getUid(), 'id' => $id));
$form = $this->createForm(WebForm::class, $formular);
@ -108,31 +110,38 @@ class SettingsController extends AbstractController
$documentManager->flush();
$session->getFlashBag()->add(
'success',
'Formular \'' . $formular->getFormularname() . '\' has been updated!'
'Formular \'' . $formular->getFormularname() . '\' has been updated!',
);
$logService->createLogEntry(
$selectedShop,
$this->getUser(),
LogEntry::INFO,
SettingsController::class,
$formular->getFormularname(),
'Formular updated',
);
$logService->createLogEntry($selectedShop, $this->getUser(), LogEntry::INFO, SettingsController::class, $formular->getFormularname(), "Formular updated");
}
return array('form' => $form->createView());
}
#[Template()]
#[Template('@PluginCustomPSCFormular/backend/settings/delete.html.twig')]
#[Route('/delete/{id}', name: 'plugin_custom_psc_formular_backend_delete')]
public function deleteAction(
Request $request,
\PSC\System\SettingsBundle\Service\Shop $shopService,
DocumentManager $documentManager,
EntityManagerInterface $entityManager,
Field $fieldService, $id,
Field $fieldService,
$id,
SessionInterface $session,
Log $logService
)
{
Log $logService,
) {
$selectedShop = $shopService->getSelectedShop();
/** @var Plugin\Custom\PSC\Formular\Document\Formular $formular */
$formular = $documentManager
->getRepository('Plugin\Custom\PSC\Formular\Document\Formular')
->findOneBy(array("shop" => (string)$selectedShop->getUid(), "id" => $id));
->findOneBy(array('shop' => (string) $selectedShop->getUid(), 'id' => $id));
$form = $this->createForm(DeleteType::class);
@ -143,11 +152,15 @@ class SettingsController extends AbstractController
$title = $formular->getFormularname();
$documentManager->remove($formular);
$documentManager->flush();
$session->getFlashBag()->add(
'success',
'Formular \'' . $title . '\' has been deleted!'
$session->getFlashBag()->add('success', 'Formular \'' . $title . '\' has been deleted!');
$logService->createLogEntry(
$selectedShop,
$this->getUser(),
LogEntry::INFO,
SettingsController::class,
$title,
'Formular deleted',
);
$logService->createLogEntry($selectedShop, $this->getUser(), LogEntry::INFO, SettingsController::class, $title, "Formular deleted");
return $this->redirectToRoute('plugin_custom_psc_formular_backend_list');
}
return $this->redirectToRoute('plugin_custom_psc_formular_backend_list');
@ -156,7 +169,7 @@ class SettingsController extends AbstractController
//\var_dump($formular);
return array(
'cms' => $formular,
'form' => $form->createView()
'form' => $form->createView(),
);
}
}

View File

@ -8,9 +8,9 @@ use Gregwar\Captcha\CaptchaBuilder;
use Plugin\Custom\PSC\Formular\Document\Formular;
use Plugin\Custom\PSC\Formular\Event\Submit;
use PSC\Shop\QueueBundle\Service\Event\Manager;
use PSC\System\SettingsBundle\Service\Shop;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use PSC\System\SettingsBundle\Service\Shop;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@ -18,26 +18,26 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
#[Route('/formular')]
class StartController extends AbstractController
{
function __construct(
private readonly Shop $shopService,
private readonly DocumentManager $documentManager,
private readonly Manager $eventManager,
private readonly \Twig\Environment $template,
private HttpClientInterface $httpClient,
) {}
function __construct(private readonly Shop $shopService, private readonly DocumentManager $documentManager, private readonly Manager $eventManager, private readonly \Twig\Environment $template, private HttpClientInterface $httpClient)
{
}
#[Template()]
#[Template('@PluginCustomPSCFormular/start/start.html.twig')]
#[Route('/start/{id}', name: 'plugin_custom_psc_formular_frontend_start')]
public function startAction(Request $request, string $id)
{
$selectedShop = $this->shopService->getShopByDomain();
$shopDoc = $this->shopService->getMongoShopByDomain();
/** @var Formular $formular */
$formular = $this->documentManager
->getRepository('Plugin\Custom\PSC\Formular\Document\Formular')
->findOneBy(array("shop" => (string)$selectedShop->getUid(), "id" => $id));
->findOneBy(array('shop' => (string) $selectedShop->getUid(), 'id' => $id));
$captchaEnable = $formular->getCaptcha();
$friendlyCaptchaEnabled = $formular->getFriendlyCaptcha();
@ -58,50 +58,50 @@ class StartController extends AbstractController
$secretKey = $web2mailreCaptchasecret;
$ip = $_SERVER['REMOTE_ADDR'];
if ($request->isMethod('post')) {
if ($reCaptchaEnable) {
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=" . $secretKey . "&response=" . $_POST['g-recaptcha-response'] . "&remoteip=" . $ip);
$response = file_get_contents(
'https://www.google.com/recaptcha/api/siteverify?secret='
. $secretKey
. '&response='
. $_POST['g-recaptcha-response']
. '&remoteip='
. $ip,
);
$responseKeys = json_decode($response, true);
// Spamversuch
if (intval($responseKeys["success"]) !== 1) {
if (intval($responseKeys['success']) !== 1) {
$nospam = false;
} else {
$nospam = true;
}
} elseif ($friendlyCaptchaEnabled) {
$request = $this->httpClient->request('POST',
'https://api.friendlycaptcha.com/api/v1/siteverify',
[
$request = $this->httpClient->request('POST', 'https://api.friendlycaptcha.com/api/v1/siteverify', [
'body' => [
'solution' => $_POST['frc-captcha-solution'],
'secret' => $shopDoc->getPluginSettingModule('friendlycaptcha', 'secret'),
'sitekey' => $shopDoc->getPluginSettingModule('friendlycaptcha', 'siteKey')
]
]
);
'sitekey' => $shopDoc->getPluginSettingModule('friendlycaptcha', 'siteKey'),
],
]);
$response = $request->toArray();
if (intval($response["success"]) !== 1) {
if (intval($response['success']) !== 1) {
$nospam = false;
} else {
$nospam = true;
}
} elseif ($captchaFoxEnabled) {
$request = $this->httpClient->request('POST',
'https://api.captchafox.com/siteverify',
[
$request = $this->httpClient->request('POST', 'https://api.captchafox.com/siteverify', [
'body' => [
'response' => $_POST['cf-captcha-response'],
'secret' => $shopDoc->getPluginSettingModule('captchafox', 'secretkey'),
'sitekey' => $shopDoc->getPluginSettingModule('captchafox', 'publickey')
]
]
);
'sitekey' => $shopDoc->getPluginSettingModule('captchafox', 'publickey'),
],
]);
$response = $request->toArray();
if (intval($response["success"]) !== 1) {
if (intval($response['success']) !== 1) {
$nospam = false;
} else {
$nospam = true;
@ -109,7 +109,7 @@ class StartController extends AbstractController
} elseif ($captchaEnable) {
$phrase = $request->getSession()->get('contact_captcha', false);
if($phrase && $phrase == $request->get('captcha', "") || $request->get('email_confirm', "") != "") {
if ($phrase && $phrase == $request->get('captcha', '') || $request->get('email_confirm', '') != '') {
$nospam = true;
} else {
$nospam = false;
@ -120,10 +120,10 @@ class StartController extends AbstractController
}
if ($nospam) {
$outarray = array();
$text = "";
$text = '';
foreach ($_POST as $key => $formulardata) {
if ($key != "g-recaptcha-response") {
$text .= $key . ": " . $formulardata . "<br />";
if ($key != 'g-recaptcha-response') {
$text .= $key . ': ' . $formulardata . '<br />';
}
}
if (preg_match_all("/\b\w[\w|\.|\-]+@\w[\w|\.|\-]+\.[a-zA-Z]{2,4}\b/", $text, $emails))
@ -141,7 +141,7 @@ class StartController extends AbstractController
if (isset($emails[0]) && is_string($emails[0])) {
$notify->setSenderMail($emails[0]);
} else {
$notify->setSenderMail("");
$notify->setSenderMail('');
}
$this->eventManager->addJob($notify);
@ -149,23 +149,31 @@ class StartController extends AbstractController
$spam = false;
}
} else {
}
$text = $this->template->createTemplate($web2maileditor);
$captchaCode = "";
$captchaCode = '';
if ($captchaEnable) {
$builder = new CaptchaBuilder;
$builder = new CaptchaBuilder();
$builder->build();
$captchaCode = '<img src="' . $builder->inline() . '"/>';
$request->getSession()->set('contact_captcha', $builder->getPhrase());
} elseif ($reCaptchaEnable) {
$captchaCode = '<div class="g-recaptcha" data-sitekey="'.$web2mailreCaptchawebcode.'" data-callback="enableBtn"></div>';
$captchaCode =
'<div class="g-recaptcha" data-sitekey="'
. $web2mailreCaptchawebcode
. '" data-callback="enableBtn"></div>';
} elseif ($friendlyCaptchaEnabled) {
$captchaCode = '<div class="frc-captcha" data-sitekey="' . $shopDoc->getPluginSettingModule('friendlycaptcha', 'siteKey') . '"></div>';
$captchaCode =
'<div class="frc-captcha" data-sitekey="'
. $shopDoc->getPluginSettingModule('friendlycaptcha', 'siteKey')
. '"></div>';
} elseif ($captchaFoxEnabled) {
$captchaCode = '<div class="captchafox" data-sitekey="' . $shopDoc->getPluginSettingModule('captchafox', 'publickey') . '"></div>';
$captchaCode =
'<div class="captchafox" data-sitekey="'
. $shopDoc->getPluginSettingModule('captchafox', 'publickey')
. '"></div>';
}
$text = $text->render(['captcha' => $captchaCode, 'data' => $_POST, 'captchaWrong' => $captchaWrong]);
@ -181,5 +189,5 @@ class StartController extends AbstractController
'mailadresse' => $mailadresse,
);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace Plugin\Custom\PSC\GoogleProduktXMLExport\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations\EmbeddedDocument;
use Doctrine\ODM\MongoDB\Mapping\Annotations\Field;
#[EmbeddedDocument]
class Export
{
#[Field(type: 'string')]
protected $shop;
/**
* @return string
*/
public function getShop()
{
return $this->shop;
}
/**
* @param string $shop
*/
public function setShop($shop)
{
$this->shop = $shop;
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Plugin\Custom\PSC\Gutschein\Controller;
use PSC\Shop\EntityBundle\Document\Order;
use PSC\Shop\OrderBundle\Model\Base;
use PSC\Shop\OrderBundle\Model\Order\Position;
use PSC\System\SettingsBundle\Service\Shop;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class OrderController extends AbstractController
{
#[Template('@PluginCustomPSCGutschein/order/detail.html.twig')]
public function detailAction(?Base $order, ?Position $position): array
{
return ['position' => $position];
}
}

View File

@ -1,87 +0,0 @@
<?php
namespace Plugin\Custom\PSC\Gutschein\Form\Field;
use PSC\Shop\EntityBundle\Entity\Product;
use PSC\System\PluginBundle\Form\Interfaces\Field;
use PSC\System\SettingsBundle\Service\General;
use PSC\System\SettingsBundle\Service\Tax;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
class Calc implements Field
{
public function __construct(
protected General $generalService,
protected Tax $taxService,
) {}
public function getTemplate()
{
return '@PluginCustomPSCGutschein/form/field/calc.html.twig';
}
public function getModule()
{
return Field::Product;
}
public function formPreSubmit(FormEvent $event)
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$product = $options['product'];
$builder->add('minAmount', MoneyType::class, [
'required' => false,
'label' => 'Minimaler Gutscheinwert',
'data' => 10.00,
])->add('maxAmount', MoneyType::class, [
'required' => false,
'label' => 'Maximaler Gutscheinwert',
'data' => 500.00,
])->add('defaultAmount', MoneyType::class, [
'required' => false,
'label' => 'Voreingestellter Wert',
'data' => 50.00,
])->add('validityMonths', IntegerType::class, [
'required' => false,
'label' => 'Gültigkeit (Monate)',
'data' => 12,
]);
if ($product) {
$builder->get('defaultAmount')->setData($product->gutschein['defaultAmount'] ?? null);
$builder->get('minAmount')->setData($product->gutschein['minAmount'] ?? null);
$builder->get('maxAmount')->setData($product->gutschein['maxAmount'] ?? null);
$builder->get('validityMonths')->setData($product->gutschein['validityMonths'] ?? null);
}
return $builder;
}
public function getGroup()
{
return \Plugin\Custom\PSC\Gutschein\Form\Group\Calc::GROUP_ID;
}
public function formPostSetData(FormEvent $event)
{
}
public function formPostSubmit(FormEvent $event)
{
}
public function formPreSetData(FormEvent $event)
{
}
public function formSubmit(FormEvent $event)
{
}
}

View File

@ -14,24 +14,24 @@ use Symfony\Component\Form\FormEvent;
class ProductSettings implements Field
{
public function __construct(
private readonly EntityManagerInterface $entityManager
private readonly EntityManagerInterface $entityManager,
) {}
public function getTemplate()
public function getTemplate(): string
{
return '@PluginCustomPSCGutschein/form/field/product_settings.html.twig';
}
public function getModule()
public function getModule(): int
{
return Field::Product;
}
public function formPreSubmit(FormEvent $event)
public function formPreSubmit(FormEvent $event): void
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
public function buildForm(FormBuilderInterface $builder, array $options): FormBuilderInterface
{
$product = $options['product'];
@ -45,11 +45,7 @@ class ProductSettings implements Field
foreach ($vouchers as $voucher) {
$unusedCount = $voucherItemRepo->countUnusedCodes($voucher->getUid());
$label = sprintf(
'%s (%d verfügbare Codes)',
$voucher->getTitle(),
$unusedCount
);
$label = sprintf('%s (%d verfügbare Codes)', $voucher->getTitle(), $unusedCount);
$choices[$label] = (string) $voucher->getUid();
}
@ -69,21 +65,22 @@ class ProductSettings implements Field
return $builder;
}
public function getGroup()
public function getGroup(): string
{
return \Plugin\Custom\PSC\Gutschein\Form\Group\Calc::GROUP_ID;
}
public function formPostSetData(FormEvent $event)
public function formPostSetData(FormEvent $event): void
{
}
public function formPostSubmit(FormEvent $event)
public function formPostSubmit(FormEvent $event): void
{
/** @var Product $product */
$product = $event->getData();
$form = $event->getForm();
$product->setPrice(0);
$product->setCanBuyWithNoPrice(1);
if ($form->has('linkedVoucherUid')) {
$linkedVoucherUid = $form->get('linkedVoucherUid')->getData();
@ -103,11 +100,11 @@ class ProductSettings implements Field
}
}
public function formPreSetData(FormEvent $event)
public function formPreSetData(FormEvent $event): void
{
}
public function formSubmit(FormEvent $event)
public function formSubmit(FormEvent $event): void
{
}
}

View File

@ -6,27 +6,11 @@ use PSC\Shop\OrderBundle\Model\Order\Position\IProductTypeObject;
class ProductSpecialObject implements IProductTypeObject
{
private int $taxClass = 1900; // 19% VAT
private int $taxClass = 0; // 19% VAT
private array $params = [];
// Backend configuration (set by admin)
private float $minAmount = 10.00;
private float $maxAmount = 500.00;
private ?float $defaultAmount = 50.00;
private int $validityMonths = 12;
// Customer-entered data
private float $voucherAmount = 0;
private string $recipientName = '';
private string $greetingMessage = '';
private string $deliveryMethod = 'digital';
// Generated data
private string $voucherCode = '';
private ?\DateTime $expirationDate = null;
// VoucherBundle integration
private ?int $linkedVoucherUid = null;
private ?string $voucherCode = '';
public function getName(): string
{
@ -42,14 +26,8 @@ class ProductSpecialObject implements IProductTypeObject
{
return [
'params' => $this->params,
'voucherAmount' => $this->voucherAmount,
'recipientName' => $this->recipientName,
'greetingMessage' => $this->greetingMessage,
'deliveryMethod' => $this->deliveryMethod,
'voucherCode' => $this->voucherCode,
'expirationDate' => $this->expirationDate?->format('Y-m-d H:i:s'),
'validityMonths' => $this->validityMonths,
'linkedVoucherUid' => $this->linkedVoucherUid,
'voucherCode' => $this->voucherCode,
];
}
@ -74,106 +52,6 @@ class ProductSpecialObject implements IProductTypeObject
$this->params = $params;
}
public function getMinAmount(): float
{
return $this->minAmount;
}
public function setMinAmount(float $minAmount): void
{
$this->minAmount = $minAmount;
}
public function getMaxAmount(): float
{
return $this->maxAmount;
}
public function setMaxAmount(float $maxAmount): void
{
$this->maxAmount = $maxAmount;
}
public function getDefaultAmount(): ?float
{
return $this->defaultAmount;
}
public function setDefaultAmount(?float $defaultAmount): void
{
$this->defaultAmount = $defaultAmount;
}
public function getValidityMonths(): int
{
return $this->validityMonths;
}
public function setValidityMonths(int $validityMonths): void
{
$this->validityMonths = $validityMonths;
}
public function getVoucherAmount(): float
{
return $this->voucherAmount;
}
public function setVoucherAmount(float $voucherAmount): void
{
$this->voucherAmount = $voucherAmount;
}
public function getRecipientName(): string
{
return $this->recipientName;
}
public function setRecipientName(string $recipientName): void
{
$this->recipientName = $recipientName;
}
public function getGreetingMessage(): string
{
return $this->greetingMessage;
}
public function setGreetingMessage(string $greetingMessage): void
{
$this->greetingMessage = $greetingMessage;
}
public function getDeliveryMethod(): string
{
return $this->deliveryMethod;
}
public function setDeliveryMethod(string $deliveryMethod): void
{
$this->deliveryMethod = $deliveryMethod;
}
public function getVoucherCode(): string
{
return $this->voucherCode;
}
public function setVoucherCode(string $voucherCode): void
{
$this->voucherCode = $voucherCode;
}
public function getExpirationDate(): ?\DateTime
{
return $this->expirationDate;
}
public function setExpirationDate(?\DateTime $expirationDate): void
{
$this->expirationDate = $expirationDate;
}
public function getLinkedVoucherUid(): ?int
{
return $this->linkedVoucherUid;
@ -183,4 +61,14 @@ class ProductSpecialObject implements IProductTypeObject
{
$this->linkedVoucherUid = $linkedVoucherUid;
}
public function getVoucherCode(): string
{
return $this->voucherCode;
}
public function setVoucherCode(string $code): void
{
$this->voucherCode = $code;
}
}

View File

@ -14,10 +14,6 @@ services:
tags:
- { name: psc.backend.custom.groups, productType: 9 }
Plugin\Custom\PSC\Gutschein\Form\Field\Calc:
tags:
- { name: psc.backend.custom.fields, productType: 9 }
Plugin\Custom\PSC\Gutschein\Form\Field\ProductSettings:
tags:
- { name: psc.backend.custom.fields, productType: 9 }

View File

@ -1,44 +0,0 @@
<div class="card mb-3">
<div class="card-header">
<h5>Gutschein-Konfiguration</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
{{ form_label(form.validityMonths) }}
{{ form_widget(form.validityMonths) }}
<small class="form-text text-muted">Gültigkeitsdauer ab Kaufdatum</small>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
{{ form_label(form.minAmount) }}
{{ form_widget(form.minAmount) }}
<small class="form-text text-muted">Mindestbetrag</small>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
{{ form_label(form.defaultAmount) }}
{{ form_widget(form.defaultAmount) }}
<small class="form-text text-muted">Vorauswahl</small>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
{{ form_label(form.maxAmount) }}
{{ form_widget(form.maxAmount) }}
<small class="form-text text-muted">Maximalbetrag</small>
</div>
</div>
</div>
<div class="alert alert-info">
<strong>Hinweis:</strong> Kunden können beim Kauf einen beliebigen Betrag zwischen Minimal- und Maximalbetrag wählen.
</div>
</div>
</div>

View File

@ -4,9 +4,9 @@
</div>
<div class="card-body">
<div class="form-group">
{{ form_label(form.linkedVoucherUid) }}
{{ form_widget(form.linkedVoucherUid, {'attr': {'class': 'form-control'}}) }}
{{ form_help(form.linkedVoucherUid) }}
{{ form_label(form.gutschein.linkedVoucherUid) }}
{{ form_widget(form.gutschein.linkedVoucherUid, {'attr': {'class': 'form-control'}}) }}
{{ form_help(form.gutschein.linkedVoucherUid) }}
</div>
<div class="alert alert-info mt-3">
@ -15,12 +15,12 @@
<li>Wählen Sie einen Gutschein aus dem VoucherBundle aus, um vordefinierte Codes zu verwenden</li>
<li>Bei jedem Verkauf wird automatisch ein Code aus dem Voucher zugewiesen</li>
<li>Der Code wird als "verwendet" markiert und mit dem Kunden verknüpft</li>
<li>Wenn keine Codes mehr verfügbar sind, wird automatisch ein Zufallscode generiert</li>
<li>Wenn keine Codes mehr verfügbar sind, kann das Produkt nicht mehr bestellt werden</li>
<li>Ohne Verknüpfung werden weiterhin Zufallscodes generiert (Standard-Verhalten)</li>
</ul>
</div>
{% if form.linkedVoucherUid.vars.value %}
{% if form.gutschein.linkedVoucherUid.vars.value %}
<div class="alert alert-success">
<strong>Aktuell verknüpft:</strong> Dieser Gutschein verwendet Codes aus dem ausgewählten VoucherBundle-Gutschein.
</div>

View File

@ -0,0 +1 @@
<h4>Gutscheincode: {{ position.product.specialProductTypeObject.voucherCode }}</h4>

View File

@ -0,0 +1,32 @@
<?php
namespace Plugin\Custom\PSC\Gutschein\Section;
use PSC\System\PluginBundle\Form\Section;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
#[AutoconfigureTag('psc.backend.custom.section')]
class OrderPositionDetail extends Section
{
public const SECTION_ID = 'gutschein';
public function __construct()
{
$this->title = 'Gutschein';
}
public function getModule()
{
return Section::OrderPositionDetail;
}
public function getId()
{
return self::SECTION_ID;
}
public function getController()
{
return 'Plugin\\Custom\\PSC\\Gutschein\\Controller\\OrderController::detailAction';
}
}

View File

@ -2,16 +2,16 @@
namespace Plugin\Custom\PSC\Gutschein\Transformer;
use Plugin\Custom\PSC\Gutschein\Model\ProductSpecialObject;
use PSC\Shop\EntityBundle\Entity\Orderpos;
use PSC\Shop\OrderBundle\Transformer\Order\Position\IPositionTransformer;
use Plugin\Custom\PSC\Gutschein\Model\ProductSpecialObject;
class Position implements IPositionTransformer
{
public function fromDb(
\PSC\Shop\OrderBundle\Model\Order\Position $position,
Orderpos $posEntity,
\PSC\Shop\EntityBundle\Document\Position $posDoc
\PSC\Shop\EntityBundle\Document\Position $posDoc,
) {
$obj = new ProductSpecialObject();
@ -20,37 +20,19 @@ class Position implements IPositionTransformer
if (isset($data['params'])) {
$obj->setParams($data['params']);
}
if (isset($data['voucherAmount'])) {
$obj->setVoucherAmount($data['voucherAmount']);
}
if (isset($data['recipientName'])) {
$obj->setRecipientName($data['recipientName']);
}
if (isset($data['greetingMessage'])) {
$obj->setGreetingMessage($data['greetingMessage']);
}
if (isset($data['deliveryMethod'])) {
$obj->setDeliveryMethod($data['deliveryMethod']);
if (isset($data['linkedVoucherUid'])) {
$obj->setLinkedVoucherUid($data['linkedVoucherUid']);
}
if (isset($data['voucherCode'])) {
$obj->setVoucherCode($data['voucherCode']);
}
if (isset($data['expirationDate'])) {
$obj->setExpirationDate(new \DateTime($data['expirationDate']));
}
if (isset($data['validityMonths'])) {
$obj->setValidityMonths($data['validityMonths']);
}
$position->getProduct()->setSpecialProductTypeObject($obj);
}
public function toDb(
\PSC\Shop\OrderBundle\Model\Order\Position $position,
Orderpos $posEntity,
\PSC\Shop\EntityBundle\Document\Position $posDoc
\PSC\Shop\EntityBundle\Document\Position $posDoc,
) {
// Position data is stored via getPositionData() in ProductSpecialObject
// No additional transformation needed here
}
}

View File

@ -72,6 +72,7 @@ class GetSettings
$marker->setLabel("Dot {$i}");
$marker->setX(0.0);
$marker->setY(0.0);
$marker->setSize(2.0); // 2mm diameter
$ocrMarkers[] = $marker;
}
$textMarker = new \Plugin\Custom\PSC\LaufkartenLayouter\Model\OcrMarker();
@ -79,12 +80,14 @@ class GetSettings
$textMarker->setLabel('Text Position');
$textMarker->setX(0.0);
$textMarker->setY(0.0);
$textMarker->setSize(8.0); // 8pt font size
$ocrMarkers[] = $textMarker;
$triangleMarker = new \Plugin\Custom\PSC\LaufkartenLayouter\Model\OcrMarker();
$triangleMarker->setType('triangle');
$triangleMarker->setLabel('Triangle (Pfeil nach oben)');
$triangleMarker->setX(0.0);
$triangleMarker->setY(0.0);
$triangleMarker->setSize(3.0); // 3mm side length
$ocrMarkers[] = $triangleMarker;
$setting->setOcrMarkers($ocrMarkers);
}

View File

@ -18,6 +18,111 @@ use Symfony\Component\Routing\Attribute\Route;
class Preview
{
/**
* Get RGB color values for background
*/
private function getBackgroundColor(string $color): array
{
return match ($color) {
'red' => [255, 0, 0],
'green' => [0, 255, 0],
'blue' => [0, 0, 255],
'yellow' => [255, 255, 0],
'white' => [255, 255, 255], // Changed from 'black' to 'white'
default => [255, 255, 255], // Default: white background
};
}
/**
* Render OCR markers on the current page
*/
private function renderOcrMarkers(
Fpdi $pdf,
array $ocrMarkers,
array $configData = [],
array $currentFile = [],
): void {
if (empty($ocrMarkers)) {
return;
}
// Save current graphics state
$pdf->StartTransform();
foreach ($ocrMarkers as $marker) {
$x = $marker['x'] ?? 0;
$y = $marker['y'] ?? 0;
$type = $marker['type'] ?? 'dot';
$size = $marker['size'] ?? 2.0; // Default size
// Set black color for markers
$pdf->SetDrawColor(0, 0, 0);
$pdf->SetFillColor(0, 0, 0);
switch ($type) {
case 'dot':
// Draw a filled circle (dot) with configurable diameter
$radius = $size / 2; // Convert diameter to radius
$pdf->Circle($x, $y, $radius, 0, 360, 'F');
break;
case 'text':
// Build dynamic text with content area info and tab number
$contentAreaWidth = $configData['contentAreaWidth'] ?? 0;
$contentAreaHeight = $configData['contentAreaHeight'] ?? 0;
$contentAreaLeft = $configData['contentAreaLeft'] ?? 0;
$contentAreaTop = $configData['contentAreaTop'] ?? 0;
$tabNumber = $currentFile['tabNumber'] ?? '?';
$unit = $configData['unit'] ?? 'mm';
$text = sprintf(
'Inhalt: %.1f x %.1f %s @ (%.1f, %.1f) | Tab: %s',
$contentAreaWidth,
$contentAreaHeight,
$unit,
$contentAreaLeft,
$contentAreaTop,
$tabNumber,
);
// Save state and rotate text 90° counter-clockwise (vertical, bottom to top)
$pdf->StartTransform();
// Rotate 90° counter-clockwise around point (x, y)
$pdf->Rotate(90, $x, $y);
// Draw text with configurable font size
$pdf->SetFont('helvetica', 'B', $size); // size is font size in pt
$pdf->SetTextColor(0, 0, 0);
$pdf->Text($x, $y, $text);
// Restore transformation
$pdf->StopTransform();
break;
case 'triangle':
// Draw an upward-pointing triangle with configurable side length
$height = ($size * sqrt(3)) / 2; // Height of equilateral triangle
// Calculate triangle points (pointing up)
$points = [
$x,
$y - ((2 * $height) / 3), // Top point
$x - ($size / 2),
$y + ($height / 3), // Bottom left
$x + ($size / 2),
$y + ($height / 3), // Bottom right
];
$pdf->Polygon($points, 'F');
break;
}
}
// Restore graphics state
$pdf->StopTransform();
}
#[Response(response: 200, description: 'PDF preview generated successfully')]
#[Response(response: 400, description: 'Bad request')]
#[Route('/preview', name: 'plugin_custom_psc_laufkartenlayouter_preview', methods: ['POST'])]
@ -84,23 +189,25 @@ class Preview
$configData['contentAreaHeight'],
false,
);
$pdf->SetFont('helvetica', '', $fontSize);
$pdf->SetTextColor(0, 0, 0);
if ($file['color'] == 'red') {
$pdf->SetTextColor(255, 0, 0);
}
if ($file['color'] == 'green') {
$pdf->SetTextColor(0, 255, 0);
}
if ($file['color'] == 'blue') {
$pdf->SetTextColor(0, 0, 255);
}
if ($file['color'] == 'yellow') {
$pdf->SetTextColor(255, 255, 0);
}
dump($file);
dump($configData);
$tab = array_filter($configData['tabPositions'], function ($item) use ($file) {
return $item['tabNumber'] == $file['tabNumber'] ? $item : null;
})[0];
});
dump($tab);
$tab = array_shift($tab);
// Render OCR markers on this page
$this->renderOcrMarkers($pdf, $configData['ocrMarkers'] ?? [], $configData, $file);
// Draw colored background rectangle
$bgColor = $this->getBackgroundColor($file['color']);
$pdf->SetFillColor($bgColor[0], $bgColor[1], $bgColor[2]);
$pdf->Rect($tab['x'], $tab['y'], $tab['width'], $tab['height'], 'F');
// Draw text in black
$pdf->SetFont('helvetica', '', $fontSize);
$pdf->SetTextColor(0, 0, 0); // Always black text
$pdf->MultiCell(
$tab['width'],
$tab['height'],
@ -128,20 +235,21 @@ class Preview
$configData['contentAreaHeight'],
false,
);
// Render OCR markers on this page
$this->renderOcrMarkers($pdf, $configData['ocrMarkers'] ?? [], $configData, $file);
// Calculate position for page 2 (mirrored)
$xPos = $configData['width'] - $tab['width'] - $tab['x'];
// Draw colored background rectangle
$bgColor = $this->getBackgroundColor($file['color']);
$pdf->SetFillColor($bgColor[0], $bgColor[1], $bgColor[2]);
$pdf->Rect($xPos, $tab['y'], $tab['width'], $tab['height'], 'F');
// Draw text in black
$pdf->SetFont('helvetica', '', $fontSize);
$pdf->SetTextColor(0, 0, 0);
if ($file['color'] == 'red') {
$pdf->SetTextColor(255, 0, 0);
}
if ($file['color'] == 'green') {
$pdf->SetTextColor(0, 255, 0);
}
if ($file['color'] == 'blue') {
$pdf->SetTextColor(0, 0, 255);
}
if ($file['color'] == 'yellow') {
$pdf->SetTextColor(255, 255, 0);
}
$pdf->SetTextColor(0, 0, 0); // Always black text
$pdf->MultiCell(
$tab['width'],
$tab['height'],
@ -150,7 +258,7 @@ class Preview
'C',
false,
1,
($configData['width'] - $tab['width']) - $tab['x'],
$xPos,
$tab['y'],
true,
0,
@ -170,24 +278,26 @@ class Preview
$configData['contentAreaHeight'],
false,
);
$pdf->SetFont('helvetica', '', $fontSize);
$pdf->SetTextColor(0, 0, 0);
if ($file['color'] == 'red') {
$pdf->SetTextColor(255, 0, 0);
}
if ($file['color'] == 'green') {
$pdf->SetTextColor(0, 255, 0);
}
if ($file['color'] == 'blue') {
$pdf->SetTextColor(0, 0, 255);
}
if ($file['color'] == 'yellow') {
$pdf->SetTextColor(255, 255, 0);
}
if ($frontSide) {
$tab = array_filter($configData['tabPositions'], function ($item) use ($file) {
return $item['tabNumber'] == $file['tabNumber'] ? $item : null;
})[0];
// Render OCR markers on this page
$this->renderOcrMarkers($pdf, $configData['ocrMarkers'] ?? [], $configData, $file);
// Get background color
$bgColor = $this->getBackgroundColor($file['color']);
if ($frontSide) {
// Front side: normal position
// Draw colored background rectangle
$pdf->SetFillColor($bgColor[0], $bgColor[1], $bgColor[2]);
$pdf->Rect($tab['x'], $tab['y'], $tab['width'], $tab['height'], 'F');
// Draw text in black
$pdf->SetFont('helvetica', '', $fontSize);
$pdf->SetTextColor(0, 0, 0); // Always black text
$pdf->MultiCell(
$tab['width'],
$tab['height'],
@ -207,9 +317,16 @@ class Preview
);
$frontSide = false;
} else {
$tab = array_filter($configData['tabPositions'], function ($item) use ($file) {
return $item['tabNumber'] == $file['tabNumber'] ? $item : null;
})[0];
// Back side: mirrored position
$xPos = $configData['width'] - $tab['width'] - $tab['x'];
// Draw colored background rectangle
$pdf->SetFillColor($bgColor[0], $bgColor[1], $bgColor[2]);
$pdf->Rect($xPos, $tab['y'], $tab['width'], $tab['height'], 'F');
// Draw text in black
$pdf->SetFont('helvetica', '', $fontSize);
$pdf->SetTextColor(0, 0, 0); // Always black text
$pdf->MultiCell(
$tab['width'],
$tab['height'],
@ -218,7 +335,7 @@ class Preview
'C',
false,
1,
($configData['width'] - $tab['width']) - $tab['x'],
$xPos,
$tab['y'],
true,
0,

View File

@ -67,6 +67,7 @@ class IndexController extends AbstractController
$marker->setLabel("Dot {$i}");
$marker->setX(0.0);
$marker->setY(0.0);
$marker->setSize(2.0); // 2mm diameter
$ocrMarkers[] = $marker;
}
@ -76,6 +77,7 @@ class IndexController extends AbstractController
$textMarker->setLabel('Text Position');
$textMarker->setX(0.0);
$textMarker->setY(0.0);
$textMarker->setSize(8.0); // 8pt font size
$ocrMarkers[] = $textMarker;
// 1 Triangle
@ -84,6 +86,7 @@ class IndexController extends AbstractController
$triangleMarker->setLabel('Triangle (Pfeil nach oben)');
$triangleMarker->setX(0.0);
$triangleMarker->setY(0.0);
$triangleMarker->setSize(3.0); // 3mm side length
$ocrMarkers[] = $triangleMarker;
$setting->setOcrMarkers($ocrMarkers);
@ -98,6 +101,7 @@ class IndexController extends AbstractController
$marker->setLabel("Dot {$i}");
$marker->setX(0.0);
$marker->setY(0.0);
$marker->setSize(2.0); // 2mm diameter
$ocrMarkers[] = $marker;
}
$textMarker = new \Plugin\Custom\PSC\LaufkartenLayouter\Model\OcrMarker();
@ -105,12 +109,14 @@ class IndexController extends AbstractController
$textMarker->setLabel('Text Position');
$textMarker->setX(0.0);
$textMarker->setY(0.0);
$textMarker->setSize(8.0); // 8pt font size
$ocrMarkers[] = $textMarker;
$triangleMarker = new \Plugin\Custom\PSC\LaufkartenLayouter\Model\OcrMarker();
$triangleMarker->setType('triangle');
$triangleMarker->setLabel('Triangle (Pfeil nach oben)');
$triangleMarker->setX(0.0);
$triangleMarker->setY(0.0);
$triangleMarker->setSize(3.0); // 3mm side length
$ocrMarkers[] = $triangleMarker;
$setting->setOcrMarkers($ocrMarkers);
}

View File

@ -38,6 +38,13 @@ class OcrMarker extends AbstractType
'scale' => 1,
'html5' => true,
'attr' => ['step' => '0.1'],
])
->add('size', NumberType::class, [
'label' => 'Größe / Durchmesser',
'scale' => 1,
'html5' => true,
'attr' => ['step' => '0.1', 'min' => '0.1'],
'help' => 'Durchmesser in mm für Dots, Schriftgröße für Text, Seitenlänge für Dreieck',
]);
}

View File

@ -8,6 +8,7 @@ class OcrMarker
private string $label;
private float $x = 0.0;
private float $y = 0.0;
private float $size = 2.0; // Diameter in mm for dots, font size for text, size for triangle
public function getType(): string
{
@ -52,4 +53,15 @@ class OcrMarker
$this->y = $y;
return $this;
}
public function getSize(): float
{
return $this->size;
}
public function setSize(float $size): self
{
$this->size = $size;
return $this;
}
}

View File

@ -254,10 +254,11 @@
<table class="table table-striped table-bordered">
<thead class="table-dark">
<tr>
<th style="width: 15%">Type</th>
<th style="width: 25%">Label</th>
<th style="width: 30%">X Position ({{ setting.unit }})</th>
<th style="width: 30%">Y Position ({{ setting.unit }})</th>
<th style="width: 12%">Type</th>
<th style="width: 20%">Label</th>
<th style="width: 22%">X Position ({{ setting.unit }})</th>
<th style="width: 22%">Y Position ({{ setting.unit }})</th>
<th style="width: 24%">Größe ({{ setting.unit }})</th>
</tr>
</thead>
<tbody>
@ -283,6 +284,16 @@
<td>
{{ form_widget(ocrMarker.y, {'attr': {'class': 'form-control', 'placeholder': '0.0'}}) }}
</td>
<td>
{{ form_widget(ocrMarker.size, {'attr': {'class': 'form-control', 'placeholder': '2.0'}}) }}
{% if ocrMarker.vars.data.type == 'dot' %}
<small class="text-muted">Durchmesser</small>
{% elseif ocrMarker.vars.data.type == 'text' %}
<small class="text-muted">Schriftgröße (pt)</small>
{% elseif ocrMarker.vars.data.type == 'triangle' %}
<small class="text-muted">Seitenlänge</small>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -320,7 +320,7 @@
uuid: fileData.uuid,
fileName: fileData.fileName,
ocrNumber: fileData.ocrNumber || '',
color: fileData.color || 'black',
color: fileData.color || 'white',
numPages: fileData.numPages || 0,
isDuplex: fileData.isDuplex || false
};
@ -509,7 +509,7 @@
numPages: numPages,
isDuplex: numPages % 2 === 0 && numPages > 1,
ocrNumber: '',
color: 'black',
color: 'white',
processed: false,
isAlreadyUploaded: false, // Mark as NOT uploaded yet
isValid: isValid // Only 1 or 2 pages are valid
@ -646,7 +646,7 @@
numPages: numPages,
isDuplex: numPages % 2 === 0 && numPages > 1,
ocrNumber: '',
color: 'black',
color: 'white',
processed: false,
isAlreadyUploaded: false, // New files need to be uploaded
isValid: isValid // Only 1 or 2 pages are valid
@ -807,8 +807,8 @@
<select class="px-2 py-1 border border-gray-300 rounded focus:outline-none focus:border-blue-500"
id="color-select-${index}"
onchange="updateColor(${index}, this.value)"
style="color: ${pdf.color || 'black'};">
<option value="black" ${(!pdf.color || pdf.color === 'black') ? 'selected' : ''} style="color: black;">Schwarz</option>
style="color: ${pdf.color === 'white' ? '#333' : pdf.color || '#333'};">
<option value="white" ${(!pdf.color || pdf.color === 'white') ? 'selected' : ''} style="color: #333;">Weiß</option>
<option value="red" ${pdf.color === 'red' ? 'selected' : ''} style="color: red;">Rot</option>
<option value="green" ${pdf.color === 'green' ? 'selected' : ''} style="color: green;">Grün</option>
<option value="blue" ${pdf.color === 'blue' ? 'selected' : ''} style="color: blue;">Blau</option>
@ -946,7 +946,38 @@
});
/**
* Split a multi-page PDF into 2-page chunks
* Decompress/re-save a PDF using pdf-lib to make it compatible with FPDI
* @param {File} file - The PDF file to decompress
* @returns {Promise<File>} The decompressed PDF file
*/
async function decompressPdf(file) {
try {
const arrayBuffer = await file.arrayBuffer();
const pdfDoc = await PDFLib.PDFDocument.load(arrayBuffer, {
ignoreEncryption: true,
updateMetadata: false
});
// Re-save the PDF with explicit options to avoid compression
// useObjectStreams: false prevents object stream compression
const pdfBytes = await pdfDoc.save({
useObjectStreams: false,
addDefaultPage: false,
objectsPerTick: Infinity
});
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const newFile = new File([blob], file.name, { type: 'application/pdf' });
console.log(`Decompressed PDF: ${file.name} (${file.size} -> ${newFile.size} bytes)`);
return newFile;
} catch (error) {
console.error(`Error decompressing PDF ${file.name}:`, error);
throw error;
}
}
/**
* Split a multi-page PDF into 2-page chunks (also decompresses for FPDI compatibility)
* @param {File} file - The PDF file to split
* @returns {Promise<Array>} Array of {file: File, error: string|null}
*/
@ -954,12 +985,23 @@
try {
// Read the PDF file
const arrayBuffer = await file.arrayBuffer();
const pdfDoc = await PDFLib.PDFDocument.load(arrayBuffer);
const pdfDoc = await PDFLib.PDFDocument.load(arrayBuffer, {
ignoreEncryption: true
});
const totalPages = pdfDoc.getPageCount();
// If 1-2 pages, no splitting needed
// If 1-2 pages, just decompress/re-save (no splitting needed)
if (totalPages <= 2) {
return [{ file: file, error: null }];
// Re-save PDF to decompress it for FPDI compatibility
const pdfBytes = await pdfDoc.save({
useObjectStreams: false,
addDefaultPage: false,
objectsPerTick: Infinity
});
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const newFile = new File([blob], file.name, { type: 'application/pdf' });
console.log(`Decompressed PDF (no split needed): ${file.name} (${file.size} -> ${newFile.size} bytes)`);
return [{ file: newFile, error: null }];
}
// Check if page count is even
@ -984,8 +1026,12 @@
newPdf.addPage(page1);
newPdf.addPage(page2);
// Save as new PDF
const pdfBytes = await newPdf.save();
// Save as new PDF with decompression options for FPDI compatibility
const pdfBytes = await newPdf.save({
useObjectStreams: false,
addDefaultPage: false,
objectsPerTick: Infinity
});
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const chunkNumber = (i / 2) + 1;
const totalChunks = totalPages / 2;
@ -1659,23 +1705,19 @@
printPdfBtn.textContent = 'Generiere Preview...';
try {
// Step 1: Upload all valid PDFs if not already uploaded
// Step 1: Upload all valid PDFs (ALWAYS re-upload to ensure decompression for FPDI)
const uploadedUUIDs = [];
for (let i = 0; i < validPdfs.length; i++) {
let uploadUuid;
if (validPdfs[i].isAlreadyUploaded && validPdfs[i].uploadedUuid) {
console.log(`Using existing upload for ${validPdfs[i].fileName}`);
uploadUuid = validPdfs[i].uploadedUuid;
} else {
printPdfBtn.textContent = `Uploading... (${i + 1}/${validPdfs.length})`;
// Always re-upload to ensure PDF is decompressed for FPDI compatibility
printPdfBtn.textContent = `Uploading & Decompressing... (${i + 1}/${validPdfs.length})`;
const uploadResult = await uploadSinglePDF(validPdfs[i], i);
uploadUuid = uploadResult.uuid;
validPdfs[i].uploadedUuid = uploadUuid;
validPdfs[i].isAlreadyUploaded = true;
console.log(`Uploaded ${validPdfs[i].fileName}: ${uploadUuid}`);
}
console.log(`Uploaded (decompressed) ${validPdfs[i].fileName}: ${uploadUuid}`);
uploadedUUIDs.push({
uuid: uploadUuid,
@ -1737,8 +1779,18 @@
}
async function uploadSinglePDF(pdf, index) {
// ALWAYS decompress PDF before uploading for FPDI compatibility
let fileToUpload;
try {
console.log(`Decompressing PDF before upload: ${pdf.fileName}`);
fileToUpload = await decompressPdf(pdf.file);
} catch (error) {
console.error(`Failed to decompress ${pdf.fileName}, using original:`, error);
fileToUpload = pdf.file;
}
const formData = new FormData();
formData.append('file', pdf.file);
formData.append('file', fileToUpload);
formData.append('fileName', pdf.fileName);
formData.append('folder', '693fd9be532acac26f0b6bf8');
@ -1953,21 +2005,21 @@
validPdfs.forEach((pdf, index) => {
const colorNames = {
'black': 'Schwarz',
'white': 'Weiß',
'red': 'Rot',
'green': 'Grün',
'blue': 'Blau',
'yellow': 'Gelb'
};
const colorName = colorNames[pdf.color] || 'Schwarz';
const colorName = colorNames[pdf.color] || 'Weiß';
tableHtml += `
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm">${index + 1}</td>
<td class="px-4 py-3 text-sm">${pdf.fileName}</td>
<td class="px-4 py-3 text-sm text-center">${pdf.numPages}</td>
<td class="px-4 py-3 text-sm text-center">${pdf.isDuplex ? 'Ja' : 'Nein'}</td>
<td class="px-4 py-3 text-sm text-center"><strong style="color: ${pdf.color || 'black'};">${pdf.ocrNumber || '-'}</strong></td>
<td class="px-4 py-3 text-sm text-center"><span style="color: ${pdf.color || 'black'};">${colorName}</span></td>
<td class="px-4 py-3 text-sm text-center"><strong style="color: #000; background-color: ${pdf.color || 'white'}; padding: 2px 8px; border-radius: 3px;">${pdf.ocrNumber || '-'}</strong></td>
<td class="px-4 py-3 text-sm text-center"><span style="color: #000; background-color: ${pdf.color || 'white'}; padding: 2px 8px; border-radius: 3px;">${colorName}</span></td>
</tr>
`;
});

View File

@ -0,0 +1,28 @@
<?php
namespace Plugin\System\Ariba\Auth\Form;
use PSC\System\PluginBundle\Form\Group;
use PSC\System\PluginBundle\Form\Interfaces\Field;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
#[AutoconfigureTag('psc.backend.custom.groups')]
class AuthGroup extends Group
{
const GROUP_ID = 'ariba';
public function __construct()
{
$this->title = 'Ariba';
}
public function getModule()
{
return Field::Shop;
}
public function getId()
{
return self::GROUP_ID;
}
}

View File

@ -0,0 +1,80 @@
<?php
namespace Plugin\System\Ariba\Auth\Form;
use Plugin\System\PSC\CaptchaFox\Form\Group\CaptchaFox;
use PSC\Shop\EntityBundle\Document\Shop;
use PSC\System\PluginBundle\Form\Interfaces\Field;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
#[AutoconfigureTag('psc.backend.custom.fields')]
class ShopSettings implements Field
{
public function getTemplate()
{
return '@PluginSystemAribaAuth/form/shop_settings.html.twig';
}
public function getModule()
{
return Field::Shop;
}
/**
* @param array $data
*/
public function formPostSubmit(FormEvent $event)
{
}
public function formPostSetData(FormEvent $event)
{
/** @var Shop $data */
$data = $event->getData();
$event->getForm()->get('ariba')->get('secretkey')->setData($data->getPluginSettingModule('ariba', 'secretkey'));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('secretkey', TextType::class, [
'label' => 'Secret Key',
'required' => false,
'mapped' => false,
]);
return $builder;
}
public function getGroup(): string
{
return AribaAuth::GROUP_ID;
}
public function formPreSubmit(FormEvent $event)
{
// TODO: Implement formPreSubmit() method.
}
public function formPreSetData(FormEvent $event)
{
}
public function formSubmit(FormEvent $event)
{
/** @var Shop $data */
$data = $event->getData();
$data->setPluginSettingModule(
'captchafox',
'secretkey',
$event->getForm()->get('captchafox')->get('secretkey')->getData(),
);
$data->setPluginSettingModule(
'captchafox',
'publickey',
$event->getForm()->get('captchafox')->get('publickey')->getData(),
);
$event->setData($data);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Plugin\System\Ariba\Auth;
use PSC\System\PluginBundle\Plugin\Base;
class Plugin extends Base implements \PSC\System\PluginBundle\Interfaces\Plugin
{
protected $name = 'Ariba Settings';
public function getType()
{
return Plugin::Frontend;
}
public function getDescription()
{
return 'Ariba Settings';
}
public function getVersion()
{
return 1;
}
}

View File

@ -0,0 +1,7 @@
services:
_defaults:
autowire: true
autoconfigure: true
Plugin\System\Ariba\Auth\:
resource: '../../*/*'

View File

@ -0,0 +1,10 @@
<div class="row">
<div class="col-md-3">
<div class="form-group row">
{{ form_label(form.ariba.secretkey) }}
<div class="col-md-12">
{{ form_widget(form.ariba.secretkey, {attr: {'class': 'form-control'}}) }}
</div>
</div>
</div>
</div>

View File

@ -1,42 +1,30 @@
<?php
namespace Plugin\System\PSC\Bootstrap4\Controller\Backend;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
use Plugin\System\PSC\Bootstrap4\Form\SlideType;
use Plugin\System\PSC\Production\Form\Backend\QuickStatusType;
use Plugin\System\PSC\Production\Form\Backend\StatusType;
use PSC\Library\Calc\Engine;
use PSC\Library\Calc\PaperContainer;
use PSC\Shop\EntityBundle\Entity\Domain;
use PSC\Shop\EntityBundle\Entity\Orderpos;
use PSC\Shop\EntityBundle\Entity\Shop;
use PSC\Shop\EntityBundle\Entity\Shopsetting;
use PSC\Shop\EntityBundle\Entity\Upload;
use Plugin\System\PSC\Production\Form\Backend\UploadType;
use PSC\Shop\QueueBundle\Event\Position\Status\Change;
use Ramsey\Uuid\Uuid;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Attribute\Route;
#[Route('/Slider')]
class SliderController extends AbstractController
{
#[Route('/', name: 'psc_plugin_bootstrap4_backend_slider_index')]
#[Template('@PluginSystemPSCBootstrap4ControllerBackend/slider/index.html.twig')]
public function indexAction(\PSC\System\SettingsBundle\Service\Shop $shopService, EntityManagerInterface $entityManager)
{
#[Template('@PluginSystemPSCBootstrap4/backend/slider/index.html.twig')]
public function indexAction(
\PSC\System\SettingsBundle\Service\Shop $shopService,
EntityManagerInterface $entityManager,
) {
$selectedShop = $shopService->getSelectedShop();
$settings = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findBy(array("shop" => $selectedShop->getUid(), "key" => "index_slides"));
$settings = $entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')
->findBy(array('shop' => $selectedShop->getUid(), 'key' => 'index_slides'));
$tmp = [];
foreach ($settings as $setting) {
@ -46,16 +34,22 @@ class SliderController extends AbstractController
return ['slides' => $tmp];
}
#[Template]
#[Template('@PluginSystemPSCBootstrap4/backend/slider/edit.html.twig')]
#[Route(path: '/edit/{uid}', defaults: ['uid' => ''], name: 'psc_plugin_bootstrap4_backend_slider_edit')]
public function editAction(Request $request, \PSC\System\SettingsBundle\Service\Shop $shopService, EntityManagerInterface $entityManager, $uid)
{
public function editAction(
Request $request,
\PSC\System\SettingsBundle\Service\Shop $shopService,
EntityManagerInterface $entityManager,
$uid,
) {
$selectedShop = $shopService->getSelectedShop();
$data = ["title" => ""];
$data = ['title' => ''];
if ($uid) {
/** @var Shopsetting $setting */
$setting = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $selectedShop->getUid(), "uid" => $uid));
$setting = $entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')
->findOneBy(array('shop' => $selectedShop->getUid(), 'uid' => $uid));
$data = array_merge(['uid' => $setting->getUid()], json_decode($setting->getValue(), true));
}
@ -69,41 +63,46 @@ class SliderController extends AbstractController
'title' => $dataForm['title'],
'link' => $dataForm['link'],
'text' => $dataForm['text'],
'image' => $dataForm['image']
'image' => $dataForm['image'],
]));
} else {
$setting = new Shopsetting();
$setting->setShop($selectedShop);
$setting->setUid(time());
$setting->setKey("index_slides");
$setting->setKey('index_slides');
$setting->setValue(json_encode([
'title' => $dataForm['title'],
'link' => $dataForm['link'],
'text' => $dataForm['text'],
'image' => $dataForm['image']
'image' => $dataForm['image'],
]));
}
$entityManager->persist($setting);
$entityManager->flush();
return $this->redirectToRoute("psc_plugin_bootstrap4_backend_slider_index");
return $this->redirectToRoute('psc_plugin_bootstrap4_backend_slider_index');
}
return ['form' => $form->createView(), "slide" => $data];
return ['form' => $form->createView(), 'slide' => $data];
}
#[Template('@PluginSystemPSCBootstrap4ControllerBackend/slider/delete.html.twig')]
#[Template('@PluginSystemPSCBootstrap4/backend/slider/delete.html.twig')]
#[Route(path: '/delete/{uid}', name: 'psc_plugin_bootstrap4_backend_slider_delete')]
public function deleteAction(Request $request, SessionInterface $session, \PSC\System\SettingsBundle\Service\Shop $shopService, EntityManagerInterface $entityManager, $uid)
{
public function deleteAction(
Request $request,
SessionInterface $session,
\PSC\System\SettingsBundle\Service\Shop $shopService,
EntityManagerInterface $entityManager,
$uid,
) {
$selectedShop = $shopService->getSelectedShop();
if ($uid) {
/** @var Shopsetting $setting */
$setting = $entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')->findOneBy(array("shop" => $selectedShop->getUid(), "uid" => $uid));
$setting = $entityManager
->getRepository('PSC\Shop\EntityBundle\Entity\Shopsetting')
->findOneBy(array('shop' => $selectedShop->getUid(), 'uid' => $uid));
$data = array_merge(['uid' => $setting->getUid()], json_decode($setting->getValue(), true));
}
@ -117,10 +116,7 @@ class SliderController extends AbstractController
$title = $data['title'];
$entityManager->remove($setting);
$entityManager->flush();
$session->getFlashBag()->add(
'success',
'Slide \'' . $title . '\' has been deleted!'
);
$session->getFlashBag()->add('success', 'Slide \'' . $title . '\' has been deleted!');
return $this->redirectToRoute('psc_plugin_bootstrap4_backend_slider_index');
}
return $this->redirectToRoute('psc_plugin_bootstrap4_backend_slider_index');
@ -129,3 +125,4 @@ class SliderController extends AbstractController
return ['slide' => $data, 'form' => $form->createView()];
}
}

View File

@ -7,7 +7,7 @@ import {Order} from "../../model/order"
import { Button } from "flowbite-react"
import React from 'react'
class ButtonComponent extends Component<{loadOrder},{disabled: boolean}> {
class ButtonComponent extends Component<{ loadOrder }, { disabled: boolean, saving: boolean }> {
orderState: OrderState
orderService: OrderService
constructor(props) {
@ -15,7 +15,7 @@ class ButtonComponent extends Component<{loadOrder},{disabled: boolean}> {
this.orderState = container.resolve(OrderState)
this.orderService = container.resolve(OrderService)
this.state = {disabled: true}
this.state = { disabled: true, saving: false }
}
componentDidMount() {
@ -44,9 +44,12 @@ class ButtonComponent extends Component<{loadOrder},{disabled: boolean}> {
async handleSave(e) {
e.preventDefault()
this.setState({ saving: true })
let result = await this.orderService.saveOrder(this.orderState.getCurrentOrder().value)
this.props.loadOrder(result['uuid'])
this.setState({ saving: false })
}
render() {
@ -61,7 +64,8 @@ class ButtonComponent extends Component<{loadOrder},{disabled: boolean}> {
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" fill="none" className="mr-2 h-5 w-5">
<path strokeLinecap="round" strokeLinejoin="round" d="M6 20.25h12A2.25 2.25 0 0 0 20.25 18V7.5L16.5 3.75H6A2.25 2.25 0 0 0 3.75 6v12A2.25 2.25 0 0 0 6 20.25zm9.75-16.5v5h-9.5v-5zM13 5.5V7m-6.75 4.25h11.5v6.5H6.25Z"></path>
</svg>
Speichern
{this.state.saving === true && <span>wird gespeichert...</span>}
{this.state.saving === false && <span>Speichern</span>}
</Button>
<Button
size="md"

View File

@ -23,11 +23,17 @@ export default defineConfig({
dedupe: ['react', 'react-dom']
},
build: {
cssCodeSplit: false,
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`,
assetFileNames: (assetInfo) => {
if (assetInfo.name && assetInfo.name.endsWith('.css')) {
return 'assets/index.css'
}
return 'assets/[name].[ext]'
},
format: 'iife',
inlineDynamicImports: true
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<script type="module" crossorigin src="/assets/index.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index.css">
</head>
<body>
<div id="root"></div>

View File

@ -1,33 +1,30 @@
<?php
namespace Plugin\System\PSC\XmlCalc\Controller\Backend;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Bridge\Twig\Attribute\Template;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
#[Route('/live')]
class LiveController extends AbstractController
{
#[Template("@PluginSystemPSCXmlCalc/backend/live/index.html.twig")]
#[Template('@PluginSystemPSCXmlCalc/backend/live/index.html.twig')]
#[IsGranted('ROLE_ADMIN')]
#[Route('/calc/{uuid}/{test}', defaults: ['uuid' => '', 'test' => false], name: 'psc_plugin_system_xmlcalc_backend_live_index')]
public function indexAction(
Request $request,
JWTTokenManagerInterface $jwtManager,
sring $uuid, $test = false
) {
#[Route(
'/calc/{uuid}/{test}',
defaults: ['uuid' => '', 'test' => false],
name: 'psc_plugin_system_xmlcalc_backend_live_index',
)]
public function indexAction(Request $request, JWTTokenManagerInterface $jwtManager, string $uuid, $test = false)
{
return array(
'test' => $test,
'product' => $uuid,
'jwt' => $jwtManager->create($this->getUser())
'jwt' => $jwtManager->create($this->getUser()),
);
}
}

View File

@ -1730,6 +1730,11 @@ html {
border-top-width: 1px;
}
.border-blue-200{
--tw-border-opacity: 1;
border-color: rgb(191 219 254 / var(--tw-border-opacity));
}
.border-blue-600{
--tw-border-opacity: 1;
border-color: rgb(37 99 235 / var(--tw-border-opacity));
@ -1790,6 +1795,11 @@ html {
background-color: rgb(219 234 254 / var(--tw-bg-opacity));
}
.bg-blue-50{
--tw-bg-opacity: 1;
background-color: rgb(239 246 255 / var(--tw-bg-opacity));
}
.bg-blue-700{
--tw-bg-opacity: 1;
background-color: rgb(29 78 216 / var(--tw-bg-opacity));
@ -3114,6 +3124,11 @@ html {
border-color: rgb(59 130 246 / var(--tw-border-opacity));
}
:is(.dark .dark\:border-blue-800){
--tw-border-opacity: 1;
border-color: rgb(30 64 175 / var(--tw-border-opacity));
}
:is(.dark .dark\:border-gray-600){
--tw-border-opacity: 1;
border-color: rgb(75 85 99 / var(--tw-border-opacity));
@ -3133,11 +3148,20 @@ html {
border-color: transparent;
}
:is(.dark .dark\:border-yellow-800){
--tw-border-opacity: 1;
border-color: rgb(133 77 14 / var(--tw-border-opacity));
}
:is(.dark .dark\:bg-blue-600){
--tw-bg-opacity: 1;
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
}
:is(.dark .dark\:bg-blue-900\/20){
background-color: rgb(30 58 138 / 0.2);
}
:is(.dark .dark\:bg-gray-600){
--tw-bg-opacity: 1;
background-color: rgb(75 85 99 / var(--tw-bg-opacity));
@ -3175,6 +3199,25 @@ html {
background-color: rgb(127 29 29 / 0.2);
}
:is(.dark .dark\:bg-yellow-900){
--tw-bg-opacity: 1;
background-color: rgb(113 63 18 / var(--tw-bg-opacity));
}
:is(.dark .dark\:bg-yellow-900\/20){
background-color: rgb(113 63 18 / 0.2);
}
:is(.dark .dark\:text-blue-200){
--tw-text-opacity: 1;
color: rgb(191 219 254 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-blue-400){
--tw-text-opacity: 1;
color: rgb(96 165 250 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-blue-500){
--tw-text-opacity: 1;
color: rgb(59 130 246 / var(--tw-text-opacity));
@ -3205,6 +3248,11 @@ html {
color: rgb(34 197 94 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-psc-400){
--tw-text-opacity: 1;
color: rgb(214 76 63 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-purple-500){
--tw-text-opacity: 1;
color: rgb(168 85 247 / var(--tw-text-opacity));
@ -3225,6 +3273,11 @@ html {
color: rgb(255 255 255 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-yellow-200){
--tw-text-opacity: 1;
color: rgb(254 240 138 / var(--tw-text-opacity));
}
:is(.dark .dark\:text-yellow-500){
--tw-text-opacity: 1;
color: rgb(234 179 8 / var(--tw-text-opacity));

View File

@ -0,0 +1,56 @@
<?php
class gutschein_article
{
public $id = '9';
public $netto = 0;
public $name = 'Gutschein Produkt';
public $template = 'edition_article';
public $information = 'Bietet Gutscheinprodukte an';
public $backend = 'Gutschein/config/backend.ini';
public $frontend = 'Gutschein/config/frontend.xml';
public $path = 'Gutschein';
public function getNetto()
{
return $this->netto;
}
public function setNetto($value)
{
$this->netto = $value;
}
public function createFrontend($view, $translate, Article $article, $ajax = false)
{
return 0;
}
public function buyFinishDispatch($article, Orders $order, Orderspos $pos)
{
$voucherId = $article->getPluginSettings('gutschein', 'linkedVoucherUid');
var_dump($article->getPluginSettings('gutschein', 'linkedVoucherUid'));
$voucher = Doctrine_Query::create()
->from('CreditSystemDetail c')
->where('c.creditsystem_id = ? && c.used = 0', array(
$voucherId,
))
->fetchOne();
$pos->setSpecialProductTypeObject([
'voucherCode' => $voucher->uuid,
'linkedVoucherUid' => $voucherId,
'params' => [],
]);
$voucher->used = true;
$voucher->contact_id = $order->contact_id;
$voucher->save();
}
}

View File

@ -0,0 +1,173 @@
[Contact]
[Account: Contact]
[Shop Operator : Account]
buttons.3.title = "PDF Vorschau"
buttons.3.target = "_blank"
buttons.3.href = "'/admin/article/pdf/uuid/'.$data->uuid"
buttons.3.requireArticle = 1
tabs.20.general.title = "W&L"
tabs.20.fields.12.name = "display_market"
tabs.20.fields.12.fieldLabel = "article_backend_fieldLabel_Display_Market"
tabs.20.fields.12.editor.allowBlank = "true"
tabs.20.fields.12.editor.xtype = "xcheckbox"
tabs.20.fields.13.name = "a6_resale_price"
tabs.20.fields.13.fieldLabel = "orders_gridorder_js_ResalePrice"
tabs.20.fields.13.editor.allowBlank = "true"
tabs.20.fields.13.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#orders_gridorder_js_ResalePrice"
[System Operator : Shop Operator]
tabs.13.fields.318.name = "preis"
tabs.13.fields.318.fieldLabel = "Preis"
tabs.13.fields.318.editor.allowBlank = "false"
tabs.16.general.title = "D&H"
tabs.16.general.labelAlign = "top"
tabs.16.fields.75.id = "self_name_sum5"
tabs.16.fields.75.name = "self_name_sum5"
tabs.16.fields.75.fieldLabel = "Dateien"
tabs.16.fields.75.editor.xtype = "compositefield"
tabs.16.fields.75.editor.height = "60"
tabs.16.fields.75.items.10.name = "vorlage_file"
tabs.16.fields.75.items.10.fieldLabel = "article_backend_fieldLabel_Vorlage_File"
tabs.16.fields.75.items.10.editor.allowBlank = "false"
tabs.16.fields.75.items.10.editor.xtype = "uploadfield"
tabs.16.fields.75.items.10.editor.id = "vorlage_file"
tabs.16.fields.75.items.10.editor.name = "vorlage_file"
tabs.16.fields.75.items.10.editor.height = "90"
tabs.16.fields.75.items.10.help = "admin/product/settings/uploadweblayouter#vorlagefile"
tabs.16.fields.75.items.20.name = "vorlage_file1"
tabs.16.fields.75.items.20.fieldLabel = "article_backend_fieldLabel_Vorlage_File"
tabs.16.fields.75.items.20.editor.allowBlank = "false"
tabs.16.fields.75.items.20.editor.xtype = "uploadfield"
tabs.16.fields.75.items.20.editor.id = "vorlage_file1"
tabs.16.fields.75.items.20.editor.name = "vorlage_file1"
tabs.16.fields.75.items.20.editor.height = "90"
tabs.16.fields.75.items.20.help = "admin/product/settings/uploadweblayouter#vorlagefile"
tabs.16.fields.75.items.30.name = "vorlage_file2"
tabs.16.fields.75.items.30.fieldLabel = "article_backend_fieldLabel_Vorlage_File"
tabs.16.fields.75.items.30.editor.allowBlank = "false"
tabs.16.fields.75.items.30.editor.xtype = "uploadfield"
tabs.16.fields.75.items.30.editor.id = "vorlage_file2"
tabs.16.fields.75.items.30.editor.name = "vorlage_file2"
tabs.16.fields.75.items.30.editor.height = "90"
tabs.16.fields.75.items.30.help = "admin/product/settings/uploadweblayouter#vorlagefile"
tabs.16.fields.75.items.40.name = "vorlage_file3"
tabs.16.fields.75.items.40.fieldLabel = "article_backend_fieldLabel_Vorlage_File"
tabs.16.fields.75.items.40.editor.allowBlank = "false"
tabs.16.fields.75.items.40.editor.xtype = "uploadfield"
tabs.16.fields.75.items.40.editor.id = "vorlage_file3"
tabs.16.fields.75.items.40.editor.name = "vorlage_file3"
tabs.16.fields.75.items.40.editor.height = "90"
tabs.16.fields.75.items.40.help = "admin/product/settings/uploadweblayouter#vorlagefile"
tabs.16.fields.65.name = "vorlage_info"
tabs.16.fields.65.fieldLabel = "article_backend_fieldLabel_Vorlage_Info"
tabs.16.fields.65.editor.allowBlank = "false"
tabs.16.fields.65.editor.xtype = "htmleditor"
tabs.16.fields.65.editor.anchor = "98%"
tabs.16.fields.65.editor.editorheight = "280"
tabs.16.fields.65.editor.editorwidth = "420"
tabs.16.fields.65.help = "admin/product/settings/uploadweblayouter#vorlageinfo"
tabs.20.fields.20.name = "a4_auflagen"
tabs.20.fields.20.fieldLabel = "Auflagen"
tabs.20.fields.20.editor.allowBlank = "false"
tabs.20.fields.20.editor.xtype="textarea"
tabs.20.fields.20.editor.height="80"
tabs.20.fields.20.help = "admin/product/settings/waren#auflagen"
tabs.20.fields.30.name = "init_status_title"
tabs.20.fields.30.nameid = "init_status"
tabs.20.fields.30.fieldLabel = "article_backend_fieldLabel_init_status"
tabs.20.fields.30.editor.allowBlank = "true"
tabs.20.fields.30.editor.xtype = "combo"
tabs.20.fields.30.editor.service = "status"
tabs.20.fields.30.help = "admin/product/settings/waren#initstatus"
tabs.20.fields.60.name = "stock"
tabs.20.fields.60.fieldLabel = "Lagerartikel?"
tabs.20.fields.60.editor.allowBlank = "false"
tabs.20.fields.60.editor.xtype = "xcheckbox"
tabs.20.fields.60.help = "admin/product/settings/waren#stock"
tabs.20.fields.61.name = "stock_count"
tabs.20.fields.61.fieldLabel = "Auf Lager?"
tabs.20.fields.61.editor.allowBlank = "false"
tabs.20.fields.61.help = "admin/product/settings/waren#stockcount"
tabs.20.fields.63.name = "stock_count_min"
tabs.20.fields.63.fieldLabel = "Mind. Anzahl Lager?"
tabs.20.fields.63.editor.allowBlank = "false"
tabs.20.fields.63.help = "admin/product/settings/waren#stockcountmin"
tabs.20.fields.64.name = "stock_place"
tabs.20.fields.64.fieldLabel = "Lagerplatz?"
tabs.20.fields.64.editor.allowBlank = "false"
tabs.20.fields.64.help = "admin/product/settings/waren#stockplace"
tabs.20.fields.65.name = "stock_max_buy"
tabs.20.fields.65.fieldLabel = "Max. Anzahl Kaufen?"
tabs.20.fields.65.editor.allowBlank = "false"
tabs.20.fields.65.help = "admin/product/settings/waren#stockmaxbuy"
tabs.20.fields.75.name = "lager_file_preview"
tabs.20.fields.75.fieldLabel = "article_backend_fieldLabel_Lager_File_Preview"
tabs.20.fields.75.editor.allowBlank = "false"
tabs.20.fields.75.editor.xtype = "uploadfield"
tabs.20.fields.75.editor.id = "lager_file_preview"
tabs.20.fields.75.editor.name = "lager_file_preview"
tabs.20.fields.75.editor.width = "90"
tabs.20.fields.75.help = "admin/product/settings/waren#lagerfilepreview"
tabs.20.fields.76.name = "lager_file_file"
tabs.20.fields.76.fieldLabel = "article_backend_fieldLabel_Lager_File"
tabs.20.fields.76.editor.allowBlank = "false"
tabs.20.fields.76.editor.xtype = "uploadfield"
tabs.20.fields.76.editor.id = "lager_file_file"
tabs.20.fields.76.editor.name = "lager_file_file"
tabs.20.fields.76.editor.width = "90"
tabs.20.fields.76.help = "admin/product/settings/waren#lagerfilefile"
tabs.122.general.title = "Custom"
tabs.122.fields.12.name = "verpackungseinheit"
tabs.122.fields.12.fieldLabel = "Verpackungseinheit"
tabs.122.fields.12.editor.allowBlank = "true"
tabs.122.fields.15.name = "papierfaktor"
tabs.122.fields.15.fieldLabel = "Papierfaktor"
tabs.122.fields.15.editor.allowBlank = "true"
tabs.122.fields.20.name = "set_config"
tabs.122.fields.20.fieldLabel = "Set Konfiguration"
tabs.122.fields.20.editor.allowBlank = "false"
tabs.122.fields.20.editor.xtype="textarea"
tabs.122.fields.20.editor.height="80"
tabs.122.fields.20.help = "admin/product/settings/waren#set"
tabs.122.fields.61.name = "upload_steplayouter_sum"
tabs.122.fields.61.fieldLabel = "Layouter 2"
tabs.122.fields.61.editor.xtype = "compositefield"
tabs.122.fields.61.items.10.name = "upload_steplayouter2"
tabs.122.fields.61.items.10.fieldLabel = "article_backend_fieldLabel_upload_templateprint"
tabs.122.fields.61.items.10.editor.allowBlank = "true"
tabs.122.fields.61.items.10.editor.xtype = "xcheckbox"
tabs.122.fields.61.items.10.editor.width = "40"
[Admin : System Operator]

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<kalkulation>
<artikel>
<name>Handbuch</name>
<kommentar>kein</kommentar>
<option id="auflage" name="Auflage" type="Input" width="3" require="true">
</option>
<option id="umfang" name="Umfang" type="Input" width="3" require="true">
</option>
<option id="dateien" name="Dateien" type="Input" width="3" require="true">
</option>
<option id="schnitte" name="Schnitte" type="Input" width="3">
</option>
<option id="papier" name="Papier" type="Select">
<opt id="80" name="80g/m²" default="true">
<umfang>
<grenze preis="1.00" pauschale="2.55">1</grenze>
<grenze preis="1.20" pauschale="2.00">2-6</grenze>
<grenze preis="5.00" pauschale="1.00">7-20</grenze>
<grenze preis="5.00" pauschale="1.00">21-</grenze>
</umfang>
<auflage>
<grenze preis="1.00" pauschale="3.00">1-99</grenze>
<grenze preis="1.00" pauschale="4.00">100-</grenze>
</auflage>
</opt>
<opt id="100" name="100g/m²">
<umfang>
<grenze preis="1.00" pauschale="2.55">1</grenze>
<grenze preis="1.20" pauschale="2.00">2-6</grenze>
<grenze preis="5.00" pauschale="1.00">7-20</grenze>
</umfang>
<auflage>
<grenze preis="1.00" pauschale="3.00">1-99</grenze>
<grenze preis="1.00" pauschale="4.00">100-</grenze>
</auflage>
</opt>
<opt id="120" name="120g/m²">
<umfang>
<grenze preis="1.00" pauschale="2.55">1</grenze>
<grenze preis="9.00" pauschale="1.00">2-6</grenze>
<grenze preis="5.00" pauschale="1.00">7-20</grenze>
<grenze preis="5.00" pauschale="1.00">21-</grenze>
</umfang>
<auflage>
<grenze preis="0.30" pauschale="3.00">1-3</grenze>
<grenze preis="0.20" pauschale="4.00">4-99</grenze>
<grenze preis="1.00" pauschale="5.00">100-</grenze>
</auflage>
</opt>
</option>
<option id="beids" name="Beidseitig?" type="Select">
<opt id="nein" name="Nein">
<auflage>
<grenze formel="">1-</grenze>
</auflage>
</opt>
<opt id="ja" name="Ja">
<auflage>
<grenze formel="$papier$*2">1-</grenze>
</auflage>
</opt>
</option>
<option id="aus" name="Ausführung" type="Select">
<opt id="leimgebunden" name="Leimgebunden">
<auflage>
<grenze preis="1.00" pauschale="0.00">1-30</grenze>
<grenze preis="0.90" pauschale="0.00">31-</grenze>
</auflage>
</opt>
<opt id="randabfallend" name="Randabfallend">
<auflage>
<grenze preis="1.00" pauschale="0.00">1-</grenze>
</auflage>
</opt>
</option>
<option id="bohren" name="Bohren" type="Select">
<opt id="nichts" name="Nichts">
<auflage>
<grenze preis="1.00" pauschale="0.00">1-30</grenze>
<grenze preis="0.90" pauschale="0.00">31-</grenze>
</auflage>
</opt>
<opt id="1" name="1 Mal">
<auflage>
<grenze preis="1.00" pauschale="0.00">1-</grenze>
</auflage>
</opt>
</option>
<option id="static" name="Versand und Zusätzliches" type="Input" width="10" />
</artikel>
</kalkulation>

View File

@ -0,0 +1,6 @@
Simple Product;Produktdaten
count;Anzahl
Price;Preis
Private;Gebunden
Articlegroups;Produktgruppen
Informations;Infos
1 Simple Product Produktdaten
2 count Anzahl
3 Price Preis
4 Private Gebunden
5 Articlegroups Produktgruppen
6 Informations Infos

View File

@ -1,242 +0,0 @@
<?php
class merchandise_article {
public $id = "9";
public $articlegroups;
public $private;
public $versandwert;
public $versand;
public $netto = 0;
public $name = "Merchandise Product";
public $template = "merchandise_article";
public $information = "Bietet Merchandise Produkte an";
public $backend = 'Merchandise/config/backend.ini';
public $backend_market = 'Merchandise/config/backend_market.ini';
public $frontend = 'Merchandise/config/frontend.xml';
public $path = 'Merchandise';
public $title;
public $text;
public $file;
public $file1;
public $xmltext;
public function getNetto() {
return $this->netto;
}
public function setNetto($value) {
$this->netto = $value;
}
public function toArray() {
return array('thomas' => $this->thomas, 'pdf' => $this->pdf, 'template' => $this->template, 'a1_xml' => str_replace('\\', '', $this->a1_xml), 'versand' => $this->versand,'versandwert' => $this->versandwert,'private' => $this->private, 'articlegroups' => $this->articlegroups, 'mwert' => $this->mwert, 'title' => $this->title, 'price' => $this->price, 'text' => $this->text, 'file' => $this->file, 'file1' => $this->file1);
}
public function createFrontend($view, $translate, Article $article, $ajax = false) {
if($article->a6_org_article > 0) {
$orgArticle = $article->OrgArticle;
}else{
$orgArticle = $article;
}
$xml = simplexml_load_string($orgArticle->a9_sizes);
$basket = new TP_Basket ( );
$netto = $article->a6_resale_price;
$count = 0;
$prices = array();
$install = Zend_Registry::get('install');
$pt = new SimpleXMLElement($install['a9_pt'], null, false);
$params = array();
$print_sizes = array();
foreach($xml as $el) {
$value = intval($view->getRequest()->getParam('s'.$el['id'], 0));
$print_sizes[] = array(
'width' => (string)$el['wth'],
'height' => (string)$el['hth'],
'value' => $value,
'id' => $el['id']
);
$prices[] = array('id' => 's'.(string)$el['id'], 'name' => (string)$el['size'], 'value' => $value);
if(isset($el['added_price'])) {
$netto = $netto + ($value * (float)$el['added_price']);
}
$netto = $netto + ($orgArticle->preis * $value);
$count += $value;
$params['s'.(string)$el['id']] = array('value' => $value, 'name' => (string)$el['size'] );
}
$view->view->has_price = $count;
$tempPro = $basket->getTempProduct($article->uuid);
$tempPro = $tempPro->getDesignerData();
$tempProOrg = $tempPro;
$tempProOrg = $tempPro;
if(!isset($tempPro['design_config']) || $tempPro['design_config'] == "") {
$tempPro = Zend_Json::decode($article->mercendise_design);
}
if(isset($tempProOrg['colors']) || $tempProOrg['colors'] == "") {
$tempPro['colors'] = $tempProOrg['colors'];
}
if(isset($tempPro['design_config']) && $tempPro['design_config'] != "") {
$install = Zend_Registry::get('install');
$motiv1 = $install['motiv_1'];
$motiv2 = $install['motiv_2'];
$motiv3 = $install['motiv_3'];
$price = 0;
$xmldes = simplexml_load_string('<?xml version="1.0"?><root>' . str_replace("\n","#", str_replace("&","+",$tempPro['design_config'])) . '</root>');
foreach ($xmldes->clip as $el) {
if((string)$el['colname'] != "undefined") {
$colname = strstr((string)$el['colname'], ":", true);
if((string)$colname == 'Flex Print') {
$colname = "Flex Folie";
}
}else{
if ((string)$el['type'] == 'txt') {
$colname = "Flex Folie";
}else{
$colname = "Digitaldruck";
}
}
$itm = $pt->xpath('//printing/itm[@technology_name="' . $colname . '"]');
if(!$orgArticle->a9_price_print_disable) {
$price = $price + (float)$itm[0]['technology_price'];
}
if ((string)$el['type'] == 'img') {
if (strpos($el['path_str'], "readusermotivebig")) {
$match = str_replace("/service/designer/readusermotivebig?id=", "", str_replace(",undefined,undefined", "", $el['path_str']));
$motiv = Doctrine_Query::create()
->from('Motiv a')
->where('a.uuid = ?', array($match))->fetchOne();
foreach($print_sizes as $ps) {
$area = 'a9_'.(string)$el['side'].'_area';
$screen = explode(',', $orgArticle->$area);
$fw = ($ps['width'] / ($screen[2] / (float)$el['width']));
$fh = ($ps['height'] / ($screen[3] / (float)$el['height']));
$mm = $fw * $fh;
if($mm <= $motiv1) {
$motiv_group = 1;
}elseif($mm > $motiv1 && $mm <= $motiv2) {
$motiv_group = 2;
}elseif($mm > $motiv2 && $mm <= $motiv3) {
$motiv_group = 3;
}else{
$motiv_group = 3;
}
if(!$orgArticle->a9_price_print_disable) {
$netto = $netto + ($ps['value'] * ($orgArticle->a9_price_motiv + $motiv['price'.$motiv_group]));
}else{
$netto = $netto + ($ps['value'] * $motiv['price'.$motiv_group]);
}
}
reset($print_sizes);
}else{
if(!$orgArticle->a9_price_print_disable) {
$netto = $netto + ($count * $orgArticle->a9_price_icon);
}
}
}
if ((string)$el['type'] == 'txt') {
$netto = $netto + ($count * $orgArticle->a9_price_text);
$anzahl = substr_count((string)$el['path_str'], '#');
$anzahl = $anzahl;
if($anzahl < 0) {
$anzahl = 0;
}
if(!$orgArticle->a9_price_print_disable) {
$netto = $netto + ($count * ($anzahl * $orgArticle->a9_price_text_line1));
}
}
}
$netto = $netto + ($count * $price);
}
if(isset($tempPro['colors']) && $tempPro['colors'] != "") {
$color = str_replace(',','', strstr($tempPro['colors'], ','));
$xml = simplexml_load_string($orgArticle->a9_colors);
$element = $xml->xpath('//itm[@colorvalue="' . $color . '"]');
if(isset($element[0]) && isset($element[0]['added_price'])) {
$netto = $netto + ($count * (float)$element[0]['added_price']);
}
}
$view->view->prices = $prices;
$sessart = $basket->getTempProduct($article->uuid);
$sessart->setCount($count);
$sessart->setDesignerCost($netto);
$sessart->setDesignerParam($params);
return $netto;
}
public function generatePreview($articleId, $layouterPreviewId = false) {
$articleSession = new TP_Layoutersession();
$articleSess = $articleSession->getLayouterArticle($layouterPreviewId);
return $articleSess->getPreviewPath();
}
public function copyPreDispatch($data, $orguuid = false, $art = false) {
if ($orguuid != false) {
$articleSession = new TP_Layoutersession();
$articleSess = $articleSession->getLayouterArticle($orguuid);
$data->mercendise_design = $articleSess->getDesignerXML();
$shop = Zend_Registry::get('target_shop');
if(!file_exists('uploads/' . $shop . '/designer/')) {
mkdir('uploads/' . $shop . '/designer/', 0777, true);
}
copy($articleSess->getPreviewPath(), 'uploads/' . $shop . '/designer/' . $data->id . '.jpg');
$data->mercendise_thumbnail = 'uploads/' . $shop . '/designer/' . $data->id . '.jpg';
$data->save();
}
}
}

View File

@ -1,271 +0,0 @@
[Contact]
[Account: Contact]
[Shop Operator : Account]
[System Operator : Shop Operator]
tabs.13.fields.318.name = "preis"
tabs.13.fields.318.fieldLabel = "Preis"
tabs.13.fields.318.editor.allowBlank = "false"
tabs.13.fields.319.name = "a9_price_motiv"
tabs.13.fields.319.fieldLabel = "Druckkosten Motiv"
tabs.13.fields.319.editor.allowBlank = "false"
tabs.13.fields.330.name = "a9_price_icon"
tabs.13.fields.330.fieldLabel = "Druckkosten Icon"
tabs.13.fields.330.editor.allowBlank = "false"
tabs.13.fields.332.name = "a9_price_text"
tabs.13.fields.332.fieldLabel = "Druckkosten Text"
tabs.13.fields.332.editor.allowBlank = "false"
tabs.13.fields.333.name = "a9_price_text_line1"
tabs.13.fields.333.fieldLabel = "Druckkosten Text pro + Zeile"
tabs.13.fields.333.editor.allowBlank = "false"
tabs.13.fields.334.name = "a9_price_print_disable"
tabs.13.fields.334.fieldLabel = "Druckkosten nicht berechnen"
tabs.13.fields.334.editor.xtype = "xcheckbox"
tabs.19.general.title = "ML Settings"
tabs.19.fields.21.name = "display_market"
tabs.19.fields.21.fieldLabel = "article_backend_fieldLabel_Display_Market"
tabs.19.fields.21.editor.allowBlank = "true"
tabs.19.fields.21.editor.xtype = "xcheckbox"
tabs.19.fields.21.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#article_backend_fieldLabel_Display_Market"
tabs.19.fields.22.name = "resale"
tabs.19.fields.22.fieldLabel = "article_backend_fieldLabel_Resale"
tabs.19.fields.22.editor.allowBlank = "true"
tabs.19.fields.22.editor.xtype = "xcheckbox"
tabs.19.fields.22.help = "admin/myweb2print/shop/products/detail/webbasedlayoutersourceproduct#article_backend_fieldLabel_Resale"
tabs.19.fields.30.name = "a9_sizes"
tabs.19.fields.30.fieldLabel = "Sizes"
tabs.19.fields.30.editor.allowBlank = "false"
tabs.19.fields.30.editor.xtype = "textarea"
tabs.19.fields.30.editor.height= "90"
tabs.19.fields.35.name = "a9_colors"
tabs.19.fields.35.fieldLabel = "Colors"
tabs.19.fields.35.editor.allowBlank = "false"
tabs.19.fields.35.editor.xtype = "textarea"
tabs.19.fields.35.editor.height= "90"
tabs.19.fields.45.name = "a9_pt"
tabs.19.fields.45.fieldLabel = "Drucktechnologie"
tabs.19.fields.45.editor.allowBlank = "false"
tabs.19.fields.46.name = "a9_front_area"
tabs.19.fields.46.fieldLabel = "Vorderseite"
tabs.19.fields.46.editor.allowBlank = "false"
tabs.19.fields.47.name = "a9_back_area"
tabs.19.fields.47.fieldLabel = "Rückseite"
tabs.19.fields.47.editor.allowBlank = "false"
tabs.19.fields.48.name = "a9_left_area"
tabs.19.fields.48.fieldLabel = "linke Seite"
tabs.19.fields.48.editor.allowBlank = "false"
tabs.19.fields.49.name = "a9_right_area"
tabs.19.fields.49.fieldLabel = "rechte Seite"
tabs.19.fields.49.editor.allowBlank = "false"
tabs.20.general.title = "ML Images"
tabs.20.fields.40.id = "self_name_sum1"
tabs.20.fields.40.name = "self_name_sum1"
tabs.20.fields.40.fieldLabel = "article_backend_fieldLabel_a9_1"
tabs.20.fields.40.editor.xtype = "compositefield"
tabs.20.fields.40.editor.height = "90"
tabs.20.fields.40.items.5.id = "a9_front1"
tabs.20.fields.40.items.5.name = "a9_front1"
tabs.20.fields.40.items.5.editor.allowBlank = "false"
tabs.20.fields.40.items.5.editor.xtype = "uploadfield"
tabs.20.fields.40.items.5.editor.id = "a9_front1"
tabs.20.fields.40.items.5.editor.name = "a9_front1"
tabs.20.fields.40.items.5.editor.height = "90"
tabs.20.fields.40.items.15.id = "a9_back1"
tabs.20.fields.40.items.15.name = "a9_back1"
tabs.20.fields.40.items.15.editor.allowBlank = "false"
tabs.20.fields.40.items.15.editor.xtype = "uploadfield"
tabs.20.fields.40.items.15.editor.id = "a9_back1"
tabs.20.fields.40.items.15.editor.name = "a9_back1"
tabs.20.fields.40.items.15.editor.height = "90"
tabs.20.fields.40.items.25.id = "a9_left1"
tabs.20.fields.40.items.25.name = "a9_left1"
tabs.20.fields.40.items.25.editor.allowBlank = "false"
tabs.20.fields.40.items.25.editor.xtype = "uploadfield"
tabs.20.fields.40.items.25.editor.id = "a9_left1"
tabs.20.fields.40.items.25.editor.name = "a9_left1"
tabs.20.fields.40.items.25.editor.height = "90"
tabs.20.fields.40.items.35.id = "a9_right1"
tabs.20.fields.40.items.35.name = "a9_right1"
tabs.20.fields.40.items.35.editor.allowBlank = "false"
tabs.20.fields.40.items.35.editor.xtype = "uploadfield"
tabs.20.fields.40.items.35.editor.id = "a9_right1"
tabs.20.fields.40.items.35.editor.name = "a9_right1"
tabs.20.fields.40.items.35.editor.height = "90"
tabs.20.fields.45.id = "self_name_sum2"
tabs.20.fields.45.name = "self_name_sum2"
tabs.20.fields.45.fieldLabel = "article_backend_fieldLabel_a9_2"
tabs.20.fields.45.editor.xtype = "compositefield"
tabs.20.fields.45.editor.height = "90"
tabs.20.fields.45.items.5.id = "a9_front2"
tabs.20.fields.45.items.5.name = "a9_front2"
tabs.20.fields.45.items.5.editor.allowBlank = "false"
tabs.20.fields.45.items.5.editor.xtype = "uploadfield"
tabs.20.fields.45.items.5.editor.id = "a9_front2"
tabs.20.fields.45.items.5.editor.name = "a9_front2"
tabs.20.fields.45.items.5.editor.height = "90"
tabs.20.fields.45.items.15.id = "a9_back2"
tabs.20.fields.45.items.15.name = "a9_back2"
tabs.20.fields.45.items.15.editor.allowBlank = "false"
tabs.20.fields.45.items.15.editor.xtype = "uploadfield"
tabs.20.fields.45.items.15.editor.id = "a9_back2"
tabs.20.fields.45.items.15.editor.name = "a9_back2"
tabs.20.fields.45.items.15.editor.height = "90"
tabs.20.fields.45.items.25.id = "a9_left2"
tabs.20.fields.45.items.25.name = "a9_left2"
tabs.20.fields.45.items.25.editor.allowBlank = "false"
tabs.20.fields.45.items.25.editor.xtype = "uploadfield"
tabs.20.fields.45.items.25.editor.id = "a9_left2"
tabs.20.fields.45.items.25.editor.name = "a9_left2"
tabs.20.fields.45.items.25.editor.height = "90"
tabs.20.fields.45.items.25.id = "a9_right2"
tabs.20.fields.45.items.35.name = "a9_right2"
tabs.20.fields.45.items.35.editor.allowBlank = "false"
tabs.20.fields.45.items.35.editor.xtype = "uploadfield"
tabs.20.fields.45.items.35.editor.id = "a9_right2"
tabs.20.fields.45.items.35.editor.name = "a9_right2"
tabs.20.fields.45.items.35.editor.height = "90"
tabs.20.fields.55.id = "self_name_sum3"
tabs.20.fields.55.name = "self_name_sum3"
tabs.20.fields.55.fieldLabel = "article_backend_fieldLabel_a9_3"
tabs.20.fields.55.editor.xtype = "compositefield"
tabs.20.fields.55.editor.height = "90"
tabs.20.fields.55.items.5.id = "a9_front3"
tabs.20.fields.55.items.5.name = "a9_front3"
tabs.20.fields.55.items.5.editor.allowBlank = "false"
tabs.20.fields.55.items.5.editor.xtype = "uploadfield"
tabs.20.fields.55.items.5.editor.id = "a9_front3"
tabs.20.fields.55.items.5.editor.name = "a9_front3"
tabs.20.fields.55.items.5.editor.height = "90"
tabs.20.fields.55.items.15.id = "a9_back3"
tabs.20.fields.55.items.15.name = "a9_back3"
tabs.20.fields.55.items.15.editor.allowBlank = "false"
tabs.20.fields.55.items.15.editor.xtype = "uploadfield"
tabs.20.fields.55.items.15.editor.id = "a9_back3"
tabs.20.fields.55.items.15.editor.name = "a9_back3"
tabs.20.fields.55.items.15.editor.height = "90"
tabs.20.fields.55.items.25.id = "a9_left3"
tabs.20.fields.55.items.25.name = "a9_left3"
tabs.20.fields.55.items.25.editor.allowBlank = "false"
tabs.20.fields.55.items.25.editor.xtype = "uploadfield"
tabs.20.fields.55.items.25.editor.id = "a9_left3"
tabs.20.fields.55.items.25.editor.name = "a9_left3"
tabs.20.fields.55.items.25.editor.height = "90"
tabs.20.fields.55.items.25.id = "a9_right3"
tabs.20.fields.55.items.35.name = "a9_right3"
tabs.20.fields.55.items.35.editor.allowBlank = "false"
tabs.20.fields.55.items.35.editor.xtype = "uploadfield"
tabs.20.fields.55.items.35.editor.id = "a9_right3"
tabs.20.fields.55.items.35.editor.name = "a9_right3"
tabs.20.fields.55.items.35.editor.height = "90"
tabs.20.fields.65.id = "self_name_sum4"
tabs.20.fields.65.name = "self_name_sum4"
tabs.20.fields.65.fieldLabel = "article_backend_fieldLabel_a9_4"
tabs.20.fields.65.editor.xtype = "compositefield"
tabs.20.fields.65.editor.height = "90"
tabs.20.fields.65.items.5.id = "a9_front4"
tabs.20.fields.65.items.5.name = "a9_front4"
tabs.20.fields.65.items.5.editor.allowBlank = "false"
tabs.20.fields.65.items.5.editor.xtype = "uploadfield"
tabs.20.fields.65.items.5.editor.id = "a9_front4"
tabs.20.fields.65.items.5.editor.name = "a9_front4"
tabs.20.fields.65.items.5.editor.height = "90"
tabs.20.fields.65.items.15.id = "a9_back4"
tabs.20.fields.65.items.15.name = "a9_back4"
tabs.20.fields.65.items.15.editor.allowBlank = "false"
tabs.20.fields.65.items.15.editor.xtype = "uploadfield"
tabs.20.fields.65.items.15.editor.id = "a9_back4"
tabs.20.fields.65.items.15.editor.name = "a9_back4"
tabs.20.fields.65.items.15.editor.height = "90"
tabs.20.fields.65.items.25.id = "a9_left4"
tabs.20.fields.65.items.25.name = "a9_left4"
tabs.20.fields.65.items.25.editor.allowBlank = "false"
tabs.20.fields.65.items.25.editor.xtype = "uploadfield"
tabs.20.fields.65.items.25.editor.id = "a9_left4"
tabs.20.fields.65.items.25.editor.name = "a9_left4"
tabs.20.fields.65.items.25.editor.height = "90"
tabs.20.fields.65.items.25.id = "a9_right4"
tabs.20.fields.65.items.35.name = "a9_right4"
tabs.20.fields.65.items.35.editor.allowBlank = "false"
tabs.20.fields.65.items.35.editor.xtype = "uploadfield"
tabs.20.fields.65.items.35.editor.id = "a9_right4"
tabs.20.fields.65.items.35.editor.name = "a9_right4"
tabs.20.fields.65.items.35.editor.height = "90"
tabs.20.fields.75.id = "self_name_sum5"
tabs.20.fields.75.name = "self_name_sum5"
tabs.20.fields.75.fieldLabel = "article_backend_fieldLabel_a9_5"
tabs.20.fields.75.editor.xtype = "compositefield"
tabs.20.fields.75.editor.height = "90"
tabs.20.fields.75.items.5.id = "a9_front5"
tabs.20.fields.75.items.5.name = "a9_front5"
tabs.20.fields.75.items.5.editor.allowBlank = "false"
tabs.20.fields.75.items.5.editor.xtype = "uploadfield"
tabs.20.fields.75.items.5.editor.id = "a9_front5"
tabs.20.fields.75.items.5.editor.name = "a9_front5"
tabs.20.fields.75.items.5.editor.height = "90"
tabs.20.fields.75.items.15.id = "a9_back5"
tabs.20.fields.75.items.15.name = "a9_back5"
tabs.20.fields.75.items.15.editor.allowBlank = "false"
tabs.20.fields.75.items.15.editor.xtype = "uploadfield"
tabs.20.fields.75.items.15.editor.id = "a9_back5"
tabs.20.fields.75.items.15.editor.name = "a9_back5"
tabs.20.fields.75.items.15.editor.height = "90"
tabs.20.fields.75.items.25.id = "a9_left5"
tabs.20.fields.75.items.25.name = "a9_left5"
tabs.20.fields.75.items.25.editor.allowBlank = "false"
tabs.20.fields.75.items.25.editor.xtype = "uploadfield"
tabs.20.fields.75.items.25.editor.id = "a9_left5"
tabs.20.fields.75.items.25.editor.name = "a9_left5"
tabs.20.fields.75.items.25.editor.height = "90"
tabs.20.fields.75.items.25.id = "a9_right5"
tabs.20.fields.75.items.35.name = "a9_right5"
tabs.20.fields.75.items.35.editor.allowBlank = "false"
tabs.20.fields.75.items.35.editor.xtype = "uploadfield"
tabs.20.fields.75.items.35.editor.id = "a9_right5"
tabs.20.fields.75.items.35.editor.name = "a9_right5"
tabs.20.fields.75.items.35.editor.height = "90"
[Admin : System Operator]

View File

@ -1,301 +0,0 @@
[Contact]
[Account: Contact]
[Shop Operator : Account]
tabs.14.general.title = "Marktplatz"
tabs.14.fields.21.name = "display_market"
tabs.14.fields.21.fieldLabel = "article_backend_fieldLabel_Display_Market"
tabs.14.fields.21.editor.allowBlank = "true"
tabs.14.fields.21.editor.xtype = "xcheckbox"
tabs.14.fields.21.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#article_backend_fieldLabel_Display_Market"
;tabs.14.fields.22.name = "resale"
;tabs.14.fields.22.fieldLabel = "article_backend_fieldLabel_Resale"
;tabs.14.fields.22.editor.allowBlank = "true"
;tabs.14.fields.22.editor.xtype = "xcheckbox"
;tabs.14.fields.22.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#article_backend_fieldLabel_Resale"
tabs.14.fields.23.name = "resale_design"
tabs.14.fields.23.fieldLabel = "article_backend_fieldLabel_Resale_Design"
tabs.14.fields.23.editor.allowBlank = "true"
tabs.14.fields.23.editor.xtype = "xcheckbox"
tabs.14.fields.23.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#article_backend_fieldLabel_Resale_Design"
tabs.14.fields.24.name = "not_edit"
tabs.14.fields.24.fieldLabel = "article_backend_fieldLabel_Not_edit"
tabs.14.fields.24.editor.allowBlank = "true"
tabs.14.fields.24.editor.xtype = "xcheckbox"
tabs.14.fields.24.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#article_backend_fieldLabel_Not_edit"
tabs.14.fields.28.name = "a6_resale_price"
tabs.14.fields.28.fieldLabel = "orders_gridorder_js_ResalePrice"
tabs.14.fields.28.editor.allowBlank = "true"
tabs.14.fields.28.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#orders_gridorder_js_ResalePrice"
tabs.14.fields.35.name = "releatedthememarket[]"
tabs.14.fields.35.id = "releatedthememarket"
tabs.14.fields.35.fieldLabel = "article_backend_fieldLabel_releatedthememarket"
tabs.14.fields.35.editor.allowBlank = "false"
tabs.14.fields.35.editor.xtype = "superboxselect"
tabs.14.fields.35.editor.height = "450"
tabs.14.fields.35.editor.service = "articlemarketthemes"
tabs.14.fields.35.help = "admin/myadministration/shop/products/detail/webbasedlayoutersubproductandtemplate#article_backend_fieldLabel_releatedthememarket"
[System Operator : Shop Operator]
tabs.13.fields.318.name = "preis"
tabs.13.fields.318.fieldLabel = "Preis"
tabs.13.fields.318.editor.allowBlank = "false"
tabs.13.fields.319.name = "a9_price_motiv"
tabs.13.fields.319.fieldLabel = "Druckkosten Motiv"
tabs.13.fields.319.editor.allowBlank = "false"
tabs.13.fields.330.name = "a9_price_icon"
tabs.13.fields.330.fieldLabel = "Druckkosten Icon"
tabs.13.fields.330.editor.allowBlank = "false"
tabs.13.fields.332.name = "a9_price_text"
tabs.13.fields.332.fieldLabel = "Druckkosten Text"
tabs.13.fields.332.editor.allowBlank = "false"
tabs.13.fields.333.name = "a9_price_text_line1"
tabs.13.fields.333.fieldLabel = "Druckkosten Text pro + Zeile"
tabs.13.fields.333.editor.allowBlank = "false"
tabs.13.fields.334.name = "a9_price_print_disable"
tabs.13.fields.334.fieldLabel = "Druckkosten nicht berechnen"
tabs.13.fields.334.editor.xtype = "xcheckbox"
tabs.19.general.title = "ML Settings"
tabs.19.fields.30.name = "a9_sizes"
tabs.19.fields.30.fieldLabel = "Sizes"
tabs.19.fields.30.editor.allowBlank = "false"
tabs.19.fields.30.editor.xtype = "textarea"
tabs.19.fields.30.editor.height= "90"
tabs.19.fields.35.name = "a9_colors"
tabs.19.fields.35.fieldLabel = "Colors"
tabs.19.fields.35.editor.allowBlank = "false"
tabs.19.fields.35.editor.xtype = "textarea"
tabs.19.fields.35.editor.height= "90"
tabs.19.fields.45.name = "a9_pt"
tabs.19.fields.45.fieldLabel = "Drucktechnologie"
tabs.19.fields.45.editor.allowBlank = "false"
tabs.19.fields.46.name = "a9_front_area"
tabs.19.fields.46.fieldLabel = "Vorderseite"
tabs.19.fields.46.editor.allowBlank = "false"
tabs.19.fields.47.name = "a9_back_area"
tabs.19.fields.47.fieldLabel = "Rückseite"
tabs.19.fields.47.editor.allowBlank = "false"
tabs.19.fields.48.name = "a9_left_area"
tabs.19.fields.48.fieldLabel = "linke Seite"
tabs.19.fields.48.editor.allowBlank = "false"
tabs.19.fields.49.name = "a9_right_area"
tabs.19.fields.49.fieldLabel = "rechte Seite"
tabs.19.fields.49.editor.allowBlank = "false"
tabs.20.general.title = "ML Images"
tabs.20.fields.40.id = "self_name_sum1"
tabs.20.fields.40.name = "self_name_sum1"
tabs.20.fields.40.fieldLabel = "article_backend_fieldLabel_a9_1"
tabs.20.fields.40.editor.xtype = "compositefield"
tabs.20.fields.40.editor.height = "90"
tabs.20.fields.40.items.5.id = "a9_front1"
tabs.20.fields.40.items.5.name = "a9_front1"
tabs.20.fields.40.items.5.editor.allowBlank = "false"
tabs.20.fields.40.items.5.editor.xtype = "uploadfield"
tabs.20.fields.40.items.5.editor.id = "a9_front1"
tabs.20.fields.40.items.5.editor.name = "a9_front1"
tabs.20.fields.40.items.5.editor.height = "90"
tabs.20.fields.40.items.15.id = "a9_back1"
tabs.20.fields.40.items.15.name = "a9_back1"
tabs.20.fields.40.items.15.editor.allowBlank = "false"
tabs.20.fields.40.items.15.editor.xtype = "uploadfield"
tabs.20.fields.40.items.15.editor.id = "a9_back1"
tabs.20.fields.40.items.15.editor.name = "a9_back1"
tabs.20.fields.40.items.15.editor.height = "90"
tabs.20.fields.40.items.25.id = "a9_left1"
tabs.20.fields.40.items.25.name = "a9_left1"
tabs.20.fields.40.items.25.editor.allowBlank = "false"
tabs.20.fields.40.items.25.editor.xtype = "uploadfield"
tabs.20.fields.40.items.25.editor.id = "a9_left1"
tabs.20.fields.40.items.25.editor.name = "a9_left1"
tabs.20.fields.40.items.25.editor.height = "90"
tabs.20.fields.40.items.35.id = "a9_right1"
tabs.20.fields.40.items.35.name = "a9_right1"
tabs.20.fields.40.items.35.editor.allowBlank = "false"
tabs.20.fields.40.items.35.editor.xtype = "uploadfield"
tabs.20.fields.40.items.35.editor.id = "a9_right1"
tabs.20.fields.40.items.35.editor.name = "a9_right1"
tabs.20.fields.40.items.35.editor.height = "90"
tabs.20.fields.45.id = "self_name_sum2"
tabs.20.fields.45.name = "self_name_sum2"
tabs.20.fields.45.fieldLabel = "article_backend_fieldLabel_a9_2"
tabs.20.fields.45.editor.xtype = "compositefield"
tabs.20.fields.45.editor.height = "90"
tabs.20.fields.45.items.5.id = "a9_front2"
tabs.20.fields.45.items.5.name = "a9_front2"
tabs.20.fields.45.items.5.editor.allowBlank = "false"
tabs.20.fields.45.items.5.editor.xtype = "uploadfield"
tabs.20.fields.45.items.5.editor.id = "a9_front2"
tabs.20.fields.45.items.5.editor.name = "a9_front2"
tabs.20.fields.45.items.5.editor.height = "90"
tabs.20.fields.45.items.15.id = "a9_back2"
tabs.20.fields.45.items.15.name = "a9_back2"
tabs.20.fields.45.items.15.editor.allowBlank = "false"
tabs.20.fields.45.items.15.editor.xtype = "uploadfield"
tabs.20.fields.45.items.15.editor.id = "a9_back2"
tabs.20.fields.45.items.15.editor.name = "a9_back2"
tabs.20.fields.45.items.15.editor.height = "90"
tabs.20.fields.45.items.25.id = "a9_left2"
tabs.20.fields.45.items.25.name = "a9_left2"
tabs.20.fields.45.items.25.editor.allowBlank = "false"
tabs.20.fields.45.items.25.editor.xtype = "uploadfield"
tabs.20.fields.45.items.25.editor.id = "a9_left2"
tabs.20.fields.45.items.25.editor.name = "a9_left2"
tabs.20.fields.45.items.25.editor.height = "90"
tabs.20.fields.45.items.25.id = "a9_right2"
tabs.20.fields.45.items.35.name = "a9_right2"
tabs.20.fields.45.items.35.editor.allowBlank = "false"
tabs.20.fields.45.items.35.editor.xtype = "uploadfield"
tabs.20.fields.45.items.35.editor.id = "a9_right2"
tabs.20.fields.45.items.35.editor.name = "a9_right2"
tabs.20.fields.45.items.35.editor.height = "90"
tabs.20.fields.55.id = "self_name_sum3"
tabs.20.fields.55.name = "self_name_sum3"
tabs.20.fields.55.fieldLabel = "article_backend_fieldLabel_a9_3"
tabs.20.fields.55.editor.xtype = "compositefield"
tabs.20.fields.55.editor.height = "90"
tabs.20.fields.55.items.5.id = "a9_front3"
tabs.20.fields.55.items.5.name = "a9_front3"
tabs.20.fields.55.items.5.editor.allowBlank = "false"
tabs.20.fields.55.items.5.editor.xtype = "uploadfield"
tabs.20.fields.55.items.5.editor.id = "a9_front3"
tabs.20.fields.55.items.5.editor.name = "a9_front3"
tabs.20.fields.55.items.5.editor.height = "90"
tabs.20.fields.55.items.15.id = "a9_back3"
tabs.20.fields.55.items.15.name = "a9_back3"
tabs.20.fields.55.items.15.editor.allowBlank = "false"
tabs.20.fields.55.items.15.editor.xtype = "uploadfield"
tabs.20.fields.55.items.15.editor.id = "a9_back3"
tabs.20.fields.55.items.15.editor.name = "a9_back3"
tabs.20.fields.55.items.15.editor.height = "90"
tabs.20.fields.55.items.25.id = "a9_left3"
tabs.20.fields.55.items.25.name = "a9_left3"
tabs.20.fields.55.items.25.editor.allowBlank = "false"
tabs.20.fields.55.items.25.editor.xtype = "uploadfield"
tabs.20.fields.55.items.25.editor.id = "a9_left3"
tabs.20.fields.55.items.25.editor.name = "a9_left3"
tabs.20.fields.55.items.25.editor.height = "90"
tabs.20.fields.55.items.25.id = "a9_right3"
tabs.20.fields.55.items.35.name = "a9_right3"
tabs.20.fields.55.items.35.editor.allowBlank = "false"
tabs.20.fields.55.items.35.editor.xtype = "uploadfield"
tabs.20.fields.55.items.35.editor.id = "a9_right3"
tabs.20.fields.55.items.35.editor.name = "a9_right3"
tabs.20.fields.55.items.35.editor.height = "90"
tabs.20.fields.65.id = "self_name_sum4"
tabs.20.fields.65.name = "self_name_sum4"
tabs.20.fields.65.fieldLabel = "article_backend_fieldLabel_a9_4"
tabs.20.fields.65.editor.xtype = "compositefield"
tabs.20.fields.65.editor.height = "90"
tabs.20.fields.65.items.5.id = "a9_front4"
tabs.20.fields.65.items.5.name = "a9_front4"
tabs.20.fields.65.items.5.editor.allowBlank = "false"
tabs.20.fields.65.items.5.editor.xtype = "uploadfield"
tabs.20.fields.65.items.5.editor.id = "a9_front4"
tabs.20.fields.65.items.5.editor.name = "a9_front4"
tabs.20.fields.65.items.5.editor.height = "90"
tabs.20.fields.65.items.15.id = "a9_back4"
tabs.20.fields.65.items.15.name = "a9_back4"
tabs.20.fields.65.items.15.editor.allowBlank = "false"
tabs.20.fields.65.items.15.editor.xtype = "uploadfield"
tabs.20.fields.65.items.15.editor.id = "a9_back4"
tabs.20.fields.65.items.15.editor.name = "a9_back4"
tabs.20.fields.65.items.15.editor.height = "90"
tabs.20.fields.65.items.25.id = "a9_left4"
tabs.20.fields.65.items.25.name = "a9_left4"
tabs.20.fields.65.items.25.editor.allowBlank = "false"
tabs.20.fields.65.items.25.editor.xtype = "uploadfield"
tabs.20.fields.65.items.25.editor.id = "a9_left4"
tabs.20.fields.65.items.25.editor.name = "a9_left4"
tabs.20.fields.65.items.25.editor.height = "90"
tabs.20.fields.65.items.25.id = "a9_right4"
tabs.20.fields.65.items.35.name = "a9_right4"
tabs.20.fields.65.items.35.editor.allowBlank = "false"
tabs.20.fields.65.items.35.editor.xtype = "uploadfield"
tabs.20.fields.65.items.35.editor.id = "a9_right4"
tabs.20.fields.65.items.35.editor.name = "a9_right4"
tabs.20.fields.65.items.35.editor.height = "90"
tabs.20.fields.75.id = "self_name_sum5"
tabs.20.fields.75.name = "self_name_sum5"
tabs.20.fields.75.fieldLabel = "article_backend_fieldLabel_a9_5"
tabs.20.fields.75.editor.xtype = "compositefield"
tabs.20.fields.75.editor.height = "90"
tabs.20.fields.75.items.5.id = "a9_front5"
tabs.20.fields.75.items.5.name = "a9_front5"
tabs.20.fields.75.items.5.editor.allowBlank = "false"
tabs.20.fields.75.items.5.editor.xtype = "uploadfield"
tabs.20.fields.75.items.5.editor.id = "a9_front5"
tabs.20.fields.75.items.5.editor.name = "a9_front5"
tabs.20.fields.75.items.5.editor.height = "90"
tabs.20.fields.75.items.15.id = "a9_back5"
tabs.20.fields.75.items.15.name = "a9_back5"
tabs.20.fields.75.items.15.editor.allowBlank = "false"
tabs.20.fields.75.items.15.editor.xtype = "uploadfield"
tabs.20.fields.75.items.15.editor.id = "a9_back5"
tabs.20.fields.75.items.15.editor.name = "a9_back5"
tabs.20.fields.75.items.15.editor.height = "90"
tabs.20.fields.75.items.25.id = "a9_left5"
tabs.20.fields.75.items.25.name = "a9_left5"
tabs.20.fields.75.items.25.editor.allowBlank = "false"
tabs.20.fields.75.items.25.editor.xtype = "uploadfield"
tabs.20.fields.75.items.25.editor.id = "a9_left5"
tabs.20.fields.75.items.25.editor.name = "a9_left5"
tabs.20.fields.75.items.25.editor.height = "90"
tabs.20.fields.75.items.25.id = "a9_right5"
tabs.20.fields.75.items.35.name = "a9_right5"
tabs.20.fields.75.items.35.editor.allowBlank = "false"
tabs.20.fields.75.items.35.editor.xtype = "uploadfield"
tabs.20.fields.75.items.35.editor.id = "a9_right5"
tabs.20.fields.75.items.35.editor.name = "a9_right5"
tabs.20.fields.75.items.35.editor.height = "90"
[Admin : System Operator]

View File

@ -1 +0,0 @@
Calcarticle;Kalkulationsartikel
1 Calcarticle Kalkulationsartikel

View File

@ -45,22 +45,22 @@ class Orderspos extends BaseOrderspos
protected $calcReferences = [];
protected $additionalInfos = [];
protected $setConfig = [];
protected $customerInfo = "";
protected $customerInfo = '';
protected $xmlProduct = "";
protected $uploadMode = "";
protected $xmlProduct = '';
protected $uploadMode = '';
protected $mongoLoaded = false;
protected $reOrder = false;
protected $reOrderOrder = "";
protected $reOrderPos = "";
protected $reOrderOrder = '';
protected $reOrderPos = '';
protected $specialProductTypeObject = [];
public function preSave($event)
{
if ($this->uuid == '') {
$this->uuid = TP_Util::uuid();
}
if ($this->version == "") {
if ($this->version == '') {
$this->version = 0;
}
$this->version = $this->version + 1;
@ -68,11 +68,9 @@ class Orderspos extends BaseOrderspos
public function getPostionData($key)
{
$data = $this->getAllPostionData();
if ($this->count != 1 && $key == "auflage") {
if ($this->count != 1 && $key == 'auflage') {
return $this->count;
}
if (isset($data[$key])) {
@ -89,7 +87,7 @@ class Orderspos extends BaseOrderspos
public function getRef()
{
if ($this->ref == "") {
if ($this->ref == '') {
return $this->Article->getTitle();
}
@ -121,6 +119,7 @@ class Orderspos extends BaseOrderspos
$this->reOrder = (bool) $obj['reOrder'];
$this->reOrderOrder = (string) $obj['reOrderOrder'];
$this->reOrderPos = (string) $obj['reOrderPos'];
$this->specialProductTypeObject = $obj['specialProductTypeObject'];
$this->mongoLoaded = true;
}
}
@ -133,8 +132,8 @@ class Orderspos extends BaseOrderspos
$dbMongo->Position->updateOne(array('uid' => $this->id), ['$set' => $this->getArray()]);
} else {
$dbMongo->Position->insertOne($this->getArray());
} $this->mongoLoaded = true;
}
$this->mongoLoaded = true;
}
public function getArray()
@ -155,6 +154,7 @@ class Orderspos extends BaseOrderspos
'reOrder' => $this->reOrder,
'reOrderOrder' => $this->reOrderOrder,
'reOrderPos' => $this->reOrderPos,
'specialProductTypeObject' => $this->specialProductTypeObject,
);
}
@ -319,24 +319,40 @@ class Orderspos extends BaseOrderspos
{
$this->reOrder = $var;
}
public function setReOrderPos(string $var): void
{
$this->reOrderPos = $var;
}
public function setReOrderOrder(string $var): void
{
$this->reOrderOrder = $var;
}
public function setSpecialProductTypeObject(array $var): void
{
$this->specialProductTypeObject = $var;
}
public function getSpecialProductTypeObject(): array
{
$this->loadMongo();
return $this->specialProductTypeObject;
}
public function isReOrder(): bool
{
$this->loadMongo();
return $this->reOrder;
}
public function getReOrderOrder(): string
{
$this->loadMongo();
return $this->reOrderOrder;
}
public function getReOrderPos(): string
{
$this->loadMongo();

View File

@ -0,0 +1,245 @@
<script>
function loadFile(link, file, title) {
if(file == "pic") {
$('.thumbnail').html('<a href="' + link + '" data-lightbox="article_detail"><img id="layouter" src="' + link +'" class="articlelistimg " alt="' + title + '" title="' + title + '"></a>');
} else if(file == "youtube") {
$('.thumbnail').html('<iframe style="width:100%;" src="' + link + '" frameborder="0" allowfullscreen=""></iframe>');
}
}
</script>
<div class="row articletemplates-2">
<div class="col-xs-12">
<a class="btn-large pull-right" href="<?php echo $this->backurl ?>"><?php echo $this->translate('Zurück') ?></a>
<h1><?php echo $this->article->title ?></h1>
</div>
<div class="col-xs-12">
<ul class="nav nav-tabs" role="tablist">
<li class="active" role="presentation" ><a href="#details" data-toggle="tab"><?php echo $this->translate('Produkt') ?></a></li>
<?php if(!$this->designsettings()->get('einbetten')): ?><li><a href="#einbetten" data-toggle="tab"><?php echo $this->translate('Einbetten')?></a></li><?php endif; ?>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="details">
<div class="col-md-3">
<div class="thumbnail">
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file, true); ?>" data-lightbox="article_detail"><?php echo $this->image()->thumbnailImage($this->article->title, 'layouter', $this->article->file); ?></a>
<br/>
</div>
<?php if ($this->admin && $this->role->level >= 40): ?>
<a class="btn btn-inverse btn-large pop_over" data-trigger="hover" data-placement="bottom" data-content="Bearbeiten Sie die Eigenschaften des Produkts." data-original-title="Eigenschaften" onclick="javascript:window.open('/admin/article/edit?sid=<?= $this->article->shop_id ?>&uid=<?= $this->article->id ?>&type=<?= $this->article->typ ?>', 'contactWindow', 'width=800,height=600,top=10,left=10,directories=no,toolbar=no,location=no,menubar=no,scrollbars=no,status=no,resizable=yes,dependent=no');return false;" href="/myshop/editarticle/<?= $this->article->uuid ?>">
<span class="glyphicon glyphicon-folder-open"></span> &nbsp; <?php echo $this->translate('Eigenschaften bearbeiten')?>
</a>
<?php endif; ?>
</div>
<?php
/******************************************************************************************************************************************************************************
* Beginn SPalte 2
*/
?>
<div class="col-md-9">
<form method="post" action="">
<dl> <?php echo $this->form->auflage ?></dl> <?php echo $this->form->ajax_calc_id ?>
</form>
<?php
/**
* Produktkonfiguration und Summe:
* Verschachtelte Anzeige: daher: neue Row
*/
?>
<div class="row">
<div class="col-md-8" style="padding:0 2em">
<?php if ($this->article->lager_file_preview != ""): ?>
<a href="<?= $this->image()->thumbnailImage('test', 'test', $this->article->lager_file_preview, true, true) ?>"><?php $this->translate('Vorschau') ?></a>
<?php endif; ?>
<?= $this->article->info ?>
<p><br/></p>
</div>
<div class="col-md-4" style="padding-right: 0px;padding-left: 0px;">
<div class="well wellMobile2 andMobile" style="padding: 10px;">
<?php if(!$this->article->display_no_price): ?>
<?php if($this->article->stock): ?>
<label class="basketstocklabel"><?php echo $this->translate('Aktueller Bestand')?>: <?php echo $this->article->stock_count ?> <?php echo $this->translate('Stk.')?></label><br />
<?php endif; ?>
<?php if(!$this->article->display_no_price and !$this->designsettings()->get('display_no_price')): ?>
<h3><?php echo $this->translate('Summe')?></h3>
<br/>
<?php endif; ?>
<?php endif; ?>
<?php if($this->weight > 0): ?>
<p id="weight_display" class="text-info"><?php echo $this->translate('Gewicht')?>: <span><?php echo $this->weight ?></span>g</p>
<?php endif; ?>
<div class="wellforMobilePrice">
<?php if(!$this->article->display_no_price and !$this->designsettings()->get('display_no_price')): ?>
<table class="table">
<tbody>
<tr>
<td><?php echo $this->translate('Preis (netto)')?>:</td>
<td class="pull-right"><span
id="price_netto"><?= $this->currency->toCurrency($this->netto) ?></span>
</td>
</tr>
<tr>
<td><?= $this->translate('zzgl. ') ?> <?php echo $this->article->mwert; ?>% <?= $this->translate('MwSt.') ?></td>
<td class="pull-right"><span
id="price_steuer"><?= $this->currency->toCurrency(($this->brutto - $this->netto) * 1) ?></span>
</td>
</tr>
<tr>
<td><strong><?php echo $this->translate('Preis (brutto)')?>:</strong></td>
<td class="pull-right"><strong><span
id="price_brutto"><?= $this->currency->toCurrency($this->brutto) ?></span></strong>
</td>
</tr>
</tbody>
</table>
<?php endif; ?>
</div>
<div class="wellforMobileBTN">
<form action="/article/buy/?id=<?= $this->article->id ?>" target="_self" role="form" class="form-horizontal buy" id="buyform" method="POST" style="padding:8px">
<div class="form-group form-group-sm">
<label class="col-sm-3 control-label" for="count"><?php echo $this->translate('Anzahl')?>: </label>
<div class="col-sm-5 col-sm-offset-4">
<input type="text" value="1" class="form-control" name="count">
</div>
</div>
<div class="clearfix"></div>
<?= $this->formHidden('load', $this->load) ?>
<input type="submit" class="btn btn-success btn-large orderbtn"
value="<?= $this->translate('Buy') ?>">
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<?php if(!$this->designsettings()->get('einbetten')): ?>
<div class="tab-pane" id="einbetten">
<h2><?php echo $this->translate('Einbetten') ?></h2>
<p><?php echo $this->translate('Teilen Sie dieses Produkt mit Anderen, bewerben Sie es im eigenen BLOG oder Ihrer Website') ?></p>
<div class="htmlSnippet">
<textarea onclick="this.focus(); this.select();" style="width:99%; height: 180px;">
<?php echo $this->escape($this->htmlsnippet) ?>
</textarea>
</div>
</div>
<?php endif; ?>
</div>
<div class="clearfix"></div>
<div class="col-xs-12">
<!-- vorschau-bilder -->
<?php if($this->article->file1 != "" || $this->article->file2 != "" || $this->article->file3 != "" || $this->article->file4 != "" || $this->article->file5 != ""): ?>
<div class="vorschau-bilder-klein clearfix">
<?php if ($this->article->file1 != "") : ?>
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file1, true); ?>" data-lightbox="article_detail">
<img src="<?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file1, true); ?>" class="img-fluid">
</a>
<?php endif; ?>
<?php if ($this->article->file2 != "") : ?>
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file2, true); ?>" data-lightbox="article_detail">
<img src="<?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file2, true); ?>" class="img-fluid">
</a>
<?php endif; ?>
<?php if ($this->article->file3 != "") : ?>
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file3, true); ?>" data-lightbox="article_detail">
<img src="<?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file3, true); ?>" class="img-fluid">
</a>
<?php endif; ?>
<?php if ($this->article->file4 != "") : ?>
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file4, true); ?>" data-lightbox="article_detail">
<img src="<?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file4, true); ?>" class="img-fluid">
</a>
<?php endif; ?>
<?php if ($this->article->file5 != "") : ?>
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file5, true); ?>" data-lightbox="article_detail">
<img src="<?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file5, true); ?>" class="img-fluid">
</a>
<?php endif; ?>
<?php if ($this->article->file6 != "") : ?>
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file6, true); ?>" data-lightbox="article_detail">
<img src="<?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file6, true); ?>" class="img-fluid">
</a>
<?php endif; ?>
<?php if ($this->article->file7 != "") : ?>
<a href="<?php echo $this->image()->thumbnailImage($this->article->title, 'articlesinglegreater', $this->article->file7, true); ?>" data-lightbox="article_detail">
<img src="<?php echo $this->image()->thumbnailImage($this->article->title, 'little', $this->article->file7, true); ?>" class="img-fluid">
</a>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<hr />
<div class="col-md-4" style="padding-left: 0px;padding-right: 0px;">
<?php if($this->article->text_art != ""):?><?php echo $this->article->text_art ?><br/><?php endif; ?>
<?php if($this->article->text_format != ""):?><?php echo $this->article->text_format ?><br/><?php endif; ?>
<?php if($this->article->kostenstelle): ?>
<?= $this->translate('Kostenstelle') ?>: <?php echo $this->article->kostenstelle; ?><br />
<?php endif; ?>
<?php if($this->article->article_nr_extern): ?>
<?= $this->translate('Artikelnummer') ?>: <?php echo $this->article->article_nr_extern; ?><br />
<?php endif; ?>
<?php if($this->weight > 0): ?>
<p id="weight_display" class="text-info"><?= $this->translate('Gewicht') ?>: <span><?php echo $this->weight ?></span>g</p>
<?php endif; ?>
<?php if($this->article->article_nr_extern or $this->article->stock or $this->weight > 0): ?>
<?php endif; ?>
<p>
<br/><?php if($this->shop->install_id == 7):?><a target="_blank" href="/cms/zahlung-versand#lieferzeiten"><?php echo $this->translate('Die Lieferzeiten in der Übersicht')?></a><?php endif; ?>
</p>
</div>
<div class="col-md-5" style="padding-left: 0px;padding-right: 0px;">
<?php /*var_dump($this->article->getAblaufDatum(),"d.m.Y"); if($this->article->getAblaufDatum()) { echo "Ablaufdatum: " . date_format($this->article->getAblaufDatum(),"d.m.Y") . "<br />"; }*/
if($this->article->getZusatzDesigner() != "") {
echo $this->article->getZusatzDesigner() . "<br />";
}
if($this->article->getZusatzAbmessung() != "") {
echo $this->article->getZusatzAbmessung() . "<br />";
}
if($this->article->getZusatzShipping() != "") {
echo $this->article->getZusatzShipping() . "<br />";
}
if($this->article->getAnsprechPartner() != "") {
echo $this->article->getAnsprechPartner() . "<br />";
}
?>
</div>
<div class="clearfix"></div>
<div style="margin-bottom:50px;"><?php echo $this->article->getText() ?></div>
</div> <!-- // row articletemplates-2 -->

View File

@ -0,0 +1,20 @@
<?php
$basketArticle = $this->article['article'];
$filesOptions = $this->article['basketarticle']->getFiles();
?>
<div class="col-sm-4"><?php echo
$this->image()->thumbnailImage($basketArticle['title'], 'articlelist', $basketArticle['file'])
; ?></div>
<div class="col-sm-4"><?php echo $basketArticle['title'] ?></b></div>
<div class="col-sm-4" style="text-align: right;"> <a href="<?php echo
$this->url(array('del' => $this->article['uuid']), 'basketdel')
?>"><?php echo $this->translate('Löschen'); ?></a></p></div>
<div class="clearfix"></div>

View File

@ -36,7 +36,6 @@ $(function() {
});
$("#in_basket").click(function(event) {
if (($('#upload_mode').val() == 'none' || $('#upload_mode').val() == '') && $('#myUpload .modal-body > div').length > 0) {
@ -91,6 +90,36 @@ $(function() {
}
})
function updateBasketPos() {
var formElements = $('#CALCFORM').serializeArray();
var formArray = {};
$.each(formElements, function(index, value) {
var name = value.name;
var val = value.value;
if (name != "xmlProduct") {
formArray[name] = val;
}
});
var xmlProduct = "";
if ($('#CALCFORM select[name="xmlProduct"]').length > 0) {
xmlProduct = $('#CALCFORM select[name="xmlProduct"]').val();
}
if (productLoaded === 1) {
$.ajax({
url: "/apps/api/basket/legacy/update",
contentType: "application/json",
dataType: 'json',
method: 'post',
data: JSON.stringify({ productUUId: productUUId, values: formArray, count: 1, uploadMode: $('#upload_mode').val(), deliveryDate: delivery_date, deliveryInfo: delivery_info, xmlProduct: xmlProduct }),
success: function(result) {
}
});
return false;
}
}
function loadCalc(productUUId, firstLoad = false) {
var formArray = {};
@ -228,6 +257,7 @@ function loadCalc(productUUId, firstLoad = false) {
loadPreCalc(productUUId, false, result.preCalc);
}
bindCalcButtons();
updateBasketPos();
productXml = result.xmlProduct;
},
error: function(err) {