Class: Quote::Copier
- Inherits:
-
Object
- Object
- Quote::Copier
- Defined in:
- app/services/quote/copier.rb
Instance Attribute Summary collapse
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#quote ⇒ Object
readonly
Returns the value of attribute quote.
-
#results ⇒ Object
readonly
Returns the value of attribute results.
Instance Method Summary collapse
- #append_deliveries(quote, new_quote, logger) ⇒ Object
- #clear_shipping_address(new_quote) ⇒ Object
- #copy_to(opportunity, options = {}) {|1, 5, 'Analyzing quote'| ... } ⇒ Object
-
#initialize(quote, options = {}) ⇒ Copier
constructor
A new instance of Copier.
Constructor Details
#initialize(quote, options = {}) ⇒ Copier
Returns a new instance of Copier.
5 6 7 8 9 10 |
# File 'app/services/quote/copier.rb', line 5 def initialize(quote, ={}) @options = @quote = quote @logger = [:logger] || Rails.logger @skip_room_plan_generation = [:skip_room_plan_generation] end |
Instance Attribute Details
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
3 4 5 |
# File 'app/services/quote/copier.rb', line 3 def logger @logger end |
#quote ⇒ Object (readonly)
Returns the value of attribute quote.
3 4 5 |
# File 'app/services/quote/copier.rb', line 3 def quote @quote end |
#results ⇒ Object (readonly)
Returns the value of attribute results.
3 4 5 |
# File 'app/services/quote/copier.rb', line 3 def results @results end |
Instance Method Details
#append_deliveries(quote, new_quote, logger) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'app/services/quote/copier.rb', line 118 def append_deliveries(quote, new_quote, logger) quote.deliveries.each do |dq| new_dq_attrs = dq.attributes.dup.symbolize_keys.except(:id, :quote_id, :selected_shipping_cost_id) logger.debug("Copying delivery", delivery_id: dq.id, origin_address_id: dq.origin_address_id) ndq = new_quote.deliveries.create! new_dq_attrs # Clone shipping costs dq.shipping_costs.each do |osc| logger.info "Adding shipping cost #{osc.id} to new delivery" nsc = osc.dup ndq.shipping_costs << nsc #nsc.save! end # Update shipping line in order orig_shipping_line = dq.line_items.detect(&:is_shipping?) # Remap our lines to the new delivery quotes new_quote.line_items.active_lines.select{|li| li.original_delivery_id == dq.id }.each do |li| if li.is_shipping? existing_shipping_option_id = orig_shipping_line&.shipping_cost.shipping_option_id li.shipping_cost = ndq.shipping_costs.detect{|sc| sc.shipping_option_id == existing_shipping_option_id } end li.delivery = ndq #remap li.save! end # Clone shipments dq.shipments.each do |shp| logger.info "Adding shipment #{shp.id} to new delivery" nshp = shp.dup nshp.container_code = nil # do this in case of quote pre-pack assigning a container code because duplicate container codes will prevent saving - Ramie ndq.shipments << nshp end # Ensure selected shipping cost is remapped to new delivery if dq.selected_shipping_cost&.shipping_option.present? ndq.reload ndq.selected_shipping_cost_id = ndq.shipping_costs.detect{|sc| sc.shipping_option_id == dq.selected_shipping_cost.shipping_option_id}&.id ndq.save end end new_quote.deliveries.size end |
#clear_shipping_address(new_quote) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 |
# File 'app/services/quote/copier.rb', line 159 def clear_shipping_address(new_quote) # remove shipping lines new_quote.line_items.active_lines.each do |li| # must do this first because we are in before_save context, even a destroyed line item will fail the validation on order save li.delivery_id = nil li.destroy if li.is_shipping? end new_quote.shipping_address_id = nil new_quote.recalculate_shipping = false new_quote.do_not_detect_shipping = true end |
#copy_to(opportunity, options = {}) {|1, 5, 'Analyzing quote'| ... } ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 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 |
# File 'app/services/quote/copier.rb', line 12 def copy_to(opportunity, = {}, &block) customer = @quote.customer # If this method is called from a larger operation, e.g an opportunity copy which copies # many rooms, many quotes. We want to know the rooms that were already copied so we # don't re-clone them. Room map is a hash { old_rc_id => new_rc_id } room_map = [:room_map] || {} yield(1, 5, 'Analyzing quote') if block_given? report = { errors: [], successes: [], new_quote: []} new_rc_ids = [] Quote.transaction do begin #Garbage stays behind @quote.orders.cancelled.each(&:destroy) @quote.orders.carts.each(&:destroy) yield(2, 5, 'Creating cloned room configurations') if block_given? # Here we will exclude the cloning of rooms that were already copied room_configurations = @quote.room_configurations # Keep track of our original rooms in this quote original_room_configuration_ids = room_configurations.map(&:id) if room_map.present? room_configurations = room_configurations.where.not(id: room_map.keys) end res_rc_copy = RoomConfiguration::Copier.new(room_configurations, skip_room_plan_generation: true).copy_to(opportunity, &block) # Now that we have an additional room map, we will merge it with our existing map room_map = room_map.merge(res_rc_copy.room_copy_results) # Ok finally, now, what are the new room configuration ids provided by our merged map new_rc_ids = original_room_configuration_ids.map{|old_rc_id| room_map[old_rc_id]} # these are the new room configuration ids # If for some reason we're missing a mapping, this indicates a problem we need to abort if new_rc_ids.any?(&:nil?) raise StandardError.new("Rooms were not copied and are missing in quote cloner, original: #{original_room_configuration_ids.join(', ')} and resulting map is #{new_rc_ids.join(', ')}") end yield(3, 5, 'Creating cloned quote') if block_given? @new_quote = @quote.deep_dup @new_quote.tap do |q| q.disable_auto_coupon = true # q.line_items = [] # this is just wrong! To be deleted - Ramie 030223 q.room_configuration_ids = [] q.pricing_program_description = customer.pricing_program_description q.pricing_program_discount = customer.pricing_program_discount q.shipping_address = @quote.shipping_address q.state = 'pending' q.contact_points.clear # Clear out to be safe q.reference_number = nil q.opportunity_id = opportunity.id q.created_at = nil q.updated_at = nil q.room_configuration_ids = [] # We also need to copy/clone ungrouped items, the room config line items that were cloned gets added later # Basically now our quote has a copy of all line items (thanks to deep_dup) but we need to remove all those # line items belonging to a room q.line_items = q.line_items.to_a.reject(&:room_configuration_id) end @new_quote.save! # This will add the line items back @new_quote.room_configuration_ids = new_rc_ids.uniq.sort @new_quote.quick_note "Quote was copied from #{@quote.reference_number} in customer #{customer.reference_number}" @new_quote.reload # Keep references @new_quote.uploads.each{|u| u.update(category: 'archive', note: "Was #{u.category}") } if @quote.deliveries.any? and @quote.shipping_address.present? append_deliveries(@quote, @new_quote, logger) else logger.info " * quote has no delivery quotes, removing shipping address and shipping lines if any" clear_shipping_address(@new_quote) end # Technically this is already done earlier when we assign the room id yield(4, 5, 'Copying and remapping room configurations') if block_given? @new_quote.room_configurations.each do |nrc| nrc.synchronize_lines(@new_quote) end yield(4, 5, 'Resetting discount and tax rate') if block_given? @new_quote.reset_discount @new_quote.refresh_tax_rate msg = "Copying #{@quote.name} to the target opportunity #{opportunity.name} (#{opportunity.reference_number})." report[:successes] << msg report[:new_quote] << @new_quote.id.to_s # logger.info msg rescue StandardError => exc msg = "Cannot copy the #{@quote.name} to the target opportunity #{opportunity.name} (#{opportunity.reference_number}) due to errors: #{exc.to_s}" logger.error msg report[:errors] << msg raise ActiveRecord::Rollback end end yield(5, 5, 'Finishing and queuing floorplan generation') if block_given? unless @skip_room_plan_generation RoomConfiguration::Copier.generate_all_plans(RoomConfiguration.where(id: new_rc_ids)) end report end |