View Issue Details

IDProjectCategoryView StatusLast Update
0001817OXID eShop (all versions)2. ----- eShop backend (admin) -----public2012-12-10 14:22
Reporterumaun Assigned To 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version4.3.1 revision 27257 
Fixed in Version4.3.2 revision 27884 
Summary0001817: In xml export foreign currencies ar enot converted according to currency rate
Descriptionin xml export all amounts from orders with foreign currencies are wrong.
e.g. shop uses EUR and an order comes in with CHF
then all amounts where exported without converting from CHF to EUR
Additional Informationin xml export only one currency is used
(always <Standardwaehrung>978</Standardwaehrung>)
therefore exporting amounts without using the currency rate of the order is wrong.

after testing i will propose a diff for oximex.php
TagsExport, Import
Attached Files
oximex.php (21,792 bytes)   
<?php
/**
 *    This file is part of OXID eShop Community Edition.
 *
 *    OXID eShop Community Edition is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    OXID eShop Community Edition is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with OXID eShop Community Edition.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @link      http://www.oxid-esales.com
 * @package   core
 * @copyright (C) OXID eSales AG 2003-2010
 * @version OXID eShop CE
 * @version   SVN: $Id: oximex.php 26767 2010-03-23 13:36:51Z vilma $
 */

/**
 * @package core
 */
