diff --git a/.env.example b/.env.example index 80ab17aa5..f98c69fb8 100644 --- a/.env.example +++ b/.env.example @@ -12,6 +12,7 @@ AMBER_CLIENT_SECRET= FROM_EMAIL=noreply@societeitflux.nl ICT_EMAIL=ict@csvalpha.nl ADMIN_EMAIL=streepsysteem@societeitflux.nl +TREASURER_TITLE=penningmeester TREASURER_EMAIL=penningmeester@societeitflux.nl TREASURER_NAME= TREASURER_PHONE= @@ -28,12 +29,15 @@ COMPANY_KVK=41 032 169 SITE_NAME=S.O.F.I.A. SITE_SHORT_NAME=SOFIA +SITE_LONG_NAME=Streepsysteem voor de Ordentelijke Festiviteiten van Inleggend Alpha SITE_ASSOCIATION=C.S.V. Alpha CODE_BEER=8010 +CODE_LOW_ALCOHOL_BEER=8011 CODE_CRAFT_BEER=8015 CODE_NON_ALCOHOLIC=8020 CODE_DISTILLED=8030 +CODE_WHISKEY=8035 CODE_WINE=8040 CODE_FOOD=8050 CODE_TOBACCO=8060 diff --git a/.github/workflows/cleanup-registry.yml b/.github/workflows/cleanup-registry.yml index ba90d6107..32b82f8df 100644 --- a/.github/workflows/cleanup-registry.yml +++ b/.github/workflows/cleanup-registry.yml @@ -5,20 +5,14 @@ on: - cron: '0 0 * * 1' # https://crontab.guru/#0_0_*_*_1 workflow_dispatch: -env: - IMAGE_NAMES: sofia - jobs: cleanup: name: Cleanup runs-on: ubuntu-latest steps: - - name: Delete old versions - uses: snok/container-retention-policy@f617f1ca161a52bce48417eedd76924e71d0b4d9 # v2.1.0 + - name: Delete untagged images + uses: actions/delete-package-versions@0d39a63126868f5eefaa47169615edd3c0f61e20 # v4.1.1 with: - image-names: ${{ env.IMAGE_NAMES }} - cut-off: 2 days ago UTC - account-type: org - org-name: ${{ github.repository_owner }} - skip-tags: latest,staging - token: ${{ secrets.GH_PAT }} + package-name: ${{ github.event.repository.name }} + package-type: container + delete-only-untagged-versions: true diff --git a/.github/workflows/continuous-delivery.yml b/.github/workflows/continuous-delivery.yml index 441795fa2..738ed981c 100644 --- a/.github/workflows/continuous-delivery.yml +++ b/.github/workflows/continuous-delivery.yml @@ -7,6 +7,13 @@ on: description: Merge staging into master first? (y/N) required: false default: 'n' + target_env: + type: choice + description: Target environment + options: + - csvalpha + - luxadmosam + default: 'csvalpha' concurrency: group: cd-${{ github.ref_name }} @@ -20,11 +27,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Validate branch + env: + TARGET_ENV: ${{ github.event.inputs.target_env }} run: | if [ "$GITHUB_REF_NAME" != 'staging' ] && [ "$GITHUB_REF_NAME" != 'master' ]; then echo 'This workflow can only be run on branches staging and master.' exit 1 fi + if [ "$TARGET_ENV" == 'luxadmosam' ] && [ "$GITHUB_REF_NAME" != 'master' ]; then + echo 'Only the master branch can be deployed to Lux ad Mosam.' + exit 1 + fi metadata: name: Metadata @@ -41,6 +54,7 @@ jobs: id: get_metadata env: INPUT_MERGE: ${{ github.event.inputs.merge }} + TARGET_ENV: ${{ github.event.inputs.target_env }} run: | if [ "$GITHUB_REF_NAME" = 'master' ]; then if [ "${INPUT_MERGE,,}" = 'y' ]; then @@ -52,7 +66,11 @@ jobs: fi fi - echo 'stage=production' >> "$GITHUB_OUTPUT" + if [ "$TARGET_ENV" == 'luxadmosam' ]; then + echo 'stage=luxproduction' >> "$GITHUB_OUTPUT" + else + echo 'stage=production' >> "$GITHUB_OUTPUT" + fi else echo 'stage=staging' >> "$GITHUB_OUTPUT" fi @@ -130,8 +148,12 @@ jobs: steps: - name: Get environment URL id: get_url + env: + TARGET_ENV: ${{ github.event.inputs.target_env }} run: | - if [ "$GITHUB_REF_NAME" = 'master' ]; then + if [ "$TARGET_ENV" == 'luxadmosam' ] && [ "$GITHUB_REF_NAME" = 'master' ]; then + echo 'environment_url=https://luxstreep.csvalpha.nl' >> "$GITHUB_OUTPUT" + elif [ "$GITHUB_REF_NAME" = 'master' ]; then echo 'environment_url=https://streep.csvalpha.nl' >> "$GITHUB_OUTPUT" else echo 'environment_url=https://stagingstreep.csvalpha.nl' >> "$GITHUB_OUTPUT" diff --git a/.rubocop.yml b/.rubocop.yml index 29bf50a25..7e692d4f3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -22,6 +22,7 @@ AllCops: Rails/UnknownEnv: Environments: - production + - luxproduction - development - test - staging diff --git a/Dockerfile b/Dockerfile index fa8dec243..c43ecb67e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,7 @@ ARG RAILS_MASTER_KEY # Pre-install gems, so that they can be cached. COPY Gemfile* /app/ -RUN if [ "$RAILS_ENV" = 'production' ] || [ "$RAILS_ENV" = 'staging' ]; then \ +RUN if [ "$RAILS_ENV" = 'production' ] || [ "$RAILS_ENV" = 'staging' ] || [ "$RAILS_ENV" = 'luxproduction' ]; then \ bundle config set --local without 'development test'; \ else \ bundle config set --local without 'development'; \ @@ -44,7 +44,7 @@ COPY . /app/ # Precompile assets after copying app because whole Rails pipeline is needed. RUN --mount=type=secret,id=rails_master_key \ - if [ "$RAILS_ENV" = 'production' ] || [ "$RAILS_ENV" = 'staging' ]; then \ + if [ "$RAILS_ENV" = 'production' ] || [ "$RAILS_ENV" = 'staging' ] || [ "$RAILS_ENV" = 'luxproduction' ]; then \ # Use secret if RAILS_MASTER_KEY build arg is not set. RAILS_MASTER_KEY="${RAILS_MASTER_KEY:-$(cat /run/secrets/rails_master_key)}" bundle exec rails assets:precompile; \ else \ diff --git a/Gemfile b/Gemfile index e073ebd83..ba5dd2b0c 100644 --- a/Gemfile +++ b/Gemfile @@ -21,7 +21,7 @@ gem 'omniauth', '~> 2.1.1' gem 'omniauth-oauth2', '~> 1.8.0' gem 'omniauth-rails_csrf_protection', '~> 1.0', '>= 1.0.1' gem 'paper_trail', '~> 14.0.0' -gem 'paranoia', '~> 2.6.1' +gem 'paranoia', '~> 3.0.0' gem 'pg', '~> 1.5.3' gem 'puma', '~> 6.2.2' gem 'pundit', '~> 2.3.0' diff --git a/Gemfile.lock b/Gemfile.lock index 5b315c5fd..c49d9e062 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,7 +100,7 @@ GEM sidekiq (>= 6.0) coderay (1.1.3) colorize (0.8.1) - concurrent-ruby (1.2.2) + concurrent-ruby (1.3.4) connection_pool (2.4.0) consistency_fail (0.3.7) crass (1.0.6) @@ -113,7 +113,7 @@ GEM devise-i18n (1.11.0) devise (>= 4.9.0) diff-lcs (1.5.0) - digest (3.1.0) + digest (3.1.1) docile (1.4.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) @@ -183,7 +183,7 @@ GEM domain_name (~> 0.5) http-form_data (2.3.0) http_parser.rb (0.8.0) - i18n (1.13.0) + i18n (1.14.5) concurrent-ruby (~> 1.0) jbuilder (2.11.5) actionview (>= 5.0.0) @@ -234,7 +234,7 @@ GEM mini_portile2 (2.8.2) mini_racer (0.6.3) libv8-node (~> 16.10.0.0) - minitest (5.18.0) + minitest (5.24.1) mollie-api-ruby (4.7.1) msgpack (1.7.0) multi_json (1.15.0) @@ -290,8 +290,8 @@ GEM activerecord (>= 6.0) request_store (~> 1.4) parallel (1.23.0) - paranoia (2.6.1) - activerecord (>= 5.1, < 7.1) + paranoia (3.0.0) + activerecord (>= 6, < 8.1) parser (3.2.2.1) ast (~> 2.4.1) pg (1.5.3) @@ -497,7 +497,7 @@ GEM tilt (2.1.0) timecop (0.9.5) timeliness (0.4.5) - timeout (0.3.0) + timeout (0.3.1) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) @@ -573,7 +573,7 @@ DEPENDENCIES omniauth-oauth2 (~> 1.8.0) omniauth-rails_csrf_protection (~> 1.0, >= 1.0.1) paper_trail (~> 14.0.0) - paranoia (~> 2.6.1) + paranoia (~> 3.0.0) pg (~> 1.5.3) pry-byebug pry-rails diff --git a/app/assets/stylesheets/price_lists.scss b/app/assets/stylesheets/price_lists.scss index c8cd21f2f..b1ba68630 100644 --- a/app/assets/stylesheets/price_lists.scss +++ b/app/assets/stylesheets/price_lists.scss @@ -1,21 +1,59 @@ @import 'theme_sofia'; -.center-text { - margin: 0 auto; - text-align: center; -} +.price-lists-table { + width: fit-content; + max-height: calc(100vh - 18rem); + + .center-text { + margin: 0 auto; + text-align: center; + } -th { - &.products-id { + .products-id, + .products-cancel-edit { + left: 0; width: 1.75rem; } - &.products-actions { - width: 4rem; + .products-name { + left: 2.1rem; + width: 6rem; + } + + .products-actions, + .products-new-edit-button, + .products-save-new { + right: 0; + } + + .products-id, + .products-cancel-edit, + .products-name, + .products-new-edit-button, + .products-save-new { + position: sticky; + z-index: 1; + background-color: $body-bg; + } + + .products-actions { + position: sticky; + z-index: 1; + } + + thead { + position: sticky; + top: 0; + z-index: 2; + background-color: $body-bg; + } + + th { + &.products-actions { + width: 4rem; + } } -} -.price_lists_table { tr { &:last-child { td { @@ -23,38 +61,39 @@ th { } } } -} -td { - &.products-new-edit-button { - padding: .5rem 1rem; - } - &.products-new { - input { - &.form-control { - width: 6rem; - } + td { + &.products-new-edit-button { + padding: .5rem 1rem; } - select { - &.form-control { - width: 4rem; + &.products-new { + input { + &.form-control { + width: 6rem; + } + } + + select { + &.form-control { + width: 4rem; + } } } - } - &.products-new-price { - input { - &.form-control { - width: 2rem; + &.products-new-price { + input { + &.form-control { + width: 4rem; + } } } - } - &.products-cancel-new, - &.products-cancel-edit, - &.products-save-new { - vertical-align: middle; + &.products-cancel-new, + &.products-cancel-edit, + &.products-save-new { + vertical-align: middle; + } } } diff --git a/app/controllers/credit_mutations_controller.rb b/app/controllers/credit_mutations_controller.rb index 17bba8bbf..4ed43df97 100644 --- a/app/controllers/credit_mutations_controller.rb +++ b/app/controllers/credit_mutations_controller.rb @@ -17,7 +17,7 @@ def create # rubocop:disable Metrics/MethodLength, Metrics/AbcSize respond_to do |format| if @mutation.save - NewCreditMutationNotificationJob.perform_later(@mutation) if Rails.env.production? || Rails.env.staging? + NewCreditMutationNotificationJob.perform_later(@mutation) if Rails.env.production? || Rails.env.staging? || Rails.env.luxproduction? format.html { redirect_to which_redirect?, flash: { success: 'Inleg of mutatie aangemaakt' } } format.json do render json: @mutation, include: { user: { methods: User.orderscreen_json_includes } } diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb index 0be81a169..4f6ed90e6 100644 --- a/app/controllers/payments_controller.rb +++ b/app/controllers/payments_controller.rb @@ -22,9 +22,15 @@ def create # rubocop:disable Metrics/AbcSize end end - def add + def add # rubocop:disable Metrics/AbcSize authorize :payment + if Rails.application.config.x.mollie_api_key.blank? + flash[:error] = 'iDEAL is niet beschikbaar' + redirect_to users_path + return + end + @user = current_user @payment = Payment.new @@ -39,7 +45,9 @@ def callback # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/Pe end if payment.completed? - flash[:error] = 'Deze betaling is al gesloten. Mocht het bedrag niet bij uw inleg staan neem dan contact op met de penningmeester.' + flash[:error] = + "Deze betaling is al gesloten. Mocht het bedrag niet bij uw inleg staan + neem dan contact op met de #{Rails.application.config.x.treasurer_title}" else tries = 3 begin @@ -47,8 +55,8 @@ def callback # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/Pe if payment.mollie_payment.paid? flash[:success] = 'iDEAL betaling geslaagd' else - flash[:error] = 'Uw iDEAL betaling is mislukt. - Mocht het bedrag wel van uw rekening zijn gegaan neem dan contact op met de penningmeester' + flash[:error] = "Uw iDEAL betaling is mislukt. Mocht het bedrag wel van uw rekening zijn gegaan + neem dan contact op met de #{Rails.application.config.x.treasurer_title}" end rescue ActiveRecord::StaleObjectError => e raise e unless (tries -= 1).positive? diff --git a/app/controllers/price_lists_controller.rb b/app/controllers/price_lists_controller.rb index 62c22909d..6a1a02ec3 100644 --- a/app/controllers/price_lists_controller.rb +++ b/app/controllers/price_lists_controller.rb @@ -4,14 +4,14 @@ class PriceListsController < ApplicationController after_action :verify_authorized def index - recent_price_lists = PriceList.order(created_at: :desc).limit(6) + price_lists = PriceList.order(created_at: :desc) products = Product.all.order(:id).includes(:product_prices) - authorize recent_price_lists + authorize price_lists @price_list = PriceList.new - @recent_price_lists_json = recent_price_lists.to_json(except: %i[created_at updated_at deleted_at]) + @price_lists_json = price_lists.to_json(except: %i[created_at updated_at deleted_at]) @products_json = products.to_json( include: { product_prices: { except: %i[created_at updated_at deleted_at] } }, methods: :t_category, @@ -43,6 +43,36 @@ def update redirect_to @price_list end + def archive + @price_list = PriceList.find(params[:id]) + authorize @price_list + + @price_list.archived_at = Time.zone.now + + respond_to do |format| + if @price_list.save + format.json { render json: @price_list.archived_at } + else + format.json { render json: @price_list.errors, status: :unprocessable_entity } + end + end + end + + def unarchive + @price_list = PriceList.find(params[:id]) + authorize @price_list + + @price_list.archived_at = nil + + respond_to do |format| + if @price_list.save + format.json { render json: @price_list.archived_at } + else + format.json { render json: @price_list.errors, status: :unprocessable_entity } + end + end + end + private def permitted_attributes diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 94a4ef7ad..ea3ff35e9 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -117,7 +117,7 @@ def activities # rubocop:disable Metrics/AbcSize private def send_slack_users_refresh_notification - return unless Rails.env.production? || Rails.env.staging? + return unless Rails.env.production? || Rails.env.staging? || Rails.env.luxproduction? # :nocov: SlackMessageJob.perform_later("User ##{current_user.id} (#{current_user.name}) " \ diff --git a/app/javascript/packs/price_lists.js b/app/javascript/packs/price_lists.js index 82fd06a2a..7585ec79d 100644 --- a/app/javascript/packs/price_lists.js +++ b/app/javascript/packs/price_lists.js @@ -8,7 +8,7 @@ Vue.use(VueResource); document.addEventListener('turbolinks:load', () => { Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); - var element = document.getElementById('price_lists_table'); + var element = document.getElementById('pricelists-container'); if (element != null) { var priceLists = JSON.parse(element.dataset.priceLists); var products = JSON.parse(element.dataset.products); @@ -19,7 +19,16 @@ document.addEventListener('turbolinks:load', () => { new Vue({ el: element, data: () => { - return { priceLists: priceLists, products: products }; + return { priceLists: priceLists, products: products, showArchived: false }; + }, + computed: { + filteredPriceLists: function() { + if (this.showArchived) { + return priceLists; + } else { + return priceLists.filter(priceList => !priceList.archived_at); + } + } }, methods: { findPrice: function(product, priceList) { @@ -124,6 +133,22 @@ document.addEventListener('turbolinks:load', () => { return products; }, + archivePriceList: function(priceList) { + this.$http.post(`/price_lists/${priceList.id}/archive`, {}).then((response) => { + priceList.archived_at = response.data; + }, (response) => { + this.errors = response.data.errors; + }); + }, + + unarchivePriceList: function(priceList) { + this.$http.post(`/price_lists/${priceList.id}/unarchive`, {}).then((response) => { + priceList.archived_at = response.data; + }, (response) => { + this.errors = response.data.errors; + }); + }, + productPriceToCurrency: function(productPrice) { return (productPrice && productPrice.price) ? `€ ${parseFloat(productPrice.price).toFixed(2)}` : ''; }, diff --git a/app/jobs/credit_insufficient_notification_job.rb b/app/jobs/credit_insufficient_notification_job.rb index 87b4bd616..fe99065b4 100644 --- a/app/jobs/credit_insufficient_notification_job.rb +++ b/app/jobs/credit_insufficient_notification_job.rb @@ -23,14 +23,14 @@ def users_with_insufficient_credit User.all.select { |user| user.credit.negative? } end - def send_notification_delivery_reports(success_count, unnotifyable_users) + def send_notification_delivery_reports(success_count, unnotifyable_users) # rubocop:disable Metrics/AbcSize User.treasurer.each do |treasurer| UserCreditMailer.credit_delivery_report_mail( treasurer, success_count, unnotifyable_users ).deliver_later end - return unless Rails.env.production? || Rails.env.staging? + return unless Rails.env.production? || Rails.env.staging? || Rails.env.luxproduction? SlackMessageJob.perform_later("Er is voor #{Rails.application.config.x.amber_api_host} een saldomail " \ "verstuurd naar #{success_count} mensen, en #{unnotifyable_users.count} saldomail(s) kon(den) niet " \ diff --git a/app/jobs/payment_poll_job.rb b/app/jobs/payment_poll_job.rb index 4ecee9bd2..de1e5e1cb 100644 --- a/app/jobs/payment_poll_job.rb +++ b/app/jobs/payment_poll_job.rb @@ -9,7 +9,7 @@ def perform # it will be checked again the next time this poll job runs end - return unless Rails.env.production? || Rails.env.staging? + return unless Rails.env.production? || Rails.env.staging? || Rails.env.luxproduction? HealthCheckJob.perform_later('payment_poll') end diff --git a/app/mailers/invoice_mailer.rb b/app/mailers/invoice_mailer.rb index 6db7ee09d..b22410cf3 100644 --- a/app/mailers/invoice_mailer.rb +++ b/app/mailers/invoice_mailer.rb @@ -1,12 +1,16 @@ class InvoiceMailer < ApplicationMailer - def invoice_mail(invoice) # rubocop:disable Metrics/AbcSize + def invoice_mail(invoice) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength @user = Struct.new(:name).new(invoice.name) @invoice = invoice - @cab_link = url_for(controller: 'invoices', action: 'show', id: invoice.token) - @cab_text = 'iDeal betaling' + if Rails.application.config.x.mollie_api_key.present? + @cab_link = url_for(controller: 'invoices', action: 'show', id: invoice.token) + @cab_text = 'iDeal betaling' + else + @cab_disabled = true + end attachments["#{invoice.human_id}.pdf"] = WickedPdf.new.pdf_from_string( - render_to_string(pdf: invoice.human_id.to_s, template: 'invoices/show.html.erb', layout: 'pdf.html.erb') + render_to_string(pdf: invoice.human_id.to_s, template: 'invoices/show', layout: 'pdf') ) mail to: @invoice.email, subject: "Factuur #{invoice.human_id} #{Rails.application.config.x.company_name}" diff --git a/app/models/product.rb b/app/models/product.rb index c01cb05c1..8082251ac 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -1,5 +1,6 @@ class Product < ApplicationRecord - enum category: { beer: 0, craft_beer: 6, non_alcoholic: 1, distilled: 2, wine: 3, food: 4, tobacco: 5, donation: 7 } + enum category: { beer: 0, low_alcohol_beer: 9, craft_beer: 6, non_alcoholic: 1, distilled: 2, whiskey: 8, wine: 3, food: 4, tobacco: 5, + donation: 7 } has_many :product_prices, dependent: :destroy has_many :price_lists, through: :product_prices, dependent: :restrict_with_error @@ -10,7 +11,7 @@ class Product < ApplicationRecord accepts_nested_attributes_for :product_prices, allow_destroy: true def requires_age - %w[beer craft_beer distilled wine tobacco].include? category + %w[beer craft_beer distilled whiskey wine tobacco].include? category end def t_category diff --git a/app/models/role.rb b/app/models/role.rb index afb6680fa..779a9ad66 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -7,7 +7,7 @@ class Role < ApplicationRecord def name if treasurer? - 'Penningmeester' + Rails.application.config.x.treasurer_title.capitalize elsif main_bartender? 'Hoofdtapper' end diff --git a/app/policies/payment_policy.rb b/app/policies/payment_policy.rb index 9d3036a15..aba51a76d 100644 --- a/app/policies/payment_policy.rb +++ b/app/policies/payment_policy.rb @@ -1,17 +1,21 @@ class PaymentPolicy < ApplicationPolicy def index? - user.treasurer? + mollie_enabled? && user.treasurer? end def create? - user + mollie_enabled? && user end def add? - user + mollie_enabled? && user end def invoice_callback? - record && !record.completed? + mollie_enabled? && record && !record.completed? + end + + def mollie_enabled? + Rails.application.config.x.mollie_api_key.present? end end diff --git a/app/policies/price_list_policy.rb b/app/policies/price_list_policy.rb index 4d6d653ec..a28c98dec 100644 --- a/app/policies/price_list_policy.rb +++ b/app/policies/price_list_policy.rb @@ -15,6 +15,14 @@ def update? create? end + def archive? + create? + end + + def unarchive? + create? + end + def search? index? end diff --git a/app/views/activities/_cannot_order_modal.html.erb b/app/views/activities/_cannot_order_modal.html.erb index df30baef1..ad6e47f39 100644 --- a/app/views/activities/_cannot_order_modal.html.erb +++ b/app/views/activities/_cannot_order_modal.html.erb @@ -7,7 +7,7 @@ - - <%= content_tag :table, id: 'price_lists_table', class: 'price_lists_table table table-striped table-responsive-md', - data: {price_lists: @recent_price_lists_json, products: @products_json} do %> +
+ + +
+ + - - @@ -48,23 +54,25 @@ <%= fa_icon 'times lg' %> - - - - - + - <% end %> +
ID Product Categorie +
{{ priceList.name }}
+
+
+
+
@@ -75,15 +83,15 @@
+
+ + +
+<% end %> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 80e03a72c..98868d3a9 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -56,7 +56,7 @@ Accountbron <% if @user.provider == 'amber_oauth2' %> - <%= link_to 'C.S.V. Alpha', "#{Rails.application.config.x.amber_api_url}/users/#{@user.uid}" %> + <%= link_to Rails.application.config.x.site_association, "#{Rails.application.config.x.amber_api_url}/users/#{@user.uid}" %> <% else %> <%= @user.provider || 'Handmatig aangemaakt' %> @@ -107,12 +107,18 @@

