<NME> option_value_namer.js.coffee
<BEF> ADDFILE
<MSG> Adding dynamic text to display as placeholder

<DFF> @@ -0,0 +1,66 @@
+angular.module("ofn.admin").factory "optionValueNamer", ($resource) ->
+  class OptionValueNamer
+    constructor: (@variant) ->
+
+    name: ->
+      [value, unit] = @option_value_value_unit()
+      separator = if @value_scaled() then '' else ' '
+
+      name_fields = []
+      name_fields.push "#{value}#{separator}#{unit}" if value? && unit?
+      name_fields.push @variant.unit_description if @variant.unit_description?
+      name_fields.join ' '
+
+    value_scaled: ->
+      @variant.product.variant_unit_scale?
+
+    option_value_value_unit: ->
+      if @variant.unit_value?
+        if @variant.product.variant_unit in ["weight", "volume"]
+          [value, unit_name] = @option_value_value_unit_scaled()
+    
+        else
+          value = @variant.unit_value
+          unit_name = @variant.product.variant_unit_name
+          # TODO needs to add pluralize to line below
+          # unit_name = unit_name if value > 1
+    
+        value = parseInt(value, 10) if value == parseInt(value, 10)
+    
+      else
+        value = unit_name = null
+    
+      [value, unit_name]
+
+    option_value_value_unit_scaled: ->
+      [unit_scale, unit_name] = @scale_for_unit_value()
+
+      value = @variant.unit_value / unit_scale
+
+      [value, unit_name]
+
+    scale_for_unit_value: ->
+      units = 
+        'weight':
+          1.0: 'g'
+          1000.0: 'kg'
+          1000000.0: 'T'
+        'volume':
+          0.001: 'mL'
+          1.0: 'L'
+          1000000.0: 'ML'
+
+      # Find the largest available unit where unit_value comes to >= 1 when expressed in it.
+      # If there is none available where this is true, use the smallest available unit.
+      unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit] when @variant.unit_value / scale >= 1).reduce (unit, [scale, unit_name]) ->
+        if (unit && scale > unit[0]) || !unit?
+          [scale, unit_name]
+        else
+          unit
+      , null
+      if !unit?
+        unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit]).reduce (unit, [scale, unit_name]) ->
+          if scale < unit[0] then [scale, unit_name] else unit
+        , [Infinity,""]
+
+      unit
\ No newline at end of file

