Andrew Grant 6 сар өмнө
parent
commit
9a666cc656
100 өөрчлөгдсөн 5282 нэмэгдсэн , 3 устгасан
  1. 5 0
      pom.xml
  2. 27 0
      src/main/java/scot/carricksoftware/grants/BaseEntity.java
  3. 3 3
      src/main/java/scot/carricksoftware/grants/GrantsApplication.java
  4. 70 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadCensus.java
  5. 56 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadCertificates.java
  6. 71 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadImages.java
  7. 48 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadPeople.java
  8. 82 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadPlaces.java
  9. 63 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadTexts.java
  10. 58 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadTwoPartyCertificates.java
  11. 35 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoader.java
  12. 35 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoaderPrimary.java
  13. 42 0
      src/main/java/scot/carricksoftware/grants/bootstrap/DataLoaderSecondary.java
  14. 30 0
      src/main/java/scot/carricksoftware/grants/commands/census/CensusCommand.java
  15. 64 0
      src/main/java/scot/carricksoftware/grants/commands/census/CensusCommandImpl.java
  16. 28 0
      src/main/java/scot/carricksoftware/grants/commands/census/CensusEntryCommand.java
  17. 58 0
      src/main/java/scot/carricksoftware/grants/commands/census/CensusEntryCommandImpl.java
  18. 20 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/birthcertificates/BirthCertificateCommand.java
  19. 33 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/birthcertificates/BirthCertificateCommandImpl.java
  20. 20 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/deathcertificates/DeathCertificateCommand.java
  21. 35 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/deathcertificates/DeathCertificateCommandImpl.java
  22. 26 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/divorcecertificates/DivorceCertificateCommand.java
  23. 44 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/divorcecertificates/DivorceCertificateCommandImpl.java
  24. 25 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/marriagecertificates/MarriageCertificateCommand.java
  25. 50 0
      src/main/java/scot/carricksoftware/grants/commands/certificates/marriagecertificates/MarriageCertificateCommandImpl.java
  26. 12 0
      src/main/java/scot/carricksoftware/grants/commands/images/ImageCommand.java
  27. 24 0
      src/main/java/scot/carricksoftware/grants/commands/images/ImageCommandImpl.java
  28. 18 0
      src/main/java/scot/carricksoftware/grants/commands/images/PersonImageCommand.java
  29. 36 0
      src/main/java/scot/carricksoftware/grants/commands/images/PersonImageCommandImpl.java
  30. 18 0
      src/main/java/scot/carricksoftware/grants/commands/images/PlaceImageCommand.java
  31. 36 0
      src/main/java/scot/carricksoftware/grants/commands/images/PlaceImageCommandImpl.java
  32. 21 0
      src/main/java/scot/carricksoftware/grants/commands/people/PersonCommand.java
  33. 40 0
      src/main/java/scot/carricksoftware/grants/commands/people/PersonCommandImpl.java
  34. 29 0
      src/main/java/scot/carricksoftware/grants/commands/places/countries/CountryCommand.java
  35. 52 0
      src/main/java/scot/carricksoftware/grants/commands/places/countries/CountryCommandImpl.java
  36. 35 0
      src/main/java/scot/carricksoftware/grants/commands/places/places/PlaceCommand.java
  37. 64 0
      src/main/java/scot/carricksoftware/grants/commands/places/places/PlaceCommandImpl.java
  38. 36 0
      src/main/java/scot/carricksoftware/grants/commands/places/regions/RegionCommand.java
  39. 66 0
      src/main/java/scot/carricksoftware/grants/commands/places/regions/RegionCommandImpl.java
  40. 12 0
      src/main/java/scot/carricksoftware/grants/commands/text/DocumentTextCommand.java
  41. 23 0
      src/main/java/scot/carricksoftware/grants/commands/text/DocumentTextCommandImpl.java
  42. 19 0
      src/main/java/scot/carricksoftware/grants/commands/text/PersonTextCommand.java
  43. 35 0
      src/main/java/scot/carricksoftware/grants/commands/text/PersonTextCommandImpl.java
  44. 18 0
      src/main/java/scot/carricksoftware/grants/commands/text/PlaceTextCommand.java
  45. 36 0
      src/main/java/scot/carricksoftware/grants/commands/text/PlaceTextCommandImpl.java
  46. 27 0
      src/main/java/scot/carricksoftware/grants/constants/ApplicationConstants.java
  47. 65 0
      src/main/java/scot/carricksoftware/grants/constants/AttributeConstants.java
  48. 25 0
      src/main/java/scot/carricksoftware/grants/constants/ButtonConstants.java
  49. 40 0
      src/main/java/scot/carricksoftware/grants/constants/ImageAttributeConstants.java
  50. 87 0
      src/main/java/scot/carricksoftware/grants/constants/ImageMappingConstants.java
  51. 226 0
      src/main/java/scot/carricksoftware/grants/constants/MappingConstants.java
  52. 39 0
      src/main/java/scot/carricksoftware/grants/constants/ValidationConstants.java
  53. 60 0
      src/main/java/scot/carricksoftware/grants/constants/ViewConstants.java
  54. 17 0
      src/main/java/scot/carricksoftware/grants/controllers/ControllerHelper.java
  55. 27 0
      src/main/java/scot/carricksoftware/grants/controllers/ControllerHelperImpl.java
  56. 18 0
      src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusFormController.java
  57. 92 0
      src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerImpl.java
  58. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusListController.java
  59. 107 0
      src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusListControllerImpl.java
  60. 18 0
      src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormController.java
  61. 109 0
      src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerImpl.java
  62. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryListController.java
  63. 108 0
      src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryListControllerImpl.java
  64. 34 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateFormController.java
  65. 110 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateFormControllerImpl.java
  66. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateListController.java
  67. 106 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateListControllerImpl.java
  68. 34 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateFormController.java
  69. 109 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateFormControllerImpl.java
  70. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateListController.java
  71. 106 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateListControllerImpl.java
  72. 34 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateFormController.java
  73. 109 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateFormControllerImpl.java
  74. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateListController.java
  75. 106 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateListControllerImpl.java
  76. 35 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateFormController.java
  77. 110 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateFormControllerImpl.java
  78. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateListController.java
  79. 106 0
      src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateListControllerImpl.java
  80. 18 0
      src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageFormController.java
  81. 97 0
      src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageFormControllerImpl.java
  82. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageListController.java
  83. 104 0
      src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageListControllerImpl.java
  84. 18 0
      src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageFormController.java
  85. 105 0
      src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageFormControllerImpl.java
  86. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageListController.java
  87. 104 0
      src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageListControllerImpl.java
  88. 18 0
      src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageFormController.java
  89. 105 0
      src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageFormControllerImpl.java
  90. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageListController.java
  91. 104 0
      src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageListControllerImpl.java
  92. 18 0
      src/main/java/scot/carricksoftware/grants/controllers/people/PersonFormController.java
  93. 106 0
      src/main/java/scot/carricksoftware/grants/controllers/people/PersonFormControllerImpl.java
  94. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/people/PersonListController.java
  95. 106 0
      src/main/java/scot/carricksoftware/grants/controllers/people/PersonListControllerImpl.java
  96. 18 0
      src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryFormController.java
  97. 105 0
      src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryFormControllerImpl.java
  98. 29 0
      src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryListController.java
  99. 108 0
      src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryListControllerImpl.java
  100. 107 0
      src/main/java/scot/carricksoftware/grants/controllers/places/places/PLaceListControllerImpl.java

+ 5 - 0
pom.xml

@@ -55,6 +55,11 @@
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+		<dependency>
+			<groupId>org.pitest</groupId>
+			<artifactId>pitest-junit5-plugin</artifactId>
+			<version>1.2.2</version>
+		</dependency>
 
 
 		<dependency>

+ 27 - 0
src/main/java/scot/carricksoftware/grants/BaseEntity.java

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c)  02 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants;
+
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.MappedSuperclass;
+
+@MappedSuperclass
+public class BaseEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getId() {
+        return id;
+    }
+}

+ 3 - 3
src/main/java/scot/carricksoftware/grants/GrantsApplication.java

@@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 @SpringBootApplication
 public class GrantsApplication {
 
-	public static void main(String[] args) {
-		SpringApplication.run(GrantsApplication.class, args);
-	}
+    public static void main(String[] args) {
+        SpringApplication.run(GrantsApplication.class, args);
+    }
 
 }

+ 70 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadCensus.java

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c)  18 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.commands.census.CensusCommand;
+import scot.carricksoftware.grants.commands.census.CensusCommandImpl;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommand;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommandImpl;
+import scot.carricksoftware.grants.domains.places.Place;
+import scot.carricksoftware.grants.services.census.CensusEntryService;
+import scot.carricksoftware.grants.services.census.CensusService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.services.places.places.PlaceService;
+
+import java.time.LocalDate;
+
+@Component
+public class DataLoadCensus {
+
+    private static final Logger logger = LogManager.getLogger(DataLoadCensus.class);
+
+
+    private final CensusService censusService;
+    private final CensusEntryService censusEntryService;
+    private final PlaceService placeService;
+    private final PersonService personService;
+
+    public DataLoadCensus(CensusService censusService,
+                          CensusEntryService censusEntryService,
+                          PlaceService placeService,
+                          PersonService personService) {
+
+        this.censusService = censusService;
+        this.censusEntryService = censusEntryService;
+        this.placeService = placeService;
+        this.personService = personService;
+    }
+
+    public void load() {
+        logger.debug("DataLoadCensus::load");
+        loadCensus();
+        loadCensusEntry();
+    }
+
+    private void loadCensus() {
+        logger.debug("DataLoadCensus::loadCensus");
+        CensusCommand censusCommand = new CensusCommandImpl();
+        Place place = placeService.findById(1L);
+        censusCommand.setDate(LocalDate.now());
+        censusCommand.setPlace(place);
+        censusService.saveCensusCommand(censusCommand);
+    }
+
+    private void loadCensusEntry() {
+        logger.debug("DataLoadCensus::loadCensusEntry");
+        CensusEntryCommand censusEntryCommand = new CensusEntryCommandImpl();
+        censusEntryCommand.setName("Archie Grant");
+        censusEntryCommand.setCensus(censusService.findById(1L));
+        censusEntryCommand.setPerson(personService.findById(1L));
+        censusEntryService.saveCensusEntryCommand(censusEntryCommand);
+    }
+
+
+}

+ 56 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadCertificates.java

