diff --git a/entity/Offer_entity/entityfields/neworder/onActionProcess.js b/entity/Offer_entity/entityfields/neworder/onActionProcess.js
index 20fc048a90db93380fadb7f69ca5fb89c2db25bd..844372309437195d52fcdb07c5c0dc4b4e56ab6d 100644
--- a/entity/Offer_entity/entityfields/neworder/onActionProcess.js
+++ b/entity/Offer_entity/entityfields/neworder/onActionProcess.js
@@ -1,14 +1,14 @@
 import("system.vars");
 import("system.neon");
+import("Offer_lib");
 
-var params = {
-    "RelationId_param" : vars.getString("$field.RELATION_ID"),
-    "SalesprojectId_param" : vars.getString("$field.SALESPROJECT_ID"),
-    "OrderCurrency_param" : vars.getString("$field.CURRENCY"),
-    "OrderLanguage_param" : vars.getString("$field.LANGUAGE"),
-    "OrderHeader_param" : vars.getString("$field.HEADER"),
-    "OrderAddress_param" : vars.getString("$field.ADDRESS"),
-    "OfferId_param" : vars.getString("$field.OFFERID")
-};
+var contactId = vars.getString("$field.CONTACT_ID");
+var salesprojectId = vars.getString("$field.SALESPROJECT_ID");
+var currency = vars.getString("$field.CURRENCY");
+var language = vars.getString("$field.LANGUAGE");
+var header = vars.getString("$field.HEADER");
+var address = vars.getString("$field.ADDRESS");
+var offerId = vars.getString("$field.OFFERID");
 
-neon.openContext("Order_context", null, null, neon.OPERATINGSTATE_NEW, params);
+OfferUtils.copyToOrder(offerId, salesprojectId, contactId, language, currency, address, header);
+    
\ No newline at end of file
diff --git a/entity/Order_entity/recordcontainers/db/onDBInsert.js b/entity/Order_entity/recordcontainers/db/onDBInsert.js
index db29c0a1c5b19b53099471e2c9a50c54187fefba..f3f8fd6de5a6a1febfa39604a10cd0249ed35e89 100644
--- a/entity/Order_entity/recordcontainers/db/onDBInsert.js
+++ b/entity/Order_entity/recordcontainers/db/onDBInsert.js
@@ -1,5 +1,3 @@
-import("system.util");
-import("system.db");
 import("system.neon");
 import("system.vars");
 import("Sql_lib");
@@ -7,44 +5,8 @@ import("Order_lib");
 
 if (vars.get("$sys.operatingstate") == neon.OPERATINGSTATE_NEW && vars.exists("$param.OfferId_param"))
 {
-    var rowId = vars.getString("$field.SALESORDERID");
+    var orderId = vars.getString("$field.SALESORDERID");
     var offerId = vars.getString("$param.OfferId_param");
     
-    var cols = [
-        "UNIT", 
-        "QUANTITY", 
-        "GROUPCODEID", 
-        "ASSIGNEDTO", 
-        "PRICE", 
-        "ITEMSORT", 
-        "PRODUCT_ID", 
-        "VAT", 
-        "ITEMNAME", 
-        "OPTIONAL", 
-        "DISCOUNT", 
-        "ITEMPOSITION", 
-        "INFO"
-    ];
-    var offerItemSql = SqlCondition.begin()
-        .andPrepare("OFFERITEM.OFFER_ID", offerId)
-        .buildSql("select " + cols.join(", ") + " from OFFERITEM", "1=0");
-    var offerItems = db.table(offerItemSql);
-    
-    var table = "SALESORDERITEM";
-    cols = cols.concat(["SALESORDER_ID", "SALESORDERITEMID"]);
-    var types = db.getColumnTypes(table, cols);
-    
-    var toInsert = offerItems.map(function (row) 
-    {
-        return [table, cols, types, row.concat([rowId, util.getNewUUID()])];
-    });
-    db.inserts(toInsert);
-    
-    var oiUtils = new OrderItemUtils(rowId);
-    
-    //update order price
-    cols = ["NET", "VAT"];
-    var vals = oiUtils.getNetAndVat();
-    
-    db.updateData("SALESORDER", cols, null, vals, SqlCondition.equals("SALESORDER.SALESORDERID", rowId, "1 = 2"));
-}
\ No newline at end of file
+    OrderUtils.copyOfferItemsToOrder(offerId, orderId); //copy all offerItems
+}
diff --git a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
index c03732c0b6d031ac806d6c0554172303169fad5c..82772126b5fda75a37d80784a694669e5ea50a17 100644
--- a/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
+++ b/language/_____LANGUAGE_EXTRA/_____LANGUAGE_EXTRA.aod
@@ -2268,6 +2268,9 @@
     <entry>
       <key>Create receipt</key>
     </entry>
+    <entry>
+      <key>New time tracking</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 9b057dd5bf9ad45a5ed3ccc749b324146e8eb9bc..afaaf670ca6db7070035c3d672402b82c39be14d 100644
--- a/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
+++ b/language/_____LANGUAGE_de/_____LANGUAGE_de.aod
@@ -2594,6 +2594,7 @@
     </entry>
     <entry>
       <key>Framework contract</key>
+      <value>Vertrag</value>
     </entry>
     <entry>
       <key>Niger</key>
