diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java index 719ebd52d..a16cb3ed1 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/api/ClientApiConstants.java @@ -76,6 +76,14 @@ public class ClientApiConstants { public static final String MARITAL_STATUS = "MaritalStatus"; public static final String maritalStatusIdParamName = "maritalStatusId"; public static final String maritalStatusParamName = "maritalStatus"; + public static final String EDUCATION_LEVEL = "EducationLevel"; + public static final String educationLevelIdParamName = "educationLevelId"; + public static final String DEGREE_QUALIFICATION = "DegreeQualification"; + public static final String degreeQualificationIdParamName = "degreeQualificationId"; + public static final String RELIGION = "Religion"; + public static final String religionIdParamName = "religionId"; + public static final String SOCIAL_CATEGORY = "SocialCategory"; + public static final String socialCategoryIdParamName = "socialCategoryId"; public static final String CLIENT_TYPE_INDIVIDUAL = "Individual"; @@ -125,8 +133,14 @@ public class ClientApiConstants { public static final String occupationCategoryParamName = "occupationCategory"; public static final String occupationIdParamName = "occupationId"; public static final String occupationParamName = "occupation"; + public static final String educationLevelParamName = "educationLevel"; + public static final String degreeQualificationParamName = "degreeQualification"; + public static final String religionParamName = "religion"; + public static final String socialCategoryParamName = "socialCategory"; public static final String monthlyIncomeParamName = "monthlyIncome"; public static final String annualTurnoverParamName = "annualTurnover"; + public static final String agricultureIncomeParamName = "agricultureIncome"; + public static final String nonAgricultureIncomeParamName = "nonAgricultureIncome"; public static final String ageYearsParamName = "ageYears"; public static final String ageMonthsParamName = "ageMonths"; public static final String ageDaysParamName = "ageDays"; @@ -232,8 +246,11 @@ public class ClientApiConstants { officeNameParamName, transferToOfficeIdParamName, transferToOfficeNameParamName, hierarchyParamName, imageIdParamName, imagePresentParamName, staffIdParamName, staffNameParamName, timelineParamName, groupsParamName, officeOptionsParamName, staffOptionsParamName, dateOfBirthParamName, genderParamName, clientTypeParamName, clientClassificationParamName, - salutationParamName, occupationCategoryParamName, occupationParamName, maritalStatusParamName, monthlyIncomeParamName, - annualTurnoverParamName, ageYearsParamName, ageMonthsParamName, ageDaysParamName, + salutationParamName, occupationCategoryParamName, occupationParamName, maritalStatusParamName, + educationLevelParamName, degreeQualificationParamName, + religionParamName, socialCategoryParamName, monthlyIncomeParamName, + annualTurnoverParamName, agricultureIncomeParamName, nonAgricultureIncomeParamName, + ageYearsParamName, ageMonthsParamName, ageDaysParamName, nationalityIdParamName, isMinorParamName, guardianClientIdParamName, guardianClientDisplayNameParamName, guardianRelationParamName, dipVerifiedParamName, dipLookupLogIdParamName, dipTimestampParamName, alternateMobileNoParamName, alternateDipVerifiedParamName, alternateDipLookupLogIdParamName, alternateDipTimestampParamName, diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/data/ClientData.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/data/ClientData.java index bea9deb01..c6a691408 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/data/ClientData.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/data/ClientData.java @@ -77,8 +77,14 @@ public final class ClientData implements Comparable, Serializable { private CodeValueData occupationCategory; private CodeValueData occupation; private CodeValueData maritalStatus; + private CodeValueData educationLevel; + private CodeValueData degreeQualification; + private CodeValueData religion; + private CodeValueData socialCategory; private BigDecimal monthlyIncome; private BigDecimal annualTurnover; + private BigDecimal agricultureIncome; + private BigDecimal nonAgricultureIncome; private Integer ageYears; private Integer ageMonths; private Integer ageDays; @@ -130,6 +136,10 @@ public final class ClientData implements Comparable, Serializable { private Collection clientClassificationOptions; private Collection occupationCategoryOptions; private Collection occupationOptions; + private Collection educationLevelOptions; + private Collection degreeQualificationOptions; + private Collection religionOptions; + private Collection socialCategoryOptions; private Collection clientNonPersonConstitutionOptions; private Collection clientNonPersonMainBusinessLineOptions; private List clientLegalFormOptions; @@ -357,6 +367,10 @@ public final class ClientData implements Comparable, Serializable { data.salutationOptions = salutationOptions; data.occupationCategoryOptions = occupationCategoryOptions; data.occupationOptions = occupationOptions; + data.educationLevelOptions = null; + data.degreeQualificationOptions = null; + data.religionOptions = null; + data.socialCategoryOptions = null; return data; } @@ -382,9 +396,19 @@ public final class ClientData implements Comparable, Serializable { data.occupation = clientData.occupation; data.occupationCategoryOptions = templateData.occupationCategoryOptions; data.occupationOptions = templateData.occupationOptions; + data.educationLevelOptions = templateData.educationLevelOptions; + data.degreeQualificationOptions = templateData.degreeQualificationOptions; + data.religionOptions = templateData.religionOptions; + data.socialCategoryOptions = templateData.socialCategoryOptions; data.maritalStatus = clientData.maritalStatus; + data.educationLevel = clientData.educationLevel; + data.degreeQualification = clientData.degreeQualification; + data.religion = clientData.religion; + data.socialCategory = clientData.socialCategory; data.monthlyIncome = clientData.monthlyIncome; data.annualTurnover = clientData.annualTurnover; + data.agricultureIncome = clientData.agricultureIncome; + data.nonAgricultureIncome = clientData.nonAgricultureIncome; data.ageYears = clientData.ageYears; data.ageMonths = clientData.ageMonths; data.ageDays = clientData.ageDays; @@ -428,9 +452,19 @@ public final class ClientData implements Comparable, Serializable { data.occupation = clientData.occupation; data.occupationCategoryOptions = clientData.occupationCategoryOptions; data.occupationOptions = clientData.occupationOptions; + data.educationLevelOptions = clientData.educationLevelOptions; + data.degreeQualificationOptions = clientData.degreeQualificationOptions; + data.religionOptions = clientData.religionOptions; + data.socialCategoryOptions = clientData.socialCategoryOptions; data.maritalStatus = clientData.maritalStatus; + data.educationLevel = clientData.educationLevel; + data.degreeQualification = clientData.degreeQualification; + data.religion = clientData.religion; + data.socialCategory = clientData.socialCategory; data.monthlyIncome = clientData.monthlyIncome; data.annualTurnover = clientData.annualTurnover; + data.agricultureIncome = clientData.agricultureIncome; + data.nonAgricultureIncome = clientData.nonAgricultureIncome; data.ageYears = clientData.ageYears; data.ageMonths = clientData.ageMonths; data.ageDays = clientData.ageDays; @@ -470,8 +504,14 @@ public final class ClientData implements Comparable, Serializable { data.occupationCategory = clientData.occupationCategory; data.occupation = clientData.occupation; data.maritalStatus = clientData.maritalStatus; + data.educationLevel = clientData.educationLevel; + data.degreeQualification = clientData.degreeQualification; + data.religion = clientData.religion; + data.socialCategory = clientData.socialCategory; data.monthlyIncome = clientData.monthlyIncome; data.annualTurnover = clientData.annualTurnover; + data.agricultureIncome = clientData.agricultureIncome; + data.nonAgricultureIncome = clientData.nonAgricultureIncome; data.ageYears = clientData.ageYears; data.ageMonths = clientData.ageMonths; data.ageDays = clientData.ageDays; diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java index 8d96b2062..8692c6098 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java @@ -212,12 +212,34 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { @JoinColumn(name = "marital_status_cv_id") private CodeValue maritalStatus; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "education_level_cv_id") + private CodeValue educationLevel; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "degree_qualification_cv_id") + private CodeValue degreeQualification; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "religion_cv_id") + private CodeValue religion; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "social_category_cv_id") + private CodeValue socialCategory; + @Column(name = "monthly_income") private java.math.BigDecimal monthlyIncome; @Column(name = "annual_turnover") private java.math.BigDecimal annualTurnover; + @Column(name = "agriculture_income") + private java.math.BigDecimal agricultureIncome; + + @Column(name = "non_agriculture_income") + private java.math.BigDecimal nonAgricultureIncome; + @Column(name = "nationality", length = 100) private String nationality; @@ -782,6 +804,38 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { this.maritalStatus = maritalStatus; } + public Long educationLevelId() { + return this.educationLevel != null ? this.educationLevel.getId() : null; + } + + public void updateEducationLevel(CodeValue educationLevel) { + this.educationLevel = educationLevel; + } + + public Long degreeQualificationId() { + return this.degreeQualification != null ? this.degreeQualification.getId() : null; + } + + public void updateDegreeQualification(CodeValue degreeQualification) { + this.degreeQualification = degreeQualification; + } + + public Long religionId() { + return this.religion != null ? this.religion.getId() : null; + } + + public void updateReligion(CodeValue religion) { + this.religion = religion; + } + + public Long socialCategoryId() { + return this.socialCategory != null ? this.socialCategory.getId() : null; + } + + public void updateSocialCategory(CodeValue socialCategory) { + this.socialCategory = socialCategory; + } + public void updateGender(CodeValue gender) { this.gender = gender; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientApiCollectionConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientApiCollectionConstants.java index 8ea06cc90..063cfc30c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientApiCollectionConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/data/ClientApiCollectionConstants.java @@ -30,7 +30,10 @@ public class ClientApiCollectionConstants extends ClientApiConstants { alternateMobileNoParamName, emailAddressParamName, firstnameParamName, middlenameParamName, lastnameParamName, fullnameParamName, officeIdParamName, activeParamName, activationDateParamName, staffIdParamName, submittedOnDateParamName, savingsProductIdParamName, dateOfBirthParamName, genderIdParamName, salutationIdParamName, clientTypeIdParamName, clientClassificationIdParamName, - occupationCategoryIdParamName, occupationIdParamName, maritalStatusIdParamName, monthlyIncomeParamName, annualTurnoverParamName, + occupationCategoryIdParamName, occupationIdParamName, maritalStatusIdParamName, + educationLevelIdParamName, degreeQualificationIdParamName, + religionIdParamName, socialCategoryIdParamName, monthlyIncomeParamName, annualTurnoverParamName, + agricultureIncomeParamName, nonAgricultureIncomeParamName, ageYearsParamName, ageMonthsParamName, ageDaysParamName, nationalityIdParamName, isMinorParamName, guardianClientIdParamName, guardianRelationParamName, dipVerifiedParamName, dipLookupLogIdParamName, dipTimestampParamName, @@ -49,7 +52,10 @@ public class ClientApiCollectionConstants extends ClientApiConstants { lastnameParamName, fullnameParamName, activeParamName, activationDateParamName, staffIdParamName, savingsProductIdParamName, dateOfBirthParamName, genderIdParamName, salutationIdParamName, clientTypeIdParamName, clientClassificationIdParamName, - occupationCategoryIdParamName, occupationIdParamName, maritalStatusIdParamName, monthlyIncomeParamName, annualTurnoverParamName, + occupationCategoryIdParamName, occupationIdParamName, maritalStatusIdParamName, + educationLevelIdParamName, degreeQualificationIdParamName, + religionIdParamName, socialCategoryIdParamName, monthlyIncomeParamName, annualTurnoverParamName, + agricultureIncomeParamName, nonAgricultureIncomeParamName, ageYearsParamName, ageMonthsParamName, ageDaysParamName, nationalityIdParamName, isMinorParamName, guardianClientIdParamName, guardianRelationParamName, dipVerifiedParamName, dipLookupLogIdParamName, dipTimestampParamName, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/mapper/ClientMapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/mapper/ClientMapper.java index 344df02ac..6b1a0baa1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/mapper/ClientMapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/mapper/ClientMapper.java @@ -61,8 +61,16 @@ public interface ClientMapper { @Mapping(target = "occupationCategory", source = "source", qualifiedByName = "occupationCategoryCode") @Mapping(target = "occupation", source = "source", qualifiedByName = "occupationCode") @Mapping(target = "maritalStatus", source = "source", qualifiedByName = "maritalStatusCode") + @Mapping(target = "educationLevel", source = "source", qualifiedByName = "educationLevelCode") + @Mapping(target = "degreeQualification", source = "source", qualifiedByName = "degreeQualificationCode") + @Mapping(target = "religion", source = "source", qualifiedByName = "religionCode") + @Mapping(target = "socialCategory", source = "source", qualifiedByName = "socialCategoryCode") @Mapping(target = "occupationCategoryOptions", ignore = true) @Mapping(target = "occupationOptions", ignore = true) + @Mapping(target = "educationLevelOptions", ignore = true) + @Mapping(target = "degreeQualificationOptions", ignore = true) + @Mapping(target = "religionOptions", ignore = true) + @Mapping(target = "socialCategoryOptions", ignore = true) @Mapping(target = "legalForm", source = "source", qualifiedByName = "clientLegalFormEnum") @Mapping(target = "isStaff", source = "source", qualifiedByName = "clientIsStaff") @Mapping(target = "ageYears", ignore = true) @@ -152,6 +160,42 @@ public interface ClientMapper { return CodeValueData.instance(code.getId(), code.getLabel()); } + @Named("educationLevelCode") + default CodeValueData educationLevelCode(Client client) { + final CodeValue code = client.getEducationLevel(); + if (code == null) { + return null; + } + return CodeValueData.instance(code.getId(), code.getLabel()); + } + + @Named("degreeQualificationCode") + default CodeValueData degreeQualificationCode(Client client) { + final CodeValue code = client.getDegreeQualification(); + if (code == null) { + return null; + } + return CodeValueData.instance(code.getId(), code.getLabel()); + } + + @Named("religionCode") + default CodeValueData religionCode(Client client) { + final CodeValue code = client.getReligion(); + if (code == null) { + return null; + } + return CodeValueData.instance(code.getId(), code.getLabel()); + } + + @Named("socialCategoryCode") + default CodeValueData socialCategoryCode(Client client) { + final CodeValue code = client.getSocialCategory(); + if (code == null) { + return null; + } + return CodeValueData.instance(code.getId(), code.getLabel()); + } + @Named("clientSubStatusCode") default CodeValueData clientSubStatusCode(Client client) { final CodeValue code = client.getSubStatus(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTemplateReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTemplateReadPlatformServiceImpl.java index aeaacbc90..964d46cc4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTemplateReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTemplateReadPlatformServiceImpl.java @@ -114,6 +114,18 @@ public class ClientTemplateReadPlatformServiceImpl implements ClientTemplateRead final List occupationOptions = new ArrayList<>( this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.OCCUPATION)); + final List educationLevelOptions = new ArrayList<>( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.EDUCATION_LEVEL)); + + final List degreeQualificationOptions = new ArrayList<>( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.DEGREE_QUALIFICATION)); + + final List religionOptions = new ArrayList<>( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.RELIGION)); + + final List socialCategoryOptions = new ArrayList<>( + this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.SOCIAL_CATEGORY)); + final List clientNonPersonConstitutionOptions = new ArrayList<>( this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_NON_PERSON_CONSTITUTION)); @@ -125,11 +137,16 @@ public class ClientTemplateReadPlatformServiceImpl implements ClientTemplateRead final List datatableTemplates = this.entityDatatableChecksReadService.retrieveTemplates(StatusEnum.CREATE.getValue(), EntityTables.CLIENT.getName(), null); - return ClientData.template(defaultOfficeId, LocalDate.now(DateUtils.getDateTimeZoneOfTenant()), offices, staffOptions, null, + ClientData templateData = ClientData.template(defaultOfficeId, LocalDate.now(DateUtils.getDateTimeZoneOfTenant()), offices, staffOptions, null, genderOptions, salutationOptions, savingsProductDatas, clientTypeOptions, clientClassificationOptions, occupationCategoryOptions, occupationOptions, clientNonPersonConstitutionOptions, clientNonPersonMainBusinessLineOptions, clientLegalFormOptions, familyMemberOptions, new ArrayList(Arrays.asList(address)), isAddressEnabled, datatableTemplates); + templateData.setEducationLevelOptions(educationLevelOptions); + templateData.setDegreeQualificationOptions(degreeQualificationOptions); + templateData.setReligionOptions(religionOptions); + templateData.setSocialCategoryOptions(socialCategoryOptions); + return templateData; } private Long defaultToUsersOfficeIfNull(final Long officeId) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index b416714a3..e19ddc229 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -264,6 +264,34 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.MARITAL_STATUS, maritalStatusId); } + CodeValue educationLevel = null; + final Long educationLevelId = command.longValueOfParameterNamed(ClientApiConstants.educationLevelIdParamName); + if (educationLevelId != null) { + educationLevel = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.EDUCATION_LEVEL, educationLevelId); + } + + CodeValue degreeQualification = null; + final Long degreeQualificationId = command.longValueOfParameterNamed(ClientApiConstants.degreeQualificationIdParamName); + if (degreeQualificationId != null) { + degreeQualification = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.DEGREE_QUALIFICATION, degreeQualificationId); + } + + CodeValue religion = null; + final Long religionId = command.longValueOfParameterNamed(ClientApiConstants.religionIdParamName); + if (religionId != null) { + religion = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.RELIGION, religionId); + } + + CodeValue socialCategory = null; + final Long socialCategoryId = command.longValueOfParameterNamed(ClientApiConstants.socialCategoryIdParamName); + if (socialCategoryId != null) { + socialCategory = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.SOCIAL_CATEGORY, socialCategoryId); + } + final Long savingsProductId = command.longValueOfParameterNamed(ClientApiConstants.savingsProductIdParamName); if (savingsProductId != null) { this.savingsProductRepository.findById(savingsProductId) @@ -335,10 +363,36 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP newClient.setAnnualTurnover(annualTurnover); } + final java.math.BigDecimal agricultureIncome = command.bigDecimalValueOfParameterNamed(ClientApiConstants.agricultureIncomeParamName); + if (agricultureIncome != null) { + newClient.setAgricultureIncome(agricultureIncome); + } + + final java.math.BigDecimal nonAgricultureIncome = command.bigDecimalValueOfParameterNamed(ClientApiConstants.nonAgricultureIncomeParamName); + if (nonAgricultureIncome != null) { + newClient.setNonAgricultureIncome(nonAgricultureIncome); + } + if (maritalStatus != null) { newClient.setMaritalStatus(maritalStatus); } + if (educationLevel != null) { + newClient.setEducationLevel(educationLevel); + } + + if (degreeQualification != null) { + newClient.setDegreeQualification(degreeQualification); + } + + if (religion != null) { + newClient.setReligion(religion); + } + + if (socialCategory != null) { + newClient.setSocialCategory(socialCategory); + } + final String nationality = command.stringValueOfParameterNamed(ClientApiConstants.nationalityIdParamName); if (nationality != null) { newClient.setNationality(nationality); @@ -688,6 +742,30 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP changes.put(ClientApiConstants.maritalStatusIdParamName, newValue); } + if (command.isChangeInLongParameterNamed(ClientApiConstants.educationLevelIdParamName, + clientForUpdate.educationLevelId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.educationLevelIdParamName); + changes.put(ClientApiConstants.educationLevelIdParamName, newValue); + } + + if (command.isChangeInLongParameterNamed(ClientApiConstants.degreeQualificationIdParamName, + clientForUpdate.degreeQualificationId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.degreeQualificationIdParamName); + changes.put(ClientApiConstants.degreeQualificationIdParamName, newValue); + } + + if (command.isChangeInLongParameterNamed(ClientApiConstants.religionIdParamName, + clientForUpdate.religionId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.religionIdParamName); + changes.put(ClientApiConstants.religionIdParamName, newValue); + } + + if (command.isChangeInLongParameterNamed(ClientApiConstants.socialCategoryIdParamName, + clientForUpdate.socialCategoryId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.socialCategoryIdParamName); + changes.put(ClientApiConstants.socialCategoryIdParamName, newValue); + } + if (command.isChangeInBigDecimalParameterNamed(ClientApiConstants.monthlyIncomeParamName, clientForUpdate.getMonthlyIncome())) { final java.math.BigDecimal newValue = command.bigDecimalValueOfParameterNamed(ClientApiConstants.monthlyIncomeParamName); changes.put(ClientApiConstants.monthlyIncomeParamName, newValue); @@ -700,6 +778,18 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP clientForUpdate.setAnnualTurnover(newValue); } + if (command.isChangeInBigDecimalParameterNamed(ClientApiConstants.agricultureIncomeParamName, clientForUpdate.getAgricultureIncome())) { + final java.math.BigDecimal newValue = command.bigDecimalValueOfParameterNamed(ClientApiConstants.agricultureIncomeParamName); + changes.put(ClientApiConstants.agricultureIncomeParamName, newValue); + clientForUpdate.setAgricultureIncome(newValue); + } + + if (command.isChangeInBigDecimalParameterNamed(ClientApiConstants.nonAgricultureIncomeParamName, clientForUpdate.getNonAgricultureIncome())) { + final java.math.BigDecimal newValue = command.bigDecimalValueOfParameterNamed(ClientApiConstants.nonAgricultureIncomeParamName); + changes.put(ClientApiConstants.nonAgricultureIncomeParamName, newValue); + clientForUpdate.setNonAgricultureIncome(newValue); + } + if (command.isChangeInStringParameterNamed(ClientApiConstants.nationalityIdParamName, clientForUpdate.getNationality())) { final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.nationalityIdParamName); changes.put(ClientApiConstants.nationalityIdParamName, newValue); @@ -938,6 +1028,46 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP clientForUpdate.updateMaritalStatus(newCodeVal); } + if (changes.containsKey(ClientApiConstants.educationLevelIdParamName)) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.educationLevelIdParamName); + CodeValue newCodeVal = null; + if (newValue != null) { + newCodeVal = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.EDUCATION_LEVEL, newValue); + } + clientForUpdate.updateEducationLevel(newCodeVal); + } + + if (changes.containsKey(ClientApiConstants.degreeQualificationIdParamName)) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.degreeQualificationIdParamName); + CodeValue newCodeVal = null; + if (newValue != null) { + newCodeVal = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.DEGREE_QUALIFICATION, newValue); + } + clientForUpdate.updateDegreeQualification(newCodeVal); + } + + if (changes.containsKey(ClientApiConstants.religionIdParamName)) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.religionIdParamName); + CodeValue newCodeVal = null; + if (newValue != null) { + newCodeVal = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.RELIGION, newValue); + } + clientForUpdate.updateReligion(newCodeVal); + } + + if (changes.containsKey(ClientApiConstants.socialCategoryIdParamName)) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.socialCategoryIdParamName); + CodeValue newCodeVal = null; + if (newValue != null) { + newCodeVal = this.codeValueRepository + .findOneByCodeNameAndIdWithNotFoundDetection(ClientApiConstants.SOCIAL_CATEGORY, newValue); + } + clientForUpdate.updateSocialCategory(newCodeVal); + } + if (!changes.isEmpty()) { this.clientRepository.saveAndFlush(clientForUpdate); } diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index 511da882e..6b48f3398 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -274,4 +274,7 @@ + + + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0256_add_education_level_degree_codes.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0256_add_education_level_degree_codes.xml new file mode 100644 index 000000000..78f47158f --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0256_add_education_level_degree_codes.xml @@ -0,0 +1,139 @@ + + + + + + + + INSERT INTO m_code (code_name, is_system_defined) + SELECT 'EducationLevel', false + WHERE NOT EXISTS (SELECT 1 FROM m_code WHERE code_name = 'EducationLevel'); + + + + + + INSERT INTO m_code_value (code_id, code_value, order_position, is_active, is_mandatory) + SELECT c.id, v.code_value, v.order_position, true, false + FROM m_code c + CROSS JOIN ( + VALUES + ('School', 1), + ('Undergraduate', 2), + ('Postgraduate', 3), + ('Doctorate / Professional', 4) + ) AS v(code_value, order_position) + WHERE c.code_name = 'EducationLevel' + AND NOT EXISTS ( + SELECT 1 FROM m_code_value cv + WHERE cv.code_id = c.id AND cv.code_value = v.code_value + ); + + + + + + + INSERT INTO m_code (code_name, is_system_defined) + SELECT 'DegreeQualification', false + WHERE NOT EXISTS (SELECT 1 FROM m_code WHERE code_name = 'DegreeQualification'); + + + + + + INSERT INTO m_code_value (code_id, code_value, code_description, order_position, is_active, is_mandatory) + SELECT c.id, v.code_value, v.code_description, v.order_position, true, false + FROM m_code c + CROSS JOIN ( + VALUES + ('Below 10th', 'School', 1), + ('10th / SSC / Matriculation', 'School', 2), + ('12th / HSC / Intermediate', 'School', 3), + ('Diploma', 'School', 4), + ('ITI', 'School', 5), + ('B.A. (Bachelor of Arts)', 'Undergraduate', 6), + ('B.Sc. (Bachelor of Science)', 'Undergraduate', 7), + ('B.Com. (Bachelor of Commerce)', 'Undergraduate', 8), + ('BBA (Business Administration)', 'Undergraduate', 9), + ('BCA (Computer Applications)', 'Undergraduate', 10), + ('B.Tech / B.E. (Engineering)', 'Undergraduate', 11), + ('B.Ed. (Education)', 'Undergraduate', 12), + ('LLB (Laws)', 'Undergraduate', 13), + ('MBBS', 'Undergraduate', 14), + ('BDS', 'Undergraduate', 15), + ('BAMS', 'Undergraduate', 16), + ('BHMS', 'Undergraduate', 17), + ('B.Pharm', 'Undergraduate', 18), + ('B.Arch', 'Undergraduate', 19), + ('BFA (Fine Arts)', 'Undergraduate', 20), + ('BHM (Hotel Management)', 'Undergraduate', 21), + ('B.Sc. Nursing', 'Undergraduate', 22), + ('Other UG', 'Undergraduate', 23), + ('M.A. (Master of Arts)', 'Postgraduate', 24), + ('M.Sc. (Master of Science)', 'Postgraduate', 25), + ('M.Com. (Master of Commerce)', 'Postgraduate', 26), + ('MBA (Business Administration)', 'Postgraduate', 27), + ('MCA (Computer Applications)', 'Postgraduate', 28), + ('M.Tech / M.E. (Engineering)', 'Postgraduate', 29), + ('M.Ed. (Education)', 'Postgraduate', 30), + ('LLM (Laws)', 'Postgraduate', 31), + ('MD (Medicine)', 'Postgraduate', 32), + ('MS (Surgery)', 'Postgraduate', 33), + ('MDS', 'Postgraduate', 34), + ('M.Pharm', 'Postgraduate', 35), + ('M.Arch', 'Postgraduate', 36), + ('MFA (Fine Arts)', 'Postgraduate', 37), + ('MSW (Social Work)', 'Postgraduate', 38), + ('Other PG', 'Postgraduate', 39), + ('Ph.D. (Doctor of Philosophy)', 'Doctorate / Professional', 40), + ('D.Litt.', 'Doctorate / Professional', 41), + ('D.Sc.', 'Doctorate / Professional', 42), + ('CA (Chartered Accountant)', 'Doctorate / Professional', 43), + ('CS (Company Secretary)', 'Doctorate / Professional', 44), + ('CMA (Cost & Mgmt Accountant)', 'Doctorate / Professional', 45), + ('CFA', 'Doctorate / Professional', 46), + ('Other Professional', 'Doctorate / Professional', 47) + ) AS v(code_value, code_description, order_position) + WHERE c.code_name = 'DegreeQualification' + AND NOT EXISTS ( + SELECT 1 FROM m_code_value cv + WHERE cv.code_id = c.id AND cv.code_value = v.code_value + ); + + + + + + + + + + + + + + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0257_add_religion_social_category_codes.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0257_add_religion_social_category_codes.xml new file mode 100644 index 000000000..b73ad40a7 --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0257_add_religion_social_category_codes.xml @@ -0,0 +1,99 @@ + + + + + + + + INSERT INTO m_code (code_name, is_system_defined) + SELECT 'Religion', false + WHERE NOT EXISTS (SELECT 1 FROM m_code WHERE code_name = 'Religion'); + + + + + + INSERT INTO m_code_value (code_id, code_value, order_position, is_active, is_mandatory) + SELECT c.id, v.code_value, v.order_position, true, false + FROM m_code c + CROSS JOIN ( + VALUES + ('Hindu', 1), + ('Muslim', 2), + ('Sikh', 3), + ('Christian', 4), + ('Jain', 5), + ('Buddhist', 6), + ('Others', 7) + ) AS v(code_value, order_position) + WHERE c.code_name = 'Religion' + AND NOT EXISTS ( + SELECT 1 FROM m_code_value cv + WHERE cv.code_id = c.id AND cv.code_value = v.code_value + ); + + + + + + + INSERT INTO m_code (code_name, is_system_defined) + SELECT 'SocialCategory', false + WHERE NOT EXISTS (SELECT 1 FROM m_code WHERE code_name = 'SocialCategory'); + + + + + + INSERT INTO m_code_value (code_id, code_value, order_position, is_active, is_mandatory) + SELECT c.id, v.code_value, v.order_position, true, false + FROM m_code c + CROSS JOIN ( + VALUES + ('General', 1), + ('OBC', 2), + ('SC', 3), + ('ST', 4) + ) AS v(code_value, order_position) + WHERE c.code_name = 'SocialCategory' + AND NOT EXISTS ( + SELECT 1 FROM m_code_value cv + WHERE cv.code_id = c.id AND cv.code_value = v.code_value + ); + + + + + + + + + + + + + + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0258_add_agriculture_non_agriculture_income.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0258_add_agriculture_non_agriculture_income.xml new file mode 100644 index 000000000..a89d3805b --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0258_add_agriculture_non_agriculture_income.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/postman/Education_Level_Degree_Qualification.postman_collection.json b/postman/Education_Level_Degree_Qualification.postman_collection.json new file mode 100644 index 000000000..b62543119 --- /dev/null +++ b/postman/Education_Level_Degree_Qualification.postman_collection.json @@ -0,0 +1,356 @@ +{ + "info": { + "name": "Education, Religion & Social Category", + "description": "Postman collection for Education Level, Degree/Qualification, Religion and Social Category dropdowns in Client registration.\n\nWorkflow:\n1. Get all codes to find code IDs\n2. Get code values for each to populate dropdowns\n3. Create/Update client with all dropdown IDs", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "variable": [ + { + "key": "base_url", + "value": "https://localhost:8443/fineract-provider/api/v1" + }, + { + "key": "tenant_id", + "value": "default" + }, + { + "key": "username", + "value": "mifos" + }, + { + "key": "password", + "value": "password" + } + ], + "auth": { + "type": "basic", + "basic": [ + { "key": "username", "value": "{{username}}" }, + { "key": "password", "value": "{{password}}" } + ] + }, + "item": [ + { + "name": "1. Get All Codes", + "request": { + "method": "GET", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "url": { + "raw": "{{base_url}}/codes", + "host": ["{{base_url}}"], + "path": ["codes"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "var codeMap = {", + " 'EducationLevel': 'education_level_code_id',", + " 'DegreeQualification': 'degree_qualification_code_id',", + " 'Religion': 'religion_code_id',", + " 'SocialCategory': 'social_category_code_id'", + "};", + "jsonData.forEach(function(code) {", + " if (codeMap[code.name]) {", + " pm.collectionVariables.set(codeMap[code.name], code.id);", + " console.log(code.name + ' code id: ' + code.id);", + " }", + "});", + "Object.keys(codeMap).forEach(function(name) {", + " pm.test(name + ' code exists', function () {", + " pm.expect(pm.collectionVariables.get(codeMap[name])).to.not.be.undefined;", + " });", + "});" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "2. Get Education Level Code Values", + "request": { + "method": "GET", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "url": { + "raw": "{{base_url}}/codes/{{education_level_code_id}}/codevalues", + "host": ["{{base_url}}"], + "path": ["codes", "{{education_level_code_id}}", "codevalues"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "pm.test('Education Level values returned', function () {", + " pm.expect(jsonData.length).to.be.greaterThan(0);", + "});", + "console.log('Education Level options:');", + "jsonData.forEach(function(v) {", + " console.log(' id=' + v.id + ' name=' + v.name);", + "});", + "if (jsonData.length > 0) {", + " pm.collectionVariables.set('sample_education_level_id', jsonData[0].id);", + "}" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "3. Get Degree Qualification Code Values", + "request": { + "method": "GET", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "url": { + "raw": "{{base_url}}/codes/{{degree_qualification_code_id}}/codevalues", + "host": ["{{base_url}}"], + "path": ["codes", "{{degree_qualification_code_id}}", "codevalues"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "pm.test('Degree Qualification values returned', function () {", + " pm.expect(jsonData.length).to.be.greaterThan(0);", + "});", + "console.log('Degree/Qualification options:');", + "jsonData.forEach(function(v) {", + " console.log(' id=' + v.id + ' name=' + v.name + ' description=' + v.description);", + "});", + "if (jsonData.length > 0) {", + " pm.collectionVariables.set('sample_degree_qualification_id', jsonData[0].id);", + "}" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "4. Get Religion Code Values", + "request": { + "method": "GET", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "url": { + "raw": "{{base_url}}/codes/{{religion_code_id}}/codevalues", + "host": ["{{base_url}}"], + "path": ["codes", "{{religion_code_id}}", "codevalues"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "pm.test('Religion values returned', function () {", + " pm.expect(jsonData.length).to.be.greaterThan(0);", + "});", + "console.log('Religion options:');", + "jsonData.forEach(function(v) {", + " console.log(' id=' + v.id + ' name=' + v.name);", + "});", + "if (jsonData.length > 0) {", + " pm.collectionVariables.set('sample_religion_id', jsonData[0].id);", + "}" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "5. Get Social Category Code Values", + "request": { + "method": "GET", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "url": { + "raw": "{{base_url}}/codes/{{social_category_code_id}}/codevalues", + "host": ["{{base_url}}"], + "path": ["codes", "{{social_category_code_id}}", "codevalues"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "pm.test('Social Category values returned', function () {", + " pm.expect(jsonData.length).to.be.greaterThan(0);", + "});", + "console.log('Social Category options:');", + "jsonData.forEach(function(v) {", + " console.log(' id=' + v.id + ' name=' + v.name);", + "});", + "if (jsonData.length > 0) {", + " pm.collectionVariables.set('sample_social_category_id', jsonData[0].id);", + "}" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "6. Get Client Template (with all dropdown options)", + "request": { + "method": "GET", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "url": { + "raw": "{{base_url}}/clients/template", + "host": ["{{base_url}}"], + "path": ["clients", "template"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "['educationLevelOptions', 'degreeQualificationOptions', 'religionOptions', 'socialCategoryOptions'].forEach(function(opt) {", + " pm.test(opt + ' present in template', function () {", + " pm.expect(jsonData).to.have.property(opt);", + " });", + " console.log(opt + ':', JSON.stringify(jsonData[opt]));", + "});" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "7. Create Client with all dropdown fields", + "request": { + "method": "POST", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "body": { + "mode": "raw", + "raw": "{\n \"officeId\": 1,\n \"firstname\": \"Dropdown\",\n \"lastname\": \"Test Client\",\n \"active\": true,\n \"activationDate\": \"20 April 2026\",\n \"dateFormat\": \"dd MMMM yyyy\",\n \"locale\": \"en\",\n \"legalFormId\": 1,\n \"educationLevelId\": {{sample_education_level_id}},\n \"degreeQualificationId\": {{sample_degree_qualification_id}},\n \"religionId\": {{sample_religion_id}},\n \"socialCategoryId\": {{sample_social_category_id}}\n}" + }, + "url": { + "raw": "{{base_url}}/clients", + "host": ["{{base_url}}"], + "path": ["clients"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "pm.test('Client created successfully', function () {", + " pm.expect(pm.response.code).to.equal(200);", + " pm.expect(jsonData.clientId).to.not.be.undefined;", + "});", + "if (jsonData.clientId) {", + " pm.collectionVariables.set('created_client_id', jsonData.clientId);", + " console.log('Created client id: ' + jsonData.clientId);", + "}" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "8. Get Client (verify all dropdown fields)", + "request": { + "method": "GET", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "url": { + "raw": "{{base_url}}/clients/{{created_client_id}}", + "host": ["{{base_url}}"], + "path": ["clients", "{{created_client_id}}"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = pm.response.json();", + "['educationLevel', 'degreeQualification', 'religion', 'socialCategory'].forEach(function(field) {", + " pm.test(field + ' present in response', function () {", + " pm.expect(jsonData).to.have.property(field);", + " pm.expect(jsonData[field]).to.not.be.null;", + " });", + " console.log(field + ':', JSON.stringify(jsonData[field]));", + "});" + ], + "type": "text/javascript" + } + } + ] + }, + { + "name": "9. Update Client dropdown fields", + "request": { + "method": "PUT", + "header": [ + { "key": "Fineract-Platform-TenantId", "value": "{{tenant_id}}" }, + { "key": "Content-Type", "value": "application/json" } + ], + "body": { + "mode": "raw", + "raw": "{\n \"educationLevelId\": {{sample_education_level_id}},\n \"degreeQualificationId\": {{sample_degree_qualification_id}},\n \"religionId\": {{sample_religion_id}},\n \"socialCategoryId\": {{sample_social_category_id}}\n}" + }, + "url": { + "raw": "{{base_url}}/clients/{{created_client_id}}", + "host": ["{{base_url}}"], + "path": ["clients", "{{created_client_id}}"] + } + }, + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Client updated successfully', function () {", + " pm.expect(pm.response.code).to.equal(200);", + "});" + ], + "type": "text/javascript" + } + } + ] + } + ] +}