@@ -97,11 +97,11 @@ def can_discount?(object)
9797 # @param adjustable [Object] The object to calculate the discount for (e.g., LineItem, Shipment, ShippingRate)
9898 # @param ... [args, kwargs] Additional arguments passed to the calculator's compute method
9999 #
100- # @return [SolidusPromotions::ItemDiscount , nil] An ItemDiscount object if a discount applies, nil if the amount is zero
100+ # @return [Spree::Adjustment, SolidusPromotions::ShippingRateDiscount , nil] An ItemDiscount object if a discount applies, nil if the amount is zero
101101 #
102102 # @example Calculating a discount for a line item
103103 # benefit.discount(line_item)
104- # # => #<SolidusPromotions::ItemDiscount item: #<Spree::LineItem> , amount: -10.00, ...>
104+ # # => #<Spree::Adjustment, adjustable: line_item , amount: -10.00, ...>
105105 #
106106 # @see #compute_amount
107107 # @see #adjustment_label
@@ -175,14 +175,48 @@ def compute_amount(adjustable, ...)
175175
176176 # Builds the localized label for adjustments created by this benefit.
177177 #
178- # @param adjustable [Object]
179- # @return [String]
180- def adjustment_label ( adjustable )
181- I18n . t (
182- "solidus_promotions.adjustment_labels.#{ adjustable . class . name . demodulize . underscore } " ,
183- promotion : SolidusPromotions ::Promotion . model_name . human ,
184- promotion_customer_label : promotion . customer_label
185- )
178+ # This method attempts to use a calculator-specific label method if available,
179+ # falling back to a localized string key based on the adjustable's class name.
180+ #
181+ # ## Calculator Override
182+ #
183+ # Calculators can provide custom labels by implementing a method named after the
184+ # adjustable type. For example, a calculator that discounts line items could
185+ # implement `line_item_adjustment_label`:
186+ #
187+ # @example Custom calculator with adjustment label
188+ # class MyCalculator < Spree::Calculator
189+ # def compute(adjustable, *args)
190+ # # calculation logic
191+ # end
192+ #
193+ # def line_item_adjustment_label(line_item, *args)
194+ # "Custom discount for #{line_item.product.name}"
195+ # end
196+ # end
197+ #
198+ # The method name follows the pattern: `{adjustable_type}_adjustment_label`
199+ # where `{adjustable_type}` is the underscored class name of the adjustable
200+ # (e.g., `line_item`, `shipment`, `shipping_rate`).
201+ #
202+ # If the calculator does not respond to the expected method, the benefit will
203+ # fall back to using an i18n translation key based on the adjustable's class.
204+ #
205+ # @param adjustable [Object] the object being discounted (e.g., Spree::LineItem, Spree::Shipment)
206+ # @param ... [args, kwargs] additional arguments forwarded to the calculator's label method
207+ # @return [String] a localized label suitable for display in adjustments
208+ #
209+ # @see #adjustment_label_method_for
210+ def adjustment_label ( adjustable , ...)
211+ if calculator . respond_to? ( adjustment_label_method_for ( adjustable ) )
212+ calculator . send ( adjustment_label_method_for ( adjustable ) , adjustable , ...)
213+ else
214+ I18n . t (
215+ "solidus_promotions.adjustment_labels.#{ adjustable . class . name . demodulize . underscore } " ,
216+ promotion : SolidusPromotions ::Promotion . model_name . human ,
217+ promotion_customer_label : promotion . customer_label
218+ )
219+ end
186220 end
187221
188222 # Partial path used for admin forms for this benefit type.
@@ -277,6 +311,10 @@ def discount_method_for(adjustable)
277311 :"discount_#{ adjustable . class . name . demodulize . underscore } "
278312 end
279313
314+ def adjustment_label_method_for ( adjustable )
315+ :"#{ adjustable . class . name . demodulize . underscore } _adjustment_label"
316+ end
317+
280318 # Prevents destroying a benefit when it has adjustments on completed orders.
281319 #
282320 # Adds an error and aborts the destroy callback chain when such adjustments exist.
0 commit comments