Final
This commit is contained in:
parent
60148d9c9e
commit
a22df31b30
@ -64,10 +64,10 @@ server {
|
||||
try_files $uri @sfFront;
|
||||
}
|
||||
|
||||
location /w2p/ {
|
||||
proxy_pass http://tp:8080/w2p/;
|
||||
proxy_temp_path /tmp/proxy;
|
||||
}
|
||||
# location /w2p/ {
|
||||
# proxy_pass http://tp:8080/w2p/;
|
||||
# proxy_temp_path /tmp/proxy;
|
||||
#}
|
||||
|
||||
location @sfFront { # Symfony
|
||||
if ($request_method = 'OPTIONS') {
|
||||
|
||||
@ -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: "Europe/Berlin"
|
||||
* default_timezone?: scalar|Param|null, // Default: "UTC"
|
||||
* 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: "Europe/Berlin"
|
||||
* default_timezone?: scalar|Param|null, // Default: "UTC"
|
||||
* cdata?: scalar|Param|null, // Default: true
|
||||
* },
|
||||
* array_collection?: array{
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<span class="hidden md:inline"><input type="checkbox" class=" border-gray-300 rounded-sm shadow-sm text-primary-600 outline-none focus:ring focus:ring-primary-200 focus:ring-opacity-50" onchange="window.location='{{ path('psc_backend_dashboard_toogle_deleted_shop') }}'" {% if displayDeletedShop %}checked="checked"{% endif %}/> Deaktive Shops zeigen</span>
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
@ -26,15 +26,15 @@ class Get extends AbstractController
|
||||
|
||||
#[Response(
|
||||
response: 200,
|
||||
description: 'my shops',
|
||||
description: 'all shops',
|
||||
content: new JsonContent(ref: new Model(type: PSC\Component\ApiBundle\Dto\Shop\Shops\Output::class)),
|
||||
)]
|
||||
#[Tag(name: 'Shops')]
|
||||
#[Security(name: 'ApiKeyAuth')]
|
||||
#[Security(name: 'Bearer')]
|
||||
#[Route(path: '/my_shops', methods: ['GET'])]
|
||||
#[Route(path: '/shops', methods: ['GET'])]
|
||||
#[IsGranted('ROLE_SHOP')]
|
||||
public function myShops(): JsonResponse
|
||||
public function allShops(): JsonResponse
|
||||
{
|
||||
$shops = $this->entityManager->getRepository(\PSC\Shop\EntityBundle\Entity\Shop::class)->findAll();
|
||||
|
||||
@ -49,15 +49,15 @@ class Get extends AbstractController
|
||||
|
||||
#[Response(
|
||||
response: 200,
|
||||
description: 'shops',
|
||||
description: 'my shops',
|
||||
content: new JsonContent(ref: new Model(type: PSC\Component\ApiBundle\Dto\Shop\Shops\Output::class)),
|
||||
)]
|
||||
#[Tag(name: 'Shops')]
|
||||
#[Security(name: 'ApiKeyAuth')]
|
||||
#[Security(name: 'Bearer')]
|
||||
#[Route(path: '/shops', methods: ['GET'])]
|
||||
#[Route(path: '/my_shops', methods: ['GET'])]
|
||||
#[IsGranted('ROLE_SHOP')]
|
||||
public function allAction(): JsonResponse
|
||||
public function myAction(): JsonResponse
|
||||
{
|
||||
$shops = $this->shopContactRepository->myEditableShops($this->getUser());
|
||||
|
||||
|
||||
@ -60,10 +60,12 @@ class Save extends AbstractController
|
||||
$row->setLayouterModus($data->layouterModus);
|
||||
// TODO: Store uploadedFiles in session data
|
||||
$this->entityManager->persist($row);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'layouterUUId' => $row->getUuid(),
|
||||
'layouterModus' => $row->getLayouterModus(),
|
||||
'auth' => true,
|
||||
'user' => $this->tokenStorage
|
||||
->getToken()
|
||||
|
||||
@ -23,7 +23,7 @@ class LayouterSession
|
||||
#[ORM\Column(name: 'title', type: 'string', length: 255, nullable: true)]
|
||||
protected string $title;
|
||||
|
||||
#[ORM\Column(name: 'org_article_id', type: 'integer')]
|
||||
#[ORM\Column(name: 'org_article_id', type: 'string', length: 40, nullable: true)]
|
||||
protected string $productId;
|
||||
|
||||
#[ORM\Column(name: 'contact_id', type: 'integer')]
|
||||
|
||||
@ -120,6 +120,9 @@ class Orderpos
|
||||
*/
|
||||
#[ORM\Column(name: 'external_approval_status', type: 'integer', nullable: true)]
|
||||
private ?int $externalApprovalStatus = null;
|
||||
|
||||
#[ORM\Column(name: 'external_approval_message', type: 'text', nullable: true)]
|
||||
private ?string $externalApprovalMessage = null;
|
||||
/**
|
||||
* @var Product
|
||||
*/
|
||||
@ -219,17 +222,17 @@ class Orderpos
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
#[ORM\Column(name: 'delivery_date', type: 'date', nullable: false)]
|
||||
#[ORM\Column(name: 'delivery_date', type: 'date', nullable: true)]
|
||||
private $deliveryDate;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
#[ORM\Column(name: 'maschine', type: 'integer', nullable: false)]
|
||||
#[ORM\Column(name: 'maschine', type: 'integer', nullable: true)]
|
||||
private $maschine;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
#[ORM\Column(name: 'papier', type: 'integer', nullable: false)]
|
||||
#[ORM\Column(name: 'papier', type: 'integer', nullable: true)]
|
||||
private $papier;
|
||||
/**
|
||||
* @var \DateTime
|
||||
@ -1046,4 +1049,14 @@ class Orderpos
|
||||
{
|
||||
$this->externalApprovalStatus = $status;
|
||||
}
|
||||
|
||||
public function getExternalApprovalMessage(): ?string
|
||||
{
|
||||
return $this->externalApprovalMessage;
|
||||
}
|
||||
|
||||
public function setExternalApprovalMessage(?string $message): void
|
||||
{
|
||||
$this->externalApprovalMessage = $message;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,19 @@
|
||||
|
||||
namespace PSC\Shop\OrderBundle\Controller;
|
||||
|
||||
use Doctrine\ODM\MongoDB\DocumentManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PSC\Library\Calc\Engine;
|
||||
use PSC\Library\Calc\PaperContainer;
|
||||
use PSC\Shop\EntityBundle\Document\Position;
|
||||
use PSC\Shop\EntityBundle\Document\Product;
|
||||
use PSC\Shop\EntityBundle\Entity\Orderpos;
|
||||
use PSC\Shop\EntityBundle\Entity\Upload;
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position as AliasedPosition;
|
||||
use PSC\Shop\OrderBundle\Transformer\Order\Position as PSCPosition;
|
||||
use PSC\Shop\QueueBundle\Event\Position\ApprovalExternalAccept;
|
||||
use PSC\Shop\QueueBundle\Event\Position\ApprovalExternalDeclined;
|
||||
use PSC\System\SettingsBundle\Service\PaperDB;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -16,22 +26,49 @@ use Symfony\Component\Routing\Attribute\Route;
|
||||
class ExternalApprovalController extends AbstractController
|
||||
{
|
||||
#[Route(path: '/{uuid}', name: 'psc_shop_order_external_approval_show', methods: ['GET', 'POST'])]
|
||||
public function show(string $uuid, Request $request, EntityManagerInterface $em): Response
|
||||
{
|
||||
public function show(
|
||||
string $uuid,
|
||||
Request $request,
|
||||
EntityManagerInterface $em,
|
||||
DocumentManager $dm,
|
||||
PaperDB $paperService,
|
||||
\PSC\Shop\QueueBundle\Service\Event\Manager $eventManagerService,
|
||||
PSCPosition $positionTransformer,
|
||||
): Response {
|
||||
/** @var Orderpos|null $orderpos */
|
||||
$orderpos = $em->getRepository(Orderpos::class)->findOneBy(['uuid' => $uuid]);
|
||||
$orderposDoc = $dm->getRepository(Position::class)->findOneBy(['uid' => $orderpos->getUid()]);
|
||||
|
||||
if (!$orderpos) {
|
||||
throw $this->createNotFoundException('Position nicht gefunden.');
|
||||
}
|
||||
$position = new AliasedPosition();
|
||||
$positionTransformer->fromDb($position, $orderpos, $orderposDoc);
|
||||
|
||||
if ($request->isMethod('POST')) {
|
||||
$action = $request->request->get('action');
|
||||
$message = trim($request->request->get('message', ''));
|
||||
|
||||
if ($action === 'approve') {
|
||||
$orderpos->setExternalApprovalStatus(1);
|
||||
$notify = new ApprovalExternalAccept();
|
||||
$notify->setShop($orderpos->getOrder()->getShop()->getUID());
|
||||
$notify->setOrder($orderpos->getOrder()->getUuid());
|
||||
$notify->setPosition($orderpos->getUuid());
|
||||
$notify->setMessage($message);
|
||||
$eventManagerService->addJob($notify);
|
||||
} elseif ($action === 'reject') {
|
||||
$orderpos->setExternalApprovalStatus(-1);
|
||||
$notify = new ApprovalExternalDeclined();
|
||||
$notify->setShop($orderpos->getOrder()->getShop()->getUID());
|
||||
$notify->setOrder($orderpos->getOrder()->getUuid());
|
||||
$notify->setPosition($orderpos->getUuid());
|
||||
$notify->setMessage($message);
|
||||
$eventManagerService->addJob($notify);
|
||||
}
|
||||
|
||||
if ($message !== '') {
|
||||
$orderpos->setExternalApprovalMessage($message);
|
||||
}
|
||||
|
||||
$em->flush();
|
||||
@ -39,8 +76,12 @@ class ExternalApprovalController extends AbstractController
|
||||
return $this->redirectToRoute('psc_shop_order_external_approval_show', ['uuid' => $uuid]);
|
||||
}
|
||||
|
||||
$articleCalc = $this->buildCalc($orderpos, $dm, $paperService);
|
||||
|
||||
return $this->render('@PSCShopOrder/external_approval/show.html.twig', [
|
||||
'orderpos' => $orderpos,
|
||||
'articleCalc' => $articleCalc,
|
||||
'position' => $position,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -72,4 +113,50 @@ class ExternalApprovalController extends AbstractController
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function buildCalc(Orderpos $orderpos, DocumentManager $dm, PaperDB $paperService): ?object
|
||||
{
|
||||
if (!$orderpos->hasCalcXml()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$shop = $orderpos->getOrder()->getShop();
|
||||
|
||||
/** @var Position|null $objDoc */
|
||||
$objDoc = $dm->getRepository(Position::class)->findOneBy(['uid' => (string) $orderpos->getId()]);
|
||||
|
||||
$paperContainer = new PaperContainer();
|
||||
$paperContainer->parse(simplexml_load_string($shop->getInstall()->getPaperContainer()));
|
||||
|
||||
$engine = new Engine();
|
||||
$engine->setPaperRepository($paperService);
|
||||
$engine->setPaperContainer($paperContainer);
|
||||
|
||||
if ($shop->getInstall()->getCalcTemplates()) {
|
||||
$engine->setTemplates('<root>' . $shop->getInstall()->getCalcTemplates() . '</root>');
|
||||
}
|
||||
|
||||
$engine->loadString($orderpos->getCalcXml());
|
||||
$engine->setFormulas($shop->getFormel());
|
||||
$engine->setParameters($shop->getParameter());
|
||||
|
||||
if ($objDoc && isset($objDoc->getSpecialProductTypeObject()['params'])) {
|
||||
$engine->setVariables($objDoc->getSpecialProductTypeObject()['params']);
|
||||
$engine->setSavedCalcReferences($objDoc->getCalcReferences());
|
||||
if (isset($objDoc->getSpecialProductTypeObject()['kalk_artikel'])) {
|
||||
$engine->setActiveArticle($objDoc->getSpecialProductTypeObject()['kalk_artikel']);
|
||||
}
|
||||
} elseif ($orderpos->getData()) {
|
||||
$objPosition = unserialize($orderpos->getData());
|
||||
$engine->setVariables($objPosition->getOptions());
|
||||
if (isset($objPosition->getOptions()['kalk_artikel'])) {
|
||||
$engine->setActiveArticle($objPosition->getOptions()['kalk_artikel']);
|
||||
}
|
||||
if ($objDoc && $objDoc->getXmlProduct() !== '') {
|
||||
$engine->setActiveArticle($objDoc->getXmlProduct());
|
||||
}
|
||||
}
|
||||
|
||||
return $engine->getArticle();
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@
|
||||
|
||||
namespace PSC\Shop\OrderBundle\Form\Backend;
|
||||
|
||||
use PSC\System\SettingsBundle\Service\Status;
|
||||
use Spiriit\Bundle\FormFilterBundle\Filter\Form\Type\TextFilterType;
|
||||
use Spiriit\Bundle\FormFilterBundle\Filter\Query\QueryInterface;
|
||||
use PSC\System\SettingsBundle\Service\Status;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@ -26,8 +26,9 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
class SearchType extends AbstractType
|
||||
{
|
||||
protected $status = array();
|
||||
/** @var Session */
|
||||
/** @var Session */
|
||||
protected $session;
|
||||
|
||||
public function __construct(RequestStack $requestStack, Status $status)
|
||||
{
|
||||
$this->status = $status->getOrderStatusAsArray();
|
||||
@ -37,51 +38,74 @@ class SearchType extends AbstractType
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$session = $this->session;
|
||||
$builder
|
||||
->setMethod('POST')
|
||||
->add('term', TextFilterType::class, array(
|
||||
'data' => $session->get('order_search_term'),
|
||||
'apply_filter' => function (QueryInterface $filterQuery, $field, $values) use ($session) {
|
||||
|
||||
$session->set('order_search_term', $values['value']);
|
||||
if (empty($values['value'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filterQuery->getQueryBuilder()
|
||||
->andWhere("(
|
||||
orders.basketfield1 LIKE '%" . $values['value'] . "%' OR
|
||||
orders.basketfield2 LIKE '%" . $values['value'] . "%' OR
|
||||
contact.firstname LIKE '%" . $values['value'] . "%' OR
|
||||
contact.lastname LIKE '%" . $values['value'] . "%' OR
|
||||
contact.zip LIKE '%" . $values['value'] . "%' OR
|
||||
contact.city LIKE '%" . $values['value'] . "%' OR
|
||||
contact.houseNumber LIKE '%" . $values['value'] . "%' OR
|
||||
contact.street LIKE '%" . $values['value'] . "%' OR
|
||||
contact.uid = '" . $values['value'] . "' OR
|
||||
orders.alias LIKE '%" . $values['value'] . "%')
|
||||
");
|
||||
}))
|
||||
->add('status', ChoiceType::class, array(
|
||||
'choices' => $this->status,
|
||||
'required' => false,
|
||||
'multiple' => true,
|
||||
//'expanded' => true,
|
||||
'label_attr' => ['class' => 'float-left'],
|
||||
'data' => $session->get('order_search_status'),
|
||||
'apply_filter' => function (QueryInterface $filterQuery, $field, $values) use ($session) {
|
||||
|
||||
$session->set('order_search_status', $values['value']);
|
||||
if (empty($values['value'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filterQuery->getQueryBuilder()
|
||||
->andWhere("
|
||||
orders.status in (" . implode(",", $values['value']) . ")
|
||||
");
|
||||
$builder->setMethod('POST')->add('term', TextFilterType::class, array(
|
||||
'data' => $session->get('order_search_term'),
|
||||
'apply_filter' => function (QueryInterface $filterQuery, $field, $values) use ($session) {
|
||||
$session->set('order_search_term', $values['value']);
|
||||
if (empty($values['value'])) {
|
||||
return null;
|
||||
}
|
||||
));
|
||||
|
||||
$filterQuery
|
||||
->getQueryBuilder()
|
||||
->andWhere(
|
||||
"(
|
||||
orders.basketfield1 LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
orders.basketfield2 LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.firstname LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.lastname LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.zip LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.city LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.houseNumber LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.street LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.username LIKE '%"
|
||||
. $values['value']
|
||||
. "%' OR
|
||||
contact.uid = '"
|
||||
. $values['value']
|
||||
. "' OR
|
||||
orders.alias LIKE '%"
|
||||
. $values['value']
|
||||
. "%')
|
||||
",
|
||||
);
|
||||
},
|
||||
))->add('status', ChoiceType::class, array(
|
||||
'choices' => $this->status,
|
||||
'required' => false,
|
||||
'multiple' => true,
|
||||
//'expanded' => true,
|
||||
'label_attr' => ['class' => 'float-left'],
|
||||
'data' => $session->get('order_search_status'),
|
||||
'apply_filter' => function (QueryInterface $filterQuery, $field, $values) use ($session) {
|
||||
$session->set('order_search_status', $values['value']);
|
||||
if (empty($values['value'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filterQuery->getQueryBuilder()->andWhere('
|
||||
orders.status in ('
|
||||
. implode(',', $values['value'])
|
||||
. ')
|
||||
');
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
@ -94,7 +118,7 @@ class SearchType extends AbstractType
|
||||
$resolver->setDefaults(array(
|
||||
'translation_domain' => 'status',
|
||||
'choice_translation_domain' => 'status',
|
||||
'csrf_protection' => false
|
||||
'csrf_protection' => false,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
psc_shop_order_backend:
|
||||
resource: "@PSCShopOrderBundle/Controller/Backend"
|
||||
type: attribute
|
||||
prefix: /backend/order
|
||||
|
||||
psc_shop_order:
|
||||
resource: "@PSCShopOrderBundle/Controller"
|
||||
type: attribute
|
||||
prefix: /order
|
||||
|
||||
|
||||
psc_shop_order_backend:
|
||||
resource: "@PSCShopOrderBundle/Controller/Backend"
|
||||
type: attribute
|
||||
prefix: /backend/order
|
||||
|
||||
psc_shop_order_api:
|
||||
resource: "@PSCShopOrderBundle/Api"
|
||||
|
||||
@ -61,41 +61,102 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# Auftragsdetails #}
|
||||
{% set order = orderpos.order %}
|
||||
<div class="rounded-lg border bg-white shadow-sm">
|
||||
<div class="px-6 py-4 border-b border-gray-200">
|
||||
<h2 class="text-base font-semibold text-gray-800">Auftragsdetails</h2>
|
||||
</div>
|
||||
<div class="divide-y divide-gray-100 text-sm">
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Auftragsnummer</span>
|
||||
<span class="font-medium text-gray-800">{{ order.alias }}</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Auftrag-ID</span>
|
||||
<span class="font-medium text-gray-800">{{ order.uid }}</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Datum</span>
|
||||
<span class="font-medium text-gray-800">{{ order.created|date('d.m.Y H:i') }}</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Kunde</span>
|
||||
<div>
|
||||
<p class="font-medium text-gray-800">{{ order.contact.firstname }} {{ order.contact.lastname }}</p>
|
||||
<p class="text-gray-500 text-xs">{{ order.contact.username }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% set inv = order.invoiceAddress %}
|
||||
{% if inv %}
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Rechnungsadresse</span>
|
||||
<div class="text-gray-800 leading-snug">
|
||||
{% if inv.company %}<p class="font-medium">{{ inv.company }}</p>{% endif %}
|
||||
<p>{{ inv.firstname }} {{ inv.lastname }}</p>
|
||||
<p>{{ inv.street }} {{ inv.houseNumber }}</p>
|
||||
<p>{{ inv.zip }} {{ inv.city }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if order.basketfield1 or order.basketfield2 %}
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Kostenstelle</span>
|
||||
<span class="font-medium text-gray-800">{{ order.basketfield1 }} {{ order.basketfield2 }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Positionsdetails #}
|
||||
<div class="rounded-lg border bg-white shadow-sm">
|
||||
<div class="px-6 py-4 border-b border-gray-200">
|
||||
<h2 class="text-base font-semibold text-gray-800">Positionsdetails</h2>
|
||||
<h2 class="text-base font-semibold text-gray-800">Position</h2>
|
||||
</div>
|
||||
<div class="px-6 py-4 space-y-3 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<div class="divide-y divide-gray-100 text-sm">
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Produkt</span>
|
||||
<span class="font-medium text-gray-800">{{ orderpos.product.title }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Menge</span>
|
||||
<span class="font-medium text-gray-800">{{ orderpos.count }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-500">Preis (netto)</span>
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Preis netto</span>
|
||||
<span class="font-medium text-gray-800">{{ orderpos.priceAllNetto|number_format(2, ',', '.') }} €</span>
|
||||
</div>
|
||||
{% if orderpos.order %}
|
||||
<div class="flex justify-between">
|
||||
<span class="text-gray-500">Auftragsnummer</span>
|
||||
<span class="font-medium text-gray-800">{{ orderpos.order.alias }}</span>
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Preis brutto</span>
|
||||
<span class="font-medium text-gray-800">{{ orderpos.priceAllBrutto|number_format(2, ',', '.') }} €</span>
|
||||
</div>
|
||||
{% if articleCalc %}
|
||||
<div class="grid grid-cols-2 px-6 py-3 gap-4">
|
||||
<span class="text-gray-500">Konfiguration</span>
|
||||
<ul class="space-y-1 text-gray-800">
|
||||
{% for opt in articleCalc.getOptions %}
|
||||
{% if opt is not instanceof('\\PSC\\Library\\Calc\\Option\\Type\\Hidden') and opt.isValid() %}
|
||||
<li class="flex gap-2">
|
||||
<span class="text-gray-500">{{ opt.name }}:</span>
|
||||
<span class="font-medium">{{ opt.value }}</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Uploads #}
|
||||
{% if orderpos.uploads|length > 0 %}
|
||||
{% if position.uploadTypeObject %}
|
||||
{% if position.uploadTypeObject.uploads|length > 0 %}
|
||||
<div class="rounded-lg border bg-white shadow-sm">
|
||||
<div class="px-6 py-4 border-b border-gray-200">
|
||||
<h2 class="text-base font-semibold text-gray-800">Druckdaten ({{ orderpos.uploads|length }})</h2>
|
||||
<h2 class="text-base font-semibold text-gray-800">Druckdaten ({{ position.uploadTypeObject.uploads|length }})</h2>
|
||||
</div>
|
||||
<ul class="divide-y divide-gray-100">
|
||||
{% for upload in orderpos.uploads %}
|
||||
{% for upload in position.uploadTypeObject.uploads %}
|
||||
<li class="px-6 py-3 flex items-center justify-between gap-4">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
@ -103,12 +164,12 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-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 0 0-9-9Z"/>
|
||||
</svg>
|
||||
<span class="text-sm text-gray-800 truncate">{{ upload.name }}</span>
|
||||
<span class="text-sm text-gray-800 truncate">{{ upload.filename }}</span>
|
||||
{% if upload.typ %}
|
||||
<span class="text-xs text-gray-400 shrink-0">{{ upload.typ }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<a href="{{ path('psc_shop_order_external_approval_download', {uuid: orderpos.uuid, uploadUuid: upload.uuid}) }}"
|
||||
<a href="{{ upload.path }}"
|
||||
class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium text-white bg-green-600 hover:bg-green-700 transition-colors shrink-0">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor" class="w-4 h-4">
|
||||
@ -122,16 +183,24 @@
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{# Aktionen #}
|
||||
{% if orderpos.externalApprovalStatus is null %}
|
||||
<div class="rounded-lg border bg-white shadow-sm p-6">
|
||||
<h2 class="text-base font-semibold text-gray-800 mb-4">Ihre Entscheidung</h2>
|
||||
<div class="flex gap-4">
|
||||
<form method="post" action="{{ path('psc_shop_order_external_approval_show', {uuid: orderpos.uuid}) }}" class="flex-1">
|
||||
<input type="hidden" name="action" value="approve">
|
||||
<button type="submit"
|
||||
class="w-full inline-flex items-center justify-center gap-2 px-5 py-3 rounded-lg text-sm font-semibold text-white bg-green-600 hover:bg-green-700 transition-colors shadow-sm">
|
||||
<form method="post" action="{{ path('psc_shop_order_external_approval_show', {uuid: orderpos.uuid}) }}">
|
||||
<div class="mb-4">
|
||||
<label for="approval-message" class="block text-sm font-medium text-gray-700 mb-1">
|
||||
Mitteilung <span class="text-gray-400 font-normal">(optional)</span>
|
||||
</label>
|
||||
<textarea id="approval-message" name="message" rows="3"
|
||||
placeholder="z.B. Grund für Ablehnung oder Anmerkung zur Freigabe …"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-gray-400 resize-none"></textarea>
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<button type="submit" name="action" value="approve"
|
||||
class="flex-1 inline-flex items-center justify-center gap-2 px-5 py-3 rounded-lg text-sm font-semibold text-white bg-green-600 hover:bg-green-700 transition-colors 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-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
@ -139,11 +208,8 @@
|
||||
</svg>
|
||||
Freigeben
|
||||
</button>
|
||||
</form>
|
||||
<form method="post" action="{{ path('psc_shop_order_external_approval_show', {uuid: orderpos.uuid}) }}" class="flex-1">
|
||||
<input type="hidden" name="action" value="reject">
|
||||
<button type="submit"
|
||||
class="w-full inline-flex items-center justify-center gap-2 px-5 py-3 rounded-lg text-sm font-semibold text-white bg-red-600 hover:bg-red-700 transition-colors shadow-sm">
|
||||
<button type="submit" name="action" value="reject"
|
||||
class="flex-1 inline-flex items-center justify-center gap-2 px-5 py-3 rounded-lg text-sm font-semibold text-white bg-red-600 hover:bg-red-700 transition-colors 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-5 h-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
@ -151,8 +217,13 @@
|
||||
</svg>
|
||||
Ablehnen
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% elseif orderpos.externalApprovalMessage %}
|
||||
<div class="rounded-lg border bg-white shadow-sm p-6">
|
||||
<h2 class="text-base font-semibold text-gray-800 mb-2">Mitteilung</h2>
|
||||
<p class="text-sm text-gray-700 whitespace-pre-line">{{ orderpos.externalApprovalMessage }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@ -41,6 +41,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\TemplatedEmail;
|
||||
use Symfony\Bridge\Twig\Mime\WrappedTemplatedEmail;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
@ -394,7 +395,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
'shop' => $shop,
|
||||
];
|
||||
try {
|
||||
$message = new Email()
|
||||
$message = new TemplatedEmail()
|
||||
->subject($subject->render($params))
|
||||
->from($from->render($params))
|
||||
->to(trim($to->render($params)));
|
||||
@ -476,7 +477,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
'shop' => $shop,
|
||||
];
|
||||
try {
|
||||
$message = new Email()
|
||||
$message = new TemplatedEmail()
|
||||
->subject($subject->render($params))
|
||||
->from($from->render($params))
|
||||
->to(trim($to->render($params)));
|
||||
@ -551,7 +552,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
'shop' => $shop,
|
||||
];
|
||||
try {
|
||||
$message = new Email()
|
||||
$message = new TemplatedEmail()
|
||||
->subject($subject->render($params))
|
||||
->from($from->render($params))
|
||||
->to(trim($to->render($params)));
|
||||
@ -628,7 +629,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
'shop' => $shop,
|
||||
];
|
||||
try {
|
||||
$message = new Email()
|
||||
$message = new TemplatedEmail()
|
||||
->subject($subject->render($params))
|
||||
->from($from->render($params))
|
||||
->to(trim($to->render($params)));
|
||||
@ -702,7 +703,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
$params['doc'] = $objDoc;
|
||||
$params['packageLink'] = '/apps/backend/order/detail/package/printpartner/' . $event->getPosition();
|
||||
try {
|
||||
$message = new Email()
|
||||
$message = new TemplatedEmail()
|
||||
->subject($subject->render($params))
|
||||
->from($from->render($params))
|
||||
->to($to->render($params));
|
||||
@ -746,7 +747,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
$position = $positionRepo->findOneBy(['uuid' => $event->getPosition()]);
|
||||
$templateVars->loadOrder($position->getOrder()->getUuid());
|
||||
try {
|
||||
$message = new Email()
|
||||
$message = new TemplatedEmail()
|
||||
->subject($subject->render($templateVars->getPosTwigVars($position->getUuid())))
|
||||
->from($from->render($templateVars->getPosTwigVars($position->getUuid())))
|
||||
->to($to->render($templateVars->getPosTwigVars($position->getUuid())));
|
||||
@ -765,7 +766,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render(array_merge($templateVars->getPosTwigVars($position->getUuid(), [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $html),
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $message),
|
||||
]))));
|
||||
}
|
||||
|
||||
@ -916,7 +917,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
) {
|
||||
$templateVars->loadOrder($event->getOrder());
|
||||
try {
|
||||
$message = new Email()
|
||||
$message = new TemplatedEmail()
|
||||
->subject($subject->render($templateVars->getTwigVars()))
|
||||
->from($from->render($templateVars->getTwigVars()))
|
||||
->to(trim($to->render($templateVars->getTwigVars())));
|
||||
@ -935,7 +936,7 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
|
||||
if ($html) {
|
||||
$message->html($html->render(array_merge($templateVars->getTwigVars(), [
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $html),
|
||||
'email' => new WrappedTemplatedEmail($this->_template, $message),
|
||||
])));
|
||||
}
|
||||
|
||||
@ -1265,7 +1266,6 @@ class Mail implements QueueInterface, ConfigurableElementInterface
|
||||
],
|
||||
);
|
||||
$this->_mailer->send($message);
|
||||
die();
|
||||
} catch (\Exception $e) {
|
||||
$this->_logService->createLogEntry(
|
||||
$templateVars->getOrder()->getShop(),
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace PSC\System\UpdateBundle\Migrations;
|
||||
|
||||
class Version20260311100002 extends Base
|
||||
{
|
||||
public function migrateDatabase(): void
|
||||
{
|
||||
$this->entityManager->getConnection()->executeQuery("ALTER TABLE orderspos ADD COLUMN IF NOT EXISTS external_approval_message TEXT NULL DEFAULT NULL;");
|
||||
}
|
||||
}
|
||||
@ -49,13 +49,18 @@
|
||||
</ul>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
{{ render(controller('\\PSC\\System\\SettingsBundle\\Controller\\FtpController::myDataTailwindAction')) }}
|
||||
<hr/>
|
||||
|
||||
{% endif %}
|
||||
<p class="text-center text-psc">{{ date("now")|date('d.m.Y H:i:s') }}</p>
|
||||
<p class="mt-1 text-center">
|
||||
<hr/>
|
||||
<p class="text-left ml-5 text-psc">{{ date("now")|date('d.m.Y H:i:s') }}</p>
|
||||
<p class="mt-1 ml-5 text-left">
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<a href="{{ path('psc_system_version_backend_changelog') }}" class="text-xs text-gray-400 hover:text-psc-500 transition-colors">
|
||||
v{{ versionService.release }} ({{ versionService.datum }})
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="text-xs text-gray-400 hover:text-psc-500 transition-colors">v{{ versionService.release }} ({{ versionService.datum }})</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</nav>
|
||||
</aside>
|
||||
@ -72,8 +77,10 @@
|
||||
<div class="mr-3">
|
||||
{{ render(controller('PSC\\Backend\\DashboardBundle\\Controller\\ShopController::myEditableShopsTailwindAction', { tw: true })) }}
|
||||
</div>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<div class="hidden md:block swarm">
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% if app.request.locale == 'de_DE' %}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Custom\PSC\CollectLayouter\Model;
|
||||
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position\Upload as BaseUpload;
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position\Upload\IUploadTypeObject;
|
||||
|
||||
class Upload implements IUploadTypeObject
|
||||
{
|
||||
public array $uploads = [];
|
||||
|
||||
public function canPreview(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getCode(): string
|
||||
{
|
||||
return 102;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'CollectLayouter';
|
||||
}
|
||||
|
||||
public function addUpload(BaseUpload $upload): void
|
||||
{
|
||||
$this->uploads[] = $upload;
|
||||
}
|
||||
}
|
||||
@ -18,7 +18,7 @@ use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
require_once (__DIR__ .'/../../../../../../src/PSC/Shop/EntityBundle/Lagacy/TP_Basket_Item.php');
|
||||
require_once __DIR__ . '/../../../../../../src/PSC/Shop/EntityBundle/Lagacy/TP_Basket_Item.php';
|
||||
|
||||
#[AutoconfigureTag('queues')]
|
||||
class Render implements QueueInterface, ConfigurableElementInterface
|
||||
@ -34,7 +34,6 @@ class Render implements QueueInterface, ConfigurableElementInterface
|
||||
*/
|
||||
private $_pdf;
|
||||
|
||||
|
||||
function __construct(EntityManagerInterface $entityManager, Pdf $pdf)
|
||||
{
|
||||
$this->_entityManager = $entityManager;
|
||||
@ -67,25 +66,13 @@ class Render implements QueueInterface, ConfigurableElementInterface
|
||||
return 'Form Based Renderer';
|
||||
}
|
||||
|
||||
public function getForm(FormBuilderInterface $builder, $form_options, EventInterface $event)
|
||||
{
|
||||
public function getForm(FormBuilderInterface $builder, $form_options, EventInterface $event) {}
|
||||
|
||||
}
|
||||
public function injectDocument(Form $form, EventInterface $event, Queue $objQueue) {}
|
||||
|
||||
public function injectDocument(Form $form, EventInterface $event, Queue $objQueue)
|
||||
{
|
||||
public function setFormData(Form $form, EventInterface $event, Queue $queueObj) {}
|
||||
|
||||
}
|
||||
|
||||
public function setFormData(Form $form, EventInterface $event, Queue $queueObj)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getTemplate()
|
||||
{
|
||||
|
||||
}
|
||||
public function getTemplate() {}
|
||||
|
||||
/**
|
||||
* @param EventInterface $event
|
||||
@ -94,31 +81,46 @@ class Render implements QueueInterface, ConfigurableElementInterface
|
||||
*/
|
||||
public function execute(EventInterface $event, Queue $doc)
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
$orderspos = $this->_entityManager->getRepository('PSC\Shop\EntityBundle\Entity\Orderpos')
|
||||
->findby(['layouterMode' => 102, 'renderPrint' => 1]);
|
||||
$orderspos = $this->_entityManager
|
||||
->getRepository('PSC\Shop\EntityBundle\Entity\Orderpos')
|
||||
->findby(['layouterMode' => 102, 'renderPrint' => 1]);
|
||||
|
||||
/** @var Orderpos $pos */
|
||||
foreach($orderspos as $pos) {
|
||||
foreach ($orderspos as $pos) {
|
||||
/** @var \TP_Basket_Item $objPosition */
|
||||
$objPosition = unserialize(($pos->getData()));
|
||||
if($objPosition->getLayouterId() != "") {
|
||||
if(!file_exists('/data/www/old/market/steplayouter/basket/' . $pos->getOrder()->getUid() . '/' . $pos->getPos())) {
|
||||
mkdir('/data/www/old/market/steplayouter/basket/' . $pos->getOrder()->getUid() . '/' . $pos->getPos(), 0777, true);
|
||||
$objPosition = unserialize($pos->getData());
|
||||
if ($objPosition->getLayouterId() != '') {
|
||||
if (!file_exists(
|
||||
'/data/www/old/market/steplayouter/basket/' . $pos->getOrder()->getUid() . '/' . $pos->getPos(),
|
||||
)) {
|
||||
mkdir(
|
||||
'/data/www/old/market/steplayouter/basket/' . $pos->getOrder()->getUid() . '/'
|
||||
. $pos->getPos(),
|
||||
0777,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$layoutDesignData = $this->_entityManager
|
||||
->getRepository(Layoutdesigndata::class)->findOneBy(array('uuid' => $objPosition->getLayouterId()));
|
||||
->getRepository(Layoutdesigndata::class)
|
||||
->findOneBy(array('uuid' => $objPosition->getLayouterId()));
|
||||
|
||||
if($layoutDesignData) {
|
||||
if ($layoutDesignData) {
|
||||
$data = $layoutDesignData->getDesign();
|
||||
|
||||
$outfile = '/data/www/old/market/steplayouter/basket/' . $pos->getOrder()->getUid() . '/' . $pos->getPos() . '/' . $pos->getOrder()->getAlias() . '_' . $pos->getPos() . '.pdf';
|
||||
$outfile =
|
||||
'/data/www/old/market/steplayouter/basket/'
|
||||
. $pos->getOrder()->getUid()
|
||||
. '/'
|
||||
. $pos->getPos()
|
||||
. '/'
|
||||
. $pos->getOrder()->getAlias()
|
||||
. '_'
|
||||
. $pos->getPos()
|
||||
. '.pdf';
|
||||
|
||||
copy($data['pdf'], $outfile);
|
||||
}
|
||||
@ -127,11 +129,7 @@ class Render implements QueueInterface, ConfigurableElementInterface
|
||||
$this->_entityManager->persist($pos);
|
||||
$this->_entityManager->flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} catch (\Exception $e) {
|
||||
echo $e->getLine();
|
||||
echo $e->getMessage();
|
||||
@ -145,5 +143,5 @@ class Render implements QueueInterface, ConfigurableElementInterface
|
||||
{
|
||||
return $this->_error;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Custom\PSC\CollectLayouter\Service;
|
||||
|
||||
use Plugin\Custom\PSC\CollectLayouter\Transformer\CollectLayouter;
|
||||
use PSC\Shop\EntityBundle\Document\Product as ProductDoc;
|
||||
use PSC\Shop\EntityBundle\Entity\Product as ProductEntity;
|
||||
use PSC\Shop\ProductBundle\Interfaces\IUploadOption;
|
||||
use PSC\Shop\ProductBundle\Transformer\Order\Position\IUploadOptionTransformer;
|
||||
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
|
||||
|
||||
#[AutoconfigureTag('product.upload.option')]
|
||||
class CollectLayouterUpload implements IUploadOption
|
||||
{
|
||||
public function getType(): string
|
||||
{
|
||||
return 102;
|
||||
}
|
||||
|
||||
public function getLabel(): string
|
||||
{
|
||||
return 'CollectLayouter Designer';
|
||||
}
|
||||
|
||||
public function getTransformer(): IUploadOptionTransformer
|
||||
{
|
||||
return new CollectLayouter();
|
||||
}
|
||||
|
||||
public function getContentUrl(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isEnabled(ProductEntity $entity, ?ProductDoc $document): bool
|
||||
{
|
||||
return (bool) $document->getPluginSettingModule('collectlayouter', 'uploadCollectLayouter');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Custom\PSC\CollectLayouter\Transformer;
|
||||
|
||||
use Plugin\Custom\PSC\CollectLayouter\Model\Upload as PluginUpload;
|
||||
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\ProductBundle\Transformer\Order\Position\IUploadOptionTransformer;
|
||||
|
||||
class CollectLayouter implements IUploadOptionTransformer
|
||||
{
|
||||
public function fromDb(Position $position, Orderpos $posEntity, PosDoc $posDoc): void
|
||||
{
|
||||
$upload = new PluginUpload();
|
||||
$outDir =
|
||||
'/data/www/old/market/steplayouter/basket/' . $posEntity->getOrder()->getUid() . '/' . $posEntity->getPos();
|
||||
$outFile = $outDir . '/' . $posEntity->getOrder()->getAlias() . '_' . $posEntity->getPos() . '.pdf';
|
||||
|
||||
if (file_exists($outFile)) {
|
||||
$up = new Upload();
|
||||
$up->setFileName($posEntity->getOrder()->getAlias() . '_' . $posEntity->getPos() . '.pdf');
|
||||
$up->setTyp('pdf');
|
||||
$up->setPath(
|
||||
'/apps/market/steplayouter/basket/'
|
||||
. $posEntity->getOrder()->getUid()
|
||||
. '/'
|
||||
. $posEntity->getPos()
|
||||
. '/'
|
||||
. $posEntity->getOrder()->getAlias()
|
||||
. '_'
|
||||
. $posEntity->getPos()
|
||||
. '.pdf',
|
||||
);
|
||||
$upload->addUpload($up);
|
||||
}
|
||||
$position->setUploadTypeObject($upload);
|
||||
}
|
||||
|
||||
public function toDb(Position $position, Orderpos $posEntity, PosDoc $posDoc): void {}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Custom\PSC\LaufkartenLayouter\Model;
|
||||
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position\Upload as BaseUpload;
|
||||
use PSC\Shop\OrderBundle\Model\Order\Position\Upload\IUploadTypeObject;
|
||||
|
||||
class Upload implements IUploadTypeObject
|
||||
{
|
||||
public array $uploads = [];
|
||||
|
||||
public function canPreview(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getCode(): string
|
||||
{
|
||||
return 106;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Laufkartenlayouter';
|
||||
}
|
||||
|
||||
public function addUpload(BaseUpload $upload): void
|
||||
{
|
||||
$this->uploads[] = $upload;
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,6 @@ class Render implements QueueInterface, ConfigurableElementInterface
|
||||
{
|
||||
try {
|
||||
set_time_limit(0);
|
||||
|
||||
$orderspos = $this->entityManager
|
||||
->getRepository(Orderpos::class)
|
||||
->findby(['layouterMode' => 106, 'renderPrint' => 1]);
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Custom\PSC\LaufkartenLayouter\Service;
|
||||
|
||||
use Plugin\Custom\PSC\LaufkartenLayouter\Transformer\Laufkarten;
|
||||
use PSC\Shop\EntityBundle\Document\Product as ProductDoc;
|
||||
use PSC\Shop\EntityBundle\Entity\Product as ProductEntity;
|
||||
use PSC\Shop\ProductBundle\Interfaces\IUploadOption;
|
||||
use PSC\Shop\ProductBundle\Transformer\Order\Position\IUploadOptionTransformer;
|
||||
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
|
||||
|
||||
#[AutoconfigureTag('product.upload.option')]
|
||||
class LaufkartenUpload implements IUploadOption
|
||||
{
|
||||
public function getType(): string
|
||||
{
|
||||
return 106;
|
||||
}
|
||||
|
||||
public function getLabel(): string
|
||||
{
|
||||
return 'Laufkarten Designer';
|
||||
}
|
||||
|
||||
public function getTransformer(): IUploadOptionTransformer
|
||||
{
|
||||
return new Laufkarten();
|
||||
}
|
||||
|
||||
public function getContentUrl(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isEnabled(ProductEntity $entity, ?ProductDoc $document): bool
|
||||
{
|
||||
return (bool) $document->getPluginSettingModule('laufkartenlayouter', 'active');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Plugin\Custom\PSC\LaufkartenLayouter\Transformer;
|
||||
|
||||
use Plugin\Custom\PSC\LaufkartenLayouter\Model\Upload as PluginUpload;
|
||||
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\ProductBundle\Transformer\Order\Position\IUploadOptionTransformer;
|
||||
|
||||
class Laufkarten implements IUploadOptionTransformer
|
||||
{
|
||||
public function fromDb(Position $position, Orderpos $posEntity, PosDoc $posDoc): void
|
||||
{
|
||||
$upload = new PluginUpload();
|
||||
$outDir =
|
||||
'/data/www/old/market/steplayouter/basket/' . $posEntity->getOrder()->getUid() . '/' . $posEntity->getPos();
|
||||
$outFile = $outDir . '/' . $posEntity->getOrder()->getAlias() . '_' . $posEntity->getPos() . '.pdf';
|
||||
|
||||
if (file_exists($outFile)) {
|
||||
$up = new Upload();
|
||||
$up->setFileName($posEntity->getOrder()->getAlias() . '_' . $posEntity->getPos() . '.pdf');
|
||||
$up->setTyp('pdf');
|
||||
$up->setPath(
|
||||
'/apps/market/steplayouter/basket/'
|
||||
. $posEntity->getOrder()->getUid()
|
||||
. '/'
|
||||
. $posEntity->getPos()
|
||||
. '/'
|
||||
. $posEntity->getOrder()->getAlias()
|
||||
. '_'
|
||||
. $posEntity->getPos()
|
||||
. '.pdf',
|
||||
);
|
||||
$upload->addUpload($up);
|
||||
}
|
||||
$position->setUploadTypeObject($upload);
|
||||
}
|
||||
|
||||
public function toDb(Position $position, Orderpos $posEntity, PosDoc $posDoc): void {}
|
||||
}
|
||||
@ -57,10 +57,17 @@ class DesignController extends AbstractController
|
||||
}
|
||||
if (isset($output['data'])) {
|
||||
foreach ($output['data']['__items'] as $item) {
|
||||
if(strpos($item, 'folder')!== false) {
|
||||
$data = $this->getItems($data, $item);
|
||||
}
|
||||
}
|
||||
foreach ($output['data']['items'] as $item)
|
||||
{
|
||||
if (isset($item['unit'])) {
|
||||
$data['designs'][] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'designs' => $data,
|
||||
'product' => $product,
|
||||
@ -73,7 +80,7 @@ class DesignController extends AbstractController
|
||||
if (isset($itemResult['data']['unit'])) {
|
||||
$data['designs'][] = $itemResult['data'];
|
||||
}
|
||||
if (!isset($itemResult['data']['unit']) && isset($itemResult['data']['items'])) {
|
||||
if (!isset($itemResult['data']['unit']) && isset($itemResult['data']['__items'])) {
|
||||
$data['folders'][] = $itemResult['data'];
|
||||
}
|
||||
return $data;
|
||||
|
||||
@ -104,6 +104,10 @@ class Producer implements IUiProducer, IProducerHydrateModel, ICalcNeedContact
|
||||
*/
|
||||
$specProd = $this->product->getSpecialProductTypeObject();
|
||||
|
||||
if (isset($specProd->getParams()['type'])) {
|
||||
$this->engine->setActiveArticle($specProd->getParams()['type']);
|
||||
}
|
||||
|
||||
$this->engine->setVariables($specProd->getParams());
|
||||
if ($this->contact && $this->contact->getAccountType()->value > 1) {
|
||||
$this->engine->setVariable('contact.accountType', $this->contact->getAccountType()->value);
|
||||
@ -194,6 +198,21 @@ class Producer implements IUiProducer, IProducerHydrateModel, ICalcNeedContact
|
||||
'required' => [],
|
||||
];
|
||||
|
||||
if ($this->engine->getArticles()->count() > 1) {
|
||||
$temp['properties']['type'] = [
|
||||
'type' => 'string',
|
||||
'title' => 'Typ',
|
||||
'oneOf' => [],
|
||||
'default' => $this->engine->getArticle()->getName(),
|
||||
];
|
||||
foreach ($this->engine->getArticles() as $article) {
|
||||
$temp['properties']['type']['oneOf'][] = [
|
||||
'title' => $article->getName(),
|
||||
'const' => $article->getName(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->engine->getArticle()->getOptions() as $option) {
|
||||
if (!$option->isValid()) {
|
||||
continue;
|
||||
|
||||
@ -1037,6 +1037,10 @@ html {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.ml-5{
|
||||
margin-left: 1.25rem;
|
||||
}
|
||||
|
||||
.ml-auto{
|
||||
margin-left: auto;
|
||||
}
|
||||
@ -1190,6 +1194,10 @@ html {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.h-12{
|
||||
height: 3rem;
|
||||
}
|
||||
|
||||
.h-16{
|
||||
height: 4rem;
|
||||
}
|
||||
@ -1274,6 +1282,10 @@ html {
|
||||
width: 2.75rem;
|
||||
}
|
||||
|
||||
.w-12{
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.w-16{
|
||||
width: 4rem;
|
||||
}
|
||||
@ -1521,6 +1533,10 @@ html {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.resize-none{
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.resize{
|
||||
resize: both;
|
||||
}
|
||||
@ -1551,6 +1567,10 @@ html {
|
||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid-cols-2{
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid-cols-4{
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
@ -1746,6 +1766,10 @@ html {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.whitespace-pre-line{
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.whitespace-pre-wrap{
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
@ -1889,6 +1913,11 @@ html {
|
||||
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-green-200{
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(187 247 208 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-psc-200{
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(226 128 119 / var(--tw-border-opacity));
|
||||
@ -1988,6 +2017,11 @@ html {
|
||||
background-color: rgb(220 252 231 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-50{
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(240 253 244 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-600{
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
||||
@ -2127,6 +2161,10 @@ html {
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.p-6{
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.p-8{
|
||||
padding: 2rem;
|
||||
}
|
||||
@ -2346,6 +2384,10 @@ html {
|
||||
line-height: 2.25rem;
|
||||
}
|
||||
|
||||
.leading-snug{
|
||||
line-height: 1.375;
|
||||
}
|
||||
|
||||
.tracking-tight{
|
||||
letter-spacing: -0.025em;
|
||||
}
|
||||
@ -2404,6 +2446,11 @@ html {
|
||||
color: rgb(22 163 74 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-green-700{
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(21 128 61 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-green-800{
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(22 101 52 / var(--tw-text-opacity));
|
||||
@ -3283,6 +3330,11 @@ html {
|
||||
--tw-ring-color: rgb(229 231 235 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-gray-400:focus{
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(156 163 175 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-gray-500:focus{
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity));
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
info:
|
||||
datum: 10.03.2026
|
||||
release: 2.3.3
|
||||
datum: 19.03.2026
|
||||
release: 2.3.4
|
||||
|
||||
changelog:
|
||||
- version: 2.3.4
|
||||
datum: 19.03.2026
|
||||
changes:
|
||||
- "Auftragssuche nach EMail"
|
||||
- "Freigabeprozess für Externe implementiert (Aktion, Events)"
|
||||
- "Kalkulation in Auftrag bearbeiten kann mehrere Produkte pro XML"
|
||||
- "Kosmetische änderungen für eingeschränkte Benutzer"
|
||||
- version: 2.3.3
|
||||
datum: 10.03.2026
|
||||
changes:
|
||||
|
||||
@ -4807,7 +4807,7 @@ class BasketController extends TP_Controller_Action
|
||||
$articleSession = new TP_Layoutersession();
|
||||
|
||||
$articleSess = $articleSession->getLayouterArticle($artikel->getLayouterId());
|
||||
$art->layouter_mode = 4;
|
||||
$art->layouter_mode = $articleSess->getLayouterModus();
|
||||
|
||||
if ($articleSess->getLayouterModus() == 2) {
|
||||
$articleSess->copyToBasketStepLayouter($order, $art, $articleSess->getArticleId());
|
||||
@ -5244,6 +5244,9 @@ class BasketController extends TP_Controller_Action
|
||||
if ($article->confirmExternal) {
|
||||
$art->status = 90;
|
||||
$order->status = 90;
|
||||
$order->save();
|
||||
$art->save();
|
||||
|
||||
$dbMongo = TP_Mongo::getInstance();
|
||||
$dbMongo->Job->insertOne(array(
|
||||
'shop' => $this->shop->id,
|
||||
|
||||
BIN
src/old/market/steplayouter/basket/295/1/AF-11.03.2026-89_1.pdf
Normal file
BIN
src/old/market/steplayouter/basket/295/1/AF-11.03.2026-89_1.pdf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user