Skip to content

Commit

Permalink
Merge branch 'feat/observation-multiple-evidences' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
tsubik committed Jan 26, 2024
2 parents 8fbf24f + fad1298 commit 236a0ab
Show file tree
Hide file tree
Showing 23 changed files with 289 additions and 76 deletions.
23 changes: 15 additions & 8 deletions app/admin/observation_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@

csv do
column :id
column :observation do |od|
od.observation&.id
end
column :name
column :document_type
column :user do |od|
od.user&.name
end
Expand All @@ -38,8 +36,10 @@

index do
column :id
column :observation, sortable: "observation_id"
column :observation_report
column :observations
column :name
column :document_type
column :attachment do |o|
link_to o&.name, o.attachment&.url if o.attachment&.url
end
Expand All @@ -62,7 +62,10 @@
end
end

filter :observation, as: :select, collection: -> { Observation.joins(:observation_documents).distinct.order(:id).pluck(:id) }
filter :observations, as: :select, collection: -> { Observation.joins(:observation_documents).distinct.order(:id).pluck(:id) }
filter :observation_report,
label: -> { I18n.t("activerecord.models.observation_report") }, as: :select,
collection: -> { ObservationReport.where(id: ObservationDocument.select(:observation_report_id)).order(:title) }
filter :name, as: :select
filter :attachment, as: :select
filter :user
Expand All @@ -73,9 +76,11 @@
form do |f|
f.semantic_errors(*f.object.errors.attribute_names)
f.inputs do
f.input :observation, collection: Observation.all.map { |o| [o.id, o.id] }, input_html: {disabled: true}
f.input :observation_report, input_html: {disabled: true}
f.input :observations, input_html: {disabled: true}
f.input :user, input_html: {disabled: true}
f.input :name
f.input :document_type
f.input :attachment, as: :file, hint: f.object&.attachment&.file&.filename

f.actions
Expand All @@ -85,7 +90,9 @@
show do
attributes_table do
row :id
row :observation
row :observation_report
row :observations
row :document_type
row :attachment do |o|
link_to o&.name, o.attachment&.url if o.attachment&.url
end
Expand All @@ -99,7 +106,7 @@

controller do
def scoped_collection
end_of_association_chain.includes(:user)
end_of_association_chain.includes(:user, :observations)
end
end
end
4 changes: 2 additions & 2 deletions app/importers/observations_importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
class ObservationsImporter < FileDataImport::BaseImporter
PERMITTED_ATTRIBUTES = %i[
observation_type publication_date pv is_active location_accuracy
lat lng fmu_id evidence_type location_information actions_taken
evidence_on_report validation_status is_physical_place user_id
lat lng fmu_id location_information actions_taken
evidence_type evidence_on_report validation_status is_physical_place user_id
observer_ids
].freeze

Expand Down
20 changes: 20 additions & 0 deletions app/models/concerns/observation_old_attributes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Purpose to use with paper_trail history, to get the previous version of some attributes
module ObservationOldAttributes
extend ActiveSupport::Concern

EVIDENCE_TYPE_V0 = {
"Government Documents" => 0, "Company Documents" => 1, "Photos" => 2,
"Testimony from local communities" => 3, "Other" => 4, "Evidence presented in the report" => 5,
"Maps" => 6
}.freeze

included do
attr_accessor :evidence_type_v0
end

def evidence_type
return EVIDENCE_TYPE_V0.key(evidence_type_v0) if evidence_type_v0.present?

super
end
end
7 changes: 7 additions & 0 deletions app/models/countries_observer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# frozen_string_literal: true

# == Schema Information
#
# Table name: countries_observers
#
# country_id :integer not null
# observer_id :integer not null
#
class CountriesObserver < ApplicationRecord
belongs_to :country
belongs_to :observer
Expand Down
37 changes: 19 additions & 18 deletions app/models/observation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,21 @@ class Observation < ApplicationRecord
include Translatable
include Activable
include ValidationHelper
include ObservationOldAttributes

translates :details, :concern_opinion, :litigation_status, touch: true, versioning: :paper_trail, paranoia: true
active_admin_translates :details, :concern_opinion, :litigation_status

enum evidence_type: {"No evidence" => 0, "Uploaded documents" => 1, "Evidence presented in the report" => 2}
enum observation_type: {"operator" => 0, "government" => 1}
enum validation_status: {"Created" => 0, "Ready for QC" => 1, "QC in progress" => 2, "Approved" => 3,
"Rejected" => 4, "Needs revision" => 5, "Ready for publication" => 6,
"Published (no comments)" => 7, "Published (not modified)" => 8,
"Published (modified)" => 9}
enum evidence_type: {"Government Documents" => 0, "Company Documents" => 1, "Photos" => 2,
"Testimony from local communities" => 3, "Other" => 4, "Evidence presented in the report" => 5,
"Maps" => 6}
enum location_accuracy: {"Estimated location" => 0, "GPS coordinates extracted from photo" => 1,
"Accurate GPS coordinates" => 2}

