From 6fa059ddfe62ec8996361c2201bbad3b797d26c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maximilian=20Schr=C3=B6ger?= <m.schroeger@adito.de>
Date: Mon, 22 Oct 2018 17:41:24 +0200
Subject: [PATCH] Angebot Field-Prozesse, diverse Bugfixes

---
 aliasDefinition/Data_alias/Data_alias.aod     | 214 ++++++++++++++++++
 .../_____SYSTEM_APPLICATION_NEON.aod          |   1 +
 entity/Contract_entity/Contract_entity.aod    |   1 +
 .../entityfields/contractend/onValidation.js  |   6 -
 .../entityfields/contractend/onValueChange.js |   7 +
 .../contractstart/onValidation.js             |   4 -
 .../contractstart/onValueChange.js            |   7 +
 entity/Offer_entity/Offer_entity.aod          | 133 +++++++++++
 .../currency/possibleItemsProcess.js          |   8 +
 .../entityfields/date_edit/valueProcess.js    |   6 +
 .../entityfields/date_new/valueProcess.js     |   6 +
 .../entityfields/image/valueProcess.js        |   7 +
 .../language/possibleItemsProcess.js          |   8 +
 .../entityfields/offercode/onValidation.js    |  11 +
 .../entityfields/offercode/valueProcess.js    |  11 +
 .../entityfields/offerdate/valueProcess.js    |  12 +
 .../entityfields/offerid/valueProcess.js      |   7 +
 .../probability/possibleItemsProcess.js       |   8 +
 .../status/possibleItemsProcess.js            |   8 +
 .../entityfields/user_edit/valueProcess.js    |   6 +
 .../entityfields/user_new/valueProcess.js     |   6 +
 .../entityfields/orgname/onValueChange.js     |   2 +-
 .../entityfields/projectcode/onValueChange.js |  16 +-
 .../_____LANGUAGE_EXTRA.aod                   |  45 ++++
 .../_____LANGUAGE_de/_____LANGUAGE_de.aod     |  54 +++++
 .../_____LANGUAGE_en/_____LANGUAGE_en.aod     |  45 ++++
 neonContext/Offer_context/Offer_context.aod   |  28 +++
 neonView/OfferEdit_view/OfferEdit_view.aod    |  47 ++++
 .../OfferFilter_view/OfferFilter_view.aod     |  42 ++++
 neonView/OfferMain_view/OfferMain_view.aod    |  18 ++
 .../OfferPreview_view/OfferPreview_view.aod   |  58 +++++
 others/db_changes/masterChangelog.xml         |   2 +
 .../db_changes/struct/changeLanguageType.xml  |   7 +
 others/db_changes/struct/create_offer.xml     |  30 +++
 others/db_changes/struct/offerChanges.xml     |   9 +
 process/Keyword_lib/process.js                |  17 ++
 process/Offer_lib/Offer_lib.aod               |   6 +
 process/Offer_lib/process.js                  |  33 +++
 process/Salesproject_lib/process.js           |  28 +--
 process/Util_lib/process.js                   |  51 +++++
 40 files changed, 977 insertions(+), 38 deletions(-)
 create mode 100644 entity/Contract_entity/entityfields/contractstart/onValueChange.js
 create mode 100644 entity/Offer_entity/Offer_entity.aod
 create mode 100644 entity/Offer_entity/entityfields/currency/possibleItemsProcess.js
 create mode 100644 entity/Offer_entity/entityfields/date_edit/valueProcess.js
 create mode 100644 entity/Offer_entity/entityfields/date_new/valueProcess.js
 create mode 100644 entity/Offer_entity/entityfields/image/valueProcess.js
 create mode 100644 entity/Offer_entity/entityfields/language/possibleItemsProcess.js
 create mode 100644 entity/Offer_entity/entityfields/offercode/onValidation.js
 create mode 100644 entity/Offer_entity/entityfields/offercode/valueProcess.js
 create mode 100644 entity/Offer_entity/entityfields/offerdate/valueProcess.js
 create mode 100644 entity/Offer_entity/entityfields/offerid/valueProcess.js
 create mode 100644 entity/Offer_entity/entityfields/probability/possibleItemsProcess.js
 create mode 100644 entity/Offer_entity/entityfields/status/possibleItemsProcess.js
 create mode 100644 entity/Offer_entity/entityfields/user_edit/valueProcess.js
 create mode 100644 entity/Offer_entity/entityfields/user_new/valueProcess.js
 create mode 100644 neonContext/Offer_context/Offer_context.aod
 create mode 100644 neonView/OfferEdit_view/OfferEdit_view.aod
 create mode 100644 neonView/OfferFilter_view/OfferFilter_view.aod
 create mode 100644 neonView/OfferMain_view/OfferMain_view.aod
 create mode 100644 neonView/OfferPreview_view/OfferPreview_view.aod
 create mode 100644 others/db_changes/struct/changeLanguageType.xml
 create mode 100644 others/db_changes/struct/create_offer.xml
 create mode 100644 others/db_changes/struct/offerChanges.xml
 create mode 100644 process/Offer_lib/Offer_lib.aod
 create mode 100644 process/Offer_lib/process.js

diff --git a/aliasDefinition/Data_alias/Data_alias.aod b/aliasDefinition/Data_alias/Data_alias.aod
index 9bbe128ca5..3e69267134 100644
--- a/aliasDefinition/Data_alias/Data_alias.aod
+++ b/aliasDefinition/Data_alias/Data_alias.aod
@@ -2358,6 +2358,220 @@
               </entityFieldDb>
             </entityFields>
           </entityDb>
