diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9f702a254..69c109429 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -55,6 +55,7 @@ jobs:
- restore_cache:
<<: *restore_bundle
- run: bundle install --path vendor/bundle --without development
+ - run: bin/plugdo bundle install --path "$(readlink -m vendor/bundle)" --without development
- save_cache:
key: nokul-bundle-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
paths:
@@ -128,9 +129,11 @@ jobs:
- restore_cache:
<<: *restore_yarn
- run: bundle --path vendor/bundle --without development
+ - run: bin/plugdo bundle install --path "$(readlink -m vendor/bundle)" --without development
+ - run: sudo apt install -y postgresql-client || true
- run: bin/yarn install
- - run: bundle exec rake db:create db:schema:load
- - run: bundle exec rake test
+ - run: bundle exec rake db:create db:structure:load
+ - run: bundle exec rails test:system test
deploy_develop:
machine:
enabled: true
@@ -139,8 +142,8 @@ jobs:
- run:
name: Deploy Develop to Dokku
command: |
- git remote add develop dokku@app.omu.sh:nokul-develop &&
- git push develop develop:master
+ git remote add beta dokku@app.omu.sh:nokul-develop &&
+ git push beta develop:master
deploy_master:
machine:
enabled: true
@@ -149,8 +152,8 @@ jobs:
- run:
name: Deploy Master to Dokku
command: |
- git remote add beta dokku@app.omu.sh:nokul &&
- git push beta master
+ git remote add production dokku@app.omu.sh:nokul &&
+ git push production master
# build flow
workflows:
diff --git a/.envrc b/.envrc
deleted file mode 100644
index 977a5e8f4..000000000
--- a/.envrc
+++ /dev/null
@@ -1 +0,0 @@
-export PATH=$PWD/bin:$PATH
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2a5a3844c..f8f237723 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -18,4 +18,5 @@ Vagrantfile @roktas @huseyin @ecylmz @sinansh
/lib/ @msdundar @ecmelkytz @dilara @isubas @sinansh
/test/ @msdundar @ecmelkytz @dilara @isubas @sinansh
Gemfile @msdundar @ecmelkytz @dilara @isubas @sinansh
+Gemfile.lock @msdundar @ecmelkytz @dilara @isubas @sinansh
package.json @msdundar @ecmelkytz @dilara @isubas @sinansh
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 8b7b410c6..309bb82b5 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -44,7 +44,7 @@ Proje sırları `credentials.yml.enc` dosyasında tutulmaktadır. Bu dosyaya eri
- VPN
-Harici servisler yalnızca BAUM-VPN'e açıktır. Geliştirme yaparken ihtiyaç duyacağınız bu servisleri kullanmak için BAUM-VPN'e bağlı olmalısınız. VPN erişimi için [sistem grubu](https://github.com/orgs/omu/teams/ops) ile iletişime geçin. Tüm geliştirme süreciniz boyunca ve testleri çalıştırırken mutlaka BAUM-VPN'e bağlı olun.
+Harici servisler yalnızca [BAUM-VPN](https://github.com/omu/omu/blob/master/doc/vpn.md#baum-vpn)'e açıktır. Geliştirme yaparken ihtiyaç duyacağınız bu servisleri kullanmak için BAUM-VPN'e bağlı olmalısınız. VPN erişimi için [sistem grubu](https://github.com/orgs/omu/teams/ops) ile iletişime geçin. Tüm geliştirme süreciniz boyunca ve testleri çalıştırırken mutlaka BAUM-VPN'e bağlı olun.
### Geliştirme Süreci
---------------------
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
index b4671a045..f98d0a7a5 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -1,6 +1,7 @@
---
name: Hata raporu
about: Tespit ettiğiniz hataları, beklenen dışında çalışan özelliklerin bildirimi.
+labels: bug
---
diff --git a/.github/ISSUE_TEMPLATE/design-proposal.md b/.github/ISSUE_TEMPLATE/design-proposal.md
index bf556daa6..1e2be49df 100644
--- a/.github/ISSUE_TEMPLATE/design-proposal.md
+++ b/.github/ISSUE_TEMPLATE/design-proposal.md
@@ -1,6 +1,7 @@
---
name: Tasarım önerisi
about: Uygulamanın varolan UI/UX'i ile ilgili değişiklik önerisi. Varolan sayfalardaki sorunlar için 'hata raporu', varolmayan sayfalar için 'özellik önerisi' template'ini kullanın.
+labels: ux, product
---
diff --git a/.github/ISSUE_TEMPLATE/feature-proposal.md b/.github/ISSUE_TEMPLATE/feature-proposal.md
index 52b9c27ee..3ffb045e7 100644
--- a/.github/ISSUE_TEMPLATE/feature-proposal.md
+++ b/.github/ISSUE_TEMPLATE/feature-proposal.md
@@ -1,6 +1,8 @@
---
name: Özellik önerisi
about: Bu projeye eklenmesini istediğiniz veya değiştirilmesini istediğiniz bir özellik.
+labels: product
+assignees: abdagli, begum, ekural
---
diff --git a/.github/ISSUE_TEMPLATE/use-case.md b/.github/ISSUE_TEMPLATE/use-case.md
index 784686817..eedcec320 100644
--- a/.github/ISSUE_TEMPLATE/use-case.md
+++ b/.github/ISSUE_TEMPLATE/use-case.md
@@ -1,6 +1,7 @@
---
name: Use Case
about: Product ekibi tarafından hazırlanmış `use case` için iş kaydı.
+labels: feature, product
---
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 8d722678e..6402a3da7 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -2,13 +2,9 @@
[//]: # (Kısa ve net bir şekilde bu PR'e neden ihtiyaç var, ne iş/değişiklik yapıyor açıklanmalıdır.)
-**İlgili iş kayıtları:**
+**İlgili/kapatılacak iş kayıtları:**
-[//]: # (Bu PR ile ilişkili iş kayıtlarının ID numaraları, örn. #123456, #123457, #123458, listeleyin.)
-
-**Kapatılacak iş kayıtları:**
-
-[//]: # (Bu PR merge edildiğinde hangi iş kayıtları kapatılacak, `Closes`, `Fixes` gibi anahtar kelimeler ile birlikte ID numaralarını listeleyin.)
+[//]: # (Bu PR merge edildiğinde hangi iş kayıtları kapatılacak ise `Closes`, `Fixes` gibi anahtar kelimeler ile birlikte ID numaralarını listeleyin. Kapatılmayan ancak referans verilecek iş kayıtları için `References` anahtar kelimesini kullanın.)
**Veritabanına etkileri:**
@@ -32,4 +28,4 @@
**Ek içerik:**
-[//]: # (Kaynaklar, dış bağlantılar, ekran görüntüleri, örnek çözümler ve benzeri diğer kaynakları ekleyiniz.)
+[//]: # (Varsa kaynaklar, dış bağlantılar, ekran görüntüleri, örnek çözümler ve benzeri diğer kaynakları ekleyiniz.)
diff --git a/.gitignore b/.gitignore
index 500ba0bba..0c85068f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,12 @@
.byebug_history
.vagrant*/
.env
+.envrc
/storage/*
+/.local/
# never remove!
-config/master.key
\ No newline at end of file
+config/master.key
+
+# Ignore misc.
+/bin/dokku
diff --git a/.rubocop.yml b/.rubocop.yml
index 2cb6ae3d2..9b4484f52 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,6 +1,4 @@
Style/AsciiComments:
- Description: 'Use only ascii symbols in comments.'
- StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-comments'
Enabled: false
Style/Lambda:
Enabled: false
@@ -18,7 +16,9 @@ Metrics/LineLength:
- app/validators/employee_validator.rb # Won't fix
Metrics/BlockLength:
Exclude:
+ - config/routes/**/*
- lib/tasks/**/*.rake # Won't fix
+ - test/models/concerns/reference_validations_test.rb
Metrics/ClassLength:
Exclude:
- test/**/*.rb
@@ -28,12 +28,11 @@ AllCops:
Exclude:
- bin/**/*
- vendor/bundle/**/*
+ - node_modules/**/*
- db/schema.rb
- db/migrate/*.rb
- config/initializers/simple_form.rb
- config/initializers/simple_form_bootstrap.rb
- config/environments/*.rb
- config/routes.rb
- - app/services/kps/omu/adres.rb # WIP
- - app/services/kps/omu/kimlik.rb # WIP
- Vagrantfile
diff --git a/Dockerfile b/Dockerfile
index 9f283263c..deb7adba8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,20 @@
FROM ondokuz/ruby-stretch:0.10.0
-ARG RAILS_ENV
+ENV PATH=/app/bin:$PATH
+
+RUN apt-get update \
+ && apt-get -y --no-install-recommends install xfonts-75dpi=1:1.0.4+nmu1 xfonts-base=1:1.0.4+nmu1 \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb \
+ && dpkg -i wkhtmlto* \
+ && rm -f wkhtmlto*
+
+ARG NOKUL_TENANT=omu
+ENV NOKUL_TENANT=$NOKUL_TENANT
+
+ARG RAILS_ENV=beta
ENV RAILS_ENV=$RAILS_ENV
ARG RAILS_MASTER_KEY
@@ -15,6 +29,16 @@ COPY .ruby-version ./
COPY Gemfile Gemfile.lock ./
COPY package.json yarn.lock ./
+COPY plugins/support/lib/nokul/support/version.rb ./plugins/support/lib/nokul/support/version.rb
+COPY plugins/support/nokul-support.gemspec ./plugins/support/nokul-support.gemspec
+
+COPY plugins/tenant/common/lib/nokul/tenant/version.rb ./plugins/tenant/common/lib/nokul/tenant/version.rb
+COPY plugins/tenant/common/nokul-tenant.gemspec ./plugins/tenant/common/nokul-tenant.gemspec
+
+COPY plugins/tenant/$NOKUL_TENANT/lib/nokul/tenant/$NOKUL_TENANT/version.rb ./plugins/tenant/$NOKUL_TENANT/lib/nokul/tenant/$NOKUL_TENANT/version.rb
+COPY plugins/tenant/$NOKUL_TENANT/nokul-tenant-$NOKUL_TENANT.gemspec ./plugins/tenant/$NOKUL_TENANT/nokul-tenant-$NOKUL_TENANT.gemspec
+
+RUN bundle config --global silence_root_warning true
RUN bundle install --without development:test -j4 --deployment
RUN yarn install
diff --git a/Gemfile b/Gemfile
index a3e2d2695..441a5a4f2 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,12 +10,17 @@ end
# core
gem 'bootsnap', '>= 1.1.0', require: false
-gem 'pg'
gem 'puma', '~> 3.11'
gem 'rails', '~> 5.2.1'
gem 'redis'
gem 'sidekiq'
+# database
+gem 'pg'
+gem 'pg_search'
+gem 'pghero'
+gem 'rein'
+
# active-record
gem 'ancestry'
@@ -37,19 +42,18 @@ gem 'font-awesome-rails'
gem 'groupdate' # for chartkick
gem 'pagy'
gem 'simple_form'
+gem 'wicked_pdf'
# api
gem 'jbuilder', '~> 2.5'
# security
gem 'bcrypt', '~> 3.1.7'
+gem 'rack-attack'
# validators
gem 'email_address'
-# search
-gem 'pg_search'
-
# error tracking
gem 'rollbar'
@@ -86,3 +90,14 @@ group :development do
gem 'spring-watcher-listen', '~> 2.0.0'
gem 'web-console', '>= 3.3.0' # call <%= console %> anywhere in the code.
end
+
+# core plugins
+gem 'nokul-support', path: 'plugins/support'
+gem 'nokul-tenant', path: 'plugins/tenant/common'
+
+# tenants (won't be listed at Rails.groups)
+Dir['plugins/tenant/**/*.gemspec'].each do |gemspec|
+ next if (name = File.basename(gemspec, '.gemspec')) == 'nokul-tenant'
+
+ gem name, path: File.dirname(gemspec), require: false
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index ca770e199..18c1d4f6d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,3 +1,22 @@
+PATH
+ remote: plugins/support
+ specs:
+ nokul-support (0.1.0)
+ activesupport (~> 5.2.2)
+
+PATH
+ remote: plugins/tenant/common
+ specs:
+ nokul-tenant (0.1.0)
+ nokul-support
+
+PATH
+ remote: plugins/tenant/omu
+ specs:
+ nokul-tenant-omu (0.1.0)
+ nokul-tenant
+ rails (~> 5.2.2)
+
GEM
remote: https://rubygems.org/
specs:
@@ -51,8 +70,8 @@ GEM
arel (9.0.0)
ast (2.4.0)
aws-eventstream (1.0.1)
- aws-partitions (1.121.0)
- aws-sdk-core (3.42.0)
+ aws-partitions (1.133.0)
+ aws-sdk-core (3.46.0)
aws-eventstream (~> 1.0)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.0)
@@ -60,7 +79,7 @@ GEM
aws-sdk-kms (1.13.0)
aws-sdk-core (~> 3, >= 3.39.0)
aws-sigv4 (~> 1.0)
- aws-sdk-s3 (1.29.0)
+ aws-sdk-s3 (1.30.1)
aws-sdk-core (~> 3, >= 3.39.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0)
@@ -69,13 +88,13 @@ GEM
bindex (0.5.0)
bootsnap (1.3.2)
msgpack (~> 1.0)
- brakeman (4.3.1)
+ brakeman (4.4.0)
builder (3.2.3)
bullet (5.9.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
- bundler-audit (0.6.0)
- bundler (~> 1.2)
+ bundler-audit (0.6.1)
+ bundler (>= 1.2.0, < 3)
thor (~> 0.18)
byebug (10.0.2)
capybara (3.12.0)
@@ -86,7 +105,7 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (~> 1.2)
xpath (~> 3.2)
- chartkick (3.0.1)
+ chartkick (3.0.2)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
chromedriver-helper (2.1.0)
@@ -96,7 +115,7 @@ GEM
codacy-coverage (2.1.0)
simplecov
coderay (1.1.2)
- concurrent-ruby (1.1.3)
+ concurrent-ruby (1.1.4)
connection_pool (2.2.2)
crack (0.4.3)
safe_yaml (~> 1.0.0)
@@ -108,34 +127,34 @@ GEM
responders
warden (~> 1.2.3)
docile (1.3.1)
- dotenv (2.5.0)
- dotenv-rails (2.5.0)
- dotenv (= 2.5.0)
+ dotenv (2.6.0)
+ dotenv-rails (2.6.0)
+ dotenv (= 2.6.0)
railties (>= 3.2, < 6.0)
email_address (0.1.11)
netaddr (~> 2.0)
simpleidn
- erubi (1.7.1)
+ erubi (1.8.0)
execjs (2.7.0)
ffi (1.9.25)
fit-commit (3.8.0)
swearjar (~> 1.0)
font-awesome-rails (4.7.0.4)
railties (>= 3.2, < 6.0)
- friendly_id (5.2.4)
+ friendly_id (5.2.5)
activerecord (>= 4.0.0)
- globalid (0.4.1)
+ globalid (0.4.2)
activesupport (>= 4.2.0)
- groupdate (4.1.0)
+ groupdate (4.1.1)
activesupport (>= 4.2)
- hashdiff (0.3.7)
- i18n (1.1.1)
+ hashdiff (0.3.8)
+ i18n (1.5.2)
concurrent-ruby (~> 1.0)
image_processing (1.7.1)
mini_magick (~> 4.0)
ruby-vips (>= 2.0.13, < 3)
io-like (0.3.0)
- jaro_winkler (1.5.1)
+ jaro_winkler (1.5.2)
jbuilder (2.8.0)
activesupport (>= 4.2.0)
multi_json (>= 1.2)
@@ -143,7 +162,7 @@ GEM
json (2.1.0)
launchy (2.4.3)
addressable (~> 2.3)
- letter_opener (1.6.0)
+ letter_opener (1.7.0)
launchy (~> 2.2)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
@@ -161,39 +180,43 @@ GEM
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
- mimemagic (0.3.2)
+ mimemagic (0.3.3)
mini_magick (4.9.2)
mini_mime (1.0.1)
- mini_portile2 (2.3.0)
+ mini_portile2 (2.4.0)
minitest (5.11.3)
- msgpack (1.2.4)
+ msgpack (1.2.6)
multi_json (1.13.1)
netaddr (2.0.3)
nio4r (2.3.1)
- nokogiri (1.8.5)
- mini_portile2 (~> 2.3.0)
+ nokogiri (1.10.1)
+ mini_portile2 (~> 2.4.0)
orm_adapter (0.5.0)
- pagy (1.2.0)
- parallel (1.12.1)
- parser (2.5.3.0)
+ pagy (1.3)
+ parallel (1.13.0)
+ parser (2.6.0.0)
ast (~> 2.4.0)
- pg (1.1.3)
- pg_search (2.1.2)
+ pg (1.1.4)
+ pg_search (2.1.3)
activerecord (>= 4.2)
activesupport (>= 4.2)
arel (>= 6)
+ pghero (2.2.0)
+ activerecord
powerpack (0.1.2)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
- pry-rails (0.3.8)
+ pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (3.0.3)
puma (3.12.0)
rack (2.0.6)
- rack-mini-profiler (1.0.0)
+ rack-attack (5.4.2)
+ rack (>= 1.0, < 3)
+ rack-mini-profiler (1.0.1)
rack (>= 1.2.0)
- rack-protection (2.0.4)
+ rack-protection (2.0.5)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
@@ -222,18 +245,21 @@ GEM
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
- rake (12.3.1)
+ rake (12.3.2)
rb-fsevent (0.10.3)
- rb-inotify (0.9.10)
- ffi (>= 0.5.0, < 2)
- redis (4.0.3)
+ rb-inotify (0.10.0)
+ ffi (~> 1.0)
+ redis (4.1.0)
regexp_parser (1.3.0)
+ rein (3.5.0)
+ activerecord (>= 4.0.0, < 6)
+ activesupport (>= 4.0.0, < 6)
responders (2.4.0)
actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
- rollbar (2.18.0)
+ rollbar (2.18.2)
multi_json
- rubocop (0.60.0)
+ rubocop (0.63.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1)
@@ -250,7 +276,7 @@ GEM
sassc (2.0.0)
ffi (~> 1.9.6)
rake
- sassc-rails (2.0.0)
+ sassc-rails (2.1.0)
railties (>= 4.0.0)
sassc (>= 2.0)
sprockets (> 3.0)
@@ -259,8 +285,9 @@ GEM
selenium-webdriver (3.141.0)
childprocess (~> 0.5)
rubyzip (~> 1.2, >= 1.2.2)
- sidekiq (5.2.3)
+ sidekiq (5.2.5)
connection_pool (~> 2.2, >= 2.2.2)
+ rack (>= 1.5.0)
rack-protection (>= 1.5.0)
redis (>= 3.3.5, < 5)
simple_form (4.1.0)
@@ -296,7 +323,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.7.5)
- unicode-display_width (1.4.0)
+ unicode-display_width (1.4.1)
uniform_notifier (1.12.1)
warden (1.2.8)
rack (>= 2.0.6)
@@ -305,13 +332,14 @@ GEM
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
- webmock (3.4.2)
+ webmock (3.5.1)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
+ wicked_pdf (1.1.0)
xpath (3.2.0)
nokogiri (~> 1.8)
@@ -344,14 +372,20 @@ DEPENDENCIES
letter_opener
listen (>= 3.0.5, < 3.2)
lol_dba
+ nokul-support!
+ nokul-tenant!
+ nokul-tenant-omu!
pagy
pg
pg_search
+ pghero
pry-rails
puma (~> 3.11)
+ rack-attack
rack-mini-profiler
rails (~> 5.2.1)
redis
+ rein
rollbar
rubocop
ruby-progressbar
@@ -365,9 +399,10 @@ DEPENDENCIES
uglifier (>= 1.3.0)
web-console (>= 3.3.0)
webmock
+ wicked_pdf
RUBY VERSION
ruby 2.5.1p57
BUNDLED WITH
- 1.17.1
+ 1.17.3
diff --git a/Rakefile b/Rakefile
index d841fe27e..488c551fe 100644
--- a/Rakefile
+++ b/Rakefile
@@ -4,7 +4,5 @@
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative 'config/application'
-require_relative 'lib/support/utils/rake_utils'
-require_relative 'lib/support/ext/progress_bar'
Rails.application.load_tasks
diff --git a/Vagrantfile b/Vagrantfile
index 62e0ff171..9ee46cf68 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -1,6 +1,15 @@
# frozen_string_literal: true
Vagrant.configure('2') do |config|
+ if ENV['LOCAL_CACHE_DIR']
+ FileUtils.mkdir_p ENV['LOCAL_CACHE_DIR'] unless Dir.exist?(ENV['LOCAL_CACHE_DIR'])
+ app_cache_dir = '/var/cache/app'
+
+ config.vm.synced_folder ENV['LOCAL_CACHE_DIR'], app_cache_dir
+
+ env = { 'LOCAL_CACHE_DIR': app_cache_dir }
+ end
+
config.vm.define 'dev', primary: true do |dev|
dev.vm.box = 'omu/debian-stable-server'
@@ -10,34 +19,19 @@ Vagrant.configure('2') do |config|
lxc.customize 'cgroup.memory.limit_in_bytes', '2048M'
end
- dev.vm.provision 'shell', inline: <<~SHELL
- systemctl enable --now postgresql
- systemctl enable --now redis-server
-
- gem install bundler foreman
-
- cd /vagrant
-
- sudo -u postgres psql <<-EOF
- CREATE USER nokul WITH ENCRYPTED PASSWORD 'nokul';
- ALTER ROLE nokul LOGIN CREATEDB SUPERUSER;
- EOF
-
- sudo -u op sh -xs <<-EOF
- bundle install -j4 --deployment
- yarn install
-
- bin/rails db:create
- bin/rails db:migrate
- bin/rails db:seed
- EOF
-
- foreman export -p3000 --app nokul --user op systemd /etc/systemd/system/
- systemctl enable --now nokul.target
- SHELL
+ dev.vm.provision 'shell', name: 'preinst', env: env, path: 'lib/scripts/preinst.sh'
+ dev.vm.provision 'shell', name: 'environment', env: env, path: 'lib/scripts/environment.sh'
+ dev.vm.provision 'shell', name: 'deploy', env: env, path: 'lib/scripts/deploy.sh'
end
config.vm.define 'paas', autostart: false do |paas|
paas.vm.box = 'omu/debian-stable-paas'
+
+ paas.trigger.after :provision do |trigger|
+ Dir.chdir __dir__
+
+ trigger.info = 'Provisioning paas...'
+ trigger.run = { inline: 'bash lib/scripts/paas.sh' }
+ end
end
end
diff --git a/app/assets/javascripts/helpers/dynamic_select.js b/app/assets/javascripts/helpers/dynamic_select.js
index f433c452b..f5d826bdb 100644
--- a/app/assets/javascripts/helpers/dynamic_select.js
+++ b/app/assets/javascripts/helpers/dynamic_select.js
@@ -5,26 +5,31 @@
var DynamicSelect = function (parameters) { // eslint-disable-line no-unused-vars
function init () {
$.each(parameters, function (k, parameter) {
- $(parameter['el']).change(function (event) {
+ $(parameter.el).change(function (event, value = undefined) {
var path = generateSourcePath(parameter)
var config = {
- label_attribute: parameter['label_attribute'],
- value_attribute: parameter['value_attribute'],
- placeholder: parameter['placeholder'],
- target: parameter['target']
+ value: value,
+ label_attribute: parameter.label_attribute,
+ value_attribute: parameter.value_attribute,
+ placeholder: parameter.placeholder,
+ target: parameter.target
}
- reset($(parameter['reset_selectors']))
+ reset($(parameter.reset_selectors))
builder(path, config)
})
+ if ('after_initialize' in parameter) parameter.after_initialize()
})
}
function builder (path, config) {
$.getJSON(path, function (response) {
var options = new OptionsBuilder(
- response, config.placeholder, { 'labelMethod': config.label_attribute, 'valueMethod': config.value_attribute }
+ response, config.placeholder, {
+ labelMethod: config.label_attribute,
+ valueMethod: config.value_attribute
+ }
)
- options.setSelectBox($(config.target))
+ options.setSelectBox($(config.target), config.value)
})
}
@@ -77,10 +82,11 @@ var OptionsBuilder = function (datas, placeholder, config = {}) {
return `${placeholder} `
}
- function setSelectBox (el) {
+ function setSelectBox (el, value = undefined) {
var options = build()
el.html(options.join(' '))
el.attr('disabled', false)
+ if (value !== undefined) el.val(value)
}
return {
diff --git a/app/controllers/admin/assessment_methods_controller.rb b/app/controllers/admin/assessment_methods_controller.rb
new file mode 100644
index 000000000..d4f2dd0c4
--- /dev/null
+++ b/app/controllers/admin/assessment_methods_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Admin
+ class AssessmentMethodsController < ApplicationController
+ include ReferenceResource
+
+ private
+
+ def secure_params
+ params.require(:assessment_method).permit(:name)
+ end
+ end
+end
diff --git a/app/controllers/admin/cities_controller.rb b/app/controllers/admin/cities_controller.rb
new file mode 100644
index 000000000..1c678f794
--- /dev/null
+++ b/app/controllers/admin/cities_controller.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Admin
+ class CitiesController < ApplicationController
+ include PagyBackendWithHelpers
+
+ before_action :set_country
+ before_action :set_city, only: %i[show edit update destroy]
+
+ def show
+ @districts = pagy_by_search(@city.districts.order(:name))
+ end
+
+ def new
+ @city = @country.cities.new
+ end
+
+ def create
+ @city = @country.cities.new(city_params)
+ @city.save ? redirect_to([:admin, @country, @city], notice: t('.success')) : render(:new)
+ end
+
+ def edit; end
+
+ def update
+ @city.update(city_params) ? redirect_to([:admin, @country, @city], notice: t('.success')) : render(:edit)
+ end
+
+ def destroy
+ if @city.destroy
+ redirect_to([:admin, @country], notice: t('.success'))
+ else
+ redirect_to([:admin, @country], alert: t('.warning'))
+ end
+ end
+
+ private
+
+ def set_country
+ @country = Country.find(params[:country_id])
+ end
+
+ def set_city
+ @city = @country.cities.find(params[:id])
+ end
+
+ def city_params
+ params.require(:city).permit(:name, :alpha_2_code)
+ end
+ end
+end
diff --git a/app/controllers/admin/countries_controller.rb b/app/controllers/admin/countries_controller.rb
new file mode 100644
index 000000000..49fdc8fb2
--- /dev/null
+++ b/app/controllers/admin/countries_controller.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Admin
+ class CountriesController < ApplicationController
+ include PagyBackendWithHelpers
+
+ before_action :set_country, only: %i[show edit update destroy]
+
+ def index
+ @countries = pagy_by_search(Country.order(:name))
+ end
+
+ def show
+ @cities = pagy_by_search(@country.cities.order(:name))
+ end
+
+ def new
+ @country = Country.new
+ end
+
+ def create
+ @country = Country.new(country_params)
+ @country.save ? redirect_to([:admin, @country], notice: t('.success')) : render(:new)
+ end
+
+ def edit; end
+
+ def update
+ @country.update(country_params) ? redirect_to([:admin, @country], notice: t('.success')) : render(:edit)
+ end
+
+ def destroy
+ if @country.destroy
+ redirect_to(index_path, notice: t('.success'))
+ else
+ redirect_to(index_path, alert: t('.warning'))
+ end
+ end
+
+ private
+
+ def index_path
+ %i[admin countries]
+ end
+
+ def set_country
+ @country = Country.find(params[:id])
+ end
+
+ def country_params
+ params.require(:country).permit(:name, :alpha_2_code, :alpha_3_code, :numeric_code, :mernis_code, :yoksis_code)
+ end
+ end
+end
diff --git a/app/controllers/admin/districts_controller.rb b/app/controllers/admin/districts_controller.rb
new file mode 100644
index 000000000..6e8c37c45
--- /dev/null
+++ b/app/controllers/admin/districts_controller.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Admin
+ class DistrictsController < ApplicationController
+ before_action :set_city
+ before_action :set_district, only: %i[edit update destroy]
+
+ def new
+ @district = @city.districts.new
+ end
+
+ def create
+ @district = @city.districts.new(district_params)
+ @city.save ? redirect_to(index_path, notice: t('.success')) : render(:new)
+ end
+
+ def edit; end
+
+ def update
+ if @district.update(district_params)
+ redirect_to(index_path, notice: t('.success'))
+ else
+ render(:edit)
+ end
+ end
+
+ def destroy
+ if @district.destroy
+ redirect_to(index_path, notice: t('.success'))
+ else
+ redirect_to(index_path, alert: t('.warning'))
+ end
+ end
+
+ private
+
+ def index_path
+ [:admin, @city.country, @city]
+ end
+
+ def set_city
+ @city = City.find(params[:city_id])
+ end
+
+ def set_district
+ @district = @city.districts.find(params[:id])
+ end
+
+ def district_params
+ params.require(:district).permit(:name, :mernis_code, :active)
+ end
+ end
+end
diff --git a/app/controllers/admin/document_types_controller.rb b/app/controllers/admin/document_types_controller.rb
new file mode 100644
index 000000000..d47254d41
--- /dev/null
+++ b/app/controllers/admin/document_types_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Admin
+ class DocumentTypesController < ApplicationController
+ include ReferenceResource
+
+ private
+
+ def secure_params
+ params.require(:document_type).permit(:name, :active)
+ end
+ end
+end
diff --git a/app/controllers/admin/evaluation_types_controller.rb b/app/controllers/admin/evaluation_types_controller.rb
new file mode 100644
index 000000000..d307b8ccd
--- /dev/null
+++ b/app/controllers/admin/evaluation_types_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Admin
+ class EvaluationTypesController < ApplicationController
+ include ReferenceResource
+
+ private
+
+ def secure_params
+ params.require(:evaluation_type).permit(:name)
+ end
+ end
+end
diff --git a/app/controllers/yoksis_references/high_school_types_controller.rb b/app/controllers/admin/high_school_types_controller.rb
similarity index 90%
rename from app/controllers/yoksis_references/high_school_types_controller.rb
rename to app/controllers/admin/high_school_types_controller.rb
index fd936ef20..c96a5b08f 100644
--- a/app/controllers/yoksis_references/high_school_types_controller.rb
+++ b/app/controllers/admin/high_school_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class HighSchoolTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/admin/languages_controller.rb b/app/controllers/admin/languages_controller.rb
new file mode 100644
index 000000000..23c2c104d
--- /dev/null
+++ b/app/controllers/admin/languages_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Admin
+ class LanguagesController < ApplicationController
+ include ReferenceResource
+
+ private
+
+ def secure_params
+ params.require(:language).permit(:name, :iso)
+ end
+ end
+end
diff --git a/app/controllers/yoksis_references/student_disability_types_controller.rb b/app/controllers/admin/student_disability_types_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_disability_types_controller.rb
rename to app/controllers/admin/student_disability_types_controller.rb
index 146b33902..30c792981 100644
--- a/app/controllers/yoksis_references/student_disability_types_controller.rb
+++ b/app/controllers/admin/student_disability_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentDisabilityTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_drop_out_types_controller.rb b/app/controllers/admin/student_drop_out_types_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_drop_out_types_controller.rb
rename to app/controllers/admin/student_drop_out_types_controller.rb
index 6b2390569..21ab1be21 100644
--- a/app/controllers/yoksis_references/student_drop_out_types_controller.rb
+++ b/app/controllers/admin/student_drop_out_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentDropOutTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_education_levels_controller.rb b/app/controllers/admin/student_education_levels_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_education_levels_controller.rb
rename to app/controllers/admin/student_education_levels_controller.rb
index f7f78be20..e18b5bc59 100644
--- a/app/controllers/yoksis_references/student_education_levels_controller.rb
+++ b/app/controllers/admin/student_education_levels_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentEducationLevelsController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_entrance_point_types_controller.rb b/app/controllers/admin/student_entrance_point_types_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_entrance_point_types_controller.rb
rename to app/controllers/admin/student_entrance_point_types_controller.rb
index 1d14cda97..a211ecf9b 100644
--- a/app/controllers/yoksis_references/student_entrance_point_types_controller.rb
+++ b/app/controllers/admin/student_entrance_point_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentEntrancePointTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_entrance_types_controller.rb b/app/controllers/admin/student_entrance_types_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_entrance_types_controller.rb
rename to app/controllers/admin/student_entrance_types_controller.rb
index 6645f518d..a9995fce9 100644
--- a/app/controllers/yoksis_references/student_entrance_types_controller.rb
+++ b/app/controllers/admin/student_entrance_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentEntranceTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_grades_controller.rb b/app/controllers/admin/student_grades_controller.rb
similarity index 90%
rename from app/controllers/yoksis_references/student_grades_controller.rb
rename to app/controllers/admin/student_grades_controller.rb
index 9fa0c4f1a..39f6c0651 100644
--- a/app/controllers/yoksis_references/student_grades_controller.rb
+++ b/app/controllers/admin/student_grades_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentGradesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_grading_systems_controller.rb b/app/controllers/admin/student_grading_systems_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_grading_systems_controller.rb
rename to app/controllers/admin/student_grading_systems_controller.rb
index b4a470941..b49f21c2c 100644
--- a/app/controllers/yoksis_references/student_grading_systems_controller.rb
+++ b/app/controllers/admin/student_grading_systems_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentGradingSystemsController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_punishment_types_controller.rb b/app/controllers/admin/student_punishment_types_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_punishment_types_controller.rb
rename to app/controllers/admin/student_punishment_types_controller.rb
index 01e653b78..852e9812b 100644
--- a/app/controllers/yoksis_references/student_punishment_types_controller.rb
+++ b/app/controllers/admin/student_punishment_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentPunishmentTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/student_studentship_statuses_controller.rb b/app/controllers/admin/student_studentship_statuses_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/student_studentship_statuses_controller.rb
rename to app/controllers/admin/student_studentship_statuses_controller.rb
index 6e793025a..114932b64 100644
--- a/app/controllers/yoksis_references/student_studentship_statuses_controller.rb
+++ b/app/controllers/admin/student_studentship_statuses_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class StudentStudentshipStatusesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/admin/titles_controller.rb b/app/controllers/admin/titles_controller.rb
new file mode 100644
index 000000000..9ee2281da
--- /dev/null
+++ b/app/controllers/admin/titles_controller.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Admin
+ class TitlesController < ApplicationController
+ include ReferenceResource
+
+ private
+
+ def secure_params
+ params.require(:title).permit(:name, :code, :branch)
+ end
+ end
+end
diff --git a/app/controllers/yoksis_references/unit_instruction_languages_controller.rb b/app/controllers/admin/unit_instruction_languages_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/unit_instruction_languages_controller.rb
rename to app/controllers/admin/unit_instruction_languages_controller.rb
index 64ed53a2c..2bc2b9796 100644
--- a/app/controllers/yoksis_references/unit_instruction_languages_controller.rb
+++ b/app/controllers/admin/unit_instruction_languages_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class UnitInstructionLanguagesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/unit_instruction_types_controller.rb b/app/controllers/admin/unit_instruction_types_controller.rb
similarity index 91%
rename from app/controllers/yoksis_references/unit_instruction_types_controller.rb
rename to app/controllers/admin/unit_instruction_types_controller.rb
index 995162805..e6036083e 100644
--- a/app/controllers/yoksis_references/unit_instruction_types_controller.rb
+++ b/app/controllers/admin/unit_instruction_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class UnitInstructionTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/unit_statuses_controller.rb b/app/controllers/admin/unit_statuses_controller.rb
similarity index 90%
rename from app/controllers/yoksis_references/unit_statuses_controller.rb
rename to app/controllers/admin/unit_statuses_controller.rb
index 6aa8edfb9..4e13035a5 100644
--- a/app/controllers/yoksis_references/unit_statuses_controller.rb
+++ b/app/controllers/admin/unit_statuses_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class UnitStatusesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/unit_types_controller.rb b/app/controllers/admin/unit_types_controller.rb
similarity index 90%
rename from app/controllers/yoksis_references/unit_types_controller.rb
rename to app/controllers/admin/unit_types_controller.rb
index 93a9f1906..51bee44e8 100644
--- a/app/controllers/yoksis_references/unit_types_controller.rb
+++ b/app/controllers/admin/unit_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class UnitTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/yoksis_references/university_types_controller.rb b/app/controllers/admin/university_types_controller.rb
similarity index 90%
rename from app/controllers/yoksis_references/university_types_controller.rb
rename to app/controllers/admin/university_types_controller.rb
index 32b68a33b..98567534d 100644
--- a/app/controllers/yoksis_references/university_types_controller.rb
+++ b/app/controllers/admin/university_types_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module YoksisReferences
+module Admin
class UniversityTypesController < ApplicationController
include ReferenceResource
diff --git a/app/controllers/admin/yoksis_dashboard_controller.rb b/app/controllers/admin/yoksis_dashboard_controller.rb
new file mode 100644
index 000000000..3e79f5cda
--- /dev/null
+++ b/app/controllers/admin/yoksis_dashboard_controller.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Admin
+ class YoksisDashboardController < ApplicationController
+ def index; end
+ end
+end
diff --git a/app/controllers/calendar/academic_calendars_controller.rb b/app/controllers/calendar/academic_calendars_controller.rb
deleted file mode 100644
index 1333f3a00..000000000
--- a/app/controllers/calendar/academic_calendars_controller.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# frozen_string_literal: true
-
-module Calendar
- class AcademicCalendarsController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_academic_calendar, only: %i[show edit update destroy]
-
- def index
- @academic_calendars = pagy_by_search(
- AcademicCalendar.includes(:academic_term, :calendar_type).order(created_at: :desc)
- )
- end
-
- def show
- @events = pagy_by_search(@academic_calendar.calendar_events.order(:start_date).includes(:calendar_title))
- end
-
- def new
- @academic_calendar = AcademicCalendar.new
- end
-
- def edit; end
-
- def create
- @academic_calendar = AcademicCalendar.new(calendar_params)
- @academic_calendar.save ? redirect_with('success') : render(:new)
- end
-
- def update
- if @academic_calendar.update(calendar_params)
- redirect_to(@academic_calendar, notice: t('.success'))
- else
- render(:edit)
- end
- end
-
- def destroy
- @academic_calendar.destroy ? redirect_with('success') : redirect_with('warning')
- end
-
- private
-
- def redirect_with(message)
- redirect_to(academic_calendars_path, notice: t(".#{message}"))
- end
-
- def set_academic_calendar
- @academic_calendar = AcademicCalendar.find(params[:id])
- end
-
- def calendar_params
- params.require(:academic_calendar)
- .permit(
- :name, :year, :academic_term_id, :calendar_type_id,
- :senate_decision_date, :senate_decision_no, :description,
- calendar_events_attributes: %i[
- id calendar_type_id academic_term_id calendar_title_id start_date end_date _destroy
- ],
- unit_ids: []
- )
- end
- end
-end
diff --git a/app/controllers/calendar/calendar_titles_controller.rb b/app/controllers/calendar/calendar_titles_controller.rb
deleted file mode 100644
index b654f368b..000000000
--- a/app/controllers/calendar/calendar_titles_controller.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-module Calendar
- class CalendarTitlesController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_calendar_title, only: %i[edit update]
-
- def index
- @calendar_titles = pagy_by_search(CalendarTitle.includes(:types, :calendar_title_types))
- end
-
- def edit; end
-
- def update
- @calendar_title.update(calendar_title_params) ? redirect_with('success') : render(:edit)
- end
-
- private
-
- def redirect_with(message)
- redirect_to(calendar_titles_path, notice: t(".#{message}"))
- end
-
- def set_calendar_title
- @calendar_title = CalendarTitle.find(params[:id])
- end
-
- def calendar_title_params
- params.require(:calendar_title).permit(type_ids: [])
- end
- end
-end
diff --git a/app/controllers/calendar/calendar_types_controller.rb b/app/controllers/calendar/calendar_types_controller.rb
deleted file mode 100644
index a1dd8c565..000000000
--- a/app/controllers/calendar/calendar_types_controller.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: true
-
-module Calendar
- class CalendarTypesController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_calendar_type, only: %i[show edit update destroy]
-
- def index
- @calendar_types = pagy_by_search(CalendarType.all)
- end
-
- def show
- @titles = pagy_by_search(@calendar_type.titles)
- end
-
- def new
- @calendar_type = CalendarType.new
- end
-
- def edit; end
-
- def create
- @calendar_type = CalendarType.new(calendar_type_params)
- @calendar_type.save ? redirect_with('success') : render(:new)
- end
-
- def update
- @calendar_type.update(calendar_type_params) ? redirect_with('success') : render(:edit)
- end
-
- def destroy
- @calendar_type.destroy ? redirect_with('success') : redirect_with('warning')
- end
-
- private
-
- def redirect_with(message)
- redirect_to(calendar_types_path, notice: t(".#{message}"))
- end
-
- def set_calendar_type
- @calendar_type = CalendarType.find(params[:id])
- end
-
- def calendar_type_params
- params.require(:calendar_type).permit(:name, unit_type_ids: [])
- end
- end
-end
diff --git a/app/controllers/calendar_management/calendar_event_types_controller.rb b/app/controllers/calendar_management/calendar_event_types_controller.rb
new file mode 100644
index 000000000..199468ab3
--- /dev/null
+++ b/app/controllers/calendar_management/calendar_event_types_controller.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module CalendarManagement
+ class CalendarEventTypesController < ApplicationController
+ include PagyBackendWithHelpers
+
+ before_action :set_calendar_event_type, only: %i[edit update destroy]
+
+ def index
+ @calendar_event_types = pagy_by_search(CalendarEventType.order(:name))
+ end
+
+ def new
+ @calendar_event_type = CalendarEventType.new
+ end
+
+ def create
+ @calendar_event_type = CalendarEventType.new(calendar_event_type_params)
+ @calendar_event_type.save ? redirect_to(index_path, notice: t('.success')) : render(:new)
+ end
+
+ def edit; end
+
+ def update
+ if @calendar_event_type.update(calendar_event_type_params)
+ redirect_to(index_path, notice: t('.success'))
+ else
+ render(:edit)
+ end
+ end
+
+ def destroy
+ if @calendar_event_type.destroy
+ redirect_to(index_path, notice: t('.success'))
+ else
+ redirect_to(index_path, alert: t('.warning'))
+ end
+ end
+
+ private
+
+ def index_path
+ %i[calendar_management calendar_event_types]
+ end
+
+ def set_calendar_event_type
+ @calendar_event_type = CalendarEventType.find(params[:id])
+ end
+
+ def calendar_event_type_params
+ params.require(:calendar_event_type).permit(:name, :identifier, :category)
+ end
+ end
+end
diff --git a/app/controllers/calendar_management/calendars_controller.rb b/app/controllers/calendar_management/calendars_controller.rb
new file mode 100644
index 000000000..26b84b11f
--- /dev/null
+++ b/app/controllers/calendar_management/calendars_controller.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+module CalendarManagement
+ class CalendarsController < ApplicationController
+ include PagyBackendWithHelpers
+
+ before_action :set_calendar, only: %i[show edit update destroy]
+
+ def index
+ @calendars = pagy_by_search(Calendar.includes(:academic_term).order(created_at: :desc))
+ end
+
+ def show
+ respond_to do |format|
+ format.html
+ format.pdf do
+ render pdf: @calendar.name
+ end
+ end
+ end
+
+ def new
+ @calendar = Calendar.new
+ end
+
+ def create
+ @calendar = Calendar.new(calendar_params)
+ @calendar.save ? redirect_to(index_path, notice: t('.success')) : render(:new)
+ end
+
+ def edit; end
+
+ def update
+ @calendar.update(calendar_params) ? redirect_to(index_path, notice: t('.success')) : render(:edit)
+ end
+
+ def destroy
+ if @calendar.destroy
+ redirect_to(index_path, notice: t('.success'))
+ else
+ redirect_to(index_path, alert: t('.warning'))
+ end
+ end
+
+ def duplicate
+ @calendar = Calendar.find(params[:calendar_id])
+ @duplicate_record = DuplicateService.new(@calendar, 'name').duplicate
+
+ redirect_to(index_path, alert: t('.warning')) && return unless @duplicate_record
+
+ AcademicCalendars::DuplicateEventsService.new(@calendar, @duplicate_record)
+
+ redirect_to([:edit, :calendar_management, @duplicate_record], notice: t('.success'))
+ end
+
+ def units
+ @calendar = Calendar.find(params[:calendar_id])
+ end
+
+ private
+
+ def index_path
+ %i[calendar_management calendars]
+ end
+
+ def set_calendar
+ @calendar = Calendar.includes(calendar_events: [:calendar_event_type]).find(params[:id])
+ end
+
+ def calendar_params
+ params.require(:calendar)
+ .permit(
+ :name, :senate_decision_date, :senate_decision_no, :description, :timezone, :academic_term_id,
+ unit_ids: [], calendar_events_attributes: %i[
+ id calendar_event_type_id start_time end_time location timezone visible _destroy
+ ]
+ )
+ end
+ end
+end
diff --git a/app/controllers/committee/dashboard_controller.rb b/app/controllers/committee/dashboard_controller.rb
index 36d6c5621..34dcb6137 100644
--- a/app/controllers/committee/dashboard_controller.rb
+++ b/app/controllers/committee/dashboard_controller.rb
@@ -6,7 +6,7 @@ class DashboardController < ApplicationController
def index
@committees = pagy_by_search(
- Unit.committees.includes(:unit_type, :unit_status, district: :city)
+ Unit.includes(:unit_type, district: :city).committees.active.order(:name)
)
end
end
diff --git a/app/controllers/concerns/reference_resource.rb b/app/controllers/concerns/reference_resource.rb
index 96e8adf67..5a82a7ecb 100644
--- a/app/controllers/concerns/reference_resource.rb
+++ b/app/controllers/concerns/reference_resource.rb
@@ -49,7 +49,7 @@ def set_resource
end
def redirect_with(message)
- redirect_to(send("#{controller_name}_path"), notice: t(".#{message}"))
+ redirect_to(send("admin_#{controller_name}_path"), notice: t(".#{message}"))
end
end
# rubocop:enable Metrics/BlockLength
diff --git a/app/controllers/course_management/available_course_groups_controller.rb b/app/controllers/course_management/available_course_groups_controller.rb
new file mode 100644
index 000000000..0abace1bb
--- /dev/null
+++ b/app/controllers/course_management/available_course_groups_controller.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module CourseManagement
+ class AvailableCourseGroupsController < ApplicationController
+ before_action :set_available_course
+ before_action :set_lecturers
+ before_action :set_available_course_group, only: %i[edit update destroy]
+
+ def new
+ @available_course_group = @available_course.groups.new
+ end
+
+ def create
+ @available_course_group = @available_course.groups.new(available_course_group_params)
+ @available_course_group.save ? redirect_with('success') : render(:new)
+ end
+
+ def edit; end
+
+ def update
+ @available_course_group.update(available_course_group_params) ? redirect_with('success') : render(:edit)
+ end
+
+ def destroy
+ message = @available_course_group.destroy ? 'success' : 'error'
+ redirect_with(message)
+ end
+
+ private
+
+ def redirect_with(message)
+ redirect_to @available_course, flash: { info: t(".#{message}") }
+ end
+
+ def set_available_course
+ @available_course = AvailableCourse.find(params[:available_course_id])
+ end
+
+ def set_available_course_group
+ @available_course_group = @available_course.groups.find(params[:id])
+ end
+
+ def set_lecturers
+ @lecturers = @available_course.unit.subtree_employees
+ end
+
+ def available_course_group_params
+ params.require(:available_course_group).permit(
+ :quota, :name, lecturers_attributes: %i[id lecturer_id coordinator _destroy]
+ )
+ end
+ end
+end
diff --git a/app/controllers/course_management/available_courses_controller.rb b/app/controllers/course_management/available_courses_controller.rb
new file mode 100644
index 000000000..974a1251d
--- /dev/null
+++ b/app/controllers/course_management/available_courses_controller.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+module CourseManagement
+ class AvailableCoursesController < ApplicationController
+ include PagyBackendWithHelpers
+
+ before_action :set_available_course, only: %i[show edit update destroy]
+
+ def index
+ available_courses = AvailableCourse.includes(:unit, :curriculum, :course, :academic_term)
+ .order('units.name, curriculums.name')
+ .dynamic_search(search_params(AvailableCourse))
+
+ @pagy, @available_courses = pagy(available_courses)
+ end
+
+ def show
+ @groups = @available_course.groups.includes(lecturers: [lecturer: %i[title user]])
+ @evaluation_types =
+ @available_course.evaluation_types.includes(:evaluation_type, course_assessment_methods: :assessment_method)
+ end
+
+ def new
+ @available_course = AvailableCourse.new
+ end
+
+ def create
+ @available_course = AvailableCourse.new(available_course_params)
+ if @available_course.save
+ redirect_to new_available_course_available_course_group_path(@available_course)
+ else
+ render(:new)
+ end
+ end
+
+ def edit; end
+
+ def update
+ if @available_course.update(available_course_params)
+ redirect_to(@available_course, notice: t('.success'))
+ else
+ render(:edit)
+ end
+ end
+
+ def destroy
+ message = @available_course.destroy ? 'success' : 'error'
+ redirect_with(message)
+ end
+
+ private
+
+ def redirect_with(message)
+ redirect_to available_courses_path, flash: { info: t(".#{message}") }
+ end
+
+ def set_available_course
+ @available_course = AvailableCourse.find(params[:id])
+ end
+
+ def available_course_params
+ params.require(:available_course).permit(
+ :curriculum_id, :course_id, :unit_id, :coordinator_id
+ )
+ end
+ end
+end
diff --git a/app/controllers/course_management/course_evaluation_types_controller.rb b/app/controllers/course_management/course_evaluation_types_controller.rb
new file mode 100644
index 000000000..e8a1e6a4d
--- /dev/null
+++ b/app/controllers/course_management/course_evaluation_types_controller.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module CourseManagement
+ class CourseEvaluationTypesController < ApplicationController
+ before_action :set_available_course
+ before_action :set_course_evaluation_type, only: %i[edit update destroy]
+
+ def new
+ @evaluation_type = @available_course.evaluation_types.new
+ @evaluation_type.course_assessment_methods.build
+ end
+
+ def create
+ @evaluation_type = @available_course.evaluation_types.new(course_evaluation_type_params)
+ @evaluation_type.save ? redirect_with('success') : render(:new)
+ end
+
+ def edit; end
+
+ def update
+ @evaluation_type.update(course_evaluation_type_params) ? redirect_with('success') : render(:edit)
+ end
+
+ def destroy
+ message = @evaluation_type.destroy ? 'success' : 'error'
+ redirect_with(message)
+ end
+
+ private
+
+ def redirect_with(message)
+ redirect_to(available_course_path(@available_course), notice: t(".#{message}"))
+ end
+
+ def set_available_course
+ @available_course = AvailableCourse.find(params[:available_course_id])
+ end
+
+ def set_course_evaluation_type
+ @evaluation_type = @available_course.evaluation_types.find(params[:id])
+ end
+
+ def course_evaluation_type_params
+ params.require(:course_evaluation_type)
+ .permit(:evaluation_type_id, :percentage,
+ course_assessment_methods_attributes: %i[id assessment_method_id percentage _destroy])
+ end
+ end
+end
diff --git a/app/controllers/course_management/course_groups_controller.rb b/app/controllers/course_management/course_groups_controller.rb
index 5dd0dd4c4..0f8369ea8 100644
--- a/app/controllers/course_management/course_groups_controller.rb
+++ b/app/controllers/course_management/course_groups_controller.rb
@@ -2,12 +2,14 @@
module CourseManagement
class CourseGroupsController < ApplicationController
- include PagyBackendWithHelpers
+ include Pagy::Backend
before_action :set_course_group, only: %i[show edit update destroy]
def index
- @course_groups = pagy_by_search(CourseGroup.includes(:unit, :course_group_type))
+ course_groups = CourseGroup.includes(:unit, :course_group_type)
+ .dynamic_search(search_params(CourseGroup))
+ @pagy, @course_groups = pagy(course_groups)
end
def show
diff --git a/app/controllers/course_management/curriculum_course_groups_controller.rb b/app/controllers/course_management/curriculum_course_groups_controller.rb
index 0b634f29e..138b18a6b 100644
--- a/app/controllers/course_management/curriculum_course_groups_controller.rb
+++ b/app/controllers/course_management/curriculum_course_groups_controller.rb
@@ -6,12 +6,10 @@ class CurriculumCourseGroupsController < ApplicationController
before_action :set_curriculum_course_group, only: %i[edit update destroy]
def new
- @curriculum_course_group = @semester.curriculum_course_groups.new
+ @curriculum_course_groups = @semester.build_curriculum_course_groups
end
- def edit
- @curriculum_course_group.build_curriculum_courses
- end
+ def edit; end
def create
@curriculum_course_group = @semester.curriculum_course_groups.new(curriculum_course_params)
diff --git a/app/controllers/course_management/curriculums_controller.rb b/app/controllers/course_management/curriculums_controller.rb
index a07473b33..4553a6c94 100644
--- a/app/controllers/course_management/curriculums_controller.rb
+++ b/app/controllers/course_management/curriculums_controller.rb
@@ -3,7 +3,7 @@
module CourseManagement
class CurriculumsController < ApplicationController
include PagyBackendWithHelpers
- before_action :set_curriculum, only: %i[show edit update destroy]
+ before_action :set_curriculum, only: %i[show edit update destroy openable_courses]
def index
curriculums = Curriculum.includes(:unit)
@@ -44,6 +44,11 @@ def destroy
redirect_with(message)
end
+ def openable_courses
+ @curriculum = CurriculumDecorator.new(@curriculum)
+ render json: @curriculum.openable_courses_for_active_term
+ end
+
private
def redirect_with(message)
diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb
deleted file mode 100644
index fccc1351f..000000000
--- a/app/controllers/documents_controller.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-class DocumentsController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_document, only: %i[edit update destroy show]
-
- def index
- @pagy, @documents = pagy(Document.order(:name))
- end
-
- def show; end
-
- def new
- @document = Document.new
- end
-
- def create
- @document = Document.new(document_params)
- @document.save ? redirect_to(@document, notice: t('.success')) : render(:new)
- end
-
- def edit; end
-
- def update
- @document.update(document_params) ? redirect_to(@document, notice: t('.success')) : render(:edit)
- end
-
- def destroy
- if @document.destroy
- redirect_to(documents_path, notice: t('.success'))
- else
- redirect_to(documents_path, alert: t('.warning'))
- end
- end
-
- private
-
- def set_document
- @document = Document.find(params[:id])
- end
-
- def document_params
- params.require(:document).permit(
- :name, :statement
- )
- end
-end
diff --git a/app/controllers/first_registration/prospective_students_controller.rb b/app/controllers/first_registration/prospective_students_controller.rb
new file mode 100644
index 000000000..d6b3aa2d4
--- /dev/null
+++ b/app/controllers/first_registration/prospective_students_controller.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module FirstRegistration
+ class ProspectiveStudentsController < ApplicationController
+ include PagyBackendWithHelpers
+
+ before_action :set_prospective_student, only: %i[show register]
+ before_action :can_register?, only: :register
+
+ def index
+ prospective_students = ProspectiveStudent.includes(:unit, :student_entrance_type)
+ .dynamic_search(search_params(ProspectiveStudent))
+ @pagy, @prospective_students = pagy(prospective_students)
+ end
+
+ def show
+ @prospective_student = ProspectiveStudentDecorator.new(@prospective_student)
+ end
+
+ def register
+ prospective_student = FirstRegistration::ProspectiveStudentService.new(@prospective_student)
+
+ if prospective_student.register
+ @prospective_student.update(registered: true)
+ redirect_to(index_path, notice: t('.success'))
+ else
+ redirect_to(index_path, alert: t('.warning'))
+ end
+ end
+
+ private
+
+ def index_path
+ %i[first_registration prospective_students]
+ end
+
+ def set_prospective_student
+ @prospective_student = ProspectiveStudent.find(params[:id])
+ end
+
+ def can_register?
+ redirect_with_warning('.can_not_register') unless @prospective_student.can_temporarily_register?
+ end
+ end
+end
diff --git a/app/controllers/first_registration/registration_documents_controller.rb b/app/controllers/first_registration/registration_documents_controller.rb
new file mode 100644
index 000000000..2dd659032
--- /dev/null
+++ b/app/controllers/first_registration/registration_documents_controller.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module FirstRegistration
+ class RegistrationDocumentsController < ApplicationController
+ include PagyBackendWithHelpers
+
+ before_action :set_registration_document, only: %i[edit update destroy]
+
+ def index
+ @registration_documents = pagy_by_search(
+ RegistrationDocument.includes(
+ :academic_term, :document_type, :unit
+ ).order(created_at: :desc)
+ )
+ end
+
+ def new
+ @registration_document = RegistrationDocument.new
+ end
+
+ def create
+ @registration_document = RegistrationDocument.new(registration_document_params)
+ if @registration_document.save
+ redirect_to(index_path, notice: t('.success'))
+ else
+ render(:new)
+ end
+ end
+
+ def edit; end
+
+ def update
+ if @registration_document.update(registration_document_params)
+ redirect_to(index_path, notice: t('.success'))
+ else
+ render(:edit)
+ end
+ end
+
+ def destroy
+ if @registration_document.destroy
+ redirect_to(index_path, notice: t('.success'))
+ else
+ redirect_to(index_path, alert: t('.warning'))
+ end
+ end
+
+ private
+
+ def index_path
+ [:first_registration, 'registration_documents']
+ end
+
+ def set_registration_document
+ @registration_document = RegistrationDocument.find(params[:id])
+ end
+
+ def registration_document_params
+ params.require(:registration_document).permit(:unit_id, :academic_term_id, :document_type_id, :description)
+ end
+ end
+end
diff --git a/app/controllers/public_profile_controller.rb b/app/controllers/public_profile_controller.rb
index f651a8d46..356e9ecf7 100644
--- a/app/controllers/public_profile_controller.rb
+++ b/app/controllers/public_profile_controller.rb
@@ -15,7 +15,8 @@ def index
end
def vcard
- send_data VcardBuilder.new(@identity), type: 'text/vcard; charset=utf-8; header=present', filename: 'contact.vcf'
+ send_data VcardBuilderService.new(@identity).generate, type: 'text/vcard; charset=utf-8; header=present',
+ filename: 'contact.vcf'
end
private
diff --git a/app/controllers/calendar/academic_terms_controller.rb b/app/controllers/references/academic_terms_controller.rb
similarity index 98%
rename from app/controllers/calendar/academic_terms_controller.rb
rename to app/controllers/references/academic_terms_controller.rb
index d60ba55f6..be7325f1f 100644
--- a/app/controllers/calendar/academic_terms_controller.rb
+++ b/app/controllers/references/academic_terms_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module Calendar
+module References
class AcademicTermsController < ApplicationController
include PagyBackendWithHelpers
diff --git a/app/controllers/references/cities_controller.rb b/app/controllers/references/cities_controller.rb
deleted file mode 100644
index 27e688ef2..000000000
--- a/app/controllers/references/cities_controller.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module References
- class CitiesController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_country
- before_action :set_city, only: %i[show edit update destroy]
-
- def show
- @districts = pagy_by_search(@city.districts.order(:name))
- end
-
- def new
- @city = @country.cities.new
- end
-
- def create
- @city = @country.cities.new(city_params)
- @city.save ? redirect_to([@country, @city], notice: t('.success')) : render(:new)
- end
-
- def edit; end
-
- def update
- @city.update(city_params) ? redirect_to([@country, @city], notice: t('.success')) : render(:edit)
- end
-
- def destroy
- if @city.destroy
- redirect_to(@country, notice: t('.success'))
- else
- redirect_to(@country, alert: t('.warning'))
- end
- end
-
- private
-
- def set_country
- @country = Country.find(params[:country_id])
- end
-
- def set_city
- @city = @country.cities.find(params[:id])
- end
-
- def city_params
- params.require(:city).permit(:name, :alpha_2_code)
- end
- end
-end
diff --git a/app/controllers/references/countries_controller.rb b/app/controllers/references/countries_controller.rb
deleted file mode 100644
index e62c2a319..000000000
--- a/app/controllers/references/countries_controller.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: true
-
-module References
- class CountriesController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_country, only: %i[show edit update destroy]
-
- def index
- @countries = pagy_by_search(Country.order(:name))
- end
-
- def show
- @cities = pagy_by_search(@country.cities.order(:name))
- end
-
- def new
- @country = Country.new
- end
-
- def create
- @country = Country.new(country_params)
- @country.save ? redirect_to(@country, notice: t('.success')) : render(:new)
- end
-
- def edit; end
-
- def update
- @country.update(country_params) ? redirect_to(@country, notice: t('.success')) : render(:edit)
- end
-
- def destroy
- if @country.destroy
- redirect_to(countries_path, notice: t('.success'))
- else
- redirect_to(countries_path, alert: t('.warning'))
- end
- end
-
- private
-
- def set_country
- @country = Country.find(params[:id])
- end
-
- def country_params
- params.require(:country).permit(:name, :alpha_2_code, :alpha_3_code, :numeric_code, :mernis_code, :yoksis_code)
- end
- end
-end
diff --git a/app/controllers/references/districts_controller.rb b/app/controllers/references/districts_controller.rb
deleted file mode 100644
index 48076a4ea..000000000
--- a/app/controllers/references/districts_controller.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-module References
- class DistrictsController < ApplicationController
- before_action :set_city
- before_action :set_district, only: %i[edit update destroy]
-
- def new
- @district = @city.districts.new
- end
-
- def create
- @district = @city.districts.new(district_params)
- @city.save ? redirect_to([@city.country, @city], notice: t('.success')) : render(:new)
- end
-
- def edit; end
-
- def update
- @district.update(district_params) ? redirect_to([@city.country, @city], notice: t('.success')) : render(:edit)
- end
-
- def destroy
- if @district.destroy
- redirect_to([@city.country, @city], notice: t('.success'))
- else
- redirect_to([@city.country, @city], alert: t('.warning'))
- end
- end
-
- private
-
- def set_city
- @city = City.find(params[:city_id])
- end
-
- def set_district
- @district = @city.districts.find(params[:id])
- end
-
- def district_params
- params.require(:district).permit(:name, :mernis_code, :active)
- end
- end
-end
diff --git a/app/controllers/references/home_controller.rb b/app/controllers/references/home_controller.rb
deleted file mode 100644
index 695b629a0..000000000
--- a/app/controllers/references/home_controller.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-module References
- class HomeController < ApplicationController
- def index; end
- end
-end
diff --git a/app/controllers/references/languages_controller.rb b/app/controllers/references/languages_controller.rb
deleted file mode 100644
index 6dc30ed19..000000000
--- a/app/controllers/references/languages_controller.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-module References
- class LanguagesController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_language, only: %i[edit update destroy]
-
- def index
- @languages = pagy_by_search(Language.order(:name))
- end
-
- def new
- @language = Language.new
- end
-
- def create
- @language = Language.new(language_params)
- @language.save ? redirect_to(languages_path, notice: t('.success')) : render(:new)
- end
-
- def edit; end
-
- def update
- @language.update(language_params) ? redirect_to(languages_path, notice: t('.success')) : render(:edit)
- end
-
- def destroy
- if @language.destroy
- redirect_to(languages_path, notice: t('.success'))
- else
- redirect_to(languages_path, alert: t('.warning'))
- end
- end
-
- private
-
- def set_language
- @language = Language.find(params[:id])
- end
-
- def language_params
- params.require(:language).permit(:name, :iso)
- end
- end
-end
diff --git a/app/controllers/registration_documents_controller.rb b/app/controllers/registration_documents_controller.rb
deleted file mode 100644
index d26b33f26..000000000
--- a/app/controllers/registration_documents_controller.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-
-class RegistrationDocumentsController < ApplicationController
- before_action :set_unit
- before_action :set_registration_document, only: %i[show edit update destroy]
-
- def index
- @registration_documents = @unit.registration_documents.includes(:academic_term, :document).order(created_at: :desc)
- end
-
- def show; end
-
- def new
- @registration_document = @unit.registration_documents.new
- end
-
- def create
- @registration_document = @unit.registration_documents.new(document_params)
- @registration_document.save ? redirect_to(@unit, notice: t('.success')) : render(:new)
- end
-
- def edit; end
-
- def update
- @registration_document.update(document_params) ? redirect_to(@unit, notice: t('.success')) : render(:edit)
- end
-
- def destroy
- if @registration_document.destroy
- redirect_to(@unit, notice: t('.success'))
- else
- redirect_to(@unit, alert: t('.warning'))
- end
- end
-
- private
-
- def set_unit
- @unit = Unit.programs.find(params[:unit_id])
- end
-
- def set_registration_document
- @registration_document = @unit.registration_documents.find(params[:id])
- end
-
- def document_params
- params.require(:registration_document).permit(:unit_id, :academic_term_id, :document_id)
- end
-end
diff --git a/app/controllers/student_management/prospective_students_controller.rb b/app/controllers/student_management/prospective_students_controller.rb
deleted file mode 100644
index f6fc9330f..000000000
--- a/app/controllers/student_management/prospective_students_controller.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-module StudentManagement
- class ProspectiveStudentsController < ApplicationController
- include PagyBackendWithHelpers
-
- before_action :set_prospective_student, only: %i[show register]
- before_action :can_register?, only: :register
-
- def index
- prospective_students = ProspectiveStudent.includes(:unit, :student_entrance_type)
- .dynamic_search(search_params(ProspectiveStudent))
- @pagy, @prospective_students = pagy(prospective_students)
- end
-
- def show
- @prospective_student = ProspectiveStudentDecorator.new(@prospective_student)
- end
-
- def register
- prospective_student = ProspectiveStudentService.new(@prospective_student)
- user = prospective_student.create_user
-
- if user.save
- student = prospective_student.create_student
- student.save ? redirect_with_success : redirect_with_warning('.warning')
- else
- redirect_with_warning('.warning')
- end
-
- @prospective_student.update(registered: true)
- end
-
- private
-
- def set_prospective_student
- @prospective_student = ProspectiveStudent.find(params[:id])
- end
-
- def can_register?
- redirect_with_warning('.can_not_register') unless @prospective_student.can_temporarily_register?
- end
-
- def redirect_with_success
- redirect_to(prospective_students_path, flash: { notice: t('.success') })
- end
-
- def redirect_with_warning(message)
- redirect_to(prospective_students_path, flash: { alert: t(".#{message}") })
- end
- end
-end
diff --git a/app/controllers/units_controller.rb b/app/controllers/units_controller.rb
index 1ecc36389..cce3d70aa 100644
--- a/app/controllers/units_controller.rb
+++ b/app/controllers/units_controller.rb
@@ -2,11 +2,11 @@
class UnitsController < ApplicationController
include PagyBackendWithHelpers
- before_action :set_unit, only: %i[edit update destroy show courses programs]
+ before_action :set_unit, only: %i[edit update destroy show courses programs curriculums employees]
def index
units = Unit.includes(
- :unit_status, :unit_instruction_language, :unit_instruction_type, :unit_type, district: [:city]
+ :unit_status, :unit_instruction_type, :unit_type
).order(:name)
@pagy, @units = pagy(units.dynamic_search(search_params(Unit)))
@@ -46,6 +46,16 @@ def programs
render json: @units
end
+ def curriculums
+ @curriculums = @unit.managed_curriculums.active.order(:name)
+ render json: @curriculums
+ end
+
+ def employees
+ @employees = Employee.includes(:units, :title, user: :identities)
+ .where(units: { id: @unit.subtree.active.ids })
+ end
+
private
def set_unit
@@ -55,7 +65,8 @@ def set_unit
def unit_params
params.require(:unit).permit(
:name, :yoksis_id, :detsis_id, :foet_code, :founded_at, :duration, :district_id, :parent_id, :unit_status_id,
- :unit_instruction_language_id, :unit_instruction_type_id, :unit_type_id, :university_type_id
+ :unit_instruction_language_id, :unit_instruction_type_id, :unit_type_id, :university_type_id, :abbreviation,
+ :code
)
end
end
diff --git a/app/decorators/curriculum_decorator.rb b/app/decorators/curriculum_decorator.rb
new file mode 100644
index 000000000..840da3112
--- /dev/null
+++ b/app/decorators/curriculum_decorator.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class CurriculumDecorator < SimpleDelegator
+ def openable_courses_for_active_term(appends: nil)
+ term = AcademicTerm.active.last.try(:term)
+
+ return [] unless term
+
+ courses = semesters.where(term: term)
+ .includes(:courses)
+ .where.not(courses: { id: available_courses.pluck(:course_id) })
+ .order('courses.name')
+ .map(&:courses)
+ [*appends, courses].flatten
+ end
+end
diff --git a/app/decorators/curriculum_semester_decorator.rb b/app/decorators/curriculum_semester_decorator.rb
index 86118a44b..05cedc9b3 100644
--- a/app/decorators/curriculum_semester_decorator.rb
+++ b/app/decorators/curriculum_semester_decorator.rb
@@ -3,15 +3,22 @@
class CurriculumSemesterDecorator < SimpleDelegator
# TODO: Gelistirilecek
def available_courses(appends: [])
- courses = curriculum.unit.courses.active - curriculum.courses
+ courses = unit.courses.active - curriculum.courses - elective_courses
merge(courses, appends)
end
def available_course_groups(appends: [])
- course_groups = curriculum.unit.course_groups - curriculum.course_groups
+ course_groups = unit.course_groups - curriculum.course_groups
merge(course_groups, appends)
end
+ def build_curriculum_course_groups
+ available_course_groups.map do |course_group|
+ curriculum_course_groups.new(course_group_id: course_group.id)
+ .build_curriculum_courses
+ end
+ end
+
private
def merge(collection, appends)
@@ -19,4 +26,12 @@ def merge(collection, appends)
(collection + appends.compact).uniq
end
+
+ def unit
+ @unit ||= curriculum.unit
+ end
+
+ def elective_courses
+ unit.course_groups.includes(:courses).map(&:courses).flatten
+ end
end
diff --git a/app/decorators/prospective_student_decorator.rb b/app/decorators/prospective_student_decorator.rb
index c6af52d12..6ad8ef56d 100644
--- a/app/decorators/prospective_student_decorator.rb
+++ b/app/decorators/prospective_student_decorator.rb
@@ -1,14 +1,14 @@
# frozen_string_literal: true
class ProspectiveStudentDecorator < SimpleDelegator
- def academic_calendar
- @academic_calendar ||= unit.academic_calendars.find_by(
+ def calendar
+ @calendar ||= unit.calendars.find_by(
academic_term: academic_term
)
end
def academic_term
- @academic_term ||= AcademicTerm.active.first
+ @academic_term ||= AcademicTerm.active.last
end
def registration_documents
@@ -18,14 +18,32 @@ def registration_documents
end
def permanent_registrable?
- academic_calendar.try(:proper_event_range?, :application_permanent_registration)
+ check_events('permanent_registration_applications')
end
def temporary_registrable?
- academic_calendar.try(:proper_event_range?, :application_temporary_registration)
+ check_events('temporary_registration_applications')
end
def document_required?
registration_documents.present?
end
+
+ private
+
+ def event_type(identifier)
+ CalendarEventType.find_by(identifier: identifier)
+ end
+
+ def calendar_events
+ calendar&.calendar_events
+ end
+
+ def check_events(identifier)
+ return unless event_type(identifier) && calendar_events.present?
+
+ calendar_events.find_by(
+ calendar_event_type: event_type(identifier)
+ ).try(:active_now?)
+ end
end
diff --git a/app/helpers/apa_helper.rb b/app/helpers/apa_helper.rb
index 828130252..bc9e92299 100644
--- a/app/helpers/apa_helper.rb
+++ b/app/helpers/apa_helper.rb
@@ -2,7 +2,7 @@
module ApaHelper
def apa_citation(article)
- title = article.title.capitalize_all
+ title = article.title.capitalize_turkish
"#{authors_in_apa_format(article)}. (#{article.year}). #{title}. #{article.journal}, \
#{article.volume}(#{article.issue}), #{article.first_page}-#{article.last_page}"
@@ -11,7 +11,7 @@ def apa_citation(article)
def authors_in_apa_format(article)
article.authors.split(',').map do |author|
names = author.split
- last_name = names.shift.capitalize_all
+ last_name = names.shift.capitalize_turkish
first_name = names.map(&:first).join('. ')
"#{last_name}, #{first_name}"
end.join(' & ')
diff --git a/app/helpers/full_name_helper.rb b/app/helpers/full_name_helper.rb
index 33b787789..8ced4b311 100644
--- a/app/helpers/full_name_helper.rb
+++ b/app/helpers/full_name_helper.rb
@@ -3,12 +3,20 @@
module FullNameHelper
include I18nHelper
+ # rubocop:disable Metrics/AbcSize
def full_name(object)
case object.class.to_s
when 'AcademicTerm'
"#{object.year} / #{enum_t(object, :term)}"
when 'Identity'
"#{object.first_name} #{object.last_name}"
+ when 'Employee'
+ if object.identities.formal.present?
+ "#{object.title_name}
+ #{object.identities.formal.first.first_name}
+ #{object.identities.formal.first.last_name}"
+ end
end
end
+ # rubocop:enable Metrics/AbcSize
end
diff --git a/app/helpers/icon_helper.rb b/app/helpers/icon_helper.rb
new file mode 100644
index 000000000..b467d3bb6
--- /dev/null
+++ b/app/helpers/icon_helper.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module IconHelper
+ def icon_for_check(status)
+ if status
+ tag.span class: 'text-success' do
+ fa_icon('check-circle-o')
+ end
+ else
+ tag.span class: 'text-danger' do
+ fa_icon('times-circle-o')
+ end
+ end
+ end
+end
diff --git a/app/helpers/link_helper.rb b/app/helpers/link_helper.rb
index 85af1c2b8..6d63f8ce9 100644
--- a/app/helpers/link_helper.rb
+++ b/app/helpers/link_helper.rb
@@ -1,62 +1,79 @@
# frozen_string_literal: true
module LinkHelper
- def link_to_back(path = nil, text = t('action_group.back'))
- link_to(
- fa_icon('arrow-left', text: text),
- path,
- class: 'btn btn-secondary btn-sm'
- )
- end
-
- def link_to_destroy(path = nil, text = t('action_group.destroy'))
- link_to(
- fa_icon('trash', text: text),
- path,
- method: :delete,
- data: { confirm: t('are_you_sure') },
- class: 'btn btn-outline-danger btn-sm'
- )
- end
-
- def link_to_edit(path = nil, text = t('action_group.edit'))
- link_to(
- fa_icon('pencil', text: text),
- path,
- class: 'btn btn-outline-success btn-sm'
- )
- end
+ LINKS = {
+ back: {
+ icon: 'arrow-left',
+ text: I18n.t('action_group.back'),
+ options: {
+ class: 'btn btn-secondary btn-sm'
+ }
+ },
+ destroy: {
+ icon: 'trash',
+ text: I18n.t('action_group.destroy'),
+ options: {
+ class: 'btn btn-outline-danger btn-sm',
+ method: :delete,
+ data: { confirm: I18n.t('are_you_sure') }
+ }
+ },
+ edit: {
+ icon: 'pencil',
+ text: I18n.t('action_group.edit'),
+ options: {
+ class: 'btn btn-outline-success btn-sm'
+ }
+ },
+ new: {
+ icon: 'plus',
+ text: I18n.t('action_group.add'),
+ options: {
+ class: 'btn btn-outline-primary btn-sm',
+ id: 'add-button'
+ }
+ },
+ show: {
+ icon: 'eye',
+ text: I18n.t('action_group.show'),
+ options: {
+ class: 'btn btn-outline-info btn-sm'
+ }
+ },
+ update: {
+ icon: 'pencil-square-o',
+ text: I18n.t('action_group.update'),
+ options: {
+ class: 'btn btn-outline-info btn-sm'
+ }
+ },
+ file: {
+ icon: 'file-word-o',
+ text: I18n.t('action_group.file'),
+ options: {
+ class: 'btn btn-secondary btn-sm'
+ }
+ }
+ }.freeze
- def link_to_new(path = nil, text = t('action_group.add'))
- link_to(
- fa_icon('plus', text: text),
- path,
- class: 'btn btn-outline-primary btn-sm',
- id: 'add-button'
- )
+ LINKS.each do |action, configuration|
+ define_method("link_to_#{action}") do |*args|
+ link_builder(args, configuration)
+ end
end
- def link_to_show(path = nil, text = t('action_group.show'))
- link_to(
- fa_icon('eye', text: text),
- path,
- class: 'btn btn-outline-info btn-sm'
- )
- end
+ private
- def link_to_update(path = nil, text = t('action_group.update'))
+ def link_builder(args, configuration)
+ text, path = split_args_for_link_to(args)
link_to(
- fa_icon('pencil-square-o', text: text),
+ fa_icon(configuration[:icon], text: text || configuration[:text]),
path,
- class: 'btn btn-outline-info btn-sm'
+ configuration.fetch(:options, {})
)
end
- def link_to_file(path = nil, text = t('action_group.file'))
- link_to(
- fa_icon('file-word-o', text: text),
- path,
- class: 'btn btn-secondary btn-sm'
- )
+ def split_args_for_link_to(args)
+ args.length == 1 ? [nil, *args] : args
end
end
diff --git a/app/helpers/timezone_helper.rb b/app/helpers/timezone_helper.rb
new file mode 100644
index 000000000..029e9a382
--- /dev/null
+++ b/app/helpers/timezone_helper.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module TimezoneHelper
+ def timezone_list_with_offset
+ arr = []
+ ActiveSupport::TimeZone.all.each do |timezone|
+ arr << [timezone.name + " (#{timezone.formatted_offset})", timezone.name]
+ end
+ arr
+ end
+end
diff --git a/app/helpers/toastr_helper.rb b/app/helpers/toastr_helper.rb
index 3acfa65ed..226410fe4 100644
--- a/app/helpers/toastr_helper.rb
+++ b/app/helpers/toastr_helper.rb
@@ -2,6 +2,7 @@
module ToastrHelper
def toastr_flash_class(type)
+ # See https://github.com/plataformatec/devise/issues/1777 for type check in toastr partial
{
'alert' => 'toastr.error',
'notice' => 'toastr.success'
diff --git a/app/jobs/kps/identity_save_job.rb b/app/jobs/kps/identity_save_job.rb
index 053df9b2a..daeb695bf 100644
--- a/app/jobs/kps/identity_save_job.rb
+++ b/app/jobs/kps/identity_save_job.rb
@@ -6,16 +6,25 @@ class IdentitySaveJob < ApplicationJob
# slow operation
def perform(user, student_id = nil)
+ @user = user
@student_id = student_id
- @response = Xokul::Kps::Identity.new(user.id_number)
+ @response = Xokul::Kps::Identity.new(@user.id_number)
end
# callbacks
- after_perform do |job|
- model_data = @response.model_data.merge(student_id: @student_id, type: 'formal')
- user = job.arguments.first
- formal_identity = user.identities.user_identity
- formal_identity.present? ? formal_identity.update(model_data) : user.identities.create(model_data)
+ after_perform do
+ model_data = @response.model_data.merge!(type: 'formal')
+ user_identity = @user.identities.user_identity
+ student_identity = @user.identities.where(student_id: @student_id)
+
+ if @student_id.present?
+ model_data = model_data.merge(student_id: @student_id)
+ return if student_identity.present?
+
+ @user.identities.create(model_data)
+ else
+ user_identity.present? ? user_identity.update(model_data) : @user.identities.create(model_data)
+ end
end
end
end
diff --git a/app/jobs/osym/import_prospective_students_job.rb b/app/jobs/osym/import_prospective_students_job.rb
index 0e6c3128f..ad32eec4c 100644
--- a/app/jobs/osym/import_prospective_students_job.rb
+++ b/app/jobs/osym/import_prospective_students_job.rb
@@ -8,7 +8,7 @@ class ImportProspectiveStudentsJob < ApplicationJob
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/BlockLength
def perform(file_path)
- content = Sensitive.readlines(file_path)
+ content = Support::Sensitive.readlines(file_path)
progress_bar = ProgressBar.spawn('Prospective Students', content.count)
@@ -90,10 +90,11 @@ def find_nationality(turkish, kktc, foreign)
def find_placement_type(str)
'general' if str.eql?('Genel')
'additional_score' if str.eql?('Ek Puanli')
+ nil if str.nil?
end
def find_language(language)
- Language.find_by(name: language.capitalize_all) unless language.eql?('null')
+ Language.find_by(name: language.capitalize_turkish) unless language.eql?('null')
end
def find_obs_registered_program(program)
diff --git a/app/jobs/yoksis/certifications_create_job.rb b/app/jobs/yoksis/certifications_create_job.rb
index 7229a88fd..430a54414 100644
--- a/app/jobs/yoksis/certifications_create_job.rb
+++ b/app/jobs/yoksis/certifications_create_job.rb
@@ -18,7 +18,7 @@ def perform(user)
user.certifications.create(
type: certification[:type_id],
scope: certification[:scope_id],
- title: certification[:title_name].try(:capitalize_all),
+ title: certification[:title_name].try(:capitalize_turkish),
status: certification[:activity_id],
**certification.slice(
:yoksis_id, :name, :content, :location, :start_date, :end_date, :last_update,
diff --git a/app/lib/nokul/version.rb b/app/lib/nokul/version.rb
new file mode 100644
index 000000000..32a9688c2
--- /dev/null
+++ b/app/lib/nokul/version.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module Nokul
+ VERSION = '0.4.7'
+end
diff --git a/app/lib/support.rb b/app/lib/support.rb
new file mode 100644
index 000000000..70885c0db
--- /dev/null
+++ b/app/lib/support.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+require 'nokul-support'
+
+# Shortcut for convenience
+Support = Nokul::Support
diff --git a/app/lib/tenant.rb b/app/lib/tenant.rb
new file mode 100644
index 000000000..4be9fff5d
--- /dev/null
+++ b/app/lib/tenant.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+require 'nokul-tenant'
+
+# Shortcut for convenience
+Tenant = Nokul::Tenant
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index e66805729..74b647e2a 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base
- default from: Rails.application.config.tenant.email.default_from
+ default from: Tenant.configuration.email.default_from
layout 'mailer'
end
diff --git a/app/models/academic_calendar.rb b/app/models/academic_calendar.rb
deleted file mode 100644
index 290846c65..000000000
--- a/app/models/academic_calendar.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-class AcademicCalendar < ApplicationRecord
- # search
- include PgSearch
- pg_search_scope(
- :search,
- against: %i[name],
- using: { tsearch: { prefix: true } }
- )
-
- # relations
- belongs_to :academic_term
- belongs_to :calendar_type
- has_many :calendar_events, dependent: :destroy
- has_many :calendar_units, dependent: :destroy
- has_many :units, through: :calendar_units
- accepts_nested_attributes_for :calendar_events, allow_destroy: true
-
- # validations
- validates :name, presence: true
- validates :senate_decision_date, presence: true
- validates :senate_decision_no, presence: true
- validates :academic_term, uniqueness: { scope: :calendar_type }
- validates :units, presence: true, on: :update
-
- # delegates
- delegate :name, to: :calendar_type, prefix: :type
- delegate :active?, to: :academic_term
-
- # scopes
- scope :active, -> { joins(:academic_term).merge(AcademicTerm.where(active: true)) }
-
- def proper_event_range?(title)
- event = calendar_events.find_by(calendar_title: CalendarTitle.find_by(identifier: title))
- event.present? && event.proper_range?
- end
-end
diff --git a/app/models/academic_term.rb b/app/models/academic_term.rb
index e638bdac1..dc071378a 100644
--- a/app/models/academic_term.rb
+++ b/app/models/academic_term.rb
@@ -1,18 +1,21 @@
# frozen_string_literal: true
class AcademicTerm < ApplicationRecord
+ include EnumForTerm
+
+ # callbacks
+ after_save -> { AcademicTerm.where.not(id: id).update(active: false) }, if: :active?
+
# relations
- has_many :academic_calendars, dependent: :nullify
- has_many :calendar_events, through: :academic_calendars
+ has_many :calendars, dependent: :nullify
+ has_many :registration_documents, dependent: :nullify
# validations
- validates :term, presence: true
- validates :year, presence: true, uniqueness: { scope: :term }
+ validates :year, presence: true, uniqueness: { scope: :term }, length: { maximum: 255 }
validates :start_of_term, presence: true
validates :end_of_term, presence: true
-
- # enums
- enum term: { fall: 0, spring: 1, summer: 2 }
+ validates :active, inclusion: { in: [true, false] }
+ validates_with AcademicTermValidator
# scopes
scope :active, -> { where(active: true) }
diff --git a/app/models/address.rb b/app/models/address.rb
index b783a0d9a..e199a499a 100644
--- a/app/models/address.rb
+++ b/app/models/address.rb
@@ -3,21 +3,19 @@
class Address < ApplicationRecord
self.inheritance_column = nil
+ # enums
+ enum type: { formal: 1, informal: 2 }
+
# relations
belongs_to :user
belongs_to :district
# validations
- validates :type, presence: true, uniqueness: { scope: :user }
- validates :full_address, presence: true
+ validates :type, uniqueness: { scope: :user }, inclusion: { in: types.keys }
+ validates :phone_number, length: { maximum: 255 }
+ validates :full_address, presence: true, length: { maximum: 255 }
validates_with AddressAndIdentityValidator, on: :create
- # enums
- enum type: { formal: 1, informal: 2 }
-
- # delegations
- delegate :id_number, to: :user
-
# callbacks
- before_save { self.full_address = full_address.capitalize_all }
+ before_save { self.full_address = full_address.capitalize_turkish }
end
diff --git a/app/models/administrative_function.rb b/app/models/administrative_function.rb
index 6131d6f19..65fc1b0c4 100644
--- a/app/models/administrative_function.rb
+++ b/app/models/administrative_function.rb
@@ -7,8 +7,8 @@ class AdministrativeFunction < ApplicationRecord
# validations
validates :name, presence: true, uniqueness: true
- validates :code, presence: true, uniqueness: true, numericality: { only_integer: true }
+ validates :code, uniqueness: true, numericality: { only_integer: true, greater_than: 0 }
# callbacks
- before_save { self.name = name.capitalize_all }
+ before_validation { self.name = name.capitalize_turkish if name }
end
diff --git a/app/models/agenda.rb b/app/models/agenda.rb
index d0e7de2d9..ff68a9df7 100644
--- a/app/models/agenda.rb
+++ b/app/models/agenda.rb
@@ -14,6 +14,9 @@ class Agenda < ApplicationRecord
# dynamic_search
search_keys :status, :agenda_type_id
+ # enums
+ enum status: { recent: 0, decided: 1, delayed: 2 }
+
# relations
has_one_attached :agenda_file
belongs_to :unit
@@ -22,11 +25,8 @@ class Agenda < ApplicationRecord
has_many :meetings, through: :meeting_agendas, source: :committee_meeting
# validations
- validates :description, presence: true
- validates :status, presence: true
-
- # enums
- enum status: { recent: 0, decided: 1, delayed: 2 }
+ validates :description, presence: true, length: { maximum: 65_535 }
+ validates :status, inclusion: { in: statuses.keys }
# scopes
scope :active, -> { where(status: %i[recent delayed]) }
diff --git a/app/models/agenda_type.rb b/app/models/agenda_type.rb
index d41e289c5..1f5e5ac7e 100644
--- a/app/models/agenda_type.rb
+++ b/app/models/agenda_type.rb
@@ -9,8 +9,8 @@ class AgendaType < ApplicationRecord
has_many :agendas, dependent: :nullify
# validations
- validates :name, presence: true
+ validates :name, presence: true, length: { maximum: 255 }
# callbacks
- before_save { self.name = name.capitalize_all }
+ before_save { self.name = name.capitalize_turkish }
end
diff --git a/app/models/article.rb b/app/models/article.rb
index c2d963431..5c3723082 100644
--- a/app/models/article.rb
+++ b/app/models/article.rb
@@ -3,13 +3,6 @@
class Article < ApplicationRecord
self.inheritance_column = nil
- # relations
- belongs_to :user, counter_cache: true
-
- # validations
- validates :yoksis_id, presence: true, uniqueness: { scope: %i[user_id status] }
- validates :title, presence: true
-
# enums
enum scope: { national: 0, international: 1 }
enum review: { reviewed: 0, not_reviewed: 1 }
@@ -54,6 +47,45 @@ class Article < ApplicationRecord
short_article: 11
}
+ # relations
+ belongs_to :user, counter_cache: true
+
+ # validations
+ validates :yoksis_id, uniqueness: { scope: %i[user_id status] }, numericality: { only_integer: true, greater_than: 0 }
+ validates :title, presence: true, length: { maximum: 65_535 }
+ validates :authors, presence: true, length: { maximum: 65_535 }
+ validates :city, length: { maximum: 255 }
+ validates :journal, length: { maximum: 255 }
+ validates :language_of_publication, length: { maximum: 255 }
+ validates :volume, length: { maximum: 255 }
+ validates :issue, length: { maximum: 255 }
+ validates :doi, length: { maximum: 255 }
+ validates :issn, length: { maximum: 255 }
+ validates :access_link, length: { maximum: 65_535 }
+ validates :discipline, length: { maximum: 65_535 }
+ validates :keyword, length: { maximum: 255 }
+ validates :sponsored_by, length: { maximum: 255 }
+ validates :number_of_authors, allow_nil: true, numericality: { only_integer: true, greater_than: 0 }
+ validates :type, allow_nil: true, inclusion: { in: types.keys }
+ validates :scope, allow_nil: true, inclusion: { in: scopes.keys }
+ validates :status, allow_nil: true, inclusion: { in: statuses.keys }
+ validates :review, allow_nil: true, inclusion: { in: reviews.keys }
+ validates :index, allow_nil: true, inclusion: { in: indices.keys }
+ validates :country, allow_nil: true, numericality: { only_integer: true, greater_than: 0 }
+ validates :month, allow_nil: true,
+ numericality: { only_integer: true, greater_than: 0, less_than_or_equal_to: 12 }
+ validates :year, allow_nil: true,
+ numericality: { only_integer: true, greater_than_or_equal_to: 1950, less_than_or_equal_to: 2050 }
+ validates :first_page, allow_nil: true,
+ numericality: { only_integer: true, greater_than: 0, less_than_or_equal_to: 15_000 }
+ validates :last_page, allow_nil: true,
+ numericality: { only_integer: true, greater_than: 0, less_than_or_equal_to: 15_000 }
+ validates :access_type, allow_nil: true, inclusion: { in: access_types.keys }
+ validates :special_issue, allow_nil: true, numericality: { only_integer: true, greater_than: 0 }
+ validates :special_issue_name, length: { maximum: 255 }
+ validates :author_id, numericality: { only_integer: true, greater_than: 0 }
+ validates :incentive_point, numericality: { greater_than_or_equal_to: 0 }
+
def self.unique_count
active.group_by(&:yoksis_id).count
end
diff --git a/app/models/assessment_method.rb b/app/models/assessment_method.rb
new file mode 100644
index 000000000..36e40365c
--- /dev/null
+++ b/app/models/assessment_method.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AssessmentMethod < ApplicationRecord
+ # search
+ include ReferenceSearch
+ include ReferenceCallbacks
+
+ # relations
+ has_many :course_assessment_methods, dependent: :destroy
+ has_many :course_evaluation_types, through: :course_assessment_methods
+ has_many :available_courses, through: :course_evaluation_types
+
+ # validations
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+end
diff --git a/app/models/available_course.rb b/app/models/available_course.rb
index 5f0a30555..30ac2cd6c 100644
--- a/app/models/available_course.rb
+++ b/app/models/available_course.rb
@@ -1,12 +1,39 @@
# frozen_string_literal: true
class AvailableCourse < ApplicationRecord
+ # search
+ include DynamicSearch
+ include PgSearch
+
+ pg_search_scope(
+ :search,
+ associated_against: { course: %i[name code] },
+ using: { tsearch: { prefix: true } }
+ )
+
+ # dynamic_search
+ search_keys :unit_id, :curriculum_id, :academic_term_id
+
# relations
belongs_to :academic_term
belongs_to :curriculum
belongs_to :course
+ belongs_to :unit
+ belongs_to :coordinator, class_name: 'Employee'
has_many :groups, class_name: 'AvailableCourseGroup', dependent: :destroy
+ has_many :evaluation_types, class_name: 'CourseEvaluationType', dependent: :destroy
# validations
validates :course, uniqueness: { scope: %i[academic_term curriculum] }
+ validates :assessments_approved, inclusion: { in: [true, false] }
+
+ # callbacks
+ before_validation(on: :create) do
+ self.academic_term = AcademicTerm.active.last
+ end
+
+ # delegates
+ delegate :code, :name, :theoric, :practice, :laboratory, :credit, :program_type, to: :course
+ delegate :name, to: :curriculum, prefix: true
+ delegate :name, to: :unit, prefix: true
end
diff --git a/app/models/available_course_group.rb b/app/models/available_course_group.rb
index 3b851273d..3189c584c 100644
--- a/app/models/available_course_group.rb
+++ b/app/models/available_course_group.rb
@@ -2,11 +2,14 @@
class AvailableCourseGroup < ApplicationRecord
# relations
- belongs_to :available_course
+ belongs_to :available_course, counter_cache: :groups_count
has_many :lecturers, class_name: 'AvailableCourseLecturer', foreign_key: :group_id,
inverse_of: :group, dependent: :destroy
+ # nested models
+ accepts_nested_attributes_for :lecturers, reject_if: :all_blank, allow_destroy: true
+
# validations
- validates :name, presence: true, uniqueness: { scope: :available_course }
- validates :quota, numericality: { only_integer: true, greater_than_or_equal_to: 1 }, allow_blank: true
+ validates :name, presence: true, uniqueness: { scope: :available_course }, length: { maximum: 255 }
+ validates :quota, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 1 }
end
diff --git a/app/models/available_course_lecturer.rb b/app/models/available_course_lecturer.rb
index 400bde9f7..f497eb940 100644
--- a/app/models/available_course_lecturer.rb
+++ b/app/models/available_course_lecturer.rb
@@ -8,7 +8,10 @@ class AvailableCourseLecturer < ApplicationRecord
# validations
validates :coordinator, inclusion: { in: [true, false] }
validates :lecturer, uniqueness: { scope: :group }
+ validates_with AvailableCourseLecturerValidator
# scopes
scope :coordinator, -> { where(coordinator: true) }
+
+ delegate :title, :identities, to: :lecturer
end
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
new file mode 100644
index 000000000..c096b91b5
--- /dev/null
+++ b/app/models/calendar.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+class Calendar < ApplicationRecord
+ # search
+ include PgSearch
+ pg_search_scope(
+ :search,
+ against: %i[name],
+ using: { tsearch: { prefix: true } }
+ )
+
+ # relations
+ belongs_to :academic_term
+ has_many :calendar_events, dependent: :destroy
+ has_many :calendar_event_types, through: :calendar_events
+ has_many :unit_calendars, dependent: :destroy
+ has_many :units, through: :unit_calendars,
+ before_add: proc { |calendar, unit| create_sub_calendars(calendar, unit) },
+ before_remove: proc { |calendar, unit| destroy_sub_calendars(calendar, unit) }
+
+ accepts_nested_attributes_for :units, allow_destroy: true, reject_if: :all_blank
+ accepts_nested_attributes_for :calendar_events, allow_destroy: true, reject_if: :all_blank
+
+ # validations
+ validates :name, presence: true,
+ uniqueness: { scope: %i[senate_decision_no academic_term_id] },
+ length: { maximum: 255 }
+ validates :timezone, presence: true, length: { maximum: 255 }
+ validates :senate_decision_date, presence: true, length: { maximum: 255 }
+ validates :senate_decision_no, presence: true, length: { maximum: 255 }
+ validates :description, length: { maximum: 65_535 }
+
+ # delegations
+ delegate :active?, to: :academic_term
+
+ # scopes
+ scope :active, -> { joins(:academic_term).merge(AcademicTerm.where(active: true)) }
+
+ # relational callbacks
+ class << self
+ def create_sub_calendars(calendar, unit)
+ unit.descendants.active.eventable.each do |descendant|
+ UnitCalendar.create(calendar: calendar, unit: descendant)
+ end
+ end
+
+ def destroy_sub_calendars(calendar, unit)
+ UnitCalendar.where(calendar_id: calendar.id, unit_id: unit.descendants.ids).destroy_all
+ end
+ end
+end
diff --git a/app/models/calendar_event.rb b/app/models/calendar_event.rb
index 1d14f8437..5c98f0c91 100644
--- a/app/models/calendar_event.rb
+++ b/app/models/calendar_event.rb
@@ -2,32 +2,20 @@
class CalendarEvent < ApplicationRecord
# relations
- belongs_to :academic_calendar
- belongs_to :calendar_title
- belongs_to :calendar_type, optional: true
- belongs_to :academic_term, optional: true
+ belongs_to :calendar
+ belongs_to :calendar_event_type
# validations
- validates :start_date, presence: true
- validates :end_date, presence: true
- validates :academic_calendar, uniqueness: { scope: :calendar_title }
+ validates :timezone, presence: true, length: { maximum: 255 }
+ validates :start_time, presence: true
+ validates :calendar, uniqueness: { scope: %i[calendar_event_type] }
+ validates :visible, inclusion: { in: [true, false] }
validates_with CalendarEventValidator
- # callbacks
- after_create :set_calendar_type_and_term
+ # delegations
+ delegate :name, to: :calendar_event_type, prefix: :type
- # delegates
- delegate :name, to: :calendar_title, prefix: :calendar_title
-
- # scopes
- scope :active, -> { where(academic_term: AcademicTerm.active) }
-
- def set_calendar_type_and_term
- update(calendar_type_id: academic_calendar.calendar_type.id,
- academic_term_id: academic_calendar.academic_term.id)
- end
-
- def proper_range?
- Time.current.between?(start_date, end_date)
+ def active_now?
+ end_time ? Time.current.between?(start_time, end_time) : start_time.past?
end
end
diff --git a/app/models/calendar_event_type.rb b/app/models/calendar_event_type.rb
new file mode 100644
index 000000000..a762c9cb0
--- /dev/null
+++ b/app/models/calendar_event_type.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class CalendarEventType < ApplicationRecord
+ # search
+ include PgSearch
+ pg_search_scope(
+ :search,
+ against: %i[name identifier],
+ using: { tsearch: { prefix: true } }
+ )
+
+ # enums
+ enum category: {
+ applications: 1,
+ payments: 2,
+ registrations: 3,
+ advisor: 4,
+ exams: 5,
+ courses: 6,
+ submission: 7,
+ announcement: 8
+ }
+
+ # relations
+ has_many :calendar_events, dependent: :destroy
+ has_many :calendars, through: :calendar_events
+
+ # validations
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :identifier, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :category, inclusion: { in: categories.keys }
+end
diff --git a/app/models/calendar_title.rb b/app/models/calendar_title.rb
deleted file mode 100644
index 73d2cf2b1..000000000
--- a/app/models/calendar_title.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class CalendarTitle < ApplicationRecord
- # search
- include PgSearch
- pg_search_scope(
- :search,
- against: %i[name],
- using: { tsearch: { prefix: true } }
- )
-
- # relations
- has_many :calendar_title_types, foreign_key: :title_id, inverse_of: :title, dependent: :destroy
- has_many :types, through: :calendar_title_types
- has_many :calendar_events, dependent: :destroy
-
- # validations
- validates :name, presence: true, uniqueness: true
- validates :identifier, presence: true, uniqueness: true
-end
diff --git a/app/models/calendar_title_type.rb b/app/models/calendar_title_type.rb
deleted file mode 100644
index 3b1f49759..000000000
--- a/app/models/calendar_title_type.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-class CalendarTitleType < ApplicationRecord
- # relations
- belongs_to :type, class_name: 'CalendarType'
- belongs_to :title, class_name: 'CalendarTitle'
-
- # validations
- validates :type, uniqueness: { scope: :title }
-
- # enums
- enum status: { passive: 0, active: 1 }
-end
diff --git a/app/models/calendar_type.rb b/app/models/calendar_type.rb
deleted file mode 100644
index 981814d98..000000000
--- a/app/models/calendar_type.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-class CalendarType < ApplicationRecord
- # relations
- has_many :calendar_title_types, foreign_key: :type_id, inverse_of: :type, dependent: :destroy
- has_many :titles, through: :calendar_title_types
- has_many :academic_calendars, dependent: :destroy
- has_many :calendar_unit_types, dependent: :destroy
- has_many :unit_types, through: :calendar_unit_types
- has_many :calendar_events, through: :academic_calendars
-
- # validations
- validates :name, presence: true, uniqueness: true
-end
diff --git a/app/models/calendar_unit.rb b/app/models/calendar_unit.rb
deleted file mode 100644
index f75323015..000000000
--- a/app/models/calendar_unit.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-class CalendarUnit < ApplicationRecord
- # relations
- belongs_to :academic_calendar
- belongs_to :unit
-
- # validations
- validates :unit, uniqueness: { scope: :academic_calendar }
-end
diff --git a/app/models/calendar_unit_type.rb b/app/models/calendar_unit_type.rb
deleted file mode 100644
index a74e0451c..000000000
--- a/app/models/calendar_unit_type.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-class CalendarUnitType < ApplicationRecord
- # relations
- belongs_to :calendar_type
- belongs_to :unit_type
-
- # validations
- validates :unit_type, uniqueness: { scope: :calendar_type }
-end
diff --git a/app/models/certification.rb b/app/models/certification.rb
index 262375786..9f196202e 100644
--- a/app/models/certification.rb
+++ b/app/models/certification.rb
@@ -3,14 +3,6 @@
class Certification < ApplicationRecord
self.inheritance_column = nil
- # relations
- belongs_to :user
-
- # validations
- validates :yoksis_id, presence: true, uniqueness: { scope: %i[user_id status] }
- validates :title, presence: true
- validates :type, presence: true
-
# enums
enum type: {
certification: 1,
@@ -28,4 +20,21 @@ class Certification < ApplicationRecord
enum scope: { national: 0, international: 1 }
enum status: { active: 1, passive: 2 }
+
+ # relations
+ belongs_to :user
+
+ # validations
+ validates :yoksis_id, uniqueness: { scope: %i[user_id status] },
+ numericality: { only_integer: true, greater_than: 0 }
+ validates :title, presence: true, length: { maximum: 255 }
+ validates :type, inclusion: { in: types.keys }
+ validates :name, length: { maximum: 255 }
+ validates :content, length: { maximum: 65_535 }
+ validates :location, length: { maximum: 255 }
+ validates :scope, allow_nil: true, inclusion: { in: scopes.keys }
+ validates :duration, length: { maximum: 255 }
+ validates :number_of_authors, allow_nil: true, numericality: { only_integer: true, greater_than: 0 }
+ validates :city_and_country, length: { maximum: 255 }
+ validates :status, allow_nil: true, inclusion: { in: statuses.keys }
end
diff --git a/app/models/city.rb b/app/models/city.rb
index fafa35d20..2491ae9e9 100644
--- a/app/models/city.rb
+++ b/app/models/city.rb
@@ -18,12 +18,12 @@ class City < ApplicationRecord
has_many :units, through: :districts
# validations
- validates :name, presence: true, uniqueness: { scope: %i[country_id] }
- validates :alpha_2_code, presence: true, uniqueness: true
+ validates :name, presence: true, uniqueness: { scope: %i[country_id] }, length: { maximum: 255 }
+ validates :alpha_2_code, presence: true, uniqueness: true, length: { maximum: 255 }
# callbacks
- before_save do
- self.name = name.capitalize_all
- self.alpha_2_code = alpha_2_code.upcase_tr
+ before_validation do
+ self.name = name.capitalize_turkish if name
+ self.alpha_2_code = alpha_2_code.upcase(:turkic) if alpha_2_code
end
end
diff --git a/app/models/committee_decision.rb b/app/models/committee_decision.rb
index 750ea85aa..970341f1e 100644
--- a/app/models/committee_decision.rb
+++ b/app/models/committee_decision.rb
@@ -6,9 +6,13 @@ class CommitteeDecision < ApplicationRecord
has_one :agenda, through: :meeting_agenda
# validations
- validates :description, presence: true
- validates :decision_no, presence: true, uniqueness: true
- validates :year, presence: true
+ validates :description, presence: true, length: { maximum: 65_535 }
+ validates :decision_no, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :year, numericality: {
+ only_inter: true,
+ greater_than_or_equal_to: 1950,
+ less_than_or_equal_to: 2050
+ }
# callbacks
before_validation :set_year_and_decision_no, on: :create
diff --git a/app/models/committee_meeting.rb b/app/models/committee_meeting.rb
index 17aa56ca5..5c3c56b54 100644
--- a/app/models/committee_meeting.rb
+++ b/app/models/committee_meeting.rb
@@ -9,10 +9,14 @@ class CommitteeMeeting < ApplicationRecord
accepts_nested_attributes_for :meeting_agendas, allow_destroy: true
# validations
- validates :meeting_no, presence: true, uniqueness: { scope: %i[unit year] },
+ validates :meeting_no, uniqueness: { scope: %i[unit year] },
numericality: { only_integer: true, greater_than_or_equal_to: 1 }
validates :meeting_date, presence: true
- validates :year, presence: true
+ validates :year, numericality: {
+ only_integer: true,
+ greater_than_or_equal_to: 1950,
+ less_than_or_equal_to: 2050
+ }
# callbacks
before_validation { self.year = meeting_date.try(:year) }
diff --git a/app/models/concerns/enum_for_term.rb b/app/models/concerns/enum_for_term.rb
new file mode 100644
index 000000000..a025ab31e
--- /dev/null
+++ b/app/models/concerns/enum_for_term.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module EnumForTerm
+ extend ActiveSupport::Concern
+
+ included do
+ # enum
+ enum term: {
+ fall: 0,
+ spring: 1,
+ summer: 2
+ }
+
+ # validation
+ validates :term, inclusion: { in: terms.keys }
+ end
+end
diff --git a/app/models/concerns/reference_callbacks.rb b/app/models/concerns/reference_callbacks.rb
index 61de43a80..8ad84bed0 100644
--- a/app/models/concerns/reference_callbacks.rb
+++ b/app/models/concerns/reference_callbacks.rb
@@ -4,6 +4,6 @@ module ReferenceCallbacks
extend ActiveSupport::Concern
included do
- before_save { self.name = name.capitalize_all }
+ before_validation { self.name = name.capitalize_turkish if name }
end
end
diff --git a/app/models/concerns/reference_search.rb b/app/models/concerns/reference_search.rb
new file mode 100644
index 000000000..ebeb66ad5
--- /dev/null
+++ b/app/models/concerns/reference_search.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module ReferenceSearch
+ extend ActiveSupport::Concern
+ include PgSearch
+
+ included do
+ # search
+ pg_search_scope(
+ :search,
+ against: %i[name],
+ using: { tsearch: { prefix: true } }
+ )
+ end
+end
diff --git a/app/models/concerns/reference_validations.rb b/app/models/concerns/reference_validations.rb
index 961517a9e..5feab986a 100644
--- a/app/models/concerns/reference_validations.rb
+++ b/app/models/concerns/reference_validations.rb
@@ -4,7 +4,7 @@ module ReferenceValidations
extend ActiveSupport::Concern
included do
- validates :name, presence: true, uniqueness: true
- validates :code, presence: true, uniqueness: true, numericality: { only_integer: true }
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :code, uniqueness: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
end
end
diff --git a/app/models/country.rb b/app/models/country.rb
index 40681a0c4..bfb8fe6b1 100644
--- a/app/models/country.rb
+++ b/app/models/country.rb
@@ -19,19 +19,19 @@ class Country < ApplicationRecord
has_many :units, through: :districts
# validations
- validates :name, presence: true, uniqueness: true
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
validates :alpha_2_code, presence: true, uniqueness: true, length: { is: 2 }
validates :alpha_3_code, presence: true, uniqueness: true, length: { is: 3 }
- validates :numeric_code, presence: true, uniqueness: true, numericality: { only_integer: true },
- length: { maximum: 3 }
- validates :mernis_code, uniqueness: true, numericality: { only_integer: true }, allow_blank: true,
- length: { maximum: 4 }
- validates :yoksis_code, uniqueness: true, allow_blank: true
+ validates :numeric_code, presence: true, uniqueness: true, length: { is: 3 },
+ numericality: { only_integer: true, greater_than: 0 }
+ validates :mernis_code, allow_nil: true, uniqueness: true, length: { is: 4 },
+ numericality: { only_integer: true, greater_than: 0 }
+ validates :yoksis_code, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 1 }
# callbacks
- before_save do
- self.name = name.capitalize_all
- self.alpha_2_code = alpha_2_code.upcase_tr
- self.alpha_3_code = alpha_3_code.upcase_tr
+ before_validation do
+ self.name = name.capitalize_turkish if name
+ self.alpha_2_code = alpha_2_code.upcase(:turkic) if alpha_2_code
+ self.alpha_3_code = alpha_3_code.upcase(:turkic) if alpha_3_code
end
end
diff --git a/app/models/course.rb b/app/models/course.rb
index 509474a89..8130a5bbf 100644
--- a/app/models/course.rb
+++ b/app/models/course.rb
@@ -14,33 +14,31 @@ class Course < ApplicationRecord
# dynamic_search
search_keys :course_type_id, :program_type, :language_id, :unit_id, :status
+ # enumerations
+ enum program_type: { associate: 0, undergraduate: 1, master: 2, doctoral: 3 }
+ enum status: { passive: 0, active: 1 }
+
# relations
belongs_to :course_type
belongs_to :unit
belongs_to :language
# validations
- validates :code, presence: true, uniqueness: true
- validates :credit, presence: true, numericality: {
- greater_than_or_equal_to: ->(course) { course.course_type.try(:min_credit).to_i }
- }
- validates :program_type, presence: true
- validates :laboratory, presence: true, numericality: { greater_than_or_equal_to: 0 }
- validates :name, presence: true, uniqueness: { scope: :unit_id }
- validates :practice, presence: true, numericality: { greater_than_or_equal_to: 0 }
- validates :status, presence: true
- validates :theoric, presence: true, numericality: { greater_than_or_equal_to: 0 }
+ validates :name, presence: true, uniqueness: { scope: :unit_id }, length: { maximum: 255 }
+ validates :code, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :theoric, numericality: { greater_than_or_equal_to: 0 }
+ validates :practice, numericality: { greater_than_or_equal_to: 0 }
+ validates :laboratory, numericality: { greater_than_or_equal_to: 0 }
+ validates :credit, numericality: { greater_than_or_equal_to: ->(course) { course.course_type.try(:min_credit).to_i } }
+ validates :program_type, inclusion: { in: program_types.keys }
+ validates :status, inclusion: { in: statuses.keys }
# callbacks
before_validation do
- self.name = name.capitalize_all if name
+ self.name = name.capitalize_turkish if name
self.credit = calculate_credit
end
- # enumerations
- enum program_type: { associate: 0, undergraduate: 1, master: 2, doctoral: 3 }
- enum status: { passive: 0, active: 1 }
-
def calculate_credit
theoric.to_f + ((practice.to_f + laboratory.to_f) / 2)
end
diff --git a/app/models/course_assessment_method.rb b/app/models/course_assessment_method.rb
new file mode 100644
index 000000000..b06324acd
--- /dev/null
+++ b/app/models/course_assessment_method.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CourseAssessmentMethod < ApplicationRecord
+ # relations
+ belongs_to :course_evaluation_type
+ belongs_to :assessment_method
+
+ # validations
+ validates :percentage, numericality: {
+ only_integer: true,
+ greater_than_or_equal_to: 0,
+ less_than_or_equal_to: 100
+ }
+ validates :assessment_method, uniqueness: { scope: :course_evaluation_type }
+
+ # delegates
+ delegate :name, to: :assessment_method
+end
diff --git a/app/models/course_evaluation_type.rb b/app/models/course_evaluation_type.rb
new file mode 100644
index 000000000..72912dceb
--- /dev/null
+++ b/app/models/course_evaluation_type.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class CourseEvaluationType < ApplicationRecord
+ # relations
+ belongs_to :available_course
+ belongs_to :evaluation_type
+ has_many :course_assessment_methods, dependent: :destroy
+ has_many :assessment_methods, through: :course_assessment_methods
+ accepts_nested_attributes_for :course_assessment_methods, allow_destroy: true, reject_if: :all_blank
+
+ # validations
+ validates :percentage, numericality: {
+ only_integer: true,
+ greater_than_or_equal_to: 0,
+ less_than_or_equal_to: 100
+ }
+
+ validates :evaluation_type, uniqueness: { scope: :available_course }
+ validates_with CourseEvaluationTypeValidator
+
+ # delegate
+ delegate :name, to: :evaluation_type
+end
diff --git a/app/models/course_group.rb b/app/models/course_group.rb
index 622e35d82..0782fd1d8 100644
--- a/app/models/course_group.rb
+++ b/app/models/course_group.rb
@@ -2,14 +2,18 @@
class CourseGroup < ApplicationRecord
# search
+ include DynamicSearch
include PgSearch
+
pg_search_scope(
:search,
- against: %i[name unit_id course_group_type_id],
- associated_against: { unit: :name, course_group_type: :name },
+ against: %i[name],
using: { tsearch: { prefix: true } }
)
+ # dynamic_search
+ search_keys :unit_id, :course_group_type_id
+
# relations
belongs_to :unit
belongs_to :course_group_type
@@ -18,10 +22,14 @@ class CourseGroup < ApplicationRecord
has_many :curriculum_course_groups, dependent: :destroy
# validations
- validates :name, presence: true
- validates :total_ects_condition, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :name, presence: true, uniqueness: { scope: :unit_id }, length: { maximum: 255 }
+ validates :total_ects_condition, numericality: {
+ only_integer: true,
+ greater_than_or_equal_to: 0,
+ less_than_or_equal_to: 300
+ }
validates :course_ids, presence: true
# callbacks
- before_save { self.name = name.capitalize_all }
+ before_validation { self.name = name.capitalize_turkish if name }
end
diff --git a/app/models/course_group_type.rb b/app/models/course_group_type.rb
index a03e97de1..56e5a85ac 100644
--- a/app/models/course_group_type.rb
+++ b/app/models/course_group_type.rb
@@ -9,8 +9,8 @@ class CourseGroupType < ApplicationRecord
has_many :course_groups, dependent: :nullify
# validations
- validates :name, presence: true
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
# callbacks
- before_save { self.name = name.capitalize_all }
+ before_validation { self.name = name.capitalize_turkish if name }
end
diff --git a/app/models/course_type.rb b/app/models/course_type.rb
index c93fb262e..4305d23e1 100644
--- a/app/models/course_type.rb
+++ b/app/models/course_type.rb
@@ -13,7 +13,7 @@ class CourseType < ApplicationRecord
has_many :courses, dependent: :nullify
# validations
- validates :name, presence: true, uniqueness: true
- validates :code, presence: true, uniqueness: true
- validates :min_credit, presence: true, numericality: { greater_than_or_equal_to: 0 }
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :code, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :min_credit, numericality: { greater_than_or_equal_to: 0 }
end
diff --git a/app/models/curriculum.rb b/app/models/curriculum.rb
index cb5e0e6b6..bce0682a9 100644
--- a/app/models/curriculum.rb
+++ b/app/models/curriculum.rb
@@ -20,6 +20,9 @@ class Curriculum < ApplicationRecord
# dynamic_search
search_keys :unit_id, :status
+ # enumerations
+ enum status: { passive: 0, active: 1 }
+
# relations
belongs_to :unit
has_many :curriculum_programs, dependent: :destroy
@@ -37,18 +40,19 @@ class Curriculum < ApplicationRecord
accepts_nested_attributes_for :semesters, reject_if: :all_blank, allow_destroy: true
# validations
- validates :name, presence: true, uniqueness: { scope: :unit_id }
+ validates :name, presence: true, uniqueness: { scope: :unit_id }, length: { maximum: 255 }
+ validates :programs, presence: true
validates :semesters_count, numericality: { greater_than_or_equal_to: 0 }
- validates :status, presence: true
-
- # enumerations
- enum status: { passive: 0, active: 1 }
+ validates :status, inclusion: { in: statuses.keys }
# custom methods
def build_semesters(number_of_semesters: 0, type: :periodic)
divisor = (type.to_sym == :periodic ? 2 : 1)
+ terms = %i[spring fall]
(1..number_of_semesters.to_i).each do |sequence|
- semesters.build(sequence: sequence, year: (sequence.to_f / divisor).round)
+ semesters.build(sequence: sequence,
+ year: (sequence.to_f / divisor).round,
+ term: terms[sequence % 2])
end
end
end
diff --git a/app/models/curriculum_course.rb b/app/models/curriculum_course.rb
index 0c0cf1418..e2f591b25 100644
--- a/app/models/curriculum_course.rb
+++ b/app/models/curriculum_course.rb
@@ -2,22 +2,25 @@
class CurriculumCourse < ApplicationRecord
self.inheritance_column = :_type_disabled
+
+ # enums
+ enum type: { compulsory: 0, elective: 1 }
+
# relations
belongs_to :course
belongs_to :curriculum_semester
belongs_to :curriculum_course_group, optional: true
# validations
- validates :ects, presence: true, numericality: { greater_than: 0 }
+ validates :ects, numericality: { greater_than: 0 }
+ validates :type, inclusion: { in: types.keys }
+ validates_with CurriculumCourseValidator
# delegates
delegate :code, :credit, :course_type, :name, to: :course
- # enums
- enum type: { compulsory: 0, elective: 1 }
-
# callbacks
before_validation do
- self.type = curriculum_course_group_id.nil? ? :compulsory : :elective
+ self.type = curriculum_course_group.nil? ? :compulsory : :elective
end
end
diff --git a/app/models/curriculum_course_group.rb b/app/models/curriculum_course_group.rb
index 34f9115c3..a28663ff5 100644
--- a/app/models/curriculum_course_group.rb
+++ b/app/models/curriculum_course_group.rb
@@ -11,7 +11,8 @@ class CurriculumCourseGroup < ApplicationRecord
accepts_nested_attributes_for :curriculum_courses
# validations
- validates :ects, presence: true, numericality: { greater_than: 0 }
+ validates :ects, numericality: { greater_than: 0 }
+ validates :course_group_id, uniqueness: { scope: :curriculum_semester_id }
# delegates
delegate :name, to: :course_group
@@ -24,5 +25,6 @@ def build_curriculum_courses
course_id: course.id, curriculum_semester_id: curriculum_semester_id
)
end
+ self
end
end
diff --git a/app/models/curriculum_semester.rb b/app/models/curriculum_semester.rb
index 88c2f6d02..c970e1edd 100644
--- a/app/models/curriculum_semester.rb
+++ b/app/models/curriculum_semester.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
class CurriculumSemester < ApplicationRecord
+ include EnumForTerm
+
# relations
has_many :curriculum_courses, dependent: :destroy
has_many :curriculum_course_groups, dependent: :destroy
@@ -12,6 +14,7 @@ class CurriculumSemester < ApplicationRecord
uniqueness: { scope: :curriculum_id }
validates :year, numericality: { greater_than: 0 },
uniqueness: { scope: %i[sequence curriculum_id] }
+ validates :term, uniqueness: { scope: %i[year curriculum_id] }
# custom methods
def total_ects
diff --git a/app/models/district.rb b/app/models/district.rb
index 72eaa3dee..c14db65ed 100644
--- a/app/models/district.rb
+++ b/app/models/district.rb
@@ -17,9 +17,10 @@ class District < ApplicationRecord
has_many :addresses, dependent: :nullify
# validations
- validates :name, presence: true, uniqueness: { scope: %i[city_id] }
- validates :mernis_code, uniqueness: true, numericality: { only_integer: true }, allow_blank: true
+ validates :name, presence: true, uniqueness: { scope: %i[city_id] }, length: { maximum: 255 }
+ validates :mernis_code, allow_nil: true, uniqueness: true, numericality: { only_integer: true }, length: { is: 4 }
+ validates :active, inclusion: { in: [true, false] }
# callbacks
- before_save { self.name = name.capitalize_all }
+ before_validation { self.name = name.capitalize_turkish if name }
end
diff --git a/app/models/document.rb b/app/models/document.rb
deleted file mode 100644
index 5903f9615..000000000
--- a/app/models/document.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Document < ApplicationRecord
- # relations
- has_many :registration_documents, dependent: :destroy
-
- # validations
- validates :name, presence: true, uniqueness: true
-end
diff --git a/app/models/document_type.rb b/app/models/document_type.rb
new file mode 100644
index 000000000..09fc69d7e
--- /dev/null
+++ b/app/models/document_type.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class DocumentType < ApplicationRecord
+ # search
+ include ReferenceSearch
+
+ # relations
+ has_many :registration_documents, dependent: :destroy
+
+ # validations
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :active, inclusion: { in: [true, false] }
+end
diff --git a/app/models/employee.rb b/app/models/employee.rb
index 1bb292939..dc4ecb251 100644
--- a/app/models/employee.rb
+++ b/app/models/employee.rb
@@ -24,6 +24,7 @@ class Employee < ApplicationRecord
scope :active, -> { where(active: true) }
scope :passive, -> { where(active: false) }
scope :academic, -> { joins(:title).where('titles.branch = ?', 'ÖE') }
+ scope :administrative, -> { joins(:title).where('titles.branch != ?', 'ÖE') }
# custom methods
def academic?
diff --git a/app/models/evaluation_type.rb b/app/models/evaluation_type.rb
new file mode 100644
index 000000000..d5be9ac71
--- /dev/null
+++ b/app/models/evaluation_type.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class EvaluationType < ApplicationRecord
+ # search
+ include ReferenceSearch
+ include ReferenceCallbacks
+
+ # relations
+ has_many :course_evaluation_types, dependent: :destroy
+ has_many :available_courses, through: :course_evaluation_types
+
+ # validations
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+end
diff --git a/app/models/high_school_type.rb b/app/models/high_school_type.rb
index 6a9565097..2e5622e8b 100644
--- a/app/models/high_school_type.rb
+++ b/app/models/high_school_type.rb
@@ -3,6 +3,7 @@
class HighSchoolType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
# relations
has_many :prospective_students, dependent: :nullify
diff --git a/app/models/identity.rb b/app/models/identity.rb
index db2a9ad94..f0d17ff5f 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -3,35 +3,40 @@
class Identity < ApplicationRecord
self.inheritance_column = nil
+ # enums
+ enum type: { formal: 1, informal: 2 }
+ enum gender: { male: 1, female: 2, other: 3 }
+ enum marital_status: { single: 1, married: 2, divorced: 3, unknown: 4 }
+
# relations
belongs_to :user
belongs_to :student, optional: true
# validations
- validates :type, presence: true
- validates :first_name, presence: true
- validates :last_name, presence: true
- validates :gender, presence: true
- validates :place_of_birth, presence: true
+ validates :type, inclusion: { in: types.keys }
+ validates :first_name, presence: true, length: { maximum: 255 }
+ validates :last_name, presence: true, length: { maximum: 255 }
+ validates :mothers_name, length: { maximum: 255 }
+ validates :fathers_name, length: { maximum: 255 }
+ validates :gender, inclusion: { in: genders.keys }
+ validates :marital_status, allow_nil: true, inclusion: { in: marital_statuses.keys }
+ validates :place_of_birth, presence: true, length: { maximum: 255 }
validates :date_of_birth, presence: true
- validates :student_id, uniqueness: true, allow_blank: true
+ validates :registered_to, length: { maximum: 255 }
+ validates :student_id, uniqueness: true, allow_nil: true
validates_with AddressAndIdentityValidator, on: :create
- # enums
- enum type: { formal: 1, informal: 2 }
- enum gender: { male: 1, female: 2, other: 3 }
- enum marital_status: { single: 1, married: 2, divorced: 3, unknown: 4 }
-
# scopes
scope :user_identity, -> { formal.find_by(student_id: nil) }
+ scope :student_identity, -> { formal.where.not(student_id: nil).first }
# callbacks
before_save do
self.type = 'informal' if type.blank?
- self.first_name = first_name.capitalize_all
- self.last_name = last_name.upcase_tr
- self.mothers_name = mothers_name.capitalize_all if mothers_name
- self.fathers_name = fathers_name.capitalize_all if fathers_name
- self.place_of_birth = place_of_birth.capitalize_all if place_of_birth
+ self.first_name = first_name.capitalize_turkish
+ self.last_name = last_name.upcase(:turkic)
+ self.mothers_name = mothers_name.capitalize_turkish if mothers_name
+ self.fathers_name = fathers_name.capitalize_turkish if fathers_name
+ self.place_of_birth = place_of_birth.capitalize_turkish if place_of_birth
end
end
diff --git a/app/models/language.rb b/app/models/language.rb
index 0cc4f0a1d..00a3af52e 100644
--- a/app/models/language.rb
+++ b/app/models/language.rb
@@ -2,24 +2,19 @@
class Language < ApplicationRecord
# search
- include PgSearch
- pg_search_scope(
- :search,
- against: %i[name iso],
- using: { tsearch: { prefix: true } }
- )
+ include ReferenceSearch
# relations
has_many :courses, dependent: :nullify
has_many :prospective_students, dependent: :nullify
# validations
- validates :name, presence: true, uniqueness: true
- validates :iso, presence: true, uniqueness: true
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :iso, presence: true, uniqueness: true, length: { maximum: 255 }
# callbacks
- before_save do
- self.name = name.capitalize_all
- self.iso = iso.upcase_tr
+ before_validation do
+ self.name = name.capitalize_turkish if name
+ self.iso = iso.upcase(:turkic) if iso
end
end
diff --git a/app/models/meeting_agenda.rb b/app/models/meeting_agenda.rb
index c1d0ff2c1..573bd58e6 100644
--- a/app/models/meeting_agenda.rb
+++ b/app/models/meeting_agenda.rb
@@ -7,9 +7,9 @@ class MeetingAgenda < ApplicationRecord
has_one :decision, dependent: :destroy, class_name: 'CommitteeDecision'
# validations
- validates :sequence_no, presence: true, uniqueness: { scope: %i[committee_meeting] },
+ validates :sequence_no, uniqueness: { scope: %i[committee_meeting] },
numericality: { only_integer: true, greater_than_or_equal_to: 1 }
- validates :agenda_id, presence: true, uniqueness: { scope: :committee_meeting }
+ validates :agenda_id, uniqueness: { scope: :committee_meeting }
# delegates
delegate :description, :status, :agenda_type, to: :agenda
diff --git a/app/models/project.rb b/app/models/project.rb
index 0788eda70..d605348f5 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -3,12 +3,6 @@
class Project < ApplicationRecord
self.inheritance_column = nil
- # relations
- belongs_to :user, counter_cache: true
-
- # validations
- validates :yoksis_id, presence: true, uniqueness: { scope: %i[user_id status] }
-
# enums
enum status: {
completed: 1,
@@ -19,4 +13,22 @@ class Project < ApplicationRecord
enum activity: { passive: 0, active: 1 }
enum scope: { national: 0, international: 1 }
+
+ # relations
+ belongs_to :user, counter_cache: true
+
+ # validations
+ validates :yoksis_id, uniqueness: { scope: %i[user_id status] },
+ numericality: { only_integer: true, greater_than: 0 }
+ validates :name, presence: true, length: { maximum: 65_535 }
+ validates :subject, length: { maximum: 65_535 }
+ validates :budget, length: { maximum: 255 }
+ validates :duty, length: { maximum: 255 }
+ validates :type, length: { maximum: 255 }
+ validates :currency, length: { maximum: 255 }
+ validates :title, length: { maximum: 255 }
+ validates :status, allow_nil: true, inclusion: { in: statuses.keys }
+ validates :activity, allow_nil: true, inclusion: { in: activities.keys }
+ validates :scope, allow_nil: true, inclusion: { in: scopes.keys }
+ validates :incentive_point, allow_nil: true, numericality: { greater_than_or_equal_to: 0 }
end
diff --git a/app/models/prospective_student.rb b/app/models/prospective_student.rb
index 273790afc..f3e61aaef 100644
--- a/app/models/prospective_student.rb
+++ b/app/models/prospective_student.rb
@@ -13,6 +13,12 @@ class ProspectiveStudent < ApplicationRecord
search_keys :meb_status, :military_status, :obs_status, :unit_id, :student_entrance_type_id, :registered
+ # enumerations
+ enum gender: { male: 1, female: 2 }
+ enum nationality: { turkish: 1, kktc: 2, foreign: 3 }
+ enum placement_type: { general_score: 1, additional_score: 2 }
+ enum additional_score: { handicapped: 1 }
+
# relations
belongs_to :unit
belongs_to :language, optional: true
@@ -21,26 +27,54 @@ class ProspectiveStudent < ApplicationRecord
belongs_to :student_entrance_type
# validations
- validates :id_number, presence: true, uniqueness: { scope: %i[unit_id exam_score] }
- validates :gender, presence: true
+ validates :id_number, presence: true, uniqueness: { scope: %i[unit_id exam_score] }, length: { is: 11 }
+ validates :first_name, presence: true, length: { maximum: 255 }
+ validates :last_name, presence: true, length: { maximum: 255 }
+ validates :fathers_name, length: { maximum: 255 }
+ validates :mothers_name, length: { maximum: 255 }
+ validates :gender, inclusion: { in: genders.keys }
+ validates :nationality, allow_nil: true, inclusion: { in: nationalities.keys }
+ validates :place_of_birth, length: { maximum: 255 }
+ validates :registration_city, length: { maximum: 255 }
+ validates :registration_district, length: { maximum: 255 }
+ validates :high_school_code, length: { maximum: 255 }
+ validates :high_school_branch, length: { maximum: 255 }
+ validates :state_of_education, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :high_school_graduation_year, allow_nil: true,
+ numericality: {
+ only_integer: true,
+ greater_than_or_equal_to: 1910,
+ less_than_or_equal_to: 2050
+ }
+ validates :placement_type, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :exam_score, allow_nil: true, numericality: { greater_than_or_equal_to: 0 }
+ validates :address, length: { maximum: 255 }
+ validates :home_phone, length: { maximum: 255 }
+ validates :mobile_phone, length: { maximum: 255 }
+ validates :email, length: { maximum: 255 }
+ validates :top_student, inclusion: { in: [true, false] }
+ validates :placement_score, allow_nil: true, numericality: { greater_than_or_equal_to: 0 }
+ validates :placement_rank, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :preference_order, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :placement_score_type, length: { maximum: 255 }
+ validates :additional_score, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :meb_status, inclusion: { in: [true, false] }
+ validates :military_status, inclusion: { in: [true, false] }
+ validates :obs_status, inclusion: { in: [true, false] }
+ validates :registered, inclusion: { in: [true, false] }
+ validates :obs_registered_program, length: { maximum: 255 }
# callbacks
before_create do
- self.first_name = first_name.capitalize_all
- self.last_name = last_name.upcase_tr
- self.fathers_name = fathers_name.capitalize_all if fathers_name
- self.mothers_name = mothers_name.capitalize_all if mothers_name
- self.place_of_birth = place_of_birth.capitalize_all if place_of_birth
- self.registration_city = registration_city.capitalize_all if registration_city
- self.registration_district = registration_district.capitalize_all if registration_district
+ self.first_name = first_name.capitalize_turkish
+ self.last_name = last_name.upcase(:turkic)
+ self.fathers_name = fathers_name.capitalize_turkish if fathers_name
+ self.mothers_name = mothers_name.capitalize_turkish if mothers_name
+ self.place_of_birth = place_of_birth.capitalize_turkish if place_of_birth
+ self.registration_city = registration_city.capitalize_turkish if registration_city
+ self.registration_district = registration_district.capitalize_turkish if registration_district
end
- # enumerations
- enum gender: { male: 1, female: 2 }
- enum nationality: { turkish: 1, kktc: 2, foreign: 3 }
- enum placement_type: { general_score: 1, additional_score: 2 }
- enum additional_score: { handicapped: 1 }
-
# custom methods
def can_permanently_register?
military_status && obs_status && meb_status
diff --git a/app/models/registration_document.rb b/app/models/registration_document.rb
index 552d7eb2a..0a8bfe11b 100644
--- a/app/models/registration_document.rb
+++ b/app/models/registration_document.rb
@@ -1,14 +1,26 @@
# frozen_string_literal: true
class RegistrationDocument < ApplicationRecord
+ # search
+ include PgSearch
+ pg_search_scope(
+ :search,
+ associated_against: {
+ unit: :name,
+ document_type: :name
+ },
+ using: { tsearch: { prefix: true } }
+ )
+
# relations
belongs_to :unit
belongs_to :academic_term
- belongs_to :document
+ belongs_to :document_type
# validations
- validates :unit, uniqueness: { scope: %i[academic_term document] }
+ validates :unit_id, uniqueness: { scope: %i[academic_term document_type] }
+ validates :description, length: { maximum: 65_535 }
# delegates
- delegate :name, to: :document
+ delegate :name, :active, to: :document_type
end
diff --git a/app/models/student.rb b/app/models/student.rb
index 8e041031a..06f181e93 100644
--- a/app/models/student.rb
+++ b/app/models/student.rb
@@ -5,11 +5,13 @@ class Student < ApplicationRecord
belongs_to :user
belongs_to :unit
has_one :identity, dependent: :destroy
- has_many :academic_calendars, -> { AcademicCalendar.active }, through: :unit
+ has_many :calendars, -> { Calendar.active }, through: :unit
# validations
validates :unit_id, uniqueness: { scope: %i[user] }
- validates :student_number, presence: true, uniqueness: true
+ # TODO: Will set equal_to: N, when we decide about student numbers
+ validates :student_number, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :permanently_registered, inclusion: { in: [true, false] }
# delegations
delegate :addresses, to: :user
@@ -20,11 +22,4 @@ class Student < ApplicationRecord
def build_identity_information
Kps::IdentitySaveJob.perform_later(user, id)
end
-
- def proper_event_range?(title)
- event =
- academic_calendars.last.calendar_events
- .find_by(calendar_title: CalendarTitle.find_by(identifier: title))
- !event.nil? && event.proper_range?
- end
end
diff --git a/app/models/student_disability_type.rb b/app/models/student_disability_type.rb
index 48808b61b..050170fc4 100644
--- a/app/models/student_disability_type.rb
+++ b/app/models/student_disability_type.rb
@@ -3,6 +3,7 @@
class StudentDisabilityType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
# relations
has_many :prospective_students, dependent: :nullify
diff --git a/app/models/student_drop_out_type.rb b/app/models/student_drop_out_type.rb
index 9663810cb..05a5ba875 100644
--- a/app/models/student_drop_out_type.rb
+++ b/app/models/student_drop_out_type.rb
@@ -3,4 +3,5 @@
class StudentDropOutType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
end
diff --git a/app/models/student_education_level.rb b/app/models/student_education_level.rb
index 7779a7dd9..dcba427f4 100644
--- a/app/models/student_education_level.rb
+++ b/app/models/student_education_level.rb
@@ -3,4 +3,5 @@
class StudentEducationLevel < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
end
diff --git a/app/models/student_entrance_point_type.rb b/app/models/student_entrance_point_type.rb
index 307d811bb..158b99997 100644
--- a/app/models/student_entrance_point_type.rb
+++ b/app/models/student_entrance_point_type.rb
@@ -3,4 +3,5 @@
class StudentEntrancePointType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
end
diff --git a/app/models/student_entrance_type.rb b/app/models/student_entrance_type.rb
index af54c1d51..24fb12e3e 100644
--- a/app/models/student_entrance_type.rb
+++ b/app/models/student_entrance_type.rb
@@ -3,6 +3,7 @@
class StudentEntranceType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
has_many :prospective_students, dependent: :destroy
end
diff --git a/app/models/student_grade.rb b/app/models/student_grade.rb
index 2aa21a58e..e0c9c3d89 100644
--- a/app/models/student_grade.rb
+++ b/app/models/student_grade.rb
@@ -3,4 +3,5 @@
class StudentGrade < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
end
diff --git a/app/models/student_grading_system.rb b/app/models/student_grading_system.rb
index 2d86aea76..ef9420f33 100644
--- a/app/models/student_grading_system.rb
+++ b/app/models/student_grading_system.rb
@@ -3,4 +3,5 @@
class StudentGradingSystem < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
end
diff --git a/app/models/student_punishment_type.rb b/app/models/student_punishment_type.rb
index 55d5a8e47..2a8239170 100644
--- a/app/models/student_punishment_type.rb
+++ b/app/models/student_punishment_type.rb
@@ -3,4 +3,5 @@
class StudentPunishmentType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
end
diff --git a/app/models/student_studentship_status.rb b/app/models/student_studentship_status.rb
index 770b7a684..fc8af3cc8 100644
--- a/app/models/student_studentship_status.rb
+++ b/app/models/student_studentship_status.rb
@@ -3,4 +3,5 @@
class StudentStudentshipStatus < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
end
diff --git a/app/models/title.rb b/app/models/title.rb
index 85b52f061..ef6063933 100644
--- a/app/models/title.rb
+++ b/app/models/title.rb
@@ -1,11 +1,14 @@
# frozen_string_literal: true
class Title < ApplicationRecord
+ # search
+ include ReferenceSearch
+
# relations
has_many :employees, dependent: :nullify
# validations
- validates :name, presence: true, uniqueness: { scope: %i[code branch] }
- validates :code, presence: true
- validates :branch, presence: true
+ validates :name, presence: true, uniqueness: { scope: %i[code branch] }, length: { maximum: 255 }
+ validates :code, presence: true, length: { maximum: 255 }
+ validates :branch, presence: true, length: { maximum: 255 }
end
diff --git a/app/models/unit.rb b/app/models/unit.rb
index 609241341..84a1b14a0 100644
--- a/app/models/unit.rb
+++ b/app/models/unit.rb
@@ -7,7 +7,7 @@ class Unit < ApplicationRecord
pg_search_scope(
:search,
- against: %i[name yoksis_id detsis_id],
+ against: %i[name yoksis_id detsis_id abbreviation],
using: { tsearch: { prefix: true } }
)
@@ -16,6 +16,7 @@ class Unit < ApplicationRecord
# callbacks
before_save :cache_ancestry
+ before_validation { self.name = name.capitalize_turkish if name }
# relations
has_ancestry
@@ -37,50 +38,84 @@ class Unit < ApplicationRecord
has_many :decisions, through: :meeting_agendas, class_name: 'CommitteeDecision'
has_many :courses, dependent: :nullify
has_many :course_groups, dependent: :nullify
+ has_many :curriculum_programs, dependent: :destroy
+ has_many :curriculums, through: :curriculum_programs
+ has_many :managed_curriculums, dependent: :destroy, class_name: 'Curriculum'
has_many :registration_documents, dependent: :destroy
has_many :prospective_students, dependent: :destroy
- has_many :calendar_units, dependent: :destroy
- has_many :academic_calendars, through: :calendar_units
- has_many :calendar_events, through: :academic_calendars
+ has_many :available_courses, dependent: :destroy
+ has_many :unit_calendars, dependent: :destroy
+ has_many :calendars, through: :unit_calendars
# validations
- validates :yoksis_id, uniqueness: true, allow_blank: true, numericality: { only_integer: true }, length: { is: 6 }
- validates :detsis_id, uniqueness: true, allow_blank: true, numericality: { only_integer: true }, length: { is: 8 }
- validates :name, presence: true, uniqueness: { scope: %i[ancestry unit_status] }
- validates :duration, numericality: { only_integer: true }, allow_blank: true, inclusion: 1..8
-
- # callbacks
- before_save { self.name = name.capitalize_all }
+ validates :name, presence: true,
+ uniqueness: { scope: %i[yoksis_id detsis_id unit_status] }, length: { maximum: 255 }
+ validates :abbreviation, length: { maximum: 255 }
+ validates :code, length: { maximum: 255 }
+ validates :yoksis_id, allow_nil: true, uniqueness: true, numericality: { only_integer: true }, length: { is: 6 }
+ validates :detsis_id, allow_nil: true, uniqueness: true, numericality: { only_integer: true }, length: { is: 8 }
+ validates :osym_id, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :foet_code, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :duration, allow_nil: true, numericality: { only_integer: true }, inclusion: 1..8
# scopes
- scope :active, -> { where(unit_status: UnitStatus.active) }
- scope :partially_passive, -> { where(unit_status: UnitStatus.partially_passive) }
- scope :committees, -> { where(unit_type: UnitType.committee) }
- scope :departments, -> { where(unit_type: UnitType.department) }
- scope :faculties, -> { where(unit_type: UnitType.faculty) }
- scope :programs, -> { where(unit_type: UnitType.program) }
- scope :universities, -> { where(unit_type: UnitType.university) }
- scope :majors, -> { where(unit_type: UnitType.major) }
- scope :institutes, -> { where(unit_type: UnitType.institute) }
- scope :rectorships, -> { where(unit_type: UnitType.rectorship) }
- scope :without_programs, -> { where.not(unit_type: UnitType.program) }
+ scope :active, -> { where(unit_status: UnitStatus.active) }
+ scope :partially_passive, -> { where(unit_status: UnitStatus.partially_passive) }
+ scope :others, -> { where(unit_type: UnitType.other) }
+ scope :faculties, -> { where(unit_type: UnitType.faculty) }
+ scope :departments, -> { where(unit_type: UnitType.department) }
+ scope :majors, -> { where(unit_type: UnitType.major) }
+ scope :undergraduate_programs, -> { where(unit_type: UnitType.undergraduate_program) }
+ scope :graduate_programs, -> { where(unit_type: UnitType.graduate_program) }
+ scope :institutes, -> { where(unit_type: UnitType.institute) }
+ scope :research_centers, -> { where(unit_type: UnitType.research_center) }
+ scope :committees, -> { where(unit_type: UnitType.committee) }
+ scope :administratives, -> { where(unit_type: UnitType.administrative) }
+ scope :programs, -> { where(unit_type: UnitType.program) }
+ scope :without_programs, -> { where.not(unit_type: UnitType.program) }
+
+ scope :academic, -> {
+ faculties
+ .or(departments)
+ .or(majors)
+ .or(programs)
+ .or(institutes)
+ }
scope :coursable, -> {
departments
.or(faculties)
- .or(universities)
.or(majors)
.or(institutes)
- .or(rectorships)
+ .or(others)
}
+
scope :curriculumable, -> { coursable }
+ scope :eventable, -> {
+ faculties
+ .or(institutes)
+ .or(programs)
+ .or(research_centers)
+ .or(others)
+ }
+
def cache_ancestry
- self.names_depth_cache = path.map(&:name).reverse.join(' / ')
+ parent_names = path.map(&:name)
+ self.names_depth_cache = if path.count > 1
+ parent_names.drop(1).reverse.join(' / ')
+ else
+ parent_names.reverse.join(' / ')
+ end
end
# custom methods
def subprograms
descendants.programs
end
+
+ def subtree_employees
+ Employee.includes(:user, :title).joins(:units, user: :identities)
+ .where(units: { id: subtree.active.ids })
+ end
end
diff --git a/app/models/unit_calendar.rb b/app/models/unit_calendar.rb
new file mode 100644
index 000000000..9f56d7058
--- /dev/null
+++ b/app/models/unit_calendar.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class UnitCalendar < ApplicationRecord
+ # relations
+ belongs_to :calendar
+ belongs_to :unit
+
+ # validations
+ validates :calendar, presence: true, uniqueness: { scope: :unit }
+end
diff --git a/app/models/unit_instruction_language.rb b/app/models/unit_instruction_language.rb
index 6c0d67e6b..0909ae8af 100644
--- a/app/models/unit_instruction_language.rb
+++ b/app/models/unit_instruction_language.rb
@@ -3,6 +3,7 @@
class UnitInstructionLanguage < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
# relations
has_many :units, dependent: :nullify
diff --git a/app/models/unit_instruction_type.rb b/app/models/unit_instruction_type.rb
index 75c406025..3596a279b 100644
--- a/app/models/unit_instruction_type.rb
+++ b/app/models/unit_instruction_type.rb
@@ -3,6 +3,7 @@
class UnitInstructionType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
# relations
has_many :units, dependent: :nullify
diff --git a/app/models/unit_status.rb b/app/models/unit_status.rb
index 5cf382274..be920f652 100644
--- a/app/models/unit_status.rb
+++ b/app/models/unit_status.rb
@@ -3,6 +3,7 @@
class UnitStatus < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
# relations
has_many :units, dependent: :nullify
diff --git a/app/models/unit_type.rb b/app/models/unit_type.rb
index e84e9622d..69e7295a1 100644
--- a/app/models/unit_type.rb
+++ b/app/models/unit_type.rb
@@ -3,22 +3,28 @@
class UnitType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
-
- # relations
- has_many :units, dependent: :nullify
- has_many :calendar_unit_types, dependent: :destroy
- has_many :calendar_types, through: :calendar_unit_types
+ include ReferenceSearch
# enums
enum group: {
other: 0,
- university: 1,
- faculty: 2,
- department: 3,
- program: 4,
- committee: 5,
- major: 6,
- institute: 7,
- rectorship: 8
+ faculty: 1,
+ department: 2,
+ major: 3,
+ undergraduate_program: 4,
+ graduate_program: 5,
+ institute: 6,
+ research_center: 7,
+ committee: 8,
+ administrative: 9
}
+
+ # scopes
+ scope :program, -> { where(group: %w[undergraduate_program graduate_program]) }
+
+ # relations
+ has_many :units, dependent: :nullify
+
+ # validations
+ validates :group, allow_nil: true, inclusion: { in: groups.keys }
end
diff --git a/app/models/university_type.rb b/app/models/university_type.rb
index e41a43672..d52308ef7 100644
--- a/app/models/university_type.rb
+++ b/app/models/university_type.rb
@@ -3,6 +3,7 @@
class UniversityType < ApplicationRecord
include ReferenceValidations
include ReferenceCallbacks
+ include ReferenceSearch
# relations
has_many :units, dependent: :nullify
diff --git a/app/models/user.rb b/app/models/user.rb
index a55aa1a37..4335b20ae 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -11,7 +11,8 @@ class User < ApplicationRecord
)
# authentication
- devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :lockable
+ devise :database_authenticatable, :registerable, :recoverable, :rememberable,
+ :trackable, :validatable, :lockable, :timeoutable
# relations
has_one_attached :avatar
@@ -30,8 +31,9 @@ class User < ApplicationRecord
has_many :projects, dependent: :destroy
# validations
- validates :email, presence: true, uniqueness: true
- validates :id_number, presence: true, uniqueness: true, numericality: { only_integer: true }, length: { is: 11 }
+ validates :email, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :id_number, uniqueness: true, numericality: { only_integer: true }, length: { is: 11 }
+ validates :preferred_language, inclusion: { in: I18n.available_locales.map(&:to_s) }
validates_with EmailAddress::ActiveRecordValidator, field: :email
validates_with ImageValidator, field: :avatar, if: proc { |a| a.avatar.attached? }
@@ -66,7 +68,7 @@ def build_identity_information
def permalink
username, domain = email.split('@') if email
- username if domain.eql?(Rails.application.config.tenant.email.domain)
+ username if domain.eql?(Tenant.configuration.email.domain)
end
# custom methods
@@ -74,11 +76,15 @@ def accounts
(students + employees).flatten
end
- def self.most_publishing
- where.not(articles_count: nil).order('articles_count desc').limit(10)
- end
-
def title
employees.active.first.try(:title).try(:name)
end
+
+ def self.with_most_articles
+ where.not(articles_count: 0).order('articles_count desc').limit(10)
+ end
+
+ def self.with_most_projects
+ where.not(projects_count: 0).order('projects_count desc').limit(10)
+ end
end
diff --git a/app/services/academic_calendars/duplicate_events_service.rb b/app/services/academic_calendars/duplicate_events_service.rb
new file mode 100644
index 000000000..996d92d43
--- /dev/null
+++ b/app/services/academic_calendars/duplicate_events_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module AcademicCalendars
+ class DuplicateEventsService
+ attr_reader :from_calendar, :to_calendar
+
+ def initialize(from_calendar, to_calendar)
+ @from_calendar = from_calendar
+ @to_calendar = to_calendar
+ duplicate_calendar_events
+ end
+
+ private
+
+ def duplicate_calendar_events
+ @from_calendar.calendar_events.each do |calendar_event|
+ clone_event = calendar_event.dup
+ clone_event.calendar = @to_calendar
+ clone_event.save!
+ end
+ end
+ end
+end
diff --git a/app/services/duplicate_service.rb b/app/services/duplicate_service.rb
new file mode 100644
index 000000000..768ca4aec
--- /dev/null
+++ b/app/services/duplicate_service.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class DuplicateService
+ attr_reader :record, :prefixed_param
+
+ def initialize(record, prefixed_param)
+ @record = record
+ @prefixed_param = prefixed_param
+ end
+
+ def duplicate
+ clone_record = @record.dup
+ clone_record.send(@prefixed_param).prepend('[Kopyası] ')
+ clone_record.save
+ clone_record
+ end
+end
diff --git a/app/services/first_registration/prospective_student_service.rb b/app/services/first_registration/prospective_student_service.rb
new file mode 100644
index 000000000..499b65301
--- /dev/null
+++ b/app/services/first_registration/prospective_student_service.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module FirstRegistration
+ class ProspectiveStudentService
+ def initialize(prospective_student)
+ @prospective_student = prospective_student
+ end
+
+ def register
+ initialize_user
+ initialize_student
+
+ return unless @user.valid? && @student.valid?
+
+ @user.save
+ @student.save
+ end
+
+ private
+
+ def initialize_user
+ @user = User.new(
+ id_number: @prospective_student.id_number,
+ email: @prospective_student.email,
+ password: @prospective_student.id_number,
+ password_confirmation: @prospective_student.id_number
+ )
+ end
+
+ def initialize_student
+ @student = Student.new(
+ user: @user,
+ unit: @prospective_student.unit,
+ permanently_registered: @prospective_student.can_permanently_register?,
+ student_number: @prospective_student.id_number # TODO: must be generated
+ )
+ end
+ end
+end
diff --git a/app/services/prospective_student_service.rb b/app/services/prospective_student_service.rb
deleted file mode 100644
index ce1779545..000000000
--- a/app/services/prospective_student_service.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class ProspectiveStudentService
- def initialize(prospective_student)
- @prospective_student = prospective_student
- end
-
- def create_user
- User.new(
- id_number: @prospective_student.id_number,
- email: @prospective_student.email,
- password: @prospective_student.id_number,
- password_confirmation: @prospective_student.id_number
- )
- end
-
- def create_student
- Student.new(
- user: User.find_by(id_number: @prospective_student.id_number),
- unit: @prospective_student.unit,
- permanently_registered: @prospective_student.can_permanently_register? ? true : false,
- student_number: @prospective_student.id_number # must be generated
- )
- end
-end
diff --git a/app/services/vcard_builder.rb b/app/services/vcard_builder.rb
deleted file mode 100644
index 8041a51c1..000000000
--- a/app/services/vcard_builder.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-class VcardBuilder
- def initialize(identity)
- @identity = identity
- end
-
- def build_vcard
- <<~VCARD
- BEGIN:VCARD
- VERSION:3.0
- N:#{@identity.last_name};#{@identity.first_name};;;
- FN:#{@identity.first_name} #{@identity.last_name}
- ORG:#{Rails.application.config.tenant.name}
- TITLE:#{@identity.user.title}
- EMAIL:#{@identity.user.email}
- END:VCARD
- VCARD
- end
-end
diff --git a/app/services/vcard_builder_service.rb b/app/services/vcard_builder_service.rb
new file mode 100644
index 000000000..63f5d4200
--- /dev/null
+++ b/app/services/vcard_builder_service.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class VcardBuilderService
+ def initialize(identity)
+ @identity = identity
+ end
+
+ def generate
+ <<~VCARD
+ BEGIN:VCARD
+ VERSION:3.0
+ N:#{@identity.last_name};#{@identity.first_name};;;
+ FN:#{@identity.first_name} #{@identity.last_name}
+ ORG:#{Tenant.configuration.tenant.name}
+ TITLE:#{@identity.user.title}
+ EMAIL:#{@identity.user.email}
+ END:VCARD
+ VCARD
+ end
+end
diff --git a/app/services/xokul/connection.rb b/app/services/xokul/connection.rb
index 055ce2c02..b6f680bab 100644
--- a/app/services/xokul/connection.rb
+++ b/app/services/xokul/connection.rb
@@ -2,7 +2,7 @@
module Xokul
module Connection
- BASE_URL = Rails.application.config.tenant.api_host
+ BASE_URL = Tenant.configuration.api_host
BEARER_TOKEN = Rails.application.credentials.xokul[:bearer_token]
private_constant :BASE_URL, :BEARER_TOKEN
@@ -11,7 +11,7 @@ module Connection
def self.request(path, params: {}, **http_options)
http_options[:open_timeout] ||= http_options[:read_timeout] ||= 10 if Rails.env.test?
- response = RestClient.get(
+ response = Support::RestClient.get(
URI.join(BASE_URL, path).to_s,
headers: {
'Authorization' => "Bearer #{BEARER_TOKEN}",
diff --git a/app/validators/academic_term_validator.rb b/app/validators/academic_term_validator.rb
new file mode 100644
index 000000000..09aab524d
--- /dev/null
+++ b/app/validators/academic_term_validator.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AcademicTermValidator < ActiveModel::Validator
+ def validate(record)
+ return if record.active?
+ return if AcademicTerm.where.not(id: record.id).exists?(active: true)
+
+ record.errors[:active] << I18n.t('active_check', scope: %i[validators academic_term])
+ end
+end
diff --git a/app/validators/available_course_lecturer_validator.rb b/app/validators/available_course_lecturer_validator.rb
new file mode 100644
index 000000000..b8d5798fe
--- /dev/null
+++ b/app/validators/available_course_lecturer_validator.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AvailableCourseLecturerValidator < ActiveModel::Validator
+ def validate(record)
+ lecturers = record.group.lecturers.reject { |lecturer| lecturer.equal?(record) }
+ return unless record.coordinator && lecturers.map(&:coordinator).any?
+
+ record.errors[:coordinator] << I18n.t('coordinator', scope: %i[validators available_course_lecturer])
+ end
+end
diff --git a/app/validators/calendar_event_validator.rb b/app/validators/calendar_event_validator.rb
index 39fe96f6a..03fe2e236 100644
--- a/app/validators/calendar_event_validator.rb
+++ b/app/validators/calendar_event_validator.rb
@@ -3,23 +3,23 @@
class CalendarEventValidator < ActiveModel::Validator
def validate(record)
@event = record
- @term = record.academic_calendar.academic_term
+ @academic_term = record.calendar.academic_term
- term_start_date_validation if @event.start_date?
- term_end_date_validation if @event.end_date?
- date_range_validation if @event.start_date? && @event.end_date?
+ term_start_time_validation if @event.start_time?
+ term_end_time_validation if @event.end_time?
+ date_range_validation if @event.start_time? && @event.end_time?
end
- def term_start_date_validation
- @event.errors[:start_date] << message('invalid_start_date') if @event.start_date <= @term.start_of_term
+ def term_start_time_validation
+ @event.errors[:start_time] << message('invalid_start_time') if @event.start_time <= @academic_term.start_of_term
end
- def term_end_date_validation
- @event.errors[:end_date] << message('invalid_end_date') if @event.end_date >= @term.end_of_term
+ def term_end_time_validation
+ @event.errors[:end_time] << message('invalid_end_time') if @event.end_time >= @academic_term.end_of_term
end
def date_range_validation
- @event.errors[:end_date] << message('invalid_date_range') if @event.end_date < @event.start_date
+ @event.errors[:end_time] << message('invalid_time_range') if @event.end_time < @event.start_time
end
private
diff --git a/app/validators/course_evaluation_type_validator.rb b/app/validators/course_evaluation_type_validator.rb
new file mode 100644
index 000000000..bd5861f43
--- /dev/null
+++ b/app/validators/course_evaluation_type_validator.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class CourseEvaluationTypeValidator < ActiveModel::Validator
+ def validate(record)
+ @evaluation_type = record
+ check_percentage(@evaluation_type.course_assessment_methods.map(&:percentage))
+ end
+
+ def check_percentage(percentages)
+ return if percentages.sum.equal?(100)
+
+ @evaluation_type.errors[:base] << message('invalid_percentages')
+ end
+
+ private
+
+ def message(key)
+ I18n.t(key, scope: %i[validators course_evaluation_type])
+ end
+end
diff --git a/app/validators/curriculum_course_validator.rb b/app/validators/curriculum_course_validator.rb
new file mode 100644
index 000000000..519e6677e
--- /dev/null
+++ b/app/validators/curriculum_course_validator.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class CurriculumCourseValidator < ActiveModel::Validator
+ def validate(record)
+ return unless record.curriculum_semester && record.course_id_changed?
+
+ courses = record.curriculum_semester.curriculum.courses
+ record.errors.add(:course, :taken) if courses.exists?(id: record.course_id)
+ end
+end
diff --git a/app/views/account/addresses/index.html.erb b/app/views/account/addresses/index.html.erb
index 1bd97a7e1..c36a21af6 100644
--- a/app/views/account/addresses/index.html.erb
+++ b/app/views/account/addresses/index.html.erb
@@ -1,6 +1,6 @@
<%= link_to_back user_path(@user) %>
- <%= link_to_new(new_user_address_path(@user), t('.new_address')) unless @user.addresses.informal.present? %>
+ <%= link_to_new(t('.new_address'), new_user_address_path(@user)) unless @user.addresses.informal.present? %>
<%= link_to (@addresses.formal.present? ? t('.update_from_mernis') : t('.create_from_mernis') ), save_from_mernis_user_addresses_path, class: "btn btn-outline-primary btn-sm" %>
diff --git a/app/views/account/identities/index.html.erb b/app/views/account/identities/index.html.erb
index 5ce0b2d62..5b3edefbc 100644
--- a/app/views/account/identities/index.html.erb
+++ b/app/views/account/identities/index.html.erb
@@ -1,6 +1,6 @@
<%= link_to_back user_path(@user) %>
- <%= link_to_new(new_user_identity_path(@user), t('.new_identity')) unless @user.identities.informal.present? %>
+ <%= link_to_new(t('.new_identity'), new_user_identity_path(@user)) unless @user.identities.informal.present? %>
<%= link_to (@identities.formal.present? ? t('.update_from_mernis') : t('.create_from_mernis') ), save_from_mernis_user_identities_path, class: "btn btn-outline-primary btn-sm" %>
diff --git a/app/views/admin/assessment_methods/_form.html.erb b/app/views/admin/assessment_methods/_form.html.erb
new file mode 100644
index 000000000..d30f2dd00
--- /dev/null
+++ b/app/views/admin/assessment_methods/_form.html.erb
@@ -0,0 +1,10 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @assessment_method,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/assessment_methods/edit.html.erb b/app/views/admin/assessment_methods/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/assessment_methods/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/assessment_methods/index.html.erb b/app/views/admin/assessment_methods/index.html.erb
new file mode 100644
index 000000000..3794e1018
--- /dev/null
+++ b/app/views/admin/assessment_methods/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'assessment_method',
+ collection: @assessment_methods,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/assessment_methods/new.html.erb b/app/views/admin/assessment_methods/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/assessment_methods/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/cities/_form.html.erb b/app/views/admin/cities/_form.html.erb
new file mode 100644
index 000000000..ff9f45d76
--- /dev/null
+++ b/app/views/admin/cities/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: [@country, @city],
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'alpha_2_code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/cities/edit.html.erb b/app/views/admin/cities/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/cities/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/cities/new.html.erb b/app/views/admin/cities/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/cities/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/cities/show.html.erb b/app/views/admin/cities/show.html.erb
new file mode 100644
index 000000000..13f83c1d7
--- /dev/null
+++ b/app/views/admin/cities/show.html.erb
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+ <%= t('activerecord.attributes.city.name') %>
+ <%= @city.name %>
+
+
+ <%= t('activerecord.attributes.city.alpha_2_code') %>
+ <%= @city.alpha_2_code %>
+
+
+
+
+
+
+
+
+
+ <%= render 'layouts/shared/smart_search_form',
+ path: [:admin, @country, @city],
+ placeholder: t('.name') %>
+
+
+
+ <%= t('.name') %>
+ <%= t('.mernis_code') %>
+ <%= t('.active') %>
+ <%= t('actions') %>
+
+
+
+ <% @districts.each do |district| %>
+
+ <%= district.name %>
+ <%= district.mernis_code %>
+ <%= district.active ? t('yes') : t('no') %>
+
+ <%= link_to_edit([:edit, :admin, @country, @city, district]) %>
+ <%= link_to_destroy([:admin, @country, @city, district]) %>
+
+
+ <% end %>
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/admin/countries/_form.html.erb b/app/views/admin/countries/_form.html.erb
new file mode 100644
index 000000000..7187e24e9
--- /dev/null
+++ b/app/views/admin/countries/_form.html.erb
@@ -0,0 +1,33 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @country,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'alpha_2_code',
+ width: 3,
+ required: true
+ },
+ {
+ field: 'alpha_3_code',
+ width: 3,
+ required: true
+ },
+ {
+ field: 'numeric_code',
+ width: 3,
+ required: true
+ },
+ {
+ field: 'mernis_code',
+ width: 3
+ },
+ {
+ field: 'yoksis_code',
+ width: 3
+ }
+ ] %>
diff --git a/app/views/admin/countries/edit.html.erb b/app/views/admin/countries/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/countries/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/countries/index.html.erb b/app/views/admin/countries/index.html.erb
new file mode 100644
index 000000000..da5f9b17c
--- /dev/null
+++ b/app/views/admin/countries/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'country',
+ collection: @countries,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'alpha_2_code', 'alpha_3_code', 'numeric_code', 'mernis_code', 'yoksis_code'],
+ actions: ['show', 'edit', 'destroy'] %>
diff --git a/app/views/admin/countries/new.html.erb b/app/views/admin/countries/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/countries/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/countries/show.html.erb b/app/views/admin/countries/show.html.erb
new file mode 100644
index 000000000..3c3d7b5ab
--- /dev/null
+++ b/app/views/admin/countries/show.html.erb
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+ <%= t('activerecord.attributes.country.name') %>
+ <%= @country.name %>
+
+
+ <%= t('.alpha_2_code') %>
+ <%= @country.alpha_2_code %>
+
+
+ <%= t('.alpha_3_code') %>
+ <%= @country.alpha_3_code %>
+
+
+ <%= t('.numeric_code') %>
+ <%= @country.numeric_code %>
+
+
+ <%= t('.mernis_code') %>
+ <%= @country.mernis_code %>
+
+
+ <%= t('.yoksis_code') %>
+ <%= @country.yoksis_code %>
+
+
+
+
+
+
+
+
+
+ <%= render 'layouts/shared/smart_search_form',
+ path: [:admin, @country],
+ placeholder: t('.name') %>
+ <% if @country.cities.any? %>
+
+
+
+ <%= t('.name') %>
+ <%= t('.alpha_2_code') %>
+ <%= t('actions') %>
+
+
+
+ <% @cities.each do |city| %>
+
+ <%= city.name %>
+ <%= city.alpha_2_code %>
+
+ <%= link_to_show([:admin, @country, city]) %>
+ <%= link_to_edit([:edit, :admin, @country, city]) %>
+ <%= link_to_destroy([:admin, @country, city]) %>
+
+
+ <% end %>
+
+
+ <% end %>
+
+
+
+
+
+
+
+
diff --git a/app/views/admin/districts/_form.html.erb b/app/views/admin/districts/_form.html.erb
new file mode 100644
index 000000000..e0d573280
--- /dev/null
+++ b/app/views/admin/districts/_form.html.erb
@@ -0,0 +1,14 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: [@city.country, @city, @district],
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'mernis_code',
+ width: 12
+ }
+ ] %>
diff --git a/app/views/admin/districts/edit.html.erb b/app/views/admin/districts/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/districts/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/districts/new.html.erb b/app/views/admin/districts/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/districts/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/document_types/_form.html.erb b/app/views/admin/document_types/_form.html.erb
new file mode 100644
index 000000000..977bc70c2
--- /dev/null
+++ b/app/views/admin/document_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @document_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'active',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/document_types/edit.html.erb b/app/views/admin/document_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/document_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/document_types/index.html.erb b/app/views/admin/document_types/index.html.erb
new file mode 100644
index 000000000..11d233e68
--- /dev/null
+++ b/app/views/admin/document_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'document_type',
+ collection: @document_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'active'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/document_types/new.html.erb b/app/views/admin/document_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/document_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/evaluation_types/_form.html.erb b/app/views/admin/evaluation_types/_form.html.erb
new file mode 100644
index 000000000..1a64b1df9
--- /dev/null
+++ b/app/views/admin/evaluation_types/_form.html.erb
@@ -0,0 +1,10 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @evaluation_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/evaluation_types/edit.html.erb b/app/views/admin/evaluation_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/evaluation_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/evaluation_types/index.html.erb b/app/views/admin/evaluation_types/index.html.erb
new file mode 100644
index 000000000..8cc9cf1b6
--- /dev/null
+++ b/app/views/admin/evaluation_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'evaluation_type',
+ collection: @evaluation_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/evaluation_types/new.html.erb b/app/views/admin/evaluation_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/evaluation_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/high_school_types/_form.html.erb b/app/views/admin/high_school_types/_form.html.erb
new file mode 100644
index 000000000..48cb0bb0e
--- /dev/null
+++ b/app/views/admin/high_school_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @high_school_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/high_school_types/edit.html.erb b/app/views/admin/high_school_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/high_school_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/high_school_types/index.html.erb b/app/views/admin/high_school_types/index.html.erb
new file mode 100644
index 000000000..ca753fb0b
--- /dev/null
+++ b/app/views/admin/high_school_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'high_school_type',
+ collection: @high_school_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/high_school_types/new.html.erb b/app/views/admin/high_school_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/high_school_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/languages/_form.html.erb b/app/views/admin/languages/_form.html.erb
new file mode 100644
index 000000000..140521bf1
--- /dev/null
+++ b/app/views/admin/languages/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @language,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'iso',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/languages/edit.html.erb b/app/views/admin/languages/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/languages/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/languages/index.html.erb b/app/views/admin/languages/index.html.erb
new file mode 100644
index 000000000..63155c0f1
--- /dev/null
+++ b/app/views/admin/languages/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'language',
+ collection: @languages,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'iso'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/languages/new.html.erb b/app/views/admin/languages/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/languages/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_disability_types/_form.html.erb b/app/views/admin/student_disability_types/_form.html.erb
new file mode 100644
index 000000000..67478c2a9
--- /dev/null
+++ b/app/views/admin/student_disability_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_disability_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_disability_types/edit.html.erb b/app/views/admin/student_disability_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_disability_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_disability_types/index.html.erb b/app/views/admin/student_disability_types/index.html.erb
new file mode 100644
index 000000000..7801affe0
--- /dev/null
+++ b/app/views/admin/student_disability_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_disability_type',
+ collection: @student_disability_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_disability_types/new.html.erb b/app/views/admin/student_disability_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_disability_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_drop_out_types/_form.html.erb b/app/views/admin/student_drop_out_types/_form.html.erb
new file mode 100644
index 000000000..5a48ccd35
--- /dev/null
+++ b/app/views/admin/student_drop_out_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_drop_out_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_drop_out_types/edit.html.erb b/app/views/admin/student_drop_out_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_drop_out_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_drop_out_types/index.html.erb b/app/views/admin/student_drop_out_types/index.html.erb
new file mode 100644
index 000000000..1781e55c9
--- /dev/null
+++ b/app/views/admin/student_drop_out_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_drop_out_type',
+ collection: @student_drop_out_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_drop_out_types/new.html.erb b/app/views/admin/student_drop_out_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_drop_out_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_education_levels/_form.html.erb b/app/views/admin/student_education_levels/_form.html.erb
new file mode 100644
index 000000000..3c85a5b10
--- /dev/null
+++ b/app/views/admin/student_education_levels/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_education_level,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_education_levels/edit.html.erb b/app/views/admin/student_education_levels/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_education_levels/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_education_levels/index.html.erb b/app/views/admin/student_education_levels/index.html.erb
new file mode 100644
index 000000000..8213d4981
--- /dev/null
+++ b/app/views/admin/student_education_levels/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_education_level',
+ collection: @student_education_levels,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_education_levels/new.html.erb b/app/views/admin/student_education_levels/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_education_levels/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_entrance_point_types/_form.html.erb b/app/views/admin/student_entrance_point_types/_form.html.erb
new file mode 100644
index 000000000..80ecdfd17
--- /dev/null
+++ b/app/views/admin/student_entrance_point_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_entrance_point_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_entrance_point_types/edit.html.erb b/app/views/admin/student_entrance_point_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_entrance_point_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_entrance_point_types/index.html.erb b/app/views/admin/student_entrance_point_types/index.html.erb
new file mode 100644
index 000000000..0cac7f850
--- /dev/null
+++ b/app/views/admin/student_entrance_point_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_entrance_point_type',
+ collection: @student_entrance_point_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_entrance_point_types/new.html.erb b/app/views/admin/student_entrance_point_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_entrance_point_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_entrance_types/_form.html.erb b/app/views/admin/student_entrance_types/_form.html.erb
new file mode 100644
index 000000000..b03f88231
--- /dev/null
+++ b/app/views/admin/student_entrance_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_entrance_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_entrance_types/edit.html.erb b/app/views/admin/student_entrance_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_entrance_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_entrance_types/index.html.erb b/app/views/admin/student_entrance_types/index.html.erb
new file mode 100644
index 000000000..c1e95a1d1
--- /dev/null
+++ b/app/views/admin/student_entrance_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_entrance_type',
+ collection: @student_entrance_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_entrance_types/new.html.erb b/app/views/admin/student_entrance_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_entrance_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_grades/_form.html.erb b/app/views/admin/student_grades/_form.html.erb
new file mode 100644
index 000000000..c07a62fa8
--- /dev/null
+++ b/app/views/admin/student_grades/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_grade,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_grades/edit.html.erb b/app/views/admin/student_grades/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_grades/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_grades/index.html.erb b/app/views/admin/student_grades/index.html.erb
new file mode 100644
index 000000000..1ad38256e
--- /dev/null
+++ b/app/views/admin/student_grades/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_grade',
+ collection: @student_grades,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_grades/new.html.erb b/app/views/admin/student_grades/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_grades/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_grading_systems/_form.html.erb b/app/views/admin/student_grading_systems/_form.html.erb
new file mode 100644
index 000000000..05984e715
--- /dev/null
+++ b/app/views/admin/student_grading_systems/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_grading_system,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_grading_systems/edit.html.erb b/app/views/admin/student_grading_systems/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_grading_systems/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_grading_systems/index.html.erb b/app/views/admin/student_grading_systems/index.html.erb
new file mode 100644
index 000000000..157ac0a14
--- /dev/null
+++ b/app/views/admin/student_grading_systems/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_grading_system',
+ collection: @student_grading_systems,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_grading_systems/new.html.erb b/app/views/admin/student_grading_systems/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_grading_systems/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_punishment_types/_form.html.erb b/app/views/admin/student_punishment_types/_form.html.erb
new file mode 100644
index 000000000..3cb20a80d
--- /dev/null
+++ b/app/views/admin/student_punishment_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_punishment_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_punishment_types/edit.html.erb b/app/views/admin/student_punishment_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_punishment_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_punishment_types/index.html.erb b/app/views/admin/student_punishment_types/index.html.erb
new file mode 100644
index 000000000..377c7c1f3
--- /dev/null
+++ b/app/views/admin/student_punishment_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_punishment_type',
+ collection: @student_punishment_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_punishment_types/new.html.erb b/app/views/admin/student_punishment_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_punishment_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_studentship_statuses/_form.html.erb b/app/views/admin/student_studentship_statuses/_form.html.erb
new file mode 100644
index 000000000..29ac1447d
--- /dev/null
+++ b/app/views/admin/student_studentship_statuses/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @student_studentship_status,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true,
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/student_studentship_statuses/edit.html.erb b/app/views/admin/student_studentship_statuses/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_studentship_statuses/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/student_studentship_statuses/index.html.erb b/app/views/admin/student_studentship_statuses/index.html.erb
new file mode 100644
index 000000000..7fba7e9b3
--- /dev/null
+++ b/app/views/admin/student_studentship_statuses/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'student_studentship_status',
+ collection: @student_studentship_statuses,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/student_studentship_statuses/new.html.erb b/app/views/admin/student_studentship_statuses/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/student_studentship_statuses/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/titles/_form.html.erb b/app/views/admin/titles/_form.html.erb
new file mode 100644
index 000000000..4c3908f4b
--- /dev/null
+++ b/app/views/admin/titles/_form.html.erb
@@ -0,0 +1,20 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @title,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 6,
+ required: true
+ },
+ {
+ field: 'branch',
+ width: 6,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/titles/edit.html.erb b/app/views/admin/titles/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/titles/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/titles/index.html.erb b/app/views/admin/titles/index.html.erb
new file mode 100644
index 000000000..1aabc8a3e
--- /dev/null
+++ b/app/views/admin/titles/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'title',
+ collection: @titles,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code', 'branch'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/titles/new.html.erb b/app/views/admin/titles/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/titles/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_instruction_languages/_form.html.erb b/app/views/admin/unit_instruction_languages/_form.html.erb
new file mode 100644
index 000000000..51a9a5363
--- /dev/null
+++ b/app/views/admin/unit_instruction_languages/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @unit_instruction_language,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/unit_instruction_languages/edit.html.erb b/app/views/admin/unit_instruction_languages/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_instruction_languages/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_instruction_languages/index.html.erb b/app/views/admin/unit_instruction_languages/index.html.erb
new file mode 100644
index 000000000..f27c859e4
--- /dev/null
+++ b/app/views/admin/unit_instruction_languages/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'unit_instruction_language',
+ collection: @unit_instruction_languages,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/unit_instruction_languages/new.html.erb b/app/views/admin/unit_instruction_languages/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_instruction_languages/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_instruction_types/_form.html.erb b/app/views/admin/unit_instruction_types/_form.html.erb
new file mode 100644
index 000000000..f3b80597f
--- /dev/null
+++ b/app/views/admin/unit_instruction_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @unit_instruction_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/unit_instruction_types/edit.html.erb b/app/views/admin/unit_instruction_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_instruction_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_instruction_types/index.html.erb b/app/views/admin/unit_instruction_types/index.html.erb
new file mode 100644
index 000000000..8160d8075
--- /dev/null
+++ b/app/views/admin/unit_instruction_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'unit_instruction_type',
+ collection: @unit_instruction_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/unit_instruction_types/new.html.erb b/app/views/admin/unit_instruction_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_instruction_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_statuses/_form.html.erb b/app/views/admin/unit_statuses/_form.html.erb
new file mode 100644
index 000000000..bf4861789
--- /dev/null
+++ b/app/views/admin/unit_statuses/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @unit_status,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/unit_statuses/edit.html.erb b/app/views/admin/unit_statuses/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_statuses/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_statuses/index.html.erb b/app/views/admin/unit_statuses/index.html.erb
new file mode 100644
index 000000000..546cb9f06
--- /dev/null
+++ b/app/views/admin/unit_statuses/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'unit_status',
+ collection: @unit_statuses,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/unit_statuses/new.html.erb b/app/views/admin/unit_statuses/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_statuses/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_types/_form.html.erb b/app/views/admin/unit_types/_form.html.erb
new file mode 100644
index 000000000..263b8c9cc
--- /dev/null
+++ b/app/views/admin/unit_types/_form.html.erb
@@ -0,0 +1,21 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @unit_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'group',
+ width: 12,
+ required: true,
+ collection: UnitType.groups.keys.sort
+ }
+ ] %>
diff --git a/app/views/admin/unit_types/edit.html.erb b/app/views/admin/unit_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/unit_types/index.html.erb b/app/views/admin/unit_types/index.html.erb
new file mode 100644
index 000000000..1e3e1731a
--- /dev/null
+++ b/app/views/admin/unit_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'unit_type',
+ collection: @unit_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code', 'group'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/unit_types/new.html.erb b/app/views/admin/unit_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/unit_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/university_types/_form.html.erb b/app/views/admin/university_types/_form.html.erb
new file mode 100644
index 000000000..935355664
--- /dev/null
+++ b/app/views/admin/university_types/_form.html.erb
@@ -0,0 +1,15 @@
+<%= render 'layouts/builders/form',
+ namespace: 'admin',
+ klass: @university_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'code',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/admin/university_types/edit.html.erb b/app/views/admin/university_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/university_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/admin/university_types/index.html.erb b/app/views/admin/university_types/index.html.erb
new file mode 100644
index 000000000..3b33fe3c8
--- /dev/null
+++ b/app/views/admin/university_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'admin',
+ klass: 'university_type',
+ collection: @university_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'code'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/admin/university_types/new.html.erb b/app/views/admin/university_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/admin/university_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/references/home/_card.html.erb b/app/views/admin/yoksis_dashboard/_card.html.erb
similarity index 79%
rename from app/views/references/home/_card.html.erb
rename to app/views/admin/yoksis_dashboard/_card.html.erb
index d4920e385..0fdf6c721 100644
--- a/app/views/references/home/_card.html.erb
+++ b/app/views/admin/yoksis_dashboard/_card.html.erb
@@ -1,7 +1,9 @@
-
<%= t(title) %>
+
+ <%= t(title) %>
+
<%= content %>
<%= link_to path, class: 'btn btn-block btn-secondary' do %>
<%= t('action_group.show') %>
diff --git a/app/views/admin/yoksis_dashboard/index.html.erb b/app/views/admin/yoksis_dashboard/index.html.erb
new file mode 100644
index 000000000..19e6db76a
--- /dev/null
+++ b/app/views/admin/yoksis_dashboard/index.html.erb
@@ -0,0 +1,26 @@
+
+ <% yoksis_klasses = %w[
+ HighSchoolType
+ StudentDisabilityType
+ StudentDropOutType
+ StudentEducationLevel
+ StudentEntrancePointType
+ StudentEntranceType
+ StudentGrade
+ StudentGradingSystem
+ StudentPunishmentType
+ StudentStudentshipStatus
+ UnitInstructionLanguage
+ UnitInstructionType
+ UnitStatus
+ UnitType
+ UniversityType
+ ] %>
+
+ <% yoksis_klasses.each do |klass| %>
+ <%= render 'card',
+ content: klass.constantize.count,
+ title: ".#{klass.tableize}",
+ path: send("admin_#{klass.tableize}_path") %>
+ <% end %>
+
diff --git a/app/views/calendar/academic_calendars/_calendar_event_fields.erb b/app/views/calendar/academic_calendars/_calendar_event_fields.erb
deleted file mode 100644
index d6d1f36ab..000000000
--- a/app/views/calendar/academic_calendars/_calendar_event_fields.erb
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- <%= f.input :calendar_title_id,
- collection: @academic_calendar.calendar_type.titles,
- input_html: { class: 'select_search_class' } %>
- <%= f.input :start_date,
- as: :date_time_picker,
- input_html: { data: { class: 'event-date'} } %>
- <%= f.input :end_date,
- as: :date_time_picker,
- input_html: { data: { class: 'event-date'} } %>
-
-
-
-
diff --git a/app/views/calendar/academic_calendars/_form.html.erb b/app/views/calendar/academic_calendars/_form.html.erb
deleted file mode 100644
index 38a960166..000000000
--- a/app/views/calendar/academic_calendars/_form.html.erb
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
- <%= simple_form_for(academic_calendar) do |f| %>
-
-
- <%= f.error_notification %>
- <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
-
-
- <%= f.input :name %>
-
-
- <%= f.association :academic_term, label_method: lambda { |academic_term| full_name(academic_term) }, value_method: :id %>
-
-
- <%= f.association :calendar_type %>
-
-
- <%= f.input :senate_decision_date,
- as: :date_time_picker,
- input_html: { data: { class: 'senate_decision_date'} } %>
-
-
- <%= f.input :senate_decision_no %>
-
-
- <%= f.input :description %>
-
-
- <% if academic_calendar.persisted? %>
-
- <%= f.association :units, collection: Unit.active.where(unit_type: f.object.calendar_type.unit_type_ids),
- label_method: :names_depth_cache, required: true %>
-
-
-
<%= t('.events') %>
-
- <%= f.simple_fields_for :calendar_events do |event| %>
- <%= render 'calendar_event_fields', f: event %>
- <% end %>
-
-
<%= link_to_add_association t('.new_event_link'), f, :calendar_events, class: 'btn btn-outline-primary btn-sm' %>
-
- <% end %>
-
- <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
- <%= link_to_back(:back) %>
-
- <% end %>
-
-
-
-
-
-<%= javascript_include_tag 'shared/cocoon' %>
-<%= render 'select2' %>
-
-
\ No newline at end of file
diff --git a/app/views/calendar/academic_calendars/_select2.html.erb b/app/views/calendar/academic_calendars/_select2.html.erb
deleted file mode 100644
index 159bbc742..000000000
--- a/app/views/calendar/academic_calendars/_select2.html.erb
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/app/views/calendar/academic_calendars/edit.html.erb b/app/views/calendar/academic_calendars/edit.html.erb
deleted file mode 100644
index f10199059..000000000
--- a/app/views/calendar/academic_calendars/edit.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', academic_calendar: @academic_calendar, form_title: t('.form_title') %>
diff --git a/app/views/calendar/academic_calendars/index.html.erb b/app/views/calendar/academic_calendars/index.html.erb
deleted file mode 100644
index 8b02a8dd1..000000000
--- a/app/views/calendar/academic_calendars/index.html.erb
+++ /dev/null
@@ -1,55 +0,0 @@
-
- <%= link_to_new(new_academic_calendar_path, t('.new_academic_calendar_link')) %>
-
-
-
-
-
-
-
- <%= render 'components/smart_search_form',
- path: academic_calendars_path,
- placeholder: t('.name') %>
-
-
-
- <%= t('.name') %>
- <%= t('.academic_term') %>
- <%= t('.calendar_type') %>
- <%= t('.senate_decision_date') %>
- <%= t('.senate_decision_no') %>
- <%= t('created_at') %>
- <%= t('updated_at') %>
- <%= t('actions') %>
-
-
-
- <% @academic_calendars.each do |academic_calendar| %>
-
- <%= academic_calendar.name %>
- <%= full_name(academic_calendar.academic_term) %>
- <%= academic_calendar.calendar_type.name %>
- <%= academic_calendar.senate_decision_date %>
- <%= academic_calendar.senate_decision_no %>
- <%= academic_calendar.created_at.to_date %>
- <%= academic_calendar.updated_at.to_date %>
-
- <%= link_to_show(academic_calendar_path(academic_calendar)) %>
- <%= link_to_edit(edit_academic_calendar_path(academic_calendar)) %>
- <%= link_to_destroy(academic_calendar) %>
-
-
- <% end %>
-
-
-
-
-
-
-
-
-
diff --git a/app/views/calendar/academic_calendars/new.html.erb b/app/views/calendar/academic_calendars/new.html.erb
deleted file mode 100644
index f10199059..000000000
--- a/app/views/calendar/academic_calendars/new.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', academic_calendar: @academic_calendar, form_title: t('.form_title') %>
diff --git a/app/views/calendar/academic_calendars/show.html.erb b/app/views/calendar/academic_calendars/show.html.erb
deleted file mode 100644
index 33342b481..000000000
--- a/app/views/calendar/academic_calendars/show.html.erb
+++ /dev/null
@@ -1,70 +0,0 @@
-
- <%= link_to_back(:back) %>
-
-
-
-
-
-
-
-
-
-
- <%= t('.name') %>
- <%= t('.calendar_type') %>
- <%= t('.senate_decision_date') %>
- <%= t('.senate_decision_no') %>
- <%= t('created_at') %>
- <%= t('updated_at') %>
- <%= t('actions') %>
-
-
-
-
- <%= full_name(@academic_calendar.academic_term) %>
- <%= @academic_calendar.type_name %>
- <%= @academic_calendar.senate_decision_date %>
- <%= @academic_calendar.senate_decision_no %>
- <%= @academic_calendar.created_at.to_date %>
- <%= @academic_calendar.updated_at.to_date %>
- <%= link_to_edit(edit_academic_calendar_path(@academic_calendar)) %>
-
-
-
- <%= t('.description') %>: <%= @academic_calendar.description %>
-
-
-
-
-
-
-
-
-
-
- <%= t('.event_title') %>
- <%= t('.event_start_date') %>
- <%= t('.event_end_date') %>
-
-
-
- <% @events.each do |event| %>
-
- <%= event.calendar_title_name %>
- <%= event.start_date.strftime('%F %T') %>
- <%= event.end_date.try(:strftime, '%F %T') %>
-
- <% end %>
-
-
-
-
-
-
-
-
-
diff --git a/app/views/calendar/academic_terms/index.html.erb b/app/views/calendar/academic_terms/index.html.erb
deleted file mode 100644
index e5f91fb07..000000000
--- a/app/views/calendar/academic_terms/index.html.erb
+++ /dev/null
@@ -1,47 +0,0 @@
-
- <%= link_to_new(new_academic_term_path, t('.new_academic_term_link')) %>
-
-
-
-
-
-
-
-
-
-
- <%= t('.year') %>
- <%= t('.term') %>
- <%= t('.start_of_term') %>
- <%= t('.end_of_term') %>
- <%= t('.active') %>
- <%= t('actions') %>
-
-
-
- <% @academic_terms.each do |academic_term| %>
-
- <%= academic_term.year %>
- <%= enum_t(academic_term, :term) %>
- <%= academic_term.start_of_term.try(:strftime, '%F %T') %>
- <%= academic_term.end_of_term.try(:strftime, '%F %T') %>
- <%= academic_term.active? ? t('active') : t('passive') %>
-
- <%= link_to_edit(edit_academic_term_path(academic_term)) %>
- <%= link_to_destroy(academic_term) %>
-
-
- <% end %>
-
-
-
-
-
-
-
-
-
diff --git a/app/views/calendar/calendar_titles/_form.html.erb b/app/views/calendar/calendar_titles/_form.html.erb
deleted file mode 100644
index abee67662..000000000
--- a/app/views/calendar/calendar_titles/_form.html.erb
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
- <%= simple_form_for(calendar_title) do |f| %>
-
-
- <%= f.error_notification %>
- <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
-
-
-
-
-
- <%= f.association :types, as: :check_boxes %>
-
-
- <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
- <%= link_to_back(:back) %>
-
-
- <% end %>
-
-
-
-
diff --git a/app/views/calendar/calendar_titles/edit.html.erb b/app/views/calendar/calendar_titles/edit.html.erb
deleted file mode 100644
index 43055b35c..000000000
--- a/app/views/calendar/calendar_titles/edit.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', calendar_title: @calendar_title, form_title: t('.form_title') %>
diff --git a/app/views/calendar/calendar_titles/index.html.erb b/app/views/calendar/calendar_titles/index.html.erb
deleted file mode 100644
index 76886f9ac..000000000
--- a/app/views/calendar/calendar_titles/index.html.erb
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
- <%= render 'components/smart_search_form',
- path: calendar_titles_path,
- placeholder: t('.name') %>
-
-
-
- <%= t('.name') %>
- <%= t('.type') %>
- <%= t('actions') %>
-
-
-
- <% @calendar_titles.each do |calendar_title| %>
-
- <%= calendar_title.name %>
- <%= calendar_title.types.map(&:name).join(', ') %>
-
- <%= link_to_edit(edit_calendar_title_path(calendar_title), t('.select_calendar_type')) %>
-
-
- <% end %>
-
-
-
-
-
-
-
-
-
diff --git a/app/views/calendar/calendar_titles/new.html.erb b/app/views/calendar/calendar_titles/new.html.erb
deleted file mode 100644
index 43055b35c..000000000
--- a/app/views/calendar/calendar_titles/new.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', calendar_title: @calendar_title, form_title: t('.form_title') %>
diff --git a/app/views/calendar/calendar_types/_form.html.erb b/app/views/calendar/calendar_types/_form.html.erb
deleted file mode 100644
index bedcc1a81..000000000
--- a/app/views/calendar/calendar_types/_form.html.erb
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
- <%= simple_form_for(calendar_type) do |f| %>
-
-
- <%= f.error_notification %>
- <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
-
-
- <%= f.input :name %>
-
-
- <%= f.association :unit_types, as: :check_boxes %>
-
-
- <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
- <%= link_to_back(:back) %>
-
-
- <% end %>
-
-
-
-
diff --git a/app/views/calendar/calendar_types/edit.html.erb b/app/views/calendar/calendar_types/edit.html.erb
deleted file mode 100644
index 281a1ef3d..000000000
--- a/app/views/calendar/calendar_types/edit.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', calendar_type: @calendar_type, form_title: t('.form_title') %>
diff --git a/app/views/calendar/calendar_types/index.html.erb b/app/views/calendar/calendar_types/index.html.erb
deleted file mode 100644
index b16e266ab..000000000
--- a/app/views/calendar/calendar_types/index.html.erb
+++ /dev/null
@@ -1,40 +0,0 @@
-
- <%= link_to_new(new_calendar_type_path, t('.new_calendar_type_link')) %>
-
-
-
-
-
-
-
-
-
-
- <%= t('.name') %>
- <%= t('actions') %>
-
-
-
- <% @calendar_types.each do |calendar_type| %>
-
- <%= calendar_type.name %>
-
- <%= link_to_show(calendar_type_path(calendar_type)) %>
- <%= link_to_edit(edit_calendar_type_path(calendar_type)) %>
- <%= link_to_destroy(calendar_type) %>
-
-
- <% end %>
-
-
-
-
-
-
-
-
-
diff --git a/app/views/calendar/calendar_types/new.html.erb b/app/views/calendar/calendar_types/new.html.erb
deleted file mode 100644
index 281a1ef3d..000000000
--- a/app/views/calendar/calendar_types/new.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', calendar_type: @calendar_type, form_title: t('.form_title') %>
diff --git a/app/views/calendar/calendar_types/show.html.erb b/app/views/calendar/calendar_types/show.html.erb
deleted file mode 100644
index dde3be3da..000000000
--- a/app/views/calendar/calendar_types/show.html.erb
+++ /dev/null
@@ -1,45 +0,0 @@
-
- <%= link_to_back calendar_types_path %>
-
-
-
-
-
-
-
-
-
-
- <%= t('.unit_types') %>
- <%= @calendar_type.unit_types.map(&:name).join(', ')%>
-
-
-
-
-
-
-
-
-
- <%= t('.calendar_titles') %>
-
-
-
- <% @titles.each do |title| %>
-
- <%= title.name %>
-
- <% end %>
-
-
-
-
-
-
-
-
-
diff --git a/app/views/calendar_management/calendar_event_types/_form.html.erb b/app/views/calendar_management/calendar_event_types/_form.html.erb
new file mode 100644
index 000000000..9aa357340
--- /dev/null
+++ b/app/views/calendar_management/calendar_event_types/_form.html.erb
@@ -0,0 +1,21 @@
+<%= render 'layouts/builders/form',
+ namespace: 'calendar_management',
+ klass: @calendar_event_type,
+ params: [
+ {
+ field: 'name',
+ width: 12,
+ required: true
+ },
+ {
+ field: 'category',
+ width: 12,
+ required: true,
+ collection: CalendarEventType.categories.keys.sort
+ },
+ {
+ field: 'identifier',
+ width: 12,
+ required: true
+ }
+ ] %>
diff --git a/app/views/calendar_management/calendar_event_types/edit.html.erb b/app/views/calendar_management/calendar_event_types/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/calendar_management/calendar_event_types/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/calendar_management/calendar_event_types/index.html.erb b/app/views/calendar_management/calendar_event_types/index.html.erb
new file mode 100644
index 000000000..68b686ba6
--- /dev/null
+++ b/app/views/calendar_management/calendar_event_types/index.html.erb
@@ -0,0 +1,8 @@
+<%= render 'layouts/builders/index',
+ namespace: 'calendar_management',
+ klass: 'calendar_event_type',
+ collection: @calendar_event_types,
+ pagy: @pagy,
+ card_header: t('.card_header'),
+ params: ['name', 'category', 'identifier'],
+ actions: ['edit', 'destroy'] %>
diff --git a/app/views/calendar_management/calendar_event_types/new.html.erb b/app/views/calendar_management/calendar_event_types/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/calendar_management/calendar_event_types/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/calendar_management/calendars/_calendar_event_fields.html.erb b/app/views/calendar_management/calendars/_calendar_event_fields.html.erb
new file mode 100644
index 000000000..b05761795
--- /dev/null
+++ b/app/views/calendar_management/calendars/_calendar_event_fields.html.erb
@@ -0,0 +1,40 @@
+
+
+
+
+
+ <%= f.input :calendar_event_type_id, required: true,
+ collection: CalendarEventType.order(:name),
+ input_html: { class: 'select_search_class' } %>
+
+
+ <%= f.input :start_time, required: true,
+ as: :date_time_picker,
+ input_html: { data: { class: 'event-date'} } %>
+
+
+ <%= f.input :end_time, required: true,
+ as: :date_time_picker,
+ input_html: { data: { class: 'event-date'} } %>
+
+
+ <%= f.input :location %>
+
+
+ <%= f.input :timezone, required: true,
+ collection: timezone_list_with_offset,
+ label_method: :first,
+ value_method: :second %>
+
+
+ <%= f.input :visible %>
+
+
+
+
+ <%= link_to_remove_association t('.delete_event'), f, class: 'btn btn-outline-danger btn-sm' %>
+
+
+
+
+
diff --git a/app/views/calendar_management/calendars/_cocoon.html.erb b/app/views/calendar_management/calendars/_cocoon.html.erb
new file mode 100644
index 000000000..a4fda2136
--- /dev/null
+++ b/app/views/calendar_management/calendars/_cocoon.html.erb
@@ -0,0 +1,9 @@
+
diff --git a/app/views/calendar_management/calendars/_flatpickr.html.erb b/app/views/calendar_management/calendars/_flatpickr.html.erb
new file mode 100644
index 000000000..a046fd80f
--- /dev/null
+++ b/app/views/calendar_management/calendars/_flatpickr.html.erb
@@ -0,0 +1,8 @@
+
diff --git a/app/views/calendar_management/calendars/_form.html.erb b/app/views/calendar_management/calendars/_form.html.erb
new file mode 100644
index 000000000..993622a8e
--- /dev/null
+++ b/app/views/calendar_management/calendars/_form.html.erb
@@ -0,0 +1,65 @@
+
+
+
+
+ <%= simple_form_for([:calendar_management, calendar]) do |f| %>
+
+
+ <%= f.error_notification %>
+ <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+
+ <%= f.input :name, required: true %>
+
+
+ <%= f.input :senate_decision_date,
+ as: :date_time_picker,
+ input_html: { data: { class: 'senate_decision_date'} } %>
+
+
+ <%= f.input :senate_decision_no, required: true %>
+
+
+ <%= f.input :timezone, required: true,
+ collection: timezone_list_with_offset,
+ label_method: :first,
+ value_method: :second %>
+
+
+ <%= f.association :academic_term,
+ label_method: lambda { |academic_term| full_name(academic_term) }, value_method: :id %>
+
+
+ <%= f.input :description, as: :text %>
+
+
+
+
+
+
+ <%= f.simple_fields_for :calendar_events do |event| %>
+ <%= render 'calendar_event_fields', f: event %>
+ <% end %>
+
+
+
+
+
+ <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
+ <%= link_to_back(:back) %>
+
+
+ <% end %>
+
+
+
+
+
+<%= javascript_include_tag 'shared/cocoon' %>
+<%= render 'flatpickr' %>
+<%= render 'cocoon' %>
diff --git a/app/views/calendar_management/calendars/edit.html.erb b/app/views/calendar_management/calendars/edit.html.erb
new file mode 100644
index 000000000..dcf991b5b
--- /dev/null
+++ b/app/views/calendar_management/calendars/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form', calendar: @calendar %>
diff --git a/app/views/calendar_management/calendars/index.html.erb b/app/views/calendar_management/calendars/index.html.erb
new file mode 100644
index 000000000..14252cfd7
--- /dev/null
+++ b/app/views/calendar_management/calendars/index.html.erb
@@ -0,0 +1,55 @@
+
+
+
+
+
+ <%= render 'layouts/shared/smart_search_form',
+ path: [:calendar_management, :calendars],
+ placeholder: t('.name') %>
+
+
+
+ <%= t('.name') %>
+ <%= t('.senate_decision_date') %>
+ <%= t('.senate_decision_no') %>
+ <%= t('.timezone') %>
+ <%= t('.academic_term') %>
+ <%= t('actions') %>
+
+
+
+ <% @calendars.each do |calendar| %>
+
+ <%= link_to("[#{full_name(calendar.academic_term)}] - #{calendar.name}", [:calendar_management, calendar]) %>
+ <%= calendar.senate_decision_date %>
+ <%= calendar.senate_decision_no %>
+ <%= calendar.timezone %>
+ <%= full_name(calendar.academic_term) %>
+
+ <%= link_to fa_icon('file-pdf-o'), [:calendar_management, calendar, format: :pdf],
+ class: 'btn btn-outline-primary btn-sm' %>
+ <%= link_to_edit([:edit, :calendar_management, calendar]) %>
+ <%= link_to_destroy([:calendar_management, calendar]) %>
+ <%= link_to fa_icon('university', text: t('.assign_to_units')), [:calendar_management, calendar, :units],
+ class: 'btn btn-outline-primary btn-sm' %>
+ <%= link_to fa_icon('copy', text: t('.duplicate')), [:calendar_management, calendar, :duplicate],
+ class: 'btn btn-outline-primary btn-sm' %>
+
+
+ <% end %>
+
+
+
+
+
+
+
+
+
diff --git a/app/views/calendar_management/calendars/new.html.erb b/app/views/calendar_management/calendars/new.html.erb
new file mode 100644
index 000000000..dcf991b5b
--- /dev/null
+++ b/app/views/calendar_management/calendars/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form', calendar: @calendar %>
diff --git a/app/views/calendar_management/calendars/show.html.erb b/app/views/calendar_management/calendars/show.html.erb
new file mode 100644
index 000000000..c899a2098
--- /dev/null
+++ b/app/views/calendar_management/calendars/show.html.erb
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+ <%= t('.senate_decision_date') %>
+ <%= @calendar.senate_decision_date %>
+
+
+ <%= t('.senate_decision_no') %>
+ <%= @calendar.senate_decision_no %>
+
+
+ <%= t('.timezone') %>
+ <%= @calendar.timezone %>
+
+
+ <%= t('.description') %>
+ <%= @calendar.description %>
+
+
+
+
+
+
+ <%= t('activerecord.attributes.calendar_event_type.name') %>
+ <%= t('activerecord.attributes.calendar_event.start_time') %>
+ <%= t('activerecord.attributes.calendar_event.end_time') %>
+ <%= t('activerecord.attributes.calendar_event.location') %>
+ <%= t('activerecord.attributes.calendar_event.timezone') %>
+
+
+
+ <% @calendar.calendar_events.each do |calendar_event| %>
+
+ <%= calendar_event.type_name %>
+ <%= as_date_and_time(calendar_event.start_time) %>
+ <%= as_date_and_time(calendar_event.end_time) %>
+ <%= calendar_event.location %>
+ <%= calendar_event.timezone %>
+
+ <% end %>
+
+
+
+
+
+
diff --git a/app/views/calendar_management/calendars/show.pdf.erb b/app/views/calendar_management/calendars/show.pdf.erb
new file mode 100644
index 000000000..701c7de3c
--- /dev/null
+++ b/app/views/calendar_management/calendars/show.pdf.erb
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+ <%= t('activerecord.attributes.calendar_event.start_time') %>
+ <%= t('activerecord.attributes.calendar_event.end_time') %>
+ <%= t('activerecord.attributes.calendar_event_type.name') %>
+
+
+
+ <% @calendar.calendar_events.each do |calendar_event| %>
+
+ <%= as_date_and_time(calendar_event.start_time) %>
+ <%= as_date_and_time(calendar_event.end_time) %>
+ <%= calendar_event.type_name %>
+
+ <% end %>
+
+
+
+
+ <%= t('.senate_decision', date: @calendar.senate_decision_date, decision_no: @calendar.senate_decision_no) %>
+
<%= @calendar.description %>
+
+
+
+
+
+
diff --git a/app/views/calendar_management/calendars/units.html.erb b/app/views/calendar_management/calendars/units.html.erb
new file mode 100644
index 000000000..361196540
--- /dev/null
+++ b/app/views/calendar_management/calendars/units.html.erb
@@ -0,0 +1,76 @@
+<%= simple_form_for([:calendar_management, @calendar]) do |f| %>
+
+
+
+
+
+
+
<%= t('.alert_text_general') %>
+
+
+ <%= t('.alert_text_programs') %>
+
+
+ <%= f.error_notification %>
+
+
+
+
+
+
+ <%= f.association :units,
+ collection: Unit.active.faculties.order(:name),
+ as: :check_boxes,
+ label: t('.faculties') %>
+
+
+
+
+
+
+ <%= f.association :units,
+ collection: Unit.active.institutes.order(:name),
+ as: :check_boxes,
+ label: t('.institutes') %>
+
+
+
+
+
+
+ <%= f.association :units,
+ collection: Unit.active.research_centers.order(:name),
+ as: :check_boxes,
+ label: t('.research_centers') %>
+
+
+
+
+
+
+ <%= f.association :units,
+ collection: Unit.active.others.order(:name),
+ as: :check_boxes,
+ label: t('.others') %>
+
+
+
+
+
+
+ <%= f.association :units,
+ collection: Unit.active.programs.order(:name),
+ as: :check_boxes,
+ label_method: :names_depth_cache,
+ label: t('.programs') %>
+
+
+
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/committee/agenda_types/index.html.erb b/app/views/committee/agenda_types/index.html.erb
index 3ea384ccc..45b0f16c5 100644
--- a/app/views/committee/agenda_types/index.html.erb
+++ b/app/views/committee/agenda_types/index.html.erb
@@ -1,5 +1,5 @@
- <%= link_to_new new_agenda_type_path, t('.new_agenda_type_link') %>
+ <%= link_to_new t('.new_agenda_type_link'), new_agenda_type_path %>
@@ -9,7 +9,7 @@
<%= fa_icon 'tags', text: t('.card_header') %>
- <%= render 'components/smart_search_form',
+ <%= render 'layouts/shared/smart_search_form',
path: agenda_types_path,
placeholder: t('.name') %>
diff --git a/app/views/committee/agendas/index.html.erb b/app/views/committee/agendas/index.html.erb
index e14ab6f94..ec1fbe45b 100644
--- a/app/views/committee/agendas/index.html.erb
+++ b/app/views/committee/agendas/index.html.erb
@@ -1,5 +1,5 @@
- <%= link_to_new new_committee_agenda_path(@committee), t('.new_agenda_link') %>
+ <%= link_to_new t('.new_agenda_link'), new_committee_agenda_path(@committee) %>
<%= link_to(fa_icon('archive', text: t('.meetings')),
committee_meetings_path(@committee),
diff --git a/app/views/committee/dashboard/index.html.erb b/app/views/committee/dashboard/index.html.erb
index 24a1b124b..bfbfff881 100644
--- a/app/views/committee/dashboard/index.html.erb
+++ b/app/views/committee/dashboard/index.html.erb
@@ -1,7 +1,3 @@
-
- <%= link_to_new new_unit_path, t('.new_committee_link') %>
-
-
@@ -9,16 +5,14 @@
<%= fa_icon 'cubes', text: t('.card_header') %>
- <%= render 'components/smart_search_form',
+ <%= render 'layouts/shared/smart_search_form',
path: committees_path,
placeholder: t('.name') %>
<%= t('.name') %>
- <%= t('.yoksis_id') %>
<%= t('.detsis_id') %>
- <%= t('.unit_status') %>
<%= t('.unit_type') %>
<%= t('.district') %>
<%= t('actions') %>
@@ -27,10 +21,8 @@
<% @committees.each do |committee| %>
- <%= link_to(committee.name, unit_path(committee)) %>
- <%= committee.yoksis_id %>
+ <%= link_to(committee.names_depth_cache, unit_path(committee)) %>
<%= committee.detsis_id %>
- <%= committee.unit_status.name %>
<%= committee.unit_type.try(:name) %>
<%= committee.district.name %> / <%= committee.district.city.name %>
diff --git a/app/views/committee/decisions/show.html.erb b/app/views/committee/decisions/show.html.erb
index 25fb5c3cd..bd50ce0e2 100644
--- a/app/views/committee/decisions/show.html.erb
+++ b/app/views/committee/decisions/show.html.erb
@@ -39,7 +39,7 @@
diff --git a/app/views/committee/meetings/index.html.erb b/app/views/committee/meetings/index.html.erb
index ce8ac4ac6..86f5298cc 100644
--- a/app/views/committee/meetings/index.html.erb
+++ b/app/views/committee/meetings/index.html.erb
@@ -1,5 +1,5 @@
- <%= link_to_new new_committee_meeting_path(@committee), t('.new_committee_meeting_link') %>
+ <%= link_to_new t('.new_committee_meeting_link'), new_committee_meeting_path(@committee) %>
<%= link_to(fa_icon('tasks', text: t('.agendas')), committee_agendas_path(@committee),
class: 'btn btn-dark btn-sm') %>
diff --git a/app/views/committee/meetings/show.html.erb b/app/views/committee/meetings/show.html.erb
index 8fdea1c26..7ccb215d1 100644
--- a/app/views/committee/meetings/show.html.erb
+++ b/app/views/committee/meetings/show.html.erb
@@ -56,10 +56,10 @@
<%= agenda.decision.try(:decision_no) %>
<% if agenda.decision.present? %>
- <%= link_to_show(committee_meeting_agenda_decision_path(@committee, agenda, agenda.decision), t('.show_decision')) %>
- <%= link_to_edit(edit_committee_meeting_agenda_decision_path(@committee, agenda), t('.update_decision')) %>
+ <%= link_to_show(t('.show_decision'), committee_meeting_agenda_decision_path(@committee, agenda, agenda.decision)) %>
+ <%= link_to_edit(t('.update_decision'), edit_committee_meeting_agenda_decision_path(@committee, agenda)) %>
<% else %>
- <%= link_to_new(new_committee_meeting_agenda_decision_path(@committee, agenda), t('.create_decision')) %>
+ <%= link_to_new(t('.create_decision'), new_committee_meeting_agenda_decision_path(@committee, agenda)) %>
<% end %>
diff --git a/app/views/course_management/available_course_groups/_form.html.erb b/app/views/course_management/available_course_groups/_form.html.erb
new file mode 100644
index 000000000..cfb700a13
--- /dev/null
+++ b/app/views/course_management/available_course_groups/_form.html.erb
@@ -0,0 +1,40 @@
+
+
+
+
+
+ <%= simple_form_for([@available_course, @available_course_group]) do |f| %>
+
+
+ <%= f.error_notification %>
+
+
+ <%= f.input :name, required: true %>
+
+
+ <%= f.input :quota, required: true %>
+
+
+
+
<%= t('.lecturers') %>
+ <%= f.simple_fields_for :lecturers do |lecturer| %>
+ <%= render 'lecturer_fields', f: lecturer %>
+ <% end %>
+
+ <%= link_to_add_association f, :lecturers, class: 'btn btn-success btn-sm' %>
+
+
+
+ <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
+ <%= link_to_back(:back) %>
+
+ <% end %>
+
+
+
+
+
+<%= javascript_include_tag 'shared/cocoon' %>
diff --git a/app/views/course_management/available_course_groups/_lecturer_fields.html.erb b/app/views/course_management/available_course_groups/_lecturer_fields.html.erb
new file mode 100644
index 000000000..116f5e3b4
--- /dev/null
+++ b/app/views/course_management/available_course_groups/_lecturer_fields.html.erb
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ <%= f.association :lecturer, collection: @lecturers, label_method: lambda { |lecturer| full_name(lecturer) } %>
+
+
+ <%= f.input :coordinator, collection: [[t('yes'), true] ,[t('no'), false]] %>
+
+
+
+
+
+
+
diff --git a/app/views/course_management/available_course_groups/edit.html.erb b/app/views/course_management/available_course_groups/edit.html.erb
new file mode 100644
index 000000000..0d5fc7a31
--- /dev/null
+++ b/app/views/course_management/available_course_groups/edit.html.erb
@@ -0,0 +1,2 @@
+<%= render 'form', available_course_group: @available_course_group,
+ form_title: t('.form_title', course: @available_course.name) %>
diff --git a/app/views/course_management/available_course_groups/new.html.erb b/app/views/course_management/available_course_groups/new.html.erb
new file mode 100644
index 000000000..0d5fc7a31
--- /dev/null
+++ b/app/views/course_management/available_course_groups/new.html.erb
@@ -0,0 +1,2 @@
+<%= render 'form', available_course_group: @available_course_group,
+ form_title: t('.form_title', course: @available_course.name) %>
diff --git a/app/views/course_management/available_courses/_evaluation_types.html.erb b/app/views/course_management/available_courses/_evaluation_types.html.erb
new file mode 100644
index 000000000..53281ebc1
--- /dev/null
+++ b/app/views/course_management/available_courses/_evaluation_types.html.erb
@@ -0,0 +1,37 @@
+
+
+
+
+ <% @evaluation_types.each do |evaluation_type| %>
+
+
+
+
+ <%= t('.assessment_method') %>
+ <%= t('.percentage') %>
+
+
+
+ <% evaluation_type.course_assessment_methods.each do |assessment| %>
+
+ <%= assessment.name %>
+ <%= assessment.percentage %>
+
+ <% end %>
+
+
+ <% end %>
+
+
+
diff --git a/app/views/course_management/available_courses/_form.html.erb b/app/views/course_management/available_courses/_form.html.erb
new file mode 100644
index 000000000..f5292f1b9
--- /dev/null
+++ b/app/views/course_management/available_courses/_form.html.erb
@@ -0,0 +1,55 @@
+
+
+
+
+
+ <%= simple_form_for(@available_course) do |f| %>
+ <%= f.error_notification %>
+ <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+ <% if f.object.errors.any? %>
+
+ <% f.object.errors.full_messages.each do |message| %>
+
+ <%= message %>
+
+ <% end %>
+
+ <% end %>
+
+
+ <%= f.association :unit,
+ collection: Unit.active.coursable.order(:name),
+ label_method: :names_depth_cache %>
+
+
+ <%= f.association :curriculum,
+ collection: [*f.object.unit.try(:managed_curriculums)] %>
+
+
+ <%= f.association :coordinator,
+ collection: [*f.object.unit.try(:subtree_employees)],
+ label_method: lambda { |c| full_name(c) } %>
+
+
+ <% if f.object.curriculum %>
+ <% courses = CurriculumDecorator.new(f.object.curriculum)
+ .openable_courses_for_active_term(appends: f.object.course) %>
+ <% end %>
+ <%= f.association :course,
+ collection: [*courses] %>
+
+
+ <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
+ <%= link_to_back(:back) %>
+
+
+ <% end %>
+
+
+
+
+
+<%= render 'js' %>
diff --git a/app/views/course_management/available_courses/_groups.html.erb b/app/views/course_management/available_courses/_groups.html.erb
new file mode 100644
index 000000000..fce2a95e4
--- /dev/null
+++ b/app/views/course_management/available_courses/_groups.html.erb
@@ -0,0 +1,43 @@
+
+
+
+
+ <% @groups.each do |group| %>
+
+
+
+
+ <%= t('.title') %>
+ <%= t('.lecturer') %>
+ <%= t('.coordinator') %>
+
+
+
+ <% group.lecturers.each do |lecturer| %>
+
+ <%= lecturer.title.name %>
+ <%= full_name(lecturer.identities.formal.first) %>
+ <%= icon_for_check(lecturer.coordinator) %>
+
+ <% end %>
+
+
+
+ <%= t('.quota')%>
+ <%= group.quota %>
+
+ <% end %>
+
+
+
diff --git a/app/views/course_management/available_courses/_js.html.erb b/app/views/course_management/available_courses/_js.html.erb
new file mode 100644
index 000000000..72df1546f
--- /dev/null
+++ b/app/views/course_management/available_courses/_js.html.erb
@@ -0,0 +1,42 @@
+
diff --git a/app/views/course_management/available_courses/_search.html.erb b/app/views/course_management/available_courses/_search.html.erb
new file mode 100644
index 000000000..e98334816
--- /dev/null
+++ b/app/views/course_management/available_courses/_search.html.erb
@@ -0,0 +1,90 @@
+
+
+
diff --git a/app/views/course_management/available_courses/edit.html.erb b/app/views/course_management/available_courses/edit.html.erb
new file mode 100644
index 000000000..f7c434741
--- /dev/null
+++ b/app/views/course_management/available_courses/edit.html.erb
@@ -0,0 +1,2 @@
+<%= render 'form', available_course: @available_course,
+ form_title: t('.form_title', course: @available_course.name) %>
diff --git a/app/views/course_management/available_courses/index.html.erb b/app/views/course_management/available_courses/index.html.erb
new file mode 100644
index 000000000..21394d227
--- /dev/null
+++ b/app/views/course_management/available_courses/index.html.erb
@@ -0,0 +1,55 @@
+<%= render 'search' %>
+
+
+
+
+
+
+
+
+
+ <%= t('.unit') %>
+ <%= t('.academic_term') %>
+ <%= t('.curriculum') %>
+ <%= t('.course_code') %>
+ <%= t('.course') %>
+ <%= t('.group_count') %>
+ <%= t('.quota') %>
+ <%= t('actions') %>
+
+
+
+ <% @available_courses.each do |available_course| %>
+
+ <%= available_course.unit.name %>
+ <%= full_name(available_course.academic_term) %>
+ <%= available_course.curriculum.name %>
+ <%= available_course.course.code %>
+ <%= available_course.course.name %>
+ <%= available_course.groups_count %>
+ <%= available_course.groups.sum(:quota) %>
+
+ <%= link_to_show available_course %>
+ <%= link_to_edit [:edit, available_course] %>
+ <%= link_to_destroy available_course %>
+
+
+ <% end %>
+
+
+
+
+
+
+
diff --git a/app/views/course_management/available_courses/new.html.erb b/app/views/course_management/available_courses/new.html.erb
new file mode 100644
index 000000000..01c8515d7
--- /dev/null
+++ b/app/views/course_management/available_courses/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form', available_course: @available_course, form_title: t('.form_title') %>
diff --git a/app/views/course_management/available_courses/show.html.erb b/app/views/course_management/available_courses/show.html.erb
new file mode 100644
index 000000000..1e4b33932
--- /dev/null
+++ b/app/views/course_management/available_courses/show.html.erb
@@ -0,0 +1,45 @@
+
+
+
+ <%= link_to_back available_courses_path %>
+ <%= link_to_edit edit_available_course_path(@available_course) %>
+ <%= link_to_destroy available_course_path(@available_course) %>
+
+
+
+
+
+
+
+
+ <%= t('.unit') %>
+ <%= @available_course.unit_name %>
+ <%= t('.curriculum') %>
+ <%= @available_course.curriculum_name %>
+
+
+ <%= t('.course') %>
+
+ <%= @available_course.name %>
+ T: <%= @available_course.theoric %>
+ P: <%= @available_course.practice %>
+ L: <%= @available_course.laboratory %>
+ K: <%= @available_course.credit %>
+
+ <%= t('.academic_term') %>
+ <%= full_name(@available_course.academic_term) %>
+
+
+ <%= t('.coordinator') %>
+ <%= full_name(@available_course.coordinator) %>
+
+
+
+
+ <%= render 'evaluation_types' %>
+ <%= render 'groups' %>
+
+
+
diff --git a/app/views/course_management/course_evaluation_types/_course_assessment_method_fields.html.erb b/app/views/course_management/course_evaluation_types/_course_assessment_method_fields.html.erb
new file mode 100644
index 000000000..966668242
--- /dev/null
+++ b/app/views/course_management/course_evaluation_types/_course_assessment_method_fields.html.erb
@@ -0,0 +1,17 @@
+
+
+
+
+
+ <%= f.association :assessment_method %>
+
+
+ <%= f.input :percentage, required: true %>
+
+
+
+
+
+
diff --git a/app/views/course_management/course_evaluation_types/_form.html.erb b/app/views/course_management/course_evaluation_types/_form.html.erb
new file mode 100644
index 000000000..843680f2a
--- /dev/null
+++ b/app/views/course_management/course_evaluation_types/_form.html.erb
@@ -0,0 +1,41 @@
+
+
+
+
+
+ <%= simple_form_for([:available_course, evaluation_type], url: url, method: method) do |f| %>
+
+
+ <%= f.error_notification %>
+ <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+
+ <%= f.association :evaluation_type %>
+
+
+ <%= f.input :percentage, required: true %>
+
+
+
<%= t('.assessment_methods') %>
+
+ <%= f.simple_fields_for :course_assessment_methods do |course_assessment| %>
+ <%= render 'course_assessment_method_fields', f: course_assessment %>
+ <% end %>
+
+ <%= link_to_add_association t('.create_assessment_method'), f, :course_assessment_methods, class: 'btn btn-outline-primary btn-sm' %>
+
+
+ <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
+ <%= link_to_back(available_course_path(@available_course)) %>
+
+
+ <% end %>
+
+
+
+
+
+<%= javascript_include_tag 'shared/cocoon' %>
diff --git a/app/views/course_management/course_evaluation_types/edit.html.erb b/app/views/course_management/course_evaluation_types/edit.html.erb
new file mode 100644
index 000000000..0db94703e
--- /dev/null
+++ b/app/views/course_management/course_evaluation_types/edit.html.erb
@@ -0,0 +1,4 @@
+<%= render 'form', evaluation_type: @evaluation_type,
+ form_title: t('.form_title', course: @available_course.name),
+ url: available_course_evaluation_type_path(@available_course, @evaluation_type),
+ method: :patch %>
diff --git a/app/views/course_management/course_evaluation_types/new.html.erb b/app/views/course_management/course_evaluation_types/new.html.erb
new file mode 100644
index 000000000..11002c7aa
--- /dev/null
+++ b/app/views/course_management/course_evaluation_types/new.html.erb
@@ -0,0 +1,4 @@
+<%= render 'form', evaluation_type: @evaluation_type,
+ form_title: t('.form_title', course: @available_course.name),
+ url: available_course_evaluation_types_path(@available_course),
+ method: :post %>
diff --git a/app/views/course_management/course_group_types/index.html.erb b/app/views/course_management/course_group_types/index.html.erb
index a25dae61f..a659f4157 100644
--- a/app/views/course_management/course_group_types/index.html.erb
+++ b/app/views/course_management/course_group_types/index.html.erb
@@ -1,5 +1,5 @@
- <%= link_to_new new_course_group_type_path, t('.new_course_group_type_link') %>
+ <%= link_to_new t('.new_course_group_type_link'), new_course_group_type_path %>
@@ -9,7 +9,7 @@
<%= fa_icon 'tags', text: t('.card_header') %>
- <%= render 'components/smart_search_form',
+ <%= render 'layouts/shared/smart_search_form',
path: course_group_types_path,
placeholder: t('.name') %>
diff --git a/app/views/course_management/course_groups/_form.html.erb b/app/views/course_management/course_groups/_form.html.erb
index a18632a6e..ffb0fffbc 100644
--- a/app/views/course_management/course_groups/_form.html.erb
+++ b/app/views/course_management/course_groups/_form.html.erb
@@ -19,7 +19,7 @@
<%= f.association :unit,
- collection: Unit.active.without_programs.order(:name),
+ collection: Unit.active.academic.without_programs.order(:name),
label_method: :names_depth_cache %>
diff --git a/app/views/course_management/course_groups/_search.html.erb b/app/views/course_management/course_groups/_search.html.erb
new file mode 100644
index 000000000..7bb6d576f
--- /dev/null
+++ b/app/views/course_management/course_groups/_search.html.erb
@@ -0,0 +1,71 @@
+
+
+
diff --git a/app/views/course_management/course_groups/index.html.erb b/app/views/course_management/course_groups/index.html.erb
index 07f422deb..6e24a0f48 100644
--- a/app/views/course_management/course_groups/index.html.erb
+++ b/app/views/course_management/course_groups/index.html.erb
@@ -1,7 +1,9 @@
- <%= link_to_new new_course_group_path, t('.new_course_group_link') %>
+ <%= link_to_new t('.new_course_group_link'), new_course_group_path %>
+<%= render 'search' %>
+
@@ -9,9 +11,6 @@
<%= fa_icon 'tags', text: t('.card_header') %>
- <%= render 'components/smart_search_form',
- path: course_groups_path,
- placeholder: t('.search_placeholder') %>
diff --git a/app/views/course_management/course_types/index.html.erb b/app/views/course_management/course_types/index.html.erb
index 463fbc8b7..0a8c23ca6 100644
--- a/app/views/course_management/course_types/index.html.erb
+++ b/app/views/course_management/course_types/index.html.erb
@@ -1,5 +1,5 @@
- <%= link_to_new new_course_type_path, t('.new_course_type_link') %>
+ <%= link_to_new t('.new_course_type_link'), new_course_type_path %>
@@ -9,7 +9,7 @@
<%= fa_icon 'tags', text: t('.card_header') %>
- <%= render 'components/smart_search_form',
+ <%= render 'layouts/shared/smart_search_form',
path: course_types_path,
placeholder: t('.name') %>
diff --git a/app/views/course_management/courses/index.html.erb b/app/views/course_management/courses/index.html.erb
index 776fc30fb..c218cfd03 100644
--- a/app/views/course_management/courses/index.html.erb
+++ b/app/views/course_management/courses/index.html.erb
@@ -1,5 +1,5 @@
- <%= link_to_new new_course_path, t('.add_new_course') %>
+ <%= link_to_new t('.add_new_course'), new_course_path %>
<%= render 'search' %>
@@ -65,4 +65,4 @@
-
\ No newline at end of file
+
diff --git a/app/views/course_management/curriculum_course_groups/_form.html.erb b/app/views/course_management/curriculum_course_groups/_form.html.erb
index 8a2774b6a..d13207f07 100644
--- a/app/views/course_management/curriculum_course_groups/_form.html.erb
+++ b/app/views/course_management/curriculum_course_groups/_form.html.erb
@@ -6,37 +6,45 @@
<%= form_title %>
- <%= simple_form_for([@semester, @curriculum_course_group]) do |f| %>
+ <%= simple_form_for([@semester, curriculum_course_group]) do |f| %>
<%= f.error_notification %>
<%= f.association :course_group,
- collection: f.object.new_record? ? @semester.available_course_groups : [f.object.course_group] %>
+ collection: [f.object.course_group],
+ include_blank: false,
+ readonly: true %>
<%= f.input :ects %>
+
+
+
+
<%= t('.courses')%>
+
+
<%= f.simple_fields_for :curriculum_courses do |p| %>
<%= p.input :curriculum_semester_id, as: :hidden %>
- <%= p.association :course, collection: f.object.course_group.courses %>
+ <%= p.association :course,
+ collection: [ p.object.course ],
+ include_blank: false,
+ readonly: true %>
<%= p.input :ects %>
<% end %>
-
-
<%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
- <%= link_to_back(:back) %>
<% end %>
-
\ No newline at end of file
+
diff --git a/app/views/course_management/curriculum_course_groups/edit.html.erb b/app/views/course_management/curriculum_course_groups/edit.html.erb
index b84819a40..f224a4b58 100644
--- a/app/views/course_management/curriculum_course_groups/edit.html.erb
+++ b/app/views/course_management/curriculum_course_groups/edit.html.erb
@@ -1 +1,5 @@
-<%= render 'form', semester_course: @semester_course, form_title: t('.form_title') %>
+
+ <%= link_to_back(:back) %>
+
+
+<%= render 'form', curriculum_course_group: @curriculum_course_group, form_title: t('.form_title') %>
diff --git a/app/views/course_management/curriculum_course_groups/new.html.erb b/app/views/course_management/curriculum_course_groups/new.html.erb
index b84819a40..4dcf56d6d 100644
--- a/app/views/course_management/curriculum_course_groups/new.html.erb
+++ b/app/views/course_management/curriculum_course_groups/new.html.erb
@@ -1 +1,33 @@
-<%= render 'form', semester_course: @semester_course, form_title: t('.form_title') %>
+
+ <%= link_to_back(:back) %>
+
+
+<% if @curriculum_course_groups %>
+
+
+
+
+ <% @curriculum_course_groups.each_with_index do |curriculum_course_group, index| %>
+
+ <%= render 'form', curriculum_course_group: curriculum_course_group, form_title: t('.form_title') %>
+
+ <% end %>
+
+<% else %>
+ <%= render 'form', curriculum_course_group: @curriculum_course_group, form_title: t('.form_title') %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/course_management/curriculum_courses/_form.html.erb b/app/views/course_management/curriculum_courses/_form.html.erb
index 3bf088a8a..1e3367cf3 100644
--- a/app/views/course_management/curriculum_courses/_form.html.erb
+++ b/app/views/course_management/curriculum_courses/_form.html.erb
@@ -1,16 +1,21 @@
+
+ <%= link_to_back(:back) %>
+
+
- <%= simple_form_for([@semester, @curriculum_course]) do |f| %>
+ <%= simple_form_for([@semester, curriculum_course]) do |f| %>
<%= f.error_notification %>
- <%= f.association :course, collection: @semester.available_courses(appends: [@curriculum_course.course]) %>
+ <%= f.association :course,
+ collection: @semester.available_courses(appends: [curriculum_course.course]).sort_by(&:name) %>
-
\ No newline at end of file
+
+
+
diff --git a/app/views/course_management/curriculum_courses/edit.html.erb b/app/views/course_management/curriculum_courses/edit.html.erb
index b84819a40..1cea62bab 100644
--- a/app/views/course_management/curriculum_courses/edit.html.erb
+++ b/app/views/course_management/curriculum_courses/edit.html.erb
@@ -1 +1 @@
-<%= render 'form', semester_course: @semester_course, form_title: t('.form_title') %>
+<%= render 'form', curriculum_course: @curriculum_course, form_title: t('.form_title') %>
diff --git a/app/views/course_management/curriculum_courses/new.html.erb b/app/views/course_management/curriculum_courses/new.html.erb
index b84819a40..1cea62bab 100644
--- a/app/views/course_management/curriculum_courses/new.html.erb
+++ b/app/views/course_management/curriculum_courses/new.html.erb
@@ -1 +1 @@
-<%= render 'form', semester_course: @semester_course, form_title: t('.form_title') %>
+<%= render 'form', curriculum_course: @curriculum_course, form_title: t('.form_title') %>
diff --git a/app/views/course_management/curriculums/_curriculum_courses.html.erb b/app/views/course_management/curriculums/_curriculum_courses.html.erb
index 5f9129ced..dc05630dc 100644
--- a/app/views/course_management/curriculums/_curriculum_courses.html.erb
+++ b/app/views/course_management/curriculums/_curriculum_courses.html.erb
@@ -41,9 +41,6 @@
<% end %>
-
- <%= t('.total_ects') %>:
- <%= total_ects %>
-
+ <%= additional_info %>
-
\ No newline at end of file
+
diff --git a/app/views/course_management/curriculums/_form.html.erb b/app/views/course_management/curriculums/_form.html.erb
index aad39c450..a8cf1522d 100644
--- a/app/views/course_management/curriculums/_form.html.erb
+++ b/app/views/course_management/curriculums/_form.html.erb
@@ -33,7 +33,7 @@
<%= f.input :number_of_semesters,
collection: (1..Curriculum::MAX_NUMBER_OF_SEMESTERS),
- selected: 12,
+ selected: 8,
include_blank: false %>
@@ -42,24 +42,25 @@
selected: :periodic,
include_blank: false %>
- <% end %>
-
- <% unless curriculum.new_record? %>
- <%= t('.semesters') %>
-
+ <% else %>
+
+
+
<%= t('.semesters') %>
+
+
+
<%= f.simple_fields_for :semesters do |semester| %>
<%= render 'semester_fields', f: semester %>
<% end %>
-
- <%= link_to_add_association f, :semesters, class: 'btn btn-success btn-sm' %>
+
+
+ <%= link_to_add_association f, :semesters, class: 'btn btn-primary btn-sm pull-right' %>
+ <% end %>
+
+
+ <%= f.button :submit, class: 'btn btn-outline-success' %>
- <% end %>
-
-
- <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
-
-
<% end %>
@@ -67,4 +68,4 @@
<%= render 'select2' %>
-<%= javascript_include_tag 'shared/cocoon' %>
\ No newline at end of file
+<%= javascript_include_tag 'shared/cocoon' %>
diff --git a/app/views/course_management/curriculums/_search.html.erb b/app/views/course_management/curriculums/_search.html.erb
index c52d6b14f..f0ab188ea 100644
--- a/app/views/course_management/curriculums/_search.html.erb
+++ b/app/views/course_management/curriculums/_search.html.erb
@@ -36,7 +36,7 @@
<%= label_tag(:unit_id, t('.unit')) %>
<%= select_tag(:unit_id,
- options_from_collection_for_select(Unit.active.departments.order(:name), :id, :name, params[:unit_id]),
+ options_from_collection_for_select(Unit.active.departments.order(:name), :id, :names_depth_cache, params[:unit_id]),
include_blank: true,
class: 'form-control') %>
diff --git a/app/views/course_management/curriculums/_semester_fields.html.erb b/app/views/course_management/curriculums/_semester_fields.html.erb
index 48ba7b8f9..a5cc0d319 100644
--- a/app/views/course_management/curriculums/_semester_fields.html.erb
+++ b/app/views/course_management/curriculums/_semester_fields.html.erb
@@ -1,19 +1,26 @@
-
-
-
-
-
-
- <%= f.input :sequence, collection: (1..Curriculum::MAX_NUMBER_OF_SEMESTERS), include_blank: false %>
-
-
- <%= f.input :year, collection: (1..Curriculum::MAX_NUMBER_OF_YEARS), include_blank: false %>
-
+
+
+
+ <%= link_to_remove_association f do %>
+ <%= button_tag('x', type: 'button', class: 'close', data: { confirm: t('are_you_sure') }) %>
+ <% end %>
+
+
+ <%= f.input :sequence,
+ collection: (1..Curriculum::MAX_NUMBER_OF_SEMESTERS),
+ include_blank: false %>
+
+
+ <%= f.input :year,
+ collection: (1..Curriculum::MAX_NUMBER_OF_YEARS),
+ include_blank: false %>
+
+
+ <%= f.input :term,
+ collection: enum_options_for_select(f.object.class, :term),
+ include_blank: false %>
-
-
-
\ No newline at end of file
+
diff --git a/app/views/course_management/curriculums/_semesters.html.erb b/app/views/course_management/curriculums/_semesters.html.erb
index c6ce8b2c1..3abcd5a28 100644
--- a/app/views/course_management/curriculums/_semesters.html.erb
+++ b/app/views/course_management/curriculums/_semesters.html.erb
@@ -3,10 +3,10 @@
@@ -16,32 +16,39 @@
actions: nil,
title: t('.compulsory_courses'),
semester: semester,
- courses: semester.curriculum_courses.compulsory,
- total_ects: semester.curriculum_courses.compulsory.sum(:ects),
- action_visible: true %>
+ courses: semester.curriculum_courses.compulsory.order('courses.name'),
+ action_visible: true,
+ additional_info: "
+ #{t('.total_ects')}
+ #{semester.curriculum_courses.compulsory.sum(:ects)}
+
".html_safe
+ %>
<% semester.curriculum_course_groups.each do |curriculum_course_group| %>
<%= render 'curriculum_courses',
klass: 'border-warning',
actions: safe_join([
- link_to_edit(edit_curriculum_semester_curriculum_course_group_path(semester, curriculum_course_group)),
+ link_to_edit(edit_curriculum_semester_curriculum_course_group_path(semester, curriculum_course_group)),
link_to_destroy([semester, curriculum_course_group])
],
' '
),
title: "#{t('.elective_courses')} - #{curriculum_course_group.name}",
semester: semester,
- courses: curriculum_course_group.curriculum_courses,
- total_ects: curriculum_course_group.ects,
- action_visible: false %>
+ courses: curriculum_course_group.curriculum_courses.order('courses.name'),
+ action_visible: false,
+ additional_info: "
+ #{t('.selectable_total_ects')}
+ #{curriculum_course_group.ects}
+
".html_safe %>
<% end %>
<% end %>
-
\ No newline at end of file
+
diff --git a/app/views/course_management/curriculums/index.html.erb b/app/views/course_management/curriculums/index.html.erb
index 576f74d9c..f27cff908 100644
--- a/app/views/course_management/curriculums/index.html.erb
+++ b/app/views/course_management/curriculums/index.html.erb
@@ -1,5 +1,5 @@
- <%= link_to_new new_curriculum_path, t('.add_new_curriculum') %>
+ <%= link_to_new t('.add_new_curriculum'), new_curriculum_path %>
<%= render 'search' %>
@@ -45,4 +45,4 @@
-
\ No newline at end of file
+
diff --git a/app/views/devise/mailer/email_changed.html.erb b/app/views/devise/mailer/email_changed.html.erb
index 0b1f51da6..5693962b1 100644
--- a/app/views/devise/mailer/email_changed.html.erb
+++ b/app/views/devise/mailer/email_changed.html.erb
@@ -1,4 +1,4 @@
<%= t('devise.mailer.common.hello', mail: @email) %>
-<%= t('.body', support_mail: Rails.application.config.tenant.email.support) %>
+<%= t('.body', support_mail: Tenant.configuration.email.support) %>
<%= t('.new_mail', mail: @resource.email) %>
diff --git a/app/views/devise/mailer/password_change.html.erb b/app/views/devise/mailer/password_change.html.erb
index c8d8f1c70..125d79ce1 100644
--- a/app/views/devise/mailer/password_change.html.erb
+++ b/app/views/devise/mailer/password_change.html.erb
@@ -1,2 +1,2 @@
<%= t('devise.mailer.common.hello', mail: @resource.email) %>
-<%= t('.body', support_mail: Rails.application.config.tenant.email.support) %>
+<%= t('.body', support_mail: Tenant.configuration.email.support) %>
diff --git a/app/views/documents/_form.html.erb b/app/views/documents/_form.html.erb
deleted file mode 100644
index bb3a76893..000000000
--- a/app/views/documents/_form.html.erb
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
- <%= simple_form_for(document) do |f| %>
-
-
- <%= f.error_notification %>
-
-
- <%= f.input :name, required: true %>
-
-
- <%= f.input :statement %>
-
-
- <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
- <%= link_to_back(:back) %>
-
-
- <% end %>
-
-
-
-
diff --git a/app/views/documents/edit.html.erb b/app/views/documents/edit.html.erb
deleted file mode 100644
index 8a2de799d..000000000
--- a/app/views/documents/edit.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', document: @document, form_title: t('.form_title') %>
diff --git a/app/views/documents/index.html.erb b/app/views/documents/index.html.erb
deleted file mode 100644
index aff3e3931..000000000
--- a/app/views/documents/index.html.erb
+++ /dev/null
@@ -1,42 +0,0 @@
-
- <%= link_to_new(new_document_path, t('.new_document_link')) %>
-
-
-
-
-
-
-
-
-
-
- <%= t('.name') %>
- <%= t('.statement') %>
- <%= t('actions') %>
-
-
-
- <% @documents.each do |document| %>
-
- <%= document.name %>
- <%= document.statement %>
-
- <%= link_to_show(document_path(document)) %>
- <%= link_to_edit(edit_document_path(document)) %>
- <%= link_to_destroy(document) %>
-
-
- <% end %>
-
-
-
-
-
-
-
-
-
diff --git a/app/views/documents/new.html.erb b/app/views/documents/new.html.erb
deleted file mode 100644
index 8a2de799d..000000000
--- a/app/views/documents/new.html.erb
+++ /dev/null
@@ -1 +0,0 @@
-<%= render 'form', document: @document, form_title: t('.form_title') %>
diff --git a/app/views/documents/show.html.erb b/app/views/documents/show.html.erb
deleted file mode 100644
index beb68aa7b..000000000
--- a/app/views/documents/show.html.erb
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
- <%= t('.name') %>
- <%= @document.name %>
-
-
- <%= t('.statement') %>
- <%= @document.statement %>
-
-
-
-
-
-
-
diff --git a/app/views/first_registration/prospective_students/_js_for_registration_button.html.erb b/app/views/first_registration/prospective_students/_js_for_registration_button.html.erb
new file mode 100644
index 000000000..b33513fd0
--- /dev/null
+++ b/app/views/first_registration/prospective_students/_js_for_registration_button.html.erb
@@ -0,0 +1,18 @@
+<% unless @prospective_student.registered %>
+
+<% end %>
diff --git a/app/views/first_registration/prospective_students/_search.html.erb b/app/views/first_registration/prospective_students/_search.html.erb
new file mode 100644
index 000000000..9d483bbf3
--- /dev/null
+++ b/app/views/first_registration/prospective_students/_search.html.erb
@@ -0,0 +1,133 @@
+
+
+
+
diff --git a/app/views/first_registration/prospective_students/index.html.erb b/app/views/first_registration/prospective_students/index.html.erb
new file mode 100644
index 000000000..738f9457f
--- /dev/null
+++ b/app/views/first_registration/prospective_students/index.html.erb
@@ -0,0 +1,49 @@
+
+
+
+
+
+ <%= render 'search' %>
+
+
+
+ <%= t('.id_number') %>
+ <%= t('.first_name') %>
+ <%= t('.last_name') %>
+ <%= t('.unit') %>
+ <%= t('.meb_status') %>
+ <%= t('.military_status') %>
+ <%= t('.obs_status') %>
+ <%= t('.student_entrance_type') %>
+ <%= t('actions') %>
+
+
+
+ <% @prospective_students.each do |prospective_student| %>
+
+ <%= prospective_student.id_number %>
+ <%= prospective_student.first_name %>
+ <%= prospective_student.last_name %>
+ <%= prospective_student.unit.name %>
+ <%= prospective_student.meb_status ? t('.graduated') : t('.not_graduated_or_unknown') %>
+ <%= prospective_student.military_status ? t('.unproblematic') : t('.must_see_recruiting_office') %>
+ <%= prospective_student.obs_status ? t('.unproblematic') : t('.student_in_a_different_unit') %>
+ <%= prospective_student.student_entrance_type.try(:name) %>
+
+ <%= link_to_show([:first_registration, prospective_student]) %>
+
+
+ <% end %>
+
+
+
+
+
+
+
+
+
diff --git a/app/views/first_registration/prospective_students/show.html.erb b/app/views/first_registration/prospective_students/show.html.erb
new file mode 100644
index 000000000..9d4e22a5a
--- /dev/null
+++ b/app/views/first_registration/prospective_students/show.html.erb
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
+ <%= t('.student_entrance_type') %>
+ <%= @prospective_student.student_entrance_type.try(:name) %>
+
+
+ <%= t('.unit') %>
+ <%= @prospective_student.unit.names_depth_cache %>
+
+
+ <%= t('.meb_status') %>
+
+ <%= @prospective_student.meb_status ? t('.graduated') : t('.not_graduated_or_unknown') %>
+ <%= t('.last_update') %>: <%= as_date_and_time(@prospective_student.meb_status_date) %>
+
+
+
+ <%= t('.military_status') %>
+
+ <%= @prospective_student.military_status ? t('.unproblematic') : t('.must_see_recruiting_office') %>
+ <%= t('.last_update') %>: <%= as_date_and_time(@prospective_student.military_status_date) %>
+
+
+
+ <%= t('.obs_status') %>
+
+ <%= @prospective_student.obs_status ? t('.unproblematic') : t('.student_in_a_different_unit') %>
+ <%= t('.last_update') %>: <%= as_date_and_time(@prospective_student.obs_status_date) %>
+ <% if @prospective_student.obs_registered_program %>
+
+ <%= fa_icon 'exclamation-triangle' %>
+ <%= t('.registered_to', program: @prospective_student.obs_registered_program) %>
+
+ <% end %>
+
+
+ <% unless @prospective_student.registered %>
+ <% @prospective_student.unit.registration_documents.each do |registration_document| %>
+
+ <%= registration_document.name %>
+
+
+
+
+
+
+
+ <% end %>
+ <% end %>
+
+
+
+
+ <% unless @prospective_student.registered %>
+
+ <% end %>
+
+
+
+
+
+
+
+
+
+ <%= t('.id_number') %>
+ <%= @prospective_student.id_number %>
+
+
+ <%= t('.first_name') %>
+ <%= @prospective_student.first_name %>
+
+
+ <%= t('.last_name') %>
+ <%= @prospective_student.last_name %>
+
+
+ <%= t('.date_of_birth') %>
+ <%= @prospective_student.date_of_birth %>
+
+
+ <%= t('.fathers_name') %>
+ <%= @prospective_student.fathers_name %>
+
+
+ <%= t('.mothers_name') %>
+ <%= @prospective_student.mothers_name %>
+
+
+ <%= t('.gender') %>
+ <%= enum_t(@prospective_student, :gender) %>
+
+
+ <%= t('.nationality') %>
+ <%= @prospective_student.nationality %>
+
+
+ <%= t('.place_of_birth') %>
+ <%= @prospective_student.place_of_birth %>
+
+
+ <%= t('.registration_city') %>
+ <%= @prospective_student.registration_city %>
+
+
+ <%= t('.registration_district') %>
+ <%= @prospective_student.registration_district %>
+
+
+ <%= t('.state_of_education') %>
+ <%= @prospective_student.state_of_education %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%= t('.high_school_code') %>
+ <%= @prospective_student.high_school_code %>
+
+
+ <%= t('.high_school_type') %>
+ <%= @prospective_student.high_school_type.try(:name) %>
+
+
+ <%= t('.high_school_graduation_year') %>
+ <%= @prospective_student.high_school_graduation_year %>
+
+
+ <%= t('.placement_type') %>
+ <%= enum_t(@prospective_student, :placement_type) %>
+
+
+ <%= t('.exam_score') %>
+ <%= @prospective_student.exam_score %>
+
+
+ <%= t('.language_id') %>
+ <%= @prospective_student.language_id %>
+
+
+ <%= t('.address') %>
+ <%= @prospective_student.address %>
+
+
+ <%= t('.home_phone') %>
+ <%= @prospective_student.home_phone %>
+
+
+ <%= t('.mobile_phone') %>
+ <%= @prospective_student.mobile_phone %>
+
+
+ <%= t('.email') %>
+ <%= @prospective_student.email %>
+
+
+ <%= t('.student_disability_type_id') %>
+ <%= @prospective_student.student_disability_type_id %>
+
+
+ <%= t('.top_student') %>
+ <%= @prospective_student.top_student ? t('yes') : t('no') %>
+
+
+ <%= t('.placement_score') %>
+ <%= @prospective_student.placement_score %>
+
+
+ <%= t('.placement_rank') %>
+ <%= @prospective_student.placement_rank %>
+
+
+ <%= t('.preference_order') %>
+ <%= @prospective_student.preference_order %>
+
+
+ <%= t('.placement_score') %>
+ <%= @prospective_student.placement_score %>
+
+
+ <%= t('.additional_score') %>
+ <%= @prospective_student.additional_score %>
+
+
+
+
+
+
+
+
+<%= render 'js_for_registration_button' %>
diff --git a/app/views/first_registration/registration_documents/_form.html.erb b/app/views/first_registration/registration_documents/_form.html.erb
new file mode 100644
index 000000000..4d0500d6a
--- /dev/null
+++ b/app/views/first_registration/registration_documents/_form.html.erb
@@ -0,0 +1,37 @@
+<%= render 'layouts/builders/form',
+ namespace: 'first_registration',
+ klass: @registration_document,
+ params: [
+ {
+ field: 'unit_id',
+ width: 12,
+ required: true,
+ collection: Unit.active.academic.order(:name),
+ label_method: 'names_depth_cache'
+ },
+ {
+ field: 'document_type_id',
+ width: 12,
+ required: true,
+ collection: DocumentType.order(:name)
+ },
+ {
+ field: 'academic_term_id',
+ collection: AcademicTerm.select(
+ :id, :year, :term
+ ).map{|record| [record.year + ' ' + enum_t(record, :term), record.id]},
+ width: 12,
+ required: true
+ },
+ {
+ as: 'text',
+ field: 'description',
+ width: 12
+ },
+ ] %>
+
+
diff --git a/app/views/first_registration/registration_documents/edit.html.erb b/app/views/first_registration/registration_documents/edit.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/first_registration/registration_documents/edit.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/first_registration/registration_documents/index.html.erb b/app/views/first_registration/registration_documents/index.html.erb
new file mode 100644
index 000000000..3c35bf497
--- /dev/null
+++ b/app/views/first_registration/registration_documents/index.html.erb
@@ -0,0 +1,47 @@
+
+
+
+
+
+ <%= render 'layouts/shared/smart_search_form',
+ path: [:first_registration, :registration_documents],
+ placeholder: t('.placeholder') %>
+
+
+
+ <%= t('.academic_term_id') %>
+ <%= t('.unit_id') %>
+ <%= t('.document_type_id') %>
+ <%= t('.description') %>
+ <%= t('actions') %>
+
+
+
+ <% @registration_documents.each do |registration_document| %>
+
+ <%= full_name(registration_document.academic_term) %>
+ <%= registration_document.unit.name %>
+ <%= registration_document.document_type.name %>
+ <%= registration_document.description %>
+
+ <%= link_to_edit([:edit, :first_registration, registration_document]) %>
+ <%= link_to_destroy([:first_registration, registration_document]) %>
+
+
+ <% end %>
+
+
+
+
+
+
+
+
+
diff --git a/app/views/first_registration/registration_documents/new.html.erb b/app/views/first_registration/registration_documents/new.html.erb
new file mode 100644
index 000000000..2d3436368
--- /dev/null
+++ b/app/views/first_registration/registration_documents/new.html.erb
@@ -0,0 +1 @@
+<%= render 'form' %>
diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb
index d2431a4ab..fbbdebd0e 100644
--- a/app/views/home/index.html.erb
+++ b/app/views/home/index.html.erb
@@ -1,3 +1,3 @@
<%= render 'home/templates/admin' %>
-
\ No newline at end of file
+
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index c8f422b6d..152858be1 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -13,7 +13,7 @@
- <%= link_to root_path, class: 'navbar-brand' do %>
+ <%= link_to :root, class: 'navbar-brand' do %>
<%= image_tag 'baum-logo.svg', height: '36', width: '134', alt: 'BAUM Logo', class: 'navbar-brand-full' %>
<% end %>
@@ -29,22 +29,22 @@
- <%= link_to user_identities_path(current_user), class: 'dropdown-item' do %>
+ <%= link_to [:user, :identities, { user_id: current_user.id }], class: 'dropdown-item' do %>
<%= fa_icon('id-card', text: t('.identities')) %>
<% end %>
- <%= link_to user_addresses_path(current_user), class: 'dropdown-item' do %>
+ <%= link_to [:user, :addresses, { user_id: current_user.id }], class: 'dropdown-item' do %>
<%= fa_icon('home', text: t('.addresses')) %>
<% end %>
- <%= link_to user_profile_path(current_user), class: 'dropdown-item' do %>
+ <%= link_to [:user, :profile, {user_id: current_user.id }], class: 'dropdown-item' do %>
<%= fa_icon('user', text: t('.profile_settings')) %>
<% end %>
- <%= link_to edit_user_registration_path, class: 'dropdown-item' do %>
+ <%= link_to %i[edit user registration], class: 'dropdown-item' do %>
<%= fa_icon('shield', text: t('.account_settings')) %>
<% end %>
- <%= link_to destroy_user_session_path, class: "dropdown-item", method: :delete do %>
+ <%= link_to %i[destroy user session], class: "dropdown-item", method: :delete do %>
<%= fa_icon('lock', text: t('.logout')) %>
<% end %>
diff --git a/app/views/layouts/builders/_form.html.erb b/app/views/layouts/builders/_form.html.erb
new file mode 100644
index 000000000..183c13775
--- /dev/null
+++ b/app/views/layouts/builders/_form.html.erb
@@ -0,0 +1,41 @@
+
+
+
+
+ <%= simple_form_for([namespace.try(:to_sym), klass].flatten) do |f| %>
+
+
+ <%= f.error_notification %>
+ <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+ <% params.each do |parameter| %>
+ <%= content_tag :div, class: "form-group col-sm-#{parameter[:width]}" do %>
+ <%= f.input parameter[:field].to_sym,
+ as: parameter[:as].try(:to_sym),
+ required: parameter[:required] || false,
+ collection: parameter[:collection],
+ label: parameter[:label],
+ inline_label: parameter[:inline_label],
+ hint: parameter[:hint],
+ placeholder: parameter[:placeholder],
+ prompt: parameter[:promt],
+ disabled: parameter[:disabled] || false,
+ start_year: parameter[:start_year],
+ end_year: parameter[:end_year],
+ discard_day: parameter[:discard_day],
+ label_method: parameter[:label_method].try(:to_sym),
+ value_method: parameter[:value_method].try(:to_sym),
+ group_method: parameter[:group_method].try(:to_sym),
+ group_label_method: parameter[:group_label_method].try(:to_sym) %>
+ <% end %>
+ <% end %>
+
+ <%= f.button :submit, class: 'btn btn-outline-success btn-sm' %>
+ <%= link_to_back(:back) %>
+
+
+ <% end %>
+
+
+
+
diff --git a/app/views/layouts/builders/_index.html.erb b/app/views/layouts/builders/_index.html.erb
new file mode 100644
index 000000000..cac403c37
--- /dev/null
+++ b/app/views/layouts/builders/_index.html.erb
@@ -0,0 +1,56 @@
+
+
+
+
+
+ <%= render 'layouts/shared/smart_search_form',
+ path: "#{klass.tableize}",
+ placeholder: t("#{namespace}.#{klass.pluralize}.index.name") %>
+
+
+
+ <% params.each do |parameter| %>
+ <%= content_tag :th do %>
+ <%= t("#{namespace}.#{klass.pluralize}.index.#{parameter}") %>
+ <% end %>
+ <% end %>
+ <%= t('actions') %>
+
+
+
+ <% collection.each do |item| %>
+
+ <% params.each do |parameter| %>
+ <% value = item.send(parameter) %>
+ <%= content_tag :td do %>
+ <% enum = item.class.defined_enums.has_key?(parameter) %>
+ <% boolean = [true, false].include?(value) %>
+ <%= (boolean || enum) ? enum_t(item, parameter.to_sym) : value %>
+ <% end %>
+ <% end %>
+
+ <%= link_to_show([namespace.to_sym, item]) if actions.include? 'show' %>
+ <%= link_to_edit([:edit, namespace.to_sym, item]) if actions.include? 'edit' %>
+ <%= link_to_destroy([namespace.to_sym, item]) if actions.include? 'destroy' %>
+
+
+ <% end %>
+
+
+
+
+
+
+
+
+
diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb
index 094ba3976..559aabb3c 100644
--- a/app/views/layouts/mailer.html.erb
+++ b/app/views/layouts/mailer.html.erb
@@ -119,7 +119,7 @@
- Ondokuz Mayıs Üniversitesi, Kurupelit Kampüsü, Atakum/SAMSUN, +9 0362 312 1919
+ <%= Tenant.configuration.contact.address %>, <%= Tenant.configuration.contact.phone %>
@@ -133,4 +133,4 @@