Class: Dscf::Marketplace::Order
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Dscf::Marketplace::Order
- Defined in:
- app/models/dscf/marketplace/order.rb
Class Method Summary collapse
- .create_from_listing(listing, user, quantity, dropoff_address = nil, payment_method = nil) ⇒ Object
- .create_from_quotation(quotation, dropoff_address = nil, payment_method = nil) ⇒ Object
- .ransackable_associations(_auth_object = nil) ⇒ Object
-
.ransackable_attributes(_auth_object = nil) ⇒ Object
Ransack configuration for secure filtering.
Instance Method Summary collapse
- #all_items_validated? ⇒ Boolean
- #calculate_total_amount ⇒ Object
- #can_be_completed? ⇒ Boolean
- #confirm! ⇒ Object
- #delivery? ⇒ Boolean
- #mark_splitting! ⇒ Object
- #mark_waiting_retailer_confirmation! ⇒ Object
- #mark_waiting_supplier_confirmation! ⇒ Object
- #requires_delivery_order? ⇒ Boolean
- #retailer_can_confirm? ⇒ Boolean
-
#self_pickup? ⇒ Boolean
Fulfillment type methods.
- #supplier ⇒ Object
- #supplier_confirmation_complete? ⇒ Boolean
- #total_amount ⇒ Object
-
#validating? ⇒ Boolean
Workflow helpers for Sprint 2 order validation + splitting.
- #validation_summary ⇒ Object
Class Method Details
.create_from_listing(listing, user, quantity, dropoff_address = nil, payment_method = nil) ⇒ Object
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 |
# File 'app/models/dscf/marketplace/order.rb', line 90 def self.create_from_listing(listing, user, quantity, dropoff_address = nil, payment_method = nil) return nil unless listing.visible? && quantity <= listing.quantity attributes = { order_type: :direct_listing, status: :validating, fulfillment_type: dropoff_address.present? ? :delivery : :self_pickup, listing: listing, user: user, # Keep for backward compatibility ordered_by: user, ordered_to: listing.business, dropoff_address: dropoff_address, total_amount: listing.price * quantity } attributes[:payment_method] = payment_method if payment_method.present? order = create!(attributes) order.order_items.create!( listing: listing, product: listing.supplier_product.product, unit: listing.supplier_product.product.unit, quantity: quantity, unit_price: listing.price, status: :pending, validation_status: :validated ) order end |
.create_from_quotation(quotation, dropoff_address = nil, payment_method = nil) ⇒ Object
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 |
# File 'app/models/dscf/marketplace/order.rb', line 56 def self.create_from_quotation(quotation, dropoff_address = nil, payment_method = nil) return nil unless quotation.accepted? attributes = { order_type: :rfq_based, status: :validating, fulfillment_type: dropoff_address.present? ? :delivery : :self_pickup, quotation: quotation, user: quotation.request_for_quotation.user, # Keep for backward compatibility ordered_by: quotation.request_for_quotation.user, ordered_to: quotation.business, dropoff_address: dropoff_address, total_amount: quotation.total_price } attributes[:payment_method] = payment_method if payment_method.present? order = create!(attributes) quotation.quotation_items.each do |item| order.order_items.create!( quotation_item: item, product: item.product, unit: item.unit, quantity: item.quantity, unit_price: item.unit_price, status: :pending, validation_status: :validated # initial from accepted quote; validation can re-run ) end order end |
.ransackable_associations(_auth_object = nil) ⇒ Object
52 53 54 |
# File 'app/models/dscf/marketplace/order.rb', line 52 def self.ransackable_associations(_auth_object = nil) %w[quotation listing user ordered_by ordered_to delivery_order dropoff_address order_items] end |
.ransackable_attributes(_auth_object = nil) ⇒ Object
Ransack configuration for secure filtering
48 49 50 |
# File 'app/models/dscf/marketplace/order.rb', line 48 def self.ransackable_attributes(_auth_object = nil) %w[id quotation_id listing_id user_id ordered_by_id ordered_to_id delivery_order_id dropoff_address_id order_type status fulfillment_type payment_method received_bank_name transaction_reference total_amount created_at updated_at] end |
Instance Method Details
#all_items_validated? ⇒ Boolean
181 182 183 |
# File 'app/models/dscf/marketplace/order.rb', line 181 def all_items_validated? order_items.all? { |i| i.validation_status == "validated" } end |
#calculate_total_amount ⇒ Object
172 173 174 |
# File 'app/models/dscf/marketplace/order.rb', line 172 def calculate_total_amount self.total_amount = order_items.sum { |item| item.quantity * item.unit_price } end |
#can_be_completed? ⇒ Boolean
153 154 155 156 157 158 159 160 161 |
# File 'app/models/dscf/marketplace/order.rb', line 153 def can_be_completed? if self_pickup? # Self-pickup orders can be completed immediately after confirmation confirmed? || processing? else # Delivery orders require delivery_order association delivery_order.present? && delivery_order.delivered? end end |
#confirm! ⇒ Object
163 164 165 166 167 168 169 170 |
# File 'app/models/dscf/marketplace/order.rb', line 163 def confirm! return false unless pending? update!(status: :confirmed) # Update order items without reloading to avoid association issues order_items.update_all(status: OrderItem.statuses[:confirmed]) true end |
#delivery? ⇒ Boolean
145 146 147 |
# File 'app/models/dscf/marketplace/order.rb', line 145 def delivery? fulfillment_type == "delivery" end |
#mark_splitting! ⇒ Object
189 190 191 |
# File 'app/models/dscf/marketplace/order.rb', line 189 def mark_splitting! update!(status: :splitting) end |
#mark_waiting_retailer_confirmation! ⇒ Object
197 198 199 |
# File 'app/models/dscf/marketplace/order.rb', line 197 def mark_waiting_retailer_confirmation! update!(status: :waiting_retailer_confirmation) end |
#mark_waiting_supplier_confirmation! ⇒ Object
193 194 195 |
# File 'app/models/dscf/marketplace/order.rb', line 193 def mark_waiting_supplier_confirmation! update!(status: :waiting_supplier_confirmation) end |
#requires_delivery_order? ⇒ Boolean
149 150 151 |
# File 'app/models/dscf/marketplace/order.rb', line 149 def requires_delivery_order? delivery? && !completed? end |
#retailer_can_confirm? ⇒ Boolean
201 202 203 |
# File 'app/models/dscf/marketplace/order.rb', line 201 def retailer_can_confirm? waiting_retailer_confirmation? || confirmed? # allow re-confirm safety end |
#self_pickup? ⇒ Boolean
Fulfillment type methods
141 142 143 |
# File 'app/models/dscf/marketplace/order.rb', line 141 def self_pickup? fulfillment_type == "self_pickup" end |
#supplier ⇒ Object
132 133 134 135 136 137 138 |
# File 'app/models/dscf/marketplace/order.rb', line 132 def supplier if rfq_based? quotation&.business elsif direct_listing? listing&.business || ordered_to end end |
#supplier_confirmation_complete? ⇒ Boolean
205 206 207 208 |
# File 'app/models/dscf/marketplace/order.rb', line 205 def supplier_confirmation_complete? # simplistic: all items have source and are confirmed or cancelled order_items.all? { |i| i.source_id.present? && (i.status.to_s == "confirmed" || i.status.to_s == "cancelled") } end |
#total_amount ⇒ Object
122 123 124 125 126 127 128 129 130 |
# File 'app/models/dscf/marketplace/order.rb', line 122 def total_amount # Return stored value if it exists and is greater than 0, otherwise calculate stored_value = super calculated_value = order_items.sum { |item| item.quantity * item.unit_price } # Return stored value if it's set and valid, otherwise return calculated value return stored_value if stored_value.present? && stored_value > 0 calculated_value end |
#validating? ⇒ Boolean
Workflow helpers for Sprint 2 order validation + splitting
177 178 179 |
# File 'app/models/dscf/marketplace/order.rb', line 177 def validating? pending? || status.to_s == "processing" end |
#validation_summary ⇒ Object
185 186 187 |
# File 'app/models/dscf/marketplace/order.rb', line 185 def validation_summary order_items.group_by(&:validation_status).transform_values(&:count) end |