- <%= 'Om je saldo aan te vullen kan je zelf geld overmaken of betalen met iDEAL. ' %> + <% if Rails.application.config.x.mollie_api_key.present? %> + Om je saldo aan te vullen kan je zelf geld overmaken of betalen met iDEAL. + <% else %> + Om je saldo aan te vullen kan je zelf geld overmaken. + <% end %> <%= "Dat kan naar #{Rails.application.config.x.company_iban} t.n.v. #{Rails.application.config.x.company_name}" %> <%= 'onder vermelding van je naam en \'Inleg Zatladder\'.' %> - <%= link_to add_payments_path do %> - <%= 'Klik hier om je saldo over te maken via iDEAL ' %> + <% if Rails.application.config.x.mollie_api_key.present? %> + <%= link_to add_payments_path do %> + <%= 'Klik hier om je saldo over te maken via iDEAL ' %> + <% end %> <% end %>

diff --git a/babel.config.js b/babel.config.js index f930f3e0a..7026b3860 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,8 +1,8 @@ module.exports = function(api) { - var validEnv = ['development', 'test', 'production'] + var validEnv = ['development', 'test', 'production', 'luxproduction'] var currentEnv = api.env() var isDevelopmentEnv = api.env('development') - var isProductionEnv = api.env('production') + var isProductionEnv = api.env('production') || api.env('luxproduction') var isTestEnv = api.env('test') if (!validEnv.includes(currentEnv)) { diff --git a/config/application.rb b/config/application.rb index 38ac15da1..9df8e9b67 100644 --- a/config/application.rb +++ b/config/application.rb @@ -52,6 +52,7 @@ class Application < Rails::Application config.x.from_email = ENV.fetch('FROM_EMAIL', 'noreply@example.com') config.x.ict_email = ENV.fetch('ICT_EMAIL', 'ict@example.com') config.x.admin_email = ENV.fetch('ADMIN_EMAIL', 'admin@example.com') + config.x.treasurer_title = ENV.fetch('TREASURER_TITLE', 'penningmeester') config.x.treasurer_email = ENV.fetch('TREASURER_EMAIL', 'treasurer@example.com') config.x.treasurer_name = ENV.fetch('TREASURER_NAME', nil) config.x.treasurer_phone = ENV.fetch('TREASURER_PHONE', nil) @@ -64,18 +65,23 @@ class Application < Rails::Application config.x.site_name = ENV.fetch('SITE_NAME', 'S.O.F.I.A.') config.x.site_short_name = ENV.fetch('SITE_SHORT_NAME', 'SOFIA') + config.x.site_long_name = ENV.fetch('SITE_LONG_NAME', 'Streepsysteem voor de Ordentelijke Festiviteiten van Inleggend Alpha') config.x.site_association = ENV.fetch('SITE_ASSOCIATION', 'C.S.V. Alpha') - config.x.code_beer = ENV.fetch('CODE_BEER', nil) - config.x.code_craft_beer = ENV.fetch('CODE_CRAFT_BEER', nil) - config.x.code_non_alcoholic = ENV.fetch('CODE_NON_ALCOHOLIC', nil) - config.x.code_distilled = ENV.fetch('CODE_DISTILLED', nil) - config.x.code_wine = ENV.fetch('CODE_WINE', nil) - config.x.code_food = ENV.fetch('CODE_FOOD', nil) - config.x.code_tobacco = ENV.fetch('CODE_TOBACCO', nil) - config.x.code_donation = ENV.fetch('CODE_DONATION', nil) - config.x.code_credit_mutation = ENV.fetch('CODE_CREDIT_MUTATION', nil) - config.x.code_cash = ENV.fetch('CODE_CASH', nil) - config.x.code_pin = ENV.fetch('CODE_PIN', nil) + config.x.codes = { + beer: ENV.fetch('CODE_BEER', nil), + low_alcohol_beer: ENV.fetch('CODE_LOW_ALCOHOL_BEER', nil), + craft_beer: ENV.fetch('CODE_CRAFT_BEER', nil), + non_alcoholic: ENV.fetch('CODE_NON_ALCOHOLIC', nil), + distilled: ENV.fetch('CODE_DISTILLED', nil), + whiskey: ENV.fetch('CODE_WHISKEY', nil), + wine: ENV.fetch('CODE_WINE', nil), + food: ENV.fetch('CODE_FOOD', nil), + tobacco: ENV.fetch('CODE_TOBACCO', nil), + donation: ENV.fetch('CODE_DONATION', nil), + credit_mutation: ENV.fetch('CODE_CREDIT_MUTATION', nil), + cash: ENV.fetch('CODE_CASH', nil), + pin: ENV.fetch('CODE_PIN', nil) + } end end diff --git a/config/cable.yml b/config/cable.yml index 76936d94e..23ef1c849 100644 --- a/config/cable.yml +++ b/config/cable.yml @@ -11,3 +11,6 @@ production: &production staging: <<: *production + +luxproduction: + <<: *production diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index 49d52e817..806bcdf6d 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -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--91HDlcGnjRME192Q--FHoijSpGcnpsYnoLQ/cSSw== \ No newline at end of file +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--G8VsFkH0hWoT5VZb--aeMXLt0yLUV+0ugJCIv8TQ== \ No newline at end of file diff --git a/config/database.yml b/config/database.yml index bff914e3f..844eb926f 100644 --- a/config/database.yml +++ b/config/database.yml @@ -20,3 +20,6 @@ production: &production staging: <<: *production + +luxproduction: + <<: *production diff --git a/config/deploy.rb b/config/deploy.rb index dfa5020b6..56439e24e 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -13,3 +13,7 @@ task :production do set :deploy_to, '/opt/docker/sofia/production' end + +task :luxproduction do + set :deploy_to, '/opt/docker/sofia/luxproduction' +end diff --git a/config/environments/luxproduction.rb b/config/environments/luxproduction.rb new file mode 100644 index 000000000..9fe6f5a1d --- /dev/null +++ b/config/environments/luxproduction.rb @@ -0,0 +1,6 @@ +require File.expand_path('production.rb', __dir__) + +Rails.application.configure do + # Only override production when applicable + # Keep in mind that staging should reflect production as close as possible +end diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index 2cf0ec2ac..1504fbdcc 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -1,6 +1,6 @@ Sentry.init do |config| config.dsn = Rails.application.config.x.sentry_dsn - config.enabled_environments = %w[production staging] + config.enabled_environments = %w[production staging luxproduction] config.environment = Rails.env config.release = ENV.fetch('BUILD_HASH', nil) end diff --git a/config/locales/nl.yml b/config/locales/nl.yml index ea74652c3..26fd3301c 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -10,9 +10,11 @@ nl: time_only: '%H:%M' beer: 'bier' + low_alcohol_beer: 'alcoholarm bier' craft_beer: 'speciaalbier' non_alcoholic: 'niet-alcoholisch' distilled: 'gedestilleerd' + whiskey: 'whiskey' wine: 'wijn' food: 'etenswaren' tobacco: 'rookwaren' @@ -26,19 +28,6 @@ nl: expired: 'verlopen' sent: 'verstuurd' - codes: - beer: 8010 - craft_beer: 8015 - non_alcoholic: 8020 - distilled: 8030 - wine: 8040 - food: 8050 - tobacco: 8060 - donation: 2095 - credit_mutation: '0610' - cash: 1000 - pin: 2060 - views: pagination: truncate: "…" diff --git a/config/routes.rb b/config/routes.rb index 18807cd79..94c0d9774 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,7 +12,12 @@ end resources :orders, only: %i[index create update destroy] - resources :price_lists, only: %i[index create update] + resources :price_lists, only: %i[index create update] do + member do + post :archive + post :unarchive + end + end resources :users, only: %i[index show create update] do collection do diff --git a/config/webpack/loaders/eslint.js b/config/webpack/loaders/eslint.js index 340526c6a..507956dbe 100644 --- a/config/webpack/loaders/eslint.js +++ b/config/webpack/loaders/eslint.js @@ -6,6 +6,6 @@ module.exports = { exclude: /node_modules/, loader: 'eslint-loader', options: { - failOnError: env.NODE_ENV !== 'production' + failOnError: env.NODE_ENV !== 'production' && env.NODE_ENV !== 'luxproduction', } }; diff --git a/config/webpack/luxproduction.js b/config/webpack/luxproduction.js new file mode 100644 index 000000000..0ba7561c6 --- /dev/null +++ b/config/webpack/luxproduction.js @@ -0,0 +1,5 @@ +process.env.NODE_ENV = process.env.NODE_ENV || 'luxproduction' + +const environment = require('./environment') + +module.exports = environment.toWebpackConfig() diff --git a/config/webpacker.yml b/config/webpacker.yml index 152516cc5..b11acd4b0 100644 --- a/config/webpacker.yml +++ b/config/webpacker.yml @@ -97,3 +97,7 @@ production: &production staging: <<: *production public_root_path: public # https://github.com/rails/webpacker/issues/1912 + +luxproduction: + <<: *production + public_root_path: public # https://github.com/rails/webpacker/issues/1912 diff --git a/db/migrate/20240202124405_add_archived_at_to_price_list.rb b/db/migrate/20240202124405_add_archived_at_to_price_list.rb new file mode 100644 index 000000000..99e50757b --- /dev/null +++ b/db/migrate/20240202124405_add_archived_at_to_price_list.rb @@ -0,0 +1,5 @@ +class AddArchivedAtToPriceList < ActiveRecord::Migration[7.0] + def change + add_column :price_lists, :archived_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 5497d9d59..26fcbda0c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,8 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_10_12_161008) do - +ActiveRecord::Schema[7.0].define(version: 2024_02_02_124405) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -50,8 +49,8 @@ t.integer "amount", null: false t.decimal "price", precision: 8, scale: 2, null: false t.datetime "deleted_at" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["invoice_id"], name: "index_invoice_rows_on_invoice_id" end @@ -115,6 +114,7 @@ t.datetime "deleted_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.datetime "archived_at" end create_table "product_prices", force: :cascade do |t| diff --git a/db/seeds/products.rb b/db/seeds/products.rb index 56547b699..8d8862fe7 100644 --- a/db/seeds/products.rb +++ b/db/seeds/products.rb @@ -3,9 +3,11 @@ def seed_products # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metri # rubocop:disable Style/WordArray products_beer = ['Bier (glas)', 'Bier (pul)', 'Bier (pitcher)', '12+1'] + products_low_alcohol_beer = ['Alcoholarm bier', 'Radler 0.0'] products_craft_beer = ['Speciaalbier', 'Speciaalbier (pul)'] products_non_alcoholic = ['Fris', 'Fris (klein)', 'Red Bull'] - products_distilled = ['Sterke drank', 'Dure Whisky', 'Weduwe Joustra Beerenburg'] + products_distilled = ['Sterke drank', 'Weduwe Joustra Beerenburg'] + products_whiskey = ['Whiskey', 'Dure Whisky'] products_wine = ['Wijn (glas)', 'Wijn (fles)'] products_food = ['Tosti', 'Nootjes', 'Chips'] products_tobacco = ['Sigaar', 'Sigaar (duur)'] @@ -16,6 +18,10 @@ def seed_products # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metri products << Product.create(name: name, category: :beer) end + products_low_alcohol_beer.each do |name| + products << Product.create(name: name, category: :low_alcohol_beer) + end + products_craft_beer.each do |name| products << Product.create(name: name, category: :craft_beer) end @@ -28,6 +34,10 @@ def seed_products # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metri products << Product.create(name: name, category: :distilled) end + products_whiskey.each do |name| + products << Product.create(name: name, category: :whiskey) + end + products_wine.each do |name| products << Product.create(name: name, category: :wine) end diff --git a/spec/factories/product.rb b/spec/factories/product.rb index bc428a066..eb620b33c 100644 --- a/spec/factories/product.rb +++ b/spec/factories/product.rb @@ -1,6 +1,6 @@ FactoryBot.define do factory :product do name { Faker::Book.title } - category { %i[beer craft_beer non_alcoholic distilled wine food tobacco donation].sample } + category { %i[beer low_alcohol_beer craft_beer non_alcoholic distilled whiskey wine food tobacco donation].sample } end end diff --git a/spec/models/product_spec.rb b/spec/models/product_spec.rb index 92b2d2f2f..e8d5c8fb2 100644 --- a/spec/models/product_spec.rb +++ b/spec/models/product_spec.rb @@ -27,7 +27,7 @@ describe '#requires_age' do context 'when with requires age category' do - subject(:product) { create(:product, category: %w[beer craft_beer distilled wine tobacco].sample) } + subject(:product) { create(:product, category: %w[beer craft_beer distilled whiskey wine tobacco].sample) } it { expect(product.requires_age).to be true } end diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb index 66577dca2..1e782d2f7 100644 --- a/spec/models/role_spec.rb +++ b/spec/models/role_spec.rb @@ -23,7 +23,7 @@ context 'when treasurer' do subject(:role) { build_stubbed(:role, role_type: :treasurer) } - it { expect(role.name).to eq 'Penningmeester' } + it { expect(role.name).to eq Rails.application.config.x.treasurer_title.capitalize } end context 'when main bartender' do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 95804b01f..8866ea435 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -5,7 +5,7 @@ ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../config/environment', __dir__) # Prevent database truncation if the environment is production -abort('The Rails environment is running in production mode!') if Rails.env.production? || Rails.env.staging? +abort('The Rails environment is running in production mode!') if Rails.env.production? || Rails.env.staging? || Rails.env.luxproduction? require 'rspec/rails' # Add additional requires below this line. Rails is not loaded until this point!