+          <entityDb>
+            <name>OFFER</name>
+            <dbName></dbName>
+            <idColumn>OFFERID</idColumn>
+            <idGeneratorType v="0" />
+            <idGeneratorInterval v="1" />
+            <title></title>
+            <description></description>
+            <auditSyncConfig>
+              <name>auditSyncConfig</name>
+              <auditMode v="0" />
+              <syncActive v="false" />
+              <syncComplete v="true" />
+              <syncDirection v="1" />
+              <syncIds></syncIds>
+            </auditSyncConfig>
+            <entityFields>
+              <entityFieldDb>
+                <name>CURRENCY</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="4" />
+                <size v="10" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>LANGUAGE</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="1" />
+                <size v="5" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>DATE_EDIT</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="93" />
+                <size v="29" />
+                <scale v="9" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>VAT</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="2" />
+                <size v="14" />
+                <scale v="2" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>OFFERDATE</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="93" />
+                <size v="29" />
+                <scale v="9" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>OFFERID</name>
+                <dbName></dbName>
+                <primaryKey v="true" />
+                <columnType v="1" />
+                <size v="36" />
+                <scale v="0" />
+                <notNull v="true" />
+                <isUnique v="true" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>SALESPROJECT_ID</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="1" />
+                <size v="36" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>USER_EDIT</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="12" />
+                <size v="50" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>OFFERCODE</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="4" />
+                <size v="10" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>PROBABILITY</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="4" />
+                <size v="10" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>STATUS</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="4" />
+                <size v="10" />
+                <scale v="0" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>DATE_NEW</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="93" />
+                <size v="29" />
+                <scale v="9" />
+                <notNull v="true" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>RELATION_ID</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="1" />
+                <size v="36" />
+                <scale v="0" />
+                <notNull v="true" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>USER_NEW</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="12" />
+                <size v="50" />
+                <scale v="0" />
+                <notNull v="true" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+              <entityFieldDb>
+                <name>NET</name>
+                <dbName></dbName>
+                <primaryKey v="false" />
+                <columnType v="2" />
+                <size v="14" />
+                <scale v="2" />
+                <notNull v="false" />
+                <isUnique v="false" />
+                <index v="false" />
+                <title></title>
+                <description></description>
+              </entityFieldDb>
+            </entityFields>
+          </entityDb>
         </entities>
       </entityGroup>
     </aliasDefDb>
diff --git a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod
index c18b704215..074c3a3c7a 100644
--- a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod
+++ b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod
@@ -18,6 +18,7 @@
     <node name="SALES" kind="123" title="Sales">
       <node name="Group2" kind="123" title="">
         <node name="Salesproject_context" kind="10077" />
+        <node name="Offer_context" kind="10077" />
         <node name="Contract_context" kind="10077" />
         <node name="Product_context" kind="10077" />
         <node name="INTERNAL_ADMINISTRATOR" kind="159" />
diff --git a/entity/Contract_entity/Contract_entity.aod b/entity/Contract_entity/Contract_entity.aod
index d46778722e..a49173f1dc 100644
--- a/entity/Contract_entity/Contract_entity.aod
+++ b/entity/Contract_entity/Contract_entity.aod
@@ -49,6 +49,7 @@
       <contentType>DATE</contentType>
       <resolution>DAY</resolution>
       <onValidation>%aditoprj%/entity/Contract_entity/entityfields/contractstart/onValidation.js</onValidation>
+      <onValueChange>%aditoprj%/entity/Contract_entity/entityfields/contractstart/onValueChange.js</onValueChange>
     </entityField>
     <entityField>
       <name>CONTRACTSTATUS</name>
diff --git a/entity/Contract_entity/entityfields/contractend/onValidation.js b/entity/Contract_entity/entityfields/contractend/onValidation.js
index 72fee09352..fdd3b12c57 100644
--- a/entity/Contract_entity/entityfields/contractend/onValidation.js
+++ b/entity/Contract_entity/entityfields/contractend/onValidation.js
@@ -1,5 +1,3 @@
-import("system.logging");
-import("system.neon");
 import("system.result");
 import("system.vars");
 import("Date_lib");
@@ -8,9 +6,5 @@ var dateUtils = new DateUtils();
 var cEnd = vars.get("$local.value");
 var cDue = vars.get("$field.CONTRACTDUE");
 
-//if (cDue > cEnd && cDue != "")
-//    neon.setFieldValue("$field.CONTRACTDUE", cEnd);
-//TODO: auslagern in onValueChange
-
 if (dateUtils.validateBeginnBeforeEnd(vars.get("$field.CONTRACTSTART"), cEnd) === false)
     result.string(dateUtils.getValidationFailString());
\ No newline at end of file
diff --git a/entity/Contract_entity/entityfields/contractend/onValueChange.js b/entity/Contract_entity/entityfields/contractend/onValueChange.js
index e69de29bb2..5a41f5caef 100644
--- a/entity/Contract_entity/entityfields/contractend/onValueChange.js
+++ b/entity/Contract_entity/entityfields/contractend/onValueChange.js
@@ -0,0 +1,7 @@
+import("system.vars");
+
+var cEnd = vars.get("$local.value");
+var cDue = vars.get("$field.CONTRACTDUE");
+
+if (cDue > cEnd && cDue != "")
+    vars.set("$field.CONTRACTDUE", cEnd);
\ No newline at end of file
diff --git a/entity/Contract_entity/entityfields/contractstart/onValidation.js b/entity/Contract_entity/entityfields/contractstart/onValidation.js
index 0e874184bf..f09d0ff9ed 100644
--- a/entity/Contract_entity/entityfields/contractstart/onValidation.js
+++ b/entity/Contract_entity/entityfields/contractstart/onValidation.js
@@ -7,9 +7,5 @@ var dateUtils = new DateUtils();
 var cStart = vars.get("$local.value");
 var cDue = vars.get("$field.CONTRACTDUE");
 
-//if (cDue < cStart && cDue != "")
-//    neon.setFieldValue("$field.CONTRACTDUE", cStart);
-//TODO: auslagern in onValueChange
-
 if (dateUtils.validateBeginnBeforeEnd(cStart, vars.get("$field.CONTRACTEND")) === false)
     result.string(dateUtils.getValidationFailString());