class oxImex extends oxBase
{
    /**
     * Performs Lexware export to file.
     *
     * @param integer $iStart    Start writing to file from line
     * @param integer $iLines    Amount of lines to write
     * @param string  $sFilepath Path to export file
     *
     * @return bool
     */
    public function exportLexwareArticles( $iStart, $iLines, $sFilepath)
    {
        $myConfig = $this->getConfig();
        $oDB      = oxDb::getDb();

        $sArticleTable = getViewName('oxarticles');

        $sSelect = "select count(oxid) from $sArticleTable ";
        $iSize = $oDB->getOne( $sSelect);

        if ( $iStart < $iSize) {
            $fp = fopen( $sFilepath, "ab");
            if ( !$iStart) {
                // first time, write header
                fwrite( $fp, "\"Artikelnummer\";\"Bezeichnung\";\"Einheit\";\"Gewicht\";\"Matchcode\";\"Preis pro Anzahl\";\"Warengruppe\";\"Warengr.-Kurzbez.\";\"Warengr.-Steuersatz\";\"Warengr.-Konto Inland\";\"Warengr.-Konto Ausland\";\"Warengr.-Konto EG\";\"Preis 1\";\"Preis 2\";\"Preis 3\";\"Preis I/1\";\"Preis I/2\";\"Preis I/3\";\"Preis II/1\";\"Preis II/2\";\"Preis II/3\";\"Preis III/1\";\"Preis III/2\";\"Preis III/3\";\"B/N\";\"Lagerartikel\";\"EK 1\";\"W�hrung EK1\";\"EK 2\";\"W�hrung EK2\";\"Staffelmenge 1\";\"Staffelmenge 2\";\"Staffelmenge 3\";\"Lieferantennummer 1\";\"Lieferantennummer 2\";\"Bestellmenge Lf.1\";\"Bestellmenge Lf.2\";\"Bestellnr. Lf.1\";\"Bestellnr. Lf.2\";\"Lieferzeit Lf.1\";\"Lieferzeit Lf.2\";\"Lagerbestand\";\"Mindestbestand\";\"Lagerort\";\"Bestellte Menge\";\"St�ckliste\";\"Internet\";\"Text\"\r\n");
            }
            $oldMode = $oDB->setFetchMode( ADODB_FETCH_ASSOC);
            $sSelect = "select * from $sArticleTable ";
            $rs = $oDB->selectLimit( $sSelect, $iLines, $iStart);
            $oDB->setFetchMode( $oldMode);

            while (!$rs->EOF) {
                $oArticle = oxNew( "oxarticle" );
                $blAdmin = $this->isAdmin();
                // TODO: this workaround should be overworked
                $this->setAdminMode( false );
                $oArticle->load( $rs->fields['OXID']);
                $this->setAdminMode( $blAdmin );

                $sSelect = "select oxtitle from oxarticles where oxid = " . $oDB->quote( $oArticle->oxarticles__oxparentid->value );
                $oTitle = $oDB->getOne( $sSelect);
                if ($oTitle != false && strlen ($oTitle)) {
                    $nTitle = $this->interForm($oTitle);
                } else {
                    $nTitle = $this->interForm($oArticle->oxarticles__oxtitle->value);
                }


                $sToFile = $oArticle->oxarticles__oxartnum->value            // Artikelnummer
                //.";".$this->interForm($oArticle->oxarticles__oxshortdesc->value." ".$oArticle->oxarticles__oxvarselect->value) // Bezeichnung
                .";".$nTitle." ".$this->interForm($oArticle->oxarticles__oxvarselect->value) // Bezeichnung
                .";"."Stueck"                        // Einheit
                .";".$oArticle->oxarticles__oxweight->value                  // Gewicht
                .";".$oArticle->oxarticles__oxartnum->value                  // Matchcode
                .";"."1,000"                         // Preis pro Anzahl
                .";"                                  // Warengruppe
                .";"                                  // Warengr.-Kurzbez.
                .";"                                 // Warengr.-Steuersatz
                .";"                                  // Warengr.-Konto Inland
                .";"                                  // Warengr.-Konto Ausland
                .";"                                  // Warengr.-Konto EG
                .";".number_format($oArticle->oxarticles__oxprice->value, 2, '.', '')  // Preis 1
                .";"                                  // Preis 2
                .";"                                 // Preis 3
                .";"                                 // Preis I/1
                .";"                                 // Preis I/2
                .";"                                  // Preis I/3
                .";"                                  // Preis II/1
                .";"                                  // Preis II/2
                .";"                                  // Preis II/3
                .";"                                  // Preis III/1
                .";"                                  // Preis III/2
                .";"                                  // Preis III/3
                .";"                           // B/N
                .";"                           // Lagerartikel
                //.";".number_format($oArticle->oxarticles__oxtprice->value, 2, '.', '')// EK 1
                // #343 fix
                .";".number_format($oArticle->oxarticles__oxbprice->value, 2, '.', '')// EK 1
                .";"                           // W�hrung EK1
                .";"                           // EK 2
                .";"                           // W�hrung EK2
                .";"                           // Staffelmenge 1
                .";"                           // Staffelmenge 2
                .";"                           // Staffelmenge 3
                .";"                           // Lieferantennummer 1
                .";"                           // Lieferantennummer 2
                .";"                           // Bestellmenge Lf.1
                .";"                           // Bestellmenge Lf.2
                .";"                           // Bestellnr. Lf.1
                .";"                           // Bestellnr. Lf.2
                .";"                           // Lieferzeit Lf.1
                .";"                           // Lieferzeit Lf.2
                .";".$oArticle->oxarticles__oxstock->value           // Lagerbestand
                .";"                           // Mindestbestand
                .";"                           // Lagerort
                .";"                           // Bestellte Menge
                .";"                           // St�ckliste
                .";1"                              // Internet
                .";".$this->interForm( $oArticle->oxarticles__oxshortdesc->value.$oArticle->oxarticles__oxlongdesc->value)// Text
                .";";
                $sToFile .= "\r\n";

                fwrite( $fp, $sToFile);
                $rs->moveNext();
            }

            fclose( $fp );
            return true;
        }

        return false;

    }

    /**
     * Ensures, that the given data can be put in the csv
     *
     * @param string $nValue given string
     *
     * @return string
     */
    function interFormSimple( $nValue )
    {
        $nValue = str_replace( "\r", "", $nValue );
        $nValue = str_replace( "\n", " ", $nValue );
        $nValue = str_replace( '"', '""', $nValue );
        return $nValue;
    }

