diff --git a/app/admin/acp.rb b/app/admin/acp.rb index 7fdfe9cd6..53fc404f8 100644 --- a/app/admin/acp.rb +++ b/app/admin/acp.rb @@ -62,7 +62,8 @@ *I18n.available_locales.map { |l| "member_information_text_#{l}" }, billing_year_divisions: [], languages: [], - features: [] + features: [], + membership_renewed_attributes: [] form data: { controller: 'code-editor' } do |f| div do @@ -218,6 +219,8 @@ required: false, hint: t('formtastic.hints.acp.open_renewal_text')) f.input :open_renewal_reminder_sent_after_in_days + f.input :membership_renewed_attributes, as: :check_boxes, + collection: membership_renewed_attributes_collection f.input :membership_renewal_depot_update handbook_button(self, 'membership_renewal') diff --git a/app/assets/images/updates/20230825_membership_renewed_attributes/settings.png b/app/assets/images/updates/20230825_membership_renewed_attributes/settings.png new file mode 100644 index 000000000..eeba9f848 Binary files /dev/null and b/app/assets/images/updates/20230825_membership_renewed_attributes/settings.png differ diff --git a/app/helpers/acps_helper.rb b/app/helpers/acps_helper.rb index bc9ccf51e..090a2e883 100644 --- a/app/helpers/acps_helper.rb +++ b/app/helpers/acps_helper.rb @@ -13,4 +13,28 @@ def fiscal_year_months_range def link_to_acp_website(options = {}) link_to Current.acp.url.sub(/https?:\/\//, ''), Current.acp.url, options end + + def membership_renewed_attributes_collection + col = [[ + Membership.human_attribute_name(:baskets_annual_price_change), + 'baskets_annual_price_change' + ]] + if BasketComplement.any? + col << [ + Membership.human_attribute_name(:basket_complements_annual_price_change), + 'basket_complements_annual_price_change' + ] + end + if feature?('activity') + col << [ + "#{t('formtastic.labels.membership.activity_participations_annual_price_change')} (#{activities_human_name})", + 'activity_participations_annual_price_change' + ] + col << [ + "#{activities_human_name} (#{t('active_admin.resource.edit.full_year')})", + 'activity_participations_demanded_annualy' + ] + end + col + end end diff --git a/app/models/acp.rb b/app/models/acp.rb index 8a84401ae..3d593446f 100644 --- a/app/models/acp.rb +++ b/app/models/acp.rb @@ -327,6 +327,22 @@ def calculate_basket_price_extra(extra, basket_price, basket_size_id, deliveries ).to_f end + def membership_renewed_attributes=(attrs) + super + unless feature?('activity') + self[:membership_renewed_attributes] += %w[ + activity_participations_demanded_annualy + activity_participations_annual_price_change + ] + end + unless BasketComplement.any? + self[:membership_renewed_attributes] += %w[ + basket_complements_annual_price_change + ] + end + self[:membership_renewed_attributes].uniq! + end + private def activity_participations_demanded_logic_must_be_valid diff --git a/app/models/membership_renewal.rb b/app/models/membership_renewal.rb index cb02f0a05..914e29067 100644 --- a/app/models/membership_renewal.rb +++ b/app/models/membership_renewal.rb @@ -1,6 +1,13 @@ class MembershipRenewal MissingDeliveriesError = Class.new(StandardError) + OPTIONAL_ATTRIBUTES = %w[ + baskets_annual_price_change + basket_complements_annual_price_change + activity_participations_demanded_annualy + activity_participations_annual_price_change + ] + attr_reader :membership, :fiscal_year def initialize(membership) @@ -32,18 +39,14 @@ def renew!(attrs = {}) def renewed_attrs(attrs = {}) membership .attributes - .slice(*%w[ + .slice(*(%w[ member_id basket_size_id basket_quantity basket_price_extra - baskets_annual_price_change depot_id deliveries_cycle_id - activity_participations_demanded_annualy - activity_participations_annual_price_change - basket_complements_annual_price_change - ]) + ] + (OPTIONAL_ATTRIBUTES & Current.acp.membership_renewed_attributes))) .symbolize_keys .merge( started_on: fiscal_year.beginning_of_year, diff --git a/app/views/updates/_20230825_membership_renewed_attributes.md.erb b/app/views/updates/_20230825_membership_renewed_attributes.md.erb new file mode 100644 index 000000000..f5230e16f --- /dev/null +++ b/app/views/updates/_20230825_membership_renewed_attributes.md.erb @@ -0,0 +1,9 @@ +# Renouvellement: configurations reprises + +Il est maintenant possible [de paramétrer si certaines configurations](/settings#membership_renewal) sont reprises ou non lors du renouvellement d'un abonnement. Historiquement ces configurations étaient toujours reprises, ce qui pouvait poser problème dans certaines situations. + +Dans tous les cas, et comme précédemment, si un changement de taille du panier ou de compléments est choisi par le membre, les configurations correspondantes ne sont pas reprises lors du renouvellement. + +![Paramètres](<%= image_url('updates/20230825_membership_renewed_attributes/settings.png') %>){:width="90%"} + +Retrouvez plus d'informations sur le renouvellement des abonnements dans [le manuel](handbook/membership_renewal). diff --git a/config/locales/activerecord.yml b/config/locales/activerecord.yml index 123bfaa74..c8b76ad97 100644 --- a/config/locales/activerecord.yml +++ b/config/locales/activerecord.yml @@ -187,6 +187,10 @@ _: _de: Erlauben Sie die Änderung das Depot _fr: Permettre le changement du dépôt _it: Permettere il cambiamento del punto di ritiro + membership_renewed_attributes: + _de: Übernommene Konfigurationen + _fr: Configurations reprises + _it: Configurazioni riprese membership_update_text: _de: Erläuterung _fr: Explication diff --git a/config/locales/formtastic.yml b/config/locales/formtastic.yml index 0dc08f392..dd0ba7a4d 100644 --- a/config/locales/formtastic.yml +++ b/config/locales/formtastic.yml @@ -126,6 +126,14 @@ _: _de: Nur die Änderung zukünftiger Lieferungen ist erlaubt. _fr: Seule la modification des futures livraisons est autorisée. _it: È consentita solo la modifica delle consegne future. + membership_renewal_depot_update: + _de: Ermöglicht es Mitgliedern, das Depot bei der Verlängerung ihres Abonnements über das Formular zu ändern. + _fr: Permettre au membre de changer de dépôt lors du renouvellement de son abonnement via le formulaire. + _it: Permettere al socio di cambiare il punto di ritiro al momento del rinnovo dell'abbonamento tramite il modulo. + membership_renewed_attributes: + _de: Die ausgewählten Konfigurationen werden beim Verlängern des Abonnements automatisch übernommen. Wenn die Korbgröße oder die Zusätze vom Mitglied geändert werden, werden die entsprechenden Konfigurationen sowieso gelöscht. + _fr: Les configurations sélectionnées seront automatiquement reprises lors du renouvellement de l'abonnement tel quel. Si la taille du panier ou les compléments sont modifiés par le membre, alors les configurations correspondantes seront de toute façon effacées. + _it: Le configurazioni selezionate saranno automaticamente riprese al momento del rinnovo dell'abbonamento. Se la dimensione del cesto o gli extra vengono modificati dal socio, le configurazioni corrispondenti saranno comunque cancellate. membership_update_text: _de: Optionaler Text, der auf der Mitgliederseite über dem Formular zur Änderung des Abonnements oder der Tasche angezeigt wird. _fr: Texte optionnel affiché sur la page de membre au-dessus du formulaire de modification de l'abonnement ou du panier. diff --git a/db/migrate/20230825120451_add_membership_renewed_attributes_to_acps.rb b/db/migrate/20230825120451_add_membership_renewed_attributes_to_acps.rb new file mode 100644 index 000000000..d7dbd099d --- /dev/null +++ b/db/migrate/20230825120451_add_membership_renewed_attributes_to_acps.rb @@ -0,0 +1,5 @@ +class AddMembershipRenewedAttributesToAcps < ActiveRecord::Migration[7.0] + def change + add_column :acps, :membership_renewed_attributes, :string, array: true, default: MembershipRenewal::OPTIONAL_ATTRIBUTES + end +end diff --git a/db/schema.rb b/db/schema.rb index 364e3a6c2..984721595 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_08_25_070903) do +ActiveRecord::Schema[7.0].define(version: 2023_08_25_120451) do # These are extensions that must be enabled in order to support this database enable_extension "hstore" enable_extension "plpgsql" @@ -111,6 +111,7 @@ t.string "depots_member_order_mode", default: "price_asc", null: false t.string "deliveries_cycles_member_order_mode", default: "deliveries_count_desc", null: false t.integer "shop_order_automatic_invoicing_delay_in_days" + t.string "membership_renewed_attributes", default: ["baskets_annual_price_change", "basket_complements_annual_price_change", "activity_participations_demanded_annualy", "activity_participations_annual_price_change"], array: true t.index ["host"], name: "index_acps_on_host" t.index ["tenant_name"], name: "index_acps_on_tenant_name" end diff --git a/spec/models/membership_renewal_spec.rb b/spec/models/membership_renewal_spec.rb index c418feea4..1483263d6 100644 --- a/spec/models/membership_renewal_spec.rb +++ b/spec/models/membership_renewal_spec.rb @@ -146,4 +146,36 @@ basket_complements_annual_price_change: 0) expect(renewed.memberships_basket_complements.count).to eq 1 end + + specify 'ignore optional attributes' do + create(:delivery, date: next_fy.beginning_of_year) + create(:basket_complement, id: 1, price: 3.2) + create(:basket_complement, id: 2, price: 4.5) + membership = create(:membership, + baskets_annual_price_change: 130, + activity_participations_demanded_annualy: 5, + activity_participations_annual_price_change: -60, + basket_complements_annual_price_change: -32, + memberships_basket_complements_attributes: { + '0' => { basket_complement_id: 1, quantity: 1 } + }) + + Current.acp.update!(membership_renewed_attributes: %w[ + activity_participations_demanded_annualy + ]) + + expect { + MembershipRenewal.new(membership).renew!( + memberships_basket_complements_attributes: { + '0' => { basket_complement_id: 1, quantity: 1 }, + } + ) + }.to change(Membership, :count).by(1) + + expect(membership.renewed_membership).to have_attributes( + baskets_annual_price_change: 0, + activity_participations_demanded_annualy: 5, + activity_participations_annual_price_change: 0, + basket_complements_annual_price_change: 0) + end end