diff --git a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
index 5371f927e029c2bc19c159ac35a480764552bf14..c5ed0cb8d71bf1eaf805cd0dd1b515aec4990a5f 100644
--- a/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
+++ b/language/_____LANGUAGE_en/_____LANGUAGE_en.aod
@@ -2290,6 +2290,9 @@
     <entry>
       <key>Create receipt</key>
     </entry>
+    <entry>
+      <key>New time tracking</key>
+    </entry>
   </keyValueMap>
   <font name="Dialog" style="0" size="11" />
 </language>
diff --git a/process/Offer_lib/process.js b/process/Offer_lib/process.js
index 0396585e127d4a18b6e0b3bbfb937ef434d8df5e..ad45ec9e4efd4b91501596af489df44bb84e8e68 100644
--- a/process/Offer_lib/process.js
+++ b/process/Offer_lib/process.js
@@ -231,6 +231,32 @@ OfferUtils.openOfferReport = function(pOfferID)
     offerReport.openReport();
 }
 
+/**
+ * opens an order in NEW mode with values from an offer
+ * 
+ * @param pOfferId {String} id of the offer
+ * @param pSalesprojectId {String} salesproject id
+ * @param pContactId {String} contact id
+ * @param pLanguage {String} language
+ * @param pCurrency {String} [currency=""]
+ * @param pAddress {String} [address=""]
+ * @param pHeader {String} [header=""]
+ */
+OfferUtils.copyToOrder = function (pOfferId, pSalesprojectId, pContactId, pLanguage, pCurrency, pAddress, pHeader)
+{
+    var params = {
+        "ContactId_param" : pContactId,
+        "SalesprojectId_param" : pSalesprojectId,
+        "OrderLanguage_param" : pLanguage,
+        "OfferId_param" : pOfferId,
+        "OrderCurrency_param" : pCurrency || "",
+        "OrderAddress_param" : pAddress || "",
+        "OrderHeader_param" : pHeader || ""
+    };
+    neon.openContext("Order_context", null, null, neon.OPERATINGSTATE_NEW, params);
+}
+
+
 /******************************************************************************/
 
 /**
diff --git a/process/Order_lib/process.js b/process/Order_lib/process.js
index 88cfa08fd4d7979c1442c1caeb28a0a3a2e6ceaa..062753456e2da9f5f8bec2f429614a035d62e552 100644
--- a/process/Order_lib/process.js
+++ b/process/Order_lib/process.js
@@ -77,6 +77,82 @@ OrderUtils.createNewOrder = function(pSalesprojectId, pRelationId)
     neon.openContext("Order_context", null, neon.OPERATINGSTATE_NEW, params);
 }
 
+/**
+ * copies all offerItems of an offer and creates orderItems for an order
+ * 
+ * @param {String} pOfferId the offer to get the items from
+ * @param {String} pOrderId the order to create the items for
+ * 
+ * @return {Number[]} Array with the ids of the inserted orderItems
+ */
+OrderUtils.copyOfferItemsToOrder = function (pOfferId, pOrderId)
+{
+    var cols = [
+        "UNIT", 
+        "QUANTITY", 
+        "GROUPCODEID", 
+        "ASSIGNEDTO", 
+        "PRICE", 
+        "ITEMSORT", 
+        "PRODUCT_ID", 
+        "VAT", 
+        "ITEMNAME", 
+        "OPTIONAL", 
+        "DISCOUNT", 
+        "ITEMPOSITION", 
+        "INFO"
+    ];
+    var offerItemSql = SqlCondition.begin()
+        .andPrepare("OFFERITEM.OFFER_ID", pOfferId)
+        .buildSql("select " + cols.concat(["OFFERITEMID"]).join(", ") + " from OFFERITEM", "1=0");
+    var offerItems = db.table(offerItemSql);
+
+    var table = "SALESORDERITEM";
+    cols = cols.concat(["SALESORDERITEMID", "SALESORDER_ID"]);
+    var types = db.getColumnTypes(table, cols);
+    
+    //the rows need new UIDs, but because items can be related over ASSIGNEDTO, ASSIGNEDTO must also be 
+    //changed to the newly generated id of the parent item, so the "oldId : newId" pairs have to be stored
+    //to set ASSIGNEDTO correctly
+    var idMap = {}; 
+    
+    var toInsert = [];
+    while (offerItems.length > 0)
+        for (let i = 0; i < offerItems.length; i++)
+        {
+            var row = offerItems[i];
+            
+            //checks if the parent attribute has already been put into the insert-array,
+            //otherwise the foreign-key ASSIGNEDTO could have the id of a row that hasn't been inserted yet
+            // -> toInsert needs to be in the correct order
+            if (row[3] == "" || row[3] in idMap)
+            {
+                row[3] = idMap[row[3]] || "";
+                var newId = util.getNewUUID();
+                idMap[row[13]] = newId;
+                row[13] = newId; //replace the UID
+                toInsert.push([table, cols, types, row.concat([pOrderId])]);
+                offerItems.splice(i, 1); //remove the row from offerItems
+                i--;
+            }
+        }
+    
+    db.inserts(toInsert);
+    
+    var oiUtils = new OrderItemUtils(pOrderId);
+    
+    //update order price
+    cols = ["NET", "VAT"];
+    var vals = oiUtils.getNetAndVat();
+    
+    db.updateData("SALESORDER", cols, null, vals, SqlCondition.equals("SALESORDER.SALESORDERID", pOrderId, "1 = 2"));
+    
+    return Object.keys(idMap).map(function (id) 
+    {
+        return idMap[id];
+    });
+}
+
 
 /******************************************************************************/