Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
341a34f
Enforced mandatory validation for "Reason for Refusal in section e in…
sehjotsinghunthinkable Jun 22, 2026
2908c20
Added counselled flag to confirmed cases response, indicating whether…
sehjotsinghunthinkable Jun 23, 2026
9396905
Align `/complete` and `/submitBulk` form response editing behavior
sehjotsinghunthinkable Jun 23, 2026
9e28141
Merge branch 'vb/counselling' into vb/counselling
sehjotsinghunthinkable Jun 23, 2026
105ede6
Add van/sync tracking fields (vanID, parkingPlaceID, vanSerialNo, pro…
sehjotsinghunthinkable Jun 24, 2026
21b7187
feat(dynamic-form): add Hindi localization fields and completed benef…
sehjotsinghunthinkable Jun 25, 2026
fdb1a1f
feat(dynamic-form): add Hindi localization fields and completed benef…
sehjotsinghunthinkable Jun 25, 2026
6d8cb0b
Merge branch 'vb/counselling' into vb/counselling
vishwab1 Jun 25, 2026
5f05f66
feat(beneficiary): expose GPS coordinates in getBeneficiaryData response
sehjotsinghunthinkable Jun 26, 2026
6ae9ed0
Committed 82b00ccf with only the three files:
sehjotsinghunthinkable Jun 26, 2026
0332e9b
Revert "Committed 82b00ccf with only the three files:"
sehjotsinghunthinkable Jun 26, 2026
4123985
Committed 82b00ccf with only the three files:
sehjotsinghunthinkable Jun 26, 2026
b7488fe
Committed 82b00ccf with only the three files:
sehjotsinghunthinkable Jun 26, 2026
78d402c
Merge branch 'vb/counselling' into vb/counselling
sehjotsinghunthinkable Jun 26, 2026
b92cdea
Updated isMandatory field in Section C, so changed in TbCounsellingFo…
sehjotsinghunthinkable Jun 30, 2026
81e29d2
Add optional villageId and providerServiceMapId filters to getComplet…
sehjotsinghunthinkable Jul 2, 2026
be0d0d6
Removing section f from seeder
sehjotsinghunthinkable Jul 2, 2026
f6aca3a
Removing already existing check in /complete api
sehjotsinghunthinkable Jul 2, 2026
41550c2
Add a CHECKBOX question type and a TB_COUNSELLING_V2 seeder with a GE…
sehjotsinghunthinkable Jul 5, 2026
380014c
Seed single-checkbox questions for Sections A-D and point the Counsel…
sehjotsinghunthinkable Jul 6, 2026
4aafc4b
Mark form/section status REFUSED when TB2_GI_Q1=NO on /complete, spli…
sehjotsinghunthinkable Jul 6, 2026
b4bc4e0
Resolved conflicts
sehjotsinghunthinkable Jul 7, 2026
c53b9b5
fix(stoptb): getBeneficiaryData reads anthropometry/vitals from stand…
vishwab1 Jun 30, 2026
c7806cf
fix(compile): rename variable 'a' to 'anthro' to avoid conflict with …
vishwab1 Jun 30, 2026
d8008c3
fix(stoptb): set CreatedDate on t_benvisitdetail insert to prevent NO…
vishwab1 Jun 30, 2026
095f0ae
fix(anc-pnc): guard CreatedDate on BenVisitDetail insert for ANC and …
vishwab1 Jun 30, 2026
3b3a4c5
fix(docker): set TZ=Asia/Kolkata to prevent UTC/IST date mismatch
vishwab1 Jul 1, 2026
b1d28ae
fix(stoptb): handle ISO 8601 Z suffix in parseDob to fix beneficiary …
vishwab1 Jul 1, 2026
6d92f74
fix(stoptb): fallback to i_ben_flow_outreach.ben_dob when i_beneficia…
vishwab1 Jul 1, 2026
7459c47
fix: use saveAndFlush to prevent FK violation in t_benchiefcomplaint
vishwab1 Jul 1, 2026
9fccf6f
fix(stoptb): compute age from benDetailsRMNCH_OBJ.dob instead of benD…
vishwab1 Jul 3, 2026
7ddde0a
fix(stoptb): scope Suspected/Confirmed getAll by facility+village ins…
vishwab1 Jul 3, 2026
33c4f4d
fix(stoptb): drop date filter from facility-scoped Suspected query
vishwab1 Jul 3, 2026
349e714
fix(stoptb): join facility-scoped query on beneficiaryID, not benefic…
vishwab1 Jul 3, 2026
4d6606e
Added counselled flag to confirmed cases response, indicating whether…
sehjotsinghunthinkable Jun 23, 2026
33219a1
Revert "Committed 82b00ccf with only the three files:"
sehjotsinghunthinkable Jun 26, 2026
6951221
Committed 82b00ccf with only the three files:
sehjotsinghunthinkable Jun 26, 2026
e9fd699
Merge branch 'vb/counselling' into vb/counselling
vishwab1 Jul 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/
package com.iemr.flw.controller;

import com.iemr.flw.dto.iemr.CompletedBeneficiariesDTO;
import com.iemr.flw.dto.iemr.FormResponseDTO;
import com.iemr.flw.dto.iemr.FormResponseRequest;
import com.iemr.flw.masterEnum.FormType;
Expand Down Expand Up @@ -53,7 +54,7 @@ public class DynamicFormResponseController {

private final DynamicFormResponseService responseService;

@Operation(summary = "Submit PRE_SUBMIT section answers, status → SUBMITTED. " +
@Operation(summary = "Submit GENERAL_INFO and PRE_SUBMIT section answers, status → SUBMITTED. " +
"Pass responseId in body to re-submit an existing SUBMITTED response.")
@RequestMapping(value = "/submit", method = RequestMethod.POST)
public ResponseEntity<ApiResponse> submitForm(
Expand Down Expand Up @@ -98,13 +99,14 @@ public ResponseEntity<ApiResponse> getById(@RequestParam Long responseId) {
FormResponseDTO dto = responseService.getResponseById(responseId);
return ResponseEntity.ok(new ApiResponse(true, "Response fetched successfully", dto));
}
@Operation(summary = "Get beneficiary IDs that have a COMPLETE form response for the given form type, optionally filtered by village and/or provider service map")
@Operation(summary = "Get beneficiary IDs that have a COMPLETE or REFUSED form response for the given form type, optionally filtered by village and/or provider service map")
@RequestMapping(value = "/getCompletedBeneficiaries", method = RequestMethod.GET)
public ResponseEntity<ApiResponse> getCompletedBeneficiaries(
@RequestParam FormType formType,
@RequestParam(required = false) Integer villageId,
@RequestParam(required = false) Integer providerServiceMapId) {
List<Long> beneficiaryIds = responseService.getCompletedBeneficiaries(formType, villageId, providerServiceMapId);
return ResponseEntity.ok(new ApiResponse(true, "Completed beneficiaries fetched successfully", beneficiaryIds));
CompletedBeneficiariesDTO result =
responseService.getCompletedBeneficiaries(formType, villageId, providerServiceMapId);
return ResponseEntity.ok(new ApiResponse(true, "Completed beneficiaries fetched successfully", result));
}
}
11 changes: 8 additions & 3 deletions src/main/java/com/iemr/flw/domain/iemr/FormSection.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
*/
package com.iemr.flw.domain.iemr;

import com.iemr.flw.masterEnum.SectionPhase;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
Expand Down Expand Up @@ -71,20 +74,22 @@ public class FormSection {
@Column(name = "sectionName_hindi", length = 255)
private String sectionNameHindi;

/** PRE_SUBMIT sections are shown before the form's main submit. POST_SUBMIT after. */
@Enumerated(EnumType.STRING)
@Column(name = "sectionPhase", nullable = false, length = 20)
private String sectionPhase;
private SectionPhase sectionPhase;

@Column(name = "isRequired", nullable = false)
private Boolean isRequired = true;

@Column(name = "displayOrder", nullable = false)
private Integer displayOrder;

/** True only on the last PRE_SUBMIT section — renders the Submit button. */
@Column(name = "hasSubmitButton", nullable = false)
private Boolean hasSubmitButton = false;

@Column(name = "isEditable", nullable = false)
private Boolean isEditable = false;

@Column(name = "created_by", length = 100)
private String createdBy;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

/**
* A question within a form section.
* questionType: RADIO | MCQ | TEXT | DATE | DISPLAY | AUTO_FILL
* questionType: RADIO | MCQ | CHECKBOX | TEXT | DATE | DISPLAY | AUTO_FILL
*/
@Entity
@Table(name = "t_section_question", schema = "db_iemr")
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/com/iemr/flw/dto/iemr/CompletedBeneficiariesDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* AMRIT – Accessible Medical Records via Integrated Technology
* Integrated EHR (Electronic Health Records) Solution
*
* Copyright (C) "Piramal Swasthya Management and Research Institute"
*
* This file is part of AMRIT.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
package com.iemr.flw.dto.iemr;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
* Beneficiary IDs for a form type, split by outcome: those who completed the form and those
* who refused (TB2_GI_Q1 = NO on the General Info consent question).
*
* @author Piramal Swasthya
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CompletedBeneficiariesDTO {
private List<Long> completed;
private List<Long> refused;
}
7 changes: 5 additions & 2 deletions src/main/java/com/iemr/flw/dto/iemr/FormSectionDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/
package com.iemr.flw.dto.iemr;

import com.iemr.flw.masterEnum.SectionPhase;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
Expand Down Expand Up @@ -49,8 +50,8 @@ public class FormSectionDTO {

private String sectionNameHindi;

@NotBlank(message = "sectionPhase is required (PRE_SUBMIT or POST_SUBMIT)")
private String sectionPhase;
@NotNull(message = "sectionPhase is required (GENERAL_INFO, PRE_SUBMIT, or POST_SUBMIT)")
private SectionPhase sectionPhase;

private Boolean isRequired = true;

Expand All @@ -59,6 +60,8 @@ public class FormSectionDTO {

private Boolean hasSubmitButton = false;

private Boolean isEditable = false;

@Valid
private List<SectionQuestionDTO> questions = new ArrayList<>();
}
2 changes: 2 additions & 0 deletions src/main/java/com/iemr/flw/dto/iemr/SectionResponseDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public class SectionResponseDTO {

private Long sectionResponseId;
private Long sectionId;
private String sectionUuid;
private Boolean isEditable;
private String status;
private Timestamp savedAt;
private List<QuestionResponseDTO> answers;
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/com/iemr/flw/masterEnum/FormResponseStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* AMRIT – Accessible Medical Records via Integrated Technology
* Integrated EHR (Electronic Health Records) Solution
*
* Copyright (C) "Piramal Swasthya Management and Research Institute"
*
* This file is part of AMRIT.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
package com.iemr.flw.masterEnum;

/**
* Lifecycle status stored in FormResponse.status.
*
* @author Piramal Swasthya
*/
public enum FormResponseStatus {
/** Saved via /submit. */
SUBMITTED,
/** Saved via /complete, consent question answered YES (or not applicable). */
COMPLETE,
/** Saved via /complete, consent question TB2_GI_Q1 answered NO. */
REFUSED
}
3 changes: 2 additions & 1 deletion src/main/java/com/iemr/flw/masterEnum/FormType.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ public enum FormType {
COUNSELLING_MODULE,
SCREENING,
COUNSELLING,
TB_COUNSELLING
TB_COUNSELLING,
TB_COUNSELLING_V2
}
3 changes: 3 additions & 0 deletions src/main/java/com/iemr/flw/masterEnum/QuestionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public enum QuestionType {
RADIO,
/** Multi-select from a predefined list of options. */
MCQ,
/** Single boolean checkbox — checked or unchecked. May carry options for display
* purposes; answers are still stored as free text. */
CHECKBOX,
/** Free-text input. */
TEXT,
/** Date picker input. */
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/iemr/flw/masterEnum/SectionPhase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* AMRIT – Accessible Medical Records via Integrated Technology
* Integrated EHR (Electronic Health Records) Solution
*
* Copyright (C) "Piramal Swasthya Management and Research Institute"
*
* This file is part of AMRIT.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
package com.iemr.flw.masterEnum;

/**
* Exhaustive set of phases a form section can belong to.
* No other values may be stored in t_form_section.sectionPhase.
*
* @author Piramal Swasthya
*/
public enum SectionPhase {
/** Shown first, before PRE_SUBMIT sections. */
GENERAL_INFO,
/** Shown before the form's main submit. Saved via /submit. */
PRE_SUBMIT,
/** Shown after the main submit. Saved via /complete. */
POST_SUBMIT
}
8 changes: 8 additions & 0 deletions src/main/java/com/iemr/flw/repo/iemr/FormResponseRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ List<Long> findCounselledBenIds(@Param("benIds") List<Long> benIds,
@Param("formId") Long formId,
@Param("status") String status);

@Query("SELECT r.beneficiaryId FROM FormResponse r " +
"WHERE r.beneficiaryId IN :benIds " +
"AND r.formId = :formId " +
"AND r.status = :status")
List<Long> findCounselledBenIds(@Param("benIds") List<Long> benIds,
@Param("formId") Long formId,
@Param("status") String status);

@Query("SELECT r FROM FormResponse r "
+ "WHERE r.formId IN :formIds "
+ "AND r.status = 'SUBMITTED' "
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/com/iemr/flw/seeder/TbCounsellingFormSeeder.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.iemr.flw.dto.iemr.SectionQuestionDTO;
import com.iemr.flw.masterEnum.FormType;
import com.iemr.flw.masterEnum.QuestionType;
import com.iemr.flw.masterEnum.SectionPhase;
import com.iemr.flw.masterEnum.ValidationType;
import com.iemr.flw.repo.iemr.DynamicFormRepo;
import com.iemr.flw.service.DynamicFormDefinitionService;
Expand Down Expand Up @@ -93,7 +94,7 @@ private DynamicFormDTO buildFormDto() {
// ── Section A: Disease Awareness ─────────────────────────────────────────────

private FormSectionDTO buildSectionA() {
FormSectionDTO s = section("TB_SEC_A", "Disease Awareness", "बीमारी के बारे में जागरूकता", "PRE_SUBMIT", 1, true, false);
FormSectionDTO s = section("TB_SEC_A", "Disease Awareness", "बीमारी के बारे में जागरूकता", SectionPhase.PRE_SUBMIT, 1, true, false);
List<SectionQuestionDTO> qs = new ArrayList<>();
qs.add(yesNoRadio("TB_A_Q1", "TB disease explained to patient", "मरीज़ को टीबी बीमारी के बारे में समझाया गया।", 1, true));
qs.add(yesNoRadio("TB_A_Q2", "Transmission route explained", "ट्रांसमिशन के तरीके के बारे में जानकारी", 2, true));
Expand All @@ -107,7 +108,7 @@ private FormSectionDTO buildSectionA() {
// ── Section B: Do's and Don'ts ───────────────────────────────────────────────

private FormSectionDTO buildSectionB() {
FormSectionDTO s = section("TB_SEC_B", "Do's and Don'ts", "करो और ना करो", "PRE_SUBMIT", 2, true, false);
FormSectionDTO s = section("TB_SEC_B", "Do's and Don'ts", "करो और ना करो", SectionPhase.PRE_SUBMIT, 2, true, false);
List<SectionQuestionDTO> qs = new ArrayList<>();
qs.add(yesNoRadio("TB_B_Q1", "Cover mouth while coughing — advised", "खांसते समय मुंह ढकने की सलाह दी जाती है।", 1, true));
qs.add(yesNoRadio("TB_B_Q2", "Complete full treatment course — advised", "इलाज का पूरा कोर्स पूरा करने की सलाह दी जाती है।", 2, true));
Expand All @@ -123,7 +124,7 @@ private FormSectionDTO buildSectionB() {
// ── Section C: Government Schemes ────────────────────────────────────────────

private FormSectionDTO buildSectionC() {
FormSectionDTO s = section("TB_SEC_C", "Government Schemes", "सरकारी योजनाएं", "PRE_SUBMIT", 3, false, false);
FormSectionDTO s = section("TB_SEC_C", "Government Schemes", "सरकारी योजनाएं", SectionPhase.PRE_SUBMIT, 3, false, false);
List<SectionQuestionDTO> qs = new ArrayList<>();
qs.add(yesNoRadio("TB_C_Q1", "Nikshay Poshan Yojana (NPY) eligibility explained", "निक्षय पोषण योजना (एनपीवाई) पात्रता के बारे में बताया गया", 1, true));
qs.add(yesNoRadio("TB_C_Q2", "DOTS free treatment explained", "DOTS मुफ़्त इलाज के बारे में जानकारी", 2, true));
Expand All @@ -135,7 +136,7 @@ private FormSectionDTO buildSectionC() {
// ── Section D: Treatment Regimen ─────────────────────────────────────────────

private FormSectionDTO buildSectionD() {
FormSectionDTO s = section("TB_SEC_D", "Treatment Regimen", "इलाज का तरीका", "PRE_SUBMIT", 4, true, false);
FormSectionDTO s = section("TB_SEC_D", "Treatment Regimen", "इलाज का तरीका", SectionPhase.PRE_SUBMIT, 4, true, false);
List<SectionQuestionDTO> qs = new ArrayList<>();
qs.add(yesNoRadio("TB_D_Q1", "Regimen explained to patient", "मरीज़ को इलाज का तरीका समझाया गया।", 1, true));
qs.add(yesNoRadio("TB_D_Q2", "Medication names explained", "दवाओं के नामों की जानकारी", 2, true));
Expand All @@ -149,7 +150,7 @@ private FormSectionDTO buildSectionD() {
// ── Section E: Counselling Completion ────────────────────────────────────────

private FormSectionDTO buildSectionE() {
FormSectionDTO s = section("TB_SEC_E", "Counselling Completion", "काउंसलिंग पूरी होना", "PRE_SUBMIT", 5, true, true);
FormSectionDTO s = section("TB_SEC_E", "Counselling Completion", "काउंसलिंग पूरी होना", SectionPhase.PRE_SUBMIT, 5, true, true);
List<SectionQuestionDTO> qs = new ArrayList<>();

// Counselling completion status — RADIO: Complete | Refused
Expand Down Expand Up @@ -194,7 +195,7 @@ private FormSectionDTO buildSectionE() {
// ── Section F: Follow Up to TU ───────────────────────────────────────────────

private FormSectionDTO buildSectionF() {
FormSectionDTO s = section("TB_SEC_F", "Follow Up to TU", "TU के बाद की कार्रवाई", "POST_SUBMIT", 6, true, true);
FormSectionDTO s = section("TB_SEC_F", "Follow Up to TU", "TU के बाद की कार्रवाई", SectionPhase.POST_SUBMIT, 6, true, true);
List<SectionQuestionDTO> qs = new ArrayList<>();

// "Has the patient started TB treatment?" — RADIO: Yes | No
Expand Down Expand Up @@ -244,7 +245,7 @@ private FormSectionDTO buildSectionF() {

// ── Builder Helpers ───────────────────────────────────────────────────────────

private FormSectionDTO section(String uuid, String name, String nameHindi, String phase,
private FormSectionDTO section(String uuid, String name, String nameHindi, SectionPhase phase,
int order, boolean required, boolean hasSubmitButton) {
FormSectionDTO s = new FormSectionDTO();
s.setSectionUuid(uuid);
Expand Down
Loading