\ No newline at end of file
diff --git a/entity/Contract_entity/entityfields/contractstart/onValueChange.js b/entity/Contract_entity/entityfields/contractstart/onValueChange.js
new file mode 100644
index 0000000000..c8715e611c
--- /dev/null
+++ b/entity/Contract_entity/entityfields/contractstart/onValueChange.js
@@ -0,0 +1,7 @@
+import("system.vars");
+
+var cStart = vars.get("$local.value");
+var cDue = vars.get("$field.CONTRACTDUE");
+
+if (cDue < cStart && cDue != "")
+    vars.set("$field.CONTRACTDUE", cStart);
\ No newline at end of file
diff --git a/entity/Offer_entity/Offer_entity.aod b/entity/Offer_entity/Offer_entity.aod
new file mode 100644
index 0000000000..696f09f949
--- /dev/null
+++ b/entity/Offer_entity/Offer_entity.aod
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.0.3">
+  <name>Offer_entity</name>
+  <title>Offer</title>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <alias>Data_alias</alias>
+  <recordContainerType>DB</recordContainerType>
+  <caption>Offer</caption>
+  <entityFields>
+    <entityIncomingField>
+      <name>#INCOMING</name>
+    </entityIncomingField>
+    <entityField>
+      <name>CURRENCY</name>
+      <tableName>OFFER</tableName>
+      <columnName>CURRENCY</columnName>
+      <caption>Currency</caption>
+      <possibleItemsProcess>%aditoprj%/entity/Offer_entity/entityfields/currency/possibleItemsProcess.js</possibleItemsProcess>
+    </entityField>
+    <entityField>
+      <name>DATE_EDIT</name>
+      <tableName>OFFER</tableName>
+      <columnName>DATE_EDIT</columnName>
+      <contentType>DATE</contentType>
+      <outputFormat>yyyy-MM-dd&amp;apos;T&amp;apos;HH:mm:ssZ</outputFormat>
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/date_edit/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>DATE_NEW</name>
+      <tableName>OFFER</tableName>
+      <columnName>DATE_NEW</columnName>
+      <contentType>DATE</contentType>
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/date_new/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>LANGUAGE</name>
+      <tableName>OFFER</tableName>
+      <columnName>LANGUAGE</columnName>
+      <caption>Language</caption>
+      <mandatory v="true" />
+      <possibleItemsProcess>%aditoprj%/entity/Offer_entity/entityfields/language/possibleItemsProcess.js</possibleItemsProcess>
+    </entityField>
+    <entityField>
+      <name>NET</name>
+      <tableName>OFFER</tableName>
+      <columnName>NET</columnName>
+      <caption>Total net</caption>
+    </entityField>
+    <entityField>
+      <name>OFFERCODE</name>
+      <tableName>OFFER</tableName>
+      <columnName>OFFERCODE</columnName>
+      <caption>Offer number</caption>
+      <state>READONLY</state>
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/offercode/valueProcess.js</valueProcess>
+      <onValidation>%aditoprj%/entity/Offer_entity/entityfields/offercode/onValidation.js</onValidation>
+    </entityField>
+    <entityField>
+      <name>OFFERDATE</name>
+      <tableName>OFFER</tableName>
+      <columnName>OFFERDATE</columnName>
+      <caption>Date</caption>
+      <contentType>DATE</contentType>
+      <resolution>DAY</resolution>
+      <mandatory v="true" />
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/offerdate/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>OFFERID</name>
+      <tableName>OFFER</tableName>
+      <columnName>OFFERID</columnName>
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/offerid/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>PROBABILITY</name>
+      <tableName>OFFER</tableName>
+      <columnName>PROBABILITY</columnName>
+      <caption>Probability</caption>
+      <possibleItemsProcess>%aditoprj%/entity/Offer_entity/entityfields/probability/possibleItemsProcess.js</possibleItemsProcess>
+    </entityField>
+    <entityField>
+      <name>RELATION_ID</name>
+      <tableName>OFFER</tableName>
+      <columnName>RELATION_ID</columnName>
+      <caption>Contact / Company</caption>
+      <mandatory v="true" />
+    </entityField>
+    <entityField>
+      <name>SALESPROJECT_ID</name>
+      <tableName>OFFER</tableName>
+      <columnName>SALESPROJECT_ID</columnName>
+      <caption>Salesproject</caption>
+    </entityField>
+    <entityField>
+      <name>STATUS</name>
+      <tableName>OFFER</tableName>
+      <columnName>STATUS</columnName>
+      <caption>Status</caption>
+      <possibleItemsProcess>%aditoprj%/entity/Offer_entity/entityfields/status/possibleItemsProcess.js</possibleItemsProcess>
+    </entityField>
+    <entityField>
+      <name>USER_EDIT</name>
+      <tableName>OFFER</tableName>
+      <columnName>USER_EDIT</columnName>
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/user_edit/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>USER_NEW</name>
+      <tableName>OFFER</tableName>
+      <columnName>USER_NEW</columnName>
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/user_new/valueProcess.js</valueProcess>
+    </entityField>
+    <entityField>
+      <name>VAT</name>
+      <tableName>OFFER</tableName>
+      <columnName>VAT</columnName>
+      <caption>Total VAT</caption>
+    </entityField>
+    <entityField>
+      <name>IMAGE</name>
+      <contentType>IMAGE</contentType>
+      <valueProcess>%aditoprj%/entity/Offer_entity/entityfields/image/valueProcess.js</valueProcess>
+    </entityField>
+  </entityFields>
+  <linkInformation>
+    <linkInformation>
+      <name>8f05a818-b447-40e6-8ee6-d3c2452f3dbe</name>
+      <tableName>OFFER</tableName>
+      <primaryKey>OFFERID</primaryKey>
+      <isUIDTable v="true" />
+    </linkInformation>
+  </linkInformation>
+</entity>
diff --git a/entity/Offer_entity/entityfields/currency/possibleItemsProcess.js b/entity/Offer_entity/entityfields/currency/possibleItemsProcess.js
new file mode 100644
index 0000000000..9720030d09
--- /dev/null
+++ b/entity/Offer_entity/entityfields/currency/possibleItemsProcess.js
@@ -0,0 +1,8 @@
+import("system.result");
+import("Keyword_lib");
+
+var kwdUtils, items;
+
+kwdUtils = new KeywordUtils();
+items = kwdUtils.getStandardArray("CURRENCY");
+result.object(items);
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/date_edit/valueProcess.js b/entity/Offer_entity/entityfields/date_edit/valueProcess.js
new file mode 100644
index 0000000000..00e95d744e
--- /dev/null
+++ b/entity/Offer_entity/entityfields/date_edit/valueProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT)
+    result.string(vars.getString("$sys.date"));
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/date_new/valueProcess.js b/entity/Offer_entity/entityfields/date_new/valueProcess.js
new file mode 100644
index 0000000000..7ace625314
--- /dev/null
+++ b/entity/Offer_entity/entityfields/date_new/valueProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+    result.string(vars.getString("$sys.date"));
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/image/valueProcess.js b/entity/Offer_entity/entityfields/image/valueProcess.js
new file mode 100644
index 0000000000..f0d0bb6a8a
--- /dev/null
+++ b/entity/Offer_entity/entityfields/image/valueProcess.js
@@ -0,0 +1,7 @@
+import("system.vars");
+import("system.result");
+import("Keyword_lib");
+
+var KeywUtils = new KeywordUtils();
+
+result.string("TEXT:" + KeywUtils.getViewValue("OFFER.STATUS", vars.getString("$field.STATUS")) );
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/language/possibleItemsProcess.js b/entity/Offer_entity/entityfields/language/possibleItemsProcess.js
new file mode 100644
index 0000000000..26992f2c6c
--- /dev/null
+++ b/entity/Offer_entity/entityfields/language/possibleItemsProcess.js
@@ -0,0 +1,8 @@
+import("system.result");
+import("Keyword_lib");
+
+var kwdUtils, items;
+
+kwdUtils = new KeywordUtils();
+items = kwdUtils.getStandardArray("LANGUAGE");
+result.object(items);
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offercode/onValidation.js b/entity/Offer_entity/entityfields/offercode/onValidation.js
new file mode 100644
index 0000000000..7dc708a6c7
--- /dev/null
+++ b/entity/Offer_entity/entityfields/offercode/onValidation.js
@@ -0,0 +1,11 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+import("Offer_lib");
+
+var OfferUtils = new OfferUtils();
+
+if( !OfferUtils.validateOfferNumber(vars.get("$local.value")) )
+{
+    result.string(OfferUtils.getOfferNumberValidationFailString());
+}
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offercode/valueProcess.js b/entity/Offer_entity/entityfields/offercode/valueProcess.js
new file mode 100644
index 0000000000..05581ec804
--- /dev/null
+++ b/entity/Offer_entity/entityfields/offercode/valueProcess.js
@@ -0,0 +1,11 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+import("Offer_lib");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+{
+    var OfferUtils = new OfferUtils();
+    
+    result.string( OfferUtils.getNextOfferNumber() );
+}
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offerdate/valueProcess.js b/entity/Offer_entity/entityfields/offerdate/valueProcess.js
new file mode 100644
index 0000000000..af2c1f09cc
--- /dev/null
+++ b/entity/Offer_entity/entityfields/offerdate/valueProcess.js
@@ -0,0 +1,12 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+import("Date_lib");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.get("$this.value") == "")
+{
+    var DateUtils = new DateUtils();
+    result.string(DateUtils.getTodayUTC());
+}
+else
+    result.string(vars.get("$this.value"));
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/offerid/valueProcess.js b/entity/Offer_entity/entityfields/offerid/valueProcess.js
new file mode 100644
index 0000000000..5be18c3983
--- /dev/null
+++ b/entity/Offer_entity/entityfields/offerid/valueProcess.js
@@ -0,0 +1,7 @@
+import("system.util");
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+    result.string(util.getNewUUID());
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/probability/possibleItemsProcess.js b/entity/Offer_entity/entityfields/probability/possibleItemsProcess.js
new file mode 100644
index 0000000000..21b13505b4
--- /dev/null
+++ b/entity/Offer_entity/entityfields/probability/possibleItemsProcess.js
@@ -0,0 +1,8 @@
+import("system.result");
+import("Keyword_lib");
+
+var kwdUtils, items;
+
+kwdUtils = new KeywordUtils();
+items = kwdUtils.getStandardArray("OFFER.PROBABILITY");
+result.object(items);
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/status/possibleItemsProcess.js b/entity/Offer_entity/entityfields/status/possibleItemsProcess.js
new file mode 100644
index 0000000000..5eab809f3a
--- /dev/null
+++ b/entity/Offer_entity/entityfields/status/possibleItemsProcess.js
@@ -0,0 +1,8 @@
+import("system.result");
+import("Keyword_lib");
+
+var kwdUtils, items;
+
+kwdUtils = new KeywordUtils();
+items = kwdUtils.getStandardArray("OFFER.STATUS");
+result.object(items);
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/user_edit/valueProcess.js b/entity/Offer_entity/entityfields/user_edit/valueProcess.js
new file mode 100644
index 0000000000..67c86b14ca
--- /dev/null
+++ b/entity/Offer_entity/entityfields/user_edit/valueProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_EDIT)
+    result.string(vars.getString("$sys.user"));
\ No newline at end of file
diff --git a/entity/Offer_entity/entityfields/user_new/valueProcess.js b/entity/Offer_entity/entityfields/user_new/valueProcess.js
new file mode 100644
index 0000000000..81966a3fbc
--- /dev/null
+++ b/entity/Offer_entity/entityfields/user_new/valueProcess.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("system.result");
+import("system.neon");
+
+if(vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW)
+    result.string(vars.getString("$sys.user"));
\ No newline at end of file
diff --git a/entity/Pers_entity/entityfields/orgname/onValueChange.js b/entity/Pers_entity/entityfields/orgname/onValueChange.js
index fce9fb549e..5829235884 100644
--- a/entity/Pers_entity/entityfields/orgname/onValueChange.js
+++ b/entity/Pers_entity/entityfields/orgname/onValueChange.js
@@ -9,7 +9,7 @@ logging.log("value change -> " + org_id);
 
 if(org_id != '')
 {
-    neon.setFieldValue("$field.ORG_ID", org_id);            
+    vars.set("$field.ORG_ID", org_id);            
 
     var org_name = db.cell("select NAME from ORG where ORGID = '" + org_id + "'");
     vars.set("$image.lookup_orgname", org_name);
diff --git a/entity/Salesproject_entity/entityfields/projectcode/onValueChange.js b/entity/Salesproject_entity/entityfields/projectcode/onValueChange.js
index 0f757ce13a..937237a494 100644
--- a/entity/Salesproject_entity/entityfields/projectcode/onValueChange.js
+++ b/entity/Salesproject_entity/entityfields/projectcode/onValueChange.js
@@ -1,7 +1,9 @@
-//import("system.neon");
-//import("system.result");
-//import("Salesproject_lib");
-//
-//var SalesprojectUtils = new SalesprojectUtils();
-//
-//neon.setFieldValue("$field.PROJECTCODE", SalesprojectUtils.getNextProjectNumber());
\ No newline at end of file
+import("system.vars");
+import("system.result");
+import("Salesproject_lib");
+
+var SalesprojectUtils = new SalesprojectUtils();
+if( !SalesprojectUtils.validateProjectNumber(vars.get("$local.value")) )
+{
+    vars.set("$field.PROJECTCODE", SalesprojectUtils.getNextProjectNumber());
+}
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index 633b9e2ba9..5e43abff3d 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -615,6 +615,51 @@
     <entry>
       <key>Statement given</key>
     </entry>
+    <entry>
+      <key>Total net</key>
+    </entry>
+    <entry>
+      <key>Offer</key>
+    </entry>
+    <entry>
+      <key>Offer number</key>
+    </entry>
+    <entry>
+      <key>Probability</key>
+    </entry>
+    <entry>
+      <key>Total VAT</key>
+    </entry>
+    <entry>
+      <key>Person / Firma</key>
+    </entry>
+    <entry>
+      <key>The offer number already exists!</key>
+    </entry>
+    <entry>
+      <key>0 %</key>
+    </entry>
+    <entry>
+      <key>75 %</key>
+    </entry>
+    <entry>
+      <key>100 %</key>
+    </entry>
+    <entry>
+      <key>25 %</key>
+    </entry>
+    <entry>
+      <key>50 %</key>
+    </entry>
+    <entry>
+      <key>Won</key>
+    </entry>
+    <entry>
+      <key>Checked</key>
+    </entry>
+    <entry>
+      <key>Sent</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
   <sqlModels>
diff --git a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
index 4efdbc55af..527dfbf942 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -810,6 +810,60 @@
       <key>Statement given</key>
       <value>Stellungnahme abgeben</value>
     </entry>
+    <entry>
+      <key>Total net</key>
+      <value>Betrag netto</value>
+    </entry>
+    <entry>
+      <key>Offer</key>
+      <value>Angebot</value>
+    </entry>
+    <entry>
+      <key>Offer number</key>
+      <value>Angebotsnummer</value>
+    </entry>
+    <entry>
+      <key>Probability</key>
+      <value>Wahrscheinlichkeit</value>
+    </entry>
+    <entry>
+      <key>Total VAT</key>
+      <value>Betrag MWST</value>
+    </entry>
+    <entry>
+      <key>Person / Firma</key>
+    </entry>
+    <entry>
+      <key>The offer number already exists!</key>
+      <value>Die Angebotsnummer existiert bereits!</value>
+    </entry>
+    <entry>
+      <key>0 %</key>
+    </entry>
+    <entry>
+      <key>75 %</key>
+    </entry>
+    <entry>
+      <key>100 %</key>
+    </entry>
+    <entry>
+      <key>25 %</key>
+    </entry>
+    <entry>
+      <key>50 %</key>
+    </entry>
+    <entry>
+      <key>Won</key>
+      <value>Gewonnen</value>
+    </entry>
+    <entry>
+      <key>Checked</key>
+      <value>Geprüft</value>
+    </entry>
+    <entry>
+      <key>Sent</key>
+      <value>Versendet</value>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 1443178f82..d2c0fea478 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -623,6 +623,51 @@
     <entry>
       <key>Statement given</key>
     </entry>
+    <entry>
+      <key>Total net</key>
+    </entry>
+    <entry>
+      <key>Offer</key>
+    </entry>
+    <entry>
+      <key>Offer number</key>
+    </entry>
+    <entry>
+      <key>Probability</key>
+    </entry>
+    <entry>
+      <key>Total VAT</key>
+    </entry>
+    <entry>
+      <key>Person / Firma</key>
+    </entry>
+    <entry>
+      <key>The offer number already exists!</key>
+    </entry>
+    <entry>
+      <key>0 %</key>
+    </entry>
+    <entry>
+      <key>75 %</key>
+    </entry>
+    <entry>
+      <key>100 %</key>
+    </entry>
+    <entry>
+      <key>25 %</key>
+    </entry>
+    <entry>
+      <key>50 %</key>
+    </entry>
+    <entry>
+      <key>Won</key>
+    </entry>
+    <entry>
+      <key>Checked</key>
+    </entry>
+    <entry>
+      <key>Sent</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/neonContext/Offer_context/Offer_context.aod b/neonContext/Offer_context/Offer_context.aod
new file mode 100644
index 0000000000..77b1dfe024
--- /dev/null
+++ b/neonContext/Offer_context/Offer_context.aod
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.0.0">
+  <name>Offer_context</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <mainview>OfferMain_view</mainview>
+  <filterview>OfferFilter_view</filterview>
+  <editview>OfferEdit_view</editview>
+  <preview>OfferPreview_view</preview>
+  <entity>Offer_entity</entity>
+  <references>
+    <neonViewReference>
+      <name>1dd0290d-b820-4a3b-ada7-1850025ca914</name>
+      <view>OfferFilter_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>08b180ed-7983-4675-9be4-2b55467c713c</name>
+      <view>OfferMain_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>4ed03135-fe7e-4413-8272-c64ad5f3287d</name>
+      <view>OfferEdit_view</view>
+    </neonViewReference>
+    <neonViewReference>
+      <name>c7f456ce-a141-436b-ad4b-7007a95eae04</name>
+      <view>OfferPreview_view</view>
+    </neonViewReference>
+  </references>
+</neonContext>
diff --git a/neonView/OfferEdit_view/OfferEdit_view.aod b/neonView/OfferEdit_view/OfferEdit_view.aod
new file mode 100644
index 0000000000..fc6c2ad735
--- /dev/null
+++ b/neonView/OfferEdit_view/OfferEdit_view.aod
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
+  <name>OfferEdit_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <genericViewTemplate>
+      <name>OfferEdit_generic</name>
+      <editMode v="true" />
+      <entityField>#ENTITY</entityField>
+      <fields>
+        <entityFieldLink>
+          <name>20a42587-69dd-4b8e-9a2e-3f7e8717b6ee</name>
+          <entityField>OFFERCODE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>e95c7a5d-3931-4637-a759-c034ae5eb81d</name>
+          <entityField>RELATION_ID</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>768683f3-08c8-4e85-bb4c-7e5c74a8dec0</name>
+          <entityField>OFFERDATE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>ca883d2e-f391-4681-b9f7-72040d4b9669</name>
+          <entityField>LANGUAGE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>ce72d9f3-66ce-4a5e-a5af-c3a82520141d</name>
+          <entityField>PROBABILITY</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>767a9e6e-596b-4903-aa86-7bc0f66cd037</name>
+          <entityField>STATUS</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>64cb7376-3a7c-4ce9-99e8-e70bc91b41d0</name>
+          <entityField>CURRENCY</entityField>
+        </entityFieldLink>
+      </fields>
+    </genericViewTemplate>
+  </children>
+</neonView>
diff --git a/neonView/OfferFilter_view/OfferFilter_view.aod b/neonView/OfferFilter_view/OfferFilter_view.aod
new file mode 100644
index 0000000000..c50ceb2b9d
--- /dev/null
+++ b/neonView/OfferFilter_view/OfferFilter_view.aod
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
+  <name>OfferFilter_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <tableViewTemplate>
+      <name>OfferFilter_template</name>
+      <entityField>#ENTITY</entityField>
+      <columns>
+        <neonTableColumn>
+          <name>60b83daa-9349-4bef-94d8-5f1fc350da59</name>
+          <entityField>OFFERCODE</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>2e926750-d1db-4cb0-8fd9-f930ed7f0252</name>
+          <entityField>RELATION_ID</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>443c8480-5676-43a3-9617-f86dae39c960</name>
+          <entityField>OFFERDATE</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>6f55da1e-281c-44ba-ab97-729b75516c32</name>
+          <entityField>NET</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>a0e5fc8f-ce4f-4a79-902d-27f3e3ad2a3d</name>
+          <entityField>CURRENCY</entityField>
+        </neonTableColumn>
+        <neonTableColumn>
+          <name>24440d2f-cb7a-4a5f-9d54-b1cd130908c8</name>
+          <entityField>PROBABILITY</entityField>
+        </neonTableColumn>
+      </columns>
+    </tableViewTemplate>
+  </children>
+</neonView>
diff --git a/neonView/OfferMain_view/OfferMain_view.aod b/neonView/OfferMain_view/OfferMain_view.aod
new file mode 100644
index 0000000000..957c32ed2f
--- /dev/null
+++ b/neonView/OfferMain_view/OfferMain_view.aod
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
+  <name>OfferMain_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <masterSlaveLayout>
+      <name>layout</name>
+      <master>5b93621b-c597-4ee8-88d5-3075e3890eb5</master>
+    </masterSlaveLayout>
+  </layout>
+  <children>
+    <neonViewReference>
+      <name>5b93621b-c597-4ee8-88d5-3075e3890eb5</name>
+      <entityField>#ENTITY</entityField>
+      <view>OfferPreview_view</view>
+    </neonViewReference>
+  </children>
+</neonView>
diff --git a/neonView/OfferPreview_view/OfferPreview_view.aod b/neonView/OfferPreview_view/OfferPreview_view.aod
new file mode 100644
index 0000000000..d639c0b4f7
--- /dev/null
+++ b/neonView/OfferPreview_view/OfferPreview_view.aod
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0">
+  <name>OfferPreview_view</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <layout>
+    <boxLayout>
+      <name>layout</name>
+    </boxLayout>
+  </layout>
+  <children>
+    <cardViewTemplate>
+      <name>OfferHeader_template</name>
+      <iconField>IMAGE</iconField>
+      <titleField>OFFERCODE</titleField>
+      <descriptionField>RELATION_ID</descriptionField>
+      <entityField>#ENTITY</entityField>
+    </cardViewTemplate>
+    <genericViewTemplate>
+      <name>Offer_generic</name>
+      <showDrawer v="true" />
+      <entityField>#ENTITY</entityField>
+      <fields>
+        <entityFieldLink>
+          <name>b120a564-fb97-4ae3-bd3e-13ce25d97834</name>
+          <entityField>OFFERDATE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>42befe2f-40c0-4674-b0b1-70ae5523f861</name>
+          <entityField>STATUS</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>7a145c84-dc49-4af2-870f-44960dd89d12</name>
+          <entityField>LANGUAGE</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>9e876b07-3029-42fe-a1e7-5c19b845e50d</name>
+          <entityField>NET</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>cd72899a-69b2-4fe2-bf58-4fb9f594324e</name>
+          <entityField>VAT</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>16d38881-d3d3-4c4d-9f23-39d60eadce8d</name>
+          <entityField>CURRENCY</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>037889c4-136c-4e9e-b8e2-ff4f13af13c1</name>
+          <entityField>PROBABILITY</entityField>
+        </entityFieldLink>
+        <entityFieldLink>
+          <name>3317b73e-68e8-41a8-a678-89c7c7c8513e</name>
+          <entityField>SALESPROJECT_ID</entityField>
+        </entityFieldLink>
+      </fields>
+    </genericViewTemplate>
+  </children>
+</neonView>
diff --git a/others/db_changes/masterChangelog.xml b/others/db_changes/masterChangelog.xml
index 39d5255053..eb33b63d87 100644
--- a/others/db_changes/masterChangelog.xml
+++ b/others/db_changes/masterChangelog.xml
@@ -14,7 +14,9 @@
     <include file="struct/create_productprice.xml"/>
     <include file="struct/create_stock.xml"/>
     <include file="struct/create_salesproject.xml"/>
+    <include file="struct/create_offer.xml"/>
     <include file="struct/contractChanges.xml"/>
+    <include file="struct/offerChanges.xml"/>
     <include file="struct/productChanges.xml"/>
     <include file="misc/1535533490181_persChanges.xml"/>
     <include file="struct/1535612802325_addressChange.xml"/>
diff --git a/others/db_changes/struct/changeLanguageType.xml b/others/db_changes/struct/changeLanguageType.xml
new file mode 100644
index 0000000000..77aeb44c5d
--- /dev/null
+++ b/others/db_changes/struct/changeLanguageType.xml
@@ -0,0 +1,7 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <changeSet author="m.schroeger" id="609a8e0d-d104-4cdb-a803-3ac65bb456b3">
+    <modifyDataType tableName="OFFER" columnName="LANGUAGE" newDataType="varchar(5)"/>
+    <modifyDataType tableName="RELATION" columnName="LANGUAGE" newDataType="varchar(5)"/>
+    </changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/others/db_changes/struct/create_offer.xml b/others/db_changes/struct/create_offer.xml
new file mode 100644
index 0000000000..45c57d54f2
--- /dev/null
+++ b/others/db_changes/struct/create_offer.xml
@@ -0,0 +1,30 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+<changeSet author="m.schroeger" id="2f02d14b-731b-4e66-a945-af90b2e3b762">
+	<createTable tableName="OFFER">
+		<column name="OFFERID" type="CHAR(36)">
+			<constraints primaryKey="true" primaryKeyName="PK_OFFER_OFFERID"/>
+		</column>   
+                <column name="RELATION_ID" type="CHAR(36)">
+                    <constraints nullable="false"/>
+                </column>                           
+                <column name="SALESPROJECT_ID" type="CHAR(36)"/>
+                <column name="OFFERDATE" type="TIMESTAMP"/>
+                <column name="LANGUAGE" type="INTEGER"/>
+                <column name="OFFERCODE" type="INTEGER"/>
+                <column name="STATUS" type="INTEGER"/>
+                <column name="PROBABILITY" type="INTEGER"/>
+                <column name="NET" type="NUMERIC(14,2)"/>
+                <column name="VAT" type="NUMERIC(14,2)"/>
+                <column name="CURRENCY" type="INTEGER"/>
+		<column name="DATE_EDIT" type="TIMESTAMP"/>
+                <column name="DATE_NEW" type="TIMESTAMP">
+                    <constraints nullable="false"/>
+                </column>
+		<column name="USER_EDIT" type="VARCHAR(50)"/>
+                <column name="USER_NEW" type="VARCHAR(50)">
+                    <constraints nullable="false"/>
+                </column>                                                         
+	</createTable>      
+</changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/others/db_changes/struct/offerChanges.xml b/others/db_changes/struct/offerChanges.xml
new file mode 100644
index 0000000000..37adab85f1
--- /dev/null
+++ b/others/db_changes/struct/offerChanges.xml
@@ -0,0 +1,9 @@
+<?xml version="1.1" encoding="UTF-8" standalone="no"?>
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
+    <changeSet author="m.schroeger" id="27bc9279-0794-436c-9b54-dda05c3c310e">
+        <dropColumn tableName="OFFER" columnName="LANGUAGE"/>
+        <addColumn tableName="OFFER">
+            <column name="LANGUAGE" type="varchar(5)"/>
+        </addColumn>
+    </changeSet>
+</databaseChangeLog>
\ No newline at end of file
diff --git a/process/Keyword_lib/process.js b/process/Keyword_lib/process.js
index bb12c1b1d8..7e8781529f 100644
--- a/process/Keyword_lib/process.js
+++ b/process/Keyword_lib/process.js
@@ -208,6 +208,23 @@ function KeywordUtils(){
                     ,createKeywordEntry("9", translate.text("Lead"))
                 ]);
                 break;
