custom/plugins/SteincoProducts/src/Subscriber/OrderEventsSubscriber.php line 154

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Schoettler\SteincoProducts\Subscriber;
  3. use Schoettler\SteincoProducts\SharedFunctions;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  6. use Shopware\Core\Checkout\Order\OrderEvents;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  8. use Shopware\Core\System\SystemConfig\SystemConfigService;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  12. use DateTimeImmutable;
  13. use DateTimeInterface;
  14. // Rechnung immer zuerst
  15. class OrderEventsSubscriber implements EventSubscriberInterface {
  16.     public static function getSubscribedEvents() : array 
  17.     {
  18.         // Return the events to listen to as array like this:  <event to listen to> => <method to execute>
  19.         return [
  20.             OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderWritten',
  21.             'document.written' => 'onDocumentWritten'
  22.         ];
  23.     }
  24.     Private $DOK_RECHNUNG "IRGVK";
  25.     Private $DOK_LIEFERSCHEIN "ILSVK";
  26.     Private $DOK_GUTSCHRIFT "IGUVK";
  27.     Private $DOK_RECHNUNGSSTORNO "IGUVK";
  28.     Private $DOK_GUTSCHRIFTSTORNO "IGUST";
  29.     Private $DOK_AUFTRAGBESTAETIGUNG "IABVK";
  30.     Private $LINEBREAK "\r\n";
  31.     private $context;
  32.     /**
  33.      * @var SystemConfigService
  34.      */
  35.     private $systemConfigService;
  36.     /**
  37.      * @var EntityRepository
  38.      */
  39.     private $customerRepository;
  40.     /**
  41.      * @var EntityRepository
  42.      */
  43.     private $orderRepository;
  44.     /**
  45.      * @var EntityRepository
  46.      */
  47.     private $documentRepository;
  48.     /**
  49.      * @var EntityRepository
  50.      */
  51.     private $propertyOptionRepository;
  52.     
  53.     /**
  54.      * @var EntityRepository
  55.      */
  56.     private $propertyRepository;
  57.     /**
  58.      * @var DocumentService
  59.      */
  60.     protected $documentService;
  61.      /**
  62.      * @var EntityRepository
  63.      */
  64.     private  $mediaRepository;
  65.     public function __construct(SystemConfigService $systemConfigService,
  66.     EntityRepository $customerRepositoryEntityRepository $orderRepository,
  67.      EntityRepository $documentRepositoryEntityRepository $propertyOptionRepository,
  68.      EntityRepository $propertyRepository$docService$mediaRepository)
  69.     {
  70.         $this->systemConfigService $systemConfigService;
  71.         $this->customerRepository $customerRepository;
  72.         $this->orderRepository $orderRepository;
  73.         $this->documentRepository $documentRepository;
  74.         $this->propertyOptionRepository $propertyOptionRepository;
  75.         $this->propertyRepository $propertyRepository;
  76.         $this->documentService $docService;
  77.         $this->mediaRepository $mediaRepository;
  78.         //$this->urlGenerator = $urlGenerator;
  79.     }
  80.     public function onOrderWritten(EntityWrittenEvent $event
  81.     {
  82.         //Database
  83.         $dbHost $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseHost');
  84.         $dbUser $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseUser');
  85.         $dbPass $this->systemConfigService->get('SteincoProductsController.config.externalDatabasePassword');
  86.         $dbName $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseName');
  87.         $mysqli = new \mysqli($dbHost$dbUser$dbPass$dbName);
  88.         if($mysqli->connect_errno ) {
  89.             // Log the error somehow
  90.             //dump($mysqli->connect_errno);
  91.         }  
  92.         $orderUUID $event->getWriteResults()[0]->getPrimaryKey();
  93.         $myContext $event->getContext();
  94.         $this->context $myContext ?? \Shopware\Core\Framework\Context::createDefaultContext();
  95.         $orderCriteria = new Criteria([]);
  96.         $orderCriteria->addAssociation('currency')->addAssociation('billingAddress')->addFilter(new EqualsFilter('id'$orderUUID));
  97.        
  98.         $order_searchresult $this->orderRepository->search(
  99.             $orderCriteria,
  100.            \Shopware\Core\Framework\Context::createDefaultContext());
  101.         
  102.         $order $order_searchresult->getEntities()->getElements()[$orderUUID];
  103.         // TODO: if order is empty
  104.         $order_number $order->getOrderNumber();
  105.         $customer_number $order->getOrderCustomer()->getCustomerNumber();
  106.     //dump($order_searchresult, $order);
  107.         // check if the order is already present in the Shop2DWH_Erstbesteller table
  108.         $check_erstbesteller_sql 'SELECT NOT EXISTS (SELECT * FROM Shop2DWH_Erstbesteller WHERE Kundennummer = "' 
  109.         .$customer_number .'" ) AS firstorder';
  110.         if($check_erstbesteller_query $mysqli->query($check_erstbesteller_sql)) {
  111.             $row mysqli_fetch_array($check_erstbesteller_query);
  112.             $no_entry_exists $row['firstorder'];
  113.             $check_erstbesteller_query->close();
  114.             $firstorderDate $order->getCreatedAt();
  115.             $erstbestelldatum $firstorderDate->format('Y-m-d H:i:s');
  116.             if($no_entry_exists == 1) {
  117.                 // first order by this Customer, write to Shop2DWH_Erstbesteller
  118.                 $sql 'INSERT INTO Shop2DWH_Erstbesteller (Kundennummer, order_id, Erstbestelldatum)' 
  119.                 .' VALUES ("' .$customer_number .'", "' .$order_number .'", "' .$erstbestelldatum .'" )';
  120.                 if(! $mysqli->query($sql)){
  121.                     //dump(mysqli_error($mysqli), $sql, $customer);
  122.                 }
  123.             }
  124.         } else {
  125.             //TODO: query failed
  126.         }
  127.     }
  128.     public function onDocumentWritten(EntityWrittenEvent $event){
  129.         SharedFunctions::dumpToLog("onDocumentWritten()");
  130.         //get DB-related data
  131.         $dbHost $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseHost');
  132.         $dbUser $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseUser');
  133.         $dbPass $this->systemConfigService->get('SteincoProductsController.config.externalDatabasePassword');
  134.         $dbName $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseName');
  135.        
  136.         // each document should only be written once, so all data must be present at this event
  137.         $myContext $event->getContext();
  138.         $this->context $myContext ?? \Shopware\Core\Framework\Context::createDefaultContext();
  139.         $writeResult $event->getWriteResults();
  140.         $writeResult reset($writeResult);
  141.         $writeResult $writeResult->getPayload(); 
  142.         // SharedFunctions::dumpToLog($writeResult);
  143.         $orderUUID $writeResult['orderId'];
  144.         $orderVersionUUID $writeResult['orderVersionId']; // probably not needed
  145.         $documentUUID $writeResult['id'];
  146.         // get the document including type
  147.         $documentCritera = new Criteria([]);
  148.         $documentCritera->addAssociation("documentType")->addFilter(New EqualsFilter('id'$documentUUID));
  149.         $document_searchresult $this->documentRepository->search(
  150.             $documentCritera,
  151.             $myContext
  152.         );
  153.         $document $document_searchresult->getEntities()->getElements()[$documentUUID];
  154. //dump($document_searchresult->getEntities()->getElements()[$documentUUID],$documentUUID,$document_searchresult->getEntities()->getElements());
  155.         // we only want Rechnung, Storno, Gutschrift for the bulk of data
  156.         $documentTechnicalName $document->getDocumentType()->getTechnicalName();
  157.         $invoice_types = ['invoice'];
  158.         $creditNote_types = ['credit_note''storno'];
  159.         // if the document is just created, we need to create a copy of the pdf and create a jpl-file
  160.         // pass document and order
  161. //dump("copying document");
  162.         if(!empty($orderUUID)){
  163.         $this->writeFilesToExchangeFolder($orderUUID$document);
  164. //dump("copied document");
  165.         // delivery_note => Lieferschein
  166.         if ($documentTechnicalName == 'delivery_note'){
  167.             // delivery_note is created after invoice by design, 
  168.             // we just use it to update the Lieferschein field in existing entries
  169.             // UPDATE Shop2DWH_BelegPosition Set Lieferschein = $belegnummer WHERE BelegkopfId = $belegkopfId
  170.             // To retrieve BelegkopfId we need the invoice, which we can get using Bestellnr
  171.             $order $this->getOrder($orderUUID);
  172.             $orderNumber $order->getOrderNumber();
  173.             $documentCriteria = new Criteria();
  174.             $documentCriteria->addFilter(new EqualsFilter('orderId'$orderUUID));
  175.             
  176.             $documents $this->documentRepository->search($documentCriteria$this->context);
  177.             // loop over the docs and update Belegpositionen
  178.             $documentEntities $documents->getEntities()->getElements();
  179.             $whereClause ' WHERE LieferscheinNr ';
  180.             $numberOfElemets sizeof($documentEntities);
  181. //dump("trying to update delivery-note");
  182.             If($numberOfElemets 0){
  183.                 If ($numberOfElemets == 1) {
  184.                     $doc reset($documentEntities);
  185.                     $whereClause .= '= "' .$doc->getConfig()['documentNumber'] .'" ';
  186.                 } elseif ($numberOfElemets 1) {
  187.                     $whereClause .= 'IN(';
  188.                     foreach ($documentEntities as $oldDocuments) {
  189.                         $whereClause .= '"' .$oldDocuments->getConfig()['documentNumber'] .'", ';
  190.                     }
  191.                     $whereClause substr($whereClause0strlen($whereClause) - 2);
  192.                     $whereClause .= ') ';
  193.                 }
  194.                 $updateSQL 'UPDATE Shop2DWH_Belegposition SET LieferscheinNr = "' .$writeResult['config']['documentNumber'] .'" ' .$whereClause;
  195.                 
  196.                 $mysqli = new \mysqli($dbHost$dbUser$dbPass$dbName);
  197.                 if($mysqli->connect_errno ) {
  198.                     // Log the error somehow
  199.                     //dump($mysqli->connect_errno);
  200.                 }
  201.                 if(! $mysqli->query($updateSQL)){
  202.                  //dump(mysqli_error($mysqli), $updateSQL);
  203.                 }
  204.             }
  205.         }
  206.         if(in_array($documentTechnicalName$invoice_types) || in_array($documentTechnicalName$creditNote_types))
  207.         {
  208.             SharedFunctions::dumpToLog("Creating BelegkopfSQL");
  209.             // get the order including currency and billing-address and shipping-address
  210.             $order $this->getOrder($orderUUID);
  211.             $zahlungsart $this->getZahlungsart($orderUUID$orderVersionUUID$order->getLanguageId());
  212.             
  213.             $dummy_time strtotime('2999-12-31');
  214.             $dummy_date date('Y-m-d H:i:s'$dummy_time);
  215.             $bestellnummer $order->getOrderNumber();
  216.             $belegwaehrung $order->getCurrency()->getIsoCode();
  217.             $billing_address_country $order->getBillingAddress()->getCountry()->getIso3();
  218.             // get necessary Data for Belegkopf and write to external DB
  219.             $belegart in_array($documentTechnicalName$creditNote_types)? 'GAS' 'RAS'//"RAS"; // possible values: RAS, GAS (Rechnungs/Gutschriftsausgang)
  220.             $belegnummer $writeResult['config']['documentNumber'];
  221.             $belegdatum strtotime($writeResult['config']['documentDate']);
  222.             $belegdatum date('Y-m-d H:i:s'$belegdatum);
  223.             $leistungsdatum $belegdatum;
  224.             $erzeugungsdatum $writeResult['createdAt']; 
  225.             // This is a DateTimeImmutable Object
  226.             $erzeugungsdatum $erzeugungsdatum->format('Y-m-d H:i:s');
  227.             $referenznummer $writeResult['config']['referencedDocumentId']?? ' '// z.B. bei Storno: Nummer der stornierten Rechnung
  228.             $personenkonto $order->getOrderCustomer()->getCustomerNumber();
  229.             $zahlungsdienstleister_OP_ID '';// $order->getOrderTransactions()->getCustomFileds()['swag_paypal_order_id'];//''; // Paypal Transaktions ID; bei Rechnung: Rechnungsnummer, nullable $order->getOrderTransactions()->getCustomFileds()['swag_paypal_order_id']
  230.             $transactions $order->getTransactions()->getElements();
  231.             //we use the first
  232.             $first_transaction reset($transactions);
  233.             if($first_transaction) {
  234.                 $custom_transactionfields $first_transaction->getCustomFields() ?? [];
  235.                 $zahlungsdienstleister_OP_ID array_key_exists('swag_paypal_order_id'$custom_transactionfields) ? $custom_transactionfields['swag_paypal_order_id'] : '';
  236.             }
  237.             $valutadatum $leistungsdatum;
  238.             $ziel1 $dummy_date;
  239.             $skonto1Betrag $order->getAmountTotal(); //
  240.             $skonto1Prozent "0";
  241.             $faelligAm $belegdatum;
  242.             $land_Lieferadresse_ISO3 $billing_address_country// no shipping Address in Order or Document! -> because there is only one address per customer ATM, just take the billing address
  243.             $land_Rechnungsadresse_ISO3 $billing_address_country;
  244.             $ust_id $order->getOrderCustomer()->getVatIds()[0]?? "";
  245.             $ust_id preg_replace('/[^a-zA-Z0-9]/'""$ust_id); // remove white space and non-alphanumeric characters
  246.             $endbetrag $order->getAmountTotal();
  247.             $taxes $order->getPrice()->getCalculatedTaxes()->getElements();
  248.             // HALLO: muss es hier fix 7 und 19 sein?
  249.             $endbetrag_Steuerschluessel1 array_key_exists(19$taxes) ? $taxes[19]->getTax() : 0;
  250.             $endbetrag_Steuerschluessel2 array_key_exists(7$taxes) ? $taxes[7]->getTax() : 0;
  251.             // Credit-note type should have negative values for money-related entries
  252.             if(in_array($documentTechnicalName$creditNote_types)){
  253.               $skonto1Betrag *= -1;
  254.               $endbetrag *= -1;
  255.               $endbetrag_Steuerschluessel1 *= -1;
  256.               $endbetrag_Steuerschluessel2 *= -1;
  257.             }
  258.             $sql_belegkopf 'INSERT INTO Shop2DWH_Belegkopf (' 
  259.             .'`Belegart`, ' 
  260.             .'`Belegnummer`, '
  261.             .'`BestellNr`, ' 
  262.             .'`Belegwaehrung`, ' 
  263.             .'`Belegdatum`, ' 
  264.             .'`Leistungsdatum`, ' 
  265.             .'`Erzeugungsdatum`, ' 
  266.             .'`Referenznr`, '
  267.             .'`Personenkonto`, ' 
  268.             .'`ZahlungsDienstleister_OP_ID`, ' 
  269.             .'`Valutadatum`, ' 
  270.             .'`Ziel1`, ' 
  271.             .'`Skonto1Betrag`, ' 
  272.             .'`Skonto1Prozent`, ' 
  273.             .'`FaelligAm`, ' 
  274.             .'`Land_Lieferadresse_ISO3`, '
  275.             .'`Land_Rechnungsadresse_ISO3`, '
  276.             .'`UST-ID`, '
  277.             .'`Endbetrag`, '
  278.             .'`Endbetrag_Steuerschluessel1`, '
  279.             .'`Endbetrag_Steuerschluessel2`, '
  280.             .'`Zahlungsart`'
  281.              .' )'
  282.             .' VALUES ( '
  283.             .'"' .$belegart .'", '
  284.             .'"' .$belegnummer .'", '
  285.             .'"' .$bestellnummer .'", '
  286.             .'"' .$belegwaehrung .'", '
  287.             .'"' .$belegdatum .'", '
  288.             .'"' .$leistungsdatum .'", '
  289.             .'"' .$erzeugungsdatum .'", '
  290.             .'"' .$referenznummer.'", '
  291.             .'"' .$personenkonto .'", '
  292.             .'"' .$zahlungsdienstleister_OP_ID .'", '
  293.             .'"' .$valutadatum .'", '
  294.             .'"' .$ziel1 .'", '
  295.             .'"' .$skonto1Betrag .'", '
  296.             .'"' .$skonto1Prozent .'", '
  297.             .'"' .$faelligAm .'", '
  298.             .'"' .$land_Lieferadresse_ISO3 .'", '
  299.             .'"' .$land_Rechnungsadresse_ISO3 .'", '
  300.             .'"' .$ust_id .'", '
  301.             .'"' .$endbetrag .'", '
  302.             .'"' .$endbetrag_Steuerschluessel1 .'", '
  303.             .'"' .$endbetrag_Steuerschluessel2 .'", '
  304.             .'"' .$zahlungsart .'"'
  305.             .' )';
  306.             
  307.             //dump($sql_belegkopf);
  308.             $mysqli = new \mysqli($dbHost$dbUser$dbPass$dbName);
  309.             if($mysqli->connect_errno ) {
  310.                 // Log the error somehow
  311.                 //dump($mysqli->connect_errno);
  312.             }
  313.             
  314.             if(! $mysqli->query($sql_belegkopf)){
  315.                //dump(mysqli_error($mysqli), $sql_belegkopf);
  316.             }
  317. //dump("Belegkopf persisted");
  318.             // retrieve the belegkopfId
  319.             $belegkopfId '';
  320.             $sql_getBelegkopf 'SELECT BelegkopfID AS kopfid FROM Shop2DWH_Belegkopf WHERE Belegnummer = "' .$belegnummer .'" ';
  321.             if($get_belegkopfid_query $mysqli->query($sql_getBelegkopf)) {
  322.                 $row mysqli_fetch_array($get_belegkopfid_query);
  323.                 // dump($row);
  324.                 $belegkopfId $row['kopfid'];
  325.                 $get_belegkopfid_query->close();
  326.             }
  327.             $optionSearchResult $this->getPropertyOptions_by_name_and_propertydescription('1''istHandelwareWebshop');
  328.             $handelswareOption reset($optionSearchResult);
  329.             if ($handelswareOption !== false) {
  330.                 $handelswareId $handelswareOption->getId();
  331.             } else {
  332.                 // Umgang mit dem Fall, dass keine Option gefunden wurde
  333.                 SharedFunctions::dumpToLog('Keine Handelsware-Option gefunden.');
  334.                 $handelswareId '<->'// oder ein anderer sinnvoller Wert
  335.             }
  336.             // get neccessary Data for Belegposition and write to external DB
  337. //dump("create Belegpositionquery");
  338.             $order_linteitems $order->getLineItems()->getElements();
  339.             foreach($order_linteitems as $lineItem){
  340.                 $positionsnummer $lineItem->getPosition();
  341.                 $betragNetto $lineItem->getPrice()->getTotalPrice();
  342.                 $betragSteuer $lineItem->getPrice()->getCalculatedTaxes()->getElements()[19]->getTax();
  343.                 $steuerschluessel '9';
  344.                 $steuerProzent $lineItem->getPrice()->getCalculatedTaxes()->getElements()[19]->getTaxRate();
  345.                 $positionstext $lineItem->getDescription() ?? "";
  346.                 $lieferscheinNr $belegnummer;
  347.                 $payload $lineItem->getPayload();
  348.                 $artikelNr array_key_exists('productNumber'$payload) ? $payload['productNumber'] : 'ohne';
  349.                 $menge $lineItem->getQuantity();
  350.                 $me 'StĂĽck';
  351.                 
  352.                 $produktart 'Eigenfertigung';
  353.                 if ($lineItem->getProduct()) {
  354.                     $propertyIds $lineItem->getProduct()->getPropertyIds();
  355.                     if(in_array($handelswareId$propertyIds)){
  356.                         $produktart 'Handelsware';
  357.                     }
  358.                 } else {
  359.                     $produktart 'Rabatt';
  360.                 }
  361.             /*
  362.                 Get all info about order and write to Shop2DWH_Belegkopf and Shop2DWH_Belegposition
  363.                 Belegkopf:
  364.                 Belegart, Belegnummer, BestellNr, Belegdatum, Leistungsdatum, Erzeugungsdatum, (Referenznummer), Personenkonto,
  365.                 Zahlungsdienstleister_OP_ID, Valutadatum, Ziel1, Skonto1Betrag, Skonto1Prozent, FaelligAm, Land_Lieferadresse_ISO3,
  366.                 Land_Rechnungsadresse_ISO3, UST-ID, Endbetrag, Endbetrag_Steuerschluessel1, Endbetrag_Steuerschluessel2, 
  367.                 
  368.                 Belegposition:
  369.                 *BelegkopfID int11
  370.                 PositionsNr int11
  371.                 BetragNetto decimal
  372.                 BetragSteuer decimal
  373.                 Steuerschluessel varchar: 9=> 19%, 5:0%
  374.                 SteuerProzent decimal(4,2) (???)
  375.                 PositionsText
  376.                 LieferscheinNr varchar15
  377.                 Leistungsdatum date
  378.                 ArtikelNr
  379.                 Menge int
  380.                 ME varchar(15) ???
  381.                 Produktart varchar(15) ???
  382.                  */
  383.                 // Credit-note type should have negative values for money-related entries
  384.                 if(in_array($documentTechnicalName$creditNote_types)){
  385.                   $betragNetto *= -1;
  386.                   $betragSteuer *= -1;
  387.                 }
  388.                  $sql_belegposition 'INSERT INTO Shop2DWH_Belegposition ('
  389.                  .' BelegkopfID , PositionsNr, BetragNetto, BetragSteuer, Steuerschluessel, '
  390.                  .'SteuerProzent, PositionsText, LieferscheinNr, Leistungsdatum, '
  391.                  .'ArtikelNr, Menge, ME, Produktart ) VALUES ( '
  392.                  .$belegkopfId .', '
  393.                  .$positionsnummer .', '
  394.                  .$betragNetto .', '
  395.                  .$betragSteuer .', '
  396.                  .'"' .$steuerschluessel .'", '
  397.                  .$steuerProzent .', '
  398.                  .'"' .$positionstext .'", '
  399.                  .'"' .$lieferscheinNr .'", '
  400.                  .'"' .$leistungsdatum .'", '
  401.                  .'"' .$artikelNr .'", '
  402.                  .$menge .', '
  403.                 .'"' .$me .'", '
  404.                 .'"' .$produktart .'" )';
  405. //dump($sql_belegposition);
  406.                 if(! $mysqli->query($sql_belegposition)){
  407.                     //dump(mysqli_error($mysqli), $sql_belegposition);
  408.                 }
  409.             
  410.             }
  411.             // add another position for shipment
  412.             $shipping_costs $order->getShippingCosts();
  413.             $betragNetto $shipping_costs->getTotalPrice();
  414.             $betragSteuer $shipping_costs->getCalculatedTaxes()->getElements()[19]->getTax();
  415.             $steuerschluessel '9';
  416.             $steuerProzent $shipping_costs->getCalculatedTaxes()->getElements()[19]->getTaxRate();
  417.             $positionstext 'Versandkosten';
  418.             $lieferscheinNr $belegnummer;
  419.             $artikelNr 'ohne';
  420.             $menge 1;
  421.             $me 'StĂĽck';
  422.                 
  423.             $produktart 'Versandkosten';
  424.             
  425.             if(in_array($documentTechnicalName$creditNote_types)){
  426.                   $betragNetto *= -1;
  427.                   $betragSteuer *= -1;
  428.             }
  429.             
  430.             $sql_shipmentPosition 'INSERT INTO Shop2DWH_Belegposition ('
  431.             .' BelegkopfID , PositionsNr, BetragNetto, BetragSteuer, Steuerschluessel, '
  432.             .'SteuerProzent, PositionsText, LieferscheinNr, Leistungsdatum, '
  433.             .'ArtikelNr, Menge, ME, Produktart ) VALUES ( '
  434.             .$belegkopfId .', '
  435.             .'99998' .', '
  436.             .$betragNetto .', '
  437.             .$betragSteuer .', '
  438.             .'"' .$steuerschluessel .'", '
  439.             .$steuerProzent .', '
  440.             .'"' .$positionstext .'", '
  441.             .'"' .$lieferscheinNr .'", '
  442.             .'"' .$leistungsdatum .'", '
  443.             .'"' .$artikelNr .'", '
  444.             .$menge .', '
  445.             .'"' .$me .'", '
  446.             .'"' .$produktart .'" )';
  447.             
  448.             if(! $mysqli->query($sql_shipmentPosition)){
  449.                 // TODO sql-query failed
  450.             }
  451.             //dump("added shipment");
  452.         
  453.         //dump("finished");
  454.         } else {
  455.             //no-op
  456.         }
  457.     }
  458.     private function getZahlungsart($orderUUID$orderVersionUUID$languageUUID) {
  459.         // get the payment method as "Name"
  460.         SharedFunctions::dumpToLog("getZahlungsart()");
  461.         $dbHost $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseHost');
  462.         $dbUser $this->systemConfigService->get('SteincoProductsController.config.externalDatabaseUser');
  463.         $dbPass $this->systemConfigService->get('SteincoProductsController.config.externalDatabasePassword');
  464.         $dbName $this->systemConfigService->get('SteincoProductsController.config.shopDatabaseName');
  465.         $mySql = new \mysqli($dbHost$dbUser$dbPass$dbName);
  466.         if ($mySql->connect_errno) {
  467.             SharedFunctions::dumpToLog('Could not connect to MySQL: ' $mySql->connect_error);
  468.             return "";
  469.         }
  470.         $zahlungsart "";
  471.         try {
  472.             $sql "
  473.                 SELECT 
  474.                     COALESCE(pmt.distinguishable_name, pmt.name) AS payment_method 
  475.                 FROM 
  476.                     order_transaction ot 
  477.                 JOIN 
  478.                     payment_method pm ON ot.payment_method_id = pm.id 
  479.                 JOIN 
  480.                     payment_method_translation pmt ON pm.id = pmt.payment_method_id 
  481.                 WHERE 
  482.                     ot.order_id = UNHEX('" $orderUUID "') 
  483.                     AND ot.order_version_id = UNHEX('" $orderVersionUUID "') 
  484.                     AND pmt.language_id = UNHEX('" $languageUUID "') 
  485.                 LIMIT 1
  486.             ";
  487.             $result $mySql->query($sql);
  488.             if ($result) {
  489.                 $row $result->fetch_assoc();
  490.                 if ($row) {
  491.                     $zahlungsart $row['payment_method'];
  492.                     SharedFunctions::dumpToLog($result);
  493.                 } else {
  494.                     SharedFunctions::dumpToLog('Keine Daten gefunden. SQL: ' $sql);
  495.                 }
  496.             } else {
  497.                 SharedFunctions::dumpToLog('Error executing: ' $sql);
  498.                 SharedFunctions::dumpToLog('SQL-Error: ' $mySql->error);
  499.             }
  500.         } catch (\Exception $e) {
  501.             // Logge die Fehlermeldung in eine Datei oder verarbeite den Fehler entsprechend
  502.             SharedFunctions::dumpToLog('Abfrage der Zahlungsart fehlgeschlagen: .'$sql);
  503.             SharedFunctions::dumpToLog($e->getMessage());
  504.         }
  505.         return $zahlungsart;
  506.     }
  507.     private function getPropertyOptions_by_name_and_propertydescription($propertyoptionname$propertydescription)
  508.     {
  509.         SharedFunctions::dumpToLog("getPropertyOptions_by_name_and_propertydescription(): [" $propertyoptionname "], [" $propertydescription "]");
  510.         $property_uuid $this->getPropertyUUID_by_description($propertydescription);
  511.         $property_filter = new EqualsFilter('groupId'$property_uuid);
  512.         $propertyoption_filter = new EqualsFilter('name'$propertyoptionname);
  513.         $search_criteria = new Criteria([]);
  514.         $search_criteria->addFilter($property_filter);
  515.         $search_criteria->addFilter($propertyoption_filter);
  516.         $search_results $this->propertyOptionRepository->search($search_criteria,
  517.             $this->context)->getElements();
  518.         SharedFunctions::dumpToLog($search_results);
  519.         return $search_results;
  520.     }
  521.     private function getPropertyUUID_by_description($name) {
  522.         $filter = new EqualsFilter("description"$name);
  523.         $entity $this->propertyRepository->search((new Criteria())->addFilter($filter), 
  524.         $this->context)->first();
  525.         if($entity) {
  526.             return $entity->getId();
  527.         }
  528.         return null;
  529.     }
  530.     private function getOrder($orderUUID){
  531.         $orderCriteria = new Criteria([]);
  532.         $orderCriteria->addAssociation('currency')
  533.         ->addAssociation('billingAddress')
  534.         ->addAssociation('lineItems')
  535.         ->addAssociation('lineItems.product')
  536.         ->addAssociation('lineItems.product.properties')
  537.         ->addAssociation('transactions')
  538.         ->addAssociation('transactions.paymentMethod')
  539.         ->addAssociation('paymentMethod')
  540.         ->addAssociation('billingAddress.country')
  541.         ->addFilter(new EqualsFilter('id'$orderUUID));
  542.         $order_searchresult $this->orderRepository->search(
  543.             $orderCriteria,
  544.         \Shopware\Core\Framework\Context::createDefaultContext());
  545.         
  546.         $order $order_searchresult->getEntities()->getElements()[$orderUUID];
  547.         return $order;
  548.     }
  549.     // file stuff
  550.     //TODO: what data do we need?: $orderID, $config? $documentTypeName?
  551.     private function writeFilesToExchangeFolder($orderId$document){
  552.         $orderCriteria = new Criteria([]);
  553.         $orderCriteria->addAssociation('currency')->addAssociation('billingAddress')->addAssociation('salesChannel')->addAssociation('documents')->addAssociation('createdBy')->addFilter(new EqualsFilter('id'$orderId));
  554.         $order_searchresult $this->orderRepository->search(
  555.             $orderCriteria,
  556.            \Shopware\Core\Framework\Context::createDefaultContext());
  557.         
  558.         $order $order_searchresult->getEntities()->getElements()[$orderId];
  559.         $this->createJPLFile($order$document->getConfig(), $document->getConfig()['name']);
  560.         // find the file and copy to the selected directory
  561.         $this->copyCreatedFileToFileExchangeDirectory($document->getId(), $this->context);
  562.     }
  563.     // taken from SchoettlerDocumentService
  564.     Private function copyCreatedFileToFileExchangeDirectory($documentId$context) {
  565.         $outputdirectory $this->systemConfigService->get('SteincoProductsController.config.fileOutputPath');
  566.         $archivedirectory $this->systemConfigService->get('SteincoProductsController.config.archivefileOutputPath');
  567.         // find the source file
  568.         //dump($documentId);
  569.         $criteria = new Criteria([$documentId]);
  570.         $criteria->addAssociation('documentMediaFile');
  571.         $criteria->addAssociation('documentType');
  572.         /** @var DocumentEntity $document */
  573.         $document $this->documentRepository->search($criteria$context)->get($documentId);
  574.         $generatedDocument $this->documentService->getDocument($document$context);
  575.         if ((!$outputdirectory == NULL) and ($outputdirectory != "") and ($generatedDocument) and $generatedDocument->getFilename())  {
  576.             if((!$archivedirectory == NULL) and ($archivedirectory != "")) {
  577.                 $archivefilename $archivedirectory .$generatedDocument->getFilename();
  578.                 $archivefile fopen($archivefilename"w");
  579.                 fwrite($archivefile$generatedDocument->getFileBlob());
  580.                 fclose($archivefile);
  581.             }
  582.             $filename $outputdirectory .$generatedDocument->getFilename();
  583.             $file fopen($filename"w");
  584.             fwrite($file$generatedDocument->getFileBlob());
  585.             fclose($file);
  586.         }
  587.     }
  588.     Private function createJPLFile($order$config$documentTypeName) {
  589.         $myDocType "unbekannt";
  590.         //$shopname = $context
  591.         $outputContent null;
  592.         switch ($documentTypeName) {
  593.         case ("invoice"):
  594.             $myDocType $this->DOK_RECHNUNG;
  595.             $outputContent $this->getInvoiceOutputContent($order$config);
  596.             break;
  597.         case ("credit_note"):
  598.             $myDocType$this->DOK_GUTSCHRIFT;
  599.             $outputContent $this->getCreditNoteOutput($order$config);
  600.             break;
  601.         case ("delivery_note"):
  602.             $myDocType $this->DOK_LIEFERSCHEIN;
  603.             $outputContent $this->getDeliveryNoteOutput($order$config);
  604.             break;
  605.         case ("storno"):
  606.             $myDocType $this->DOK_RECHNUNGSSTORNO;
  607.             $outputContent $this->getStornoBillOutput($order$config);
  608.             break;
  609.             // No types for Gutschriftstorno, Auftragbestätigung implemented (yet)
  610.         }
  611.         if (!$outputContent) {
  612.             $outputContent "Error while creating content of this file.";
  613.         }
  614.         $archivedirectory $this->systemConfigService->get('SteincoProductsController.config.archivefileOutputPath');
  615.         $outputdirectory $this->systemConfigService->get('SteincoProductsController.config.fileOutputPath');
  616.         if (!empty($outputdirectory)) {
  617.             if (!empty($archivedirectory)) {
  618.                 $archivefilename $archivedirectory .$documentTypeName ."_" .$config['documentNumber'] .".jpl";
  619.                 $archivefile fopen($archivefilename"a");
  620.                 fwrite($archivefile$outputContent);
  621.                 fclose($archivefile);
  622.             }
  623.             $filename $outputdirectory .$documentTypeName ."_" .$config['documentNumber'] .".jpl";
  624.             $file fopen($filename"a");
  625.             fwrite($file$outputContent);
  626.             fclose($file);
  627.         }
  628.         // some error: could not create file because of missing outputpath
  629.     }
  630.     private function getInvoiceOutputContent($order$config
  631.     {
  632.         // $shopname -should be in context
  633.         // 
  634.         $customerName $order->getOrderCustomer()->getCompany();
  635.         if (!$customerName) {
  636.             $customerName $order->getOrderCustomer()->getLastName() .", "$order->getOrderCustomer()->getFirstName();
  637.         } 
  638.         $bearbeiter "shopware";
  639.         $result 'zeich_nr= "Shop' .$this->DOK_RECHNUNG .$config['documentNumber'] .'"' .$this->LINEBREAK
  640.             .'dokuart= "' .$this->DOK_RECHNUNG .'"'.$this->LINEBREAK
  641.             .'logi_verzeichnis = "Fr"'.$this->LINEBREAK
  642.             .'dok_dat_feld[1] = "' .$order->getOrderCustomer()->getCustomerNumber() .'"'.$this->LINEBREAK
  643.             .'dok_dat_feld[2] = "' .$customerName .'"'.$this->LINEBREAK
  644.             .'dok_dat_feld[14] = "' .$config['documentNumber'] .'"'.$this->LINEBREAK
  645.             .'dok_dat_feld[38] = "' .$bearbeiter .'"'.$this->LINEBREAK
  646.             .'dok_dat_feld[39] = "Shop"'.$this->LINEBREAK
  647.             .'dok_dat_feld[51] = "' date("d.m.Y") .'"'.$this->LINEBREAK;
  648.            
  649.             $result .= 'dok_dat_feld_60[1] = "' .$order->getOrderNumber() .'"' .$this->LINEBREAK;
  650.         return $result;
  651.     }
  652.     Private function getCreditNoteOutput($order$config)
  653.     {
  654.         $bearbeiter "shopware";
  655.         $customerName $order->getOrderCustomer()->getCompany();
  656.         if (!$customerName) {
  657.             $customerName $order->getOrderCustomer()->getLastName() .", "$order->getOrderCustomer()->getFirstName();
  658.         } 
  659.         $result 'zeich_nr = "Shop' .$this->DOK_GUTSCHRIFT .$config['documentNumber'] ."'" .$this->LINEBREAK
  660.             .'dokuart = "' .$this->DOK_GUTSCHRIFT .'"' .$this->LINEBREAK
  661.             .'var_nr = 1'.$this->LINEBREAK
  662.             .'logi_verzeichnis = "Fr"' .$this->LINEBREAK
  663.             .'dok_dat_feld[1] = "' .$order->getOrderCustomer()->getCustomerNumber() .'"'.$this->LINEBREAK
  664.             .'dok_dat_feld[2] = "' .$customerName .'"'.$this->LINEBREAK
  665.             .'dok_dat_feld[15] = "' .$config['documentNumber'] .'"'.$this->LINEBREAK
  666.             .'dok_dat_feld[38] = "' .$bearbeiter .'"' .$this->LINEBREAK
  667.             .'dok_dat_feld[39] = "Shop"'.$this->LINEBREAK
  668.             .'dok_dat_feld[51] = "' date("d.m.Y") .'"'.$this->LINEBREAK;
  669.             // multiple Orders?
  670.         $result .= 'dok_dat_feld_60[1] = "' .$order->getOrderNumber() .'"' .$this->LINEBREAK;
  671.         return $result;
  672.     }
  673.     Private function getDeliveryNoteOutput($order$config
  674.     {
  675.        /*  zeich_nr = "RollenILSVK823000817"                Dokument ID: "Shop", Dokumentart, Dokument Nr
  676.         dokuart = "ILSVK"                        Dokumentart
  677.         var_nr = "1"                            Konstante
  678.         logi_verzeichnis = "Fr"                        Konstante
  679.         dok_dat_feld[1] = "1209331"                    KundenNr
  680.         dok_dat_feld[2] = "PASOTEC GmbH"                KundenName
  681.         dok_dat_feld[13] = "823000817"                    Dokument Nr
  682.         dok_dat_feld[38] = "PURSCHKES"                    Bearbeiter
  683.         dok_dat_feld[39] = "Rollen"                    Shop (=Konstante) 
  684.         dok_dat_feld[51] = "12.10.2021"                    Datum
  685.         dok_dat_feld_60[1] = "KA53131"                    Auftrag
  686.          */
  687.         $bearbeiter "shopware";
  688.         $customerName $order->getOrderCustomer()->getCompany();
  689.         if (!$customerName) {
  690.             $customerName $order->getOrderCustomer()->getLastName() .", "$order->getOrderCustomer()->getFirstName();
  691.         } 
  692.         $result 'zeich_nr = "Shop' .$this->DOK_LIEFERSCHEIN .$config['documentNumber'] .'"' .$this->LINEBREAK
  693.         .'dokuart = "' .$this->DOK_LIEFERSCHEIN .'"' .$this->LINEBREAK
  694.         .'var_nr = 1'.$this->LINEBREAK
  695.         .'logi_verzeichnis = "Fr"' .$this->LINEBREAK
  696.         .'dok_dat_feld[1] = "' .$order->getOrderCustomer()->getCustomerNumber() .'"'.$this->LINEBREAK
  697.         .'dok_dat_feld[2] = "' .$customerName .'"'.$this->LINEBREAK
  698.         .'dok_dat_feld[13] = "' .$config['documentNumber'] .'"'.$this->LINEBREAK
  699.         .'dok_dat_feld[38] = "' .$bearbeiter .'"' .$this->LINEBREAK
  700.         .'dok_dat_feld[39] = "Shop"'.$this->LINEBREAK
  701.         .'dok_dat_feld[51] = "' date("d.m.Y") .'"'.$this->LINEBREAK;
  702.         $result .= 'dok_dat_feld_60[1] = "' .$order->getOrderNumber() .'"' .$this->LINEBREAK;
  703.         return $result;
  704.     }
  705.     Private function getStornoBillOutput($order$config)
  706.     {
  707.        /*  zeich_nr = "RollenIGUVK32001379"                Dokument ID: "Shop", Dokumentart, Dokument Nr
  708.           dokuart = "IGUVK"                        Dokumentart
  709.           var_nr = "1"                            Konstante
  710.           logi_verzeichnis = "Fr"                        Konstante
  711.           dok_dat_feld[1] = "1201307"                    KundenNr
  712.           dok_dat_feld[2] = "Universitätsklinikum Dresden"        KundenName    
  713.           dok_dat_feld[15] = "32001379"                    Dokument Nr
  714.            dok_dat_feld[38] = "LINDHORSTJ"                    Bearbeiter
  715.            dok_dat_feld[39] = "Rollen"                    SHOP (=Konstante) 
  716.            dok_dat_feld[51] = "12.10.2021"                    Datum
  717.            dok_dat_feld_60[1] = "KA54091"                    Auftrag
  718.             dok_dat_feld_60[2] = "KA54091"                    Auftrag
  719.            dok_dat_feld_61[1] = "00050066"                    Lieferschein
  720.            dok_dat_feld_61[2] = "00050066"                    Lieferschein
  721.  */
  722.         $bearbeiter "shopware";
  723.         $customerName $order->getOrderCustomer()->getCompany();
  724.         if (!$customerName) {
  725.             $customerName $order->getOrderCustomer()->getLastName() .", "$order->getOrderCustomer()->getFirstName();
  726.         } 
  727.         $result 'zeich_nr = "Shop' .$this->DOK_RECHNUNGSSTORNO .$config['documentNumber'] .'"' .$this->LINEBREAK
  728.         .'dokuart = "' .$this->DOK_RECHNUNGSSTORNO .'"' .$this->LINEBREAK
  729.         .'var_nr = 1'.$this->LINEBREAK
  730.         .'logi_verzeichnis = "Fr"' .$this->LINEBREAK
  731.         .'dok_dat_feld[1] = "' .$order->getOrderCustomer()->getCustomerNumber() .'"'.$this->LINEBREAK
  732.         .'dok_dat_feld[2] = "' .$customerName .'"'.$this->LINEBREAK
  733.         .'dok_dat_feld[15] = "' .$config['documentNumber'] .'"'.$this->LINEBREAK
  734.         .'dok_dat_feld[38] = "' .$bearbeiter .'"' .$this->LINEBREAK
  735.         .'dok_dat_feld[39] = "Shop"'.$this->LINEBREAK
  736.         .'dok_dat_feld[51] = "' date("d.m.Y") .'"'.$this->LINEBREAK;
  737.         // in shopware, a storno bill references a single invoice and thus a single order
  738.         $invoiceNr $config['custom']['invoiceNumber'] ?? '';
  739.         $result .= 'dok_dat_feld_60[1] = "' .$order->getOrderNumber() .'"' .$this->LINEBREAK
  740.             .'dok_dat_feld_61[1] = "' .$invoiceNr .'"' .$this->LINEBREAK;
  741.         return $result;
  742.     }
  743. }