Backup
This commit is contained in:
parent
c27e6c3c7f
commit
b74708ca1a
BIN
src/Anleitung_V1.3.pdf.jpg
Normal file
BIN
src/Anleitung_V1.3.pdf.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
@ -1,12 +1,39 @@
|
||||
const Order_List_Detail = ({ uuid, basketField1, customerInfo, basketField2, pos, price, product, status, allNet, reOrder, reOrderOrder, reOrderPos }, orderUuid) => `
|
||||
const Order_List_Preview = (uploadTypeObject) => {
|
||||
const notAvailable = `<div class="shrink-0 w-28 h-28 rounded-md border-2 border-dashed border-gray-300 bg-white flex flex-col items-center justify-center text-gray-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-7 h-7 mb-1">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
<span class="text-xs">not available</span>
|
||||
</div>`;
|
||||
|
||||
if (!uploadTypeObject || !uploadTypeObject.preview || !uploadTypeObject.uploads || uploadTypeObject.uploads.length === 0) {
|
||||
return notAvailable;
|
||||
}
|
||||
|
||||
const fileIconHtml = (typ) => `<div style="display:none" class="w-28 h-28 rounded-md border border-gray-200 bg-gray-100 flex flex-col items-center justify-center text-gray-400 gap-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-7 h-7">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
|
||||
</svg>
|
||||
<span class="text-xs">${typ}</span>
|
||||
</div>`;
|
||||
|
||||
return uploadTypeObject.uploads.map(upload => {
|
||||
const previewUrl = `/apps/backend/order/upload/preview?path=${encodeURIComponent(upload.path)}`;
|
||||
return `<div class="shrink-0 flex flex-col items-center gap-1">
|
||||
<img src="${previewUrl}"
|
||||
class="w-28 h-28 object-cover rounded-md border border-gray-200 shadow-sm"
|
||||
title="${upload.fileName}"
|
||||
onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';" />
|
||||
${fileIconHtml(upload.typ)}
|
||||
<span class="text-xs text-gray-500">${upload.typ}</span>
|
||||
</div>`;
|
||||
}).join('');
|
||||
};
|
||||
|
||||
const Order_List_Detail = ({ uuid, basketField1, customerInfo, basketField2, pos, price, product, status, allNet, reOrder, reOrderOrder, reOrderPos, uploadTypeObject }, orderUuid) => `
|
||||
<div class="px-6 py-4 bg-gray-50" style="${psc.order.get_pos_bg_color(status)}">
|
||||
<div class="flex gap-4 items-start" id="row-${uuid}">
|
||||
<div class="shrink-0 w-28 h-28 rounded-md border-2 border-dashed border-gray-300 bg-white flex flex-col items-center justify-center text-gray-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-7 h-7 mb-1">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
|
||||
</svg>
|
||||
<span class="text-xs">Vorschau</span>
|
||||
</div>
|
||||
${Order_List_Preview(uploadTypeObject)}
|
||||
<div class="grid grid-cols-12 gap-4 flex-1">
|
||||
<div class="col-span-1">
|
||||
<span class="text-xs font-semibold text-gray-700">Pos:</span>
|
||||
|
||||
@ -5,28 +5,33 @@ declare(strict_types=1);
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$containerConfigurator->extension('monolog',
|
||||
['handlers' =>
|
||||
['main' =>
|
||||
[
|
||||
'type' => 'fingers_crossed',
|
||||
'action_level' => 'error',
|
||||
'handler' => 'nested',
|
||||
'excluded_http_codes' => [404, 405],
|
||||
'buffer_size' => 50
|
||||
],
|
||||
'nested' =>
|
||||
[
|
||||
'type' => 'stream',
|
||||
'path' => '%kernel.logs_dir%/%kernel.environment%.log',
|
||||
'level' => 'debug'
|
||||
],
|
||||
'console' =>
|
||||
[
|
||||
'type' => 'console',
|
||||
'process_psr_3_messages' => false,
|
||||
'channels' => ['!event', '!doctrine']
|
||||
]
|
||||
]
|
||||
]);
|
||||
$containerConfigurator->extension('monolog', [
|
||||
'channels' => ['ai'],
|
||||
'handlers' => [
|
||||
'ai' => [
|
||||
'type' => 'stream',
|
||||
'path' => '%kernel.logs_dir%/ai.log',
|
||||
'level' => 'debug',
|
||||
'channels' => ['ai'],
|
||||
],
|
||||
|
||||
'main' => [
|
||||
'type' => 'fingers_crossed',
|
||||
'action_level' => 'error',
|
||||
'handler' => 'nested',
|
||||
'excluded_http_codes' => [404, 405],
|
||||
'buffer_size' => 50,
|
||||
],
|
||||
'nested' => [
|
||||
'type' => 'stream',
|
||||
'path' => '%kernel.logs_dir%/%kernel.environment%.log',
|
||||
'level' => 'debug',
|
||||
],
|
||||
'console' => [
|
||||
'type' => 'console',
|
||||
'process_psr_3_messages' => false,
|
||||
'channels' => ['!event', '!doctrine'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
};
|
||||
|
||||
@ -26,10 +26,12 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
'role_hierarchy' => [
|
||||
'ROLE_SHOP' => 'ROLE_USER',
|
||||
'ROLE_PRODUCT_EDITOR' => ['ROLE_SHOP'],
|
||||
'ROLE_ORDER_VIEW' => ['ROLE_SHOP'],
|
||||
'ROLE_SHOP_OPERATOR' => [
|
||||
'ROLE_SHOP',
|
||||
'ROLE_PRODUCTION',
|
||||
'ROLE_PRODUCT_EDITOR',
|
||||
'ROLE_ORDER_VIEW',
|
||||
],
|
||||
'ROLE_SHOP_ADMIN' => [
|
||||
'ROLE_SHOP',
|
||||
@ -39,6 +41,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
'ROLE_SHOP',
|
||||
'ROLE_SHOP_OPERATOR',
|
||||
'ROLE_SHOP_ADMIN',
|
||||
'ROLE_ORDER_VIEW',
|
||||
],
|
||||
'ROLE_WAREHOUSE' => [
|
||||
'ROLE_USER',
|
||||
|
||||
@ -476,7 +476,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* datetime?: array{
|
||||
* default_format?: scalar|Param|null, // Default: "Y-m-d\\TH:i:sP"
|
||||
* default_deserialization_formats?: list<scalar|Param|null>,
|
||||
* default_timezone?: scalar|Param|null, // Default: "UTC"
|
||||
* default_timezone?: scalar|Param|null, // Default: "Europe/Berlin"
|
||||
* cdata?: scalar|Param|null, // Default: true
|
||||
* },
|
||||
* array_collection?: array{
|
||||
@ -576,7 +576,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
||||
* datetime?: array{
|
||||
* default_format?: scalar|Param|null, // Default: "Y-m-d\\TH:i:sP"
|
||||
* default_deserialization_formats?: list<scalar|Param|null>,
|
||||
* default_timezone?: scalar|Param|null, // Default: "UTC"
|
||||
* default_timezone?: scalar|Param|null, // Default: "Europe/Berlin"
|
||||
* cdata?: scalar|Param|null, // Default: true
|
||||
* },
|
||||
* array_collection?: array{
|
||||
|
||||
@ -15,12 +15,21 @@ class PdfTransformer implements PreviewTransformerInterface
|
||||
{
|
||||
$info = pathinfo($absolutePath);
|
||||
|
||||
if (isset($info['extension']) && false !== strpos(strtolower($info['extension']), 'pdf') && file_exists($absolutePath)) {
|
||||
if (
|
||||
isset($info['extension'])
|
||||
&& false !== strpos(strtolower($info['extension']), 'pdf')
|
||||
&& file_exists($absolutePath)
|
||||
) {
|
||||
// If it doesn't exist yet, extract the first page of the PDF
|
||||
$previewFilename = $this->getPreviewFilename($absolutePath);
|
||||
|
||||
if (!file_exists($previewFilename)) {
|
||||
exec("convert -background white -alpha remove -density 140 -resample 100 -colorspace sRGB '" . $absolutePath . "[0]' -quality 75 " . $previewFilename);
|
||||
exec(
|
||||
"convert -background white -alpha remove -density 140 -resample 100 -colorspace sRGB "
|
||||
. escapeshellarg($absolutePath . '[0]')
|
||||
. " -quality 75 "
|
||||
. escapeshellarg($previewFilename),
|
||||
);
|
||||
}
|
||||
|
||||
$absolutePath = $previewFilename;
|
||||
|
||||
@ -33,6 +33,7 @@ class Create extends AbstractController
|
||||
new MediaType('multipart/form-data', new Schema(properties: [
|
||||
new Property(property: 'file', format: 'binary', type: 'string', description: 'File to upload'),
|
||||
new Property(property: 'position', type: 'string', description: 'Position UUID'),
|
||||
new Property(property: 'typ', type: 'string', description: 'Typ'),
|
||||
], required: ['file', 'position'])),
|
||||
])]
|
||||
#[Response(
|
||||
|
||||
@ -49,6 +49,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Bridge\Twig\Attribute\Template;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
require_once __DIR__ . '/../../../EntityBundle/Lagacy/TP_Basket_Item.php';
|
||||
@ -65,6 +66,7 @@ class DetailController extends AbstractController
|
||||
{
|
||||
}
|
||||
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/detail/show/{uuid}/{enableDelivery}', defaults: ['enableDelivery' => 0], name: 'psc_shop_order_backend_detail_show')]
|
||||
#[Template('@PSCShopOrder/backend/detail/show.html.twig')]
|
||||
public function showAction(
|
||||
@ -350,6 +352,7 @@ class DetailController extends AbstractController
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
* @internal param Request $request
|
||||
*/
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/detail/switchposstatus/{order}/{pos}/{status}', name: 'psc_shop_order_backend_detail_switchposstatus')]
|
||||
#[Template('@PSCShopOrder/backend/detail/switchposstatus.html.twig')]
|
||||
public function switchPosStatusAction(EntityManagerInterface $entityManagerService, Manager $eventManagerService, Shop $shopService, $order = "", $pos = "", $status = 10)
|
||||
@ -382,6 +385,7 @@ class DetailController extends AbstractController
|
||||
* @param string $uuid
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/package/exported/{uuid}', name: 'psc_shop_order_backend_change_exported')]
|
||||
#[Template('@PSCShopOrder/backend/detail/setpackageexported.html.twig')]
|
||||
public function setPackageExportedAction(DocumentManager $mongoService, EntityManagerInterface $entityManagerService, Manager $eventManagerService, Shop $shopService, $uuid = "")
|
||||
@ -426,6 +430,7 @@ class DetailController extends AbstractController
|
||||
* @param string $uuid
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/detail/create/new/order/status/{uuid}', name: 'psc_shop_order_backend_create_new_order_status')]
|
||||
#[Template('@PSCShopOrder/backend/detail/createneworderstatus.html.twig')]
|
||||
public function createNewOrderStatus(DocumentManager $mongoService, EntityManagerInterface $entityManagerService, Manager $eventManagerService, Shop $shopService, $uuid = "")
|
||||
@ -481,6 +486,7 @@ class DetailController extends AbstractController
|
||||
* @param string $uuid
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/detail/delete/{uuid}', name: 'psc_shop_order_backend_detail_delete')]
|
||||
#[Template('@PSCShopOrder/backend/detail/deleteorder.html.twig')]
|
||||
public function deleteOrder(DocumentManager $mongoService, EntityManagerInterface $entityManagerService, Manager $eventManagerService, Shop $shopService, $uuid = "")
|
||||
|
||||
@ -66,7 +66,7 @@ class ListController extends AbstractController
|
||||
* @return array
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*/
|
||||
#[IsGranted('ROLE_ADMIN')]
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/list/index', name: 'psc_shop_order_backend_list_index')]
|
||||
#[Template('@PSCShopOrder/backend/list/index.html.twig')]
|
||||
public function indexAction(
|
||||
|
||||
@ -46,6 +46,7 @@ require_once(__DIR__ . '/../../../EntityBundle/Lagacy/TP_Basket_Item.php');
|
||||
|
||||
class PrintController extends AbstractController
|
||||
{
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/detail/print/{type}/{uuid}', name: 'psc_shop_order_backend_detail_print')]
|
||||
#[Template('@PSCShopOrder/backend/print/print.html.twig')]
|
||||
public function printAction(
|
||||
@ -89,6 +90,7 @@ class PrintController extends AbstractController
|
||||
return $response;
|
||||
}
|
||||
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/detail/printpos/{type}/{uuid}/{posuuid}', name: 'psc_shop_order_backend_detail_print_pos')]
|
||||
#[Template('@PSCShopOrder/backend/print/printpos.html.twig')]
|
||||
public function printPosAction(
|
||||
@ -180,6 +182,7 @@ class PrintController extends AbstractController
|
||||
return $response;
|
||||
}
|
||||
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/detail/xrechnung/{uuid}', name: 'psc_shop_order_backend_detail_xrechnung')]
|
||||
#[Template('@PSCShopOrder/backend/print/xrechnung.html.twig')]
|
||||
public function xrechnung(
|
||||
|
||||
@ -15,15 +15,17 @@ namespace PSC\Shop\OrderBundle\Controller\Backend;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PSC\Shop\EntityBundle\Entity\Motiv;
|
||||
use PSC\Shop\MediaBundle\Helper\Transformer\PdfTransformer;
|
||||
use PSC\Shop\OrderBundle\Form\Backend\Upload\DeleteType;
|
||||
use Symfony\Bridge\Twig\Attribute\Template;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\Security\Core\SecurityContext;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Bridge\Twig\Attribute\Template;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Core\SecurityContext;
|
||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
|
||||
/**
|
||||
* UploadController fürs Backend
|
||||
@ -33,6 +35,53 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
*/
|
||||
class UploadController extends AbstractController
|
||||
{
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/upload/preview', name: 'psc_shop_order_backend_upload_preview', methods: ['GET'])]
|
||||
public function previewAction(Request $request, PdfTransformer $pdfTransformer): BinaryFileResponse
|
||||
{
|
||||
$path = $request->query->get('path', '');
|
||||
|
||||
if (
|
||||
!str_starts_with($path, 'uploads/')
|
||||
|| str_contains($path, '..')
|
||||
|| str_contains($path, "\0")
|
||||
|| str_contains($path, "'")
|
||||
) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$absolutePath = $this->getParameter('kernel.project_dir') . '/../old/public/' . $path;
|
||||
|
||||
if (!file_exists($absolutePath)) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$previewPath = $pdfTransformer->apply($absolutePath);
|
||||
|
||||
$ext = strtolower(pathinfo($previewPath, PATHINFO_EXTENSION));
|
||||
if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
if (!file_exists($previewPath)) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$mimeMap = [
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'png' => 'image/png',
|
||||
'gif' => 'image/gif',
|
||||
'webp' => 'image/webp',
|
||||
];
|
||||
$response = new BinaryFileResponse($previewPath);
|
||||
$response->headers->set('Content-Type', $mimeMap[$ext] ?? 'image/jpeg');
|
||||
$response->setPublic();
|
||||
$response->setMaxAge(3600);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Seite
|
||||
*
|
||||
@ -44,19 +93,19 @@ class UploadController extends AbstractController
|
||||
* @return array|View|\Symfony\Component\HttpFoundation\RedirectResponse
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*/
|
||||
#[IsGranted('ROLE_ORDER_VIEW')]
|
||||
#[Route(path: '/upload/deleteAll/{uuid}', name: 'psc_shop_order_backend_upload_deleteAll')]
|
||||
#[Template('@PSCShopOrder/backend/upload/deleteall.html.twig')]
|
||||
public function deleteAllAction(
|
||||
Request $request,
|
||||
\PSC\System\SettingsBundle\Service\Shop $shopService,
|
||||
EntityManagerInterface $entityManager,
|
||||
$uuid = ""
|
||||
$uuid = '',
|
||||
) {
|
||||
|
||||
$selectedShop = $shopService->getSelectedShop();
|
||||
$order = $entityManager
|
||||
->getRepository('PSC\Shop\EntityBundle\Entity\Order')
|
||||
->findOneBy(array('shop' => $selectedShop, 'uuid' => $uuid));
|
||||
->getRepository('PSC\Shop\EntityBundle\Entity\Order')
|
||||
->findOneBy(array('shop' => $selectedShop, 'uuid' => $uuid));
|
||||
$form = $this->createForm(DeleteType::class);
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
@ -64,7 +113,7 @@ class UploadController extends AbstractController
|
||||
foreach ($order->getPositions() as $position) {
|
||||
foreach ($position->getUploads() as $upload) {
|
||||
if (file_exists($upload->getPath())) {
|
||||
unlink($upload->getPath());
|
||||
unlink($upload->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,7 +124,7 @@ class UploadController extends AbstractController
|
||||
|
||||
return array(
|
||||
'order' => $order,
|
||||
'form' => $form->createView()
|
||||
'form' => $form->createView(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ class ConfigureMenuListener
|
||||
*/
|
||||
public function onMenuConfigureMain(ConfigureMenuEvent $event)
|
||||
{
|
||||
if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
|
||||
if ($this->authorizationChecker->isGranted('ROLE_ORDER_VIEW')) {
|
||||
$menu = $event->getMenu();
|
||||
$menu->addChild('Aufträge', array(
|
||||
'route' => 'psc_shop_order_backend_list_index',
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
namespace PSC\Shop\OrderBundle\Model\Order\Position\Upload;
|
||||
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position\Upload;
|
||||
|
||||
class Center implements IUploadTypeObject
|
||||
{
|
||||
public array $uploads = [];
|
||||
@ -18,10 +20,10 @@ class Center implements IUploadTypeObject
|
||||
|
||||
public function canPreview(): bool
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function addUpload(array $upload): void
|
||||
public function addUpload(Upload $upload): void
|
||||
{
|
||||
$this->uploads[] = $upload;
|
||||
}
|
||||
|
||||
@ -441,7 +441,7 @@
|
||||
<tbody>
|
||||
{% for pos in positions %}
|
||||
{% set posModel = orderModel.getPositionByUuid(pos.obj.uuid) %}
|
||||
<tr class="border-t border-stroke hover:bg-gray-50">
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-3 py-3 font-medium">{{ pos.obj.pos }}</td>
|
||||
<td class="px-3 py-3">
|
||||
<a href="{{ path('backend_production_product_edit', {uuid: pos.obj.product.uuid}) }}" class="text-psc-500 hover:underline font-medium">{{ pos.obj.product.title }}</a>
|
||||
@ -480,7 +480,7 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-t border-dashed border-gray-200 bg-gray-50">
|
||||
<tr class="">
|
||||
<td class="px-3 py-2"></td>
|
||||
<td class="px-3 py-2">
|
||||
{% if pos.objDoc.setConfig|length > 0 %}
|
||||
@ -528,7 +528,7 @@
|
||||
{{ form_start(pos.formProdinfo) }}
|
||||
<div class="flex-1">{{ form_widget(pos.formProdinfo.customerInfo) }}</div>
|
||||
{{ form_rest(pos.formProdinfo) }}
|
||||
<button class="inline-flex items-center px-2.5 py-1.5 rounded-sm text-xs font-medium text-white bg-blue-500 hover:bg-blue-600 shadow-sm shrink-0" type="submit">Dem Kunden zeigen</button>
|
||||
<button class="inline-flex items-center px-2.5 py-1.5 rounded-sm text-xs font-medium text-white bg-blue-500 hover:bg-blue-600 shadow-sm shrink-0" type="submit">Dem Kunden in seinem Account anzeigen</button>
|
||||
{{ form_end(pos.formProdinfo) }}
|
||||
</div>
|
||||
{% if posModel.reOrder %}
|
||||
@ -538,7 +538,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-t border-dashed border-gray-200 bg-gray-50">
|
||||
<tr class="">
|
||||
<td class="px-3 py-2" colspan="10">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{% if shop.docOfferPosition != "" %}<a target="_blank" href="{{ path('psc_shop_order_backend_detail_print_pos', { uuid: order.uuid, posuuid: pos.obj.uuid, type: 5}) }}" class="inline-flex items-center gap-1 px-2.5 py-1 rounded-sm text-xs font-medium text-gray-700 bg-white border border-gray-300 hover:bg-gray-50 shadow-sm"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 16.5V9.75m0 0l3 3m-3-3l-3 3M6.75 19.5a4.5 4.5 0 01-1.41-8.775 5.25 5.25 0 0110.233-2.33 3 3 0 013.758 3.848A3.752 3.752 0 0118 19.5H6.75z" /></svg>{{'offer'|trans}}</a>{% endif %}
|
||||
@ -551,6 +551,29 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% if pos.obj.uploads|length > 0 %}
|
||||
<tr class="">
|
||||
<td class="px-3 py-3" colspan="10">
|
||||
<div class="flex flex-wrap gap-3">
|
||||
{% for upload in pos.obj.uploads %}
|
||||
<div class="flex flex-col items-center gap-1">
|
||||
<img src="/apps/backend/order/upload/preview?path={{ upload.path|url_encode }}"
|
||||
class="w-28 h-28 object-cover rounded-md border border-gray-200 shadow-sm"
|
||||
title="{{ upload.name }}"
|
||||
onerror="this.style.display='none'; this.nextElementSibling.style.display='flex';" />
|
||||
<div style="display:none" class="w-28 h-28 rounded-md border border-gray-200 bg-gray-100 flex flex-col items-center justify-center text-gray-400 gap-1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-7 h-7">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z" />
|
||||
</svg>
|
||||
<span class="text-xs">{{ upload.typ }}</span>
|
||||
</div>
|
||||
<span class="text-xs text-gray-500">{{ upload.name }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td colspan="10" class="h-1 bg-psc-500 p-0"></td>
|
||||
</tr>
|
||||
|
||||
@ -5,6 +5,7 @@ namespace PSC\Shop\OrderBundle\Transformer\Order\Position\Upload;
|
||||
use PSC\Shop\EntityBundle\Document\Position as PosDoc;
|
||||
use PSC\Shop\EntityBundle\Entity\Orderpos;
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position;
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position\Upload;
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position\Upload\Center as PSCCenter;
|
||||
use PSC\Shop\OrderBundle\Transformer\Order\Position\IUploadModeTransformer;
|
||||
|
||||
@ -14,10 +15,13 @@ class Center implements IUploadModeTransformer
|
||||
{
|
||||
$center = new PSCCenter();
|
||||
foreach ($posEntity->getUploads() as $upload) {
|
||||
var_dump($upload->getName());
|
||||
var_dump($upload->getPath());
|
||||
$up = new Upload();
|
||||
$up->setFileName($upload->getName());
|
||||
$up->setTyp($upload->getTyp());
|
||||
$up->setChunkTitle((string) $upload->getChunktitle());
|
||||
$up->setPath($upload->getPath());
|
||||
$center->addUpload($up);
|
||||
}
|
||||
$center->addUpload(['fileName' => 'test', 'name' => 'test', 'type' => 'umschlag']);
|
||||
$position->setUploadTypeObject($center);
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@ use PSC\System\SettingsBundle\Service\Log;
|
||||
use PSC\System\SettingsBundle\Service\Printing;
|
||||
use PSC\System\SettingsBundle\Service\TemplateVars;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
@ -408,7 +409,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render($params));
|
||||
$message->html($html->render(array_merge($params, [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $message),
|
||||
])));
|
||||
}
|
||||
$this->_logService->createLogEntry(
|
||||
$shop,
|
||||
@ -444,9 +447,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
$event instanceof UnLock ||
|
||||
$event instanceof \PSC\Shop\QueueBundle\Event\Contact\Create ||
|
||||
$event instanceof \PSC\Shop\QueueBundle\Event\Contact\Login
|
||||
$event instanceof UnLock
|
||||
|| $event instanceof \PSC\Shop\QueueBundle\Event\Contact\Create
|
||||
|| $event instanceof \PSC\Shop\QueueBundle\Event\Contact\Login
|
||||
) {
|
||||
$contactRepo = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Contact');
|
||||
/**
|
||||
@ -488,7 +491,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render($params));
|
||||
$message->html($html->render(array_merge($params, [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $message),
|
||||
])));
|
||||
}
|
||||
$this->_logService->createLogEntry(
|
||||
$shop,
|
||||
@ -561,7 +566,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render($params));
|
||||
$message->html($html->render(array_merge($params, [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $message),
|
||||
])));
|
||||
}
|
||||
$this->_logService->createLogEntry(
|
||||
$shop,
|
||||
@ -636,7 +643,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render($params));
|
||||
$message->html($html->render(array_merge($params, [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $message),
|
||||
])));
|
||||
}
|
||||
|
||||
$this->_logService->createLogEntry(
|
||||
@ -708,7 +717,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render($params));
|
||||
$message->html($html->render(array_merge($params, [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $message),
|
||||
])));
|
||||
}
|
||||
|
||||
$content = $printing->generatePosition($position, Printing::JOBTICKET_PRINTPARTNER);
|
||||
@ -750,7 +761,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render($templateVars->getPosTwigVars($position->getUuid())));
|
||||
$message->html($html->render(array_merge($templateVars->getPosTwigVars($position->getUuid(), [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $html),
|
||||
]))));
|
||||
}
|
||||
|
||||
if ($mailDoc->isSendInvoice()) {
|
||||
@ -893,10 +906,10 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
$event instanceof Create ||
|
||||
$event instanceof Uploaded ||
|
||||
$event instanceof \PSC\Shop\QueueBundle\Event\Order\Status\Change ||
|
||||
$event instanceof \PSC\Shop\QueueBundle\Event\Offer\Create
|
||||
$event instanceof Create
|
||||
|| $event instanceof Uploaded
|
||||
|| $event instanceof \PSC\Shop\QueueBundle\Event\Order\Status\Change
|
||||
|| $event instanceof \PSC\Shop\QueueBundle\Event\Offer\Create
|
||||
) {
|
||||
$templateVars->loadOrder($event->getOrder());
|
||||
try {
|
||||
@ -918,7 +931,9 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
}
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render($templateVars->getTwigVars()));
|
||||
$message->html($html->render(array_merge($templateVars->getTwigVars(), [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $html),
|
||||
])));
|
||||
}
|
||||
|
||||
if ($mailDoc->isSendInvoice()) {
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace PSC\System\UpdateBundle\Migrations;
|
||||
|
||||
class Version20260303100000 extends Base
|
||||
{
|
||||
public function migrateDatabase(): void
|
||||
{
|
||||
$this->entityManager->getConnection()->executeQuery("INSERT IGNORE INTO role (name, level) VALUES ('ROLE_ORDER_VIEW', 22);");
|
||||
}
|
||||
}
|
||||
@ -105,7 +105,7 @@ class CreateCenterTest extends WebTestCase
|
||||
$client->request(
|
||||
'POST',
|
||||
'/api/upload/create',
|
||||
['position' => $positionUuid, 'type' => 'umschlag'],
|
||||
['position' => $positionUuid, 'typ' => 'umschlag'],
|
||||
['file' => new UploadedFile($tmpUmschlag, 'umschlag.pdf', 'application/pdf', null, true)],
|
||||
['HTTP_apiKey' => $shop->getApiKey()],
|
||||
);
|
||||
@ -115,7 +115,7 @@ class CreateCenterTest extends WebTestCase
|
||||
$client->request(
|
||||
'POST',
|
||||
'/api/upload/create',
|
||||
['position' => $positionUuid, 'type' => 'inhalt'],
|
||||
['position' => $positionUuid, 'typ' => 'inhalt'],
|
||||
['file' => new UploadedFile($tmpInhalt, 'inhalt.pdf', 'application/pdf', null, true)],
|
||||
['HTTP_apiKey' => $shop->getApiKey()],
|
||||
);
|
||||
@ -137,9 +137,7 @@ class CreateCenterTest extends WebTestCase
|
||||
self::assertSame(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$data = json_decode($client->getResponse()->getContent(), true);
|
||||
|
||||
self::assertCount(2, $data['positions'][0]['uploads']);
|
||||
var_dump($data['positions'][0]['uploadTypeObject']['uploads']);
|
||||
self::assertSame('umschlag.pdf', $data['positions'][0]['uploadTypeObject']['uploads'][0]['fileName']);
|
||||
self::assertSame('umschlag', $data['positions'][0]['uploadTypeObject']['uploads'][0]['typ']);
|
||||
self::assertSame('inhalt.pdf', $data['positions'][0]['uploadTypeObject']['uploads'][1]['fileName']);
|
||||
|
||||
@ -2072,6 +2072,11 @@ html {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.object-cover{
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.p-0{
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ changelog:
|
||||
- version: 2.3.3
|
||||
datum: 25.02.2026
|
||||
changes:
|
||||
- "Auftragsdetails in Tailwind"
|
||||
- "Bereich Aufträge hat jetzt eigene Benutzergruppe"
|
||||
- "In EMails können Bilder eingebettet werden: {{ email.image('@images/logo.png') }}"
|
||||
- "Fix Graphgeneration in Calc"
|
||||
- version: 2.3.2
|
||||
datum: 17.02.2026
|
||||
|
||||
BIN
src/new/web/Anleitung_V1.3.pdf.jpg
Normal file
BIN
src/new/web/Anleitung_V1.3.pdf.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
BIN
src/old/market/steplayouter/basket/283/1/AF-03.03.2026-78_1.pdf
Normal file
BIN
src/old/market/steplayouter/basket/283/1/AF-03.03.2026-78_1.pdf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 638 KiB |
Loading…
Reference in New Issue
Block a user