Class: Coupon::DeleteDiscount

Inherits:
Object
  • Object
show all
Defined in:
app/services/coupon/delete_discount.rb

Overview

This service class is responsible for deleting a discount from an itemizable
and ensuring the total integrity is correct

Defined Under Namespace

Classes: Result

Instance Method Summary collapse

Instance Method Details

#perform(discount, options = {}) ⇒ Object



9
10
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
# File 'app/services/coupon/delete_discount.rb', line 9

def perform(discount, options = {})
  errors = []
  itemizable = discount.itemizable
  if itemizable.nil?
    errors << 'Discount is orphaned and cannot be deleted'
  elsif itemizable.editing_locked? && !options[:skip_lock_check]
    errors << "Discount cannot be deleted, #{itemizable.class.name} is locked"
  else
    lock_key = "#{itemizable.class.name.downcase}_#{itemizable.id}".freeze
    itemizable.with_advisory_lock(lock_key, timeout_seconds: 120) do
      # Check if auto coupons are disabled on this order
      auto_coupons_disabled = itemizable.try(:disable_auto_coupon) == true

      if discount.blacklisted
        # Un-blacklist (enable) the discount instead of destroying it
        # This preserves manually-added discounts and prevents them from being
        # removed during recalculation when auto-apply coupons are processed
        discount.blacklisted = false
        discount.amount = 0 # Reset amount so it gets recalculated
        discount.save
      elsif discount.blacklistable? && !(auto_coupons_disabled && discount.auto_apply)
        # Blacklist the discount to remember it was manually disabled
        # BUT if auto coupons are disabled on the order, skip blacklisting and destroy instead
        discount.mark_as_blacklisted unless Coupon::SKIP_BLACKLISTING_COUPON_CODES.include?(discount.code)
        discount.save
      else
        # Destroy in these cases:
        # 1. Auto coupons disabled + this is an auto-apply discount (no need to blacklist)
        # 2. Discount is not blacklistable (manual discount being removed)
        discount.destroy
      end
      # Set flag to trigger discount recalculation after removing a coupon
      itemizable.update_column(:recalculate_discounts, true)
      itemizable.reload
      itemizable.reset_discount
      itemizable.calculate_tax_for_all_lines
    end
  end

  Result.new(success: errors.blank?, errors: errors)
end