Module: Models::ItemSpecificationHelper
- Extended by:
- ActiveSupport::Concern
- Includes:
- Memery
- Included in:
- Item
- Defined in:
- app/concerns/models/item_specification_helper.rb
Instance Method Summary collapse
- #amps ⇒ Object
- #amps=(val) ⇒ Object
- #amps_static? ⇒ Boolean
- #area(output_unit: :sqft) ⇒ Object
- #aspect ⇒ Object
- #btu_per_hour ⇒ Object
- #calculate_amps(precision: 2) ⇒ Object
- #calculate_coverage_for_membrane(output_unit: :sqft) ⇒ Object
- #calculate_geometric_sqft ⇒ Object
-
#calculate_heated_area_for_panels(output_unit: :sqft) ⇒ Object
Calculates the coverage area for a radiant panel based on the watts, output_unit can be :sqm for square meters.
- #calculate_heated_area_sqft_for_panels ⇒ Object
- #calculate_heated_area_sqm_for_panels ⇒ Object
- #calculate_kilowatts(precision: 2) ⇒ Object
- #calculate_number_of_fixing_strips_at_3_in ⇒ Object
- #calculate_number_of_fixing_strips_at_4_in ⇒ Object
- #calculate_number_of_fixing_strips_at_5_in ⇒ Object
- #calculate_number_of_fixing_strips_at_cable_spacing(spacing_in_inches = 4) ⇒ Object
- #calculate_ohms(precision: 2) ⇒ Object
- #calculate_ohms_per_ft ⇒ Object
- #calculate_size_2d(output_unit: nil, precision: nil) ⇒ Object
- #calculate_size_2d_ft ⇒ Object
- #calculate_size_2d_in ⇒ Object
- #calculate_size_2d_metric_cm ⇒ Object
- #calculate_size_2d_metric_mm ⇒ Object
- #calculate_size_3d(output_unit: nil, precision: nil) ⇒ Object
- #calculate_size_3d_ft ⇒ Object
- #calculate_size_3d_in ⇒ Object
- #calculate_size_3d_metric_cm ⇒ Object
- #calculate_size_3d_metric_mm ⇒ Object
- #calculate_sqft(cable_spacing: nil, heated_area: true) ⇒ Object
-
#calculate_thermal_power_per_hour ⇒ Object
This is like btu per hour but kW.
-
#calculate_volts(precision: 0) ⇒ Object
The voltage V in volts (V) is equal to the current I in amps (A) times the resistance R in ohms (Ω):.
-
#calculate_watts(precision: 0) ⇒ Object
The power P in watts (W) is equal to the voltage V in volts (V) times the current I in amps (A):.
- #calculate_watts_per_sqft(precision: 2) ⇒ Object
- #can_use_amps_for_calculation? ⇒ Boolean
- #can_use_ohms_for_calculation? ⇒ Boolean
- #can_use_voltage_for_calculation? ⇒ Boolean
- #can_use_watts_for_calculation? ⇒ Boolean
- #cold_lead_length ⇒ Object
- #cold_lead_length=(val) ⇒ Object
- #control_capacity ⇒ Object
- #coverage_at_3_5_in ⇒ Object
- #coverage_at_3_75_in ⇒ Object
- #coverage_at_3_in ⇒ Object
- #coverage_at_4_5_in ⇒ Object
- #coverage_at_4_in ⇒ Object
- #coverage_at_5_in ⇒ Object
- #coverage_formatted ⇒ Object
- #create_or_set_spec_value(grouping:, text_blurb:, token: nil, name: nil, method: 'text', units: nil, visibility: 'open_visibility', locale: nil, skip_spec_refresh: false, link_to_product_line: false) ⇒ Object
- #finish ⇒ Object
- #has_spec?(token) ⇒ Boolean
- #is_dual_voltage? ⇒ Boolean
- #length(output_unit: :in) ⇒ Object
- #length=(val, unit: :in) ⇒ Object
- #length_formatted ⇒ Object
-
#linear_ft ⇒ Object
memoize :calculate_sqft.
- #maximum_current ⇒ Object
- #num_poles ⇒ Object
- #ohms ⇒ Object
- #ohms=(val) ⇒ Object
- #ohms_law_calculator ⇒ Object
- #ohms_static? ⇒ Boolean
- #plan_grouping ⇒ Object
- #plan_grouping=(val) ⇒ Object
-
#set_spec_value(token, value) ⇒ Object
Finds a direct product spec and sets the value.
-
#spec(token) ⇒ Object
Retrieves a spec from the rendered product specification Performs a little bit of value casting on the raw output before returning.
- #spec_image(token) ⇒ Object
-
#spec_output(token, locale: Mobility.locale) ⇒ Object
returns the formatted output from the spec.
- #spec_refresh_in_progress ⇒ Object
- #spec_unit(token) ⇒ Object
-
#spec_value(token, output_unit: nil, precision: nil) ⇒ Object
returns the raw value from the spec.
- #specs_for_identifier_label ⇒ Object
- #sqft ⇒ Object
- #sqft=(val) ⇒ Object
-
#token_specs_values_for_liquid(include_legacy: false) ⇒ Object
Renders a hash with a token spec value (possibly in multiple dimensions) and its value.
- #voltage ⇒ Object
- #voltage=(val) ⇒ Object
- #voltage_formatted ⇒ Object
- #voltage_static? ⇒ Boolean
- #volts ⇒ Object
- #volts=(val) ⇒ Object
- #vop ⇒ Object
- #watts ⇒ Object
- #watts=(val) ⇒ Object
- #watts_formatted ⇒ Object
- #watts_per_linear_feet(precision: 2) ⇒ Object
- #watts_per_sqft ⇒ Object
- #watts_per_sqft_at_3_5_in_spacing ⇒ Object
- #watts_per_sqft_at_3_75_in_spacing ⇒ Object
- #watts_per_sqft_at_3_in_spacing ⇒ Object
- #watts_per_sqft_at_4_5_in_spacing ⇒ Object
- #watts_per_sqft_at_4_in_spacing ⇒ Object
- #watts_per_sqft_at_5_in_spacing ⇒ Object
- #watts_static? ⇒ Boolean
- #width(output_unit: :in) ⇒ Object
- #width=(val, unit: :in) ⇒ Object
- #width_by_length_text ⇒ Object
- #width_by_length_text_2 ⇒ Object
-
#width_by_length_text_3 ⇒ Object
For larger rolls.
- #width_formatted ⇒ Object
Instance Method Details
#amps ⇒ Object
379 380 381 382 |
# File 'app/concerns/models/item_specification_helper.rb', line 379 def amps a = spec_value(:amps) a.is_a?(Numeric) ? a : nil end |
#amps=(val) ⇒ Object
384 385 386 |
# File 'app/concerns/models/item_specification_helper.rb', line 384 def amps=(val) create_or_set_spec_value(token: :amps, name: 'Amps', units: 'A', grouping: 'Electrical', text_blurb: val) end |
#amps_static? ⇒ Boolean
516 517 518 |
# File 'app/concerns/models/item_specification_helper.rb', line 516 def amps_static? rendered_product_specifications.dig(:amps, :static).to_b end |
#area(output_unit: :sqft) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 |
# File 'app/concerns/models/item_specification_helper.rb', line 218 def area(output_unit: :sqft) v = spec_value(:coverage, output_unit:) v ||= spec_value(:sqft, output_unit: :output_unit) if v.nil? && length.present? && width.present? cv = (length(output_unit: :in) * width(output_unit: :in)) cvunit = RubyUnits::Unit.new("#{cv} sqin") v = cvunit.convert_to(output_unit.to_s).scalar.to_f end v end |
#aspect ⇒ Object
651 652 653 654 655 656 657 658 659 660 661 |
# File 'app/concerns/models/item_specification_helper.rb', line 651 def aspect return unless (height = spec_value(:height)).present? && (width == spec_value(:width)).present? if height.to_i == width.to_i 'Vertical / Horizontal' elsif height.to_i > width.to_i 'Vertical' else 'Horizontal' end end |
#btu_per_hour ⇒ Object
548 549 550 551 552 553 554 555 556 |
# File 'app/concerns/models/item_specification_helper.rb', line 548 def btu_per_hour return unless (w = watts.presence) return unless w.to_f.positive? # If we have a thermal efficiency we will use it to calculate or assume 100 efficiency = spec_value(:thermal_output_efficiency)&.to_f || 100.0 # Apply the BTU conversion (w.to_f * (efficiency / 100.0) * RoomConfiguration::BTU_PER_HOUR_PER_WATT).round end |
#calculate_amps(precision: 2) ⇒ Object
407 408 409 |
# File 'app/concerns/models/item_specification_helper.rb', line 407 def calculate_amps(precision: 2) ohms_law_calculator.current&.round(precision) end |
#calculate_coverage_for_membrane(output_unit: :sqft) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'app/concerns/models/item_specification_helper.rb', line 204 def calculate_coverage_for_membrane(output_unit: :sqft) coverage = 0.0 if is_membrane? coverage = spec_value(:coverage, output_unit:) elsif is_kit? kit_target_item_relations.includes(:target_item).each do |tir| next if tir.target_item.nil? || !tir.target_item.is_membrane? coverage += tir.target_item.spec_value(:coverage, output_unit:) * tir.quantity end end coverage&.positive? ? coverage.round(2) : nil end |
#calculate_geometric_sqft ⇒ Object
583 584 585 |
# File 'app/concerns/models/item_specification_helper.rb', line 583 def calculate_geometric_sqft calculate_sqft(heated_area: false) end |
#calculate_heated_area_for_panels(output_unit: :sqft) ⇒ Object
Calculates the coverage area for a radiant panel based on the watts, output_unit can be :sqm for square meters.
185 186 187 188 189 190 191 192 193 194 |
# File 'app/concerns/models/item_specification_helper.rb', line 185 def calculate_heated_area_for_panels(output_unit: :sqft) return unless (w = watts).present? return unless is_radiant_panel? coverage_panel_in_sq_ft = (w.to_f / 7).ceil return coverage_panel_in_sq_ft if output_unit == :sqft coverage_unitized = "#{coverage_panel_in_sq_ft} sqft" RubyUnits::Unit.new(coverage_unitized).convert_to(output_unit.to_s).scalar.to_f.round end |
#calculate_heated_area_sqft_for_panels ⇒ Object
196 197 198 |
# File 'app/concerns/models/item_specification_helper.rb', line 196 def calculate_heated_area_sqft_for_panels calculate_heated_area_for_panels(output_unit: :sqft) end |
#calculate_heated_area_sqm_for_panels ⇒ Object
200 201 202 |
# File 'app/concerns/models/item_specification_helper.rb', line 200 def calculate_heated_area_sqm_for_panels calculate_heated_area_for_panels(output_unit: :sqm) end |
#calculate_kilowatts(precision: 2) ⇒ Object
474 475 476 477 478 |
# File 'app/concerns/models/item_specification_helper.rb', line 474 def calculate_kilowatts(precision: 2) return unless (w = watts || calculate_watts) (w.to_f / 1000).round(precision) end |
#calculate_number_of_fixing_strips_at_3_in ⇒ Object
287 288 289 |
# File 'app/concerns/models/item_specification_helper.rb', line 287 def calculate_number_of_fixing_strips_at_3_in calculate_number_of_fixing_strips_at_cable_spacing(3) end |
#calculate_number_of_fixing_strips_at_4_in ⇒ Object
291 292 293 |
# File 'app/concerns/models/item_specification_helper.rb', line 291 def calculate_number_of_fixing_strips_at_4_in calculate_number_of_fixing_strips_at_cable_spacing(4) end |
#calculate_number_of_fixing_strips_at_5_in ⇒ Object
295 296 297 |
# File 'app/concerns/models/item_specification_helper.rb', line 295 def calculate_number_of_fixing_strips_at_5_in calculate_number_of_fixing_strips_at_cable_spacing(5) end |
#calculate_number_of_fixing_strips_at_cable_spacing(spacing_in_inches = 4) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'app/concerns/models/item_specification_helper.rb', line 274 def calculate_number_of_fixing_strips_at_cable_spacing(spacing_in_inches = 4) return unless (cable_length = linear_ft) coefficients = { 3 => 0.1875, 4 => 0.225, 5 => 0.3125 } raise "Invalid spacing #{spacing_in_inches}, must be #{coefficients.keys.join(', ')}" unless spacing_in_inches.in?(coefficients.keys) coefficient = coefficients[spacing_in_inches] qty_fixing_strips = ((cable_length * coefficient) + 6) qty_fixing_strips = (qty_fixing_strips / 10).ceil * 10 # minimum 30 [30, qty_fixing_strips].max end |
#calculate_ohms(precision: 2) ⇒ Object
488 489 490 |
# File 'app/concerns/models/item_specification_helper.rb', line 488 def calculate_ohms(precision: 2) ohms_law_calculator.resistance&.round(precision) end |
#calculate_ohms_per_ft ⇒ Object
480 481 482 483 484 485 486 |
# File 'app/concerns/models/item_specification_helper.rb', line 480 def calculate_ohms_per_ft l = spec_value(:heating_cable_length, output_unit: 'ft') || spec_value(:length, output_unit: 'ft') o = ohms return unless o.is_a?(Numeric) && l.is_a?(Numeric) && o.positive? && l.positive? (o.to_f / l).round(3) end |
#calculate_size_2d(output_unit: nil, precision: nil) ⇒ Object
421 422 423 424 425 426 427 428 429 |
# File 'app/concerns/models/item_specification_helper.rb', line 421 def calculate_size_2d(output_unit: nil, precision: nil) output_unit ||= spec_unit(:width) precision ||= { mm: 0, in: 1, m: 2, ft: 2 }[output_unit&.to_sym] s = [ spec_value(:width, output_unit:, precision:), spec_value(:length, output_unit:, precision:) || spec_value(:height, output_unit:, precision:) ].join(' x ') "#{s} #{output_unit}" end |
#calculate_size_2d_ft ⇒ Object
462 463 464 |
# File 'app/concerns/models/item_specification_helper.rb', line 462 def calculate_size_2d_ft calculate_size_2d(output_unit: 'ft', precision: 2) end |
#calculate_size_2d_in ⇒ Object
458 459 460 |
# File 'app/concerns/models/item_specification_helper.rb', line 458 def calculate_size_2d_in calculate_size_2d(output_unit: 'in', precision: 0) end |
#calculate_size_2d_metric_cm ⇒ Object
470 471 472 |
# File 'app/concerns/models/item_specification_helper.rb', line 470 def calculate_size_2d_metric_cm calculate_size_2d(output_unit: 'cm', precision: 0) end |
#calculate_size_2d_metric_mm ⇒ Object
466 467 468 |
# File 'app/concerns/models/item_specification_helper.rb', line 466 def calculate_size_2d_metric_mm calculate_size_2d(output_unit: 'mm', precision: 0) end |
#calculate_size_3d(output_unit: nil, precision: nil) ⇒ Object
431 432 433 434 435 436 437 438 439 440 |
# File 'app/concerns/models/item_specification_helper.rb', line 431 def calculate_size_3d(output_unit: nil, precision: nil) output_unit ||= spec_unit(:width) precision ||= { mm: 0, in: 1, m: 2, ft: 2 }[output_unit&.to_sym] s = [ spec_value(:width, output_unit:, precision:), spec_value(:length, output_unit:, precision:) || spec_value(:height, output_unit:, precision:), spec_value(:depth, output_unit:, precision:) ].join(' x ') "#{s} #{output_unit}" end |
#calculate_size_3d_ft ⇒ Object
454 455 456 |
# File 'app/concerns/models/item_specification_helper.rb', line 454 def calculate_size_3d_ft calculate_size_3d(output_unit: 'ft', precision: 2) end |
#calculate_size_3d_in ⇒ Object
450 451 452 |
# File 'app/concerns/models/item_specification_helper.rb', line 450 def calculate_size_3d_in calculate_size_3d(output_unit: 'in', precision: 0) end |
#calculate_size_3d_metric_cm ⇒ Object
446 447 448 |
# File 'app/concerns/models/item_specification_helper.rb', line 446 def calculate_size_3d_metric_cm calculate_size_3d(output_unit: 'cm', precision: 0) end |
#calculate_size_3d_metric_mm ⇒ Object
442 443 444 |
# File 'app/concerns/models/item_specification_helper.rb', line 442 def calculate_size_3d_metric_mm calculate_size_3d(output_unit: 'mm', precision: 0) end |
#calculate_sqft(cable_spacing: nil, heated_area: true) ⇒ Object
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 |
# File 'app/concerns/models/item_specification_helper.rb', line 587 def calculate_sqft(cable_spacing: nil, heated_area: true) calculated_area = nil effective_width = BigDecimal(width, 2) if width effective_length = BigDecimal(length, 2) if length if effective_length && effective_length.positive? case product_category.surface_calculation_method when 'standard' if effective_width && effective_width.positive? if (is_slab_heat_mat? || is_snow_melting_mat?) && heated_area # Apply padding rule of 3" (1.5" per side bleed out for heat) effective_width += 3.0 end calculated_area = (effective_length * effective_width / 144.0) if effective_width.positive? end when 'cable_spacing' cable_spacing = calculate_ideal_cable_spacing unless cable_spacing && (cable_spacing > 0.0) effective_width = (cable_spacing || effective_width).to_f calculated_area = (effective_length * effective_width / 144.0) if effective_width.positive? end end static_area = rendered_product_specifications.dig(:coverage, :raw) if rendered_product_specifications.dig(:coverage, :static).to_b effective_area = calculated_area || static_area effective_area = BigDecimal(effective_area, 2) if effective_area effective_area end |
#calculate_thermal_power_per_hour ⇒ Object
This is like btu per hour but kW
559 560 561 562 563 564 565 566 567 |
# File 'app/concerns/models/item_specification_helper.rb', line 559 def calculate_thermal_power_per_hour return unless (w = watts.presence) return unless w.to_f.positive? # If we have a thermal efficiency we will use it to calculate or assume 100 efficiency = spec_value(:thermal_output_efficiency)&.to_f || 100.0 # Convert to kw/h (w.to_f * (efficiency / 100.0) / 1000).round(2) end |
#calculate_volts(precision: 0) ⇒ Object
The voltage V in volts (V) is equal to the current I in amps (A) times the resistance R in ohms (Ω):
412 413 414 |
# File 'app/concerns/models/item_specification_helper.rb', line 412 def calculate_volts(precision: 0) ohms_law_calculator.voltage&.round(precision) end |
#calculate_watts(precision: 0) ⇒ Object
The power P in watts (W) is equal to the voltage V in volts (V) times the current I in amps (A):
417 418 419 |
# File 'app/concerns/models/item_specification_helper.rb', line 417 def calculate_watts(precision: 0) ohms_law_calculator.power&.round(precision) end |
#calculate_watts_per_sqft(precision: 2) ⇒ Object
573 574 575 576 577 578 579 580 581 |
# File 'app/concerns/models/item_specification_helper.rb', line 573 def calculate_watts_per_sqft(precision: 2) tw = watts || calculate_watts sqft = spec_value(:coverage) || calculate_sqft return unless tw&.positive? && sqft&.positive? wps = (BigDecimal(tw.to_s) / sqft).round(precision) wps = wps.to_i if wps.frac.zero? # Makes 15.0 => 15 wps end |
#can_use_amps_for_calculation? ⇒ Boolean
520 521 522 |
# File 'app/concerns/models/item_specification_helper.rb', line 520 def can_use_amps_for_calculation? amps_static? && amps && amps > 0 end |
#can_use_ohms_for_calculation? ⇒ Boolean
504 505 506 |
# File 'app/concerns/models/item_specification_helper.rb', line 504 def can_use_ohms_for_calculation? ohms_static? && ohms && ohms > 0 end |
#can_use_voltage_for_calculation? ⇒ Boolean
512 513 514 |
# File 'app/concerns/models/item_specification_helper.rb', line 512 def can_use_voltage_for_calculation? voltage_static? && voltage && voltage > 0 end |
#can_use_watts_for_calculation? ⇒ Boolean
496 497 498 |
# File 'app/concerns/models/item_specification_helper.rb', line 496 def can_use_watts_for_calculation? watts_static? && watts && watts > 0 end |
#cold_lead_length ⇒ Object
176 177 178 |
# File 'app/concerns/models/item_specification_helper.rb', line 176 def cold_lead_length spec_value(:cold_lead_length) end |
#cold_lead_length=(val) ⇒ Object
180 181 182 |
# File 'app/concerns/models/item_specification_helper.rb', line 180 def cold_lead_length=(val) create_or_set_spec_value(token: :cold_lead_length, name: 'Cold Lead Length', units: 'in', grouping: 'Electrical', text_blurb: val) end |
#control_capacity ⇒ Object
540 541 542 |
# File 'app/concerns/models/item_specification_helper.rb', line 540 def control_capacity (maximum_current || 0) * (num_poles || 1) end |
#coverage_at_3_5_in ⇒ Object
244 245 246 247 248 |
# File 'app/concerns/models/item_specification_helper.rb', line 244 def coverage_at_3_5_in return unless l = linear_ft (l.to_f * 0.291667).round(1) end |
#coverage_at_3_75_in ⇒ Object
250 251 252 253 254 |
# File 'app/concerns/models/item_specification_helper.rb', line 250 def coverage_at_3_75_in return unless l = linear_ft (l.to_f * 0.3125).round(1) end |
#coverage_at_3_in ⇒ Object
238 239 240 241 242 |
# File 'app/concerns/models/item_specification_helper.rb', line 238 def coverage_at_3_in return unless l = linear_ft (l.to_f * 0.25).round(1) end |
#coverage_at_4_5_in ⇒ Object
262 263 264 265 266 |
# File 'app/concerns/models/item_specification_helper.rb', line 262 def coverage_at_4_5_in return unless l = linear_ft (l.to_f * 0.375).round(1) end |
#coverage_at_4_in ⇒ Object
256 257 258 259 260 |
# File 'app/concerns/models/item_specification_helper.rb', line 256 def coverage_at_4_in return unless l = linear_ft (l.to_f * 0.333333).round(1) end |
#coverage_at_5_in ⇒ Object
268 269 270 271 272 |
# File 'app/concerns/models/item_specification_helper.rb', line 268 def coverage_at_5_in return unless l = linear_ft (l.to_f * 0.416667).round(1) end |
#coverage_formatted ⇒ Object
639 640 641 |
# File 'app/concerns/models/item_specification_helper.rb', line 639 def coverage_formatted spec_output(:coverage) end |
#create_or_set_spec_value(grouping:, text_blurb:, token: nil, name: nil, method: 'text', units: nil, visibility: 'open_visibility', locale: nil, skip_spec_refresh: false, link_to_product_line: false) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'app/concerns/models/item_specification_helper.rb', line 63 def create_or_set_spec_value(grouping:, text_blurb:, token: nil, name: nil, method: 'text', units: nil, visibility: 'open_visibility', locale: nil, skip_spec_refresh: false, link_to_product_line: false) return if text_blurb.blank? # No point raise ArgumentError, 'Must specify token or name or both but not none' if token.blank? && name.blank? # If we have a name but no token, we derive it token ||= ProductSpecification.generate_token_from_name_and_grouping(name, grouping) token = token.to_sym # If we have a token but no name, we derive the name name ||= ProductSpecification.generate_name_from_token_and_grouping(token, grouping) attrs = { name: name, token: token, method: method, visibility: visibility, grouping: grouping } # if locale is specified but is en-US, we automatically will fall back to en, it makes it easier this way locale = :en if locale == :'en-US' localized_field_units = nil localized_field_text_blurb = nil %w[units text_blurb].each do |fn| fnl = "#{fn}" fnl << if locale.present? "_#{LocaleUtility.parameterized_locale(locale)}" else '_en' end localized_field_units = fnl.to_sym if fn == 'units' localized_field_text_blurb = fnl.to_sym if fn == 'text_blurb' attrs[fnl.to_sym] = binding.local_variable_get(fn.to_sym) end attrs[:grouping] = grouping attrs[:skip_spec_refresh] = true if skip_spec_refresh ps = direct_product_specifications.find_by(token:) ps ||= ProductSpecification.find_by(token: token, product_line_id: primary_product_line_id, product_category_id: product_category_id) if link_to_product_line if ps ps.do_not_compact_translation_container = true # Check if this localized value is really necessary? we check if it is the same as the fallback (in english only) if locale.present? && locale != :en && locale.to_s.start_with?('en') && ps.text_blurb_en == attrs[localized_field_text_blurb] && ps.units_en == attrs[localized_field_units] # Delete those localized attributes we don't need them attrs.delete(localized_field_text_blurb) attrs.delete(localized_field_units) # Then the localized attribute are simply the same as the fallback and can be removed logger.info 'Localized version of attributes is same as fallback, ignoring' else logger.debug("Updating product specification") ps.update(attrs) end elsif text_blurb.present? # in the context of this method, an empty value doesn't make sense # Build a new ProductSpecification and associate it with this item logger.debug("Creating product specification") ps = ProductSpecification.new(attrs) ps.do_not_compact_translation_container = true if link_to_product_line ps.product_line_id = primary_product_line_id ps.product_category_id = product_category_id else ps.items << self unless ps.items.include?(self) end ps.save! end ps end |
#finish ⇒ Object
569 570 571 |
# File 'app/concerns/models/item_specification_helper.rb', line 569 def finish rendered_product_specifications.dig(:finish, :output) end |
#has_spec?(token) ⇒ Boolean
9 10 11 12 13 |
# File 'app/concerns/models/item_specification_helper.rb', line 9 def has_spec?(token) return false if rendered_product_specifications.nil? rendered_product_specifications[token.to_sym].present? end |
#is_dual_voltage? ⇒ Boolean
544 545 546 |
# File 'app/concerns/models/item_specification_helper.rb', line 544 def is_dual_voltage? spec_value(:dual_voltage) and spec_value(:dual_voltage).to_s.downcase.first != 'f' end |
#length(output_unit: :in) ⇒ Object
141 142 143 |
# File 'app/concerns/models/item_specification_helper.rb', line 141 def length(output_unit: :in) spec_value(:length, output_unit:) end |
#length=(val, unit: :in) ⇒ Object
145 146 147 |
# File 'app/concerns/models/item_specification_helper.rb', line 145 def length=(val, unit: :in) create_or_set_spec_value(token: :length, name: 'Length', units: unit.to_s, grouping: 'Product Dimensions', text_blurb: val) end |
#length_formatted ⇒ Object
627 628 629 |
# File 'app/concerns/models/item_specification_helper.rb', line 627 def length_formatted spec_output(:length) end |
#linear_ft ⇒ Object
memoize :calculate_sqft
614 615 616 617 618 619 620 |
# File 'app/concerns/models/item_specification_helper.rb', line 614 def linear_ft return unless get_self_and_kit_items.any?(&:is_cable_heating_element?) return unless length.present? length(output_unit: :ft) end |
#maximum_current ⇒ Object
532 533 534 |
# File 'app/concerns/models/item_specification_helper.rb', line 532 def maximum_current spec_value(:maximum_current) || spec_value(:maximum_current_per_relay) if is_control? || is_power? end |
#num_poles ⇒ Object
536 537 538 |
# File 'app/concerns/models/item_specification_helper.rb', line 536 def num_poles spec_value(:numbers_of_poles) if is_relay_panel? || is_legacy_relay? end |
#ohms ⇒ Object
351 352 353 354 |
# File 'app/concerns/models/item_specification_helper.rb', line 351 def ohms o = spec_value(:ohms) o.is_a?(Numeric) ? o.round(4) : nil end |
#ohms=(val) ⇒ Object
356 357 358 |
# File 'app/concerns/models/item_specification_helper.rb', line 356 def ohms=(val) create_or_set_spec_value(token: :ohms, name: 'Ohms', units: 'ohm', grouping: 'Electrical', text_blurb: val) end |
#ohms_law_calculator ⇒ Object
396 397 398 399 400 401 402 403 404 405 |
# File 'app/concerns/models/item_specification_helper.rb', line 396 def ohms_law_calculator @ohms_calc ||= begin attrs = {} attrs[:resistance] = ohms if can_use_ohms_for_calculation? attrs[:voltage] = voltage if can_use_voltage_for_calculation? attrs[:power] = watts if can_use_watts_for_calculation? attrs[:current] = amps if can_use_amps_for_calculation? OhmsLawCalculator.new(attrs).calc end end |
#ohms_static? ⇒ Boolean
500 501 502 |
# File 'app/concerns/models/item_specification_helper.rb', line 500 def ohms_static? rendered_product_specifications.dig(:ohms, :static).to_b end |
#plan_grouping ⇒ Object
524 525 526 |
# File 'app/concerns/models/item_specification_helper.rb', line 524 def plan_grouping spec_value(:plan_grouping) end |
#plan_grouping=(val) ⇒ Object
528 529 530 |
# File 'app/concerns/models/item_specification_helper.rb', line 528 def plan_grouping=(val) create_or_set_spec_value(token: :plan_grouping, name: 'Plan Grouping', grouping: 'Logistics', visibility: 'internal', text_blurb: val) end |
#set_spec_value(token, value) ⇒ Object
Finds a direct product spec and sets the value.
54 55 56 57 58 59 60 61 |
# File 'app/concerns/models/item_specification_helper.rb', line 54 def set_spec_value(token, value) token = token.to_sym ds = direct_product_specifications.where(token:).first logger.error("No direct_product_specifications present for #{sku} with token #{token}, cannot set spec value") unless ds ds&.update_attribute(:text_blurb, value) update_rendered_product_specifications value end |
#spec(token) ⇒ Object
Retrieves a spec from the rendered product specification
Performs a little bit of value casting on the raw output before returning
17 18 19 20 21 22 23 |
# File 'app/concerns/models/item_specification_helper.rb', line 17 def spec(token) return if rendered_product_specifications.nil? return unless (ps = rendered_product_specifications[token.to_sym]) ps[:raw] = TypeCoercer.coerce(ps[:raw]) ps end |
#spec_image(token) ⇒ Object
135 136 137 138 139 |
# File 'app/concerns/models/item_specification_helper.rb', line 135 def spec_image(token) return unless (iid = spec(token)&.dig(:image_id)) Image.find(iid) end |
#spec_output(token, locale: Mobility.locale) ⇒ Object
returns the formatted output from the spec
129 130 131 132 133 |
# File 'app/concerns/models/item_specification_helper.rb', line 129 def spec_output(token, locale: Mobility.locale) Mobility.with_locale(locale) do spec(token)&.dig(:output)&.dup end end |
#spec_refresh_in_progress ⇒ Object
25 26 27 |
# File 'app/concerns/models/item_specification_helper.rb', line 25 def spec_refresh_in_progress BackgroundJobStatus.search(worker_klass: 'ItemAttributeWorker', args: id).present? end |
#spec_unit(token) ⇒ Object
46 47 48 49 50 51 |
# File 'app/concerns/models/item_specification_helper.rb', line 46 def spec_unit(token) u = spec(token)&.dig(:units)&.dup # Sqft fudging to handle leftover bad data until it transitions over in all product_specifications.units u = 'sqft' if /Sq\.? ?Ft\.?/i.match?(u) u end |
#spec_value(token, output_unit: nil, precision: nil) ⇒ Object
returns the raw value from the spec
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'app/concerns/models/item_specification_helper.rb', line 30 def spec_value(token, output_unit: nil, precision: nil) return unless (v = spec(token)&.dig(:raw)&.dup) current_unit_symbol = spec_unit(token) if current_unit_symbol.present? && output_unit.present? && current_unit_symbol.to_s != output_unit.to_s current_unit_val = RubyUnits::Unit.new("#{v} #{current_unit_symbol}") # We're using desired_unit for testing compatibility desired_unit = RubyUnits::Unit.new("1 #{output_unit}") # only convert if units are compatible v = current_unit_val.convert_to(output_unit.to_s).scalar.to_f if current_unit_val.compatible?(desired_unit) end v = v.round(precision) if precision.present? && v.respond_to?(:round) TypeCoercer.coerce(v) end |
#specs_for_identifier_label ⇒ Object
643 644 645 646 647 648 649 |
# File 'app/concerns/models/item_specification_helper.rb', line 643 def specs_for_identifier_label hsh = {} specifications_for_item_label.each do |rps| hsh[rps.name] = rps.output end hsh end |
#sqft ⇒ Object
230 231 232 |
# File 'app/concerns/models/item_specification_helper.rb', line 230 def sqft area(output_unit: :sqft) end |
#sqft=(val) ⇒ Object
234 235 236 |
# File 'app/concerns/models/item_specification_helper.rb', line 234 def sqft=(val) create_or_set_spec_value(token: :coverage, name: 'Coverage', units: 'sqft', grouping: 'Product Dimensions', text_blurb: val) end |
#token_specs_values_for_liquid(include_legacy: false) ⇒ Object
Renders a hash with a token spec value (possibly in multiple dimensions)
and its value. This hash can be used for liquid merges
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
# File 'app/concerns/models/item_specification_helper.rb', line 667 def token_specs_values_for_liquid(include_legacy: false) = {} [:item_name] = name [:detailed_description_html] = detailed_description_html [:short_description] = short_description [:feature_1] = feature_1 [:feature_2] = feature_2 [:feature_3] = feature_3 [:feature_4] = feature_4 [:feature_5] = feature_5 rendered_product_specifications&.each do |k, _v| [k] = spec_output(k) ["#{k}_formatted"] = spec_output(k) if include_legacy # This is for legacy if spec_unit(k) ["#{k}_raw"] = spec_value(k) ["#{k}_units"] = spec_unit(k) end supported_dim_units = %i[ft in m cm mm] supported_weight_units = %i[lb oz kg g] supported_coverage_units = %i[sqft sqm] current_unit = spec_unit(k)&.to_sym target_units = if supported_dim_units.include?(current_unit) supported_dim_units elsif supported_weight_units.include?(current_unit) supported_weight_units elsif supported_coverage_units.include?(current_unit) supported_coverage_units else [] end # We iterate through each dimension unit we care to have a translation for and pull the value target_units.each do |unit| next unless (val = begin spec_value(k, output_unit: unit) rescue StandardError nil end) ["#{k}_#{unit}_raw"] = val ["#{k}_#{unit}_units"] = unit.to_s end end # Now combine computed methods ProductSpecification.methods_for_select.each do |method_string| method_symbolized = method_string.to_sym next if method_symbolized == :text begin ["#{method_symbolized}"] ||= send(method_symbolized) rescue StandardError # Ignore this end end .with_indifferent_access.compact end |
#voltage ⇒ Object
360 361 362 363 |
# File 'app/concerns/models/item_specification_helper.rb', line 360 def voltage v = spec_value(:voltage) v.is_a?(Numeric) ? v : nil end |
#voltage=(val) ⇒ Object
365 366 367 |
# File 'app/concerns/models/item_specification_helper.rb', line 365 def voltage=(val) create_or_set_spec_value(token: :voltage, name: 'Voltage', units: 'V', grouping: 'Electrical', text_blurb: val) end |
#voltage_formatted ⇒ Object
631 632 633 |
# File 'app/concerns/models/item_specification_helper.rb', line 631 def voltage_formatted spec_output(:voltage) end |
#voltage_static? ⇒ Boolean
508 509 510 |
# File 'app/concerns/models/item_specification_helper.rb', line 508 def voltage_static? rendered_product_specifications.dig(:voltage, :static).to_b end |
#volts ⇒ Object
369 370 371 372 |
# File 'app/concerns/models/item_specification_helper.rb', line 369 def volts logger.warn 'Deprecated method volts, use voltage instead' voltage end |
#volts=(val) ⇒ Object
374 375 376 377 |
# File 'app/concerns/models/item_specification_helper.rb', line 374 def volts=(val) logger.warn 'Deprecated method volts, use voltage instead' create_or_set_spec_value(token: :voltage, name: 'Voltage', units: 'V', grouping: 'Electrical', text_blurb: val) end |
#vop ⇒ Object
388 389 390 |
# File 'app/concerns/models/item_specification_helper.rb', line 388 def vop spec_value(:vop) end |
#watts ⇒ Object
341 342 343 344 345 |
# File 'app/concerns/models/item_specification_helper.rb', line 341 def watts w = spec_value(:watts, output_unit: 'W') # Force watts in case this is expressed in kilowatts w.is_a?(Numeric) ? w : nil end |
#watts=(val) ⇒ Object
347 348 349 |
# File 'app/concerns/models/item_specification_helper.rb', line 347 def watts=(val) create_or_set_spec_value(token: :watts, name: 'Watts', units: 'W', grouping: 'Electrical', text_blurb: val) end |
#watts_formatted ⇒ Object
635 636 637 |
# File 'app/concerns/models/item_specification_helper.rb', line 635 def watts_formatted spec_output(:watts) end |
#watts_per_linear_feet(precision: 2) ⇒ Object
335 336 337 338 339 |
# File 'app/concerns/models/item_specification_helper.rb', line 335 def watts_per_linear_feet(precision: 2) return unless length && watts (BigDecimal(watts.to_s) / (length.to_f / 12)).truncate(precision) end |
#watts_per_sqft ⇒ Object
392 393 394 |
# File 'app/concerns/models/item_specification_helper.rb', line 392 def watts_per_sqft spec_value(:watts_per_sqft) || calculate_watts_per_sqft end |
#watts_per_sqft_at_3_5_in_spacing ⇒ Object
305 306 307 308 309 |
# File 'app/concerns/models/item_specification_helper.rb', line 305 def watts_per_sqft_at_3_5_in_spacing return unless watts && coverage_at_3_5_in (BigDecimal(watts.to_s) / coverage_at_3_5_in).truncate(1) end |
#watts_per_sqft_at_3_75_in_spacing ⇒ Object
311 312 313 314 315 |
# File 'app/concerns/models/item_specification_helper.rb', line 311 def watts_per_sqft_at_3_75_in_spacing return unless watts && coverage_at_3_75_in (BigDecimal(watts.to_s) / coverage_at_3_75_in).truncate(1) end |
#watts_per_sqft_at_3_in_spacing ⇒ Object
299 300 301 302 303 |
# File 'app/concerns/models/item_specification_helper.rb', line 299 def watts_per_sqft_at_3_in_spacing return unless watts && coverage_at_3_in (BigDecimal(watts.to_s) / coverage_at_3_in).truncate(1) end |
#watts_per_sqft_at_4_5_in_spacing ⇒ Object
323 324 325 326 327 |
# File 'app/concerns/models/item_specification_helper.rb', line 323 def watts_per_sqft_at_4_5_in_spacing return unless watts && coverage_at_4_5_in (BigDecimal(watts.to_s) / coverage_at_4_5_in).truncate(1) end |
#watts_per_sqft_at_4_in_spacing ⇒ Object
317 318 319 320 321 |
# File 'app/concerns/models/item_specification_helper.rb', line 317 def watts_per_sqft_at_4_in_spacing return unless watts && coverage_at_4_in (BigDecimal(watts.to_s) / coverage_at_4_in).truncate(1) end |
#watts_per_sqft_at_5_in_spacing ⇒ Object
329 330 331 332 333 |
# File 'app/concerns/models/item_specification_helper.rb', line 329 def watts_per_sqft_at_5_in_spacing return unless watts && coverage_at_5_in (BigDecimal(watts.to_s) / coverage_at_5_in).truncate(1) end |
#watts_static? ⇒ Boolean
492 493 494 |
# File 'app/concerns/models/item_specification_helper.rb', line 492 def watts_static? rendered_product_specifications.dig(:watts, :static).to_b end |
#width(output_unit: :in) ⇒ Object
149 150 151 |
# File 'app/concerns/models/item_specification_helper.rb', line 149 def width(output_unit: :in) spec_value(:width, output_unit:) end |
#width=(val, unit: :in) ⇒ Object
153 154 155 |
# File 'app/concerns/models/item_specification_helper.rb', line 153 def width=(val, unit: :in) create_or_set_spec_value(token: :width, name: 'Width', units: unit.to_s, grouping: 'Product Dimensions', text_blurb: val) end |
#width_by_length_text ⇒ Object
157 158 159 160 161 |
# File 'app/concerns/models/item_specification_helper.rb', line 157 def width_by_length_text return unless length && width "#{format('%.2g', width.to_f / 12)}′ x #{format('%d', length.to_f / 12)}′" end |
#width_by_length_text_2 ⇒ Object
163 164 165 166 167 |
# File 'app/concerns/models/item_specification_helper.rb', line 163 def width_by_length_text_2 return unless length && width "#{format('%.2g', width.to_f / 12)}′ x #{format('%02d', length.to_f / 12)}′" end |
#width_by_length_text_3 ⇒ Object
For larger rolls
170 171 172 173 174 |
# File 'app/concerns/models/item_specification_helper.rb', line 170 def width_by_length_text_3 return unless length && width "#{format('%.2g', width.to_f / 12)}′ x #{format('%03d', length.to_f / 12)}′" end |
#width_formatted ⇒ Object
623 624 625 |
# File 'app/concerns/models/item_specification_helper.rb', line 623 def width_formatted spec_output(:width) end |