    /**
     * Replaces some special chars to HTML compatible codes, returns string
     * with replaced chars.
     *
     * @param string $nValue string to replace special chars
     * @param object $oObj   object
     *
     * @return string
     */
    function interForm( $nValue, $oObj = null)
    {   // thnx to Volker D�rk for this function and his help here

        // #387A skipping conversion for fields where info must be passed in original format
        $aFieldTypesToSkip = array("text", "oxshortdesc", "oxlongdesc");
        $blSkipStrpTags = false;
        if ( $oObj != null) {
            // using object field "fldtype", to skip processing because usually
            // this type of field is used for HTML text
            //
            // you may change field to "fldname" and add to $aFieldTypesToSkip
            // "oxlongdesc" value to skip only longdesc field
            //
            if ( in_array( $oObj->fldtype, $aFieldTypesToSkip ) || in_array( $oObj->fldname, $aFieldTypesToSkip ) ) {
                $blSkipStripTags = true;
            }
        }

        //removing simple & (and not  &uuml; chars)
        //(not full just a simple check for existing customers for cases like Johnson&Johnson)

        $oStr = getStr();
        if ( $oStr->strpos( $nValue, "&" ) !== false && $oStr->strpos($nValue, ";" ) == false ) {
            $nValue = str_replace("&", "&amp;", $nValue);
        }

        $nValue = str_replace( "&nbsp;", " ", $nValue);
        $nValue = str_replace( "&auml;", "�", $nValue);
        $nValue = str_replace( "&ouml;", "�", $nValue);
        $nValue = str_replace( "&uuml;", "�", $nValue);
        $nValue = str_replace( "&Auml;", "�", $nValue);
        $nValue = str_replace( "&Ouml;", "�", $nValue);
        $nValue = str_replace( "&Uuml;", "�", $nValue);
        $nValue = str_replace( "&szlig;", "�", $nValue);

        // usually & symbol goes (or should go) like that:
        // "& text...", so we predict that this is a rule
        // and replace it with special HTML code
        $nValue = str_replace( "& ", "&amp; ", $nValue);

        $nValue = str_replace( "\"", "'", $nValue);
        $nValue = str_replace( "(", "'", $nValue);
        $nValue = str_replace( ")", "'", $nValue);
        $nValue = str_replace( "\r\n", "", $nValue);
        $nValue = str_replace( "\n", "", $nValue);

        if ( !$blSkipStripTags) {
            $nValue = strip_tags( $nValue );
        }

        return $nValue;
    }

    /**
     * Returns formatted price (grouped thousands, etc.).
     *
     * @param float $nPrice Price to format
     *
     * @return string
     */
    function internPrice( $nPrice)
    {  // thnx to Volker D�rk for this function and his help here
        $nPrice = $this->interForm($nPrice);
        $nPrice = number_format( (double)$nPrice, 2, '.', '');
        return $nPrice;
    }