validate_enum_attributes :observation_type, :evidence_type, :location_accuracy
validate_enum_attributes :evidence_type, :observation_type, :location_accuracy

STATUS_TRANSITIONS = {
monitor: {
Expand Down Expand Up @@ -109,7 +108,7 @@ class Observation < ApplicationRecord
has_many :observation_operators, dependent: :destroy
has_many :relevant_operators, through: :observation_operators, source: :operator

has_many :observation_documents, dependent: :destroy
has_and_belongs_to_many :observation_documents, inverse_of: :observations

accepts_nested_attributes_for :observation_documents, allow_destroy: true
accepts_nested_attributes_for :observation_report, allow_destroy: true
Expand All @@ -127,7 +126,7 @@ class Observation < ApplicationRecord

validates :lat, numericality: {greater_than_or_equal_to: -90, less_than_or_equal_to: 90, allow_blank: true}
validates :lng, numericality: {greater_than_or_equal_to: -180, less_than_or_equal_to: 180, allow_blank: true}
validate :evidence_presented_in_the_report
validates :evidence_on_report, presence: true, if: -> { evidence_type == "Evidence presented in the report" }
validate :status_changes, if: -> { user_type.present? }

validates :observers, presence: true
Expand All @@ -137,6 +136,7 @@ class Observation < ApplicationRecord
validates :admin_comment, presence: true, if: -> { validation_status == "Needs revision" }

before_validation :assign_observers_from_report, if: :observation_report_changed?
before_validation :nullify_evidence_on_report, if: -> { evidence_type != "Evidence presented in the report" }

before_save :set_active_status
before_save :nullify_fmu_and_coordinates, unless: :is_physical_place
Expand All @@ -152,7 +152,7 @@ class Observation < ApplicationRecord

after_save :create_history, if: :saved_changes?

after_save :remove_documents, if: -> { evidence_type == "Evidence presented in the report" }
after_save :remove_documents, if: -> { evidence_type != "Uploaded documents" }
after_save :update_fmu_geojson

after_commit :notify_about_creation, on: :create
Expand Down Expand Up @@ -199,7 +199,13 @@ def cache_key
super + "-" + Globalize.locale.to_s
end

HISTORICAL_ATTRIBUTES = %w[fmu_id operator_id country_id subcategory_id observation_type evidence_type location_accuracy validation_status is_active hidden deleted_at]
def update_reports_observers
return if observation_report.blank?

observation_report.update_observers
end

HISTORICAL_ATTRIBUTES = %w[fmu_id operator_id country_id subcategory_id observation_type location_accuracy validation_status is_active hidden deleted_at]

# Creates an ObservationHistory for the current Observation
def create_history
Expand All @@ -221,6 +227,10 @@ def published?

private

def nullify_evidence_on_report
self.evidence_on_report = nil
end

def nullify_fmu_and_coordinates
self.lat = nil
self.lng = nil
Expand Down Expand Up @@ -296,17 +306,8 @@ def status_changes
"Invalid validation change for #{@user_type}. Can't move from '#{validation_status_was}' to '#{validation_status}'")
end

def evidence_presented_in_the_report
if evidence_type == "Evidence presented in the report" && evidence_on_report.blank?
errors.add(:evidence_on_report, "You must add information on where to find the evidence on the report")
end
if evidence_type != "Evidence presented in the report" && evidence_on_report.present?
errors.add(:evidence_on_report, "This field can only be present when the evidence is presented on the report")
end
end

def remove_documents
ObservationDocument.where(observation_id: id).destroy_all
self.observation_documents = []
end

# If the observation is for an fmu, it updates its geojson with the new count
Expand Down
27 changes: 17 additions & 10 deletions app/models/observation_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,33 @@
#
# Table name: observation_documents
#
# id :integer not null, primary key
# name :string
# attachment :string
# created_at :datetime not null
# updated_at :datetime not null
# user_id :integer
# deleted_at :datetime
# observation_id :integer
# id :integer not null, primary key
# name :string
# attachment :string
# created_at :datetime not null
# updated_at :datetime not null
# user_id :integer
# deleted_at :datetime
# document_type :integer default("Government Documents"), not null
# observation_report_id :bigint
#

class ObservationDocument < ApplicationRecord
has_paper_trail
acts_as_paranoid
mount_base64_uploader :attachment, ObservationDocumentUploader
include MoveableAttachment

acts_as_paranoid
enum document_type: {
"Government Documents" => 0, "Company Documents" => 1, "Photos" => 2,
"Testimony from local communities" => 3, "Other" => 4, "Maps" => 5
}
validate_enum_attributes :document_type

# TODO: only nils in the database, maybe that should be removed?
belongs_to :user, inverse_of: :observation_documents, touch: true, optional: true
belongs_to :observation, inverse_of: :observation_documents, touch: true
belongs_to :observation_report, inverse_of: :observation_documents, touch: true, optional: true
has_and_belongs_to_many :observations, inverse_of: :observation_documents

skip_callback :commit, :after, :remove_attachment!
after_destroy :move_attachment_to_private_directory
Expand Down
4 changes: 0 additions & 4 deletions app/models/observation_history.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# id :integer not null, primary key
# validation_status :integer
# observation_type :integer
# evidence_type :integer
# location_accuracy :integer
# severity_level :integer
# fmu_forest_type :integer
Expand All @@ -33,9 +32,6 @@ class ObservationHistory < ApplicationRecord
"Rejected" => 4, "Needs revision" => 5, "Ready for publication" => 6,
"Published (no comments)" => 7, "Published (not modified)" => 8,
"Published (modified)" => 9}
enum evidence_type: {"Government Documents" => 0, "Company Documents" => 1, "Photos" => 2,
"Testimony from local communities" => 3, "Other" => 4, "Evidence presented in the report" => 5,
"Maps" => 6}
enum location_accuracy: {"Estimated location" => 0, "GPS coordinates extracted from photo" => 1,
"Accurate GPS coordinates" => 2}
enum fmu_forest_type: ForestType::TYPES_WITH_CODE
Expand Down
1 change: 1 addition & 0 deletions app/models/observation_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class ObservationReport < ApplicationRecord
has_many :observation_report_observers, dependent: :destroy
has_many :observers, through: :observation_report_observers, after_add: :self_touch, after_remove: :self_touch
has_many :observations, dependent: :destroy
has_many :observation_documents, inverse_of: :observation_report, dependent: :destroy

