v2.7.x SendOrderProcess

Thema wurde von Avenger, 12. August 2016 erstellt.

  1. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    "SendOrderProcess" bietet keine Möglichkeit, updatesicher weitere Attachments an die order-mail zu hängen

    Vor Versand der Mail sollte etwas wie

    Code:
    $t_mail_attachment_array=$this->add_more_attachments($t_mail_attachment_array);
    aufgerufen werden, damit man das tun kann.
     
  2. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Da ich nicht so lange warten kann, bis das existiert, habe ich einen anderen Weg gewählt, das zu erreichen:

    ich habe die "GXEngine\Classes\SystemServices\Email\Collections\AttachmentCollection.inc.php" überladen

    Folgenden Code als "user_classes\overloads\AttachmentCollection\pt_AttachmentCollection.inc.php" speichern.

    Damit kann man situationsbezogene Attachments an die order-mail anhängen.

    In meinem konkreten Fall geht es darum, einen Kundenlieferschein für eine "Dropshipping"-Funktion anzuhängen.

    (Der Shopbetreiber liefert direkt an den Endkunden des Bestellers (Händler), der Händler kann aber seinen eigenen Lieferschein mitgeben, so dass der Endkunde nicht sieht, dass der Versand nicht über seinen Händler erfolgte...)

    Code:
    <?php
    /* --------------------------------------------------------------
    pt_AttachmentCollection.inc.php 2016-08-14 Avenger
    Gambio GmbH
    http://www.gambio.de
    Copyright (c) 2015 Gambio GmbH
    
    Copyright (c) 2016 Avenger, apprentice@gmx.de
    Allow additional attachments
    
    Released under the GNU General Public License (Version 2)
    [http://www.gnu.org/licenses/gpl-2.0.html]
    --------------------------------------------------------------
    */
    
    class pt_AttachmentCollection extends pt_AttachmentCollection_parent
    {
      public function __construct()
      {
        parent::__construct();
        $php_self=basename($_SERVER['PHP_SELF']);
        if ($php_self==FILENAME_CHECKOUT_PROCESS)
        {
          //Add dropshipping defivery slip, if "dropshipping" is defined
          $dropshipping_text='dropshipping';
          $use_dropshipping=$_SESSION[$dropshipping_text]['dropshipping_select']=='true';
          if ($use_dropshipping)
          {
            $dropshipping_file=$_SESSION[$dropshipping_text]['delivery_slip_file'];
            if ($dropshipping_file)
            {
              $this->add(MainFactory::create('EmailAttachment', $dropshipping_file, TEXT_DROPSHIPPING_DELIVERY_SLIP_NAME));
            }
          }
        }
        /*
        elseif ($php_self==FILENAME_XXXXXXX)
        {
          //Check for other attachments in other contexts
        }
        */
      }
    }
    Das "Dropshipping" wird im Laufe des Checkouts bei der Versandadresse definiert....

    dropshipping.jpg

    (Wobei dann verhindert werden muss, dass diese Adresse in's Adressbuch des Händlers eingetragen wird... :))
     
  3. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Unabhängig von der vorigen Lösung sollte das aber im "SendOrderProcess" abgearbeitet werden...

    Um ggfs. auch das "Order Subject" anpassen zu können, sollte das auch in der neuen Methode möglich sein...

    Code:
    $this->add_more_attachments($t_mail_attachment_array,$order_subject);
    Die Definition der neuen Methode sollte dann so aussehen:

    Code:
    public function add_more_attachments(&$t_mail_attachment_array,&$order_subject);
    Dann kann man sich nach Herzenslust bei den Attachments austoben...
     
  4. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Beim debuggen dieser Lösung ist mir folgendes aufgefallen:

    Es werden Unmengen an Mail-Daten gespeichert!

    In den Mail-Tabellen der DB die Quelltexte der Admin- und der Kunden-Mail.

    (Der Quelltext der Kunden-Mail wird auch noch mal im "Orders"-Datensatz gespeichert.)

    Alle (PDF-)Attachments werden im Verzeichnis "uploads/attachments" gespeichert, getrennt nach Kunden- und Admin-Mail.

    Die Frage ist, ob das sinnvoll und notwendig ist, denn da sammeln sich schnell sehr viele Daten und Dateien.

    Die Daten für den Admin kann man m.E. schon mal weg lassen, da die ja identisch zu den Kunden-Daten sind...
     
  5. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Im Rahmen dieser Dropshipping-Anpassungen hatte ich ein weiteres großes Problem:

    diese Drop-Shipping Lieferadresse in die Bestellung in der DB hinein zu bekommen....

    Da diese Drop-Shipping Lieferadresse nicht im Adressbuch gespeichert wird (weil das sonst unnötig groß wird) ist das mit der GXEngine recht problematisch...

    (In Vor-GXEngine-Zeiten konnte man das updatesicher sehr einfach durch Überladen der Order-Klasse ändern.)

    Ich hoffe sehr, dass ich die Schönheit der GXEngine nur noch nicht richtig verstanden habe, weil der Weg, den ich letztendlich bisher gefunden habe, m.E: ziemlich krank ist...

    Denn ich muss 5 (in Worten: fünf) Klassen überladen, um (letztlich unter Verwendung einer geeigneten Standard-Methode (function _createCustomerAddressByArray in "GXEngine\Classes\CoreServices\Address\CustomerAddressReader.inc.php")) das gewünschte Ergebnis zu erzielen!

    (Ich habe mal den normalen Weg der Adressenspeicherung im Debugger verfolgt, und mein Problem dann analog nachgebildet.)

    Das Problem ist, dass ich mich durch diverse Klassen "durchhangeln" muss, um in den Klassen-Kontext zu gelangen, in dem die benötigte lokale ("protected") Methode "_createCustomerAddressByArray" definiert ist...

    Das ist die jetzt von mir gefundene Lösung:

    1. Überladen von "system\classes\checkout\CheckoutProcessProcess.inc.php" (pt_CheckoutProcessProcess)

    Code:
      protected function _getDeliveryAddress()
      {
        $dropshipping_text='dropshipping';
        $use_dropshipping=$_SESSION[$dropshipping_text]['dropshipping_select']=='true';
        if ($use_dropshipping)
        {
          //Set delivery address to dropshipping address
          $addressDataArray=$_SESSION[$dropshipping_text]['data'];
          $addressDataArray['address_book_id']='';
          $addressDataArray['customer_b2b_status']='';
          $addressDataArray['entry_suburb']='';
          $addressDataArray['entry_state']='';
          $customerReadService = StaticGXCoreLoader::getService('CustomerRead');
          $deliveryAddress=$customerReadService->createCustomerAddressByArray($addressDataArray);
        }
        else
        {
          $deliveryAddress=parent::_getDeliveryAddress();
        }
        return $deliveryAddress;
      }
    2. Überladen von "GXEngine\Classes\CoreServices\Customer\CustomerReadService.inc.php" (pt_CustomerReadService)

    Code:
    class pt_CustomerReadService extends pt_CustomerReadService_parent
    {
      public function createCustomerAddressByArray(array $addressDataArray)
      {
      return $this->customerRepository->createCustomerAddressByArray($addressDataArray);
      }
    }
    3. Überladen von "GXEngine\Classes\CoreServices\Address\CustomerRepository.inc.php" (pt_CustomerRepository)

    Code:
    class pt_CustomerRepository extends pt_CustomerRepository_parent
    {
      public function createCustomerAddressByArray(array $addressDataArray)
      {
        return $this->customerAddressRepository->createCustomerAddressByArray($addressDataArray);
      }
    }
    4. Überladen von "GXEngine\Classes\CoreServices\Address\CustomerAddressRepository.inc.php" (pt_CustomerAddressRepository)

    Code:
    class pt_CustomerAddressRepository extends pt_CustomerAddressRepository_parent
    {
      public function createCustomerAddressByArray(array $addressDataArray)
      {
        return $this->customerAddressReader->createCustomerAddressByArray($addressDataArray);
      }
    }
    5. "GXEngine\Classes\CoreServices\Address\CustomerAddressReader.inc.php" (pt_CustomerAddressReader)

    Code:
      public function createCustomerAddressByArray(array $addressDataArray)
      {
        $customerAddress=$this->_createCustomerAddressByArray($addressDataArray);
        return $customerAddress;
      }
    Ist das wirklich der einzige Weg, mein Ziel zu erreichen, oder gibt es eine elegantere und einfachere Lösung???
     
  6. Moritz (Gambio)

    Moritz (Gambio) Administrator

    Registriert seit:
    26. April 2011
    Beiträge:
    5.786
    Danke erhalten:
    2.692
    Danke vergeben:
    903
    Hallo Avenger,

    soll die Dropshipping-Adresse einer Bestellung woanders gespeichert werden als eine normale Adresse einer Bestellung? Wenn ja, wo? Gibt es extra Spalten oder Tabellen, die beim Anlegen der Bestellung befüllt werden müssen? Diese Infos brauche ich, um eine passgenaue Lösung anzubieten.
    Das Anhang-Problem werde ich anschließend unter die Lupe nehmen.
     
  7. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Nein, die wird gar nicht gespeichert, außer in der Bestellung....

    Wenn sie gespeichert werden sollte, könnte ich ja das vorhandene Verfahren verwenden, wobei dann allerdings das Adressbuch ziemlich voll und übersichtlich würde...

    Da die aber i.d.R. nur ein Mal gebraucht wird, muss man die nur in die Bestellung einbringen....

    Wie gesagt, ich habe das gelöst, nur erscheint mir diese Lösung sehr unelegant, und ich muss zu viel über die GXEngine-Strukturen und -Abläufe wissen...
     
  8. Moritz (Gambio)

    Moritz (Gambio) Administrator

    Registriert seit:
    26. April 2011
    Beiträge:
    5.786
    Danke erhalten:
    2.692
    Danke vergeben:
    903
    Mit Speichern meine ich nicht das Adressbuch. Ich habe es also richtig verstanden, dass die Dropshipping-Adressdaten nicht mehr Daten umfassen als eine normale Adresse, diese also alle ganz normal in die orders-Tabelle gespeichert werden?

    Wo stehen die Adressdaten zum Zeitpunkt der Order-Speicherung? Alle in einem Array in der Session?
     
  9. Moritz (Gambio)

    Moritz (Gambio) Administrator

    Registriert seit:
    26. April 2011
    Beiträge:
    5.786
    Danke erhalten:
    2.692
    Danke vergeben:
    903
    #9 Moritz (Gambio), 3. Oktober 2016
    Zuletzt bearbeitet: 3. Oktober 2016
    Angenommen du hast die Lieferadressdaten in der Session stehen. Dann benötigst du nur einen Overload der Klasse CheckoutProcessProcess. Sowas in dieser Art wäre das dann bei dir:

    PHP:
    protected function _getDeliveryAddress()
    {
        if(
    $_SESSION['dropshipping']['dropshipping_select'] === 'true')
        {
            
    $addressArray $_SESSION['dropshipping']['data'];

            
    $gender                MainFactory::create('CustomerGender'$addressArray['gender']);
            
    $firstName             MainFactory::create('CustomerFirstname'$addressArray['firstname']);
            
    $lastName              MainFactory::create('CustomerLastname'$addressArray['lastname']);
            
    $company               MainFactory::create('CustomerCompany'$addressArray['company']);
            
    $B2BStatus             MainFactory::create('CustomerB2BStatus'false);
            
    $street                MainFactory::create('CustomerStreet'$addressArray['street']);
            
    $houseNumber           MainFactory::create('CustomerHouseNumber'$addressArray['house_number']);
            
    $additionalAddressInfo MainFactory::create('CustomerAdditionalAddressInfo''');
            
    $suburb                MainFactory::create('CustomerSuburb''');
            
    $postCode              MainFactory::create('CustomerPostcode'$addressArray['postcode']);
            
    $city                  MainFactory::create('CustomerCity'$addressArray['city']);

            
    $country     MainFactory::create('CustomerCountry'
                               new 
    IdType(0),
                               
    MainFactory::create('CustomerCountryName'$addressArray['country']),
                               
    MainFactory::create('CustomerCountryIso2'$addressArray['country_iso2']),
                               
    MainFactory::create('CustomerCountryIso3'$addressArray['country_iso3']), new IdType(5), true);
            
    $countryZone MainFactory::create('CustomerCountryZone'
                               new 
    IdType(0),
                               
    MainFactory::create('CustomerCountryZoneName'''),
                               
    MainFactory::create('CustomerCountryZoneIsoCode'''));

            
    $dropshippingAddress MainFactory::create('AddressBlock'$gender$firstName$lastName$company,
                                   
    $B2BStatus$street$houseNumber$additionalAddressInfo,
                                   
    $suburb$postCode$city$country$countryZone);

            return 
    $dropshippingAddress;
        }
        else
        {
            return 
    parent::_getDeliveryAddress();
        }
    }
     
  10. Moritz (Gambio)

    Moritz (Gambio) Administrator

    Registriert seit:
    26. April 2011
    Beiträge:
    5.786
    Danke erhalten:
    2.692
    Danke vergeben:
    903
    Zum Thema E-Mail-Versand: Dein Overload der Klasse AttachmentCollection ist nicht schön, aber du hast Recht, dass aktuell die Möglichkeiten fehlen sich in der SendOrderProcess einzuklinken. Da müssen wir nachbessern. Hier habe ich für dich keine elegantere Lösung parat.
     
  11. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Ja, so ist es.
    Das wäre ja schön... :)

    Werde ich mal testen.

    Allerdings war mein Bestreben auch, schon vorhandenen Code zu verwenden....

    (function _createCustomerAddressByArray in "GXEngine\Classes\CoreServices\Address\CustomerAddressReader.inc.php"))

    Ja...
     
  12. Moritz (Gambio)

    Moritz (Gambio) Administrator

    Registriert seit:
    26. April 2011
    Beiträge:
    5.786
    Danke erhalten:
    2.692
    Danke vergeben:
    903
    Mit Klassen unterhalb des Services zu arbeiten ist riskant, da sich die auch mal grundlegend ändern können. Ziel sollte es sein nur mit dem Service an sich zu arbeiten. Falls das nicht möglich ist, sollte man uns Bescheid geben, damit wir eventuell fehlende Schnittstellen nachliefern können.
     
  13. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Wie sieht es denn damit aus?

    Um in die Bestellgenerierung eingreifen zu können.

    QUOTE]Es fehlen mir bei den orders die GXEngine-Äquivalente zu

    Code:
    $this->add_order_data($t_sql_data_array);    $this->add_order_product_quantity_data($t_sql_data_array, $p_products_array);
            $this->add_order_total_data($t_sql_data_array, $this->order_totals_array[$i]);
            $this->add_order_status_history_data($t_sql_data_array);
            $this->add_product_data($p_products_sql_data_array, $p_products_id);
            $this->add_order_product_data($t_sql_data_array, $p_product_array);
            $this->add_special_data($t_sql_data_array, $t_special_array);
            $this->add_product_attribute_data($t_sql_data_array, $p_attribute_array);
            $this->add_order_product_attribute_data($t_sql_data_array, $t_attributes_array);
            $this->add_order_product_download_data($t_sql_data_array, $t_attributes_array);
            $this->add_tracking_data($t_sql_data_array, $t_customers_logon_array);
    (und vielleicht noch andere).
    [/QUOTE]Aus http://www.gambio.de/forum/threads/ueber-den-unsinn-der-gxengine.27067/#post-226304
     
  14. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Habe das jetzt mal so implementiert, und es funktioniert.....

    Wobei es zwischen 2.7 und der aktuellen 3er Version schon wieder Unterschiede gibt...

    D.h., das Overload muss dann wieder geändert werden...

    Das Spiel kann man wohl nicht gewinnen, man muss bei jedem Release seine Overloads überprüfen.
     
  15. Avenger

    Avenger G-WARD 2012/13/14/15

    Registriert seit:
    26. April 2011
    Beiträge:
    4.771
    Danke erhalten:
    1.478
    Danke vergeben:
    89
    Also für meinen Bedarf (und generellen Bedarf denke ich), sollte "SendOrderProcess" wie folgt erweitert werden::

    Code:
        if (SEND_EMAILS == 'true')
        {
          //Avenger
          $this->add_attachment($t_mail_attachment_array);
          $this->modify_order_subject($order_subject);
          //Avenger
    Mit folgenden neuen Methoden:


    Code:
      public function modify_order_subject(&$order_subject)
      {
      }
    
      public function add_attachment(&$t_mail_attachment_array)
      {
      }
    In meinem Fall würden Overloads dazu z.B. wie folgt aussehen:


    Code:
      public function modify_order_subject(&$order_subject)
      {
          parent::modify_order_subject($order_subject);
        $dropshipping_text='dropshipping';
        $use_dropshipping=$_SESSION[$dropshipping_text]['dropshipping_select']=='true';
        if ($use_dropshipping)
        {
          $dropshipping_file=$_SESSION[$dropshipping_text]['delivery_slip_file'];
          if ($dropshipping_file)
          {
            $order_subject.=' (Dropshipping)';
          }
        }
      }
    
      public function add_attachment(&$t_mail_attachment_array)
      {
          parent::add_attachment($t_mail_attachment_array);
        //Add dropshipping defivery slip, if "dropshipping" is defined
        $dropshipping_text='dropshipping';
        $use_dropshipping=$_SESSION[$dropshipping_text]['dropshipping_select']=='true';
        if ($use_dropshipping)
        {
          $dropshipping_file=$_SESSION[$dropshipping_text]['delivery_slip_file'];
          if ($dropshipping_file)
          {
            $t_mail_attachment_array[]=array(
              'name'=>TEXT_DROPSHIPPING_DELIVERY_SLIP_NAME,
              'path'=>$dropshipping_file
            );
          }
        }
      }
     
  16. Moritz (Gambio)

    Moritz (Gambio) Administrator

    Registriert seit:
    26. April 2011
    Beiträge:
    5.786
    Danke erhalten:
    2.692
    Danke vergeben:
    903
    Die Bestellung wird ja mittels
    PHP:
    $this->orderWriteService->createNewCustomerOrder($this->_getCustomerId(),
                                                                        
    $this->_getCustomerStatusInformation(),
                                                                        
    $this->_getCustomerNumber(),
                                                                        
    $this->_getCustomerEmail(),
                                                                        
    $this->_getCustomerTelephone(),
                                                                        
    $this->_getCustomerVatId(),
                                                                        
    $this->_getCustomerDefaultAddress(),
                                                                        
    $this->_getBillingAddress(),
                                                                        
    $this->_getDeliveryAddress(),
                                                                        
    $this->_getOrderItemCollection(),
                                                                        
    $this->_getOrderTotalCollection(),
                                                                        
    $this->_getOrderShippingType(),
                                                                        
    $this->_getOrderPaymentType(),
                                                                        
    $this->_getCurrencyCode(),
                                                                        
    $this->_getLanguageCode(),
                                                                        
    $this->_getOrderTotalWeight(),
                                                                        
    $this->_getComment(),
                                                                        
    $this->_getOrderStatusId(),
                                                                        
    $this->_getOrderAddonValuesCollection());
    erzeugt. Du siehst die ganzen Getter-Methoden, die du überladen kannst, um Bestellinformationen zu erweitern oder abzuändern.