# HG changeset patch
# User Yogas Karnik <yogas.karnik@precognis.com>
# Date 1496855385 -7200
#      mié jun 07 19:09:45 2017 +0200
# Node ID 5e9b5ad792566b049da568fc83629946031a82d4
# Parent  7fd0755c388c5b94ffcc698e508297fd5421f59f
[SupportForAttributes] Added popup for quotation to order flow

diff --git a/src-db/database/sourcedata/AD_MESSAGE.xml b/src-db/database/sourcedata/AD_MESSAGE.xml
--- a/src-db/database/sourcedata/AD_MESSAGE.xml
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml
@@ -709,6 +709,18 @@
 <!--120940539EFF49778C4EA8025340A135-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--120940539EFF49778C4EA8025340A135--></AD_MESSAGE>
 
+<!--122C68F6AE6A4DC2BAF35C10090A12F6--><AD_MESSAGE>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <AD_MESSAGE_ID><![CDATA[122C68F6AE6A4DC2BAF35C10090A12F6]]></AD_MESSAGE_ID>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <VALUE><![CDATA[OBPOS_QuotationProductAttributeDesc]]></VALUE>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <MSGTEXT><![CDATA[Please scan the attribute for the products below.]]></MSGTEXT>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <AD_MODULE_ID><![CDATA[FF808181326CC34901326D53DBCF0018]]></AD_MODULE_ID>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--122C68F6AE6A4DC2BAF35C10090A12F6--></AD_MESSAGE>
+
 <!--122C89DF5DF64C48B9D823B25FE489A8--><AD_MESSAGE>
 <!--122C89DF5DF64C48B9D823B25FE489A8-->  <AD_MESSAGE_ID><![CDATA[122C89DF5DF64C48B9D823B25FE489A8]]></AD_MESSAGE_ID>
 <!--122C89DF5DF64C48B9D823B25FE489A8-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -1442,6 +1454,18 @@
 <!--2AFCDEF608BD4956BA3F083811CD8650-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--2AFCDEF608BD4956BA3F083811CD8650--></AD_MESSAGE>
 
+<!--2B3BAFAF0EA34CC98800A87628BC31C6--><AD_MESSAGE>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <AD_MESSAGE_ID><![CDATA[2B3BAFAF0EA34CC98800A87628BC31C6]]></AD_MESSAGE_ID>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <VALUE><![CDATA[OBPOS_QuotationProductAttributesDialogTitle]]></VALUE>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <MSGTEXT><![CDATA[Quotation to Order]]></MSGTEXT>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <AD_MODULE_ID><![CDATA[FF808181326CC34901326D53DBCF0018]]></AD_MODULE_ID>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--2B3BAFAF0EA34CC98800A87628BC31C6--></AD_MESSAGE>
+
 <!--2B8F152F1D03471583D640024578E9A2--><AD_MESSAGE>
 <!--2B8F152F1D03471583D640024578E9A2-->  <AD_MESSAGE_ID><![CDATA[2B8F152F1D03471583D640024578E9A2]]></AD_MESSAGE_ID>
 <!--2B8F152F1D03471583D640024578E9A2-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff --git a/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java b/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java
--- a/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java
+++ b/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java
@@ -226,6 +226,7 @@
         "pointofsale/view/modals/modalmessage",
         "pointofsale/view/modals/modalDeleteDiscounts",
         "pointofsale/view/modals/modalproductattribute",
+        "pointofsale/view/modals/modalquotationproductattribute",
 
         // Cash Management window
         "cashmgmt/model/cashmgmt-print",
diff --git a/web/org.openbravo.retail.posterminal/js/components/order.js b/web/org.openbravo.retail.posterminal/js/components/order.js
--- a/web/org.openbravo.retail.posterminal/js/components/order.js
+++ b/web/org.openbravo.retail.posterminal/js/components/order.js
@@ -639,6 +639,9 @@
         }
       }
     }, this);
