add article price adjustment scripts

# Conflicts:
#	composer.json
#	copy_this/_taxRates/Models/articlePricesAbstract.php
#	copy_this/_taxRates/Models/genericAbstract.php
#	copy_this/_taxRates/Models/raiseArticlePrices.php
#	copy_this/_taxRates/Models/raiseTrait.php
#	copy_this/_taxRates/Models/reduceArticlePrices.php
#	copy_this/_taxRates/Models/reduceTrait.php
#	copy_this/_taxRates/Models/taxRateAbstract.php
#	copy_this/_taxRates/bin/raiseArticlePrices
#	copy_this/_taxRates/bin/reduceArticlePrices
This commit is contained in:
Daniel Seifert 2020-06-25 11:37:04 +02:00
bovenliggende e6a542c13e
commit f4d7c8ef5f
Getekend door: DanielS
GPG sleutel-ID: 8A7C4C6ED1915C6F
12 gewijzigde bestanden met toevoegingen van 384 en 62 verwijderingen

Bestand weergeven

@ -5,10 +5,11 @@
### Was kann das Modul?
Dieses Modul stellt 2 Aufrufe bereit, die in Standardkonstellationen die MwSt.-Sätze anpasst, die in Deutschland zum 01.07.20 und zum 01.01.2021 geändert werden (Bestandteil des beschlossenen Corona-Konjunkturpaketes).
Weiterhin können über 2 weitere Aufrufe die Artikelpreise passend reduziert bzw. erhöht werden.
Die Anpassung kann über entsprechende Cronjobs zeitgesteuert zum Stichtermin ausgeführt werden, ohne dass hierfür Ihre Anwesenheit erforderlich ist.
Die Scripte ändern:
Die Steuerscripte ändern:
- den im Shop eingestellten allgemeinen Steuersatz
- an den Artikeln hinterlegte spezielle Steuersätze
@ -16,6 +17,19 @@ Die Scripte ändern:
- von 7% zu 5%
- sowie später auch zurück
Die Steuerscripte ändern:
- den Standardpreis der Artikel
- den UVP-Preis der Artikel
- den Varminpreis an Elternartikeln (der Variantenpreis selbst wird schon mit dem Standardpreis geändert)
- den Varmaxpreis an Elternartikeln (der Variantenpreis selbst wird schon mit dem Standardpreis geändert)
- von 19% zu 16% und
- von 7% zu 5%
- sowie später auch zurück
Berücksichtigt werden artikelabhängige Steuersätze sowie auch der generelle Steuersatz des Shops. Bei den Varianten-MinPreisen und Max-Preisen wird der Steuersatz des Elternartikels zugrunde gelegt.
Weicht der Steuersatz der Varianten vom Elternartikel ab, muss dies manuell nachgearbeitet werden.
Bei Multishopinstallationen (Enterprise Edition) können die zu aktualisierenden Subshops definiert werden.
Die Scripte prüfen anhand der Systemzeit mit kleinen Toleranzen (+/-3 Tage um das jeweilige Umstellungsdatum), ob die Veränderung ausgeführt werden darf. Damit wird verhindert, dass ein versehentliches Auslösen zur falschen Shopkonfiguration führt.
@ -28,10 +42,14 @@ Weiterhin werden auch die absoluten Artikelpreise und Berechnungswege nicht ange
- Werden Artikelpreise brutto gepflegt und angezeigt, werden danach weiterhin die bisherigen Preise verwendet, jedoch mit geändertem Steuersatz.
- Werden Artikelpreise netto gepflegt und brutto angezeigt, ändern sich die daraus errechneten Bruttopreise.
Passen Sie die Artikelpreise danach ggf. an. Beachten Sie hierbei speziell die Artikel, die einer Preisbindung unterliegen.
Für die Preisanpassungen stehen Ihnen die entsprechenden Scripte im Modul zur Verfügung.
Beachten Sie bei der Preisanpassung speziell die Artikel, die einer Preisbindung unterliegen.
Artikel, die von der Steuersenkung ausgenommen sind (z.B. Tabakwaren) können hierbei nicht berücksichtigt werden und erfordern eine manuelle Nachbearbeitung.
Die Preise werden immer auf dem im Shop vorliegenden Preis angewandt. Hierbei kann es durchaus zu Rundungsungenauigkeiten kommen.
Gibt es in Ihrem Shop reguläre Steuersätze mit 16% oder 5%, werden diese beim Zurücksetzen ebenfalls auf 19% bzw. 7% angehoben. Eine Unterscheidung, welcher Steuersatz vorab reduziert wurde, gibt es nicht. Diese Anpassung muss dann manuell durchgeführt werden.
## Systemanforderung
@ -63,6 +81,22 @@ Richten Sie einen zweiten Cronjob ein, der idealerweise am 01.01.2021 um 00:00 f
[ Shoppfad ]/_taxRates/bin/raiseTaxRate
```
Nutzen Sie für die Preisanpassungen die folgenden Scripte als Cronjob zum passenden Moment:
um die Artikelpreise zu senken::
```
[ Shoppfad ]/vendor/bin/reduceArticlePrices
```
um die Artikelpreise zurückzusetzen:
```
[ Shoppfad ]/vendor/bin/raiseArtikelPrices
```
Führen Sie die Preisanpassungsscripte nur ein einziges Mal aus, da die Preise sonst mehrfach gesenkt / erhöht werden.
Bei Fragen zur Einrichtung der Cronjobs kontaktieren Sie bitte Ihren Hostingprovider.
Prüfen Sie nach Ausführung der Scripte Ihren Shop bitte zeitnah auf richtige Funktion.
@ -87,6 +121,8 @@ Nach heutigem Stand werden die Scripte nach dem Zurücksetzen der Steuersätze n
- falsche Konvertierung der ShopId entfernt
- 1.0.2
- PHP-Versionshinweis angepasst
- unreleased
- Preisanpassungsscripte eingefügt
## Support

Bestand weergeven

@ -0,0 +1,151 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\TaxRatesAdjustment\Models;
use D3\ModCfg\Application\Model\d3database;
use OxidEsales\Eshop\Application\Model\Shop;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\DatabaseProvider;
abstract class articlePricesAbstract extends genericAbstract
{
public $baseQueriesDefaultTax = [
//'UPDATE oxarticles SET oxprice = (oxprice / 1.19 * 1.16) WHERE oxshopid = 'oxbaseshop' AND (oxvat IS NULL);',
// default prices
'UPDATE oxarticles SET oxprice = (oxprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IS NULL)',
// recommended retail price
'UPDATE oxarticles SET oxtprice = (oxtprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IS NULL)',
// varminprices
'UPDATE oxarticles SET oxvarminprice = (oxvarminprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IS NULL)',
// varmaxprices
'UPDATE oxarticles SET oxvarmaxprice = (oxvarmaxprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IS NULL)'
];
public $baseQueriesCustomTax = [
//'UPDATE oxarticles SET oxprice = (oxprice / 1.19 * 1.16) WHERE oxshopid = 'oxbaseshop' AND (oxvat IN(16, 19));',
// default prices
'UPDATE oxarticles SET oxprice = (oxprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IN(:oldTaxRate, :newTaxRate))',
// recommended retail price
'UPDATE oxarticles SET oxtprice = (oxtprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IN(:oldTaxRate, :newTaxRate))',
// varminprices
'UPDATE oxarticles SET oxvarminprice = (oxvarminprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IN(:oldTaxRate, :newTaxRate))',
// varmaxprices
'UPDATE oxarticles SET oxvarmaxprice = (oxvarmaxprice / :oldTaxPercent * :newTaxPercent) WHERE oxshopid = :shopid AND (oxvat IN(:oldTaxRate, :newTaxRate))'
];
/**
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseConnectionException
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseErrorException
*/
public function run()
{
if (false === $this->isInExecutableTimeRange()) {
trigger_error("script shouldn't run outside the defined time range", E_USER_WARNING);
die();
};
$this->changeArticlePrices();
}
/**
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseConnectionException
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseErrorException
*/
public function changeArticlePrices()
{
$shop = new Shop();
// use shop list, when parameter -d is set
$opts = getopt("s:");
$where = isset($opts['s']) ?
"oxid IN (".implode(', ', array_map(
function ($a) {return DatabaseProvider::getDb()->quote(trim($a));},
explode(',', $opts['s']))
).")" :
"1";
$q = "SELECT oxid FROM " . $shop->getCoreTableName() . " WHERE ".$where ;
foreach ( DatabaseProvider::getDb( DatabaseProvider::FETCH_MODE_ASSOC )->getAll( $q ) as $record ) {
$shopId = (int) $record["oxid"];
$count = 0;
$count += $this->changeSubshopArticlePricesDefaultTax($shopId);
$count += $this->changeSubshopArticlePricesCustomTax($shopId);
echo "$count article prices in shop $shopId changed.".PHP_EOL;
}
}
public function changeSubshopArticlePricesDefaultTax($shopId)
{
$count = 0;
$oCurrConfig = new Config();
$oldTaxRate = (int) $oCurrConfig->getConfigParam('dDefaultVAT');
$newTaxRate = $this->rateChanges[$oldTaxRate];
if ($newTaxRate === null) {
$flipped = array_flip($this->rateChanges);
$oldTaxRate = $flipped[(int) $oCurrConfig->getConfigParam('dDefaultVAT')];
$newTaxRate = $this->rateChanges[$oldTaxRate];
}
foreach ($this->baseQueriesDefaultTax as $query) {
$db = DatabaseProvider::getDb(DatabaseProvider::FETCH_MODE_ASSOC);
$queryParameters = [
'shopid' => $shopId,
'oldTaxRate'=> $oldTaxRate,
'oldTaxPercent' => 1 + ($oldTaxRate / 100),
'newTaxRate'=> $newTaxRate,
'newTaxPercent' => 1 + ($newTaxRate / 100),
];
$count += $db->execute($query, $queryParameters);
}
return $count;
}
public function changeSubshopArticlePricesCustomTax($shopId)
{
$count = 0;
foreach ($this->baseQueriesCustomTax as $query) {
foreach ($this->rateChanges as $oldTaxRate => $newTaxRate) {
$db = DatabaseProvider::getDb(DatabaseProvider::FETCH_MODE_ASSOC);
$queryParameters = [
'shopid' => $shopId,
'oldTaxRate'=> $oldTaxRate,
'oldTaxPercent' => 1 + ($oldTaxRate / 100),
'newTaxRate'=> $newTaxRate,
'newTaxPercent' => 1 + ($newTaxRate / 100),
];
$count += $db->execute($query, $queryParameters);
}
}
return $count;
}
}

Bestand weergeven

@ -0,0 +1,65 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\TaxRatesAdjustment\Models;
use OxidEsales\Eshop\Core\Config;
use OxidEsales\Eshop\Core\Registry;
abstract class genericAbstract
{
public $rateChanges = [
19 => 16,
7 => 5
];
/**
* @return bool
*/
public function isInExecutableTimeRange()
{
// skip time check, when parameter -d is set
$opts = getopt("d");
if (is_array($opts) && isset($opts['d'])) {
return true;
}
list($from, $to) = $this->execPeriod;
return (time() > strtotime($from)) && (time() < strtotime($to));
}
/**
* @param int $id
*
* @throws \oxConnectionException
*/
public function switchToShop($id)
{
if (Registry::getConfig()->isMall()
&& $id != Registry::getConfig()->getActiveShop()->getId()
) {
/** @var Config $oNewConf */
$oNewConf = new Config();
$oNewConf->setShopId($id);
$oNewConf->init();
Registry::getConfig()->onShopChange();
Registry::getSession()->setVariable('actshop', $id);
Registry::getSession()->setVariable('currentadminshop', $id);
Registry::getConfig()->setShopId($id);
}
}
}

Bestand weergeven

@ -0,0 +1,21 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\TaxRatesAdjustment\Models;
class raiseArticlePrices extends articlePricesAbstract
{
use raiseTrait;
}

Bestand weergeven

@ -19,13 +19,5 @@ require 'taxRateAbstract.php';
class raiseTaxRate extends taxRateAbstract
{
public $execPeriod = [
'2020-12-28',
'2021-01-03',
];
public function __construct()
{
$this->rateChanges = array_flip($this->rateChanges);
}
use raiseTrait;
}

Bestand weergeven

@ -0,0 +1,29 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\TaxRatesAdjustment\Models;
trait raiseTrait
{
public $execPeriod = [
'2020-12-28',
'2021-01-03',
];
public function __construct()
{
$this->rateChanges = array_flip($this->rateChanges);
}
}

Bestand weergeven

@ -0,0 +1,21 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\TaxRatesAdjustment\Models;
class reduceArticlePrices extends articlePricesAbstract
{
use reduceTrait;
}

Bestand weergeven

@ -19,8 +19,5 @@ require 'taxRateAbstract.php';
class reduceTaxRate extends taxRateAbstract
{
public $execPeriod = [
'2020-06-27',
'2020-07-03',
];
use reduceTrait;
}

Bestand weergeven

@ -0,0 +1,24 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\TaxRatesAdjustment\Models;
trait reduceTrait
{
public $execPeriod = [
'2020-06-27',
'2020-07-03',
];
}

Bestand weergeven

@ -21,34 +21,12 @@ use oxDb;
use oxRegistry;
use oxShop;
abstract class taxRateAbstract
abstract class taxRateAbstract extends genericAbstract
{
public $execPeriod = [
'2020-01-01',
'2019-12-31',
];
public $rateChanges = [
19 => 16,
7 => 5
];
/**
* @return bool
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseConnectionException
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseErrorException
*/
public function isInExecutableTimeRange()
{
// skip time check, when parameter -d is set
$opts = getopt("d");
if (is_array($opts) && isset($opts['d'])) {
return true;
}
list($from, $to) = $this->execPeriod;
return (time() > strtotime($from)) && (time() < strtotime($to));
}
public function run()
{
if (false === $this->isInExecutableTimeRange()) {
@ -83,28 +61,6 @@ abstract class taxRateAbstract
}
}
/**
* @param int $id
*
* @throws \oxConnectionException
*/
public function switchToShop($id)
{
if (oxRegistry::getConfig()->isMall()
&& $id != oxRegistry::getConfig()->getActiveShop()->getId()
) {
/** @var oxConfig $oNewConf */
$oNewConf = new oxConfig();
$oNewConf->setShopId($id);
$oNewConf->init();
oxRegistry::getConfig()->onShopChange();
oxRegistry::getSession()->setVariable('actshop', $id);
oxRegistry::getSession()->setVariable('currentadminshop', $id);
oxRegistry::getConfig()->setShopId($id);
}
}
/**
* @param int $shopId
*/

Bestand weergeven

@ -0,0 +1,15 @@
#!/usr/bin/env php
<?php
$filePath = '../bootstrap.php';
$currentDirectory = __DIR__ . '/';
$filePath = $currentDirectory . $filePath;
require($filePath);
$change = new \D3\TaxRatesAdjustment\Models\raiseArticlePrices();
try {
$change->run();
} catch ( \Exception $e) {
echo $e->getMessage();
}

Bestand weergeven

@ -0,0 +1,15 @@
#!/usr/bin/env php
<?php
$filePath = '../bootstrap.php';
$currentDirectory = __DIR__ . '/';
$filePath = $currentDirectory . $filePath;
require($filePath);
$change = new \D3\TaxRatesAdjustment\Models\reduceArticlePrices();
try {
$change->run();
} catch ( \Exception $e) {
echo $e->getMessage();
}