    /**
     * Returns XML compatible text for LexwareOrders export.
     *
     * @param integer $iFromOrderNr Order from (default null)
     * @param integer $iToOrderNr   Order number
     *
     * @return string
     */
    function exportLexwareOrders( $iFromOrderNr = "", $iToOrderNr = "")
    {
        // thnx to Volker D�rk for this function and his help here
        $myConfig = $this->getConfig();

        $sNewLine = "\r\n";

        $sSelect = "select * from oxorder where 1 ";

        if ( $iFromOrderNr !== "" ) {
            $iFromOrderNr = (int)$iFromOrderNr;
            $sSelect .= "and oxordernr >= $iFromOrderNr ";
        }

        if ( $iToOrderNr !== "" ) {
            $iToOrderNr = (int)$iToOrderNr;
            $sSelect .= "and oxordernr <= $iToOrderNr ";
        }

        $oOrderlist = oxNew( "oxlist" );
        $oOrderlist->init( "oxorder" );
        $oOrderlist->selectString( $sSelect );

        if ( !$oOrderlist->count() ) {
            return null;
        }

        $sCharset = $this->_getCharset();

        $sExport  = "<?xml version=\"1.0\" encoding=\"{$sCharset}\"?>$sNewLine";
        $sExport .= "<Bestellliste>$sNewLine";
        $sRet     = $sExport;

        foreach ( $oOrderlist->arrayKeys() as $key ) {
            $oOrder = $oOrderlist[$key];
            // Convert each amount of money with currency rate of the order
            $dOrderCurRate = $oOrder->oxorder__oxcurrate->value;

            $oUser = oxNew( "oxuser" );
            $oUser->load( $oOrder->oxorder__oxuserid->value );

            $sExport  = "<Bestellung " . $this->_convertStr( "zur�ckgestellt" ) . "=\"Nein\" bearbeitet=\"Nein\" " . $this->_convertStr( "�bertragen" ) . "=\"Nein\">$sNewLine";
            $sExport .= "<Bestellnummer>".$oOrder->oxorder__oxordernr->value."</Bestellnummer>$sNewLine";
            $sExport .= "<Rechnungsnummer>".$oOrder->oxorder__oxbillnr->value."</Rechnungsnummer>$sNewLine";
            $sExport .= "<Standardwaehrung>978</Standardwaehrung>$sNewLine";
            $sExport .= "<Bestelldatum>$sNewLine";
            $sDBDate = oxUtilsDate::getInstance()->formatDBDate($oOrder->oxorder__oxorderdate->value);
            $sExport .= "<Datum>".substr($sDBDate, 0, 10)."</Datum>$sNewLine";
            $sExport .= "<Zeit>".substr($sDBDate, 11, 8)."</Zeit>$sNewLine";
            $sExport .= "</Bestelldatum>$sNewLine";
            $sExport .= "<Kunde>$sNewLine";

            $sExport .= "<Kundennummer>"./*$this->interForm($oUser->oxuser__oxcustnr->value).*/"</Kundennummer>$sNewLine";
            $sExport .= "<Firmenname>".$this->interForm($oOrder->oxorder__oxbillcompany->value)."</Firmenname>$sNewLine";
            $sExport .= "<Anrede>".$this->interForm(oxLang::getInstance()->translateString($oOrder->oxorder__oxbillsal->value))."</Anrede>$sNewLine";
            $sExport .= "<Vorname>".$this->interForm($oOrder->oxorder__oxbillfname->value)."</Vorname>$sNewLine";
            $sExport .= "<Name>".$this->interForm($oOrder->oxorder__oxbilllname->value)."</Name>$sNewLine";
            $sExport .= "<Strasse>".$this->interForm($oOrder->oxorder__oxbillstreet->value)." ".$this->interForm($oOrder->oxorder__oxbillstreetnr->value)."</Strasse>$sNewLine";
            $sExport .= "<PLZ>".$this->interForm($oOrder->oxorder__oxbillzip->value)."</PLZ>$sNewLine";
            $sExport .= "<Ort>".$this->interForm($oOrder->oxorder__oxbillcity->value)."</Ort>$sNewLine";
            $sExport .= "<Bundesland>".""."</Bundesland>$sNewLine";
            $sExport .= "<Land>".$this->interForm($oOrder->oxorder__oxbillcountry->value)."</Land>$sNewLine";
            $sExport .= "<Email>".$this->interForm($oOrder->oxorder__oxbillemail->value)."</Email>$sNewLine";
            $sExport .= "<Telefon>".$this->interForm($oOrder->oxorder__oxbillfon->value)."</Telefon>$sNewLine";
            $sExport .= "<Telefon2>".$this->interForm($oUser->oxuser__oxprivfon->value)."</Telefon2>$sNewLine";
            $sExport .= "<Fax>".$this->interForm($oOrder->oxorder__oxbillfax->value)."</Fax>$sNewLine";

            $sDelComp    = "";
            $sDelfName   = "";
            $sDellName   = "";
            $sDelStreet  = "";
            $sDelZip     = "";
            $sDelCity    = "";
            $sDelCountry = "";

            // lieferadresse
            if ( $oOrder->oxorder__oxdellname->value) {
                $sDelComp   = $oOrder->oxorder__oxdelcompany->value;
                $sDelfName  = $oOrder->oxorder__oxdelfname->value;
                $sDellName  = $oOrder->oxorder__oxdellname->value;
                $sDelStreet = $oOrder->oxorder__oxdelstreet->value." ".$oOrder->oxorder__oxdelstreetnr->value;
                $sDelZip    = $oOrder->oxorder__oxdelzip->value;
                $sDelCity   = $oOrder->oxorder__oxdelcity->value;
                $sDelCountry= $oOrder->oxorder__oxdelcountry->value;
            }

            $sExport .= "<Lieferadresse>$sNewLine";
            $sExport .= "<Firmenname>".$this->interForm($sDelComp)."</Firmenname>$sNewLine";
            $sExport .= "<Vorname>".$this->interForm($sDelfName)."</Vorname>$sNewLine";
            $sExport .= "<Name>".$this->interForm($sDellName)."</Name>$sNewLine";
            $sExport .= "<Strasse>".$this->interForm($sDelStreet)."</Strasse>$sNewLine";
            $sExport .= "<PLZ>".$this->interForm($sDelZip)."</PLZ>$sNewLine";
            $sExport .= "<Ort>".$this->interForm($sDelCity)."</Ort>$sNewLine";
            $sExport .= "<Bundesland>".""."</Bundesland>$sNewLine";
            $sExport .= "<Land>".$this->interForm($sDelCountry)."</Land>$sNewLine";
            $sExport .= "</Lieferadresse>$sNewLine";
            $sExport .= "<Matchcode>".$this->interForm($oOrder->oxorder__oxbilllname->value).", ".$this->interForm($oOrder->oxorder__oxbillfname->value)."</Matchcode>$sNewLine";

            // ermitteln ob steuerbar oder nicht
            $sCountry = strtolower( $oUser->oxuser__oxcountryid->value );
            $aHomeCountry = $myConfig->getConfigParam( 'aHomeCountry' );
            $sSteuerbar = ( is_array( $aHomeCountry ) && in_array( $sCountry, $aHomeCountry ) ) ? "ja" : "nein";

            $sExport .= "<fSteuerbar>".$this->interForm( $sSteuerbar )."</fSteuerbar>$sNewLine";
            $sExport .= "</Kunde>$sNewLine";
            $sExport .= "<Artikelliste>$sNewLine";
            $sRet .= $sExport;

            $dSumNetPrice = 0;
            $dSumBrutPrice = 0;

            $oOrderArticles = $oOrder->getOrderArticles();
            foreach ($oOrderArticles->arrayKeys() as $key) {
                $oOrderArt = $oOrderArticles->offsetGet($key);

                $dVATSet = array_search( $oOrderArt->oxorderarticles__oxvat->value, $myConfig->getConfigParam( 'aLexwareVAT' ) );
                $sExport  = "   <Artikel>$sNewLine";
                //$sExport .= "   <Artikelzusatzinfo><Nettostaffelpreis>".$this->InternPrice( $oOrderArt->oxorderarticles__oxnetprice->value)."</Nettostaffelpreis></Artikelzusatzinfo>$sNewLine";
                $sExport .= "   <Artikelzusatzinfo><Nettostaffelpreis></Nettostaffelpreis></Artikelzusatzinfo>$sNewLine";
                $sExport .= "   <SteuersatzID>".$dVATSet."</SteuersatzID>$sNewLine";
                $sExport .= "   <Steuersatz>".$this->internPrice($oOrderArt->oxorderarticles__oxvat->value/100)."</Steuersatz>$sNewLine";
                $sExport .= "   <Artikelnummer>".$oOrderArt->oxorderarticles__oxartnum->value."</Artikelnummer>$sNewLine";
                $sExport .= "   <Anzahl>".$oOrderArt->oxorderarticles__oxamount->value."</Anzahl>$sNewLine";
                $sExport .= "   <Produktname>".$this->interForm( $oOrderArt->oxorderarticles__oxtitle->value);
                if ( $oOrderArt->oxorderarticles__oxselvariant->value) {
                    $sExport .= "/".$oOrderArt->oxorderarticles__oxselvariant->value;
                }
                $sExport .= "   </Produktname>$sNewLine";
                $sExport .= "   <Rabatt>0.00</Rabatt>$sNewLine";
                $sExport .= "   <Preis>".$this->internPrice($oOrderArt->oxorderarticles__oxbrutprice->value/$oOrderArt->oxorderarticles__oxamount->value/$dOrderCurRate)."</Preis>$sNewLine";
                $sExport .= "   </Artikel>$sNewLine";
                $sRet .= $sExport;

                $dSumNetPrice   += $oOrderArt->oxorderarticles__oxnetprice->value;
                $dSumBrutPrice  += $oOrderArt->oxorderarticles__oxbrutprice->value;
            }

            $dDiscount = $oOrder->oxorder__oxvoucherdiscount->value + $oOrder->oxorder__oxdiscount->value;
            $sExport  = "<GesamtRabatt>".$this->internPrice($dDiscount/$dOrderCurRate)."</GesamtRabatt>$sNewLine";
            $sExport .= "<GesamtNetto>".$this->internPrice($dSumNetPrice/$dOrderCurRate)."</GesamtNetto>$sNewLine";
            $sExport .= "<Lieferkosten>".$this->internPrice($oOrder->oxorder__oxdelcost->value/$dOrderCurRate)."</Lieferkosten>$sNewLine";
            $sExport .= "<Zahlungsartkosten>0.00</Zahlungsartkosten>$sNewLine";
            $sExport .= "<GesamtBrutto>".$this->internPrice($dSumBrutPrice/$dOrderCurRate)."</GesamtBrutto>$sNewLine";

            $oUserpayment = oxNew( "oxuserpayment" );
            $oUserpayment->load( $oOrder->oxorder__oxpaymentid->value);
            $sPayment = $oUserpayment->oxuserpayments__oxvalue->value;
            $sPayment = str_replace( "__", "", $sPayment);
            $sPayment = str_replace( "@@", ",", $sPayment);

            $oPayment = oxNew( "oxpayment" );
            $oPayment->load( $oOrder->oxorder__oxpaymenttype->value);


            $sExport .= "<Bemerkung>".strip_tags( $oOrder->oxorder__oxremark->value)."</Bemerkung>$sNewLine";
            $sRet .= $sExport;

            $sExport  = "</Artikelliste>$sNewLine";

            $sExport .= "<Zahlung>$sNewLine";
            $oPayment = oxNew( "oxpayment" );
            $oPayment->load( $oOrder->oxorder__oxpaymenttype->value);

            $sExport .= "<Art>".$oPayment->oxpayments__oxdesc->value."</Art>$sNewLine";
            $sExport .= "</Zahlung>$sNewLine";

            $sExport .= "</Bestellung>$sNewLine";
            $sRet .= $sExport;

            $oOrder->oxorder__oxexport->setValue(1);
            $oOrder->save();

        }
        $sExport = "</Bestellliste>$sNewLine";
        $sRet .= $sExport;

        return $sRet;
    }

    /**
     * Get current charset
     *
     * @return string
     */
    protected function _getCharset()
    {
        return oxLang::getInstance()->translateString( 'charset' );
    }

    /**
     * Converts string from 'ISO-8859-15' to defined charset
     *
     * @param string $sStr string to convert
     *
     * @return string
     */
    protected function _convertStr( $sStr )
    {
        $sCharset = $this->_getCharset();

        if ( $sCharset == 'ISO-8859-15' ) {
            return $sStr;
        }

        return $sStr = iconv( 'ISO-8859-15', $sCharset, $sStr );
    }
}
oximex.php (21,792 bytes)   
Theme
BrowserAll
PHP Versionany
Database Versionany

Activities

umaun

2010-05-08 19:01

reporter   ~0002709

this fixes the bug for me, I convert each amount with $dOrderCurRate before exporting:
// Convert each amount of money with currency rate of the order
$dOrderCurRate = $oOrder->oxorder__oxcurrate->value;
see attached file

sarunas_valaskevicius

2010-05-11 12:31

reporter   ~0002732

fixed in oximex.php similarly as proposed