diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc1958b598844ba7c234259f3ae9469e358d86bd..bbc7f43922850fb939b6d25703e8531834f1e88c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Fixed
 
+## [2.2.4]
+
+### Added
+
+### Changed
+- Promote button description is now a bit more clear.
+
+### Fixed
+- Offer position to selected applicants did not work.
+
 ## [2.2.3]
 
 ### Added
diff --git a/build.gradle.kts b/build.gradle.kts
index 8ccbf59a025e74d3f383929a6af344aaf0200247..6f498c52578be06852479470346c8f144ba88836 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,7 +4,7 @@ import nl.javadude.gradle.plugins.license.DownloadLicensesExtension
 import nl.javadude.gradle.plugins.license.LicenseExtension
 
 group = "nl.tudelft.tam"
-version = "2.2.3"
+version = "2.2.4"
 
 val javaVersion = JavaVersion.VERSION_21
 
diff --git a/src/main/java/nl/tudelft/tam/controller/ApplicationController.java b/src/main/java/nl/tudelft/tam/controller/ApplicationController.java
index 8b30913a76db8d4437e057c8dabe5c3046dc198d..87d200f408988493e8ff2c3510721bf7db26759e 100644
--- a/src/main/java/nl/tudelft/tam/controller/ApplicationController.java
+++ b/src/main/java/nl/tudelft/tam/controller/ApplicationController.java
@@ -37,6 +37,7 @@ import nl.tudelft.labracore.lib.security.user.Person;
 import nl.tudelft.librador.util.PageUtil;
 import nl.tudelft.tam.dto.create.ApplicationCreateDTO;
 import nl.tudelft.tam.dto.util.ApplicationFilterDTO;
+import nl.tudelft.tam.dto.util.BulkOfferDTO;
 import nl.tudelft.tam.dto.view.details.ApplicationDetailsJobOfferDTO;
 import nl.tudelft.tam.enums.Status;
 import nl.tudelft.tam.model.Application;