@@ -0,0 +1,56 @@
+/*
+ * Copyright (c)  18 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.certificates.BirthCertificate;
+import scot.carricksoftware.grants.domains.certificates.DeathCertificate;
+import scot.carricksoftware.grants.services.certificates.birthcertificates.BirthCertificateService;
+import scot.carricksoftware.grants.services.certificates.deathcertificates.DeathCertificateService;
+import scot.carricksoftware.grants.services.people.PersonService;
+
+@Component
+public class DataLoadCertificates {
+
+    private static final Logger logger = LogManager.getLogger(DataLoadCertificates.class);
+
+    private final BirthCertificateService birthCertificateService;
+    private final DeathCertificateService deathCertificateService;
+    private final PersonService personService;
+
+    public DataLoadCertificates(BirthCertificateService birthCertificateService,
+                                DeathCertificateService deathCertificateService,
+                                PersonService personService) {
+        this.birthCertificateService = birthCertificateService;
+        this.deathCertificateService = deathCertificateService;
+        this.personService = personService;
+    }
+
+
+    public void load() {
+        logger.debug("DataLoadPlaces::load");
+        loadBirthCertificates();
+        loadDeathCertificates();
+    }
+
+
+    private void loadBirthCertificates() {
+        BirthCertificate birthCertificate = new BirthCertificate();
+        birthCertificate.setNewBorn(personService.findById(1L));
+        birthCertificateService.save(birthCertificate);
+
+    }
+
+    private void loadDeathCertificates() {
+        DeathCertificate deathCertificate = new DeathCertificate();
+        deathCertificate.setDeceased(personService.findById(1L));
+        deathCertificateService.save(deathCertificate);
+    }
+
+
+}

+ 71 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadImages.java

@@ -0,0 +1,71 @@
+/*
+ * Copyright (c)  18 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.commands.images.*;
+import scot.carricksoftware.grants.services.images.image.ImageService;
+import scot.carricksoftware.grants.services.images.personimage.PersonImageService;
+import scot.carricksoftware.grants.services.images.placeimage.PlaceImageService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.services.places.places.PlaceService;
+
+@Component
+public class DataLoadImages {
+
+    private static final Logger logger = LogManager.getLogger(DataLoadImages.class);
+
+
+    private final ImageService imageService;
+    private final PersonImageService personImageService;
+    private final PlaceImageService placeImageService;
+    private final PersonService personService;
+    private final PlaceService placeService;
+
+
+    public DataLoadImages(ImageService imageService, PersonImageService personImageService, PlaceImageService placeImageService, PersonService personService, PlaceService placeService) {
+        this.imageService = imageService;
+        this.personImageService = personImageService;
+        this.placeImageService = placeImageService;
+        this.personService = personService;
+        this.placeService = placeService;
+    }
+
+    public void load() {
+        logger.debug("DataLoadCensus::load");
+        loadImage();
+        loadPersonImage();
+        loadPlaceImage();
+    }
+
+    private void loadImage() {
+        logger.debug("DataLoadCensus::loadImage");
+        ImageCommand imageCommand = new ImageCommandImpl();
+
+        imageService.saveImageCommand(imageCommand);
+    }
+
+    private void loadPersonImage() {
+        logger.debug("DataLoadCensus::loadPersonImage");
+        PersonImageCommand imageCommand = new PersonImageCommandImpl();
+        imageCommand.setPerson(personService.findById(1L));
+
+        personImageService.savePersonImageCommand(imageCommand);
+    }
+
+    private void loadPlaceImage() {
+        logger.debug("DataLoadCensus::loadPlaceImage");
+        PlaceImageCommand imageCommand = new PlaceImageCommandImpl();
+        imageCommand.setPlace(placeService.findById(1L));
+
+        placeImageService.savePlaceImageCommand(imageCommand);
+    }
+
+
+
+}

+ 48 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadPeople.java

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c)  18 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.people.Person;
+import scot.carricksoftware.grants.services.people.PersonService;
+
+
+@Component
+public class DataLoadPeople {
+
+    private static final Logger logger = LogManager.getLogger(DataLoadPeople.class);
+
+    private final PersonService personService;
+
+    public DataLoadPeople(PersonService personService) {
+        this.personService = personService;
+    }
+
+    public void load() {
+        logger.debug("DataLoadPlaces::load");
+        loadDad();
+        loadMum();
+    }
+
+    private void loadDad() {
+        final Person dad = new Person();
+        dad.setFirstName("Andrew");
+        dad.setLastName("Grant");
+        personService.save(dad);
+    }
+
+    private void loadMum() {
+        final Person mum = new Person();
+        mum.setFirstName("Dorothy");
+        mum.setLastName("Bramall");
+        personService.save(mum);
+
+    }
+
+
+}

+ 82 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadPlaces.java

@@ -0,0 +1,82 @@
+/*
+ * Copyright (c)  18 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.places.Country;
+import scot.carricksoftware.grants.domains.places.Place;
+import scot.carricksoftware.grants.domains.places.Region;
+import scot.carricksoftware.grants.services.places.countries.CountryService;
+import scot.carricksoftware.grants.services.places.places.PlaceService;
+import scot.carricksoftware.grants.services.places.regions.RegionService;
+
+@Component
+public class DataLoadPlaces {
+
+    private static final Logger logger = LogManager.getLogger(DataLoadPlaces.class);
+
+    private final CountryService countryService;
+    private final RegionService regionService;
+    private final PlaceService placeService;
+
+    public DataLoadPlaces(CountryService countryService,
+                          RegionService regionService,
+                          PlaceService placeService) {
+        this.countryService = countryService;
+        this.regionService = regionService;
+        this.placeService = placeService;
+    }
+
+    public void load() {
+        logger.debug("DataLoadPlaces::load");
+        loadCountries();
+        loadRegions();
+        loadPlaces();
+    }
+
+
+    final Country scotland = new Country();
+    final Country england = new Country();
+
+    final Region inverness = new Region();
+    final Region midlothian = new Region();
+
+    private void loadCountries() {
+        scotland.setName("Scotland");
+        countryService.save(scotland);
+        england.setName("England");
+        countryService.save(england);
+    }
+
+    private void loadRegions() {
+
+
+        inverness.setName("Inverness");
+        inverness.setCountry(scotland);
+        regionService.save(inverness);
+
+        midlothian.setName("Midlothian");
+        midlothian.setCountry(scotland);
+        regionService.save(midlothian);
+    }
+
+    private void loadPlaces() {
+        final Place bellFieldPark = new Place();
+        final Place wilsonAvenue = new Place();
+
+        bellFieldPark.setName("5 Bellfield Park");
+        bellFieldPark.setRegion(inverness);
+        placeService.save(bellFieldPark);
+
+        wilsonAvenue.setName("2 Wilson Avenue");
+        wilsonAvenue.setRegion(midlothian);
+        placeService.save(wilsonAvenue);
+    }
+
+
+}

+ 63 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadTexts.java

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c)  18 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.commands.text.*;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.services.places.places.PlaceService;
+import scot.carricksoftware.grants.services.text.documenttext.DocumentTextService;
+import scot.carricksoftware.grants.services.text.persontext.PersonTextService;
+import scot.carricksoftware.grants.services.text.placetext.PlaceTextService;
+
+@Component
+public class DataLoadTexts {
+
+    private static final Logger logger = LogManager.getLogger(DataLoadTexts.class);
+
+    private final DocumentTextService documentTextService;
+    private final PersonTextService personTextService;
+    private final PlaceTextService placeTextService;
+    private final PersonService personService;
+    private final PlaceService placeService;
+
+    public DataLoadTexts(DocumentTextService documentTextService,
+                         PersonTextService personTextService, PlaceTextService placeTextService,
+                         PersonService personService, PlaceService placeService) {
+        this.documentTextService = documentTextService;
+        this.personTextService = personTextService;
+        this.placeTextService = placeTextService;
+        this.personService = personService;
+        this.placeService = placeService;
+    }
+
+    public void load() {
+        logger.debug("DataLoadPlaces::load");
+        loadDocumentText();
+        loadPersonText();
+        loadPlaceText();
+    }
+
+    private void loadDocumentText() {
+        DocumentTextCommand documentTextCommand = new DocumentTextCommandImpl();
+        documentTextService.saveDocumentTextCommand(documentTextCommand);
+    }
+
+    private void loadPersonText() {
+        PersonTextCommand personTextCommand = new PersonTextCommandImpl();
+        personTextCommand.setPerson(personService.findById(1L));
+        personTextService.savePersonTextCommand(personTextCommand);
+    }
+
+    private void loadPlaceText() {
+        PlaceTextCommand placeTextCommand = new PlaceTextCommandImpl();
+        placeTextCommand.setPlace(placeService.findById(1L));
+        placeTextService.savePlaceTextCommand(placeTextCommand);
+    }
+
+}

+ 58 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoadTwoPartyCertificates.java

@@ -0,0 +1,58 @@
+/*
+ * Copyright (c)  18 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.certificates.DivorceCertificate;
+import scot.carricksoftware.grants.domains.certificates.MarriageCertificate;
+import scot.carricksoftware.grants.services.certificates.divorcecertificates.DivorceCertificateService;
+import scot.carricksoftware.grants.services.certificates.marriagecertificates.MarriageCertificateService;
+import scot.carricksoftware.grants.services.people.PersonService;
+
+@Component
+public class DataLoadTwoPartyCertificates {
+
+    private static final Logger logger = LogManager.getLogger(DataLoadTwoPartyCertificates.class);
+
+    private final MarriageCertificateService marriageCertificateService;
+    private final DivorceCertificateService divorceCertificateService;
+    private final PersonService personService;
+
+    public DataLoadTwoPartyCertificates(MarriageCertificateService marriageCertificateService,
+                                        DivorceCertificateService divorceCertificateService,
+                                        PersonService personService) {
+
+        this.marriageCertificateService = marriageCertificateService;
+        this.divorceCertificateService = divorceCertificateService;
+        this.personService = personService;
+    }
+
+    public void load() {
+        logger.debug("DataLoadPlaces::load");
+        loadMarriageCertificates();
+        loadDivorceCertificates();
+    }
+
+
+    private void loadMarriageCertificates() {
+        MarriageCertificate marriageCertificate = new MarriageCertificate();
+        marriageCertificate.setGroom(personService.findById(1L));
+        marriageCertificate.setBride(personService.findById(2L));
+        marriageCertificateService.save(marriageCertificate);
+
+    }
+
+    private void loadDivorceCertificates() {
+        DivorceCertificate divorceCertificate = new DivorceCertificate();
+        divorceCertificate.setFirstParty(personService.findById(1L));
+        divorceCertificate.setSecondParty(personService.findById(2L));
+        divorceCertificateService.save(divorceCertificate);
+    }
+
+
+}

+ 35 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoader.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2025- 03 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class DataLoader implements CommandLineRunner {
+
+
+    private static final Logger logger = LogManager.getLogger(DataLoader.class);
+
+    private final DataLoaderPrimary dataLoaderPrimary;
+    private final DataLoaderSecondary dataLoaderSecondary;
+
+    public DataLoader(DataLoaderPrimary dataLoaderPrimary, DataLoaderSecondary dataLoaderSecondary) {
+        this.dataLoaderPrimary = dataLoaderPrimary;
+        this.dataLoaderSecondary = dataLoaderSecondary;
+    }
+
+    @Override
+    public void run(String... args) {
+        logger.debug("DataLoader::run");
+        dataLoaderPrimary.load();
+        dataLoaderSecondary.load();
+    }
+
+}

+ 35 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoaderPrimary.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2025- 03 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class DataLoaderPrimary {
+
+    private static final Logger logger = LogManager.getLogger(DataLoaderPrimary.class);
+
+    private final DataLoadPlaces dataLoadPlaces;
+    private final DataLoadPeople dataLoadPeople;
+    private final DataLoadCensus dataLoadCensus;
+
+    public DataLoaderPrimary(DataLoadPlaces dataLoadPlaces, DataLoadPeople dataLoadPeople, DataLoadCensus dataLoadCensus) {
+        this.dataLoadPlaces = dataLoadPlaces;
+        this.dataLoadPeople = dataLoadPeople;
+        this.dataLoadCensus = dataLoadCensus;
+    }
+
+    public void load () {
+        logger.debug("DataLoaderPrimary::load");
+        dataLoadPlaces.load();
+        dataLoadPeople.load();
+        dataLoadCensus.load();
+    }
+
+}

+ 42 - 0
src/main/java/scot/carricksoftware/grants/bootstrap/DataLoaderSecondary.java

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2025- 03 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.bootstrap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class DataLoaderSecondary {
+
+
+    private static final Logger logger = LogManager.getLogger(DataLoaderSecondary.class);
+
+    private final DataLoadCertificates dataLoadCertificates;
+    private final DataLoadTwoPartyCertificates dataLoadTwoPartyCertificates;
+    private final DataLoadTexts dataLoadTexts;
+    private final DataLoadImages dataLoadImages;
+
+    public DataLoaderSecondary(DataLoadCertificates dataLoadCertificates,
+                               DataLoadTwoPartyCertificates dataLoadTwoPartyCertificates,
+                               DataLoadTexts dataLoadTexts,
+                               DataLoadImages dataLoadImages) {
+        this.dataLoadCertificates = dataLoadCertificates;
+        this.dataLoadTwoPartyCertificates = dataLoadTwoPartyCertificates;
+        this.dataLoadTexts = dataLoadTexts;
+        this.dataLoadImages = dataLoadImages;
+    }
+
+    public void load() {
+        logger.debug("DataLoaderSecondary::load");
+        dataLoadCertificates.load();
+        dataLoadTwoPartyCertificates.load();
+        dataLoadImages.load();
+        dataLoadTexts.load();
+    }
+
+}

+ 30 - 0
src/main/java/scot/carricksoftware/grants/commands/census/CensusCommand.java

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 19/03/2025, 01:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.census;
+
+import scot.carricksoftware.grants.domains.census.CensusEntry;
+import scot.carricksoftware.grants.domains.places.Place;
+
+import java.time.LocalDate;
+import java.util.List;
+
+public interface CensusCommand {
+    Long getId();
+
+    void setId(Long id);
+
+    LocalDate getDate();
+
+    void setDate(LocalDate date);
+
+    List<CensusEntry> getCensusEntries();
+
+    void setCensusEntries(List<CensusEntry> censusEntries);
+
+    Place getPlace();
+
+    void setPlace(Place place);
+}

+ 64 - 0
src/main/java/scot/carricksoftware/grants/commands/census/CensusCommandImpl.java

@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 19/03/2025, 02:00. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.census;
+
+import scot.carricksoftware.grants.domains.census.CensusEntry;
+import scot.carricksoftware.grants.domains.places.Place;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CensusCommandImpl implements CensusCommand {
+
+    private Long id;
+
+    private LocalDate date;
+
+    private List<CensusEntry> censusEntries = new ArrayList<>();
+
+    private Place place;
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public LocalDate getDate() {
+        return date;
+    }
+
+    @Override
+    public void setDate(LocalDate date) {
+        this.date = date;
+    }
+
+    @Override
+    public List<CensusEntry> getCensusEntries() {
+        return censusEntries;
+    }
+
+    @Override
+    public void setCensusEntries(List<CensusEntry> censusEntries) {
+        this.censusEntries = censusEntries;
+    }
+
+    @Override
+    public Place getPlace() {
+        return place;
+    }
+
+    @Override
+    public void setPlace(Place place) {
+        this.place = place;
+    }
+}

+ 28 - 0
src/main/java/scot/carricksoftware/grants/commands/census/CensusEntryCommand.java

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 20/03/2025, 11:13. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.census;
+
+import scot.carricksoftware.grants.domains.census.Census;
+import scot.carricksoftware.grants.domains.people.Person;
+
+public interface CensusEntryCommand {
+
+    Long getId();
+
+    void setId(Long id);
+
+    String getName();
+
+    void setName(String name);
+
+    Census getCensus();
+
+    void setCensus(Census census);
+
+    Person getPerson();
+
+    void setPerson(Person person);
+}

+ 58 - 0
src/main/java/scot/carricksoftware/grants/commands/census/CensusEntryCommandImpl.java

@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 19/03/2025, 02:00. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.census;
+
+import scot.carricksoftware.grants.domains.census.Census;
+import scot.carricksoftware.grants.domains.people.Person;
+
+public class CensusEntryCommandImpl implements CensusEntryCommand {
+
+    private Long id;
+
+    private String name;
+
+    private Census census;
+
+    private Person person;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public Census getCensus() {
+        return census;
+    }
+
+    @Override
+    public void setCensus(Census census) {
+        this.census = census;
+    }
+
+    @Override
+    public Person getPerson() {
+        return this.person;
+    }
+
+    @Override
+    public void setPerson(Person person) {
+        this.person = person;
+    }
+}

+ 20 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/birthcertificates/BirthCertificateCommand.java

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:51. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.birthcertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public interface BirthCertificateCommand {
+
+
+    Long getId();
+
+    void setId(Long id);
+
+    Person getNewBorn();
+
+    void setNewBorn(Person newBorn);
+}

+ 33 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/birthcertificates/BirthCertificateCommandImpl.java

@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:51. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.birthcertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public class BirthCertificateCommandImpl implements BirthCertificateCommand {
+
+    Long Id;
+
+    Person newBorn;
+
+    public Long getId() {
+        return Id;
+    }
+
+    public void setId(Long id) {
+        Id = id;
+    }
+
+    @Override
+    public Person getNewBorn() {
+        return this.newBorn;
+    }
+
+    @Override
+    public void setNewBorn(Person newBorn) {
+        this.newBorn = newBorn;
+    }
+}

+ 20 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/deathcertificates/DeathCertificateCommand.java

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:51. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.deathcertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public interface DeathCertificateCommand {
+
+
+    Long getId();
+
+    void setId(Long id);
+
+    Person getDeceased();
+
+    void setDeceased(Person deceased);
+}

+ 35 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/deathcertificates/DeathCertificateCommandImpl.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:52. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.deathcertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public class DeathCertificateCommandImpl implements DeathCertificateCommand {
+
+    Long Id;
+
+    Person deceased;
+
+
+    public Long getId() {
+        return Id;
+    }
+
+    public void setId(Long id) {
+        Id = id;
+    }
+
+    @Override
+    public Person getDeceased() {
+        return deceased;
+    }
+
+    @Override
+    public void setDeceased(Person deceased) {
+        this.deceased = deceased;
+    }
+
+}

+ 26 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/divorcecertificates/DivorceCertificateCommand.java

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:53. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.divorcecertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public interface DivorceCertificateCommand {
+
+
+    Long getId();
+
+    void setId(Long id);
+
+    Person getFirstParty();
+
+    void setFirstParty(Person firstParty);
+
+    Person getSecondParty();
+
+    void setSecondParty(Person secondParty);
+
+
+}

+ 44 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/divorcecertificates/DivorceCertificateCommandImpl.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:53. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.divorcecertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public class DivorceCertificateCommandImpl implements DivorceCertificateCommand {
+
+    Long Id;
+
+    private Person firstParty;
+
+    private Person secondParty;
+
+    public Person getFirstParty() {
+        return firstParty;
+    }
+
+    public void setFirstParty(Person firstParty) {
+        this.firstParty = firstParty;
+    }
+
+    public Person getSecondParty() {
+        return secondParty;
+    }
+
+    public void setSecondParty(Person secondParty) {
+        this.secondParty = secondParty;
+    }
+
+
+    public Long getId() {
+        return Id;
+    }
+
+    public void setId(Long id) {
+        Id = id;
+    }
+
+
+}

+ 25 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/marriagecertificates/MarriageCertificateCommand.java

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:52. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.marriagecertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public interface MarriageCertificateCommand {
+
+
+    Long getId();
+
+    void setId(Long id);
+
+
+    Person getBride();
+
+    void setBride(Person bride);
+
+    Person getGroom();
+
+    void setGroom(Person groom);
+}

+ 50 - 0
src/main/java/scot/carricksoftware/grants/commands/certificates/marriagecertificates/MarriageCertificateCommandImpl.java

@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 26/03/2025, 23:52. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.certificates.marriagecertificates;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public class MarriageCertificateCommandImpl implements MarriageCertificateCommand {
+
+    Long Id;
+
+    Person bride;
+
+    Person groom;
+
+    @Override
+    public Long getId() {
+        return Id;
+    }
+
+    public void setId(Long id) {
+        Id = id;
+    }
+
+
+    @Override
+    public Person getBride() {
+        return bride;
+    }
+
+
+    @Override
+    public void setBride(Person bride) {
+        this.bride = bride;
+    }
+
+
+    @Override
+    public Person getGroom() {
+        return groom;
+    }
+
+
+    @Override
+    public void setGroom(Person groom) {
+        this.groom = groom;
+    }
+}

+ 12 - 0
src/main/java/scot/carricksoftware/grants/commands/images/ImageCommand.java

@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 28/03/2025, 09:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.images;
+
+public interface ImageCommand {
+    Long getId();
+
+    void setId(Long id);
+}

+ 24 - 0
src/main/java/scot/carricksoftware/grants/commands/images/ImageCommandImpl.java

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 28/03/2025, 09:59. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.images;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ImageCommandImpl implements ImageCommand{
+
+    Long Id;
+
+    @Override
+    public Long getId() {
+        return Id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        Id = id;
+    }
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/commands/images/PersonImageCommand.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 28/03/2025, 09:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.images;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public interface PersonImageCommand {
+    Long getId();
+
+    void setId(Long id);
+
+    Person getPerson();
+
+    void setPerson(Person person);
+}

+ 36 - 0
src/main/java/scot/carricksoftware/grants/commands/images/PersonImageCommandImpl.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 28/03/2025, 09:59. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.images;
+
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.people.Person;
+
+@Component
+public class PersonImageCommandImpl implements PersonImageCommand{
+    Long Id;
+
+    Person person;
+
+    @Override
+    public Long getId() {
+        return Id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        Id = id;
+    }
+
+    @Override
+    public Person getPerson() {
+        return person;
+    }
+
+    @Override
+    public void setPerson(Person person) {
+        this.person = person;
+    }
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/commands/images/PlaceImageCommand.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 28/03/2025, 09:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.images;
+
+import scot.carricksoftware.grants.domains.places.Place;
+
+public interface PlaceImageCommand {
+    Long getId();
+
+    void setId(Long id);
+
+    Place getPlace();
+
+    void setPlace(Place place);
+}

+ 36 - 0
src/main/java/scot/carricksoftware/grants/commands/images/PlaceImageCommandImpl.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 28/03/2025, 09:59. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.images;
+
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.places.Place;
+
+@Component
+public class PlaceImageCommandImpl implements PlaceImageCommand{
+    Long Id;
+
+    Place place;
+
+    @Override
+    public Long getId() {
+        return Id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        Id = id;
+    }
+
+   @Override
+   public Place getPlace() {
+        return place;
+    }
+
+    @Override
+    public void setPlace(Place place) {
+        this.place = place;
+    }
+}

+ 21 - 0
src/main/java/scot/carricksoftware/grants/commands/people/PersonCommand.java

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 18/03/2025, 02:05. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.people;
+
+public interface PersonCommand {
+
+    Long getId();
+
+    void setId(Long id);
+
+    String getFirstName();
+
+    void setFirstName(String firstName);
+
+    String getLastName();
+
+    void setLastName(String lastName);
+}

+ 40 - 0
src/main/java/scot/carricksoftware/grants/commands/people/PersonCommandImpl.java

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 18/03/2025, 02:05. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.people;
+
+public class PersonCommandImpl implements PersonCommand {
+
+    Long Id;
+
+    String firstName;
+
+    String lastName;
+
+
+    public Long getId() {
+        return Id;
+    }
+
+    public void setId(Long id) {
+        Id = id;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/commands/places/countries/CountryCommand.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 17:17. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.places.countries;
+
+import scot.carricksoftware.grants.domains.places.Region;
+
+import java.util.List;
+
+public interface CountryCommand {
+
+    Long getId();
+
+    void setId(Long id);
+
+    @SuppressWarnings("unused")
+    String getName();
+
+    @SuppressWarnings("unused")
+    void setName(String name);
+
+    List<Region> getRegions();
+
+    void setRegions(List<Region> regions);
+}
+
+

+ 52 - 0
src/main/java/scot/carricksoftware/grants/commands/places/countries/CountryCommandImpl.java

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 17:17. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.places.countries;
+
+
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.places.Region;
+
+import java.util.List;
+
+@Component
+public class CountryCommandImpl implements CountryCommand {
+
+    private Long id;
+
+    private String name;
+
+    private List<Region> regions;
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public List<Region> getRegions() {
+        return regions;
+    }
+
+    @Override
+    public void setRegions(List<Region> regions) {
+        this.regions = regions;
+    }
+}

+ 35 - 0
src/main/java/scot/carricksoftware/grants/commands/places/places/PlaceCommand.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c)  20 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.commands.places.places;
+
+
+import scot.carricksoftware.grants.domains.census.Census;
+import scot.carricksoftware.grants.domains.places.Region;
+
+import java.util.List;
+
+public interface PlaceCommand {
+
+    @SuppressWarnings("unused")
+    Long getId();
+
+    @SuppressWarnings("unused")
+    void setId(Long id);
+
+    @SuppressWarnings("unused")
+    String getName();
+
+    @SuppressWarnings("unused")
+    void setName(String name);
+
+    Region getRegion();
+
+    void setRegion(Region region);
+
+    List<Census> getCensuses();
+
+    void setCensuses(List<Census> censuses);
+}

+ 64 - 0
src/main/java/scot/carricksoftware/grants/commands/places/places/PlaceCommandImpl.java

@@ -0,0 +1,64 @@
+/*
+ * Copyright (c)  20 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.commands.places.places;
+
+import scot.carricksoftware.grants.domains.census.Census;
+import scot.carricksoftware.grants.domains.places.Region;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SuppressWarnings("unused")
+public class PlaceCommandImpl implements PlaceCommand {
+    private Long id;
+
+    private Region region;
+
+    private String name;
+
+    private List<Census> censuses = new ArrayList<>();
+
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public Region getRegion() {
+        return region;
+    }
+
+    @Override
+    public void setRegion(Region region) {
+        this.region = region;
+    }
+
+    @Override
+    public List<Census> getCensuses() {
+        return censuses;
+    }
+
+    @Override
+    public void setCensuses(List<Census> censuses) {
+        this.censuses = censuses;
+    }
+}

+ 36 - 0
src/main/java/scot/carricksoftware/grants/commands/places/regions/RegionCommand.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 17:17. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.places.regions;
+
+
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.places.Country;
+import scot.carricksoftware.grants.domains.places.Place;
+
+import java.util.List;
+
+@Component
+public interface RegionCommand {
+
+
+    Long getId();
+
+    void setId(Long id);
+
+    @SuppressWarnings("unused")
+    String getName();
+
+    @SuppressWarnings("unused")
+    void setName(String name);
+
+    Country getCountry();
+
+    void setCountry(Country country);
+
+    List<Place> getPlaces();
+
+    void setPlaces(List<Place> places);
+}

+ 66 - 0
src/main/java/scot/carricksoftware/grants/commands/places/regions/RegionCommandImpl.java

@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 17:17. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.places.regions;
+
+import org.springframework.stereotype.Component;
+import scot.carricksoftware.grants.domains.places.Country;
+import scot.carricksoftware.grants.domains.places.Place;
+
+import java.util.List;
+
+@Component
+public class RegionCommandImpl implements RegionCommand {
+
+    private Long id;
+
+    private String name;
+
+    private Country country;
+
+    List<Place> Places;
+
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public Country getCountry() {
+        return country;
+    }
+
+    @Override
+    public void setCountry(Country country) {
+        this.country = country;
+    }
+
+    @Override
+    public List<Place> getPlaces() {
+        return Places;
+    }
+
+    @Override
+    public void setPlaces(List<Place> places) {
+        Places = places;
+    }
+}

+ 12 - 0
src/main/java/scot/carricksoftware/grants/commands/text/DocumentTextCommand.java

@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 30/03/2025, 10:42. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.text;
+
+public interface DocumentTextCommand {
+    Long getId();
+
+    void setId(Long id);
+}

+ 23 - 0
src/main/java/scot/carricksoftware/grants/commands/text/DocumentTextCommandImpl.java

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 30/03/2025, 10:42. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.text;
+
+public class DocumentTextCommandImpl implements DocumentTextCommand {
+
+    Long Id;
+
+    @Override
+    public Long getId() {
+        return Id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        Id = id;
+    }
+
+
+}

+ 19 - 0
src/main/java/scot/carricksoftware/grants/commands/text/PersonTextCommand.java

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 30/03/2025, 10:42. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.text;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public interface
+PersonTextCommand {
+    Long getId();
+
+    void setId(Long id);
+
+    Person getPerson();
+
+    void setPerson(Person person);
+}

+ 35 - 0
src/main/java/scot/carricksoftware/grants/commands/text/PersonTextCommandImpl.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 30/03/2025, 10:42. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.text;
+
+import scot.carricksoftware.grants.domains.people.Person;
+
+public class PersonTextCommandImpl implements PersonTextCommand {
+
+    Long Id;
+
+    Person person;
+
+    @Override
+    public Long getId() {
+        return Id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        Id = id;
+    }
+
+    @Override
+    public Person getPerson() {
+        return person;
+    }
+
+    @Override
+    public void setPerson(Person person) {
+        this.person = person;
+    }
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/commands/text/PlaceTextCommand.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 30/03/2025, 10:42. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.text;
+
+import scot.carricksoftware.grants.domains.places.Place;
+
+public interface PlaceTextCommand {
+    Long getId();
+
+    void setId(Long id);
+
+    Place getPlace();
+
+    void setPlace(Place place);
+}

+ 36 - 0
src/main/java/scot/carricksoftware/grants/commands/text/PlaceTextCommandImpl.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 30/03/2025, 10:42. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.commands.text;
+
+
+import scot.carricksoftware.grants.domains.places.Place;
+
+public class PlaceTextCommandImpl implements PlaceTextCommand {
+
+    Long Id;
+
+    Place place;
+
+    @Override
+    public Long getId() {
+        return Id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        Id = id;
+    }
+
+    @Override
+    public Place getPlace() {
+        return place;
+    }
+
+    @Override
+    public void setPlace(Place place) {
+        this.place = place;
+    }
+}

+ 27 - 0
src/main/java/scot/carricksoftware/grants/constants/ApplicationConstants.java

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 19:54. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+import java.time.format.DateTimeFormatter;
+
+@SuppressWarnings("unused")
+@Component
+public class ApplicationConstants {
+
+    private ApplicationConstants() {
+        // to stop checkstyle complaining
+    }
+
+    public static final int DEFAULT_PAGE_SIZE = 15;
+    public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy");
+    public final static String EMPTY_STRING = "";
+
+    public static final int MINIMUM_NAME_LENGTH = 3;
+    public static final int MAXIMUM_NAME_LENGTH = 40;
+
+}

+ 65 - 0
src/main/java/scot/carricksoftware/grants/constants/AttributeConstants.java

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c)  08 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class AttributeConstants {
+
+    private AttributeConstants() {
+        // to stop checkstyle complaining
+    }
+
+    @SuppressWarnings("unused")
+    public static final String PEOPLE = "people";
+    @SuppressWarnings("unused")
+    public static final String PERSON_COMMAND = "personCommand";
+
+    public static final String COUNTRIES = "countries";
+    @SuppressWarnings("unused")
+    public static final String COUNTRY_COMMAND = "countryCommand";
+
+    @SuppressWarnings("unused")
+    public static final String REGIONS = "regions";
+    @SuppressWarnings("unused")
+    public static final String REGION_COMMAND = "regionCommand";
+
+    @SuppressWarnings("unused")
+    public static final String PLACES = "places";
+    @SuppressWarnings("unused")
+    public static final String PLACE_COMMAND = "placeCommand";
+
+    @SuppressWarnings("unused")
+    public static final String CENSUSES = "censuses";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_COMMAND = "censusCommand";
+
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRIES = "censusEntries";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_ENTRY_COMMAND = "censusEntryCommand";
+
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATES = "birthCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_COMMAND = "birthCertificateCommand";
+
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATES = "deathCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_COMMAND = "deathCertificateCommand";
+
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATES = "marriageCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_COMMAND = "marriageCertificateCommand";
+
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATES = "divorceCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_COMMAND = "divorceCertificateCommand";
+}

+ 25 - 0
src/main/java/scot/carricksoftware/grants/constants/ButtonConstants.java

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c)  07 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ButtonConstants {
+    private ButtonConstants() {
+        // to stop checkstyle complaining
+    }
+
+    public static final String BACK = "<";
+    public static final String DELETE = "Delete";
+    public static final String EDIT = "Edit";
+    public static final String NEW = "New ";//Note the space at the end
+    public static final String HOME = "Home ";
+    public static final String REWIND = "<<";
+    public static final String END = ">>";
+    public static final String FORWARD = ">";
+
+}

+ 40 - 0
src/main/java/scot/carricksoftware/grants/constants/ImageAttributeConstants.java

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c)  08 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ImageAttributeConstants {
+
+    private ImageAttributeConstants() {
+        // to stop checkstyle complaining
+    }
+
+    @SuppressWarnings({"unused"})
+    public static final String IMAGES = "images";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_COMMAND = "imageCommand";
+
+    public static final String PERSON_IMAGES = "personImages";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_COMMAND = "personImageCommand";
+
+
+    public static final String PLACE_IMAGES = "placeImages";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_COMMAND = "placeImageCommand";
+
+
+
+
+
+
+}
+
+
+
+

+ 87 - 0
src/main/java/scot/carricksoftware/grants/constants/ImageMappingConstants.java

@@ -0,0 +1,87 @@
+/*
+ * Copyright (c)  08 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ImageMappingConstants {
+
+    private ImageMappingConstants() {
+        // to stop checkstyle complaining
+    }
+
+
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_LIST = "/images";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_NEXT = "/images/next";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_PREVIOUS = "/images/prev";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_REWIND = "/images/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_FF = "/images/ff";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_NEW = "/image/new";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE = "/image";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_SHOW = "/image/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_DELETE = "/image/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String IMAGE_EDIT = "image/{id}/edit";
+
+
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_LIST = "/personImages";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_NEXT = "/personImages/next";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_PREVIOUS = "/personImages/prev";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_REWIND = "/personImages/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_FF = "/personImages/ff";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_NEW = "/personImage/new";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE = "/personImage";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_SHOW = "/personImage/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_DELETE = "/personImage/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String PERSON_IMAGE_EDIT = "personImage/{id}/edit";
+
+    public static final String PLACE_IMAGE_LIST = "/placeImages";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_NEXT = "/placeImages/next";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_PREVIOUS = "/placeImages/prev";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_REWIND = "/placeImages/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_FF = "/placeImages/ff";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_NEW = "/placeImage/new";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE = "/placeImage";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_SHOW = "/placeImage/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_DELETE = "/placeImage/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String PLACE_IMAGE_EDIT = "placeImage/{id}/edit";
+
+}
+
+
+
+
+
+

+ 226 - 0
src/main/java/scot/carricksoftware/grants/constants/MappingConstants.java

@@ -0,0 +1,226 @@
+/*
+ * Copyright (c)  08 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class MappingConstants {
+
+    private MappingConstants() {
+        // to stop checkstyle complaining
+    }
+
+    @SuppressWarnings("unused")
+    public static final String PEOPLE_LIST = "/people";
+    @SuppressWarnings("unused")
+    public static final String PEOPLE_NEXT = "/people/next";
+    @SuppressWarnings("unused")
+    public static final String PEOPLE_PREVIOUS = "/people/prev";
+    @SuppressWarnings("unused")
+    public static final String PEOPLE_REWIND = "/people/rewind";
+    @SuppressWarnings("unused")
+    public static final String PEOPLE_FF = "/people/ff";
+    @SuppressWarnings("unused")
+    public static final String PERSON_NEW = "/person/new";
+    @SuppressWarnings("unused")
+    public static final String PERSON = "/person";
+    @SuppressWarnings("unused")
+    public static final String PEOPLE = "/people";
+    @SuppressWarnings("unused")
+    public static final String PERSON_SHOW = "/person/{id}/show";
+    @SuppressWarnings("unused")
+    public static final String PERSON_DELETE = "/person/{id}/delete";
+    @SuppressWarnings("unused")
+    public static final String PERSON_EDIT = "/person/{id}/edit";
+    public static final String REDIRECT = "redirect:";
+
+    public static final String COUNTRY_LIST = "/countries";
+    public static final String COUNTRY_NEXT = "/countries/next";
+    public static final String COUNTRY_PREVIOUS = "/countries/prev";
+    public static final String COUNTRY_REWIND = "/countries/rewind";
+    public static final String COUNTRY_FF = "/countries/ff";
+    @SuppressWarnings("unused")
+    public static final String COUNTRY_NEW = "/country/new";
+    @SuppressWarnings("unused")
+    public static final String COUNTRY = "/country";
+    public static final String COUNTRIES = "/countries";
+    @SuppressWarnings("unused")
+    public static final String COUNTRY_SHOW = "/country/{id}/show";
+    public static final String COUNTRY_DELETE = "/country/{id}/delete";
+    @SuppressWarnings("unused")
+    public static final String COUNTRY_EDIT = "country/{id}/edit";
+
+    @SuppressWarnings("unused")
+    public static final String REGION_LIST = "/regions";
+    @SuppressWarnings("unused")
+    public static final String REGION_NEXT = "/regions/next";
+    @SuppressWarnings("unused")
+    public static final String REGION_PREVIOUS = "/regions/prev";
+    @SuppressWarnings("unused")
+    public static final String REGION_REWIND = "/regions/rewind";
+    @SuppressWarnings("unused")
+    public static final String REGION_FF = "/regions/ff";
+    @SuppressWarnings("unused")
+    public static final String REGION_NEW = "/region/new";
+    @SuppressWarnings("unused")
+    public static final String REGION = "/region";
+    @SuppressWarnings("unused")
+    public static final String REGIONS = "/regions";
+    @SuppressWarnings("unused")
+    public static final String REGION_SHOW = "/region/{id}/show";
+    @SuppressWarnings("unused")
+    public static final String REGION_DELETE = "/region/{id}/delete";
+    @SuppressWarnings("unused")
+    public static final String REGION_EDIT = "region/{id}/edit";
+
+    @SuppressWarnings("unused")
+    public static final String PLACE_LIST = "/places";
+    @SuppressWarnings("unused")
+    public static final String PLACE_NEXT = "/places/next";
+    @SuppressWarnings("unused")
+    public static final String PLACE_PREVIOUS = "/places/prev";
+    @SuppressWarnings("unused")
+    public static final String PLACE_REWIND = "/places/rewind";
+    @SuppressWarnings("unused")
+    public static final String PLACE_FF = "/places/ff";
+    @SuppressWarnings("unused")
+    public static final String PLACE_NEW = "/place/new";
+    @SuppressWarnings("unused")
+    public static final String PLACE = "/place";
+    @SuppressWarnings("unused")
+    public static final String PLACE_SHOW = "/place/{id}/show";
+    @SuppressWarnings("unused")
+    public static final String PLACE_DELETE = "/place/{id}/delete";
+    @SuppressWarnings("unused")
+    public static final String PLACE_EDIT = "place/{id}/edit";
+
+    @SuppressWarnings("unused")
+    public static final String CENSUS_LIST = "/censuses";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_NEXT = "/censuses/next";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_PREVIOUS = "/censuses/prev";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_REWIND = "/censuses/rewind";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_FF = "/censuses/ff";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_NEW = "/census/new";
+    @SuppressWarnings("unused")
+    public static final String CENSUS = "/census";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_SHOW = "/census/{id}/show";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_DELETE = "/census/{id}/delete";
+    @SuppressWarnings("unused")
+    public static final String CENSUS_EDIT = "census/{id}/edit";
+
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_LIST = "/censusEntries";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_NEXT = "/censusEntries/next";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_PREVIOUS = "/censusEntries/prev";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_REWIND = "/censusEntries/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_FF = "/censusEntries/ff";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_NEW = "/censusEntry/new";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY = "/censusEntry";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_SHOW = "/censusEntry/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_DELETE = "/censusEntry/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String CENSUS_ENTRY_EDIT = "censusEntry/{id}/edit";
+
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_LIST = "/birthCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_NEXT = "/birthCertificates/next";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_PREVIOUS = "/birthCertificates/prev";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_REWIND = "/birthCertificates/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_FF = "/birthCertificates/ff";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_NEW = "/birthCertificate/new";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE = "/birthCertificate";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_SHOW = "/birthCertificate/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_DELETE = "/birthCertificate/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String BIRTH_CERTIFICATE_EDIT = "birthCertificate/{id}/edit";
+
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_LIST = "/deathCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_NEXT = "/deathCertificates/next";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_PREVIOUS = "/deathCertificates/prev";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_REWIND = "/deathCertificates/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_FF = "/deathCertificates/ff";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_NEW = "/deathCertificate/new";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE = "/deathCertificate";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_SHOW = "/deathCertificate/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_DELETE = "/deathCertificate/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String DEATH_CERTIFICATE_EDIT = "deathCertificate/{id}/edit";
+
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_LIST = "/marriageCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_NEXT = "/marriageCertificates/next";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_PREVIOUS = "/marriageCertificates/prev";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_REWIND = "/marriageCertificates/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_FF = "/marriageCertificates/ff";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_NEW = "/marriageCertificate/new";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE = "/marriageCertificate";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_SHOW = "/marriageCertificate/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_DELETE = "/marriageCertificate/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String MARRIAGE_CERTIFICATE_EDIT = "marriageCertificate/{id}/edit";
+
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_LIST = "/divorceCertificates";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_NEXT = "/divorceCertificates/next";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_PREVIOUS = "/divorceCertificates/prev";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_REWIND = "/divorceCertificates/rewind";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_FF = "/divorceCertificates/ff";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_NEW = "/divorceCertificate/new";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE = "/divorceCertificate";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_SHOW = "/divorceCertificate/{id}/show";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_DELETE = "/divorceCertificate/{id}/delete";
+    @SuppressWarnings({"unused"})
+    public static final String DIVORCE_CERTIFICATE_EDIT = "divorceCertificate/{id}/edit";
+}

+ 39 - 0
src/main/java/scot/carricksoftware/grants/constants/ValidationConstants.java

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 19:54. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+
+@SuppressWarnings("unused")
+@Component
+public class ValidationConstants {
+    private ValidationConstants() {
+        // to stop checkstyle complaining
+    }
+
+
+    public static final String NAME_IS_TOO_SHORT = "Name must be at least " + ApplicationConstants.MINIMUM_NAME_LENGTH + " characters long.";
+    public static final String NAME_IS_TOO_LONG = "Name must be no more than " + ApplicationConstants.MAXIMUM_NAME_LENGTH + " characters long.";
+    public static final String DATE_IS_NULL = "Date must exist.";
+    public static final String DATE_IN_FUTURE = "Date should not be in the future.";
+    public static final String CENSUS_IS_NULL = "The census should be specified";
+    public static final String CENSUS_NAME_IS_NULL = "Either Person or Untracked Person must be given";
+    public static final String CENSUS_NAME_IS_NOT_NULL = "Both Person and Untracked Person cannot be given";
+
+    public static final String PERSON_IS_NULL = "The person cannot be null.";
+    public static final String PLACE_IS_NULL = "The place cannot be null.";
+
+    public static final String BRIDE_IS_NULL = "The bride cannot be null.";
+    public static final String GROOM_IS_NULL = "The groom cannot be null.";
+    public static final String SAME_BRIDE_AND_GROOM = "The bride and groom cannot be the same person.";
+
+    public static final String FIRST_PARTY_IS_NULL = "The first party cannot be null.";
+    public static final String SECOND_PARTY_IS_NULL = "The second party cannot be null.";
+    public static final String SAME_TWO_PARTIES = "The two parties cannot be the same person.";
+
+
+}

+ 60 - 0
src/main/java/scot/carricksoftware/grants/constants/ViewConstants.java

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c)  06 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.constants;
+
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("ALL")
+@Component
+public class ViewConstants {
+
+
+    private ViewConstants() {
+        // to stop checkstyle complaining
+    }
+
+
+    public static final String PEOPLE_LIST = "person/list";
+    public static final String PERSON_FORM = "person/form";
+
+    public static final String COUNTRY_LIST = "country/list";
+    public static final String COUNTRY_FORM = "country/form";
+
+    public static final String REGION_LIST = "region/list";
+    public static final String REGION_FORM = "region/form";
+
+    public static final String PLACE_LIST = "place/list";
+    public static final String PLACE_FORM = "place/form";
+
+    public static final String CENSUS_LIST = "census/list";
+    public static final String CENSUS_FORM = "census/form";
+
+    public static final String CENSUS_ENTRY_LIST = "censusentry/list";
+    public static final String CENSUS_ENTRY_FORM = "censusentry/form";
+
+    @SuppressWarnings("unused")
+    public static final String BIRTH_CERTIFICATE_LIST = "certificates/birthCertificate/list";
+    public static final String BIRTH_CERTIFICATE_FORM = "certificates/birthCertificate/form";
+
+    public static final String DEATH_CERTIFICATE_LIST = "certificates/deathCertificate/list";
+    public static final String DEATH_CERTIFICATE_FORM = "certificates/deathCertificate/form";
+
+    public static final String MARRIAGE_CERTIFICATE_LIST = "certificates/marriageCertificate/list";
+    public static final String MARRIAGE_CERTIFICATE_FORM = "certificates/marriageCertificate/form";
+
+    public static final String DIVORCE_CERTIFICATE_LIST = "certificates/divorceCertificate/list";
+    public static final String DIVORCE_CERTIFICATE_FORM = "certificates/divorceCertificate/form";
+
+    public static final String IMAGE_LIST = "images/image/list";
+    public static final String IMAGE_FORM = "images/image/form";
+
+    public static final String PERSON_IMAGE_LIST = "images/personImage/list";
+    public static final String PERSON_IMAGE_FORM = "images/personImage/form";
+
+    public static final String PLACE_IMAGE_LIST = "images/placeImage/list";
+    public static final String PLACE_IMAGE_FORM = "images/placeImage/form";
+}
+

+ 17 - 0
src/main/java/scot/carricksoftware/grants/controllers/ControllerHelper.java

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c)  09 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.controllers;
+
+import org.springframework.stereotype.Component;
+import org.springframework.ui.Model;
+
+
+@SuppressWarnings("unused")
+@Component
+public interface ControllerHelper {
+
+    void addAttributes(Model model);
+}

+ 27 - 0
src/main/java/scot/carricksoftware/grants/controllers/ControllerHelperImpl.java

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c)  09 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.controllers;
+
+import org.springframework.stereotype.Component;
+import org.springframework.ui.Model;
+import scot.carricksoftware.grants.constants.ButtonConstants;
+
+@SuppressWarnings("unused")
+@Component
+public class ControllerHelperImpl implements ControllerHelper {
+
+    @SuppressWarnings("unused")
+    public void addAttributes(Model model) {
+        model.addAttribute("BUTTON_BACK", ButtonConstants.BACK);
+        model.addAttribute("BUTTON_DELETE", ButtonConstants.DELETE);
+        model.addAttribute("BUTTON_EDIT", ButtonConstants.EDIT);
+        model.addAttribute("BUTTON_NEW", ButtonConstants.NEW);
+        model.addAttribute("BUTTON_HOME", ButtonConstants.HOME);
+        model.addAttribute("BUTTON_REWIND", ButtonConstants.REWIND);
+        model.addAttribute("BUTTON_END", ButtonConstants.END);
+        model.addAttribute("BUTTON_FORWARD", ButtonConstants.FORWARD);
+    }
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusFormController.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.census;
+
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import scot.carricksoftware.grants.commands.census.CensusCommand;
+
+@SuppressWarnings("unused")
+
+public interface CensusFormController {
+
+    String saveOrUpdate(@ModelAttribute CensusCommand censusCommand, BindingResult bindingResult, Model model);
+}

+ 92 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusFormControllerImpl.java

@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.census;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.census.CensusCommand;
+import scot.carricksoftware.grants.commands.census.CensusCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.census.CensusConverter;
+import scot.carricksoftware.grants.services.census.CensusService;
+import scot.carricksoftware.grants.validators.census.CensusCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class CensusFormControllerImpl implements CensusFormController {
+
+    private static final Logger logger = LogManager.getLogger(CensusFormControllerImpl.class);
+    private final CensusService censusService;
+    private final CensusCommandValidator censusCommandValidator;
+    private final CensusConverter censusConverter;
+
+
+    public CensusFormControllerImpl(CensusService censusService,
+                                    CensusCommandValidator censusCommandValidator,
+                                    CensusConverter censusConverter) {
+        this.censusService = censusService;
+        this.censusCommandValidator = censusCommandValidator;
+        this.censusConverter = censusConverter;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_NEW)
+    public final String getNewCensus(final Model model) {
+        logger.debug("CensusFormControllerImpl::getNewCensus");
+        model.addAttribute(AttributeConstants.CENSUS_COMMAND, new CensusCommandImpl());
+        return ViewConstants.CENSUS_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_EDIT)
+    public final String censusEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("CensusFormControllerImpl::censusEdit");
+        model.addAttribute(AttributeConstants.CENSUS_COMMAND, censusService.findById(Long.valueOf(id)));
+        return ViewConstants.CENSUS_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.CENSUS)
+    public String saveOrUpdate(@Valid @ModelAttribute CensusCommand censusCommand, BindingResult bindingResult, Model model) {
+        logger.debug("CensusFormControllerImpl::saveOrUpdate");
+
+        censusCommandValidator.validate(censusCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            return ViewConstants.CENSUS_FORM;
+        }
+
+
+        CensusCommand savedCommand = censusService.saveCensusCommand(censusCommand);
+        model.addAttribute(AttributeConstants.CENSUS_COMMAND, savedCommand);
+        return MappingConstants.REDIRECT + MappingConstants.CENSUS_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_SHOW)
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("CensusFormControllerImpl::saveOrUpdate");
+        CensusCommand savedCommand = censusConverter.convert(censusService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.CENSUS_COMMAND, savedCommand);
+        return ViewConstants.CENSUS_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.census;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface CensusListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String censusDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 107 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/census/CensusListControllerImpl.java

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:09. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.census;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.census.CensusService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class CensusListControllerImpl implements CensusListController {
+
+    private static final Logger logger = LogManager.getLogger(CensusListControllerImpl.class);
+
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final CensusService censusService;
+
+    public CensusListControllerImpl(ControllerHelper controllerHelper,
+                                    CensusService censusService) {
+        this.controllerHelper = controllerHelper;
+        this.censusService = censusService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getCensusPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.CENSUSES, censusService.getPagedCensuses(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.CENSUS_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("CensusListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("CensusListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("CensusListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("CensusListControllerImpl::getLastPage");
+        long censusCount = censusService.count();
+        currentPage = (int) (censusCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_DELETE)
+    @Override
+    public final String censusDelete(@PathVariable final String id) {
+        logger.debug("CensusListControllerImpl::censusDelete");
+        censusService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.CENSUS_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormController.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.censusentry;
+
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommand;
+
+@SuppressWarnings("unused")
+
+public interface CensusEntryFormController {
+
+    String saveOrUpdate(@ModelAttribute CensusEntryCommand censusEntryCommand, BindingResult bindingResult, Model model);
+}

+ 109 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryFormControllerImpl.java

@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.censusentry;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommand;
+import scot.carricksoftware.grants.commands.census.CensusEntryCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.Capitalisation;
+import scot.carricksoftware.grants.converters.census.CensusEntryConverter;
+import scot.carricksoftware.grants.services.census.CensusEntryService;
+import scot.carricksoftware.grants.services.census.CensusService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.validators.census.CensusEntryCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class CensusEntryFormControllerImpl implements CensusEntryFormController {
+
+    private static final Logger logger = LogManager.getLogger(CensusEntryFormControllerImpl.class);
+    private final CensusEntryService censusEntryService;
+    private final CensusEntryCommandValidator censusEntryCommandValidator;
+    private final CensusEntryConverter censusEntryConverter;
+    private final Capitalisation capitalisation;
+    private final PersonService personService;
+    private final CensusService censusService;
+
+
+    public CensusEntryFormControllerImpl(CensusEntryService censusEntryService,
+                                         CensusEntryCommandValidator censusEntryCommandValidator,
+                                         CensusEntryConverter censusEntryConverter,
+                                         Capitalisation capitalisation, PersonService personService, CensusService censusService) {
+        this.censusEntryService = censusEntryService;
+        this.censusEntryCommandValidator = censusEntryCommandValidator;
+        this.censusEntryConverter = censusEntryConverter;
+        this.capitalisation = capitalisation;
+        this.personService = personService;
+        this.censusService = censusService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_NEW)
+    public final String getNewCensusEntry(final Model model) {
+        logger.debug("CensusEntryFormControllerImpl::getNewCensusEntry");
+        model.addAttribute(AttributeConstants.CENSUS_ENTRY_COMMAND, new CensusEntryCommandImpl());
+        model.addAttribute(AttributeConstants.CENSUSES, censusService.findAll());
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.CENSUS_ENTRY_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_EDIT)
+    public final String censusEntryEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("CensusEntryFormControllerImpl::censusEntryEdit");
+        model.addAttribute(AttributeConstants.CENSUS_ENTRY_COMMAND, censusEntryService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.CENSUSES, censusService.findAll());
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.CENSUS_ENTRY_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.CENSUS_ENTRY)
+    public String saveOrUpdate(@Valid @ModelAttribute CensusEntryCommand censusEntryCommand, BindingResult bindingResult, Model model) {
+        logger.debug("CensusEntryFormControllerImpl::saveOrUpdate");
+
+        censusEntryCommandValidator.validate(censusEntryCommand, bindingResult);
+        censusEntryCommand.setName(capitalisation.getCapitalisation(censusEntryCommand.getName()));
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+            model.addAttribute(AttributeConstants.CENSUSES, censusService.findAll());
+            return ViewConstants.CENSUS_ENTRY_FORM;
+        }
+
+        CensusEntryCommand savedCommand = censusEntryService.saveCensusEntryCommand(censusEntryCommand);
+        model.addAttribute(AttributeConstants.CENSUS_ENTRY_COMMAND, savedCommand);
+        return MappingConstants.REDIRECT + MappingConstants.CENSUS_ENTRY_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_SHOW)
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("CensusEntryFormControllerImpl::saveOrUpdate");
+        CensusEntryCommand savedCommand = censusEntryConverter.convert(censusEntryService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        model.addAttribute(AttributeConstants.CENSUS_ENTRY_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.CENSUSES, censusService.findAll());
+        return ViewConstants.CENSUS_ENTRY_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:07. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.censusentry;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface CensusEntryListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String censusEntryDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 108 - 0
src/main/java/scot/carricksoftware/grants/controllers/census/censusentry/CensusEntryListControllerImpl.java

@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 21/03/2025, 00:07. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.census.censusentry;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.census.CensusEntryService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class CensusEntryListControllerImpl implements CensusEntryListController {
+
+    private static final Logger logger = LogManager.getLogger(CensusEntryListControllerImpl.class);
+
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final CensusEntryService censusEntryService;
+
+
+    public CensusEntryListControllerImpl(ControllerHelper controllerHelper,
+                                         CensusEntryService censusEntryService) {
+        this.controllerHelper = controllerHelper;
+        this.censusEntryService = censusEntryService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getCensusEntryPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.CENSUS_ENTRIES, censusEntryService.getPagedCensusEntries(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.CENSUS_ENTRY_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("CensusEntryListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("CensusEntryListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("CensusEntryListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("CensusEntryListControllerImpl::getLastPage");
+        long censusEntryCount = censusEntryService.count();
+        currentPage = (int) (censusEntryCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.CENSUS_ENTRY_DELETE)
+    @Override
+    public final String censusEntryDelete(@PathVariable final String id) {
+        logger.debug("CensusEntryListControllerImpl::censusEntryDelete");
+        censusEntryService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.CENSUS_ENTRY_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 34 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateFormController.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.birthcertificates;
+
+import jakarta.validation.Valid;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.commands.certificates.birthcertificates.BirthCertificateCommand;
+import scot.carricksoftware.grants.constants.MappingConstants;
+
+@SuppressWarnings("unused")
+
+public interface BirthCertificateFormController {
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_NEW)
+    String getNewBirthCertificate(Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_EDIT)
+    String birthCertificateEdit(@Valid @PathVariable String id, Model model);
+
+    String saveOrUpdate(@ModelAttribute BirthCertificateCommand countryCommand, BindingResult bindingResult, Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_SHOW)
+    String showById(@PathVariable String id, Model model);
+}

+ 110 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateFormControllerImpl.java

@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.birthcertificates;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.certificates.birthcertificates.BirthCertificateCommand;
+import scot.carricksoftware.grants.commands.certificates.birthcertificates.BirthCertificateCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.certificates.birthcertificates.BirthCertificateCommandConverterImpl;
+import scot.carricksoftware.grants.converters.certificates.birthcertificates.BirthCertificateConverterImpl;
+import scot.carricksoftware.grants.services.certificates.birthcertificates.BirthCertificateService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.validators.certificates.BirthCertificateCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class BirthCertificateFormControllerImpl implements BirthCertificateFormController {
+
+    private static final Logger logger = LogManager.getLogger(BirthCertificateFormControllerImpl.class);
+    private final BirthCertificateService birthCertificateService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final BirthCertificateCommandConverterImpl birthCertificateCommandConverter;
+    private final BirthCertificateConverterImpl birthCertificateConverter;
+    private final BirthCertificateCommandValidator birthCertificateCommandValidator;
+    private final PersonService personService;
+
+
+    public BirthCertificateFormControllerImpl(BirthCertificateService birthCertificateService,
+                                              BirthCertificateCommandConverterImpl birthCertificateCommandConverter,
+                                              BirthCertificateConverterImpl birthCertificateConverter,
+                                              BirthCertificateCommandValidator birthCertificateCommandValidator,
+                                              PersonService personService) {
+        this.birthCertificateService = birthCertificateService;
+        this.birthCertificateCommandConverter = birthCertificateCommandConverter;
+
+
+        this.birthCertificateConverter = birthCertificateConverter;
+        this.birthCertificateCommandValidator = birthCertificateCommandValidator;
+        this.personService = personService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_NEW)
+    @Override
+    public final String getNewBirthCertificate(final Model model) {
+        logger.debug("BirthCertificateFormControllerImpl::getNewBirthCertificate");
+        model.addAttribute(AttributeConstants.BIRTH_CERTIFICATE_COMMAND, new BirthCertificateCommandImpl());
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.BIRTH_CERTIFICATE_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_EDIT)
+    @Override
+    public final String birthCertificateEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("BirthCertificateFormControllerImpl::birthCertificateEdit");
+        model.addAttribute(AttributeConstants.BIRTH_CERTIFICATE_COMMAND, birthCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.BIRTH_CERTIFICATE_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.BIRTH_CERTIFICATE)
+    public String saveOrUpdate(@Valid @ModelAttribute BirthCertificateCommand birthCertificateCommand, BindingResult bindingResult, Model model) {
+        logger.debug("BirthCertificateFormControllerImpl::saveOrUpdate");
+
+        birthCertificateCommandValidator.validate(birthCertificateCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+            return ViewConstants.BIRTH_CERTIFICATE_FORM;
+        }
+
+        BirthCertificateCommand savedCommand = birthCertificateService.saveBirthCertificateCommand(birthCertificateCommand);
+        model.addAttribute(AttributeConstants.BIRTH_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return MappingConstants.REDIRECT + MappingConstants.BIRTH_CERTIFICATE_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_SHOW)
+    @Override
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("BirthCertificateFormControllerImpl::saveOrUpdate");
+        BirthCertificateCommand savedCommand = birthCertificateConverter.convert(birthCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.BIRTH_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.BIRTH_CERTIFICATE_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.birthcertificates;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface BirthCertificateListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String birthCertificateDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 106 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/birthcertificates/BirthCertificateListControllerImpl.java

@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.birthcertificates;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.certificates.birthcertificates.BirthCertificateService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class BirthCertificateListControllerImpl implements BirthCertificateListController {
+
+    private static final Logger logger = LogManager.getLogger(BirthCertificateListControllerImpl.class);
+    private final BirthCertificateService birthCertificateService;
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+
+    public BirthCertificateListControllerImpl(ControllerHelper controllerHelper,
+                                              BirthCertificateService birthCertificateService) {
+        this.controllerHelper = controllerHelper;
+        this.birthCertificateService = birthCertificateService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("BirthCertificateListControllerImpl::getCensusPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.BIRTH_CERTIFICATES, birthCertificateService.getPagedBirthCertificates(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.BIRTH_CERTIFICATE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("BirthCertificateListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("BirthCertificateListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("BirthCertificateListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("BirthCertificateListControllerImpl::getLastPage");
+        long certificateCount = birthCertificateService.count();
+        currentPage = (int) (certificateCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.BIRTH_CERTIFICATE_DELETE)
+    @Override
+    public final String birthCertificateDelete(@PathVariable final String id) {
+        logger.debug("BirthCertificateControllerImpl::censusDelete");
+        birthCertificateService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.BIRTH_CERTIFICATE_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 34 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateFormController.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.deathcertificates;
+
+import jakarta.validation.Valid;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.commands.certificates.deathcertificates.DeathCertificateCommand;
+import scot.carricksoftware.grants.constants.MappingConstants;
+
+@SuppressWarnings("unused")
+
+public interface DeathCertificateFormController {
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_NEW)
+    String getNewDeathCertificate(Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_EDIT)
+    String deathCertificateEdit(@Valid @PathVariable String id, Model model);
+
+    String saveOrUpdate(@ModelAttribute DeathCertificateCommand deathCertificateCommand, BindingResult bindingResult, Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_SHOW)
+    String showById(@PathVariable String id, Model model);
+}

+ 109 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateFormControllerImpl.java

@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.deathcertificates;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.certificates.deathcertificates.DeathCertificateCommand;
+import scot.carricksoftware.grants.commands.certificates.deathcertificates.DeathCertificateCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.certificates.deathcertificates.DeathCertificateCommandConverterImpl;
+import scot.carricksoftware.grants.converters.certificates.deathcertificates.DeathCertificateConverterImpl;
+import scot.carricksoftware.grants.services.certificates.deathcertificates.DeathCertificateService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.validators.certificates.DeathCertificateCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class DeathCertificateFormControllerImpl implements DeathCertificateFormController {
+
+    private static final Logger logger = LogManager.getLogger(DeathCertificateFormControllerImpl.class);
+    private final DeathCertificateService deathCertificateService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final DeathCertificateCommandConverterImpl deathCertificateCommandConverter;
+    private final DeathCertificateConverterImpl deathCertificateConverter;
+    private final DeathCertificateCommandValidator deathCertificateCommandValidator;
+    private final PersonService personService;
+
+
+    public DeathCertificateFormControllerImpl(DeathCertificateService deathCertificateService,
+                                              DeathCertificateCommandConverterImpl deathCertificateCommandConverter,
+                                              DeathCertificateConverterImpl deathCertificateConverter,
+                                              DeathCertificateCommandValidator deathCertificateCommandValidator, PersonService personService) {
+        this.deathCertificateService = deathCertificateService;
+        this.deathCertificateCommandConverter = deathCertificateCommandConverter;
+
+
+        this.deathCertificateConverter = deathCertificateConverter;
+        this.deathCertificateCommandValidator = deathCertificateCommandValidator;
+        this.personService = personService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_NEW)
+    @Override
+    public final String getNewDeathCertificate(final Model model) {
+        logger.debug("DeathCertificateFormControllerImpl::getNewDeathCertificate");
+        model.addAttribute(AttributeConstants.DEATH_CERTIFICATE_COMMAND, new DeathCertificateCommandImpl());
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.DEATH_CERTIFICATE_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_EDIT)
+    @Override
+    public final String deathCertificateEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("DeathCertificateFormControllerImpl::deathCertificateEdit");
+        model.addAttribute(AttributeConstants.DEATH_CERTIFICATE_COMMAND, deathCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.DEATH_CERTIFICATE_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.DEATH_CERTIFICATE)
+    public String saveOrUpdate(@Valid @ModelAttribute DeathCertificateCommand deathCertificateCommand, BindingResult bindingResult, Model model) {
+        logger.debug("DeathCertificateFormControllerImpl::saveOrUpdate");
+
+        deathCertificateCommandValidator.validate(deathCertificateCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+            return ViewConstants.DEATH_CERTIFICATE_FORM;
+        }
+
+        DeathCertificateCommand savedCommand = deathCertificateService.saveDeathCertificateCommand(deathCertificateCommand);
+        model.addAttribute(AttributeConstants.DEATH_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return MappingConstants.REDIRECT + MappingConstants.DEATH_CERTIFICATE_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_SHOW)
+    @Override
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("DeathCertificateFormControllerImpl::saveOrUpdate");
+        DeathCertificateCommand savedCommand = deathCertificateConverter.convert(deathCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.DEATH_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.DEATH_CERTIFICATE_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.deathcertificates;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface DeathCertificateListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String deathCertificateDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 106 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/deathcertificates/DeathCertificateListControllerImpl.java

@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.deathcertificates;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.certificates.deathcertificates.DeathCertificateService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class DeathCertificateListControllerImpl implements DeathCertificateListController {
+
+    private static final Logger logger = LogManager.getLogger(DeathCertificateListControllerImpl.class);
+    private final DeathCertificateService deathCertificateService;
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+
+    public DeathCertificateListControllerImpl(ControllerHelper controllerHelper,
+                                              DeathCertificateService deathCertificateService) {
+        this.controllerHelper = controllerHelper;
+        this.deathCertificateService = deathCertificateService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("DeathCertificateListControllerImpl::getCensusPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.DEATH_CERTIFICATES, deathCertificateService.getPagedDeathCertificates(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.DEATH_CERTIFICATE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("DeathCertificateListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("DeathCertificateListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("DeathCertificateListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("DeathCertificateListControllerImpl::getLastPage");
+        long certificateCount = deathCertificateService.count();
+        currentPage = (int) (certificateCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DEATH_CERTIFICATE_DELETE)
+    @Override
+    public final String deathCertificateDelete(@PathVariable final String id) {
+        logger.debug("DeathCertificateControllerImpl::censusDelete");
+        deathCertificateService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.DEATH_CERTIFICATE_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 34 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateFormController.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.divorcecertificates;
+
+import jakarta.validation.Valid;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.commands.certificates.divorcecertificates.DivorceCertificateCommand;
+import scot.carricksoftware.grants.constants.MappingConstants;
+
+@SuppressWarnings("unused")
+
+public interface DivorceCertificateFormController {
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_NEW)
+    String getNewDivorceCertificate(Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_EDIT)
+    String divorceCertificateEdit(@Valid @PathVariable String id, Model model);
+
+    String saveOrUpdate(@ModelAttribute DivorceCertificateCommand divorceCertificateCommand, BindingResult bindingResult, Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_SHOW)
+    String showById(@PathVariable String id, Model model);
+}

+ 109 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateFormControllerImpl.java

@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.divorcecertificates;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.certificates.divorcecertificates.DivorceCertificateCommand;
+import scot.carricksoftware.grants.commands.certificates.divorcecertificates.DivorceCertificateCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.certificates.divorcecertificates.DivorceCertificateCommandConverterImpl;
+import scot.carricksoftware.grants.converters.certificates.divorcecertificates.DivorceCertificateConverterImpl;
+import scot.carricksoftware.grants.services.certificates.divorcecertificates.DivorceCertificateService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.validators.certificates.DivorceCertificateCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class DivorceCertificateFormControllerImpl implements DivorceCertificateFormController {
+
+    private static final Logger logger = LogManager.getLogger(DivorceCertificateFormControllerImpl.class);
+    private final DivorceCertificateService divorceCertificateService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final DivorceCertificateCommandConverterImpl divorceCertificateCommandConverter;
+    private final DivorceCertificateConverterImpl divorceCertificateConverter;
+    private final DivorceCertificateCommandValidator divorceCertificateCommandValidator;
+    private final PersonService personService;
+
+
+    public DivorceCertificateFormControllerImpl(DivorceCertificateService divorceCertificateService,
+                                                DivorceCertificateCommandConverterImpl divorceCertificateCommandConverter,
+                                                DivorceCertificateConverterImpl divorceCertificateConverter,
+                                                DivorceCertificateCommandValidator divorceCertificateCommandValidator, PersonService personService) {
+        this.divorceCertificateService = divorceCertificateService;
+        this.divorceCertificateCommandConverter = divorceCertificateCommandConverter;
+
+
+        this.divorceCertificateConverter = divorceCertificateConverter;
+        this.divorceCertificateCommandValidator = divorceCertificateCommandValidator;
+        this.personService = personService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_NEW)
+    @Override
+    public final String getNewDivorceCertificate(final Model model) {
+        logger.debug("DivorceCertificateFormControllerImpl::getNewDivorceCertificate");
+        model.addAttribute(AttributeConstants.DIVORCE_CERTIFICATE_COMMAND, new DivorceCertificateCommandImpl());
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.DIVORCE_CERTIFICATE_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_EDIT)
+    @Override
+    public final String divorceCertificateEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("DivorceCertificateFormControllerImpl::divorceCertificateEdit");
+        model.addAttribute(AttributeConstants.DIVORCE_CERTIFICATE_COMMAND, divorceCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.DIVORCE_CERTIFICATE_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.DIVORCE_CERTIFICATE)
+    public String saveOrUpdate(@Valid @ModelAttribute DivorceCertificateCommand divorceCertificateCommand, BindingResult bindingResult, Model model) {
+        logger.debug("DivorceCertificateFormControllerImpl::saveOrUpdate");
+
+        divorceCertificateCommandValidator.validate(divorceCertificateCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+            return ViewConstants.DIVORCE_CERTIFICATE_FORM;
+        }
+
+        DivorceCertificateCommand savedCommand = divorceCertificateService.saveDivorceCertificateCommand(divorceCertificateCommand);
+        model.addAttribute(AttributeConstants.DIVORCE_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return MappingConstants.REDIRECT + MappingConstants.DIVORCE_CERTIFICATE_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_SHOW)
+    @Override
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("DivorceCertificateFormControllerImpl::saveOrUpdate");
+        DivorceCertificateCommand savedCommand = divorceCertificateConverter.convert(divorceCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.DIVORCE_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.DIVORCE_CERTIFICATE_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.divorcecertificates;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface DivorceCertificateListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String divorceCertificateDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 106 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/divorcecertificates/DivorceCertificateListControllerImpl.java

@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.divorcecertificates;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.certificates.divorcecertificates.DivorceCertificateService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class DivorceCertificateListControllerImpl implements DivorceCertificateListController {
+
+    private static final Logger logger = LogManager.getLogger(DivorceCertificateListControllerImpl.class);
+    private final DivorceCertificateService divorceCertificateService;
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+
+    public DivorceCertificateListControllerImpl(ControllerHelper controllerHelper,
+                                                DivorceCertificateService divorceCertificateService) {
+        this.controllerHelper = controllerHelper;
+        this.divorceCertificateService = divorceCertificateService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("DivorceCertificateListControllerImpl::getCensusPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.DIVORCE_CERTIFICATES, divorceCertificateService.getPagedDivorceCertificates(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.DIVORCE_CERTIFICATE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("DivorceCertificateListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("DivorceCertificateListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("DivorceCertificateListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("DivorceCertificateListControllerImpl::getLastPage");
+        long certificateCount = divorceCertificateService.count();
+        currentPage = (int) (certificateCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.DIVORCE_CERTIFICATE_DELETE)
+    @Override
+    public final String divorceCertificateDelete(@PathVariable final String id) {
+        logger.debug("DivorceCertificateControllerImpl::censusDelete");
+        divorceCertificateService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.DIVORCE_CERTIFICATE_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 35 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateFormController.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.marriagecertificates;
+
+import jakarta.validation.Valid;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.commands.certificates.marriagecertificates.MarriageCertificateCommand;
+import scot.carricksoftware.grants.constants.MappingConstants;
+
+@SuppressWarnings("unused")
+
+public interface MarriageCertificateFormController {
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_NEW)
+    String getNewMarriageCertificate(Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_EDIT)
+    String marriageCertificateEdit(@Valid @PathVariable String id, Model model);
+
+    String saveOrUpdate(@ModelAttribute MarriageCertificateCommand marriageCertificateCommand, BindingResult bindingResult, Model model);
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_SHOW)
+    String showById(@PathVariable String id, Model model);
+}

+ 110 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateFormControllerImpl.java

@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.marriagecertificates;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.certificates.marriagecertificates.MarriageCertificateCommand;
+import scot.carricksoftware.grants.commands.certificates.marriagecertificates.MarriageCertificateCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.certificates.marriagecertificates.MarriageCertificateCommandConverterImpl;
+import scot.carricksoftware.grants.converters.certificates.marriagecertificates.MarriageCertificateConverterImpl;
+import scot.carricksoftware.grants.services.certificates.marriagecertificates.MarriageCertificateService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.validators.certificates.MarriageCertificateCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class MarriageCertificateFormControllerImpl implements MarriageCertificateFormController {
+
+    private static final Logger logger = LogManager.getLogger(MarriageCertificateFormControllerImpl.class);
+    private final MarriageCertificateService marriageCertificateService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final MarriageCertificateCommandConverterImpl marriageCertificateCommandConverter;
+    private final MarriageCertificateConverterImpl marriageCertificateConverter;
+    private final MarriageCertificateCommandValidator marriageCertificateCommandValidator;
+    private final PersonService personService;
+
+
+    public MarriageCertificateFormControllerImpl(MarriageCertificateService marriageCertificateService,
+                                                 MarriageCertificateCommandConverterImpl marriageCertificateCommandConverter,
+                                                 MarriageCertificateConverterImpl marriageCertificateConverter,
+                                                 MarriageCertificateCommandValidator marriageCertificateCommandValidator,
+                                                 PersonService personService) {
+        this.marriageCertificateService = marriageCertificateService;
+        this.marriageCertificateCommandConverter = marriageCertificateCommandConverter;
+
+
+        this.marriageCertificateConverter = marriageCertificateConverter;
+        this.marriageCertificateCommandValidator = marriageCertificateCommandValidator;
+        this.personService = personService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_NEW)
+    @Override
+    public final String getNewMarriageCertificate(final Model model) {
+        logger.debug("MarriageCertificateFormControllerImpl::getNewMarriageCertificate");
+        model.addAttribute(AttributeConstants.MARRIAGE_CERTIFICATE_COMMAND, new MarriageCertificateCommandImpl());
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.MARRIAGE_CERTIFICATE_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_EDIT)
+    @Override
+    public final String marriageCertificateEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("MarriageCertificateFormControllerImpl::marriageCertificateEdit");
+        model.addAttribute(AttributeConstants.MARRIAGE_CERTIFICATE_COMMAND, marriageCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.MARRIAGE_CERTIFICATE_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.MARRIAGE_CERTIFICATE)
+    public String saveOrUpdate(@Valid @ModelAttribute MarriageCertificateCommand marriageCertificateCommand, BindingResult bindingResult, Model model) {
+        logger.debug("MarriageCertificateFormControllerImpl::saveOrUpdate");
+
+        marriageCertificateCommandValidator.validate(marriageCertificateCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+            return ViewConstants.MARRIAGE_CERTIFICATE_FORM;
+        }
+
+        MarriageCertificateCommand savedCommand = marriageCertificateService.saveMarriageCertificateCommand(marriageCertificateCommand);
+        model.addAttribute(AttributeConstants.MARRIAGE_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return MappingConstants.REDIRECT + MappingConstants.MARRIAGE_CERTIFICATE_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_SHOW)
+    @Override
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("MarriageCertificateFormControllerImpl::saveOrUpdate");
+        MarriageCertificateCommand savedCommand = marriageCertificateConverter.convert(marriageCertificateService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.MARRIAGE_CERTIFICATE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.MARRIAGE_CERTIFICATE_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.marriagecertificates;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface MarriageCertificateListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String marriageCertificateDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 106 - 0
src/main/java/scot/carricksoftware/grants/controllers/certificates/marriagecertificates/MarriageCertificateListControllerImpl.java

@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 25/03/2025, 19:58. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.certificates.marriagecertificates;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.certificates.marriagecertificates.MarriageCertificateService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class MarriageCertificateListControllerImpl implements MarriageCertificateListController {
+
+    private static final Logger logger = LogManager.getLogger(MarriageCertificateListControllerImpl.class);
+    private final MarriageCertificateService marriageCertificateService;
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+
+    public MarriageCertificateListControllerImpl(ControllerHelper controllerHelper,
+                                                 MarriageCertificateService marriageCertificateService) {
+        this.controllerHelper = controllerHelper;
+        this.marriageCertificateService = marriageCertificateService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("MarriageCertificateListControllerImpl::getCensusPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.MARRIAGE_CERTIFICATES, marriageCertificateService.getPagedMarriageCertificates(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.MARRIAGE_CERTIFICATE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("MarriageCertificateListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("MarriageCertificateListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("MarriageCertificateListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("MarriageCertificateListControllerImpl::getLastPage");
+        long certificateCount = marriageCertificateService.count();
+        currentPage = (int) (certificateCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.MARRIAGE_CERTIFICATE_DELETE)
+    @Override
+    public final String marriageCertificateDelete(@PathVariable final String id) {
+        logger.debug("MarriageCertificateControllerImpl::censusDelete");
+        marriageCertificateService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.MARRIAGE_CERTIFICATE_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageFormController.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.images;
+
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import scot.carricksoftware.grants.commands.images.ImageCommand;
+
+@SuppressWarnings("unused")
+
+public interface ImageFormController {
+
+    String saveOrUpdate(@ModelAttribute ImageCommand imageCommand, BindingResult bindingResult, Model model);
+}

+ 97 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageFormControllerImpl.java

@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.images;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.images.ImageCommand;
+import scot.carricksoftware.grants.commands.images.ImageCommandImpl;
+import scot.carricksoftware.grants.constants.*;
+import scot.carricksoftware.grants.converters.images.image.ImageCommandConverterImpl;
+import scot.carricksoftware.grants.converters.images.image.ImageConverterImpl;
+import scot.carricksoftware.grants.services.images.image.ImageService;
+import scot.carricksoftware.grants.validators.images.ImageCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class ImageFormControllerImpl implements ImageFormController {
+
+    private static final Logger logger = LogManager.getLogger(ImageFormControllerImpl.class);
+    private final ImageService imageService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final ImageCommandConverterImpl imageCommandConverter;
+    private final ImageConverterImpl imageConverter;
+    private final ImageCommandValidator imageCommandValidator;
+
+
+    public ImageFormControllerImpl(ImageService imageService,
+                                   ImageCommandConverterImpl imageCommandConverter,
+                                   ImageConverterImpl imageConverter,
+                                   ImageCommandValidator imageCommandValidator) {
+        this.imageService = imageService;
+        this.imageCommandConverter = imageCommandConverter;
+
+
+        this.imageConverter = imageConverter;
+        this.imageCommandValidator = imageCommandValidator;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_NEW)
+    public final String getNewImage(final Model model) {
+        logger.debug("ImageFormControllerImpl::getNewImage");
+        model.addAttribute(ImageAttributeConstants.IMAGE_COMMAND, new ImageCommandImpl());
+        return ViewConstants.IMAGE_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_EDIT)
+    public final String imageEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("ImageFormControllerImpl::imageEdit");
+        model.addAttribute(ImageAttributeConstants.IMAGE_COMMAND, imageService.findById(Long.valueOf(id)));
+        return ViewConstants.IMAGE_FORM;
+    }
+
+
+    @Override
+    @PostMapping(ImageMappingConstants.IMAGE)
+    public String saveOrUpdate(@Valid @ModelAttribute ImageCommand imageCommand, BindingResult bindingResult, Model model) {
+        logger.debug("ImageFormControllerImpl::saveOrUpdate");
+
+        imageCommandValidator.validate(imageCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            return ViewConstants.IMAGE_FORM;
+        }
+
+        ImageCommand savedCommand = imageService.saveImageCommand(imageCommand);
+        model.addAttribute(ImageAttributeConstants.IMAGE_COMMAND, savedCommand);
+        return MappingConstants.REDIRECT + ImageMappingConstants.IMAGE_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_SHOW)
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("ImageFormControllerImpl::saveOrUpdate");
+        ImageCommand savedCommand = imageConverter.convert(imageService.findById(Long.valueOf(id)));
+        model.addAttribute(ImageAttributeConstants.IMAGE_COMMAND, savedCommand);
+        return ViewConstants.IMAGE_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.images;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface ImageListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String imageDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 104 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/images/ImageListControllerImpl.java

@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.images;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.*;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.images.image.ImageService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class ImageListControllerImpl implements ImageListController {
+
+    private static final Logger logger = LogManager.getLogger(ImageListControllerImpl.class);
+
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final ImageService imageService;
+
+    public ImageListControllerImpl(ControllerHelper controllerHelper,
+                                   ImageService imageService) {
+        this.controllerHelper = controllerHelper;
+        this.imageService = imageService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getImagePage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(ImageAttributeConstants.IMAGES, imageService.getPagedImages(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.IMAGE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("ImageListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("ImageListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("ImageListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("ImageListControllerImpl::getLastPage");
+        long imageCount = imageService.count();
+        currentPage = (int) (imageCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.IMAGE_DELETE)
+    @Override
+    public final String imageDelete(@PathVariable final String id) {
+        logger.debug("ImageListControllerImpl::imageDelete");
+        imageService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.COUNTRIES;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageFormController.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.personImages;
+
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import scot.carricksoftware.grants.commands.images.PersonImageCommand;
+
+@SuppressWarnings("unused")
+
+public interface PersonImageFormController {
+
+    String saveOrUpdate(@ModelAttribute PersonImageCommand personImageCommand, BindingResult bindingResult, Model model);
+}

+ 105 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageFormControllerImpl.java

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.personImages;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.images.PersonImageCommand;
+import scot.carricksoftware.grants.commands.images.PersonImageCommandImpl;
+import scot.carricksoftware.grants.constants.*;
+import scot.carricksoftware.grants.converters.images.personimage.PersonImageCommandConverterImpl;
+import scot.carricksoftware.grants.converters.images.personimage.PersonImageConverterImpl;
+import scot.carricksoftware.grants.services.images.personimage.PersonImageService;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.validators.images.PersonImageCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class PersonImageFormControllerImpl implements PersonImageFormController {
+
+    private static final Logger logger = LogManager.getLogger(PersonImageFormControllerImpl.class);
+    private final PersonImageService personImageService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final PersonImageCommandConverterImpl personImageCommandConverter;
+    private final PersonImageConverterImpl personImageConverter;
+    private final PersonImageCommandValidator personImageCommandValidator;
+    private final PersonService personService;
+
+
+    public PersonImageFormControllerImpl(PersonImageService personImageService,
+                                         PersonImageCommandConverterImpl personImageCommandConverter,
+                                         PersonImageConverterImpl personImageConverter,
+                                         PersonImageCommandValidator personImageCommandValidator, PersonService personService) {
+        this.personImageService = personImageService;
+        this.personImageCommandConverter = personImageCommandConverter;
+
+
+        this.personImageConverter = personImageConverter;
+        this.personImageCommandValidator = personImageCommandValidator;
+        this.personService = personService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_NEW)
+    public final String getNewPersonImage(final Model model) {
+        logger.debug("PersonImageFormControllerImpl::getNewPersonImage");
+        model.addAttribute(ImageAttributeConstants.PERSON_IMAGE_COMMAND, new PersonImageCommandImpl());
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.PERSON_IMAGE_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_EDIT)
+    public final String personImageEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("PersonImageFormControllerImpl::personImageEdit");
+        model.addAttribute(ImageAttributeConstants.PERSON_IMAGE_COMMAND, personImageService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.PERSON_IMAGE_FORM;
+    }
+
+
+    @Override
+    @PostMapping(ImageMappingConstants.PERSON_IMAGE)
+    public String saveOrUpdate(@Valid @ModelAttribute PersonImageCommand personImageCommand, BindingResult bindingResult, Model model) {
+        logger.debug("PersonImageFormControllerImpl::saveOrUpdate");
+
+        personImageCommandValidator.validate(personImageCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+            return ViewConstants.PERSON_IMAGE_FORM;
+        }
+
+        PersonImageCommand savedCommand = personImageService.savePersonImageCommand(personImageCommand);
+        model.addAttribute(ImageAttributeConstants.PERSON_IMAGE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return MappingConstants.REDIRECT + ImageMappingConstants.PERSON_IMAGE_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_SHOW)
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("PersonImageFormControllerImpl::saveOrUpdate");
+        PersonImageCommand savedCommand = personImageConverter.convert(personImageService.findById(Long.valueOf(id)));
+        model.addAttribute(ImageAttributeConstants.PERSON_IMAGE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PEOPLE, personService.findAll());
+        return ViewConstants.PERSON_IMAGE_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.personImages;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface PersonImageListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String personImageDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 104 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/personImages/PersonImageListControllerImpl.java

@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.personImages;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.*;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.images.personimage.PersonImageService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class PersonImageListControllerImpl implements PersonImageListController {
+
+    private static final Logger logger = LogManager.getLogger(PersonImageListControllerImpl.class);
+
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final PersonImageService personImageService;
+
+    public PersonImageListControllerImpl(ControllerHelper controllerHelper,
+                                         PersonImageService personImageService) {
+        this.controllerHelper = controllerHelper;
+        this.personImageService = personImageService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getPersonImagePage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(ImageAttributeConstants.PERSON_IMAGES, personImageService.getPagedPersonImages(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.PERSON_IMAGE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("PersonImageListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("PersonImageListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("PersonImageListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("PersonImageListControllerImpl::getLastPage");
+        long personImageCount = personImageService.count();
+        currentPage = (int) (personImageCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PERSON_IMAGE_DELETE)
+    @Override
+    public final String personImageDelete(@PathVariable final String id) {
+        logger.debug("PersonImageListControllerImpl::personImageDelete");
+        personImageService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + ImageMappingConstants.PERSON_IMAGE_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageFormController.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.placeimages;
+
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import scot.carricksoftware.grants.commands.images.PlaceImageCommand;
+
+@SuppressWarnings("unused")
+
+public interface PlaceImageFormController {
+
+    String saveOrUpdate(@ModelAttribute PlaceImageCommand placeImageCommand, BindingResult bindingResult, Model model);
+}

+ 105 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageFormControllerImpl.java

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.placeimages;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.images.PlaceImageCommand;
+import scot.carricksoftware.grants.commands.images.PlaceImageCommandImpl;
+import scot.carricksoftware.grants.constants.*;
+import scot.carricksoftware.grants.converters.images.placeimage.PlaceImageCommandConverterImpl;
+import scot.carricksoftware.grants.converters.images.placeimage.PlaceImageConverterImpl;
+import scot.carricksoftware.grants.services.images.placeimage.PlaceImageService;
+import scot.carricksoftware.grants.services.places.places.PlaceService;
+import scot.carricksoftware.grants.validators.images.PlaceImageCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class PlaceImageFormControllerImpl implements PlaceImageFormController {
+
+    private static final Logger logger = LogManager.getLogger(PlaceImageFormControllerImpl.class);
+    private final PlaceImageService placeImageService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final PlaceImageCommandConverterImpl placeImageCommandConverter;
+    private final PlaceImageConverterImpl placeImageConverter;
+    private final PlaceImageCommandValidator placeImageCommandValidator;
+    private final PlaceService placeService;
+
+
+    public PlaceImageFormControllerImpl(PlaceImageService placeImageService,
+                                        PlaceImageCommandConverterImpl placeImageCommandConverter,
+                                        PlaceImageConverterImpl placeImageConverter,
+                                        PlaceImageCommandValidator placeImageCommandValidator, PlaceService placeService) {
+        this.placeImageService = placeImageService;
+        this.placeImageCommandConverter = placeImageCommandConverter;
+
+
+        this.placeImageConverter = placeImageConverter;
+        this.placeImageCommandValidator = placeImageCommandValidator;
+        this.placeService = placeService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_NEW)
+    public final String getNewPlaceImage(final Model model) {
+        logger.debug("PlaceImageFormControllerImpl::getNewPlaceImage");
+        model.addAttribute(ImageAttributeConstants.PLACE_IMAGE_COMMAND, new PlaceImageCommandImpl());
+        model.addAttribute(AttributeConstants.PLACES, placeService.findAll());
+        return ViewConstants.PLACE_IMAGE_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_EDIT)
+    public final String placeImageEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("PlaceImageFormControllerImpl::placeImageEdit");
+        model.addAttribute(ImageAttributeConstants.PLACE_IMAGE_COMMAND, placeImageService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PLACES, placeService.findAll());
+        return ViewConstants.PLACE_IMAGE_FORM;
+    }
+
+
+    @Override
+    @PostMapping(ImageMappingConstants.PLACE_IMAGE)
+    public String saveOrUpdate(@Valid @ModelAttribute PlaceImageCommand placeImageCommand, BindingResult bindingResult, Model model) {
+        logger.debug("PlaceImageFormControllerImpl::saveOrUpdate");
+
+        placeImageCommandValidator.validate(placeImageCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            model.addAttribute(AttributeConstants.PLACES, placeService.findAll());
+            return ViewConstants.PLACE_IMAGE_FORM;
+        }
+
+        PlaceImageCommand savedCommand = placeImageService.savePlaceImageCommand(placeImageCommand);
+        model.addAttribute(ImageAttributeConstants.PLACE_IMAGE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PLACES, placeService.findAll());
+        return MappingConstants.REDIRECT + ImageMappingConstants.PLACE_IMAGE_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_SHOW)
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("PlaceImageFormControllerImpl::saveOrUpdate");
+        PlaceImageCommand savedCommand = placeImageConverter.convert(placeImageService.findById(Long.valueOf(id)));
+        model.addAttribute(ImageAttributeConstants.PLACE_IMAGE_COMMAND, savedCommand);
+        model.addAttribute(AttributeConstants.PLACES, placeService.findAll());
+        return ViewConstants.PLACE_IMAGE_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.placeimages;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface PlaceImageListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String placeImageDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 104 - 0
src/main/java/scot/carricksoftware/grants/controllers/images/placeimages/PlaceImageListControllerImpl.java

@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 29/03/2025, 13:08. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.images.placeimages;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.*;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.images.placeimage.PlaceImageService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class PlaceImageListControllerImpl implements PlaceImageListController {
+
+    private static final Logger logger = LogManager.getLogger(PlaceImageListControllerImpl.class);
+
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final PlaceImageService placeImageService;
+
+    public PlaceImageListControllerImpl(ControllerHelper controllerHelper,
+                                        PlaceImageService placeImageService) {
+        this.controllerHelper = controllerHelper;
+        this.placeImageService = placeImageService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PlaceListControllerImpl::getPlaceImagePage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(ImageAttributeConstants.PLACE_IMAGES, placeImageService.getPagedPlaceImages(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.PLACE_IMAGE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("PlaceImageListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("PlaceImageListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("PlaceImageListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("PlaceImageListControllerImpl::getLastPage");
+        long placeImageCount = placeImageService.count();
+        currentPage = (int) (placeImageCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(ImageMappingConstants.PLACE_IMAGE_DELETE)
+    @Override
+    public final String placeImageDelete(@PathVariable final String id) {
+        logger.debug("PlaceImageListControllerImpl::placeImageDelete");
+        placeImageService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + ImageMappingConstants.PLACE_IMAGE_LIST;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/controllers/people/PersonFormController.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c)  20 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.controllers.people;
+
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import scot.carricksoftware.grants.commands.people.PersonCommand;
+
+@SuppressWarnings("unused")
+
+public interface PersonFormController {
+
+    String saveOrUpdate(@ModelAttribute PersonCommand personCommand, BindingResult bindingResult, Model model);
+}

+ 106 - 0
src/main/java/scot/carricksoftware/grants/controllers/people/PersonFormControllerImpl.java

@@ -0,0 +1,106 @@
+/*
+ * Copyright (c)  20 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.controllers.people;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.people.PersonCommand;
+import scot.carricksoftware.grants.commands.people.PersonCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.Capitalisation;
+import scot.carricksoftware.grants.converters.people.PersonCommandConverterImpl;
+import scot.carricksoftware.grants.converters.people.PersonConverterImpl;
+import scot.carricksoftware.grants.services.people.PersonService;
+import scot.carricksoftware.grants.validators.people.PersonCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class PersonFormControllerImpl implements PersonFormController {
+
+    private static final Logger logger = LogManager.getLogger(PersonFormControllerImpl.class);
+
+    private final PersonService personService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final PersonCommandConverterImpl personCommandConverter;
+    private final PersonConverterImpl personConverter;
+    private final Capitalisation capitalisation;
+    private final PersonCommandValidator personCommandValidator;
+
+
+    public PersonFormControllerImpl(PersonService personService,
+                                    PersonCommandConverterImpl personCommandConverter,
+                                    PersonConverterImpl personConverter,
+                                    Capitalisation capitalisation, PersonCommandValidator personCommandValidator) {
+        this.personService = personService;
+        this.personCommandConverter = personCommandConverter;
+
+
+        this.personConverter = personConverter;
+        this.capitalisation = capitalisation;
+        this.personCommandValidator = personCommandValidator;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PERSON_NEW)
+    public final String getNewPerson(final Model model) {
+        logger.debug("PersonFormControllerImpl::getNewPerson");
+        model.addAttribute(AttributeConstants.PERSON_COMMAND, new PersonCommandImpl());
+        return ViewConstants.PERSON_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PERSON_EDIT)
+    public final String personEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("PersonFormControllerImpl::personEdit");
+        model.addAttribute(AttributeConstants.PERSON_COMMAND, personService.findById(Long.valueOf(id)));
+        return ViewConstants.PERSON_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.PERSON)
+    public String saveOrUpdate(@Valid @ModelAttribute PersonCommand personCommand, BindingResult bindingResult, Model model) {
+        logger.debug("PersonFormControllerImpl::saveOrUpdate");
+
+        personCommandValidator.validate(personCommand, bindingResult);
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            return ViewConstants.PERSON_FORM;
+        }
+
+        cleanUp(personCommand);
+        PersonCommand savedCommand = personService.savePersonCommand(personCommand);
+        model.addAttribute(AttributeConstants.PERSON_COMMAND, savedCommand);
+        return MappingConstants.REDIRECT + MappingConstants.PERSON_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+    private void cleanUp(PersonCommand personCommand) {
+        personCommand.setFirstName(capitalisation.getCapitalisation(personCommand.getFirstName()));
+        personCommand.setLastName(capitalisation.getCapitalisation(personCommand.getLastName()));
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PERSON_SHOW)
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("PersonFormControllerImpl::saveOrUpdate");
+        PersonCommand savedCommand = personConverter.convert(personService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.PERSON_COMMAND, savedCommand);
+        return ViewConstants.PERSON_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/people/PersonListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 22:25. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.people;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface PersonListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String personDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 106 - 0
src/main/java/scot/carricksoftware/grants/controllers/people/PersonListControllerImpl.java

@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 22:25. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.people;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.people.PersonService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class PersonListControllerImpl implements PersonListController {
+
+    private static final Logger logger = LogManager.getLogger(PersonListControllerImpl.class);
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final PersonService personService;
+
+    public PersonListControllerImpl(ControllerHelper controllerHelper,
+                                    PersonService personService) {
+        this.controllerHelper = controllerHelper;
+        this.personService = personService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PEOPLE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getPersonPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.PEOPLE, personService.getPagedPersons(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.PEOPLE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PEOPLE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PEOPLE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PEOPLE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PEOPLE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getLastPage");
+        long personCount = personService.count();
+        currentPage = (int) (personCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PERSON_DELETE)
+    @Override
+    public final String personDelete(@PathVariable final String id) {
+        logger.debug("PersonListControllerImpl::personDelete");
+        personService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.PEOPLE;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 18 - 0
src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryFormController.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c)  20 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.controllers.places.countries;
+
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import scot.carricksoftware.grants.commands.places.countries.CountryCommand;
+
+@SuppressWarnings("unused")
+
+public interface CountryFormController {
+
+    String saveOrUpdate(@ModelAttribute CountryCommand countryCommand, BindingResult bindingResult, Model model);
+}

+ 105 - 0
src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryFormControllerImpl.java

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c)  20 Feb 2025, Andrew Grant of Carrick Software .
+ * All rights reserved.
+ */
+
+package scot.carricksoftware.grants.controllers.places.countries;
+
+import jakarta.validation.Valid;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import scot.carricksoftware.grants.commands.places.countries.CountryCommand;
+import scot.carricksoftware.grants.commands.places.countries.CountryCommandImpl;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.converters.Capitalisation;
+import scot.carricksoftware.grants.converters.places.countries.CountryCommandConverterImpl;
+import scot.carricksoftware.grants.converters.places.countries.CountryConverterImpl;
+import scot.carricksoftware.grants.services.places.countries.CountryService;
+import scot.carricksoftware.grants.validators.places.CountryCommandValidator;
+
+@SuppressWarnings("LoggingSimilarMessage")
+@Controller
+public class CountryFormControllerImpl implements CountryFormController {
+
+    private static final Logger logger = LogManager.getLogger(CountryFormControllerImpl.class);
+    private final CountryService countryService;
+    @SuppressWarnings({"FieldCanBeLocal", "unused"})
+    private final CountryCommandConverterImpl countryCommandConverter;
+    private final CountryConverterImpl countryConverter;
+    private final Capitalisation capitalisation;
+    private final CountryCommandValidator countryCommandValidator;
+
+
+    public CountryFormControllerImpl(CountryService countryService,
+                                     CountryCommandConverterImpl countryCommandConverter,
+                                     CountryConverterImpl countryConverter,
+                                     Capitalisation capitalisation, CountryCommandValidator countryCommandValidator) {
+        this.countryService = countryService;
+        this.countryCommandConverter = countryCommandConverter;
+
+
+        this.countryConverter = countryConverter;
+        this.capitalisation = capitalisation;
+        this.countryCommandValidator = countryCommandValidator;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_NEW)
+    public final String getNewCountry(final Model model) {
+        logger.debug("CountryFormControllerImpl::getNewCountry");
+        model.addAttribute(AttributeConstants.COUNTRY_COMMAND, new CountryCommandImpl());
+        return ViewConstants.COUNTRY_FORM;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_EDIT)
+    public final String countryEdit(@Valid @PathVariable final String id, Model model) {
+        logger.debug("CountryFormControllerImpl::countryEdit");
+        model.addAttribute(AttributeConstants.COUNTRY_COMMAND, countryService.findById(Long.valueOf(id)));
+        return ViewConstants.COUNTRY_FORM;
+    }
+
+
+    @Override
+    @PostMapping(MappingConstants.COUNTRY)
+    public String saveOrUpdate(@Valid @ModelAttribute CountryCommand countryCommand, BindingResult bindingResult, Model model) {
+        logger.debug("CountryFormControllerImpl::saveOrUpdate");
+
+        countryCommandValidator.validate(countryCommand, bindingResult);
+
+
+        if (bindingResult.hasErrors()) {
+            bindingResult.getAllErrors().forEach(error -> logger.debug(error.getDefaultMessage()));
+            return ViewConstants.COUNTRY_FORM;
+        }
+
+        cleanUp(countryCommand);
+        CountryCommand savedCommand = countryService.saveCountryCommand(countryCommand);
+        model.addAttribute(AttributeConstants.COUNTRY_COMMAND, savedCommand);
+        return MappingConstants.REDIRECT + MappingConstants.COUNTRY_SHOW.replace("{id}", "" + savedCommand.getId());
+    }
+
+    private void cleanUp(CountryCommand countryCommand) {
+        countryCommand.setName(capitalisation.getCapitalisation(countryCommand.getName()));
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_SHOW)
+    public String showById(@PathVariable String id, Model model) {
+        logger.debug("CountryFormControllerImpl::saveOrUpdate");
+        CountryCommand savedCommand = countryConverter.convert(countryService.findById(Long.valueOf(id)));
+        model.addAttribute(AttributeConstants.COUNTRY_COMMAND, savedCommand);
+        return ViewConstants.COUNTRY_FORM;
+    }
+
+
+}

