Module: TicketSynchronizer

Defined in:
app/concerns/ticket_synchronizer.rb

Instance Method Summary collapse

Instance Method Details

#create_from_remote(remote_ticket) ⇒ Object



101
102
103
104
105
106
107
# File 'app/concerns/ticket_synchronizer.rb', line 101

def create_from_remote(remote_ticket)
  attributes = remote_ticket.attributes
  if project.ticket_tracker.features.include?(:syncing_milestones)
    attributes[:milestone_id] = project.milestones.id_for_remote_id(attributes[:milestone_id])
  end
  create(attributes)
end

#fetch_allObject



4
5
6
7
8
9
10
# File 'app/concerns/ticket_synchronizer.rb', line 4

def fetch_all
  return all if !ticket_tracker.supports?(:syncing_tickets)

  Houston.benchmark "GET All Tickets" do
    synchronize ticket_tracker.all_tickets
  end
end

#fetch_numbered(numbers) ⇒ Object



34
35
36
37
38
39
40
41
# File 'app/concerns/ticket_synchronizer.rb', line 34

def fetch_numbered(numbers)
  return [] if numbers.empty?
  return numbered(numbers) if !ticket_tracker.supports?(:syncing_tickets)

  Houston.benchmark "GET Numbered Tickets" do
    synchronize ticket_tracker.find_tickets_numbered(numbers)
  end
end

#fetch_openObject



12
13
14
15
16
17
18
# File 'app/concerns/ticket_synchronizer.rb', line 12

def fetch_open
  return open if !ticket_tracker.supports?(:syncing_tickets)

  Houston.benchmark "GET Open Tickets" do
    synchronize ticket_tracker.open_tickets
  end
end

#fetch_with_query(*query) ⇒ Object



43
44
45
46
47
48
49
# File 'app/concerns/ticket_synchronizer.rb', line 43

def fetch_with_query(*query)
  return [] unless ticket_tracker.respond_to?(:find_tickets!) # <-- an optional API

  Rails.logger.info "[tickets.fetch_with_query] query: #{query.inspect}"

  synchronize ticket_tracker.find_tickets!(*query)
end

#find_by_number!(number) ⇒ Object



20
21
22
# File 'app/concerns/ticket_synchronizer.rb', line 20

def find_by_number!(number)
  numbered(number, sync: true).first || (raise ActiveRecord::RecordNotFound)
end

#numbered(*numbers, sync: false) ⇒ Object



24
25
26
27
28
29
30
31
32
# File 'app/concerns/ticket_synchronizer.rb', line 24

def numbered(*numbers, sync: false)
  numbers = numbers.flatten.map(&:to_i).uniq
  return none if numbers.empty?

  results = super(*numbers)
  return results unless sync && ticket_tracker.supports?(:syncing_tickets)

  results.concat fetch_numbered(numbers - results.map(&:number))
end

#synchronize(unsynchronized_tickets) ⇒ Object



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
# File 'app/concerns/ticket_synchronizer.rb', line 52

def synchronize(unsynchronized_tickets)
  unsynchronized_tickets = unsynchronized_tickets.reject(&:nil?)
  return [] if unsynchronized_tickets.empty?

  map_milestone_id = project.milestones.remote_id_map

  Houston.benchmark("[tickets.synchronize] synchronizing #{unsynchronized_tickets.length} tickets") do
    numbers = unsynchronized_tickets.map(&:number)
    tickets = Ticket.unscoped { where(number: numbers) }

    unsynchronized_tickets.map do |unsynchronized_ticket|
      ticket = tickets.detect { |ticket| ticket.number == unsynchronized_ticket.number }
      attributes = unsynchronized_ticket.attributes.merge(destroyed_at: nil)

      # Convert remote milestone IDs to local milestone IDs
      attributes[:milestone_id] = map_milestone_id[attributes[:milestone_id]]

      if ticket

        # This is essentially a call to update_attributes,
        # but I broke it down so that we don't begin a
        # transaction if we don't have any changes to save.
        # This is pretty much just to reduce log verbosity.
        ticket.assign_attributes(attributes)

        # hstore always thinks it has changed
        has_legitimate_changes = ticket.changed?
        if has_legitimate_changes && ticket.changed == %w{extended_attributes}
          before, after = ticket.changes["extended_attributes"]
          has_legitimate_changes = false if before == after
        end
        if has_legitimate_changes
          ticket.updated_by = project.ticket_tracker_name
          Ticket.nosync { ticket.save }
        end
      else
        ticket = Ticket.nosync { create(attributes) }
      end

      # There's no reason why this shouldn't be set,
      # but in order to reduce a bunch of useless hits
      # to the cache and a bunch of log output...
      ticket.project = project
      ticket
    end
  end
end