Compare commits

...
This repository has been archived on 2021-01-04. You can view files and clone it, but cannot push or open issues or pull requests.

4 Commits

15 changed files with 451 additions and 67 deletions

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -21,13 +21,5 @@ use OxidEsales\Eshop\Core\Registry;
class raiseTaxRate extends taxRateAbstract
{
public $execPeriod = [
'2020-12-28',
'2021-01-03',
];
public function __construct()
{
$this->rateChanges = array_flip($this->rateChanges);
}
use raiseTrait;
}

29
Models/raiseTrait.php Normal file
View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -19,8 +19,5 @@ use OxidEsales\Eshop\Core\Registry;
class reduceTaxRate extends taxRateAbstract
{
public $execPeriod = [
'2020-06-27',
'2020-07-03',
];
use reduceTrait;
}

24
Models/reduceTrait.php Normal file
View File

@ -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',
];
}

View File

@ -22,34 +22,8 @@ use OxidEsales\Eshop\Core\DatabaseProvider;
use OxidEsales\Eshop\Core\Exception\StandardException;
use OxidEsales\Eshop\Core\Registry;
abstract class taxRateAbstract
abstract class taxRateAbstract extends genericAbstract
{
public $execPeriod = [
'2020-01-01',
'2019-12-31',
];
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));
}
/**
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseConnectionException
* @throws \OxidEsales\Eshop\Core\Exception\DatabaseErrorException
@ -92,28 +66,6 @@ abstract class taxRateAbstract
}
}
/**
* @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);
}
}
/**
* @param int $shopId
*/

View File

@ -9,10 +9,11 @@ Dieses Modul wurde für die Steueranpassung in Deutschland im Jahr 2020 erstellt
### 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
@ -20,6 +21,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.
@ -32,10 +46,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
@ -47,7 +65,7 @@ Gibt es in Ihrem Shop reguläre Steuersätze mit 16% oder 5%, werden diese beim
Während der Installation werden noch keine Shopeinstellungen geändert. Führen Sie diesen Befehl im Shophauptverzeichnis aus:
```
composer require d3/taxratesadjustment:"^2.0" --update-no-dev
composer require d3/taxratesadjustment:"dev-rel_2.x_articlePrices" --update-no-dev
```
## Ausführung
@ -67,6 +85,22 @@ Richten Sie einen zweiten Cronjob ein, der idealerweise am 01.01.2021 um 00:00 f
[ Shoppfad ]/vendor/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.
@ -96,6 +130,8 @@ composer remove d3/taxratesadjustment --update-no-dev
- Composer Command korrigiert
- 2.1.2
- PHP-Versionshinweis angepasst
- unreleased
- Preisanpassungsscripte eingefügt
## Support

15
bin/raiseArticlePrices Normal file
View File

@ -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();
}

32
bin/raiseArticleTaxMysql Normal file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# Mail-Versand erfolgt bei Profihost ueber den Cronjob selbst, andere Provider erfordern ggf. expliziten Versand
TODAY=$(date)
HOST=$(hostname)
DOMAIN='myhost.de'
DOMAIN='myhost.de'
MYSQLUSER='mysql_user'
MYSQLPASS='mysql_pass'
MYSQLDB='mysql_db'
MYSQLHOST='127.0.0.1'
MYSQLPORT='3306'
echo "------------------------------------------------------------------------------------------"
echo "USt.-Anpassung 01.01.2021"
echo "Date: $TODAY Host: $HOST ($DOMAIN)"
echo "------------------------------------------------------------------------------------------"
printf '\n 16%% -> 19%%\n\n'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Vor Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 16;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'UPDATE oxarticles SET oxvat = 19 WHERE oxvat = 16;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Nach Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 16;'
printf '\n'
echo "------------------------------------------------------------------------------------------"
printf '\n 5%% -> 7%%\n\n'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Vor Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 5;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'UPDATE oxarticles SET oxvat = 7 WHERE oxvat = 5;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Nach Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 5;'
printf '\n'

15
bin/reduceArticlePrices Normal file
View File

@ -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();
}

32
bin/reduceArticleTaxMysql Normal file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# Mail-Versand erfolgt bei Profihost ueber den Cronjob selbst, andere Provider erfordern ggf. expliziten Versand
TODAY=$(date)
HOST=$(hostname)
DOMAIN='myhost.de'
DOMAIN='myhost.de'
MYSQLUSER='mysql_user'
MYSQLPASS='mysql_pass'
MYSQLDB='mysql_db'
MYSQLHOST='127.0.0.1'
MYSQLPORT='3306'
echo "------------------------------------------------------------------------------------------"
echo "USt.-Anpassung 01.07.2020"
echo "Date: $TODAY Host: $HOST ($DOMAIN)"
echo "------------------------------------------------------------------------------------------"
printf '\n 19%% -> 16%%\n\n'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Vor Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 19;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'UPDATE oxarticles SET oxvat = 16 WHERE oxvat = 19;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Nach Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 19;'
printf '\n'
echo "------------------------------------------------------------------------------------------"
printf '\n 7%% -> 5%%\n\n'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Vor Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 7;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'UPDATE oxarticles SET oxvat = 5 WHERE oxvat = 7;'
mysql5 -u$MYSQLUSER -p$MYSQLPASS -D$MYSQLDB -h$MYSQLHOST -P$MYSQLPORT -e 'SELECT CONCAT("Nach Umstellung: ", COUNT(*), " Artikel gefunden") as result FROM oxarticles WHERE oxvat = 7;'
printf '\n'

View File

@ -1,6 +1,6 @@
{
"name": "d3/taxratesadjustment",
"description": "adjusts the tax rates for the German economic stimulus package 2020 / 2021",
"description": "adjusts the tax rates and article prices for the German economic stimulus package 2020 / 2021",
"type": "library",
"require": {
"oxid-esales/oxideshop-ce": "^6.0"
@ -20,6 +20,8 @@
},
"bin": [
"bin/reduceTaxRate",
"bin/raiseTaxRate"
"bin/raiseTaxRate",
"bin/reduceArticlePrices",
"bin/raiseArticlePrices"
]
}