Class: Pdf::Document::PriceList
- Inherits:
-
Object
- Object
- Pdf::Document::PriceList
- Includes:
- ActionView::Helpers::NumberHelper, ActiveModel::API, ActiveModel::Attributes, ActiveModel::Validations, ActiveModel::Validations::Callbacks, Heatwave::AttributeNormalizing, Base, StripAttributes
- Defined in:
- app/services/pdf/document/price_list.rb
Overview
Service object: price list.
Constant Summary collapse
- SECTIONS =
Sections.
{ 'Floor Heating': { fh_tempzone_flex_twin_120: 'TempZone Flex 120V', fh_tempzone_flex_twin_240: 'TempZone Flex 240V', fh_tempzone_cable_120: 'TempZone Cable 120V', fh_tempzone_cable_240: 'TempZone Cable 240V', fh_tempzone_ruler_cable_120: 'TempZone Ruler Cable 120V', fh_tempzone_ruler_cable_240: 'TempZone Ruler Cable 240V', fh_tempzone_easy_twin_120: 'TempZone Easy Mat 120V', fh_tempzone_shower_bench: 'TempZone Shower Bench Mat', fh_tempzone_shower_floor: 'TempZone Shower Floor Mat', fh_tempzone_custom: 'TempZone Custom Mat', fh_environ_flex_120: 'Environ Flex 120V', fh_environ_flex_240: 'Environ Flex 240V', fh_environ_easy_120: 'Environ Easy Mat 120V', fh_environ_easy_240: 'Environ Easy Mat 240V', fh_slab_cable: 'Slab Heating Cable', fh_slab_mat: 'Slab Heating Mat', fh_controls: 'Controls', fh_power_modules: 'Power Modules', fh_relay_panels: 'Relay Panels', fh_underlayment: 'Underlayment', fh_rough_in_kits: 'Rough-in Kits', fh_installation_kits: 'Installation Kits', fh_accessories: 'Accessories', fh_spare_parts: 'Spare Parts' }, 'Towel Warmers': { tw_classic_plugin: 'Classic Plug-in', tw_classic_hardwired: 'Classic Hardwired', tw_classic_dual: 'Classic Dual Connection (Plug-in or Hardwired)', tw_cosmopolitan_hardwired: 'Cosmopolitan Hardwired', tw_controls: 'Towel Warmer Controls' }, 'Infrared Heating Panels': { rp_lava_glass: 'Lava Glass', rp_lava_mirror: 'Lava Mirror', rp_lava_crystal: 'Lava Crystal', rp_lava_light: 'Lava Light', rp_lava_accessories: 'Lava Accessories', rp_ember_flex: 'Ember Flex', rp_ember_glass: 'Ember Glass', rp_ember_mirror: 'Ember Mirror', rp_ember_accessories: 'Ember Accessories', rp_controls: 'Controls' }, Mirrors: { mirror_led_marquee: 'Marquee LED Mirrors', mirror_defoggers: 'Mirror Defoggers' }, 'FeelsWarm® Countertop Heating': { ch_standard: 'Standard Kit', ch_custom: 'Custom Kit', ch_controls: 'Controls' }, 'Shower Kits': { sk_shower_pan_kit: 'Shower Pan Kit', sk_drain_assembly_kit: 'Drain Assembly Kit', sk_drain_grate_covers: 'Drain Grate Covers', sk_shower_floor_heating_kits: 'Shower Floor Heating Kits', sk_accessories: 'Accessories', sk_drain_assemblies: 'Drain Assemblies' }, 'Snow Melting': { sm_mat_120: 'Mat 120V', sm_mat_240: 'Mat 240V', sm_cable_120: 'Cable 120V', sm_cable_240: 'Cable 240V', sm_cable_208: 'Cable 208V', sm_cable_277: 'Cable 277V', sm_controls: 'Controls', sm_sensors: 'Sensors', sm_relay_panels: 'Relay Panels', sm_accessories: 'Accessories' }, 'Roof & Gutter Deicing': { rgd_self_regulating_cable_120: 'Self Regulating Cable 120V', rgd_self_regulating_cable_240: 'Self Regulating Cable 240V', rgd_constant_wattage_kit: 'Constant Wattage Kit', rgd_controls: 'Controls', rgd_sensors: 'Sensors', rgd_relay_panels: 'Relay Panels', rgd_accessories: 'Accessories' }, 'Pipe Freeze Protection': { pfp_self_regulating_cable_120: 'Self Regulating Cable 120V', pfp_self_regulating_cable_240: 'Self Regulating Cable 240V', pfp_constant_wattage_cable: 'Constant Wattage Cable', pfp_controls: 'Controls', pfp_accessories: 'Accessories' } }.freeze
- SECTION_SPEC_COLUMNS =
Maps section key prefix → [extra spec symbols] shown between NAME and PRICE
{ 'fh_tempzone_flex' => { extra: %i[width length coverage watts amps] }, 'fh_tempzone_cable' => { extra: %i[width length coverage watts amps] }, 'fh_tempzone_ruler' => { extra: %i[width length coverage watts amps] }, 'fh_tempzone_easy' => { extra: %i[coverage watts amps] }, 'fh_tempzone_shower' => { extra: %i[coverage watts] }, 'fh_tempzone_custom' => { extra: %i[coverage watts] }, 'fh_environ_flex' => { extra: %i[width length coverage watts amps] }, 'fh_environ_easy' => { extra: %i[coverage watts amps] }, 'fh_slab' => { extra: %i[length watts amps] }, 'fh_controls' => { extra: %i[maximum_current], name_col: true }, 'fh_power_modules' => { extra: %i[maximum_current], name_col: true }, 'fh_relay_panels' => { name_col: true }, 'fh_underlayment' => { extra: %i[width length], name_col: true }, 'fh_rough_in_kits' => { name_col: true }, 'fh_installation_kits' => { name_col: true }, 'fh_accessories' => { name_col: true }, 'fh_spare_parts' => { name_col: true }, 'tw_' => { extra: %i[finish width height depth], name_col: true, dimension_unit: 'in' }, 'rp_' => { name_col: true }, 'mirror_' => { name_col: true }, 'ch_' => { name_col: true }, 'sk_' => { name_col: true }, 'sm_mat' => { extra: %i[width length coverage watts amps] }, 'sm_cable' => { extra: %i[length watts amps] }, 'sm_controls' => { extra: %i[maximum_current], name_col: true }, 'sm_sensors' => { name_col: true }, 'sm_relay_panels' => { name_col: true }, 'sm_accessories' => { name_col: true }, 'rgd_' => { name_col: true }, 'pfp_' => { name_col: true } }.freeze
- GROUP_HEADINGS =
Maps section key → group heading shown before first section in that family
{ 'fh_' => 'FLOOR HEATING', 'tw_' => 'TOWEL WARMERS', 'rp_' => 'INFRARED HEATING PANELS', 'mirror_' => 'MIRRORS', 'ch_' => "FEELSWARM\u00AE COUNTERTOP HEATING", 'sk_' => 'SHOWER KITS', 'sm_' => 'SNOW MELTING', 'rgd_' => 'ROOF & GUTTER DEICING', 'pfp_' => 'PIPE FREEZE PROTECTION' }.freeze
- DIMENSION_SPECS =
Dimension specs.
%i[width length height depth].freeze
- DEFAULT_DIMENSION_UNIT =
Default unit that dimension columns (WIDTH/LENGTH/…) render in, unless a
section opts out viadimension_unit:in SECTION_SPEC_COLUMNS (towel
warmers keep inches for their finish/width/height/depth specs). 'ft'- SPEC_UNIT_LABELS =
Spec unit labels.
{ 'in' => 'in.', 'ft' => 'ft', 'mm' => 'mm', 'cm' => 'cm', 'm' => 'm' }.freeze
- FLAG_IMAGE_PATHS =
Catalogs that get a country flag in the ITEM # column. Any other catalog
surfaces its name in the header instead. { 'WarmlyYours-US' => Rails.public_path.join('images', 'pdf', 'flag-us.png').to_s, 'WarmlyYours-CA' => Rails.public_path.join('images', 'pdf', 'flag-ca.png').to_s }.freeze
Constants included from Base
Base::FONT, Base::NIMBUS_SANS_PATH, Base::NIMBUS_SANS_PATH_BOLD, Base::WY_LOGO_PATH
Instance Attribute Summary collapse
-
#renderer ⇒ Object
readonly
Returns the value of attribute renderer.
Class Method Summary collapse
-
.details_and_prices_for(catalog_id:, product_line_path: nil, product_category_path: nil, available_to_public_only: true, skus: [], sku_regex: nil, exact_product_category: false, item_condition: nil) ⇒ Object
Uses ltree path-based queries (no DB lookup needed).
- .item_conditions_for_select ⇒ Object
Instance Method Summary collapse
- #call ⇒ Object
- #catalog ⇒ Object
-
#details_and_prices_for(product_line_path:, product_category_path: nil, exact_product_category: false, available_to_public_only: true) ⇒ Object
Instance method delegates to class method.
- #file_name ⇒ Object
-
#initialize(options = {}) ⇒ PriceList
constructor
A new instance of PriceList.
Methods included from Heatwave::AttributeNormalizing
Constructor Details
#initialize(options = {}) ⇒ PriceList
Returns a new instance of PriceList.
154 155 156 |
# File 'app/services/pdf/document/price_list.rb', line 154 def initialize( = {}) super end |
Instance Attribute Details
#renderer ⇒ Object (readonly)
Returns the value of attribute renderer.
16 17 18 |
# File 'app/services/pdf/document/price_list.rb', line 16 def renderer @renderer end |
Class Method Details
.details_and_prices_for(catalog_id:, product_line_path: nil, product_category_path: nil, available_to_public_only: true, skus: [], sku_regex: nil, exact_product_category: false, item_condition: nil) ⇒ Object
Uses ltree path-based queries (no DB lookup needed)
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'app/services/pdf/document/price_list.rb', line 177 def self.details_and_prices_for(catalog_id:, product_line_path: nil, product_category_path: nil, available_to_public_only: true, skus: [], sku_regex: nil, exact_product_category: false, item_condition: nil) if skus.any? sku_order_sql = skus.each_with_index.map { |sku, i| "WHEN '#{sku}' THEN #{i}" }.join(' ') items = Item.where(sku: skus).order(Arel.sql("CASE sku #{sku_order_sql} END")) elsif sku_regex items = Item.where('sku ~* ?', sku_regex).order(price: :asc, sku: :asc) else items = Item.by_product_line_path(product_line_path) if product_category_path.present? items = exact_product_category ? items.by_product_category_path_exact(product_category_path) : items.by_product_category_path(product_category_path) end items = items.available_to_public if available_to_public_only items = items.order(:price, :sku) end price_sql = "(select amount from catalog_items left join store_items on store_items.id = catalog_items.store_item_id left join items items2 on items2.id = store_items.item_id where store_items.location = 'AVAILABLE' and catalog_id = #{catalog_id} and items2.id = items.id)" items = items.select("items.*,#{price_sql} as price") items = items.where("#{price_sql} is not null") items = items.where(condition: item_condition) if item_condition.present? items end |
.item_conditions_for_select ⇒ Object
158 159 160 |
# File 'app/services/pdf/document/price_list.rb', line 158 def self.item_conditions_for_select [['Any', ''], ['New Only', 'new'], ['Refurb/B-stocks', 'refurbished']] end |
Instance Method Details
#call ⇒ Object
205 206 207 208 209 210 211 212 213 214 |
# File 'app/services/pdf/document/price_list.rb', line 205 def call composer = build_composer draw_body(composer) (composer) io = StringIO.new composer.write(io, optimize: true) file_path = Rails.application.config.x.temp_storage_path.join(file_name) File.binwrite(file_path, io.string) Upload.uploadify(file_path, 'price_list_pdf', nil, file_name) end |
#catalog ⇒ Object
220 221 222 223 224 |
# File 'app/services/pdf/document/price_list.rb', line 220 def catalog return @catalog if defined?(@catalog) @catalog = catalog_id && Catalog.find(catalog_id) end |
#details_and_prices_for(product_line_path:, product_category_path: nil, exact_product_category: false, available_to_public_only: true) ⇒ Object
Instance method delegates to class method
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'app/services/pdf/document/price_list.rb', line 163 def details_and_prices_for(product_line_path:, product_category_path: nil, exact_product_category: false, available_to_public_only: true) Pdf::Document::PriceList.details_and_prices_for( catalog_id: catalog.id, product_line_path:, product_category_path:, item_condition:, exact_product_category:, available_to_public_only: ) end |
#file_name ⇒ Object
216 217 218 |
# File 'app/services/pdf/document/price_list.rb', line 216 def file_name 'price_list.pdf' end |