validates :attachment, presence: true
validates :observers, presence: true
Expand Down
11 changes: 8 additions & 3 deletions app/resources/v1/observation_document_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ module V1
class ObservationDocumentResource < BaseResource
caching

attributes :name, :attachment, :created_at, :updated_at
attributes :name, :attachment, :document_type, :observation_report_id, :created_at, :updated_at

has_one :observation
has_many :observations
has_one :observation_report

filters :observation_id, :name
filters :observation_report_id, :name

filter :observation_id, apply: ->(records, value, _options) {
records.where(id: ObservationDocument.joins(:observations).where(observations: value))
}
end
end
3 changes: 1 addition & 2 deletions app/uploaders/observation_document_uploader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ def extension_allowlist
end

def filename
return super if model.observation.nil?
return if super.blank?

filename = if model.name.present?
model.name[0...100]&.parameterize
else
[
model.id,
(model.observation.evidence_type || "other").parameterize
(model.document_type || "other").parameterize
].join("-")
end

Expand Down
2 changes: 2 additions & 0 deletions app/views/active_admin/resource/_attributes_table.html.arb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ panel I18n.t("active_admin.observations_page.details") do
render partial: "map", locals: {center: [r.lng, r.lat], geojson: r.fmu&.geojson, bbox: r.fmu&.bbox}
end
end
row :evidence_type
row :evidence_on_report
row :actions_taken
row :concern_opinion
row :observation_report
Expand Down
2 changes: 2 additions & 0 deletions config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,6 @@

# Uncomment if you wish to allow Action Cable access from any origin.
# config.action_cable.disable_request_forgery_protection = true

# config.active_record.migration_error = false
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class CreateObservationDocumentObservations < ActiveRecord::Migration[7.0]
def up
create_table :observation_documents_observations do |t|
t.belongs_to :observation_document, foreign_key: {on_delete: :cascade}, index: {name: "observation_documents_observations_doc_index"}, null: false
t.belongs_to :observation, foreign_key: {on_delete: :cascade}, index: {name: "observation_documents_observations_obs_index"}, null: false
t.index [:observation_document_id, :observation_id], unique: true, name: "observation_documents_observations_double_index"
t.timestamps
end

query = <<-SQL
INSERT INTO observation_documents_observations (observation_document_id, observation_id, created_at, updated_at)
SELECT
od.id, o.id, NOW(), NOW()
FROM
observation_documents od JOIN observations o ON od.observation_id = o.id
SQL
execute(query)

remove_reference :observation_documents, :observation
end

def down
add_reference :observation_documents, :observation, foreign_key: true, index: true

query = <<-SQL
UPDATE observation_documents SET observation_id = odo.observation_id
FROM (SELECT DISTINCT ON (observation_document_id) observation_document_id, observation_id FROM observation_documents_observations) odo
WHERE observation_documents.id = odo.observation_document_id
SQL
execute(query)

drop_table :observation_documents_observations
end
end
Loading

0 comments on commit 236a0ab

Please sign in to comment.