diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 655b61ede62a12986f0eb65652ba42f4c3797518..963dbda02315623d08f90f091130c87854010e2f 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -16893,9 +16893,9 @@ Represents vulnerability finding of a security report on the pipeline. | Name | Type | Description | | ---- | ---- | ----------- | -| <a id="previewbillableuserchangehasoverage"></a>`hasOverage` | [`Boolean`](#boolean) | If the group has an overage after change. | | <a id="previewbillableuserchangenewbillableusercount"></a>`newBillableUserCount` | [`Int`](#int) | Total number of billable users after change. | | <a id="previewbillableuserchangeseatsinsubscription"></a>`seatsInSubscription` | [`Int`](#int) | Number of seats in subscription. | +| <a id="previewbillableuserchangewillincreaseoverage"></a>`willIncreaseOverage` | [`Boolean`](#boolean) | If the group will have an increased overage after change. | ### `ProductAnalyticsDashboard` diff --git a/ee/app/assets/javascripts/invite_members/billable_users_count.query.graphql b/ee/app/assets/javascripts/invite_members/billable_users_count.query.graphql index bfc96f79bb30e120dade26c3a618bb1cd8a2aa25..933c59c92383f817f7223c458d109b33cb4ffc09 100644 --- a/ee/app/assets/javascripts/invite_members/billable_users_count.query.graphql +++ b/ee/app/assets/javascripts/invite_members/billable_users_count.query.graphql @@ -13,7 +13,7 @@ query getBillableUsersCount( addUserIds: $addUserIds role: $role ) { - hasOverage + willIncreaseOverage seatsInSubscription newBillableUserCount } diff --git a/ee/app/assets/javascripts/invite_members/components/invite_modal_base.vue b/ee/app/assets/javascripts/invite_members/components/invite_modal_base.vue index 5d3151b18ac3350b71ea2d2fa92f4c366ccf2cc1..50e92719e2676cd2b3924b8acf4935c1b60cd97d 100644 --- a/ee/app/assets/javascripts/invite_members/components/invite_modal_base.vue +++ b/ee/app/assets/javascripts/invite_members/components/invite_modal_base.vue @@ -82,7 +82,7 @@ export default { }, data() { return { - hasOverage: false, + willIncreaseOverage: false, totalUserCount: null, subscriptionSeats: 0, namespaceId: parseInt(this.rootGroupId, 10), @@ -102,7 +102,7 @@ export default { return undefined; }, showOverageModal() { - return this.hasOverage && this.enabledOverageCheck && !this.actualFeedbackMessage; + return this.willIncreaseOverage && this.enabledOverageCheck && !this.actualFeedbackMessage; }, submitDisabledEE() { if (this.showOverageModal) { @@ -144,7 +144,7 @@ export default { }, watch: { invalidFeedbackMessage(newValue) { - this.hasOverage = false; + this.willIncreaseOverage = false; this.actualFeedbackMessage = newValue; }, }, @@ -158,7 +158,7 @@ export default { }, onReset() { // don't reopen the overage modal - this.hasOverage = false; + this.willIncreaseOverage = false; this.actualFeedbackMessage = ''; this.$emit('reset'); @@ -166,7 +166,7 @@ export default { onSubmit(args) { if (this.reachedLimit) return; - if (this.enabledOverageCheck && !this.hasOverage && this.hasInput) { + if (this.enabledOverageCheck && !this.willIncreaseOverage && this.hasInput) { this.actualFeedbackMessage = ''; this.checkEligibility(args); } else { @@ -217,8 +217,8 @@ export default { this.emitSubmit(args); } const billingDetails = data.group.gitlabSubscriptionsPreviewBillableUserChange; - this.hasOverage = billingDetails.hasOverage; - if (this.hasOverage) { + this.willIncreaseOverage = billingDetails.willIncreaseOverage; + if (this.willIncreaseOverage) { this.totalUserCount = billingDetails.newBillableUserCount; this.subscriptionSeats = billingDetails.seatsInSubscription; } else { @@ -261,7 +261,7 @@ export default { }, onCancel() { if (this.showOverageModal) { - this.hasOverage = false; + this.willIncreaseOverage = false; } }, }, diff --git a/ee/app/graphql/types/gitlab_subscriptions/preview_billable_user_change_type.rb b/ee/app/graphql/types/gitlab_subscriptions/preview_billable_user_change_type.rb index 834f7565036e231ba75faa0f968a4fea981d3543..5ac320f04634faf663aa2963ece4d6bb7edad074 100644 --- a/ee/app/graphql/types/gitlab_subscriptions/preview_billable_user_change_type.rb +++ b/ee/app/graphql/types/gitlab_subscriptions/preview_billable_user_change_type.rb @@ -4,10 +4,11 @@ module Types module GitlabSubscriptions # rubocop:disable Graphql/AuthorizeTypes class PreviewBillableUserChangeType < BaseObject - field :has_overage, GraphQL::Types::Boolean, null: true, description: 'If the group has an overage after change.' field :new_billable_user_count, GraphQL::Types::Int, null: true, description: 'Total number of billable users after change.' field :seats_in_subscription, GraphQL::Types::Int, null: true, description: 'Number of seats in subscription.' + field :will_increase_overage, GraphQL::Types::Boolean, + null: true, description: ' If the group will have an increased overage after change.' end # rubocop:enable Graphql/AuthorizeTypes end diff --git a/ee/app/services/gitlab_subscriptions/preview_billable_user_change_service.rb b/ee/app/services/gitlab_subscriptions/preview_billable_user_change_service.rb index a1acad0753684c4262c6ec60d7a8480532e2fb94..af73667715d1d79cfafc26ef99be7310a6c2ae01 100644 --- a/ee/app/services/gitlab_subscriptions/preview_billable_user_change_service.rb +++ b/ee/app/services/gitlab_subscriptions/preview_billable_user_change_service.rb @@ -17,7 +17,7 @@ def execute { success: true, data: { - has_overage: has_overage?, + will_increase_overage: will_increase_overage?, new_billable_user_count: new_billable_user_count, seats_in_subscription: seats_in_subscription } @@ -54,8 +54,8 @@ def user_ids_from_added_group group.billed_user_ids[:user_ids] end - def has_overage? - new_billable_user_count > seats_in_subscription + def will_increase_overage? + new_billable_user_count > current_max_billable_users end def new_billable_user_count @@ -71,5 +71,9 @@ def new_billable_user_count def seats_in_subscription @seats_in_subscription ||= target_namespace.gitlab_subscription&.seats || 0 end + + def current_max_billable_users + [target_namespace.billable_members_count, seats_in_subscription].max + end end end diff --git a/ee/spec/features/groups/members/manage_members_spec.rb b/ee/spec/features/groups/members/manage_members_spec.rb index 292586e45fb8101d55fbb063fa69a360d1adfe9e..57005c0b1e83d68865ec8f0591b7c4ab43d260c7 100644 --- a/ee/spec/features/groups/members/manage_members_spec.rb +++ b/ee/spec/features/groups/members/manage_members_spec.rb @@ -98,6 +98,7 @@ context 'when adding a member to a free group' do before do + stub_subscription_request_seat_usage(false) create(:gitlab_subscription, namespace: group, hosted_plan: nil) end @@ -179,6 +180,15 @@ include_examples 'adding user by email with a given role', 'Developer' end + context 'when adding a member to a ultimate group that alerady has an overage' do + before do + create(:gitlab_subscription, namespace: group, hosted_plan: ultimate_plan, seats: 1, seats_in_use: 2) + end + + include_examples 'shows an overage modal when adding one user with a given role', 'Developer' + include_examples 'adding one user by email with a given role doesn\'t trigger an overage modal', 'Guest' + end + context 'when adding to a group not eligible for reconciliation', :aggregate_failures do before do create(:gitlab_subscription, namespace: group, hosted_plan: ultimate_plan, seats: 1, seats_in_use: 1) diff --git a/ee/spec/frontend/invite_members/components/invite_modal_base_spec.js b/ee/spec/frontend/invite_members/components/invite_modal_base_spec.js index 97afa3535474fc2282fbe16fe80265c4fad3040d..6af62077b313a0e3b599adb50701752083b20a5a 100644 --- a/ee/spec/frontend/invite_members/components/invite_modal_base_spec.js +++ b/ee/spec/frontend/invite_members/components/invite_modal_base_spec.js @@ -32,7 +32,7 @@ describe('EEInviteModalBase', () => { group: { id: 12345, gitlabSubscriptionsPreviewBillableUserChange: { - hasOverage: true, + willIncreaseOverage: true, newBillableUserCount: 2, seatsInSubscription: 1, }, diff --git a/ee/spec/requests/api/graphql/gitlab_subscriptions/preview_billable_user_change_spec.rb b/ee/spec/requests/api/graphql/gitlab_subscriptions/preview_billable_user_change_spec.rb index b069a5037d04fdbe768b056a2671ca9498296c71..9a8534f8d96dd8df99fbd1637282f1221b627503 100644 --- a/ee/spec/requests/api/graphql/gitlab_subscriptions/preview_billable_user_change_spec.rb +++ b/ee/spec/requests/api/graphql/gitlab_subscriptions/preview_billable_user_change_spec.rb @@ -6,7 +6,7 @@ include GraphqlHelpers let_it_be(:current_user) { create(:user) } - let_it_be(:fields) { 'hasOverage newBillableUserCount seatsInSubscription' } + let_it_be(:fields) { 'willIncreaseOverage newBillableUserCount seatsInSubscription' } let_it_be(:base_args) { { role: :DEVELOPER } } shared_examples 'preview billable user change' do @@ -36,7 +36,7 @@ expect(subject).to eq( { - 'hasOverage' => true, + 'willIncreaseOverage' => false, 'newBillableUserCount' => 1, 'seatsInSubscription' => 0 } @@ -52,7 +52,7 @@ expect(subject).to eq( { - 'hasOverage' => true, + 'willIncreaseOverage' => true, 'newBillableUserCount' => 2, 'seatsInSubscription' => 0 } @@ -68,7 +68,7 @@ expect(subject).to eq( { - 'hasOverage' => true, + 'willIncreaseOverage' => true, 'newBillableUserCount' => 2, 'seatsInSubscription' => 0 } diff --git a/ee/spec/services/gitlab_subscriptions/preview_billable_user_change_service_spec.rb b/ee/spec/services/gitlab_subscriptions/preview_billable_user_change_service_spec.rb index 65d46d553498c8cbe1bafe665f5afff50f598d44..cfa6190ed168191ae07ea588ed6682c4a9a1aaee 100644 --- a/ee/spec/services/gitlab_subscriptions/preview_billable_user_change_service_spec.rb +++ b/ee/spec/services/gitlab_subscriptions/preview_billable_user_change_service_spec.rb @@ -40,7 +40,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 4, seats_in_subscription: 0 } @@ -56,7 +56,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 4, seats_in_subscription: 0 } @@ -70,7 +70,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: false, new_billable_user_count: 1, seats_in_subscription: 0 } @@ -85,7 +85,7 @@ it 'returns successfully' do expect(execute).to include({ success: true, - data: { has_overage: true, new_billable_user_count: 1, seats_in_subscription: 0 } + data: { will_increase_overage: false, new_billable_user_count: 1, seats_in_subscription: 0 } }) end end @@ -108,7 +108,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 3, seats_in_subscription: 0 } @@ -122,7 +122,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 3, seats_in_subscription: 0 } @@ -147,7 +147,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 2, seats_in_subscription: 0 } @@ -161,7 +161,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 2, seats_in_subscription: 0 } @@ -191,7 +191,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: false, new_billable_user_count: 1, seats_in_subscription: 0 } @@ -208,7 +208,7 @@ expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 2, seats_in_subscription: 0 } @@ -218,7 +218,7 @@ end end - context 'when added users results in an overage' do + context 'when added users results in an increased overage' do let_it_be(:add_user_ids) do 10.times.map do |i| # rubocop:disable Performance/TimesMap non_existing_record_id - i @@ -234,11 +234,11 @@ ).execute end - it 'sets has_overage: true' do + it 'sets will_increase_overage: true' do expect(execute).to include({ success: true, data: { - has_overage: true, + will_increase_overage: true, new_billable_user_count: 11, seats_in_subscription: 0 }