Module: ErpBaseErpSvcs::Extensions::ActiveRecord::HasTrackedStatus::ClassMethods

Defined in:
lib/erp_base_erp_svcs/extensions/active_record/has_tracked_status.rb

Instance Method Summary collapse

Instance Method Details

#has_tracked_statusObject



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
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/erp_base_erp_svcs/extensions/active_record/has_tracked_status.rb', line 10

def has_tracked_status
  extend HasTrackedStatus::SingletonMethods
  include HasTrackedStatus::InstanceMethods

  has_many :status_applications, :as => :status_application_record

  before_destroy :destroy_status_applications

  scope :with_status, lambda { |status_type_iids|
                      joins(:status_applications => :tracked_status_type).
                          where("status_applications.thru_date IS NULL AND tracked_status_types.internal_identifier IN (?)",
                                status_type_iids)
                    }

  # scope record by its current status application
  # status_type_iids can either be an Array of status to scope by or a Hash with the parent status
  # as the key and the children statues to scope by as the value
  scope :with_current_status, lambda { |status_type_iids=[]|
                              model_table = self.arel_table
                              status_applications_tbl = StatusApplication.arel_table

                              #determine status_application_record_type
                              status_application_record_type = (self.superclass == ::ActiveRecord::Base) ? self.name.to_s : self.superclass.to_s

                              current_status_select = status_applications_tbl.project(status_applications_tbl[:id].maximum)
                                                          .where(model_table[:id].eq(status_applications_tbl[:status_application_record_id])
                                                                     .and(status_applications_tbl[:status_application_record_type].eq(status_application_record_type)))

                              statement = joins(:status_applications => :tracked_status_type).where(status_applications_tbl[:id].in(current_status_select))

                              if status_type_iids
                                status_ids = []

                                if status_type_iids.is_a?(Hash)
                                  parent_status = TrackedStatusType.iid(status_type_iids.keys.first)
                                  status_ids = parent_status.children.where(:internal_identifier => status_type_iids.values.first).pluck(:id)

                                elsif status_type_iids.is_a?(Array)
                                  unless status_type_iids.empty?
                                    status_ids = TrackedStatusType.where(:internal_identifier => status_type_iids).pluck(:id)
                                  end
                                end

                                unless status_ids.empty?
                                  statement = statement.where(TrackedStatusType.arel_table[:id].in status_ids)
                                end
                              end

                              statement
                            }

  # scope record by its current status application and exclude records with the passed statuses
  # status_type_iids can either be an Array of status to scope by or a Hash with the parent status
  # as the key and the children statues to scope by as the value
  scope :without_current_status, lambda { |status_type_iids=[]|
                                 model_table = self.arel_table
                                 status_applications_tbl = StatusApplication.arel_table

                                 #determine status_application_record_type
                                 status_application_record_type = (self.superclass == ::ActiveRecord::Base) ? self.name.to_s : self.superclass.to_s

                                 current_status_select = status_applications_tbl.project(status_applications_tbl[:id].maximum)
                                                             .where(model_table[:id].eq(status_applications_tbl[:status_application_record_id])
                                                                        .and(status_applications_tbl[:status_application_record_type].eq(status_application_record_type)))

                                 statement = joins(:status_applications => :tracked_status_type).where(status_applications_tbl[:id].in(current_status_select))

                                 if status_type_iids
                                   status_ids = []

                                   if status_type_iids.is_a?(Hash)
                                     parent_status = TrackedStatusType.iid(status_type_iids.keys.first)
                                     status_ids = parent_status.children.where(:internal_identifier => status_type_iids.values.first).pluck(:id)

                                   elsif status_type_iids.is_a?(Array)
                                     unless status_type_iids.empty?
                                       status_ids = TrackedStatusType.where(:internal_identifier => status_type_iids).pluck(:id)
                                     end
                                   end

                                   unless status_ids.empty?
                                     statement = statement.where(TrackedStatusType.arel_table[:id].not_in status_ids)
                                   end
                                 end

                                 statement
                               }
end