+            case "OFFER.PROBABILITY":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("1", translate.text("0 %"), null, {percentValue: 0})
+                    ,createKeywordEntry("2", translate.text("25 %"), null, {percentValue: 25})
+                    ,createKeywordEntry("3", translate.text("50 %"), null, {percentValue: 50})
+                    ,createKeywordEntry("4", translate.text("75 %"), null, {percentValue: 75})
+                    ,createKeywordEntry("5", translate.text("100 %"), null, {percentValue: 100})
+                ]);
+                break;
+            case "OFFER.STATUS":
+                valueContainer = createKeywordEntriesContainer([
+                     createKeywordEntry("1", translate.text("Checked"))
+                    ,createKeywordEntry("2", translate.text("Sent"))
+                    ,createKeywordEntry("3", translate.text("Won"))
+                    ,createKeywordEntry("4", translate.text("Lost"))
+                ]);
+                break;
             default: 
                 throw new Error(translate.withArguments("[%0]the given keyword \"%1\" has no match with the possible keywordlist", [
                     arguments.callee.name, keywordType
diff --git a/process/Offer_lib/Offer_lib.aod b/process/Offer_lib/Offer_lib.aod
new file mode 100644
index 0000000000..ae2ae4230f
--- /dev/null
+++ b/process/Offer_lib/Offer_lib.aod
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.7" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.1.7">
+  <name>Offer_lib</name>
+  <majorModelMode>DISTRIBUTED</majorModelMode>
+  <process>%aditoprj%/process/Offer_lib/process.js</process>
+</process>
diff --git a/process/Offer_lib/process.js b/process/Offer_lib/process.js
new file mode 100644
index 0000000000..d142a7bc54
--- /dev/null
+++ b/process/Offer_lib/process.js
@@ -0,0 +1,33 @@
+import("system.translate");
+import("system.db");
+import("system.eMath");
+import("Util_lib");
+
+function OfferUtils(){
+    var that = this;
+    /**
+     * Delivers the next valid offer number (has to be unique)
+     * 
+     * @result {String} next valid offer number
+     */
+    this.getNextOfferNumber = function(){
+        var JdUtils = new JDitoUtils();
+        return JdUtils.getNextUniqueNumber("OFFERCODE", "OFFER");
+    }
+    
+    /**
+     * Checks if the passed offer number is valid (has to be unique)
+     * 
+     * @param {String} pOfferNumber offer number to check
+     * 
+     * @result {boolean} passed number is valid
+     */
+    this.validateOfferNumber = function(pOfferNumber){
+        var JdUtils = new JDitoUtils();
+        return JdUtils.validateUniqueNumber(pOfferNumber, "OFFERCODE", "OFFER");
+    }
+    
+    this.getOfferNumberValidationFailString = function(){
+        return translate.text("The offer number already exists!");
+    }
+}
\ No newline at end of file
diff --git a/process/Salesproject_lib/process.js b/process/Salesproject_lib/process.js
index 29141bbff5..6f0456ff37 100644
--- a/process/Salesproject_lib/process.js
+++ b/process/Salesproject_lib/process.js
@@ -1,6 +1,7 @@
 import("system.translate");
 import("system.db");
 import("system.eMath");
+import("Util_lib");
 
 function SalesprojectUtils(){
     var that = this;
@@ -10,36 +11,23 @@ function SalesprojectUtils(){
      * @result {String} next valid project number
      */
     this.getNextProjectNumber = function(){
-        var maxNum = that.getMaxProjectNumber();
-        
-        if(maxNum == "0")    return 1000; //start number
-        
-        return eMath.addInt(maxNum, "1");//increment currently highest number
+        var JdUtils = new JDitoUtils();
+        return JdUtils.getNextUniqueNumber("PROJECTCODE", "SALESPROJECT");
     }
     
     /**
      * Checks if the passed project number is valid (has to be unique)
      * 
-     * @result {boolean} passed projectnumber is valid
+     * @param {String} pProjectNumber project number to check
+     * 
+     * @result {boolean} passed number is valid
      */
     this.validateProjectNumber = function(pProjectNumber){
-        var maxNum = that.getMaxProjectNumber();
-        
-        return Number(pProjectNumber) > Number(maxNum);
+        var JdUtils = new JDitoUtils();
+        return JdUtils.validateUniqueNumber(pProjectNumber, "PROJECTCODE", "SALESPROJECT");
     }
     
     this.getProjectNumberValidationFailString = function(){
         return translate.text("The project number already exists!");
     }
-    
-    /**
-     * Delivers the hightest project number currently stored in database
-     * 
-     * @result {String} hightest project number
-     */
-    this.getMaxProjectNumber = function(){
-        var maxNum = db.cell("select max(PROJECTCODE) from SALESPROJECT");
-        
-        return maxNum == "" ? "0" : maxNum;
-    }
 }
\ No newline at end of file
diff --git a/process/Util_lib/process.js b/process/Util_lib/process.js
index b811addbd2..406f2120f8 100644
--- a/process/Util_lib/process.js
+++ b/process/Util_lib/process.js
@@ -779,6 +779,7 @@ function BinaryUtils()
  */
 function JDitoUtils()
 {
+    var that = this;
     /**
      * A wrapper for process.executeScript
      *
@@ -899,6 +900,56 @@ function JDitoUtils()
 
         return data.concat(temp);
     }
+    
+    /**
+     * Delivers the next unique number
+     *
+     * @param {String} pColumn req database column that contains unique numbers
+     * @param {String} pTable req database table
+     * @param {Number} pStartNumber opt number to start numeration
+     * 
+     * @result {String} next valid number
+     */
+    this.getNextUniqueNumber = function(pColumn, pTable, pStartNumber){
+        var maxNum = that.getMaxUniqueNumber(pColumn, pTable);
+        
+        if(maxNum == "0")    
+        {
+            if(pStartNumber == undefined)   pStartNumber = 1000;
+            return pStartNumber;
+        }
+        
+        return eMath.addInt(maxNum, "1");//increment currently highest number
+    }
+    
+    /**
+     * Checks if the passed number is valid (has to be unique)
+     * 
+     * @param {String} pNumber number to check
+     * @param {String} pColumn req database column that contains unique numbers
+     * @param {String} pTable req database table
+     * 
+     * @result {boolean} passed number is valid
+     */
+    this.validateUniqueNumber = function(pNumber, pColumn, pTable){
+        var maxNum = that.getMaxUniqueNumber(pColumn, pTable);
+        
+        return Number(pNumber) > Number(maxNum);
+    }
+    
+    /**
+     * Delivers the hightest number currently stored in database
+     * 
+     * @param {String} pColumn req database column that contains unique numbers
+     * @param {String} pTable req database table
+     * 
+     * @result {String} hightest number
+     */
+    this.getMaxUniqueNumber = function(pColumn, pTable){
+        var maxNum = db.cell("select max(" + pColumn + ") from " + pTable);
+        
+        return maxNum == "" ? "0" : maxNum;
+    }
 }
 /**
  * Class containing utility functions for use with JSON
-- 
GitLab