+    this.order.get('lines').on('change:attributeValue', function (line) {
+      //Disable attribute component if undefined
+    }, this);
     this.order.on('change:hasbeenpaid', function (model) {
       if (model.get('isQuotation') && model.get('hasbeenpaid') === 'Y' && !model.get('obposIsDeleted') && this.$.divText.content && (this.$.divText.content === OB.I18N.getLabel('OBPOS_QuotationNew') || this.$.divText.content === OB.I18N.getLabel('OBPOS_QuotationDraft'))) {
         this.$.divText.setContent(OB.I18N.getLabel('OBPOS_QuotationUnderEvaluation'));
diff --git a/web/org.openbravo.retail.posterminal/js/model/order.js b/web/org.openbravo.retail.posterminal/js/model/order.js
--- a/web/org.openbravo.retail.posterminal/js/model/order.js
+++ b/web/org.openbravo.retail.posterminal/js/model/order.js
@@ -3038,23 +3038,44 @@
         }
       }, this);
 
-      if (updatePrices) {
-        this.updatePrices(function (order) {
-          order.calculateReceipt(function () {
+      var productHasAttribute = false,
+          productWithAttributeValue = [];
+      this.get('lines').each(function (theLine) {
+        var productAttributes = theLine.attributes.product.attributes;
+        if (OB.UTIL.isNullOrUndefined(productAttributes.hasAttributes) === false) {
+          productWithAttributeValue.push(theLine);
+          productHasAttribute = productAttributes.hasAttributes;
+        }
+      });
+      if (!productHasAttribute) {
+        if (updatePrices) {
+          this.updatePrices(function (order) {
+            order.calculateReceipt(function () {
+              OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_QuotationCreatedOrder'));
+              // This event is used in stock validation module.
+              order.trigger('orderCreatedFromQuotation');
+            });
+          });
+        } else {
+          this.set('skipApplyPromotions', true);
+          this.calculateReceipt(function () {
+            me.unset('skipApplyPromotions');
             OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_QuotationCreatedOrder'));
-            // This event is used in stock validation module.
-            order.trigger('orderCreatedFromQuotation');
+            me.trigger('orderCreatedFromQuotation');
           });
-        });
-      } else {
-        this.set('skipApplyPromotions', true);
-        this.calculateReceipt(function () {
-          me.unset('skipApplyPromotions');
-          OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_QuotationCreatedOrder'));
-          me.trigger('orderCreatedFromQuotation');
+        }
+      }
+      this.calculateReceipt();
+      //call quotation attributes popup
+      if (OB.MobileApp.model.hasPermission('OBPOS_EnableSupportForProductAttributes', true) && productHasAttribute) {
+        OB.MobileApp.view.waterfall('onShowPopup', {
+          popup: 'modalQuotationProductAttributes',
+          args: {
+            lines: productWithAttributeValue,
+            quotationProductAttribute: this
+          }
         });
       }
-      this.calculateReceipt();
     },
 
     reactivateQuotation: function () {
diff --git a/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js b/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
new file mode 100644
--- /dev/null
+++ b/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
@@ -0,0 +1,173 @@
+/*
+ ************************************************************************************
+ * Copyright (C) 2017 Openbravo S.L.U.
+ * Licensed under the Openbravo Commercial License version 1.0
+ * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
+ * or in the legal folder of this module distribution.
+ ************************************************************************************
+ */
+/*global OB, moment, enyo */
+
+enyo.kind({
+  name: 'OB.UI.ModalQuotationProductAttributesScroller.QuotationLines',
+  components: [{
+    classes: 'properties-label',
+    name: 'productName',
+    type: 'text',
+    style: 'font-size: 17px;margin-top:4px'
+  }, {
+    kind: 'OB.UI.renderTextProperty',
+    name: 'valueAttribute',
+    maxlength: '70',
+    style: 'width: 55%',
+    handlers: {
+      oninput: 'blur'
+    },
+    blur: function () {
+      this.bubble('onFieldChanged');
+    },
+    placeholder: 'Scan attribute'
+  }, {
+    style: 'clear: both'
+  }]
+});
+
+enyo.kind({
+  kind: 'OB.UI.ModalAction',
+  name: 'OB.UI.ModalQuotationProductAttributes',
+  i18nHeader: 'OBPOS_QuotationProductAttributesDialogTitle',
+  style: 'width: 700px;',
+  autoDismiss: false,
+  bodyContent: {
+    kind: 'Scroller',
+    maxHeight: '225px',
+    style: 'background-color: #ffffff;',
+    thumb: true,
+    horizontal: 'hidden',
+    components: [{
+      name: 'quotationLinesComponent'
+    }]
+  },
+  header: {
+
+  },
+  handlers: {
+    onFieldChanged: 'fieldChanged'
+  },
+  bodyButtons: {
+    components: [{
+      kind: 'OB.UI.ModalDialogButton',
+      i18nContent: 'OBMOBC_LblOk',
+      tap: function () {
+        this.owner.owner.saveAction();
+      }
+    }, {
+      kind: 'OB.UI.ModalDialogButton',
+      i18nContent: 'OBPOS_LblClear',
+      tap: function () {
+        this.owner.owner.clearAction();
+      }
+    }, {
+      kind: 'OB.UI.ModalDialogButton',
+      i18nContent: 'OBMOBC_LblCancel',
+      tap: function () {
+        this.owner.owner.cancelAction();
+      }
+    }]
+  },
+  clearAction: function () {
+    var me = this,
+        i, line = me.args.lines;
+    for (i = 0; i < line.length; i++) {
+      me.$.bodyContent.$.quotationLinesComponent.$['quotationLine' + i].$.valueAttribute.setValue(null);
+      me.$.bodyContent.$.quotationLinesComponent.$['quotationLine' + i].$.valueAttribute.addStyles('background-color: none; width: 55%');
+    }
+    me.$.bodyButtons.$.modalDialogButton.setDisabled(true);
+    return;
+  },
+  cancelAction: function () {
+    this.hide();
+    return;
+  },
+  saveAction: function () {
+    var me = this,
+        lines = me.args.lines,
+        order = me.args.quotationProductAttribute,
+        lineIndex, inpAttribute;
+    lineIndex = 0;
+    lines.forEach(function (theLine) {
+      inpAttribute = me.$.bodyContent.$.quotationLinesComponent.$['quotationLine' + lineIndex].$.valueAttribute.getValue();
+      if (inpAttribute) {
+        theLine.set('attributeValue', inpAttribute);
+        order.save();
+      }
+      lineIndex++;
+    });
+
+    me.args.quotationProductAttribute.trigger('orderCreatedFromQuotation');
+    this.hide();
+    return;
+  },
+  fieldChanged: function (inSender, inEvent) {
+    var me = this,
+        lines = me.args.lines,
+        order = me.args.quotationProductAttribute,
+        enteredAttribute, inpAttribute, lineIndex, focusIndex;
+    lineIndex = 0;
+    lines.forEach(function (theLine) {
+      enteredAttribute = false;
+      inpAttribute = me.$.bodyContent.$.quotationLinesComponent.$['quotationLine' + lineIndex].$.valueAttribute.getValue();
+      if (inpAttribute) {
+        enteredAttribute = true;
+        focusIndex = lines.length === 0 ? 0 : lineIndex + 1;
+        if (focusIndex < lines.length) {
+          me.$.bodyContent.$.quotationLinesComponent.$['quotationLine' + focusIndex].$.valueAttribute.focus();
+        }
+      } else {
+        enteredAttribute = false;
+      }
+      lineIndex++;
+    });
+    if (enteredAttribute) {
+      me.$.bodyButtons.$.modalDialogButton.setDisabled(false);
+    }
+    return true;
+  },
+  executeOnShow: function () {
+    var me = this,
+        lines = me.args.lines,
+        i;
+    me.$.header.$.headerTitle.setContent(OB.I18N.getLabel('OBPOS_QuotationProductAttributeDesc'));
+    me.$.header.$.headerTitle.addStyles('font-size: 24px');
+    i = 0;
+    me.$.bodyContent.$.quotationLinesComponent.destroyComponents();
+    lines.forEach(function (theLine) {
+      var quotationLine = me.$.bodyContent.$.quotationLinesComponent.createComponent({
+        kind: 'OB.UI.ModalQuotationProductAttributesScroller.QuotationLines',
+        name: 'quotationLine' + i
+      });
+      quotationLine.$.valueAttribute.focus();
+      quotationLine.$.productName.setContent(theLine.attributes.product.attributes._identifier);
+      i++;
+    });
+    me.$.bodyButtons.$.modalDialogButton.setDisabled(true);
+    this.$.headerCloseButton.hide();
+    me.$.bodyContent.render();
+  },
+  initComponents: function () {
+    this.inherited(arguments);
+    this.$.header.createComponent({
+      components: [{
+        name: 'headerTitle',
+        type: 'text'
+      }, {
+        name: 'documentno',
+        type: 'text'
+      }]
+    });
+  }
+});
+OB.UI.WindowView.registerPopup('OB.OBPOSPointOfSale.UI.PointOfSale', {
+  kind: 'OB.UI.ModalQuotationProductAttributes',
+  name: 'modalQuotationProductAttributes'
+});
\ No newline at end of file
diff --git a/web/org.openbravo.retail.posterminal/js/pointofsale/view/pointofsale.js b/web/org.openbravo.retail.posterminal/js/pointofsale/view/pointofsale.js
--- a/web/org.openbravo.retail.posterminal/js/pointofsale/view/pointofsale.js
+++ b/web/org.openbravo.retail.posterminal/js/pointofsale/view/pointofsale.js
@@ -257,7 +257,10 @@
     }, {
       kind: 'OB.UI.ModalProductAttributes',
       name: 'modalProductAttribute'
-    }]
+    }, {
+        kind: 'OB.UI.ModalQuotationProductAttributes',
+        name: 'modalQuotationProductAttribute'
+      }]
   }, {
     name: 'mainSubWindow',
     isMainSubWindow: true,
# HG changeset patch
# User Yogas Karnik <yogas.karnik@precognis.com>
# Date 1497002126 -7200
#      vie jun 09 11:55:26 2017 +0200
# Node ID d6af4c7a7eeabfdc21bf3fabb99b837fffdc11fe
# Parent  e1a27ce98fd8afeba6ac46eaef0492e49ba6dffc
[SupportForAttributes] Added preference to enable attributes when creating quotation and order from quotation

diff --git a/src-db/database/sourcedata/AD_REF_LIST.xml b/src-db/database/sourcedata/AD_REF_LIST.xml
--- a/src-db/database/sourcedata/AD_REF_LIST.xml
+++ b/src-db/database/sourcedata/AD_REF_LIST.xml
@@ -1317,6 +1317,17 @@
 <!--AC340E3F059542B6A207D3329644A5DB-->  <AD_MODULE_ID><![CDATA[FF808181326CC34901326D53DBCF0018]]></AD_MODULE_ID>
 <!--AC340E3F059542B6A207D3329644A5DB--></AD_REF_LIST>
 
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B--><AD_REF_LIST>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <AD_REF_LIST_ID><![CDATA[AC626DB1C31D4D90A9D0CA5DEA4A6F1B]]></AD_REF_LIST_ID>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <VALUE><![CDATA[OBPOS_EnableSupportForAttributesQuotation]]></VALUE>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <NAME><![CDATA[Web POS Enable support for product attributes in quotation]]></NAME>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B-->  <AD_MODULE_ID><![CDATA[FF808181326CC34901326D53DBCF0018]]></AD_MODULE_ID>
+<!--AC626DB1C31D4D90A9D0CA5DEA4A6F1B--></AD_REF_LIST>
+
 <!--ACEC7E55D37548C2A9DDE7668B1173AF--><AD_REF_LIST>
 <!--ACEC7E55D37548C2A9DDE7668B1173AF-->  <AD_REF_LIST_ID><![CDATA[ACEC7E55D37548C2A9DDE7668B1173AF]]></AD_REF_LIST_ID>
 <!--ACEC7E55D37548C2A9DDE7668B1173AF-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff --git a/web/org.openbravo.retail.posterminal/js/components/order.js b/web/org.openbravo.retail.posterminal/js/components/order.js
--- a/web/org.openbravo.retail.posterminal/js/components/order.js
+++ b/web/org.openbravo.retail.posterminal/js/components/order.js
@@ -639,9 +639,6 @@
         }
       }
     }, this);