+ 29 - 0
src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryListController.java

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 22:25. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.places.countries;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@SuppressWarnings("unused")
+@Controller
+public interface CountryListController {
+
+    String getListPage(final Model model);
+
+    String getNextPage(final Model model);
+
+    String getPreviousPage(final Model model);
+
+    String getFirstPage(final Model model);
+
+    String getLastPage(final Model model);
+
+    String countryDelete(@PathVariable String id);
+
+    int getPageNumber();
+}

+ 108 - 0
src/main/java/scot/carricksoftware/grants/controllers/places/countries/CountryListControllerImpl.java

@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 22:25. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.places.countries;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.places.countries.CountryService;
+
+
+import static java.lang.Integer.max;
+
+@Controller
+public class CountryListControllerImpl implements CountryListController {
+
+    private static final Logger logger = LogManager.getLogger(CountryListControllerImpl.class);
+
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final CountryService countryService;
+
+    public CountryListControllerImpl(ControllerHelper controllerHelper,
+                                     CountryService countryService) {
+        this.controllerHelper = controllerHelper;
+        this.countryService = countryService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getCountryPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.COUNTRIES, countryService.getPagedCountries(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.COUNTRY_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("CountryListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("CountryListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("CountryListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("CountryListControllerImpl::getLastPage");
+        long countryCount = countryService.count();
+        currentPage = (int) (countryCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.COUNTRY_DELETE)
+    @Override
+    public final String countryDelete(@PathVariable final String id) {
+        logger.debug("CountryListControllerImpl::countryDelete");
+        countryService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.COUNTRIES;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

+ 107 - 0
src/main/java/scot/carricksoftware/grants/controllers/places/places/PLaceListControllerImpl.java

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) Andrew Grant of Carrick Software 11/03/2025, 22:25. All rights reserved.
+ *
+ */
+
+package scot.carricksoftware.grants.controllers.places.places;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import scot.carricksoftware.grants.constants.ApplicationConstants;
+import scot.carricksoftware.grants.constants.AttributeConstants;
+import scot.carricksoftware.grants.constants.MappingConstants;
+import scot.carricksoftware.grants.constants.ViewConstants;
+import scot.carricksoftware.grants.controllers.ControllerHelper;
+import scot.carricksoftware.grants.services.places.places.PlaceService;
+
+import static java.lang.Integer.max;
+
+@Controller
+public class PLaceListControllerImpl implements PlaceListController {
+
+    private static final Logger logger = LogManager.getLogger(PLaceListControllerImpl.class);
+
+
+    private int currentPage = 0;
+    private final ControllerHelper controllerHelper;
+    private final PlaceService placeService;
+
+    public PLaceListControllerImpl(ControllerHelper controllerHelper,
+                                   PlaceService placeService) {
+        this.controllerHelper = controllerHelper;
+        this.placeService = placeService;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PLACE_LIST)
+    @Override
+    public final String getListPage(final Model model) {
+        logger.debug("PersonListControllerImpl::getPlacePage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    private String sendAttributesAndReturn(Model model) {
+        model.addAttribute(AttributeConstants.PLACES, placeService.getPagedPlaces(currentPage));
+        controllerHelper.addAttributes(model);
+        return ViewConstants.PLACE_LIST;
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PLACE_NEXT)
+    @Override
+    public final String getNextPage(final Model model) {
+        logger.debug("placeListControllerImpl::getNextPage");
+        currentPage++;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PLACE_PREVIOUS)
+    @Override
+    public final String getPreviousPage(final Model model) {
+        logger.debug("placeListControllerImpl::getPreviousPage");
+        currentPage = max(0, currentPage - 1);
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PLACE_REWIND)
+    public final String getFirstPage(final Model model) {
+        logger.debug("placeListControllerImpl::getFirstPage");
+        currentPage = 0;
+        return sendAttributesAndReturn(model);
+    }
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PLACE_FF)
+    @Override
+    public final String getLastPage(final Model model) {
+        logger.debug("placeListControllerImpl::getLastPage");
+        long placeCount = placeService.count();
+        currentPage = (int) (placeCount / ApplicationConstants.DEFAULT_PAGE_SIZE);
+        return sendAttributesAndReturn(model);
+    }
+
+
+    @SuppressWarnings("SameReturnValue")
+    @GetMapping(MappingConstants.PLACE_DELETE)
+    @Override
+    public final String placeDelete(@PathVariable final String id) {
+        logger.debug("placeListControllerImpl::placeDelete");
+        placeService.deleteById(Long.valueOf(id));
+        return MappingConstants.REDIRECT + MappingConstants.COUNTRIES;
+    }
+
+    @Override
+    public int getPageNumber() {
+        return currentPage;
+    }
+
+
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно