diff --git a/ajax/create.php b/ajax/create.php
new file mode 100644
index 0000000000000000000000000000000000000000..821d80f0b8cc64f302d4d4dc47c81e2257a21048
--- /dev/null
+++ b/ajax/create.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * This file contains package_quiqqer_discount_ajax_create
+ */
+
+/**
+ * Create a discount
+ *
+ * @return array
+ */
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_discount_ajax_create',
+    function ($params) {
+        $params    = json_decode($params, true);
+        $Discounts = new QUI\ERP\Discount\Handler();
+        $Discount  = $Discounts->createChild($params);
+
+        return $Discount->getId();
+    },
+    array('params'),
+    'Permission::checkAdminUser'
+);
diff --git a/ajax/deleteChild.php b/ajax/deleteChild.php
new file mode 100644
index 0000000000000000000000000000000000000000..24157332404fc25e6649dfcefa8a179cdd63f98b
--- /dev/null
+++ b/ajax/deleteChild.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * This file contains package_quiqqer_discount_ajax_deleteChild
+ */
+
+/**
+ * Delete a discount
+ *
+ * @param string|int $discountId - Discount-ID
+ *
+ * @return array
+ */
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_discount_ajax_deleteChild',
+    function ($discountId) {
+        $Discounts = new QUI\ERP\Discount\Handler();
+        $Discount  = $Discounts->getChild($discountId);
+        $Discount->delete();
+    },
+    array('discountId'),
+    'Permission::checkAdminUser'
+);
diff --git a/ajax/deleteChildren.php b/ajax/deleteChildren.php
new file mode 100644
index 0000000000000000000000000000000000000000..28a15d55ac7f042ce532dcb32f072a585a08ee47
--- /dev/null
+++ b/ajax/deleteChildren.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * This file contains package_quiqqer_discount_ajax_deleteChildren
+ */
+
+/**
+ * Delete multible discounts
+ *
+ * @param string $discountIds - JSON array of Discount-IDs
+ *
+ * @return array
+ */
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_discount_ajax_deleteChildren',
+    function ($discountIds) {
+        $discountIds    = json_decode($discountIds, true);
+        $Discounts      = new QUI\ERP\Discount\Handler();
+        $ExceptionStack = new QUI\ExceptionStack();
+
+        foreach ($discountIds as $discountId) {
+            try {
+                $Discount = $Discounts->getChild($discountId);
+                $Discount->delete();
+            } catch (QUI\Exception $Exception) {
+                $ExceptionStack->addException($Exception);
+            }
+        }
+
+        if (!$ExceptionStack->isEmpty()) {
+            throw new $ExceptionStack();
+        }
+    },
+    array('discountIds'),
+    'Permission::checkAdminUser'
+);
diff --git a/ajax/get.php b/ajax/get.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a337549f2a09d24ef9ccaa9f4c40c566964703c
--- /dev/null
+++ b/ajax/get.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * This file contains package_quiqqer_discount_ajax_get
+ */
+
+/**
+ * Returns a discount
+ *
+ * @param string $id - Discount-ID
+ *
+ * @return array
+ */
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_discount_ajax_get',
+    function ($id) {
+        $Discounts = new QUI\ERP\Discount\Handler();
+        $Discount = $Discounts->getChild($id);
+        $attributes = $Discount->getAttributes();
+
+        $attributes['title'] = $Discount->getTitle();
+
+        return $attributes;
+    },
+    array('id'),
+    'Permission::checkAdminUser'
+);
diff --git a/ajax/search.php b/ajax/search.php
new file mode 100644
index 0000000000000000000000000000000000000000..22b3e97b2c77779152b51000add26e620392b2bd
--- /dev/null
+++ b/ajax/search.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * This file contains package_quiqqer_discount_ajax_search
+ */
+
+/**
+ * Returns discount list
+ *
+ * @param string $params - JSON query params
+ *
+ * @return array
+ */
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_discount_ajax_search',
+    function ($params) {
+        $Discounts = new QUI\ERP\Discount\Handler();
+        $result    = array();
+        $Locale    = QUI::getLocale();
+
+        $data = $Discounts->getChildrenData(
+            json_decode($params, true)
+        );
+
+        foreach ($data as $entry) {
+            $result[] = array(
+                'id' => $entry['id'],
+                'title' => $Locale->getPartsOfLocaleString($entry['title']),
+                'text' => $Locale->parseLocaleString($entry['title'])
+            );
+        }
+
+        usort($result, function ($a, $b) {
+            return $a['text'] > $b['text'];
+        });
+
+        return $result;
+    },
+    array('params'),
+    'Permission::checkAdminUser'
+);
diff --git a/ajax/update.php b/ajax/update.php
new file mode 100644
index 0000000000000000000000000000000000000000..a4fae401f56b736b3e623c04265241db962a1391
--- /dev/null
+++ b/ajax/update.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * This file contains package_quiqqer_discount_ajax_update
+ */
+
+/**
+ * Returns discount list
+ *
+ * @param string|int $discountId - Discount-ID
+ * @param string $params - JSON Discount attributes
+ *
+ * @return array
+ */
+QUI::$Ajax->registerFunction(
+    'package_quiqqer_discount_ajax_update',
+    function ($discountId, $params) {
+        $Discounts = new QUI\ERP\Discount\Handler();
+        $Discount  = $Discounts->getChild($discountId);
+        $params    = json_decode($params, true);
+
+        $Discount->setAttributes($params);
+        $Discount->update();
+    },
+    array('discountId', 'params'),
+    'Permission::checkAdminUser'
+);
diff --git a/bin/classes/Handler.js b/bin/classes/Handler.js
new file mode 100644
index 0000000000000000000000000000000000000000..eb54fa4f59ae27afba4c680d58b64452ff8b0648
--- /dev/null
+++ b/bin/classes/Handler.js
@@ -0,0 +1,154 @@
+/**
+ * Discount handler
+ * Create and edit discounts
+ *
+ * @author www.pcsg.de (Henning Leutz)
+ *
+ * @require qui/QUI
+ * @require qui/classes/DOM
+ * @require Ajax
+ */
+define('package/quiqqer/discount/bin/classes/Handler', [
+
+    'qui/QUI',
+    'qui/classes/DOM',
+    'Ajax'
+
+], function (QUI, QUIDOM, Ajax) {
+    "use strict";
+
+    return new Class({
+
+        Extends: QUIDOM,
+        Type   : 'package/quiqqer/discount/bin/classes/Handler',
+
+        /**
+         * Search discounts
+         *
+         * @param {Object} [params] - query params
+         * @returns {Promise}
+         */
+        search: function (params) {
+            params = params || {};
+
+            return new Promise(function (resolve, reject) {
+                Ajax.get('package_quiqqer_discount_ajax_search', resolve, {
+                    'package': 'quiqqer/discount',
+                    onError  : reject,
+                    params   : JSON.encode(params)
+                });
+            });
+        },
+
+        /**
+         *
+         * @param {number} discountId
+         * @returns {Promise}
+         */
+        getChild: function (discountId) {
+            return new Promise(function (resolve, reject) {
+                Ajax.get('package_quiqqer_discount_ajax_get', resolve, {
+                    'package': 'quiqqer/discount',
+                    onError  : reject,
+                    id       : parseInt(discountId)
+                });
+            });
+        },
+
+        /**
+         *
+         * @returns {Promise}
+         */
+        getList: function () {
+            return this.search();
+        },
+
+        /**
+         * Return all unassigned countries
+         *
+         * @returns {Promise}
+         */
+        getUnAssignedCountries: function () {
+            return new Promise(function (resolve, reject) {
+                Ajax.get('package_quiqqer_discount_ajax_getUnAssignedCountries', resolve, {
+                    'package': 'quiqqer/discount',
+                    onError  : reject
+                });
+            });
+        },
+
+        /**
+         * Create a new Discount
+         *
+         * @params {Array} [params] - Discount attributes
+         * @returns {Promise}
+         */
+        createChild: function (params) {
+            return new Promise(function (resolve, reject) {
+                Ajax.post('package_quiqqer_discount_ajax_create', function (result) {
+
+                    require([
+                        'package/quiqqer/translator/bin/classes/Translator'
+                    ], function (Translator) {
+                        new Translator().refreshLocale().then(function () {
+                            resolve(result);
+                        });
+                    });
+                }, {
+                    'package': 'quiqqer/discount',
+                    onError  : reject,
+                    params   : JSON.encode(params)
+                });
+            });
+        },
+
+        /**
+         * Delete an discount
+         *
+         * @param {Number} discountId - Discount-ID
+         * @returns {Promise}
+         */
+        deleteChild: function (discountId) {
+            return new Promise(function (resolve, reject) {
+                Ajax.post('package_quiqqer_discount_ajax_deleteChild', resolve, {
+                    'package' : 'quiqqer/discount',
+                    onError   : reject,
+                    discountId: discountId
+                });
+            });
+        },
+
+        /**
+         * Delete multible discounts
+         *
+         * @param {Array} discountIds - array of Discount-IDs
+         * @returns {Promise}
+         */
+        deleteChildren: function (discountIds) {
+            return new Promise(function (resolve, reject) {
+                Ajax.post('package_quiqqer_discount_ajax_deleteChildren', resolve, {
+                    'package'  : 'quiqqer/discount',
+                    onError    : reject,
+                    discountIds: JSON.encode(discountIds)
+                });
+            });
+        },
+
+        /**
+         * Save an discount
+         *
+         * @param {Number} discountId
+         * @param {Object} data - Discount attributes
+         */
+        save: function (discountId, data) {
+            return new Promise(function (resolve, reject) {
+                Ajax.post('package_quiqqer_discount_ajax_update', resolve, {
+                    'package' : 'quiqqer/discount',
+                    onError   : reject,
+                    discountId: discountId,
+                    params    : JSON.encode(data)
+                });
+            });
+        }
+    });
+});
diff --git a/bin/controls/Discounts.js b/bin/controls/Discounts.js
new file mode 100644
index 0000000000000000000000000000000000000000..d1d58f464849cea40c8c62934f71beedb15eca9c
--- /dev/null
+++ b/bin/controls/Discounts.js
@@ -0,0 +1,210 @@
+/**
+ * Discount handler
+ * Create and edit discounts
+ *
+ * @author www.pcsg.de (Henning Leutz)
+ *
+ * @require qui/QUI
+ * @require qui/controls/desktop/Panel
+ * @require qui/controls/buttons/Button
+ * @require qui/controls/windows/Confirm
+ * @require controls/grid/Grid
+ * @require Locale
+ * @require package/quiqqer/discount/bin/classes/Handler
+ */
+define('package/quiqqer/discount/bin/controls/Discounts', [
+
+    'qui/QUI',
+    'qui/controls/desktop/Panel',
+    'qui/controls/buttons/Button',
+    'qui/controls/windows/Confirm',
+    'controls/grid/Grid',
+    'Locale',
+    'package/quiqqer/discount/bin/classes/Handler'
+
+], function (QUI, QUIPanel, QUIButton, QUIConfirm, Grid, QUILocale, Handler) {
+    "use strict";
+
+    var lg = 'quiqqer/discount';
+
+    var Discounts = new Handler();
+
+    return new Class({
+
+        Extends: QUIPanel,
+        Type   : 'package/quiqqer/discount/bin/controls/Discounts',
+
+        Binds: [
+            'createChild',
+            'editChild',
+            'deleteChild',
+            'deleteChildren',
+            'refresh',
+            '$onCreate',
+            '$onResize'
+        ],
+
+        initialize: function (options) {
+            this.parent(options);
+
+            this.$Grid = null;
+
+            this.setAttributes({
+                'title': QUILocale.get(lg, 'menu.erp.discount.panel.title')
+            });
+
+            this.addEvents({
+                onCreate: this.$onCreate,
+                onResize: this.$onResize
+            });
+        },
+
+        /**
+         * event : on create
+         */
+        $onCreate: function () {
+
+            // buttons
+            this.addButton({
+                name     : 'add',
+                text     : QUILocale.get('quiqqer/system', 'add'),
+                textimage: 'icon-plus fa fa-plus',
+                events   : {
+                    onClick: this.createChild
+                }
+            });
+
+            this.addButton({
+                name     : 'edit',
+                text     : QUILocale.get('quiqqer/system', 'edit'),
+                textimage: 'icon-edit fa fa-edit',
+                disabled : true,
+                events   : {
+                    onClick: this.createChild
+                }
+            });
+
+            this.addButton({
+                type: 'seperator'
+            });
+
+            this.addButton({
+                name     : 'delete',
+                text     : QUILocale.get('quiqqer/system', 'delete'),
+                textimage: 'icon-trash fa fa-trash',
+                disabled : true,
+                events   : {
+                    onClick: function () {
+
+                        var selected = this.$Grid.getSelectedData();
+
+                        var ids = selected.map(function (data) {
+                            return data.id;
+                        });
+
+                        this.deleteChildren(ids);
+                    }.bind(this)
+                }
+            });
+
+            // Grid
+            var self = this;
+
+            var Container = new Element('div').inject(
+                this.getContent()
+            );
+
+            this.$Grid = new Grid(Container, {
+                multipleSelection: true,
+                columnModel      : [{
+                    header   : QUILocale.get('quiqqer/system', 'id'),
+                    dataIndex: 'id',
+                    dataType : 'number',
+                    width    : 60
+                }, {
+                    header   : QUILocale.get(lg, 'discount.grid.discount.title'),
+                    dataIndex: 'title',
+                    dataType : 'string',
+                    width    : 200
+                }, {
+                    header   : QUILocale.get(lg, 'discount.grid.discount.areas'),
+                    dataIndex: 'areas',
+                    dataType : 'string',
+                    width    : 300
+                }]
+            });
+
+            this.$Grid.addEvents({
+                onRefresh : this.refresh,
+                onDblClick: function (event) {
+                    self.editChild(
+                        self.$Grid.getDataByRow(event.row).id
+                    );
+                },
+                onClick   : function () {
+                    var selected = self.$Grid.getSelectedData();
+
+                    if (selected.length) {
+                        self.getButtons('delete').enable();
+                        self.getButtons('edit').enable();
+                    } else {
+                        self.getButtons('delete').disable();
+                        self.getButtons('edit').disable();
+                    }
+                }
+            });
+
+            this.$Grid.refresh();
+        },
+
+        /**
+         * event : on resize
+         */
+        $onResize: function () {
+            if (!this.$Grid) {
+                return;
+            }
+
+            var Body = this.getContent();
+
+            if (!Body) {
+                return;
+            }
+
+
+            var size = Body.getSize();
+
+            this.$Grid.setHeight(size.y - 40);
+            this.$Grid.setWidth(size.x - 40);
+        },
+
+        /**
+         * refresh the display
+         */
+        refresh: function () {
+
+            var self = this;
+
+            this.Loader.show();
+            this.getButtons('delete').disable();
+            this.getButtons('edit').disable();
+
+            Discounts.getList().then(function (data) {
+                var dataEntry,
+                    gridData = [];
+
+                for (var i = 0, len = data.length; i < len; i++) {
+                    dataEntry = data[i];
+
+                }
+
+                self.$Grid.setData({
+                    data: gridData
+                });
+
+                self.Loader.hide();
+            });
+        }
+    });
+});
+
diff --git a/composer.json b/composer.json
index 5832f08252127e334e68434b29c4745f61feaed2..3f36576d2f7a4ffbc77ed2e4ff6de170dadb91dc 100644
--- a/composer.json
+++ b/composer.json
@@ -18,7 +18,9 @@
   },
   "require": {
     "php": ">=5.3",
-    "quiqqer/quiqqer": "*@dev"
+    "quiqqer/quiqqer": "*@dev",
+    "quiqqer/areas": "*",
+    "quiqqer/products": "*"
   },
   "autoload": {
     "psr-0": {
diff --git a/database.xml b/database.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d6389e5687e5487aca258c96ffad014d04a9453f
--- /dev/null
+++ b/database.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database>
+    <global>
+        <table name="discounts">
+            <field type="INT( 10 ) NOT NULL PRIMARY KEY">id</field>
+            <field type="INT( 1 )">active</field>
+            <field type="text">discount</field>
+            <field type="text">date_from</field>
+            <field type="text">data_to</field>
+            <field type="INT( 10 )">purchase_quantity</field>
+            <field type="text">purchase_value</field>
+
+            <field type="text">areas</field>
+            <field type="text">articles</field>
+            <field type="text">categories</field>
+            <field type="text">user_groups</field>
+            <field type="text">combined</field>
+
+            <auto_increment>id</auto_increment>
+        </table>
+    </global>
+</database>
diff --git a/locale.xml b/locale.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2a61c54a205d57b6a2679770ea9ba714d8bae05
--- /dev/null
+++ b/locale.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<locales>
+    <groups name="quiqqer/discount" datatype="php,js">
+        <locale name="menu.erp.title">
+            <de><![CDATA[ERP]]></de>
+            <en><![CDATA[ERP]]></en>
+        </locale>
+        <locale name="menu.erp.discount.title">
+            <de><![CDATA[Rabatte]]></de>
+            <en><![CDATA[Discounts]]></en>
+        </locale>
+    </groups>
+
+    <groups name="quiqqer/discount" datatype="js">
+    </groups>
+
+</locales>
\ No newline at end of file
diff --git a/menu.xml b/menu.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bac375b1d34cc19cf7ea1c2ef0f908b245705c82
--- /dev/null
+++ b/menu.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<menu>
+    <item parent="/extras/"
+          name="erp"
+          icon="icon-sun"
+    >
+        <locale group="quiqqer/discount" var="menu.erp.title" />
+    </item>
+    <item parent="/extras/erp/"
+          name="discounts"
+          require="package/quiqqer/discount/bin/controls/Discounts"
+          icon="fa fa-cart-arrow-down"
+    >
+        <locale group="quiqqer/discount" var="menu.erp.discount.title" />
+    </item>
+
+</menu>
diff --git a/permissions.xml b/permissions.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bce34c109beac120e9b73a4de77ac5b1a1bfa3ec
--- /dev/null
+++ b/permissions.xml
@@ -0,0 +1,12 @@
+
+<permissions>
+    <permission name="quiqqer.discount.create" type="bool">
+        <defaultvalue>1</defaultvalue>
+    </permission>
+    <permission name="quiqqer.discount.edit" type="bool">
+        <defaultvalue>1</defaultvalue>
+    </permission>
+    <permission name="quiqqer.discount.delete" type="bool">
+        <defaultvalue>1</defaultvalue>
+    </permission>
+</permissions>
diff --git a/src/QUI/ERP/Discount/Discount.php b/src/QUI/ERP/Discount/Discount.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ad264cef5805678407456b8ef2d934812ed49c9
--- /dev/null
+++ b/src/QUI/ERP/Discount/Discount.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * This file contains QUI\ERP\Discount\Discount
+ */
+namespace QUI\ERP\Discount;
+
+use QUI;
+
+/**
+ * Class Discount
+ * @package QUI\ERP\Discount
+ */
+class Discount extends QUI\CRUD\Child
+{
+
+}
diff --git a/src/QUI/ERP/Discount/Handler.php b/src/QUI/ERP/Discount/Handler.php
new file mode 100644
index 0000000000000000000000000000000000000000..83ea0bea2281e10d2e5dd66c386fcdc4ed2f8bad
--- /dev/null
+++ b/src/QUI/ERP/Discount/Handler.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * This file contains QUI\ERP\Discount\Handler
+ */
+namespace QUI\ERP\Discount;
+
+use QUI;
+use QUI\Rights\Permission;
+
+/**
+ * Class Handler
+ *
+ * @package QUI\ERP\Discount
+ */
+class Handler extends QUI\CRUD\Factory
+{
+    /**
+     * Handler constructor.
+     */
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->Events->addEvent('onCreateBegin', function () {
+            Permission::checkPermission('quiqqer.discount.create');
+        });
+
+        // create new translation var for the discount
+        $this->Events->addEvent('onCreateEnd', function ($New) {
+            /* @var $New QUI\ERP\Discount\Discount */
+            $newVar  = 'discount.' . $New->getId() . '.title';
+            $current = QUI::getLocale()->getCurrent();
+
+            $title = $New->getAttribute('title');
+
+            if (QUI::getLocale()->isLocaleString($title)) {
+                $parts = QUI::getLocale()->getPartsOfLocaleString($title);
+                $title = QUI::getLocale()->get($parts[0], $parts[1]);
+            }
+
+            QUI\Translator::addUserVar('quiqqer/discount', $newVar, array(
+                $current => $title,
+                'datatype' => 'php,js'
+            ));
+        });
+    }
+
+    /**
+     * return the discount db table name
+     *
+     * @return string
+     */
+    public function getDataBaseTableName()
+    {
+        return QUI::getDBTableName('discounts');
+    }
+
+    /**
+     * Return the name of the child crud class
+     *
+     * @return string
+     */
+    public function getChildClass()
+    {
+        return 'QUI\ERP\Discount\Discount';
+    }
+
+    /**
+     * Return the crud attributes for the children class
+     *
+     * @return array
+     */
+    public function getChildAttributes()
+    {
+        return array(
+            'active',
+            'discount',
+            'date_from',
+            'data_to',
+            'purchase_quantity',
+            'purchase_value',
+            'area',
+            'article',
+            'category',
+            'user_groups',
+            'combined'
+        );
+    }
+
+    /**
+     * Return a Discount
+     *
+     * @param int $id - Discount-ID
+     * @return QUI\ERP\Discount\Discount
+     * @throws QUI\Exception
+     */
+    public function getChild($id)
+    {
+        return parent::getChild($id);
+    }
+}