Class: Item::HeatingElementPlan
- Inherits:
-
Object
- Object
- Item::HeatingElementPlan
- Defined in:
- app/services/item/heating_element_plan.rb
Overview
Service object: heating element plan.
Constant Summary collapse
- SPECIAL_LEGEND_DESCRIPTIONS =
Special legend descriptions.
{ 'ot_sensor' => 'OT Sensor *', 'slab_sensor' => 'SCE-SLAB-SS-KIT Sensor #' }.freeze
Instance Attribute Summary collapse
-
#all_line_items ⇒ Object
Returns the value of attribute all_line_items.
-
#all_line_items_including_parents ⇒ Object
Returns the value of attribute all_line_items_including_parents.
-
#cable_spacing ⇒ Object
Returns the value of attribute cable_spacing.
-
#country_iso ⇒ Object
Returns the value of attribute country_iso.
-
#electricity_rate ⇒ Object
Returns the value of attribute electricity_rate.
-
#heating_elements_line_items ⇒ Object
Returns the value of attribute heating_elements_line_items.
-
#heating_elements_lines ⇒ Object
Returns the value of attribute heating_elements_lines.
-
#heating_system ⇒ Object
Returns the value of attribute heating_system.
-
#installation_postal_code ⇒ Object
Returns the value of attribute installation_postal_code.
-
#installation_sqft ⇒ Object
Returns the value of attribute installation_sqft.
-
#is_countertop ⇒ Object
Returns the value of attribute is_countertop.
-
#locale ⇒ Object
Returns the value of attribute locale.
-
#other_items ⇒ Object
Returns the value of attribute other_items.
-
#state_code ⇒ Object
Returns the value of attribute state_code.
-
#voltage ⇒ Object
Returns the value of attribute voltage.
Delegated Instance Attributes collapse
-
#controls ⇒ Object
Alias for All_line_items#controls.
-
#integration_kits ⇒ Object
Alias for All_line_items#integration_kits.
-
#power_modules ⇒ Object
Alias for All_line_items#power_modules.
-
#thermostats ⇒ Object
Alias for All_line_items#thermostats.
Class Method Summary collapse
Instance Method Summary collapse
- #air_sensors ⇒ Object
-
#alternative_volts_explanation ⇒ Object
make a hash of all alternative volts which we can display on the install plan.
- #breaker_rules ⇒ Object
- #breaker_size(amps = total_amps, max_amps = 50) ⇒ Object
- #build_from_line_item(line_item, qty = nil, heating_element_number = nil) ⇒ Object
- #cold_leads ⇒ Object
- #cold_leads_length ⇒ Object
- #control_voltage ⇒ Object
- #current_switching_thermostats ⇒ Object
- #display_cutting_info? ⇒ Boolean
- #electrical_consumption ⇒ Object
- #electrical_plan_controls ⇒ Object
- #electrical_rough_in_kits ⇒ Object
- #extra_instructions ⇒ Object
- #first_heating_element_voltage ⇒ Object
- #floor_load ⇒ Object
-
#floor_load_display ⇒ Object
Floor load formatted to ~3 significant figures across the full range of possible loads: integer part is never rounded away for large loads (21453 kW stays "21453"), and decimals grow as the value drops below 1 kW (0.573 kW stays "0.573", 0.0121 kW stays "0.0121").
- #flooring_label ⇒ Object
- #generate_heating_elements_lines ⇒ Object
- #has_item?(sku) ⇒ Boolean
- #heating_elements_table(with_cold_lead: false, with_ohms: false, with_pole_assignment: false) ⇒ Object
-
#heating_elements_table_column_headers(with_cold_lead: false, with_ohms: false, with_row_number: true, with_pole_assignment: false) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument.
- #heating_elements_table_footers ⇒ Object
- #heating_system_name ⇒ Object
- #heating_system_voltage ⇒ Object
- #heating_system_with_voltage ⇒ Object
- #hide_flip_turn? ⇒ Boolean
- #highlighted_columns ⇒ Object
-
#initialize(line_items, options = {}) ⇒ HeatingElementPlan
constructor
Initialize with an LineItem result set of heating elements or pass options: cable_spacing: 3.0 if you want to append the cable spacing in inche to the width heating_system: name of the heating system.
- #instructions(include_electrical_plan_rules = false, include_installation_plan_rules = false) ⇒ Object
- #is_countertop? ⇒ Boolean
- #is_environ? ⇒ Boolean
- #is_indoor_floor_heating_system? ⇒ Boolean
- #is_outdoor? ⇒ Boolean
- #is_pipe_freeze? ⇒ Boolean
- #legend ⇒ Object
- #line_items_for_sku(sku) ⇒ Object
- #number_of_circuits ⇒ Object
- #ot_sensors ⇒ Object
- #other_items_table ⇒ Object
- #power_kits ⇒ Object
- #relays ⇒ Object
- #requires_breaker_size_vs_circuit_length_table? ⇒ Boolean
- #roof_and_gutter_breaker_recommendations(volts) ⇒ Object
- #roof_and_gutter_breaker_size(volts, length) ⇒ Object
- #room_label ⇒ Object
- #sensors ⇒ Object
- #shorten_text(text, num_chars = 32) ⇒ Object
- #slab_heat_cable_watts_per_sqft ⇒ Object
- #snow_melt_cable_watts_per_sqft ⇒ Object
- #special_instructions ⇒ Object
- #tempzone_thick_cable_watts_per_sqft ⇒ Object
- #tempzone_thin_cable_watts_per_sqft ⇒ Object
- #total_amps ⇒ Object
- #total_btu_per_hr ⇒ Object
- #total_length ⇒ Object
- #total_watts ⇒ Object
- #watts_per_sqft(watts_only = false) ⇒ Object
Constructor Details
#initialize(line_items, options = {}) ⇒ HeatingElementPlan
Initialize with an LineItem result set of heating elements or pass
options:
cable_spacing: 3.0 if you want to append the cable spacing in inche to the width
heating_system: name of the heating system
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'app/services/item/heating_element_plan.rb', line 55 def initialize(line_items, = {}) @options = self.all_line_items = line_items.without_children self.all_line_items_including_parents = line_items self.other_items = all_line_items.to_a - all_line_items.heating_elements.to_a # line_items.controls.to_a + line_items.accessories.to_a self.heating_system = @options[:heating_system] || 'TempZone Thin Cable' # use this as the default self.cable_spacing = @options[:cable_spacing] self.voltage = @options[:voltage] || 120 # use this as the default self.is_countertop = @options[:is_countertop] || false # use this as the default self.heating_elements_line_items = all_line_items.heating_elements.sort_for_plan self.installation_postal_code = @options[:installation_postal_code] self.electricity_rate = @options[:electricity_rate] self.installation_sqft = @options[:installation_sqft] self.locale = @options[:locale] || I18n.locale self.state_code = @options[:state_code] self.country_iso = @options[:country_iso] generate_heating_elements_lines end |
Instance Attribute Details
#all_line_items ⇒ Object
Returns the value of attribute all_line_items.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def all_line_items @all_line_items end |
#all_line_items_including_parents ⇒ Object
Returns the value of attribute all_line_items_including_parents.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def all_line_items_including_parents @all_line_items_including_parents end |
#cable_spacing ⇒ Object
Returns the value of attribute cable_spacing.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def cable_spacing @cable_spacing end |
#country_iso ⇒ Object
Returns the value of attribute country_iso.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def country_iso @country_iso end |
#electricity_rate ⇒ Object
Returns the value of attribute electricity_rate.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def electricity_rate @electricity_rate end |
#heating_elements_line_items ⇒ Object
Returns the value of attribute heating_elements_line_items.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def heating_elements_line_items @heating_elements_line_items end |
#heating_elements_lines ⇒ Object
Returns the value of attribute heating_elements_lines.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def heating_elements_lines @heating_elements_lines end |
#heating_system ⇒ Object
Returns the value of attribute heating_system.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def heating_system @heating_system end |
#installation_postal_code ⇒ Object
Returns the value of attribute installation_postal_code.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def installation_postal_code @installation_postal_code end |
#installation_sqft ⇒ Object
Returns the value of attribute installation_sqft.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def installation_sqft @installation_sqft end |
#is_countertop ⇒ Object
Returns the value of attribute is_countertop.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def is_countertop @is_countertop end |
#locale ⇒ Object
Returns the value of attribute locale.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def locale @locale end |
#other_items ⇒ Object
Returns the value of attribute other_items.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def other_items @other_items end |
#state_code ⇒ Object
Returns the value of attribute state_code.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def state_code @state_code end |
#voltage ⇒ Object
Returns the value of attribute voltage.
8 9 10 |
# File 'app/services/item/heating_element_plan.rb', line 8 def voltage @voltage end |
Class Method Details
.get_room_best_location(rc) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'app/services/item/heating_element_plan.rb', line 23 def self.get_room_best_location(rc) res = {} if rc.opportunity&.installation_postal_code.present? res[:installation_postal_code] = rc.opportunity.installation_postal_code elsif (shippping_address = rc.orders.first&.shipping_address || rc.quotes.first&.shipping_address).present? res[:state_code] = shippping_address.state_code res[:country_iso] = shippping_address.country_iso res[:installation_postal_code] = shippping_address.zip else res[:state_code] = rc.opportunity.customer.state_code res[:country_iso] = rc.opportunity.customer.country_iso res[:installation_postal_code] = rc.opportunity.customer.zip end res end |
.new_from_room_configuration(rc, _options = {}) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 |
# File 'app/services/item/heating_element_plan.rb', line 11 def self.new_from_room_configuration(rc, = {}) new(rc.line_items.goods, heating_system: rc.heating_system_type_name, cable_spacing: rc.installation_plan_cable_spacing || rc.line_items.primary_heating_element_spacing, voltage: rc.installation_plan_voltage_id, electricity_rate: rc.opportunity.electricity_rate, is_countertop: rc.is_countertop?, installation_sqft: rc.installation_sqft, locale: rc.opportunity.customer.locale, **get_room_best_location(rc)) end |
Instance Method Details
#air_sensors ⇒ Object
459 460 461 |
# File 'app/services/item/heating_element_plan.rb', line 459 def air_sensors line_items_for_sku(%w[AIR-SS AIR-SS-2 SCPM-SS-120]) end |
#alternative_volts_explanation ⇒ Object
make a hash of all alternative volts which we can display on the install plan
301 302 303 304 305 306 307 308 309 310 311 |
# File 'app/services/item/heating_element_plan.rb', line 301 def alternative_volts_explanation volts = {} symbol = 1 heating_elements_lines.select { |hel| hel.alternative_volts.present? }.each do |hel| unless volts.value?(hel.alternative_volts) volts[symbol] = hel.alternative_volts symbol += 1 end end volts end |
#breaker_rules ⇒ Object
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 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 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 |
# File 'app/services/item/heating_element_plan.rb', line 608 def breaker_rules rules = [] if ['TempZone Flex Roll', 'Environ Flex Roll', 'TempZone Easy Mat', 'Environ Easy Mat', 'TempZone Cable', 'TempZone Ruler Cable', 'TempZone Thin Cable', 'TempZone Shower Mat', 'TempZone Custom Mat', 'Shower Mat Bench'].include?(heating_system) if relays.present? breakers = {} heating_elements_lines.each do |hel| bs = "#{breaker_size(hel.amps)} Amp #{hel.volts}V GFI Heater Circuit" new_qty = (breakers[bs] || 0) + 1 breakers[bs] = new_qty end breakers.each_pair { |key, value| rules << "#{value} x #{key}" } rules << "#{controls.sum(:quantity)} x 15 Amp 120V Non-GFI Control Circuit" unless controls.empty? elsif (num_power_modules = power_modules.sum(:quantity)).positive? # How many switching thermostats do we have as well? num_tstats = current_switching_thermostats.sum(&:quantity) total_switching_relays = num_tstats + num_power_modules if total_switching_relays == heating_elements_lines.length # SPECIAL CASE: If total_switching_relays matches number of heating elements, then assume 1 per switching relay and show each unit's breaker based on the heating element's amps. breakers = {} heating_elements_lines.each do |hel| bs = "#{breaker_size(hel.amps)} Amp #{hel.volts}V Non-GFI Heater Circuit" new_qty = (breakers[bs] || 0) + 1 breakers[bs] = new_qty end breakers.each_pair do |key, value| rules << "#{value} x #{key}" end else rules << "#{total_switching_relays} x 20 Amp #{heating_system_voltage}V Non-GFI Circuit" end elsif integration_kits.sum(:quantity) == 1 # if there is just 1 integration kit then show breaker info based on total heating load rules << "1 x #{breaker_size(total_amps, 30)} Amp #{heating_system_voltage}V GFI Circuit" elsif integration_kits.sum(:quantity) > 1 rules << "#{integration_kits.sum(:quantity)} x 30 Amp #{integration_kits.first.item.voltage}V GFI Circuit" elsif current_switching_thermostats.present? if (num_tstats = current_switching_thermostats.sum(&:quantity)) > 1 if num_tstats == heating_elements_lines.length # SPECIAL CASE: If multiple thermostats matches number of heating elements, then assume 1 per tstat and show each unit's breaker based on the heating element's amps. breakers = {} heating_elements_lines.each do |hel| bs = "#{breaker_size(hel.amps)} Amp #{hel.volts}V Non-GFI Heater Circuit" new_qty = (breakers[bs] || 0) + 1 breakers[bs] = new_qty end breakers.each_pair do |key, value| rules << "#{value} x #{key}" end else # If multiple thermostats, then show qty of breakers = qty of thermostats, and show each unit need 20 Amps breaker, since we are assuming maximum load. rules << "#{num_tstats} x 20 Amp #{heating_system_voltage}V Non-GFI Circuit" end else # else if single thermostat then show 1 breaker and use regular breaker size rule for total heating elements, upto max of 20 Amps. rules << "1 x #{breaker_size(total_amps, 20)} Amp #{heating_system_voltage}V Non-GFI Circuit" end else # no controls, so use generic sentence rules << 'The warming system must be electrically grounded and protected by a GFCI' end elsif ['Slab Heat Mat', 'Slab Heat Cable'].include?(heating_system) if relays.present? breakers = {} heating_elements_lines.each do |hel| bs = "#{breaker_size(hel.amps)} Amp #{hel.volts}V GFI Heater Circuit" new_qty = (breakers[bs] || 0) + 1 breakers[bs] = new_qty end breakers.each_pair { |key, value| rules << "#{value} x #{key}" } rules << "#{controls.sum(:quantity)} x 15 Amp 120V Non-GFI Control Circuit" unless controls.empty? elsif (num_power_modules = power_modules.sum(:quantity)).positive? # if a power modulator is present # How many switching thermostats do we have as well? num_tstats = current_switching_thermostats.sum(&:quantity) total_switching_relays = num_tstats + num_power_modules rules << "#{total_switching_relays} x 20 Amp #{heating_system_voltage}V Non-GFI Circuit" elsif controls.empty? # no relays, no controls, so use generic sentence rules << 'The warming system must be electrically grounded and protected by a GFCI' else # no relays, but there are controls rules << "#{controls.sum(:quantity)} x #{breaker_size(total_amps)} Amp #{heating_system_voltage}V Non-GFI Circuit" unless controls.empty? end elsif ['Snow Melt Mat', 'Snow Melt PowerMat', 'Snow Melt OmniMat', 'Snow Melt EcoMat', 'Snow Melt Cable'].include?(heating_system) if relays.present? breakers = {} heating_elements_lines.each do |hel| bs = "#{breaker_size(hel.amps)} Amp #{hel.volts}V GFEP Heater Circuit" breakers[bs] ||= 0 breakers[bs] += 1 end breakers.each_pair { |key, value| rules << "#{value} x #{key}" } rules << "#{controls.sum(:quantity)} x 15 Amp 120V Non-GFI Control Circuit" unless controls.empty? elsif has_item?(ItemConstants::POWER_MODULATORS) # if a power modulator is present power_modulator_count = line_items_for_sku(ItemConstants::POWER_MODULATORS).sum(:quantity) rules << "#{power_modulator_count} x 120V Non-GFI Control Circuit" rules << "1 x #{heating_system_voltage}V Non-GFI Circuit per contactor" elsif controls.empty? # no relays, no controls, so qty of breakers = qty of heating elements breakers = {} heating_elements_lines.each do |hel| bs = "#{breaker_size(hel.amps)} Amp #{hel.volts}V GFEP Heater Circuit" new_qty = (breakers[bs] || 0) + 1 breakers[bs] = new_qty end breakers.each_pair { |key, value| rules << "#{value} x #{key}" } else # no relays, but there are controls rules << "#{controls.sum(:quantity)} x #{breaker_size(total_amps)} Amp #{heating_system_voltage}V GFEP Circuit" unless controls.empty? end elsif /roof|pipe/i.match?(heating_system) number_of_power_kits = line_items_for_sku(%w[SR-PWR-KIT PT-PWR-KIT-H]).sum(:quantity) if has_item?('SR-PLUG-KIT') # if a plug-in kit is present number_of_kits = line_items_for_sku('SR-PLUG-KIT').sum(:quantity) rules << "#{number_of_kits} x 15 AMP 120V Non-GFI Circuit (1 outlet required per plug-in kit)" elsif relays.present? rules << "#{controls.sum(:quantity)} x 15 Amp 120V Non-GFI Control Circuit" unless controls.empty? if [120, 240].include?(heating_system_voltage) rules << if number_of_power_kits.zero? "#{heating_system_voltage}V" else "#{number_of_power_kits} x #{heating_system_voltage}V GFEP Heater Circuit" end rules << "Refer to electrical plan's circuit breaker size vs cable length table" end elsif heating_system.match(/roof/i) && has_item?(ItemConstants::POWER_MODULATORS) # if r&g and a power modulator is present power_modulator_count = line_items_for_sku(ItemConstants::POWER_MODULATORS).sum(:quantity) rules << "#{power_modulator_count} x 120V Non-GFI Control Circuit" rules << "1 x #{heating_system_voltage}V Non-GFI Circuit per contactor" elsif controls.empty? # no relays, no controls, so qty of breakers = qty of heating elements rules << if number_of_power_kits.zero? "#{heating_system_voltage}V" else "#{number_of_power_kits} x #{heating_system_voltage}V GFEP Heater Circuit" end rules << "Refer to electrical plan's circuit breaker size vs cable length table" elsif /pipe/i.match?(heating_system) # no relays, but there are controls rules << "Refer to electrical plan's circuit breaker size vs cable length table" else unless controls.empty? rules << "#{controls.sum(:quantity)} x #{roof_and_gutter_breaker_size(heating_system_voltage, total_length)} Amp #{heating_system_voltage}V GFEP Circuit" end end else [] end rules end |
#breaker_size(amps = total_amps, max_amps = 50) ⇒ Object
494 495 496 497 498 499 500 501 502 |
# File 'app/services/item/heating_element_plan.rb', line 494 def breaker_size(amps = total_amps, max_amps = 50) case amps when 0..12 then 15 when 12.01..16 then [20, max_amps].min when 16.01..24 then [30, max_amps].min when 24.01..32 then [40, max_amps].min when 32.01..40 then [50, max_amps].min end end |
#build_from_line_item(line_item, qty = nil, heating_element_number = nil) ⇒ Object
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'app/services/item/heating_element_plan.rb', line 264 def build_from_line_item(line_item, qty = nil, heating_element_number = nil) item = line_item.item multiplier = (qty || line_item.quantity || 1).to_f # Self healing in case specs are missing if item.voltage.blank? || item.amps.blank? || item.watts.blank? || item.ohms.blank? item.update_rendered_product_specifications(tokens: %w[voltage amps watts ohms]) item.reload end begin element_pole_assignments = if line_item.room_configuration && heating_element_number line_item.room_configuration.element_pole_assignments.ordered.where(heating_element_number: heating_element_number, heating_element_item_id: line_item.item_id) else ElementPoleAssignment.none end Item::HeatingElementLine.new( sku: item.sku, width: cable_spacing || item.width, length: (item.length.nil? ? nil : item.length * multiplier), volts: item.voltage, alternative_volts: item.alternative_volts.presence&.join(', '), amps: (item.amps.to_f * multiplier).round(2), watts: (item.watts.to_f * multiplier), btu_per_hr: (item.watts.to_f * multiplier) * RoomConfiguration::BTU_PER_HOUR_PER_WATT, watts_per_linear_feet: item.watts_per_linear_feet, cold_lead_length: item.cold_lead_length, ohms: item.ohms&.round(2), poles: element_pole_assignments.map(&:pole_number).join(', '), relay: element_pole_assignments.first&.relay_identifier, heating_element_number: heating_element_number ) rescue StandardError => e ErrorReporting.error(e, { line_item_id: line_item.id, item_id: item.id, item_sku: item.sku }) end end |
#cold_leads ⇒ Object
467 468 469 |
# File 'app/services/item/heating_element_plan.rb', line 467 def cold_leads line_items_for_sku('COLDLEAD') end |
#cold_leads_length ⇒ Object
480 481 482 |
# File 'app/services/item/heating_element_plan.rb', line 480 def cold_leads_length cold_leads.sum(:quantity) end |
#control_voltage ⇒ Object
431 432 433 |
# File 'app/services/item/heating_element_plan.rb', line 431 def control_voltage relays.present? ? 120 : heating_system_voltage end |
#controls ⇒ Object
Alias for All_line_items#controls
441 |
# File 'app/services/item/heating_element_plan.rb', line 441 delegate :controls, to: :all_line_items |
#current_switching_thermostats ⇒ Object
580 581 582 |
# File 'app/services/item/heating_element_plan.rb', line 580 def current_switching_thermostats all_line_items.smartstats + all_line_items.easystats + all_line_items.oj_tstats end |
#display_cutting_info? ⇒ Boolean
540 541 542 |
# File 'app/services/item/heating_element_plan.rb', line 540 def display_cutting_info? ['TempZone Flex Roll', 'Environ Flex Roll'].include?(heating_system) end |
#electrical_consumption ⇒ Object
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 |
# File 'app/services/item/heating_element_plan.rb', line 769 def electrical_consumption return nil if heating_elements_line_items.any? { |he| he.item.is_self_regulating_cable? } return nil unless total_watts&.positive? avg_rate = ElectricityRate.get_average_for_locale(locale) # I don't see a way to determine the locale to use if no zip code disclaimer = "This calculation is based on the national average of $#{avg_rate} per kWh, but consumption may vary based on individual conditions." if electricity_rate.present? avg_rate = electricity_rate.round(4) disclaimer = "This calculation is based on the rate of $#{avg_rate} per kWh, but consumption may vary based on individual conditions." elsif installation_postal_code.present? result = ElectricityRate.get_from_postal_code(installation_postal_code) if result[:status] == :ok && result[:average_rate].present? avg_rate = result[:average_rate].round(4) disclaimer = "This calculation is based on the average rate of $#{avg_rate} per kWh for zip/postal code #{installation_postal_code}, but consumption may vary based on individual conditions." end elsif (state_rate = ElectricityRate.get_average_rate_for_country_iso_state_code(country_iso, state_code)) avg_rate = state_rate disclaimer = "This calculation is based on the average rate of $#{avg_rate} per kWh for state/province #{state_code}, but consumption may vary based on individual conditions." end # 2.3 = thermal inertia # 1 = number of hours operation if heating_system.index(/roof|snow|pipe/i) # For snow melt we typically don't account for thermal inertia, because these systems can be running non-stop (Anatoliy 3/16/17) coefficient = 1 else coefficient = 0.4348 disclaimer << ' Operating cost is estimated based on the average thermal inertia due to the thermostat cycling the power during the heating period.' end watts_per_sqft(true) consumption_rate = ((avg_rate * coefficient * total_watts) / 1000).round(2) { rate: consumption_rate, coefficient:, avg_rate:, total_watts:, disclaimer: } end |
#electrical_plan_controls ⇒ Object
471 472 473 474 |
# File 'app/services/item/heating_element_plan.rb', line 471 def electrical_plan_controls # here we really want parents_only i.e. no kit compnents, I believe, per Anatoliy's request to not display the Zone braker twice all_line_items_including_parents.electrical_plan_controls.parents_only + line_items_for_sku('SR-PLUG-KIT') end |
#electrical_rough_in_kits ⇒ Object
584 585 586 |
# File 'app/services/item/heating_element_plan.rb', line 584 def electrical_rough_in_kits all_line_items_including_parents.joins(:item).where(items: { sku: 'FHE-ROUGH-IN-KIT-03' }) end |
#extra_instructions ⇒ Object
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 |
# File 'app/services/item/heating_element_plan.rb', line 753 def extra_instructions instructions = [] # Cold lead if cold_leads_length.positive? instructions << 'COLD LEAD:' instructions << "#{cold_leads_length}' of additional cold lead" end # Aerial Sensor if air_sensors.present? instructions << 'AERIAL SENSOR:' instructions << 'Provided, but not shown on drawing. Location per installer\'s discretion. WarmlyYours recommends it to be in an area most indicative of snow conditions.' end instructions end |
#first_heating_element_voltage ⇒ Object
572 573 574 |
# File 'app/services/item/heating_element_plan.rb', line 572 def first_heating_element_voltage heating_elements_lines.first&.volts end |
#floor_load ⇒ Object
403 404 405 406 |
# File 'app/services/item/heating_element_plan.rb', line 403 def floor_load # needs to be 1000.0 so both values are Float, else can lead to it being 0 (total_watts / 1000.0).round(1) end |
#floor_load_display ⇒ Object
Floor load formatted to ~3 significant figures across the full range of
possible loads: integer part is never rounded away for large loads
(21453 kW stays "21453"), and decimals grow as the value drops below 1 kW
(0.573 kW stays "0.573", 0.0121 kW stays "0.0121"). Avoids the old
round(1) collapsing small loads to a single decimal ("0.6").
413 414 415 416 417 418 419 420 421 |
# File 'app/services/item/heating_element_plan.rb', line 413 def floor_load_display kw = total_watts / 1000.0 return "0" if kw.zero? # ponytail: 3 sig figs = 2 - order-of-magnitude; clamped so the integer # part is always shown in full and never negative. decimals = [2 - Math.log10(kw.abs).floor, 0].max format("%.#{decimals}f", kw) end |
#flooring_label ⇒ Object
604 605 606 |
# File 'app/services/item/heating_element_plan.rb', line 604 def flooring_label is_outdoor? || is_countertop? ? 'Surface Type' : 'Flooring' end |
#generate_heating_elements_lines ⇒ Object
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'app/services/item/heating_element_plan.rb', line 194 def generate_heating_elements_lines self.heating_elements_lines = [] heating_element_number = 0 heating_elements_line_items.each do |he_line_item| if he_line_item.item.spec_value(:plan_grouping) == 'group_qty_to_length' # Group items by sku on plan # Build heating element line will use implicit line item quantity multiplier heating_elements_lines << build_from_line_item(he_line_item) else # one line per quantity will split the line items rendering one in the table for each qty he_line_item.quantity.times do heating_element_number += 1 # Force quantity multiplier to one since we're splitting the rendering heating_elements_lines << build_from_line_item(he_line_item, 1, heating_element_number) end end end end |
#has_item?(sku) ⇒ Boolean
447 448 449 |
# File 'app/services/item/heating_element_plan.rb', line 447 def has_item?(sku) line_items_for_sku(sku).present? end |
#heating_elements_table(with_cold_lead: false, with_ohms: false, with_pole_assignment: false) ⇒ Object
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 |
# File 'app/services/item/heating_element_plan.rb', line 345 def heating_elements_table(with_cold_lead: false, with_ohms: false, with_pole_assignment: false) table = [] heating_elements_lines.each_with_index do |hel, i| row = {} row[:row_number] = i + 1 heating_elements_table_column_headers(with_cold_lead: with_cold_lead, with_ohms: with_ohms, with_row_number: false, with_pole_assignment: with_pole_assignment).each_key do |attrib| row[attrib] = if attrib == :volts hel.volts_with_alternative_volts(alternative_volts_explanation) else hel.send(attrib) end end table << row end table end |
#heating_elements_table_column_headers(with_cold_lead: false, with_ohms: false, with_row_number: true, with_pole_assignment: false) ⇒ Object
rubocop:disable Lint/UnusedMethodArgument
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'app/services/item/heating_element_plan.rb', line 317 def heating_elements_table_column_headers(with_cold_lead: false, with_ohms: false, with_row_number: true, with_pole_assignment: false) # rubocop:disable Lint/UnusedMethodArgument _ = with_cold_lead _ = with_ohms headers = {} headers[:row_number] = '#' if with_row_number unless /TempZone Custom Mat/i.match?(heating_system) headers[:imperial_width] = (cable_spacing.present? ? 'Spacing' : 'Width') unless /roof|pipe/i.match?(heating_system) headers[:imperial_length] = 'Length' end headers[:imperial_cold_lead_length] = 'Lead' unless /roof|pipe/i.match?(heating_system) headers[:volts] = 'Volts' if /roof|pipe/i.match?(heating_system) headers[:watts_per_linear_feet] = 'Watts Per Ft' else headers[:watts] = 'Watts' headers[:btu_per_hr] = 'BTU/h' headers[:amps] = 'Amps' headers[:ohms] = 'Ohms' end if with_pole_assignment headers[:poles] = 'Poles' headers[:relay] = 'Relay' end headers end |
#heating_elements_table_footers ⇒ Object
362 363 364 365 366 367 368 369 370 371 |
# File 'app/services/item/heating_element_plan.rb', line 362 def return {} if heating_elements_lines.length <= 1 # don't add a footer if there's only 1 row = {} [:imperial_length] = UnitConversions.inches_to_feetinches(total_length) if heating_system.index(/roof|pipe/i) [:watts] = total_watts unless heating_system.index(/roof|pipe/i) [:btu_per_hr] = total_btu_per_hr unless heating_system.index(/roof|pipe/i) [:amps] = total_amps unless heating_system.index(/roof|pipe/i) end |
#heating_system_name ⇒ Object
548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'app/services/item/heating_element_plan.rb', line 548 def heating_system_name case heating_system when 'TempZone Thin Cable' 'TempZone 3W Cable' when 'TempZone Cable' 'TempZone 3.7W Cable' when 'TempZone Ruler Cable' 'TempZone 3.7W Ruler Cable' else heating_system end end |
#heating_system_voltage ⇒ Object
576 577 578 |
# File 'app/services/item/heating_element_plan.rb', line 576 def heating_system_voltage voltage || first_heating_element_voltage end |
#heating_system_with_voltage ⇒ Object
561 562 563 564 565 566 567 568 569 570 |
# File 'app/services/item/heating_element_plan.rb', line 561 def heating_system_with_voltage addendum_for_mixed_systems = '' addendum_for_mixed_systems = ' & Cable' if (heating_system_name.to_s.downcase.index('mat') || heating_system_name.to_s.downcase.index('roll')) && heating_elements_line_items.any? do |li| li.item.is_cable_system? end addendum_for_mixed_systems = ' & Mat/Roll' if heating_system_name.to_s.downcase.index('cable') && !heating_system_name.to_s.downcase.index('roof') && !heating_system_name.to_s.downcase.index('pipe') && heating_elements_line_items.any? do |li| !li.item.is_cable_system? end "#{heating_system_name}#{addendum_for_mixed_systems} #{voltage}V" end |
#hide_flip_turn? ⇒ Boolean
544 545 546 |
# File 'app/services/item/heating_element_plan.rb', line 544 def hide_flip_turn? [nil, 'Environ Flex Roll'].include?(heating_system) end |
#highlighted_columns ⇒ Object
313 314 315 |
# File 'app/services/item/heating_element_plan.rb', line 313 def highlighted_columns %i[voltage watts btu_per_hr amps ohms] end |
#instructions(include_electrical_plan_rules = false, include_installation_plan_rules = false) ⇒ Object
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 |
# File 'app/services/item/heating_element_plan.rb', line 810 def instructions(include_electrical_plan_rules = false, include_installation_plan_rules = false) inst = [] inst << 'All power leads travel back to thermostat or junction box.' if ['TempZone Flex Roll', 'Environ Flex Roll', 'Environ Easy Mat', 'TempZone Easy Mat', 'TempZone Cable', 'TempZone Ruler Cable', 'TempZone Thin Cable', 'Slab Heat Cable', 'Slab Heat Mat', 'TempZone Shower Mat', 'Shower Mat Bench'].include?(heating_system) inst << 'All power leads travel back to the controller, relay panel or junction box.' if heating_system.index(/roof|snow|pipe/i) if include_installation_plan_rules == true inst << 'Always start warming cable down unless noted otherwise.' if ['TempZone Flex Roll', 'Environ Flex Roll'].include?(heating_system) inst << 'Cut only mesh, never cut warming cable.' if ['TempZone Flex Roll', 'Slab Heat Mat', 'Snow Melt Mat', 'Snow Melt PowerMat', 'Snow Melt OmniMat', 'Snow Melt EcoMat'].include?(heating_system) inst << 'Cut only silver material, never cut warming cable.' if ['Environ Flex Roll'].include?(heating_system) inst << 'Never cut heating rolls.' if ['Environ Easy Mat', 'TempZone Easy Mat', 'TempZone Shower Mat', 'Shower Mat Bench'].include?(heating_system) inst << 'Never cut heating cable.' if ['TempZone Cable', 'TempZone Ruler Cable', 'TempZone Thin Cable', 'Snow Melt Cable', 'Snow Melt Cable'].include?(heating_system) inst << 'Never wire multiple rolls or cables together.' # all systems inst << 'Verify sum of panels equals roll length for each roll.' if ['TempZone Flex Roll', 'Environ Flex Roll', 'Slab Heat Mat', 'Snow Melt Mat', 'Snow Melt PowerMat', 'Snow Melt OmniMat', 'Snow Melt EcoMat'].include?(heating_system) end inst << 'Keep the bus wires separated. The bus wires will short if they touch each other.' if heating_system.index(/roof|pipe/i) inst << 'Keep components and ends of heating cable dry before installation.' if heating_system.index(/roof|pipe/i) inst << 'The heating cable should not be embedded in insulation or roofing material.' if heating_system.index(/roof/i) inst << 'Do not twist cable during installation.' if heating_system.index(/roof|pipe/i) if include_electrical_plan_rules == true inst << 'Always test rolls/cables out of the box with an Ohm meter and Mega-Ohm meter (optional). See manual for other required tests.' # all systems unless heating_system.index(/roof|pipe|snow/i) inst << 'Integration Kit: Can be installed on the side or inside of the separate electrical box or a distribution panel, according to NEC and local code requirements.' if integration_kits.present? if has_item?(%w[UWG4-4999 UWG4-4999-WY UWG5-4999-WY UWG4-4999-B UDG4-4999 UDG4-4999-WY UDG4-4999-B UDG-4999 UTN4-4999 USG-4000 USG5-4000]) # if an OJ tstat is present tstat_box_size = conduit_box_size = '3"x2"x3-1/2" single gang' else tstat_box_size = '4"x4" square' conduit_box_size = '4" double gang' end if thermostats.any? && integration_kits.blank? inst << "Thermostat: Install a #{tstat_box_size}, 2-1/8\" deep electrical box according to NEC and local code requirements. Electrical boxes should be located on interior walls, commonly 60\" from the floor." end inst << "Power lead Conduit: The shielded power lead can be installed with or without electrical conduit depending on local code requirements. In either case, remove one of the knock-outs in the #{conduit_box_size} box to route the lead. If electrical conduit is not required by code, install a wire collar to secure the leads where they enter the box." if sensors.present? inst << 'Floor Sensor: A floor sensor comes with our floor heating systems. It can be installed in a conduit separate from the electrical power lead. If local code requires the low voltage sensor wire be housed in conduit, it must use a separate conduit from the power leads (high voltage).' end if power_modules.present? inst << 'Power module(s) must be wired to the main Thermostat using low-voltage field wiring cable, recommended min. 20 AWG. Connect wiring from A&B terminals on the front of the thermostat base to C&D on the front of the power module base. (Keep polarity: A to C and B to D). Maximum distance between thermostat and power modules is 80 ft (25 m.) See the diagrams in the power module box.' end end end inst end |
#integration_kits ⇒ Object
Alias for All_line_items#integration_kits
437 |
# File 'app/services/item/heating_element_plan.rb', line 437 delegate :integration_kits, to: :all_line_items |
#is_countertop? ⇒ Boolean
592 593 594 |
# File 'app/services/item/heating_element_plan.rb', line 592 def is_countertop? is_countertop == true end |
#is_environ? ⇒ Boolean
242 243 244 |
# File 'app/services/item/heating_element_plan.rb', line 242 def is_environ? ['Environ Flex Roll', 'Environ Easy Mat'].include?(heating_system) end |
#is_indoor_floor_heating_system? ⇒ Boolean
237 238 239 240 |
# File 'app/services/item/heating_element_plan.rb', line 237 def is_indoor_floor_heating_system? ['TempZone Flex Roll', 'TempZone Easy Mat', 'TempZone Shower Mat', 'Shower Mat Bench', 'TempZone Cable', 'TempZone Ruler Cable', 'TempZone Thin Cable', 'Environ Flex Roll', 'Environ Easy Mat'].include?(heating_system) end |
#is_outdoor? ⇒ Boolean
588 589 590 |
# File 'app/services/item/heating_element_plan.rb', line 588 def is_outdoor? heating_system.index(/roof|snow|pipe/i) != nil end |
#is_pipe_freeze? ⇒ Boolean
596 597 598 |
# File 'app/services/item/heating_element_plan.rb', line 596 def is_pipe_freeze? heating_system.index(/pipe/i) != nil end |
#legend ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'app/services/item/heating_element_plan.rb', line 213 def legend symbols = case heating_system when /TempZone Flex Roll|Environ Flex Roll|TempZone Shower Mat|Shower Mat Bench/i %w[start end roll_number] when /Snow Melt Mat|TempZone Easy Mat|Slab Heat Mat/i %w[start end mat_number] when /TempZone Cable|TempZone Ruler Cable|TempZone Thin Cable|Snow Melt Cable|Slab Heat Cable/i %w[start end cable_number halfway_mark] when /roof|pipe/i %w[start end cable_number] when 'Environ Easy Mat' ['roll_number'] else [] end symbols << 'thermostat' if all_line_items.thermostats.present? symbols << 'relay' if relays.present? && is_indoor_floor_heating_system? symbols << 'power_module' if all_line_items.power_modules.present? symbols << 'integration_kit' if integration_kits.present? symbols << 'ot_sensor' if ot_sensors.present? symbols << 'slab_sensor' if has_item?('SLAB-SS') || has_item?('SCE-SLAB-SS-56') symbols end |
#line_items_for_sku(sku) ⇒ Object
451 452 453 |
# File 'app/services/item/heating_element_plan.rb', line 451 def line_items_for_sku(sku) all_line_items.joins(:item).where(items: { sku: }) end |
#number_of_circuits ⇒ Object
484 485 486 487 488 489 490 491 492 |
# File 'app/services/item/heating_element_plan.rb', line 484 def number_of_circuits circuits = 0 if integration_kits.sum(:quantity).positive? circuits = integration_kits.sum(:quantity) else electrical_plan_controls.each { |c| circuits += (c.item.spec_value(:circuits_required).to_i * c.quantity) } end circuits end |
#ot_sensors ⇒ Object
463 464 465 |
# File 'app/services/item/heating_element_plan.rb', line 463 def ot_sensors line_items_for_sku(['SCP-120', *ItemConstants::POWER_MODULATORS]) end |
#other_items_table ⇒ Object
373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'app/services/item/heating_element_plan.rb', line 373 def other_items_table oi_table = [] other_items.each do |line_item| item_name = begin "#{line_item.item.sku} - #{line_item.item.name}" rescue StandardError 'n/a' end oi_table << [item_name, line_item.quantity] end oi_table end |
#power_kits ⇒ Object
455 456 457 |
# File 'app/services/item/heating_element_plan.rb', line 455 def power_kits line_items_for_sku('SR-PWR-KIT') end |
#power_modules ⇒ Object
Alias for All_line_items#power_modules
435 |
# File 'app/services/item/heating_element_plan.rb', line 435 delegate :power_modules, to: :all_line_items |
#relays ⇒ Object
443 444 445 |
# File 'app/services/item/heating_element_plan.rb', line 443 def relays all_line_items.relay_panels end |
#requires_breaker_size_vs_circuit_length_table? ⇒ Boolean
532 533 534 535 536 537 538 |
# File 'app/services/item/heating_element_plan.rb', line 532 def requires_breaker_size_vs_circuit_length_table? if heating_system.match(/roof|pipe/i) && (has_item?(ItemConstants::PIPE_TRACING_CABLE_5_WATT_PER_FT_SPOOL_SKUS) || has_item?(ItemConstants::PIPE_TRACING_CABLE_8_WATT_PER_FT_SPOOL_SKUS) || has_item?(ItemConstants::PIPE_TRACING_CABLE_10_WATT_PER_FT_SPOOL_SKUS)) return true end false end |
#roof_and_gutter_breaker_recommendations(volts) ⇒ Object
524 525 526 527 528 529 530 |
# File 'app/services/item/heating_element_plan.rb', line 524 def roof_and_gutter_breaker_recommendations(volts) if volts == 120 "<table class='rg-breakers'><tr><th>Max Length</th><th>Breaker</th></tr><tr><td>107 ft</td><td>15 A 120V GFEP</td></tr><tr><td>142 ft</td><td>20 A 120V GFEP</td></tr><tr><td>214 ft</td><td>30 A 120V GFEP</td></tr></table>" elsif volts == 240 "<table class='rg-breakers'><tr><th>Max Length</th><th>Breaker</th></tr><tr><td>214 ft</td><td>15 A 240V GFEP</td></tr><tr><td>286 ft</td><td>20 A 240V GFEP</td></tr><tr><td>429 ft</td><td>30 A 240V GFEP</td></tr></table>" end end |
#roof_and_gutter_breaker_size(volts, length) ⇒ Object
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
# File 'app/services/item/heating_element_plan.rb', line 504 def roof_and_gutter_breaker_size(volts, length) # length will be in inches, so lets convert it to feet length /= 12 if volts == 120 case length when 0..107 then 15 when 108..142 then 20 else 30 end elsif volts == 240 case length when 0..214 then 15 when 215..286 then 20 else 30 end else # not set up for that voltage, so just give the max 30 end end |
#room_label ⇒ Object
600 601 602 |
# File 'app/services/item/heating_element_plan.rb', line 600 def room_label is_outdoor? ? 'Area' : 'Room' end |
#sensors ⇒ Object
476 477 478 |
# File 'app/services/item/heating_element_plan.rb', line 476 def sensors all_line_items.has_floor_sensor end |
#shorten_text(text, num_chars = 32) ⇒ Object
855 856 857 858 859 |
# File 'app/services/item/heating_element_plan.rb', line 855 def shorten_text(text, num_chars = 32) res = text res = "#{text.to_s[0..(num_chars - 4)]} ..." if text.to_s.length > num_chars res end |
#slab_heat_cable_watts_per_sqft ⇒ Object
183 184 185 186 187 188 189 190 191 192 |
# File 'app/services/item/heating_element_plan.rb', line 183 def slab_heat_cable_watts_per_sqft { '3': 23, '3.0': 23, '4': 17, '4.0': 17, '5': 15, '5.0': 15 }.fetch((cable_spacing || 3.0).round(2).to_s.to_sym, 23) end |
#snow_melt_cable_watts_per_sqft ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'app/services/item/heating_element_plan.rb', line 167 def snow_melt_cable_watts_per_sqft { '2.5': 'Up to 60', '3': 'Up to 50', '3.0': 'Up to 50', '3.5': 'Up to 43', '4': 'Up to 38.5', '4.0': 'Up to 38.5', '4.5': 'Up to 33', '5': 'Up to 31.5', '5.0': 'Up to 31.5', '6': 'Up to 25', '6.0': 'Up to 25' }.fetch((cable_spacing || 3.0).round(2).to_s.to_sym, 50) end |
#special_instructions ⇒ Object
Is this needed? We already put that in the instructions if an AIR-SS is present.
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'app/services/item/heating_element_plan.rb', line 247 def special_instructions instructions = [] if ot_sensors.present? instructions << "* Installers may locate the OT Sensor at their discretion. Placement shown is a recommendation only. Sensor must be inside metal conduit (capped off for replaceability) between two passes of heat cable." end if has_item?('SLAB-SS') || has_item?('SCE-SLAB-SS-56') instructions << "# Installers may locate Slab Sensor at their discretion. Placement shown is a recommendation only. Sensor should be located between two passes of Heating Cable where snow and ice problems normally occur. Sensor must be embedded horizontally with its top flush with the surroundings with the help of the accompanying installation plate." end instructions end |
#tempzone_thick_cable_watts_per_sqft ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'app/services/item/heating_element_plan.rb', line 150 def tempzone_thick_cable_watts_per_sqft { '2.5': 17.76, '2.9': 15.3, '3': 14.8, '3.0': 14.8, '3.13': 14.2, '3.5': 12.7, '3.75': 11.84, '4': 11.1, '4.0': 11.1, '4.75': 9.3, '5': 8.9, '5.0': 8.9 }.fetch((cable_spacing || 3.0).round(2).to_s.to_sym, 14.8) end |
#tempzone_thin_cable_watts_per_sqft ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'app/services/item/heating_element_plan.rb', line 133 def tempzone_thin_cable_watts_per_sqft { '2.5': 14.4, '2.9': 12.4, '3': 12, '3.0': 12, '3.13': 11.5, '3.5': 10.3, '3.75': 9.6, '4': 8.7, '4.0': 8.7, '4.75': 7.6, '5': 7.2, '5.0': 7.2 }.fetch((cable_spacing || 3.0).round(2).to_s.to_sym, 12) end |
#thermostats ⇒ Object
Alias for All_line_items#thermostats
439 |
# File 'app/services/item/heating_element_plan.rb', line 439 delegate :thermostats, to: :all_line_items |
#total_amps ⇒ Object
423 424 425 |
# File 'app/services/item/heating_element_plan.rb', line 423 def total_amps heating_elements_lines.to_a.sum { |he| he.amps || 0 }.round(2) end |
#total_btu_per_hr ⇒ Object
399 400 401 |
# File 'app/services/item/heating_element_plan.rb', line 399 def total_btu_per_hr heating_elements_lines.to_a.sum { |he| he.btu_per_hr || 0 }.round end |
#total_length ⇒ Object
427 428 429 |
# File 'app/services/item/heating_element_plan.rb', line 427 def total_length heating_elements_lines.to_a.sum { |he| he.length || 0 } end |
#total_watts ⇒ Object
386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'app/services/item/heating_element_plan.rb', line 386 def total_watts heating_elements_lines.to_a.sum do |he| value = if he.respond_to?(:watts) he.watts elsif he.is_a?(Hash) he[:watts] || he['watts'] else 0 end (value || 0).to_f end.round end |
#watts_per_sqft(watts_only = false) ⇒ Object
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 127 128 129 130 131 |
# File 'app/services/item/heating_element_plan.rb', line 75 def watts_per_sqft(watts_only = false) watts = case heating_system when /TempZone Flex Roll|TempZone Shower Mat|TempZone Easy Mat|Shower Mat Bench/i 15 when 'TempZone Custom Mat' watts_only ? 12.5 : '12-15' when /Environ Flex Roll|Environ Easy Mat/i 12 when 'Snow Melt Mat' if cable_spacing.to_f.round == 4 'Up to 38.5' else (cable_spacing.to_f.round == 5 ? 'Up to 31.5' : 'Up to 50') end when 'Snow Melt PowerMat' 'Up to 50' when 'Snow Melt OmniMat' 'Up to 38.5' when 'Snow Melt EcoMat' 'Up to 31.5' when 'Slab Heat Mat' 20 when 'TempZone Thin Cable' tempzone_thin_cable_watts_per_sqft when 'TempZone Cable' tempzone_thick_cable_watts_per_sqft when 'TempZone Ruler Cable' tempzone_thick_cable_watts_per_sqft when 'Snow Melt Cable' snow_melt_cable_watts_per_sqft when 'Slab Heat Cable' slab_heat_cable_watts_per_sqft when /roof/i if watts_only heating_system_voltage == 208 ? 6.5 : 7.5 else heating_system_voltage == 208 ? '4-9' : '5-10' end when /pipe/i if has_item?(ItemConstants::PIPE_TRACING_CABLE_5_WATT_PER_FT_SPOOL_SKUS) 5 elsif has_item?(ItemConstants::PIPE_TRACING_CABLE_8_WATT_PER_FT_SPOOL_SKUS) 8 elsif has_item?(ItemConstants::PIPE_TRACING_CABLE_10_WATT_PER_FT_SPOOL_SKUS) 10 end end return watts if watts_only || watts.nil? text = if /roof|pipe/i.match?(heating_system) "#{watts} W/Ft." else "#{watts} W/Sq.ft." end text += " @ #{cable_spacing}\" spacing" if !is_environ? && cable_spacing text end |