-    this.order.get('lines').on('change:attributeValue', function (line) {
-      //Disable attribute component if undefined
-    }, this);
     this.order.on('change:hasbeenpaid', function (model) {
       if (model.get('isQuotation') && model.get('hasbeenpaid') === 'Y' && !model.get('obposIsDeleted') && this.$.divText.content && (this.$.divText.content === OB.I18N.getLabel('OBPOS_QuotationNew') || this.$.divText.content === OB.I18N.getLabel('OBPOS_QuotationDraft'))) {
         this.$.divText.setContent(OB.I18N.getLabel('OBPOS_QuotationUnderEvaluation'));
diff --git a/web/org.openbravo.retail.posterminal/js/components/renderorderline.js b/web/org.openbravo.retail.posterminal/js/components/renderorderline.js
--- a/web/org.openbravo.retail.posterminal/js/components/renderorderline.js
+++ b/web/org.openbravo.retail.posterminal/js/components/renderorderline.js
@@ -108,6 +108,7 @@
       this.createComponent({
         style: 'display: block;',
         components: [{
+          name: 'productAttribute',
           content: OB.I18N.getLabel('OBPOS_AttributeValue') + this.model.get('attributeValue'),
           attributes: {
             style: 'float: left; width: 100%; clear: left;'
@@ -116,7 +117,11 @@
           style: 'clear: both;'
         }]
       });
+      if (!this.model.get('attributeValue')) {
+        this.$.productAttribute.hide();
+      }
     }
+
     if (this.model.get('product').get('characteristicDescription')) {
       this.createComponent({
         style: 'display: block; ',
diff --git a/web/org.openbravo.retail.posterminal/js/model/order.js b/web/org.openbravo.retail.posterminal/js/model/order.js
--- a/web/org.openbravo.retail.posterminal/js/model/order.js
+++ b/web/org.openbravo.retail.posterminal/js/model/order.js
@@ -1524,7 +1524,8 @@
           me = this,
           productHavingSameAttribute = false,
           productHasAttribute = p.attributes.hasAttributes,
-          attributeSearchAllowed = OB.MobileApp.model.hasPermission('OBPOS_EnableSupportForProductAttributes', true);
+          attributeSearchAllowed = OB.MobileApp.model.hasPermission('OBPOS_EnableSupportForProductAttributes', true),
+          isQuotationAndAttributeAllowed = me.attributes.isQuotation && OB.MobileApp.model.hasPermission('OBPOS_AskForAttributesWhenQuotationToSalesOrder', true);
       if (enyo.Panels.isScreenNarrow()) {
         OB.UTIL.showSuccess(OB.I18N.getLabel('OBPOS_AddLine', [qty ? qty : 1, p.get('_identifier')]));
       }
@@ -1539,7 +1540,7 @@
             if (attrs && (currentline.attributeValue === attrs.attributeValue) && (p.id === currentline.product.id)) {
               productHavingSameAttribute = true;
               line = currentline;
-              if (p.get('isSerialNo')) {
+              if (p.get('isSerialNo') || (p.get('isSerialNo') && isQuotationAndAttributeAllowed)) {
                 OB.UTIL.showConfirmation.display(OB.I18N.getLabel('OBMOBC_Error'), OB.I18N.getLabel('OBPOS_ProductDefinedAsSerialNo'));
                 if (callback) {
                   callback(false, null);
@@ -1920,7 +1921,8 @@
     },
 
     addProductToOrder: function (p, qty, options, attrs, callback) {
-      var me = this;
+      var me = this,
+          attributeSearchAllowed = OB.MobileApp.model.hasPermission('OBPOS_EnableSupportForProductAttributes', true);
       OB.UTIL.HookManager.executeHooks('OBPOS_AddProductToOrder', {
         receipt: this,
         productToAdd: p,
@@ -1969,7 +1971,8 @@
           }
           return;
         }
-        if ((!args || !args.options || !args.options.line) && OB.MobileApp.model.hasPermission('OBPOS_EnableSupportForProductAttributes', true) && p.get('hasAttributes') && qty >= 1) {
+        var isQuotationAndAttributeAllowed = args.receipt.attributes.isQuotation && OB.MobileApp.model.hasPermission('OBPOS_AskForAttributesWhenQuotationToSalesOrder', true);
+        if ((!args || !args.options || !args.options.line) && attributeSearchAllowed && p.get('hasAttributes') && qty >= 1 && (!args.receipt.attributes.isQuotation || isQuotationAndAttributeAllowed)) {
           OB.MobileApp.view.waterfall('onShowPopup', {
             popup: 'modalProductAttribute',
             args: {
@@ -2964,7 +2967,11 @@
     createOrderFromQuotation: function (updatePrices) {
       var idMap = {},
           oldIdMap = {},
-          oldId, me = this;
+          oldId, me = this,
+          productHasAttribute = false,
+          productWithAttributeValue = [],
+          needAttributeForOrder = OB.MobileApp.model.hasPermission('OBPOS_AskForAttributesWhenQuotationToSalesOrder', true),
+          attributeSearchAllowed = OB.MobileApp.model.hasPermission('OBPOS_EnableSupportForProductAttributes', true);
       this.get('lines').each(function (line) {
         oldId = line.get('id');
         line.set('id', OB.UTIL.get_UUID());
@@ -3038,16 +3045,14 @@
         }
       }, this);
 
-      var productHasAttribute = false,
-          productWithAttributeValue = [];
       this.get('lines').each(function (theLine) {
         var productAttributes = theLine.attributes.product.attributes;
-        if (OB.UTIL.isNullOrUndefined(productAttributes.hasAttributes) === false) {
+        if (OB.UTIL.isNullOrUndefined(productAttributes.hasAttributes) === false && productAttributes.hasAttributes) {
           productWithAttributeValue.push(theLine);
           productHasAttribute = productAttributes.hasAttributes;
         }
       });
-      if (!productHasAttribute) {
+      if (!productHasAttribute && !needAttributeForOrder) {
         if (updatePrices) {
           this.updatePrices(function (order) {
             order.calculateReceipt(function () {
@@ -3067,7 +3072,7 @@
       }
       this.calculateReceipt();
       //call quotation attributes popup
-      if (OB.MobileApp.model.hasPermission('OBPOS_EnableSupportForProductAttributes', true) && productHasAttribute) {
+      if (attributeSearchAllowed && !productHasAttribute && needAttributeForOrder) {
         OB.MobileApp.view.waterfall('onShowPopup', {
           popup: 'modalQuotationProductAttributes',
           args: {
diff --git a/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js b/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
--- a/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
+++ b/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
@@ -160,9 +160,6 @@
       components: [{
         name: 'headerTitle',
         type: 'text'
-      }, {
-        name: 'documentno',
-        type: 'text'
       }]
     });
   }
# HG changeset patch
# User Yogas Karnik <yogas.karnik@precognis.com>
# Date 1497954098 -7200
#      mar jun 20 12:21:38 2017 +0200
# Node ID 281856aa0bc27dfb65ca2fd137742c56cb781ce1
# Parent  d6af4c7a7eeabfdc21bf3fabb99b837fffdc11fe
[SupportForAttributes] Delete order when cancel button in pressed in quotation attribute modal

diff --git a/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js b/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
--- a/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
+++ b/web/org.openbravo.retail.posterminal/js/pointofsale/view/modals/modalquotationproductattribute.js
@@ -86,6 +86,10 @@
     return;
   },
   cancelAction: function () {
+    var me = this,
+        lines = me.args.lines,
+        order = me.args.quotationProductAttribute;
+    order.deleteOrder(lines);
     this.hide();
     return;
   },
# HG changeset patch
# User Yogas Karnik <yogas.karnik@precognis.com>
# Date 1497954184 -7200
#      mar jun 20 12:23:04 2017 +0200
# Node ID 47b508e925773cacfaacb0927982a1d42c0f8f76
# Parent  281856aa0bc27dfb65ca2fd137742c56cb781ce1
[SupportForAttributes] Bug fix, if the attribute search preference not enabled the product having attribute not adding unit

diff --git a/web/org.openbravo.retail.posterminal/js/model/order.js b/web/org.openbravo.retail.posterminal/js/model/order.js
--- a/web/org.openbravo.retail.posterminal/js/model/order.js
+++ b/web/org.openbravo.retail.posterminal/js/model/order.js
@@ -1620,8 +1620,8 @@
               }
               var splitline = !(options && options.line) && !OB.UTIL.isNullOrUndefined(args.line) && !OB.UTIL.isNullOrUndefined(args.line.get('splitline')) && args.line.get('splitline');
               var serviceProduct = args.line && (qty !== 1 || args.line.get('qty') !== -1 || args.p.get('productType') !== 'S' || (args.p.get('productType') === 'S' && !args.p.get('isLinkedToProduct')));
-              var groupedByAttributeValues = (productHasAttribute && productHavingSameAttribute) || (!productHasAttribute && !productHavingSameAttribute);
-              if (args.line && !splitline && (args.line.get('qty') > 0 || !args.line.get('replacedorderline')) && (serviceProduct) && groupedByAttributeValues) {
+              var groupedByAttributeValues = ((productHasAttribute && productHavingSameAttribute) || (!productHasAttribute && !productHavingSameAttribute)) && attributeSearchAllowed;
+              if (args.line && !splitline && (args.line.get('qty') > 0 || !args.line.get('replacedorderline')) && (serviceProduct) && (groupedByAttributeValues || !groupedByAttributeValues)) {
                 args.receipt.addUnit(args.line, args.qty);
                 if (!_.isUndefined(args.attrs)) {
                   _.each(_.keys(args.attrs), function (key) {
@@ -3052,7 +3052,7 @@
           productHasAttribute = productAttributes.hasAttributes;
         }
       });
-      if (!productHasAttribute && !needAttributeForOrder) {
+      if (productHasAttribute === false && needAttributeForOrder === false) {
         if (updatePrices) {
           this.updatePrices(function (order) {
             order.calculateReceipt(function () {
@@ -3072,7 +3072,7 @@
       }
       this.calculateReceipt();
       //call quotation attributes popup
-      if (attributeSearchAllowed && !productHasAttribute && needAttributeForOrder) {
+      if (attributeSearchAllowed && needAttributeForOrder === false && productHasAttribute) {
         OB.MobileApp.view.waterfall('onShowPopup', {
           popup: 'modalQuotationProductAttributes',
           args: {