{'commit': 'diff --git a/app/assets/javascripts/admin/controllers/variant_units_controller.js.coffee b/app/assets/javascripts/admin/controllers/variant_units_controller.js.coffee\nnew file mode 100644\nindex 000000000..41d87113a\n--- /dev/null\n+++ b/app/assets/javascripts/admin/controllers/variant_units_controller.js.coffee\n@@ -0,0 +1,42 @@\n+angular.module("ofn.admin")\n+  .controller "VariantUnitsCtrl", ($scope, optionValueNamer) ->\n+    $scope.$watchCollection \'[variant.unit_value_with_description, product.variant_unit_name, product.variant_unit_with_scale]\', ->\n+      [variant_unit, variant_unit_scale] = $scope.productUnitProperties()\n+      [unit_value, unit_description] = $scope.variantUnitProperties(variant_unit_scale)\n+      variant_object = \n+        unit_value: unit_value\n+        unit_description: unit_description\n+        product:\n+          variant_unit_scale: variant_unit_scale\n+          variant_unit: variant_unit\n+          variant_unit_name: $scope.product.variant_unit_name\n+        \n+      $scope.variant.options_text = new optionValueNamer(variant_object).name()\n+\n+    $scope.productUnitProperties = ->\n+      # get relevant product properties\n+      if $scope.product.variant_unit_with_scale\n+        match = $scope.product.variant_unit_with_scale.match(/^([^_]+)_([\\d\\.]+)$/)\n+        if match\n+          variant_unit = match[1]\n+          variant_unit_scale = parseFloat(match[2])\n+        else\n+          variant_unit = $scope.product.variant_unit_with_scale\n+          variant_unit_scale = null\n+      else\n+        variant_unit = variant_unit_scale = null\n+\n+      [variant_unit, variant_unit_scale]\n+\n+    $scope.variantUnitProperties = (variant_unit_scale)->\n+      # get relevant variant properties\n+      if $scope.variant.hasOwnProperty("unit_value_with_description")\n+        match = $scope.variant.unit_value_with_description.match(/^([\\d\\.]+(?= |$)|)( |)(.*)$/)\n+        if match\n+          unit_value  = parseFloat(match[1])\n+          unit_value  = null if isNaN(unit_value)\n+          unit_value *= variant_unit_scale if unit_value && variant_unit_scale\n+          unit_description = match[3]\n+      [unit_value, unit_description]\n+      \n+        \n\\ No newline at end of file\ndiff --git a/app/assets/javascripts/admin/services/option_value_namer.js.coffee b/app/assets/javascripts/admin/services/option_value_namer.js.coffee\nnew file mode 100644\nindex 000000000..8d127f01c\n--- /dev/null\n+++ b/app/assets/javascripts/admin/services/option_value_namer.js.coffee\n@@ -0,0 +1,66 @@\n+angular.module("ofn.admin").factory "optionValueNamer", ($resource) ->\n+  class OptionValueNamer\n+    constructor: (@variant) ->\n+\n+    name: ->\n+      [value, unit] = @option_value_value_unit()\n+      separator = if @value_scaled() then \'\' else \' \'\n+\n+      name_fields = []\n+      name_fields.push "#{value}#{separator}#{unit}" if value? && unit?\n+      name_fields.push @variant.unit_description if @variant.unit_description?\n+      name_fields.join \' \'\n+\n+    value_scaled: ->\n+      @variant.product.variant_unit_scale?\n+\n+    option_value_value_unit: ->\n+      if @variant.unit_value?\n+        if @variant.product.variant_unit in ["weight", "volume"]\n+          [value, unit_name] = @option_value_value_unit_scaled()\n+    \n+        else\n+          value = @variant.unit_value\n+          unit_name = @variant.product.variant_unit_name\n+          # TODO needs to add pluralize to line below\n+          # unit_name = unit_name if value > 1\n+    \n+        value = parseInt(value, 10) if value == parseInt(value, 10)\n+    \n+      else\n+        value = unit_name = null\n+    \n+      [value, unit_name]\n+\n+    option_value_value_unit_scaled: ->\n+      [unit_scale, unit_name] = @scale_for_unit_value()\n+\n+      value = @variant.unit_value / unit_scale\n+\n+      [value, unit_name]\n+\n+    scale_for_unit_value: ->\n+      units = \n+        \'weight\':\n+          1.0: \'g\'\n+          1000.0: \'kg\'\n+          1000000.0: \'T\'\n+        \'volume\':\n+          0.001: \'mL\'\n+          1.0: \'L\'\n+          1000000.0: \'ML\'\n+\n+      # Find the largest available unit where unit_value comes to >= 1 when expressed in it.\n+      # If there is none available where this is true, use the smallest available unit.\n+      unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit] when @variant.unit_value / scale >= 1).reduce (unit, [scale, unit_name]) ->\n+        if (unit && scale > unit[0]) || !unit?\n+          [scale, unit_name]\n+        else\n+          unit\n+      , null\n+      if !unit?\n+        unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit]).reduce (unit, [scale, unit_name]) ->\n+          if scale < unit[0] then [scale, unit_name] else unit\n+        , [Infinity,""]\n+\n+      unit\n\\ No newline at end of file\ndiff --git a/app/views/spree/admin/products/bulk_edit.html.haml b/app/views/spree/admin/products/bulk_edit.html.haml\nindex 8d943adb8..2b636af09 100644\n--- a/app/views/spree/admin/products/bulk_edit.html.haml\n+++ b/app/views/spree/admin/products/bulk_edit.html.haml\n@@ -155,7 +155,7 @@\n             %input{ \'ng-model\' => \'variant.display_name\', :name => \'variant_display_name\', \'ofn-track-variant\' => \'display_name\', :type => \'text\', placeholder: "{{ product.name }}" }\n           %td.unit_value{ \'ng-show\' => \'columns.unit.visible\' }\n             %input{ \'ng-model\' => \'variant.unit_value_with_description\', :name => \'variant_unit_value_with_description\', \'ofn-track-variant\' => \'unit_value_with_description\', :type => \'text\' }\n-          %td.display_as{ \'ng-show\' => \'columns.unit.visible\' }\n+          %td.display_as{ \'ng-show\' => \'columns.unit.visible\', \'ng-controller\' => "VariantUnitsCtrl" }\n             %input{ \'ng-model\' => \'variant.display_as\', :name => \'variant_display_as\', \'ofn-track-variant\' => \'display_as\', :type => \'text\', placeholder: "{{ variant.options_text }}" }\n           %td{ \'ng-show\' => \'columns.price.visible\' }\n             %input{ \'ng-model\' => \'variant.price\', \'ofn-decimal\' => :true, :name => \'variant_price\', \'ofn-track-variant\' => \'price\', :type => \'text\' }\n', 'commit_subject': 'Adding dynamic text to display as placeholder', 'repo_name': 'openfoodfoundation/openfoodnetwork', 'committer': {'name': 'Will Marshall', 'email': '37d41699bdee4fcb969ca499eb0f8b82c60d59cc@willmarshall.me', 'time_sec': '1402537794', 'tz_offset': '600', 'date': {'seconds': '1402537794'}}, 'commit_tree': '13d99b1ff7bfbc400245652a5a66da6a0068c593', 'commit_message': 'Adding dynamic text to display as placeholder\n', 'language_name': 'Shell', 'license': 'agpl-3.0', 'hunks': '@@ -0,0 +1,66 @@\n+angular.module("ofn.admin").factory "optionValueNamer", ($resource) ->\n+  class OptionValueNamer\n+    constructor: (@variant) ->\n+\n+    name: ->\n+      [value, unit] = @option_value_value_unit()\n+      separator = if @value_scaled() then \'\' else \' \'\n+\n+      name_fields = []\n+      name_fields.push "#{value}#{separator}#{unit}" if value? && unit?\n+      name_fields.push @variant.unit_description if @variant.unit_description?\n+      name_fields.join \' \'\n+\n+    value_scaled: ->\n+      @variant.product.variant_unit_scale?\n+\n+    option_value_value_unit: ->\n+      if @variant.unit_value?\n+        if @variant.product.variant_unit in ["weight", "volume"]\n+          [value, unit_name] = @option_value_value_unit_scaled()\n+    \n+        else\n+          value = @variant.unit_value\n+          unit_name = @variant.product.variant_unit_name\n+          # TODO needs to add pluralize to line below\n+          # unit_name = unit_name if value > 1\n+    \n+        value = parseInt(value, 10) if value == parseInt(value, 10)\n+    \n+      else\n+        value = unit_name = null\n+    \n+      [value, unit_name]\n+\n+    option_value_value_unit_scaled: ->\n+      [unit_scale, unit_name] = @scale_for_unit_value()\n+\n+      value = @variant.unit_value / unit_scale\n+\n+      [value, unit_name]\n+\n+    scale_for_unit_value: ->\n+      units = \n+        \'weight\':\n+          1.0: \'g\'\n+          1000.0: \'kg\'\n+          1000000.0: \'T\'\n+        \'volume\':\n+          0.001: \'mL\'\n+          1.0: \'L\'\n+          1000000.0: \'ML\'\n+\n+      # Find the largest available unit where unit_value comes to >= 1 when expressed in it.\n+      # If there is none available where this is true, use the smallest available unit.\n+      unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit] when @variant.unit_value / scale >= 1).reduce (unit, [scale, unit_name]) ->\n+        if (unit && scale > unit[0]) || !unit?\n+          [scale, unit_name]\n+        else\n+          unit\n+      , null\n+      if !unit?\n+        unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit]).reduce (unit, [scale, unit_name]) ->\n+          if scale < unit[0] then [scale, unit_name] else unit\n+        , [Infinity,""]\n+\n+      unit\n\\ No newline at end of file\n', 'addition_count': 66, 'deletion_count': 0, 'src_file': '/dev/null', 'tgt_file': 'b/app/assets/javascripts/admin/services/option_value_namer.js.coffee', 'file_extension': '.coffee', 'before_file': 'ADDFILE', 'message': 'Adding dynamic text to display as placeholder\n', 'author_name': 'Will Marshall', 'lang': 'js'}