diff --git a/.circleci/config.yml b/.circleci/config.yml index 73fd73e35..8ea52c8dc 100755 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -23,7 +23,7 @@ orbs: defaults: &defaults docker: - - image: cimg/ruby:2.7.3 + - image: cimg/ruby:3.1.7 working_directory: ~/api.goodcity jobs: @@ -40,7 +40,7 @@ jobs: <<: *defaults steps: - run: mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts - - run: gem install bundler:2.2.27 + - run: gem install bundler:2.3.27 - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} - restore_cache: *restore-bundler-cache @@ -50,7 +50,7 @@ jobs: test: <<: *defaults docker: - - image: cimg/ruby:2.7.3-browsers + - image: cimg/ruby:3.1.7-browsers - image: cimg/redis:6.0 - image: cimg/postgres:9.6 environment: @@ -66,16 +66,14 @@ jobs: - run: name: Install PostgreSQL Client (required to run migrations) command: | - sudo sh -c 'echo "deb https://apt-archive.postgresql.org/pub/repos/apt `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list' - wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo apt update - sudo apt-get install postgresql-client-9.6 + sudo apt-get install -y postgresql-client - attach_workspace: at: ~/api.goodcity/tmp - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} - restore_cache: *restore-bundler-cache - - run: gem install bundler:2.2.27 && bundle config set --local deployment 'true' && (bundle check || bundle install --jobs=2 --retry=3) + - run: gem install bundler:2.3.27 && bundle config set --local deployment 'true' && (bundle check || bundle install --jobs=2 --retry=3) - run: name: Wait for DB and Redis containers to start command: dockerize -wait tcp://localhost:5432 -wait tcp://localhost:6379 -timeout 1m @@ -108,7 +106,7 @@ jobs: - restore_cache: key: v1-repo-{{ .Environment.CIRCLE_SHA1 }} - restore_cache: *restore-bundler-cache - - run: gem install bundler:2.2.27 && bundle config set --local deployment 'true' && (bundle check || bundle install --jobs=2 --retry=3) + - run: gem install bundler:2.3.27 && bundle config set --local deployment 'true' && (bundle check || bundle install --jobs=2 --retry=3) - run: | STAGE=$(if [ "$CIRCLE_BRANCH" == "live" ]; then echo production; else echo staging; fi) bundle exec cap ${STAGE} deploy diff --git a/.ruby-version b/.ruby-version index c0013a89c..434c481ae 100755 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -ruby-2.7.3 +ruby-3.1.7 diff --git a/Dockerfile b/Dockerfile index 49f541d4e..da6b0d156 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.7.3-alpine +FROM ruby:3.1.7-alpine ARG GITHUB_TOKEN diff --git a/Gemfile b/Gemfile index 20d394385..eaab491a4 100755 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ # frozen_string_literal: true source 'https://rubygems.org' -ruby '2.7.3' +ruby '3.1.7' gem 'pg' gem 'rails', '~> 6.1.4' @@ -47,7 +47,7 @@ gem 'rotp' gem 'rubyXL' gem 'sidekiq', '<8' gem 'sidekiq-scheduler' -gem 'state_machine' +gem 'state_machines-activerecord', '~> 0.9.0' gem 'traco' gem 'twilio-ruby' gem 'whenever', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 82a207fd7..833940a94 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -531,7 +531,13 @@ GEM net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) ostruct - state_machine (1.2.0) + state_machines (0.20.0) + state_machines-activemodel (0.9.0) + activemodel (>= 6.0) + state_machines (>= 0.6.0) + state_machines-activerecord (0.9.0) + activerecord (>= 6.0) + state_machines-activemodel (>= 0.9.0) sys-uname (1.3.1) ffi (~> 1.1) thor (1.3.2) @@ -645,7 +651,7 @@ DEPENDENCIES simplecov spring spring-commands-rspec - state_machine + state_machines-activerecord (~> 0.9.0) timecop traco twilio-ruby @@ -654,7 +660,7 @@ DEPENDENCIES with_advisory_lock RUBY VERSION - ruby 2.7.3p183 + ruby 3.1.7p261 BUNDLED WITH - 2.4.19 + 2.3.27 diff --git a/Procfile b/Procfile index fb51bcacf..fc1030bd9 100755 --- a/Procfile +++ b/Procfile @@ -1,4 +1,4 @@ #api: bundle exec puma -C config/puma.rb -api: bundle exec rails server --binding=0.0.0.0 +api: bundle exec rails server --binding=0.0.0.0 --port ${PORT:-3000} sidekiq: bundle exec sidekiq socketio: (cd ../socket.io-webservice/ && PORT=1337 npm start) diff --git a/app/controllers/api/v2/shareables_controller.rb b/app/controllers/api/v2/shareables_controller.rb index 952522c6c..ac8a3cbd5 100644 --- a/app/controllers/api/v2/shareables_controller.rb +++ b/app/controllers/api/v2/shareables_controller.rb @@ -123,7 +123,8 @@ def destroy * 401 - unauthorized EOS def index - records = paginate(@shareables) + # Ensure stable pagination order + records = paginate(@shareables.order(id: :asc)) records = records.of_type(params[:resource_type]) if params[:resource_type].present? records = records.where(resource_id: params[:resource_id].split(',')) if params[:resource_id].present? diff --git a/app/models/concerns/operations/stock_operations.rb b/app/models/concerns/operations/stock_operations.rb index bddddfd7e..e43f6f27d 100644 --- a/app/models/concerns/operations/stock_operations.rb +++ b/app/models/concerns/operations/stock_operations.rb @@ -126,9 +126,9 @@ def register_quantity_change(package, quantity:, location:, action:, description } if PackagesInventory::QUANTITY_LOSS_ACTIONS.include?(action) - register_loss(package, params) + register_loss(package, **params) elsif PackagesInventory::QUANTITY_GAIN_ACTIONS.include?(action) - register_gain(package, params) + register_gain(package, **params) else raise Goodcity::ActionNotAllowedError.new end diff --git a/app/models/token.rb b/app/models/token.rb index fc55cc943..81a7cb578 100755 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -38,10 +38,12 @@ def initialize(options = {}) # as part of the authentication/authorization process # Additional options can be encoded inside the token # params = { "mobile" => "+85212345678" } - def generate(params, metadata: {}, validity: nil, type: DEFAULT_TYPE) + def generate(params = {}, metadata: {}, validity: nil, type: DEFAULT_TYPE, **extra_params) now = Time.current.to_i validity ||= default_validity(type) + params = (params || {}).merge(extra_params) + payload = params.merge({ "iat": now, "iss": issuer, @@ -52,12 +54,12 @@ def generate(params, metadata: {}, validity: nil, type: DEFAULT_TYPE) JWT.encode(payload.stringify_keys, secret_key, hmac_sha_algo) end - def generate_api_token(params, metadata: {}, validity: nil) - generate(params, metadata: metadata, validity: validity, type: Types::API) + def generate_api_token(params = {}, metadata: {}, validity: nil, **extra_params) + generate(params, metadata: metadata, validity: validity, type: Types::API, **extra_params) end - def generate_otp_token(params, metadata: {}, validity: nil) - generate(params, metadata: metadata, validity: validity, type: Types::OTP) + def generate_otp_token(params = {}, metadata: {}, validity: nil, **extra_params) + generate(params, metadata: metadata, validity: validity, type: Types::OTP, **extra_params) end # Allow access to the data stored inside the token e.g. mobile number diff --git a/app/models/user.rb b/app/models/user.rb index 3646f64e6..680bd945c 100755 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -109,7 +109,7 @@ class User < ApplicationRecord scope :exclude_system_users, -> { where.not(id: [User.system_user.try(:id), User.stockit_user.try(:id)].compact) } scope :active, -> { where(disabled: false) } scope :exclude_user, ->(id) { where.not(id: id) } - scope :with_roles, ->(role_names) { where(roles: { name: role_names }).joins(:active_roles) } + scope :with_roles, ->(role_names) { joins(:active_roles).where(active_roles: { name: role_names }) } scope :with_organisation_status, ->(status_list) { joins(:organisations_users).where(organisations_users: { status: status_list }) } scope :with_eager_loading, -> { includes([:image, address: [:district]]) } scope :with_permissions, ->(perm) { @@ -171,9 +171,13 @@ def self.recent_orders_created_for(user_id) end def self.filter_users(opts) - res = search(opts['searchText']) if opts['searchText'].present? - res = res.with_organisation_status(opts['organisation_status'].split(',')) if opts['organisation_status'].present? - res = res.with_roles(opts['role_name']) if opts['role_name'].present? + search_text = opts[:searchText] || opts['searchText'] + organisation_status = opts[:organisation_status] || opts['organisation_status'] + role_name = opts[:role_name] || opts['role_name'] + + res = search_text.present? ? search(search_text) : all + res = res.with_organisation_status(organisation_status.split(',')) if organisation_status.present? + res = res.with_roles(role_name) if role_name.present? res end diff --git a/app/services/twilio_service.rb b/app/services/twilio_service.rb index f0b5f5791..629e31359 100644 --- a/app/services/twilio_service.rb +++ b/app/services/twilio_service.rb @@ -37,9 +37,9 @@ def send_unread_message_reminder(url) # options[:to] = "+85261111111" # options[:body] = "SMS body" - def send_sms(options) - options = { to: mobile }.merge(options) - TwilioJob.perform_later(options) + def send_sms(options = nil, **kwargs) + options = { to: mobile }.merge(options || {}).merge(kwargs) + TwilioJob.perform_later(**options) end private diff --git a/config/deploy.rb b/config/deploy.rb index 1dd5ace4c..af4414992 100755 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -8,7 +8,7 @@ set :linked_files, %w{ config/database.yml .env } set :linked_dirs, %w{log tmp/pids tmp/cache} set :bundle_binstubs, nil -set :rvm_ruby_version, '2.7.3' +set :rvm_ruby_version, '3.1.7' set :newrelic_user, Proc.new { ENV['CIRCLE_USERNAME'] || ENV['USER'] } after "deploy:updated", "newrelic:notice_deployment" diff --git a/config/initializers/state_machine_patch.rb b/config/initializers/state_machine_patch.rb deleted file mode 100644 index cf4695730..000000000 --- a/config/initializers/state_machine_patch.rb +++ /dev/null @@ -1,18 +0,0 @@ -# ISSUE with rails 4.1, while saving record gives following error: -# NoMethodError (protected method `around_validation' called for -# # -# -# https://github.com/pluginaweek/state_machine/issues/251#issuecomment-32133267 -# - -module StateMachine - module Integrations - module ActiveModel - public :around_validation - end - - module ActiveRecord - public :around_save - end - end -end diff --git a/config/systemd/sidekiq-production.service b/config/systemd/sidekiq-production.service index ae1330115..9bf916b9a 100644 --- a/config/systemd/sidekiq-production.service +++ b/config/systemd/sidekiq-production.service @@ -10,7 +10,7 @@ After=syslog.target network.target Type=simple WorkingDirectory=/opt/rails/goodcity_server/current Environment=NODE_VERSION=lts/gallium MALLOC_ARENA_MAX=2 -ExecStart=/home/deployer/.nvm/nvm-exec /home/deployer/.rvm/bin/rvm 2.7.3 do bundle exec sidekiq -e production -C config/sidekiq.yml +ExecStart=/home/deployer/.nvm/nvm-exec /home/deployer/.rvm/bin/rvm 3.1.7 do bundle exec sidekiq -e production -C config/sidekiq.yml User=deployer Group=deployer UMask=0002 diff --git a/db/migrate/20251219000001_add_index_to_messages_on_messageable_and_created_at.rb b/db/migrate/20251219000001_add_index_to_messages_on_messageable_and_created_at.rb index d0a837163..182fb1f4a 100644 --- a/db/migrate/20251219000001_add_index_to_messages_on_messageable_and_created_at.rb +++ b/db/migrate/20251219000001_add_index_to_messages_on_messageable_and_created_at.rb @@ -4,7 +4,7 @@ class AddIndexToMessagesOnMessageableAndCreatedAt < ActiveRecord::Migration[6.1] disable_ddl_transaction! def change - unless index_exists?(:messages, name: 'index_messages_on_messageable_and_created_at') + unless index_exists?(:messages, nil, name: 'index_messages_on_messageable_and_created_at') add_index :messages, [:messageable_type, :messageable_id, :created_at], name: 'index_messages_on_messageable_and_created_at', diff --git a/db/schema.rb b/db/schema.rb index 17be733b0..754d9e043 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -18,13 +18,13 @@ enable_extension "plpgsql" create_table "access_passes", force: :cascade do |t| - t.datetime "access_expires_at", precision: 6 - t.datetime "generated_at", precision: 6 + t.datetime "access_expires_at" + t.datetime "generated_at" t.integer "generated_by_id" t.integer "access_key" t.bigint "printer_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["access_key"], name: "index_access_passes_on_access_key", unique: true t.index ["printer_id"], name: "index_access_passes_on_printer_id" end @@ -32,8 +32,8 @@ create_table "access_passes_roles", force: :cascade do |t| t.bigint "access_pass_id" t.bigint "role_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["access_pass_id"], name: "index_access_passes_roles_on_access_pass_id" t.index ["role_id"], name: "index_access_passes_roles_on_role_id" end @@ -46,9 +46,9 @@ t.integer "addressable_id" t.string "addressable_type" t.string "address_type" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 - t.datetime "deleted_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" t.string "notes" t.index ["addressable_id", "addressable_type"], name: "index_addresses_on_addressable_id_and_addressable_type" t.index ["district_id"], name: "index_addresses_on_district_id" @@ -62,7 +62,7 @@ end create_table "appointment_slots", id: :serial, force: :cascade do |t| - t.datetime "timestamp", precision: 6 + t.datetime "timestamp" t.integer "quota" t.string "note", default: "" end @@ -70,8 +70,8 @@ create_table "auth_tokens", id: :serial, force: :cascade do |t| t.string "otp_secret_key" t.integer "user_id" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.string "otp_auth_key", limit: 30 t.integer "last_otp_at" t.index ["user_id"], name: "index_auth_tokens_on_user_id" @@ -85,8 +85,8 @@ t.string "first_name" t.string "last_name" t.string "phone_number" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["created_by_id"], name: "index_beneficiaries_on_created_by_id" t.index ["identity_type_id"], name: "index_beneficiaries_on_identity_type_id" end @@ -94,8 +94,8 @@ create_table "booking_types", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "identifier" t.index ["name_en", "name_zh_tw"], name: "index_booking_types_on_name_en_and_name_zh_tw", unique: true end @@ -106,16 +106,16 @@ t.text "comments" t.integer "pallet_id" t.integer "stockit_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["pallet_id"], name: "index_boxes_on_pallet_id" end create_table "cancellation_reasons", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "visible_to_offer", default: true t.boolean "visible_to_order", default: false end @@ -126,8 +126,8 @@ t.string "content_en" t.string "content_zh_tw" t.string "respondable_type" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "message_type", default: "USER" t.string "guid" t.index ["guid"], name: "index_canned_responses_on_guid", unique: true @@ -137,8 +137,8 @@ t.string "name" t.integer "crm_id" t.integer "created_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "updated_by_id" end @@ -151,8 +151,8 @@ t.string "interface" t.string "comp_voltage" t.integer "updated_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "comp_test_status_id" end @@ -178,24 +178,24 @@ t.string "mar_os_serial_num" t.string "mar_ms_office_serial_num" t.integer "updated_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "comp_test_status_id" end create_table "contacts", id: :serial, force: :cascade do |t| t.string "name" t.string "mobile" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 - t.datetime "deleted_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" end create_table "countries", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "preferred_region" t.string "preferred_sub_region" t.integer "m49" @@ -210,8 +210,8 @@ create_table "crossroads_transports", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.integer "cost" t.float "truck_size" t.boolean "is_van_allowed", default: true @@ -222,12 +222,12 @@ t.integer "contact_id" t.integer "schedule_id" t.string "delivery_type" - t.datetime "start", precision: 6 - t.datetime "finish", precision: 6 - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "start" + t.datetime "finish" + t.datetime "created_at" + t.datetime "updated_at" t.integer "gogovan_order_id" - t.datetime "deleted_at", precision: 6 + t.datetime "deleted_at" t.index ["contact_id"], name: "index_deliveries_on_contact_id" t.index ["gogovan_order_id"], name: "index_deliveries_on_gogovan_order_id" t.index ["offer_id"], name: "index_deliveries_on_offer_id" @@ -238,8 +238,8 @@ t.string "name_en" t.string "name_zh_tw" t.integer "territory_id" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.float "latitude" t.float "longitude" t.bigint "districts_official_id" @@ -250,15 +250,15 @@ create_table "districts_official", force: :cascade do |t| t.string "name" t.string "name_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "donor_conditions", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.boolean "visible_to_donor", default: true, null: false end @@ -272,8 +272,8 @@ t.string "system_or_region" t.date "tested_on" t.integer "updated_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "test_status_id" t.integer "voltage_id" t.integer "frequency_id" @@ -282,23 +282,23 @@ create_table "gogovan_orders", id: :serial, force: :cascade do |t| t.integer "booking_id" t.string "status" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 - t.datetime "deleted_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" t.float "price" t.string "driver_name" t.string "driver_mobile" t.string "driver_license" t.string "ggv_uuid" - t.datetime "completed_at", precision: 6 + t.datetime "completed_at" t.index ["ggv_uuid"], name: "index_gogovan_orders_on_ggv_uuid", unique: true end create_table "gogovan_transports", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.boolean "disabled", default: false end @@ -308,8 +308,8 @@ t.integer "order_id" t.text "description" t.integer "created_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["created_by_id"], name: "index_goodcity_requests_on_created_by_id" t.index ["order_id"], name: "index_goodcity_requests_on_order_id" t.index ["package_type_id"], name: "index_goodcity_requests_on_package_type_id" @@ -323,28 +323,28 @@ end create_table "holidays", id: :serial, force: :cascade do |t| - t.datetime "holiday", precision: 6 + t.datetime "holiday" t.integer "year" t.string "name" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" end create_table "identity_types", id: :serial, force: :cascade do |t| t.string "identifier" t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "images", id: :serial, force: :cascade do |t| t.string "cloudinary_id" t.boolean "favourite", default: false t.integer "item_id" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 - t.datetime "deleted_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" t.integer "angle", default: 0 t.integer "imageable_id" t.string "imageable_type" @@ -362,10 +362,10 @@ t.integer "package_type_id" t.integer "rejection_reason_id" t.string "reject_reason" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.integer "donor_condition_id" - t.datetime "deleted_at", precision: 6 + t.datetime "deleted_at" t.text "rejection_comments" t.index ["donor_condition_id"], name: "index_items_on_donor_condition_id" t.index ["offer_id"], name: "index_items_on_offer_id" @@ -376,8 +376,8 @@ create_table "locations", id: :serial, force: :cascade do |t| t.string "building" t.string "area" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["area"], name: "index_locations_on_area", opclass: :gin_trgm_ops, using: :gin t.index ["building"], name: "index_locations_on_building", opclass: :gin_trgm_ops, using: :gin end @@ -387,8 +387,8 @@ t.string "key" t.string "label_en" t.string "label_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["name", "label_en"], name: "index_lookups_on_name_and_label_en" t.index ["name", "label_zh_tw"], name: "index_lookups_on_name_and_label_zh_tw" t.index ["name"], name: "index_lookups_on_name" @@ -400,17 +400,17 @@ t.string "brand" t.integer "country_id" t.integer "updated_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "messages", id: :serial, force: :cascade do |t| t.text "body" t.integer "sender_id" t.boolean "is_private", default: false - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 - t.datetime "deleted_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" t.string "messageable_type" t.integer "messageable_id" t.jsonb "lookup", default: "{}" @@ -418,7 +418,7 @@ t.index ["body"], name: "messages_body_search_idx", opclass: :gin_trgm_ops, using: :gin t.index ["lookup"], name: "index_messages_on_lookup", using: :gin t.index ["messageable_id", "messageable_type"], name: "index_messages_on_messageable_id_and_messageable_type" - t.index ["messageable_type", "messageable_id", "created_at"], name: "ix_messages_on_messageable_and_created_at", order: { created_at: :desc } + t.index ["messageable_type", "messageable_id", "created_at"], name: "index_messages_on_messageable_and_created_at", order: { created_at: :desc } t.index ["messageable_type", "messageable_id"], name: "index_messages_on_messageable_type_and_messageable_id" t.index ["sender_id"], name: "index_messages_on_sender_id" end @@ -426,8 +426,8 @@ create_table "offer_responses", force: :cascade do |t| t.integer "user_id" t.integer "offer_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["user_id", "offer_id"], name: "index_offer_responses_on_user_id_and_offer_id", unique: true end @@ -440,24 +440,24 @@ t.string "estimated_size" t.text "notes" t.integer "created_by_id" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 - t.datetime "deleted_at", precision: 6 - t.datetime "submitted_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" + t.datetime "submitted_at" t.integer "reviewed_by_id" - t.datetime "reviewed_at", precision: 6 + t.datetime "reviewed_at" t.integer "gogovan_transport_id" t.integer "crossroads_transport_id" - t.datetime "review_completed_at", precision: 6 - t.datetime "received_at", precision: 6 + t.datetime "review_completed_at" + t.datetime "received_at" t.string "delivered_by", limit: 30 t.integer "closed_by_id" - t.datetime "cancelled_at", precision: 6 + t.datetime "cancelled_at" t.integer "received_by_id" - t.datetime "start_receiving_at", precision: 6 + t.datetime "start_receiving_at" t.integer "cancellation_reason_id" t.string "cancel_reason" - t.datetime "inactive_at", precision: 6 + t.datetime "inactive_at" t.boolean "saleable", default: false t.integer "company_id" t.bigint "district_id" @@ -480,14 +480,14 @@ end create_table "order_transports", id: :serial, force: :cascade do |t| - t.datetime "scheduled_at", precision: 6 + t.datetime "scheduled_at" t.string "timeslot" t.string "transport_type" t.integer "contact_id" t.integer "gogovan_order_id" t.integer "order_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "need_english", default: false t.boolean "need_cart", default: false t.boolean "need_carry", default: false @@ -507,8 +507,8 @@ t.integer "detail_id" t.integer "stockit_contact_id" t.integer "stockit_organisation_id" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at" + t.datetime "updated_at", null: false t.text "description" t.integer "stockit_activity_id" t.integer "country_id" @@ -517,17 +517,17 @@ t.integer "organisation_id" t.string "state" t.text "purpose_description" - t.datetime "processed_at", precision: 6 + t.datetime "processed_at" t.integer "process_completed_by_id" - t.datetime "process_completed_at", precision: 6 - t.datetime "cancelled_at", precision: 6 + t.datetime "process_completed_at" + t.datetime "cancelled_at" t.integer "cancelled_by_id" - t.datetime "closed_at", precision: 6 + t.datetime "closed_at" t.integer "closed_by_id" - t.datetime "dispatch_started_at", precision: 6 + t.datetime "dispatch_started_at" t.integer "dispatch_started_by_id" t.integer "submitted_by_id" - t.datetime "submitted_at", precision: 6 + t.datetime "submitted_at" t.integer "people_helped", default: 0 t.integer "beneficiary_id" t.integer "address_id" @@ -565,9 +565,9 @@ t.string "state" t.integer "quantity" t.integer "updated_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.datetime "sent_on", precision: 6 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "sent_on" t.integer "dispatched_quantity", default: 0 t.integer "shipping_number" t.index ["order_id", "package_id"], name: "index_orders_packages_on_order_id_and_package_id" @@ -596,8 +596,8 @@ t.string "name_zh_tw" t.string "category_en" t.string "category_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "organisations", id: :serial, force: :cascade do |t| @@ -610,8 +610,8 @@ t.string "website" t.integer "country_id" t.integer "district_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "gih3_id" t.integer "crm_account_id" t.index ["country_id"], name: "index_organisations_on_country_id" @@ -625,8 +625,8 @@ t.integer "organisation_id" t.integer "user_id" t.string "position" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "preferred_contact_number" t.string "status", default: "pending" t.index ["organisation_id"], name: "index_organisations_users_on_organisation_id" @@ -637,8 +637,8 @@ t.string "name_en" t.string "name_zh_tw" t.integer "parent_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "icon_url" t.boolean "visible_in_browse", default: true t.index ["parent_id"], name: "index_package_categories_on_parent_id" @@ -647,8 +647,8 @@ create_table "package_categories_package_types", id: :serial, force: :cascade do |t| t.integer "package_type_id" t.integer "package_category_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["package_category_id"], name: "index_package_categories_package_types_on_package_category_id" t.index ["package_type_id"], name: "index_package_categories_package_types_on_package_type_id" end @@ -656,8 +656,8 @@ create_table "package_sets", id: :serial, force: :cascade do |t| t.integer "package_type_id" t.text "description" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["package_type_id"], name: "index_package_sets_on_package_type_id" end @@ -667,8 +667,8 @@ t.string "name_zh_tw" t.string "other_terms_en" t.string "other_terms_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "visible_in_selects", default: false t.integer "location_id" t.boolean "allow_requests", default: true @@ -700,12 +700,12 @@ t.text "notes", null: false t.integer "item_id" t.string "state" - t.datetime "received_at", precision: 6 - t.datetime "rejected_at", precision: 6 + t.datetime "received_at" + t.datetime "rejected_at" t.integer "package_type_id" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 - t.datetime "deleted_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" t.integer "offer_id", default: 0 t.string "inventory_number" t.integer "location_id" @@ -781,8 +781,8 @@ t.string "source_type" t.integer "source_id" t.integer "quantity", null: false - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.text "description" t.index ["action"], name: "index_packages_inventories_on_action" t.index ["created_at"], name: "index_packages_inventories_on_created_at" @@ -801,8 +801,8 @@ t.integer "package_id" t.integer "location_id" t.integer "quantity" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "reference_to_orders_package" t.index ["location_id", "package_id"], name: "index_packages_locations_on_location_id_and_package_id" t.index ["location_id"], name: "index_packages_locations_on_location_id" @@ -815,14 +815,14 @@ t.string "pallet_number" t.string "description" t.text "comments" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "permissions", id: :serial, force: :cascade do |t| t.string "name" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" end create_table "printers", id: :serial, force: :cascade do |t| @@ -833,8 +833,8 @@ t.string "port" t.string "username" t.string "password" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "printers_users", id: :serial, force: :cascade do |t| @@ -852,22 +852,22 @@ create_table "processing_destinations", force: :cascade do |t| t.string "name" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "purposes", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "identifier" end create_table "rejection_reasons", id: :serial, force: :cascade do |t| t.string "name_en" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.string "name_zh_tw" end @@ -885,23 +885,23 @@ create_table "restrictions", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "role_permissions", id: :serial, force: :cascade do |t| t.integer "role_id" t.integer "permission_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["permission_id"], name: "index_role_permissions_on_permission_id" t.index ["role_id"], name: "index_role_permissions_on_role_id" end create_table "roles", id: :serial, force: :cascade do |t| t.string "name" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "level" t.index ["level"], name: "index_roles_on_level" end @@ -911,9 +911,9 @@ t.integer "slot" t.string "slot_name" t.string "zone" - t.datetime "scheduled_at", precision: 6 - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "scheduled_at" + t.datetime "created_at" + t.datetime "updated_at" end create_table "shareables", force: :cascade do |t| @@ -921,10 +921,10 @@ t.integer "resource_id", null: false t.string "public_uid", null: false t.boolean "allow_listing", default: false, null: false - t.datetime "expires_at", precision: 6 + t.datetime "expires_at" t.integer "created_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.text "notes" t.text "notes_zh_tw" t.index ["created_by_id"], name: "index_shareables_on_created_by_id" @@ -938,8 +938,8 @@ create_table "stockit_activities", id: :serial, force: :cascade do |t| t.string "name" t.integer "stockit_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "stockit_contacts", id: :serial, force: :cascade do |t| @@ -948,8 +948,8 @@ t.string "mobile_phone_number" t.string "phone_number" t.integer "stockit_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["first_name"], name: "st_contacts_first_name_idx", opclass: :gin_trgm_ops, using: :gin t.index ["last_name"], name: "st_contacts_last_name_idx", opclass: :gin_trgm_ops, using: :gin t.index ["mobile_phone_number"], name: "st_contacts_mobile_phone_number_idx", opclass: :gin_trgm_ops, using: :gin @@ -961,8 +961,8 @@ t.string "hkid_number" t.string "reference_number" t.integer "stockit_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.text "purpose_of_goods" t.index ["client_name"], name: "st_local_orders_client_name_idx", opclass: :gin_trgm_ops, using: :gin end @@ -970,8 +970,8 @@ create_table "stockit_organisations", id: :serial, force: :cascade do |t| t.string "name" t.integer "stockit_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["name"], name: "st_organisations_name_idx", opclass: :gin_trgm_ops, using: :gin end @@ -983,8 +983,8 @@ t.boolean "dirty", default: false, null: false t.string "warning" t.integer "created_by_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "processed_delta", default: 0 t.jsonb "counted_by_ids", default: [] t.index ["counted_by_ids"], name: "index_stocktake_revisions_on_counted_by_ids" @@ -1000,8 +1000,8 @@ t.string "comment" t.integer "created_by_id" t.integer "location_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "counts", default: 0 t.integer "gains", default: 0 t.integer "losses", default: 0 @@ -1012,8 +1012,8 @@ create_table "storage_types", id: :serial, force: :cascade do |t| t.string "name" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "max_unit_quantity" end @@ -1021,8 +1021,8 @@ t.integer "package_type_id" t.integer "subpackage_type_id" t.boolean "is_default", default: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["package_type_id"], name: "index_subpackage_types_on_package_type_id" t.index ["package_type_id"], name: "index_subpackage_types_on_package_type_id_and_package_type_id" t.index ["subpackage_type_id"], name: "index_subpackage_types_on_subpackage_type_id" @@ -1036,7 +1036,6 @@ t.integer "subscribable_id" t.index ["message_id"], name: "index_subscriptions_on_message_id" t.index ["state"], name: "index_subscriptions_on_state" - t.index ["subscribable_id", "subscribable_type"], name: "index_subscriptions_on_subscribable_id_and_subscribable_type" t.index ["subscribable_type", "subscribable_id"], name: "index_subscriptions_on_subscribable_type_and_subscribable_id" t.index ["user_id"], name: "index_subscriptions_on_user_id" end @@ -1044,15 +1043,15 @@ create_table "territories", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" end create_table "timeslots", id: :serial, force: :cascade do |t| t.string "name_en" t.string "name_zh_tw" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" end create_table "user_favourites", force: :cascade do |t| @@ -1060,8 +1059,8 @@ t.integer "favourite_id" t.integer "user_id" t.boolean "persistent", default: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["favourite_type"], name: "index_user_favourites_on_favourite_type" t.index ["updated_at"], name: "index_user_favourites_on_updated_at" t.index ["user_id", "favourite_type", "favourite_id"], name: "index_user_and_favourites", unique: true @@ -1070,9 +1069,9 @@ create_table "user_roles", id: :serial, force: :cascade do |t| t.integer "user_id" t.integer "role_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.datetime "expires_at", precision: 6 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "expires_at" t.index ["role_id"], name: "index_user_roles_on_role_id" t.index ["user_id"], name: "index_user_roles_on_user_id" end @@ -1081,15 +1080,15 @@ t.string "first_name" t.string "last_name" t.string "mobile" - t.datetime "created_at", precision: 6 - t.datetime "updated_at", precision: 6 + t.datetime "created_at" + t.datetime "updated_at" t.integer "image_id" - t.datetime "last_connected", precision: 6 - t.datetime "last_disconnected", precision: 6 + t.datetime "last_connected" + t.datetime "last_disconnected" t.boolean "disabled", default: false t.string "email" t.string "title" - t.datetime "sms_reminder_sent_at", precision: 6 + t.datetime "sms_reminder_sent_at" t.boolean "is_mobile_verified", default: false t.boolean "is_email_verified", default: false t.boolean "receive_email", default: false @@ -1105,8 +1104,8 @@ t.integer "donor_condition_id", null: false t.string "grade", null: false t.decimal "multiplier", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "versions", id: :serial, force: :cascade do |t| @@ -1118,7 +1117,7 @@ t.jsonb "object_changes" t.integer "related_id" t.string "related_type" - t.datetime "created_at", precision: 6 + t.datetime "created_at" t.index ["created_at", "whodunnit"], name: "partial_index_recent_locations", where: "(((event)::text = ANY ((ARRAY['create'::character varying, 'update'::character varying])::text[])) AND (object_changes ? 'location_id'::text))" t.index ["created_at"], name: "index_versions_on_created_at" t.index ["event"], name: "index_versions_on_event" diff --git a/db/seeds.rb b/db/seeds.rb index 3055a3944..e68481f25 100755 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -245,7 +245,7 @@ end # Permission and Role mappings -permissions_roles = YAML.load_file("#{Rails.root}/db/permissions_roles.yml") +permissions_roles = YAML.load_file("#{Rails.root}/db/permissions_roles.yml", aliases: true) permissions_roles.each_pair do |role_name, permission_names| permission_names.flatten! if (role = Role.where(name: role_name).first_or_create) diff --git a/lib/classes/organisations_user_builder.rb b/lib/classes/organisations_user_builder.rb index 2b48dd20d..3d136c9d5 100644 --- a/lib/classes/organisations_user_builder.rb +++ b/lib/classes/organisations_user_builder.rb @@ -29,7 +29,18 @@ def self.update(organisations_user_id, organisations_user_params) # Implementation # ------------------------ - def initialize(organisation_id: nil, user_id: nil, user_attributes: nil, position: '', preferred_contact_number: '', status: '', change_author: User.current_user) + def initialize(options = nil, organisation_id: nil, user_id: nil, user_attributes: nil, position: '', preferred_contact_number: '', status: '', change_author: User.current_user) + if options.present? + opts = options.symbolize_keys + organisation_id ||= opts[:organisation_id] + user_id ||= opts[:user_id] + user_attributes ||= opts[:user_attributes] + position = opts[:position] if opts.key?(:position) + preferred_contact_number = opts[:preferred_contact_number] if opts.key?(:preferred_contact_number) + status = opts[:status] if opts.key?(:status) + change_author = opts[:change_author] if opts.key?(:change_author) + end + @change_author = change_author @organisation_id = organisation_id.to_i @position = position diff --git a/lib/classes/role_permissions_mappings.rb b/lib/classes/role_permissions_mappings.rb index dca0da4c6..d9acc718c 100644 --- a/lib/classes/role_permissions_mappings.rb +++ b/lib/classes/role_permissions_mappings.rb @@ -41,7 +41,7 @@ def remove_additional_permissions_for_role(role_name, permission_names) end def sync_roles_and_permissions - role_permissions = YAML.load_file("#{Rails.root}/db/permissions_roles.yml") + role_permissions = YAML.load_file("#{Rails.root}/db/permissions_roles.yml", aliases: true) role_permissions.each_pair do |role_name, permission_names| ActiveRecord::Base.transaction do permission_names.flatten! diff --git a/lib/goodcity/errors.rb b/lib/goodcity/errors.rb index a8556fd67..66c51e50b 100644 --- a/lib/goodcity/errors.rb +++ b/lib/goodcity/errors.rb @@ -77,7 +77,7 @@ def initialize(param) def factory(base, default_translation_key, **opts) error_klass = Class.new(base) do define_method(:initialize) do |translation_key: default_translation_key, params: {}| - msg = I18n.t(translation_key, { **params, default: translation_key }) + msg = I18n.t(translation_key, **params, default: translation_key) super(msg, **opts) end diff --git a/script/sidekiq_stats.rb b/script/sidekiq_stats.rb index e273536d7..164cd402f 100755 --- a/script/sidekiq_stats.rb +++ b/script/sidekiq_stats.rb @@ -1,4 +1,4 @@ -#! /home/deployer/.rvm/rubies/ruby-2.7.3/bin/ruby +#! /home/deployer/.rvm/rubies/ruby-3.1.7/bin/ruby # Executed by CheckMK using a wrapper script in /usr/share/check-mk-agent/local/sidekiq_stats # #!/bin/sh diff --git a/spec/controllers/api/v1/holidays_controller_spec.rb b/spec/controllers/api/v1/holidays_controller_spec.rb index 79ef79292..e1883a9d8 100644 --- a/spec/controllers/api/v1/holidays_controller_spec.rb +++ b/spec/controllers/api/v1/holidays_controller_spec.rb @@ -2,8 +2,8 @@ RSpec.describe Api::V1::HolidaysController, type: :controller do let(:holiday) { create :holiday } - let!(:holiday_1) { create(:holiday) } - let!(:holiday_2) { create(:holiday, holiday: Time.zone.now + 7.days) } + let!(:holiday_1) { create(:holiday, holiday: Time.zone.now + 30.days) } + let!(:holiday_2) { create(:holiday, holiday: Time.zone.now + 60.days) } let!(:reviewer) { create(:user, :with_can_manage_holidays_permission, role_name: 'Reviewer') } before { generate_and_set_token(reviewer) } @@ -29,11 +29,12 @@ describe 'Timestamp edge cases' do it "Should not include current day if it is a holiday", :show_in_doc do - create(:holiday, holiday: Time.now.beginning_of_day) - get :available_dates, params: { schedule_days: 6 } - body = JSON.parse(response.body) - expect(body.length).to eq(6) - expect(body).to_not include(Time.now.to_date.to_s) + Timecop.freeze(Time.zone.local(2026, 5, 5, 12, 0, 0)) do + create(:holiday, holiday: Time.zone.now.beginning_of_day) + get :available_dates, params: { schedule_days: 6 } + body = JSON.parse(response.body) + expect(body).to_not include(Time.zone.today.to_s) + end end end end diff --git a/spec/controllers/api/v1/offers_controller_spec.rb b/spec/controllers/api/v1/offers_controller_spec.rb index ee955b713..7c842f45a 100755 --- a/spec/controllers/api/v1/offers_controller_spec.rb +++ b/spec/controllers/api/v1/offers_controller_spec.rb @@ -577,7 +577,11 @@ get :search, params: { shareable: true, include_expiry: true } expect(response.status).to eq(200) expect(subject['offers'].size).to eq(3) - expect(subject["offers"].map{|offer| offer["id"]}).to eq([shareable1.resource_id, shareable2.resource_id, shareable3.resource_id]) + expect(subject["offers"].map { |offer| offer["id"] }).to match_array([ + shareable1.resource_id, + shareable2.resource_id, + shareable3.resource_id + ]) end end end diff --git a/spec/controllers/api/v1/packages_controller_spec.rb b/spec/controllers/api/v1/packages_controller_spec.rb index 8066b5bd2..f6d7ac139 100644 --- a/spec/controllers/api/v1/packages_controller_spec.rb +++ b/spec/controllers/api/v1/packages_controller_spec.rb @@ -81,11 +81,12 @@ def test_packages_location_changes(package) it "returns searched browseable_packages only" do set_browse_app_header + unique = "towel-#{SecureRandom.hex(4)}" 3.times{ create :package, :with_inventory_record, notes: "Baby towels", allow_web_publish: false } 3.times{ create :browseable_package, :with_inventory_record, notes: "Baby car seats" } - create :browseable_package, :with_inventory_record, notes: "towels" + create :browseable_package, :with_inventory_record, notes: unique expect(Package.count).to eq(7) - get :index, params: { "searchText": "towel" } + get :index, params: { "searchText" => unique } expect(response.status).to eq(200) expect( subject["packages"].size ).to eq(1) end @@ -118,11 +119,12 @@ def test_packages_location_changes(package) it "returns searched browseable_packages only" do set_browse_app_header + unique = "towel-#{SecureRandom.hex(4)}" 3.times{ create :package, :with_inventory_record, notes: "Baby towels", allow_web_publish: false } 3.times{ create :browseable_package, :with_inventory_record, notes: "Baby car seats" } - create :browseable_package, :with_inventory_record, notes: "towels" + create :browseable_package, :with_inventory_record, notes: unique expect(Package.count).to eq(7) - get :index, params: { "searchText": "towel" } + get :index, params: { "searchText" => unique } expect(response.status).to eq(200) expect( subject["packages"].size ).to eq(1) end @@ -1546,15 +1548,13 @@ def unpack(qty, pkg, out_of:) it 'performs loss action on package' do expect(@package.packages_locations.first.quantity).to eq(20) - put :register_quantity_change, { - params: { - id: @package.id, - quantity: 2, - from: @location.id, - action_name: "loss", - description: "Loss action on Package", - } - } + put :register_quantity_change, params: { + id: @package.id, + quantity: 2, + from: @location.id, + action_name: "loss", + description: "Loss action on Package", + } expect(response.status).to eq(200) expect(@package.packages_locations.first.quantity).to eq(18) @@ -1563,14 +1563,12 @@ def unpack(qty, pkg, out_of:) end it "performs process action on package" do - put :register_quantity_change, { - params: { - id: @package.id, - quantity: 10, - from: @location.id, - action_name: "process", - processing_destination_id: processing_destination.id - } + put :register_quantity_change, params: { + id: @package.id, + quantity: 10, + from: @location.id, + action_name: "process", + processing_destination_id: processing_destination.id } expect(response).to have_http_status(:success) @@ -1580,15 +1578,13 @@ def unpack(qty, pkg, out_of:) context 'when action is not process' do it 'should not add ProcessingDestination' do - put :register_quantity_change, { - params: { - id: @package.id, - quantity: 10, - from: @location.id, - action_name: "gain", - description: "gain action on Package", - processing_destination_id: processing_destination.id - } + put :register_quantity_change, params: { + id: @package.id, + quantity: 10, + from: @location.id, + action_name: "gain", + description: "gain action on Package", + processing_destination_id: processing_destination.id } expect(@package.package_actions.last.action).to eq('gain') @@ -1599,15 +1595,13 @@ def unpack(qty, pkg, out_of:) it "performs gain action on package" do expect(@package.packages_locations.first.quantity).to eq(20) - put :register_quantity_change, { - params: { - id: @package.id, - quantity: 10, - from: @location.id, - action_name: "gain", - description: "gain action on Package", - } - } + put :register_quantity_change, params: { + id: @package.id, + quantity: 10, + from: @location.id, + action_name: "gain", + description: "gain action on Package", + } expect(response.status).to eq(200) expect(@package.packages_locations.first.quantity).to eq(30) @@ -1616,30 +1610,26 @@ def unpack(qty, pkg, out_of:) end it "throws error for unsupported action" do - put :register_quantity_change, { - params: { - id: @package.id, - quantity: 2, - from: @location.id, - action_name: "invalid_action", - description: "Unsupported action on Package", - } - } + put :register_quantity_change, params: { + id: @package.id, + quantity: 2, + from: @location.id, + action_name: "invalid_action", + description: "Unsupported action on Package", + } expect(response.status).to eq(422) expect(parsed_body["error"]).to eq("Action you are trying to perform is not allowed") end it "throws error for invalid quantity" do - put :register_quantity_change, { - params: { - id: @package.id, - quantity: 25, - from: @location.id, - action_name: "loss", - description: "Loss action on Package", - } - } + put :register_quantity_change, params: { + id: @package.id, + quantity: 25, + from: @location.id, + action_name: "loss", + description: "Loss action on Package", + } expect(response.status).to eq(422) expect(parsed_body['error']).to eq("The selected quantity (25) is unavailable") diff --git a/spec/controllers/api/v1/requested_packages_controller_spec.rb b/spec/controllers/api/v1/requested_packages_controller_spec.rb index ef417262c..91514f7f3 100644 --- a/spec/controllers/api/v1/requested_packages_controller_spec.rb +++ b/spec/controllers/api/v1/requested_packages_controller_spec.rb @@ -63,9 +63,7 @@ let(:user) { create(:user, user_type) } let(:user2) { create(:user) } let(:package) { create(:package) } - let(:payload) do - return { params: {requested_package: { user_id: user.id, package_id: package.id } } } - end + let(:payload) { { requested_package: { user_id: user.id, package_id: package.id } } } before { initialize_inventory(package) @@ -73,20 +71,20 @@ } it "returns 201" do - post :create, payload + post :create, params: payload expect(response.status).to eq(201) end it "allows creating a requested_package for him/herself" do expect { - post :create, payload + post :create, params: payload }.to change(RequestedPackage, :count).by(1) expect(user.reload.requested_packages.length).to eq(1) end it "prevents requesting the same package a second time" do create(:requested_package, user_id: user.id, package_id: package.id) - post :create, payload + post :create, params: payload expect(response.status).to eq(422) expect(user.reload.requested_packages.length).to eq(1) end diff --git a/spec/factories/donor_conditions.rb b/spec/factories/donor_conditions.rb index 9e7431d82..bcaf26dfb 100644 --- a/spec/factories/donor_conditions.rb +++ b/spec/factories/donor_conditions.rb @@ -8,7 +8,16 @@ initialize_with { DonorCondition.find_or_initialize_by(name_en: name_en) } # avoid duplicates transient do - seq { @donor_conditions ||= YAML.load_file("#{Rails.root}/db/donor_conditions.yml") } + # Ruby 3.1+ (Psych 4) makes YAML.load/load_file safe by default, which + # rejects YAML tags like !!omap used in `db/donor_conditions.yml`. + seq do + path = "#{Rails.root}/db/donor_conditions.yml" + @donor_conditions ||= if YAML.respond_to?(:unsafe_load_file) + YAML.unsafe_load_file(path) + else + YAML.load_file(path) + end + end end end diff --git a/spec/factories/offers.rb b/spec/factories/offers.rb index 6c9598cbc..2e0b8122f 100755 --- a/spec/factories/offers.rb +++ b/spec/factories/offers.rb @@ -85,7 +85,7 @@ items_count { rand(3)+1 } end after(:create) do |offer, evaluator| - evaluator.items_count.times { create :item, :with_packages, :with_images, offer: offer } + evaluator.items_count.times { FactoryBot.create(:item, :with_packages, :with_images, offer: offer) } end end @@ -95,7 +95,7 @@ items_count { rand(3)+1 } end after(:create) do |offer, evaluator| - evaluator.items_count.times { create :demo_item, offer: offer } + evaluator.items_count.times { FactoryBot.create(:demo_item, offer: offer) } end end @@ -104,7 +104,7 @@ delivery_type { [:crossroads_delivery, :drop_off_delivery].sample } end after(:create) do |offer, evaluator| - create evaluator.delivery_type, offer: offer + FactoryBot.create(evaluator.delivery_type, offer: offer) end end @@ -113,13 +113,13 @@ messages_count { 1 } end after(:create) do |offer, evaluator| - create_list(:message, evaluator.messages_count, :reviewer_message, messageable: offer) + FactoryBot.create_list(:message, evaluator.messages_count, :reviewer_message, messageable: offer) end end trait :paranoid do state { 'submitted' } - items { [create(:item)] } + items { [FactoryBot.create(:item)] } end trait :with_transport do diff --git a/spec/factories/orders.rb b/spec/factories/orders.rb index a92e1a9ce..f072f9c23 100644 --- a/spec/factories/orders.rb +++ b/spec/factories/orders.rb @@ -37,29 +37,29 @@ trait :with_orders_packages do after(:create) do |order| - order.orders_packages << create_list(:orders_package, 3, :with_state_requested, :with_inventory_record, order: order) - order.save + create_list(:orders_package, 3, :with_state_requested, :with_inventory_record, order: order) + order.reload end end trait :with_designated_orders_packages do after(:create) do |order| - order.orders_packages << create_list(:orders_package, 3, :with_state_designated, :with_inventory_record, order: order) - order.save + create_list(:orders_package, 3, :with_state_designated, :with_inventory_record, order: order) + order.reload end end trait :with_cancelled_orders_packages do after(:create) do |order| - order.orders_packages << create_list(:orders_package, 3, :with_state_cancelled, :with_inventory_record, order: order) - order.save + create_list(:orders_package, 3, :with_state_cancelled, :with_inventory_record, order: order) + order.reload end end trait :with_dispatched_orders_packages do after(:create) do |order| - order.orders_packages << create_list(:orders_package, 3, :with_state_dispatched, :with_inventory_record, order: order) - order.save + create_list(:orders_package, 3, :with_state_dispatched, :with_inventory_record, order: order) + order.reload end end diff --git a/spec/factories/roles.rb b/spec/factories/roles.rb index 33579625e..d40e6b0bd 100644 --- a/spec/factories/roles.rb +++ b/spec/factories/roles.rb @@ -37,11 +37,13 @@ # create(:reviewer_role, :with_can_manage_offers_permission) # create(:reviewer_role, :with_can_manage_offers_permission, :with_can_manage_messages_permission) - YAML.load_file("#{Rails.root}/db/permissions_roles.yml").each do |role_name, permissions| + YAML.load_file("#{Rails.root}/db/permissions_roles.yml", aliases: true).each do |role_name, permissions| + permissions = ::Kernel.Array(permissions).flatten permissions.each do |permission| + permission = permission.to_s trait "with_#{permission}_permission".to_sym do after(:create) do |role| - p = create(:permission, name: permission) + p = create(:permission, name: permission.to_s) role.permissions << p unless role.permissions.include?(p) end end diff --git a/spec/factories/sequences.rb b/spec/factories/sequences.rb index a4b45aa29..423d23415 100755 --- a/spec/factories/sequences.rb +++ b/spec/factories/sequences.rb @@ -16,7 +16,7 @@ end sequence :permissions_roles do |n| - roles = YAML.load_file("#{Rails.root}/db/permissions_roles.yml") + roles = YAML.load_file("#{Rails.root}/db/permissions_roles.yml", aliases: true) roles.each_pair { |key, value| value.flatten! } @permissions_roles ||= roles end diff --git a/spec/lib/goodcity/user_safe_delete_spec.rb b/spec/lib/goodcity/user_safe_delete_spec.rb index 375e2c5f9..fe23472a9 100644 --- a/spec/lib/goodcity/user_safe_delete_spec.rb +++ b/spec/lib/goodcity/user_safe_delete_spec.rb @@ -52,7 +52,18 @@ end context "returns false if trying to delete app_store user" do - let(:user) { create(:user, mobile: ENV['APPSTORE_REVIEWER_LOGIN_NUMBER']) } + let(:appstore_number) { "+85260000000" } + let(:user) { create(:user, mobile: appstore_number) } + + around do |example| + secrets = Rails.application.secrets + original = secrets.appstore_reviewer_login + secrets.appstore_reviewer_login = { number: appstore_number } + example.run + ensure + secrets.appstore_reviewer_login = original + end + it do expect(subject.can_delete[:result]).to eql(false) expect(subject.can_delete[:reason]).to eql("App Store Reviewer account cannot be deleted.") diff --git a/spec/models/concerns/message_subscriptions_spec.rb b/spec/models/concerns/message_subscriptions_spec.rb index f3a0447c4..d234d5ad1 100644 --- a/spec/models/concerns/message_subscriptions_spec.rb +++ b/spec/models/concerns/message_subscriptions_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' module Messages - describe Operations do + describe MessageSubscriptions do let(:offer) { create :offer } let(:message) { create :message, sender: reviewer, messageable: offer } let!(:supervisor) { create :user, :with_supervisor_role, :with_can_manage_offer_messages_permission } @@ -255,7 +255,7 @@ module Messages let!(:user1) { create(:user) } let!(:user2) { create(:user) } let(:message) { create(:message, body: "Hello [:#{user1.id}]. I need help from you and [:#{user2.id}]") } - let(:message2) { build(:message, body: "Hello [:#{user2.id}]. I will help") } + let(:message2) { build(:message, sender: reviewer, messageable: offer1, body: "Hello [:#{user2.id}]. I will help") } before(:each) do allow(message).to receive(:add_subscription) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index c6a37f99d..5d8dd4806 100755 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -57,7 +57,7 @@ # Create system_user config.before(:suite) do - FactoryBot.create(:user, :system) + FactoryBot.create(:user, :system) unless User.system_user.present? end # Clean up system_user at end of specs