@@ -290,8 +291,8 @@ public class ApplicationController {
 	@PostMapping("offer/{offerId}")
 	@PreAuthorize("@authorisationService.canManageJob(#offerId)")
 	public String bulkOfferApplication(@AuthenticatedPerson Person person, @PathVariable Long offerId,
-			@RequestParam String identifiersAll) {
-		applicationService.bulkOffer(offerId, identifiersAll, person.getId());
+			BulkOfferDTO offerTo) {
+		applicationService.bulkOffer(offerId, offerTo.getIdentifiersAll(), person.getId());
 		return "redirect:/job-offer/" + offerId;
 	}
 
diff --git a/src/main/java/nl/tudelft/tam/dto/util/BulkOfferDTO.java b/src/main/java/nl/tudelft/tam/dto/util/BulkOfferDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..45c733b840fa6e7460651bfda1d8f9a948236af7
--- /dev/null
+++ b/src/main/java/nl/tudelft/tam/dto/util/BulkOfferDTO.java
@@ -0,0 +1,33 @@
+/*
+ * TAM
+ * Copyright (C) 2021 - Delft University of Technology
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+package nl.tudelft.tam.dto.util;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BulkOfferDTO {
+
+	private String identifiersAll;
+
+}
diff --git a/src/main/java/nl/tudelft/tam/dto/view/details/ApplicationDetailsPersonDTO.java b/src/main/java/nl/tudelft/tam/dto/view/details/ApplicationDetailsPersonDTO.java
index b0d208efb7f2758ca074cb3477805a0188ab2239..54bddc02727759ba8a6e85d4650a1f496a88e627 100644
--- a/src/main/java/nl/tudelft/tam/dto/view/details/ApplicationDetailsPersonDTO.java
+++ b/src/main/java/nl/tudelft/tam/dto/view/details/ApplicationDetailsPersonDTO.java
@@ -33,4 +33,7 @@ public class ApplicationDetailsPersonDTO extends ApplicationSummaryDTO {
 
 	@Builder.Default
 	private Boolean taBefore = false;
+
+	@Builder.Default
+	private Boolean isHeadTA = false;
 }
diff --git a/src/main/java/nl/tudelft/tam/service/ApplicationService.java b/src/main/java/nl/tudelft/tam/service/ApplicationService.java
index ef5d14c18fa7ba9ecf0fd4a28a7b9d7e473d67a0..d8ea3be426772237a171ef1fc2d75cc54a57f509 100644
--- a/src/main/java/nl/tudelft/tam/service/ApplicationService.java
+++ b/src/main/java/nl/tudelft/tam/service/ApplicationService.java
@@ -26,7 +26,6 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.apache.commons.lang3.ArrayUtils;
-import org.checkerframework.checker.units.qual.A;
 import org.modelmapper.ModelMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -446,6 +445,37 @@ public class ApplicationService {
 				.anyMatch(offer -> appExistsFor(personId, offer.getId()));
 	}
 
+	/**
+	 * Sets the TAed before field for a list of applications.
+	 *
+	 * @param applications The applications
+	 * @param jobOfferId   The job offer for which to check
+	 */
+	public void setRoleInformation(List<ApplicationDetailsPersonDTO> applications, Long jobOfferId) {
+		JobOffer jobOffer = jobOfferService.findByIdOrThrow(jobOfferId);
+		EditionDetailsDTO edition = editionService.getEditionById(jobOffer.getEditionId());
+		CourseDetailsDTO course = courseService.getOrThrow(edition.getCourse().getId());
+		List<Long> personIds = applications.stream().map(ApplicationSummaryDTO::getPersonId).toList();
+		Set<Long> taIds = roleService
+				.getRolesById(course.getEditions().stream().map(EditionSummaryDTO::getId)
+						.collect(Collectors.toList()), personIds)
+				.stream()
+				.filter(r -> r.getType() == RoleDetailsDTO.TypeEnum.TA
+						|| r.getType() == RoleDetailsDTO.TypeEnum.HEAD_TA)
+				.map(r -> r.getPerson().getId())
+				.collect(Collectors.toSet());
+		Set<Long> headTAIds = roleService
+				.getRolesById(List.of(edition.getId()), personIds)
+				.stream()
+				.filter(r -> r.getType() == RoleDetailsDTO.TypeEnum.HEAD_TA)
+				.map(r -> r.getPerson().getId())
+				.collect(Collectors.toSet());
+		applications.forEach(a -> {
+			a.setTaBefore(taIds.contains(a.getPersonId()));
+			a.setIsHeadTA(headTAIds.contains(a.getPersonId()));
+		});
+	}
+
 	/**
 	 * Check if a person has ta'ed a course which is provided by a job offer.
 	 *
@@ -543,14 +573,15 @@ public class ApplicationService {
 				.getPeopleById(
 						apps.stream().map(a -> a.getId().getPersonId()).collect(Collectors.toList()))
 				.stream().collect(Collectors.toMap(PersonSummaryDTO::getId, p -> p));
-		return apps.stream().map(a -> {
+		List<ApplicationDetailsPersonDTO> dtos = apps.stream().map(a -> {
 			ApplicationDetailsPersonDTO dto = mapper.map(a, ApplicationDetailsPersonDTO.class);
 			dto.setPersonId(a.getId().getPersonId());
 			dto.setJobOfferId(a.getId().getJobOfferId());
 			dto.setPerson(ppl.get(dto.getPersonId()));
-			dto.setTaBefore(hasTAedBefore(dto.getPersonId(), dto.getJobOfferId()));
 			return dto;
 		}).toList();
+		setRoleInformation(dtos, id);
+		return dtos;
 	}
 
 	/**
diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties
index 3c893e1411bacdaae5dd6be72d04efbeb0ce6650..40647b75cd73addfa351895aa7bffe63a8e8396a 100644
--- a/src/main/resources/messages.properties
+++ b/src/main/resources/messages.properties
@@ -239,10 +239,10 @@ jobOffer.accept = Accept
 jobOffer.reject = Reject
 jobOffer.promote = Promote
 jobOffer.promote.confirm = Confirm Promotion
-jobOffer.promote.confirm.desc = Are you sure you would like to promote the following people:
+jobOffer.promote.confirm.desc = Are you sure you would like to promote the following people to Head TA:
 jobOffer.demote = Demote
 jobOffer.demote.confirm = Confirm Demote
-jobOffer.demote.confirm.desc = Are you sure you would like to demote the following people:
+jobOffer.demote.confirm.desc = Are you sure you would like to demote the following people to regular TA:
 jobOffer.reject.confirm = Confirm Rejection
 jobOffer.reject.confirm.desc = Are you sure you would like to reject the following people:
 jobOffer.offer = Send Offer
diff --git a/src/main/resources/migrations.yaml b/src/main/resources/migrations.yaml
index 5c5564e0d0a71a1567aaba05fc3ae91763908a6c..3e5a2b1c6702bc88f75035cfddacad1c92e792bb 100644
--- a/src/main/resources/migrations.yaml
+++ b/src/main/resources/migrations.yaml
@@ -928,4 +928,4 @@ databaseChangeLog:
                 name: teachers_have_access
                 type: bit
                 defaultValueBoolean: true
-          tableName: tamprogram
+          tableName: tamprogram
\ No newline at end of file
diff --git a/src/main/resources/templates/job_offer/confirm_offer_all_app.html b/src/main/resources/templates/job_offer/confirm_offer_all_app.html
index 24bab1ab8b1cdda346ba4aa6fc81ec34829fe72a..b57348fbbf893d86b096db013d7cf4d6be9e5bf4 100644
--- a/src/main/resources/templates/job_offer/confirm_offer_all_app.html
+++ b/src/main/resources/templates/job_offer/confirm_offer_all_app.html
@@ -29,7 +29,7 @@
             data-closable
             class="dialog">
             <form
-                th:action="@{|/application/offer/${offer.id}/|}"
+                th:action="@{|/application/offer/${offer.id}|}"
                 th:method="post"
                 class="flex vertical p-7">
                 <h1 class="underlined font-500" th:text="#{jobOffer.addOffer.confirm}"></h1>
diff --git a/src/main/resources/templates/job_offer/view_one.html b/src/main/resources/templates/job_offer/view_one.html
index 23600e4488a60904bd512a737a22e0844cacb0c4..a6fe771ff6fe5617845c46aae0f4e038709cefaa 100644
--- a/src/main/resources/templates/job_offer/view_one.html
+++ b/src/main/resources/templates/job_offer/view_one.html
@@ -670,7 +670,7 @@
                     class="table-row"
                     th:each="app : ${applications}"
                     th:data-status="${#strings.toLowerCase(app.status.name())}"
-                    th:with="headTA = ${@roleService.hasHeadTARole(app.personId, offer.editionId)}">
+                    th:with="headTA = ${app.isHeadTA}">
                     <td>
                         <label class="check-box">
                             <input