Class: SpreeDelhivery::ShipmentSender
- Inherits:
-
Object
- Object
- SpreeDelhivery::ShipmentSender
- Defined in:
- app/services/spree_delhivery/shipment_sender.rb
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(shipment) ⇒ ShipmentSender
constructor
A new instance of ShipmentSender.
Constructor Details
#initialize(shipment) ⇒ ShipmentSender
Returns a new instance of ShipmentSender.
3 4 5 6 7 8 9 |
# File 'app/services/spree_delhivery/shipment_sender.rb', line 3 def initialize(shipment) @shipment = shipment @order = shipment.order @address = @order.ship_address @client = SpreeDelhivery::Client.new @integration = @client.integration end |
Instance Method Details
#call ⇒ Object
11 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 |
# File 'app/services/spree_delhivery/shipment_sender.rb', line 11 def call return error("Shipment already has a Waybill") if @shipment.delhivery_waybill.present? payload = build_payload # Send API Request response = @client.create_shipment(payload) # Check for explicit success or package success status success_status = response['success'] || (response['packages'].present? && response['packages'][0]['status'] == 'Success') if success_status pkg_data = response['packages'].first # 1. Update Data Columns Safely # Using update_columns to bypass Spree callbacks that might confuse the hash response with a model @shipment.update_columns( tracking: pkg_data['waybill'], delhivery_waybill: pkg_data['waybill'], delhivery_ref_id: pkg_data['refnum'], delhivery_response_data: response # Rails handles JSON serialization automatically ) # 2. Reload object to ensure fresh state @shipment.reload # 3. Fire Spree Shipment State Machine # This moves state from 'ready' -> 'shipped' if @shipment.can_ship? @shipment.ship! end # 4. Fetch Label URL immediately begin label_res = @client.fetch_label(pkg_data['waybill']) if label_res['packages'] && label_res['packages'][0]['pdf_download_link'] @shipment.update_column(:delhivery_label_url, label_res['packages'][0]['pdf_download_link']) end rescue => e Rails.logger.error("Delhivery Label Fetch Failed: #{e.}") end return success(@shipment) else # --- IMPROVED ERROR HANDLING --- # 1. Extract the deep error message first (it's more accurate than 'rmk') raw_error = response.dig('packages', 0, 'remarks')&.join(', ') || response['rmk'] || "Unknown Error" # 2. Map known API errors to friendly user messages friendly_error = case raw_error.to_s.downcase when /insufficient balance/ # Fetch live balance to show the user current_bal = @client.fetch_balance rescue nil msg = "Authorization Failed: Insufficient Delhivery Wallet Balance." msg += " Current Balance: ₹#{current_bal}." if current_bal msg + " Please recharge." when /duplicate/ "Duplicate Order: This order ID has already been processed." when /pincode/ "Serviceability Error: Pincode (#{@address.zipcode}) not serviceable." else "Delhivery Error: #{raw_error}" end return error(friendly_error) end rescue StandardError => e Rails.logger.error(e.backtrace.join("\n")) return error(e.) end |