diff --git a/.github/workflows/build-distribute.yml b/.github/workflows/build-distribute.yml
new file mode 100644
index 000000000..bf53cde10
--- /dev/null
+++ b/.github/workflows/build-distribute.yml
@@ -0,0 +1,136 @@
+name: Build and Distribute
+
+on:
+ workflow_call:
+ inputs:
+ branch:
+ required: true
+ type: string
+ environment:
+ required: true
+ type: string
+ flavor:
+ required: true
+ type: string
+ build_type:
+ required: true
+ type: string
+ version:
+ required: true
+ type: string
+ version_code:
+ required: true
+ type: string
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ environment: ${{ inputs.environment }}
+
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ inputs.branch }}
+
+ - name: Cache NDK
+ uses: actions/cache@v4
+ with:
+ path: /usr/local/lib/android/sdk/ndk
+ key: ubuntu-latest-ndk-r29
+
+ - name: Cache CMake
+ uses: actions/cache@v4
+ with:
+ path: ~/.cmake
+ key: ubuntu-latest-cmake-3.31.1
+
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ distribution: zulu
+ java-version: '17'
+
+ - name: Set up Android SDK
+ uses: android-actions/setup-android@v2
+
+ - name: Set up Android NDK
+ uses: nttld/setup-ndk@v1.5.0
+ with:
+ ndk-version: r29
+ link-to-sdk: true
+
+ - name: Install CMake
+ uses: jwlawson/actions-setup-cmake@v1
+ with:
+ cmake-version: '3.31.1'
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.3'
+ bundler-cache: true
+
+ - name: Verify Ruby
+ run: ruby -v
+
+ - name: Decode google-services.json
+ run: |
+ echo "${{ secrets.GOOGLE_SERVICES_JSON_GENERIC }}" | base64 --decode > app/google-services.json
+
+ - name: Decode debug keystore
+ if: inputs.build_type == 'debug'
+ run: |
+ echo "${{ secrets.DEBUG_KEYSTORE_FILE }}" | base64 --decode > debug-keystore.jks
+ echo "Keystore file size: $(stat --format=%s debug-keystore.jks) bytes"
+ keytool -list -keystore debug-keystore.jks -storepass android -alias debugkey 2>&1 | head -5
+
+ - name: Decode Firebase credentials
+ if: inputs.build_type == 'debug'
+ run: |
+ echo "${{ secrets.FIREBASE_CREDENTIALS_JSON }}" | base64 --decode > firebase_credentials.json
+
+ - name: Decode Google Play JSON key
+ if: inputs.build_type == 'release'
+ run: |
+ echo "${{ secrets.GOOGLE_PLAY_JSON_KEY }}" | base64 --decode > fastlane/google_play_service_account.json
+
+ - name: Decode keystore
+ if: inputs.build_type == 'release'
+ run: |
+ echo "${{ secrets.KEYSTORE_FILE }}" | base64 --decode > keystore.jks
+
+ - name: Create local.properties
+ run: echo "sdk.dir=$ANDROID_SDK_ROOT" > local.properties
+
+ - name: Build and Distribute
+ env:
+ # Inputs as env vars to avoid shell injection (inputs.version is free-text)
+ INPUT_FLAVOR: ${{ inputs.flavor }}
+ INPUT_VERSION: ${{ inputs.version }}
+ INPUT_VERSION_CODE: ${{ inputs.version_code }}
+ INPUT_BUILD_TYPE: ${{ inputs.build_type }}
+ # Native build env vars (must match CMakeLists.txt)
+ ENCRYPTED_PASS_KEY: ${{ secrets.ENCRYPTED_PASS_KEY }}
+ ABHA_CLIENT_SECRET: ${{ secrets.ABHA_CLIENT_SECRET }}
+ ABHA_CLIENT_ID: ${{ secrets.ABHA_CLIENT_ID }}
+ BASE_TMC_URL: ${{ vars.BASE_TMC_URL }}
+ BASE_ABHA_URL: ${{ vars.BASE_ABHA_URL }}
+ ABHA_TOKEN_URL: ${{ vars.ABHA_TOKEN_URL }}
+ ABHA_AUTH_URL: ${{ vars.ABHA_AUTH_URL }}
+ CHAT_URL: ${{ vars.CHAT_URL }}
+ # Signing env vars (used by Fastlane for release builds)
+ KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
+ KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
+ KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
+ # Firebase env vars
+ FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}
+ run: |
+ if [ "$INPUT_BUILD_TYPE" = "debug" ]; then
+ bundle exec fastlane build_and_distribute_debug flavor:"$INPUT_FLAVOR" version_name:"$INPUT_VERSION" version_code:"$INPUT_VERSION_CODE"
+ else
+ bundle exec fastlane build_and_distribute_release flavor:"$INPUT_FLAVOR" version_name:"$INPUT_VERSION" version_code:"$INPUT_VERSION_CODE"
+ fi
diff --git a/.github/workflows/flw-android-build.yml b/.github/workflows/flw-android-build.yml
new file mode 100644
index 000000000..6bb55ce7d
--- /dev/null
+++ b/.github/workflows/flw-android-build.yml
@@ -0,0 +1,117 @@
+name: FLW Android Build
+
+on:
+ workflow_dispatch:
+ inputs:
+ project:
+ description: "Project to build"
+ required: true
+ type: choice
+ options:
+ - sakshamStag
+ - sakshamUat
+ - saksham
+ - xushrukha
+ - niramay
+ - mitaninStag
+ - mitaninUat
+ - mitanin
+
+ branch:
+ description: "Git branch to build"
+ required: true
+ default: main
+ type: string
+
+ version:
+ description: "Version name (example: 2.5.0)"
+ required: true
+ type: string
+
+ versionCode:
+ description: "Version code (example: 16)"
+ required: true
+ type: string
+
+jobs:
+ resolve-config:
+ runs-on: ubuntu-latest
+ permissions: {}
+ outputs:
+ flavor: ${{ steps.resolve.outputs.flavor }}
+ environment: ${{ steps.resolve.outputs.environment }}
+ build_type: ${{ steps.resolve.outputs.build_type }}
+ steps:
+ - name: Resolve project configuration
+ id: resolve
+ run: |
+ case "${{ inputs.project }}" in
+ sakshamStag)
+ echo "flavor=SakshamStag" >> $GITHUB_OUTPUT
+ echo "environment=SAKSHAM_STAG" >> $GITHUB_OUTPUT
+ echo "build_type=debug" >> $GITHUB_OUTPUT
+ ;;
+ sakshamUat)
+ echo "flavor=SakshamUat" >> $GITHUB_OUTPUT
+ echo "environment=SAKSHAM_UAT" >> $GITHUB_OUTPUT
+ echo "build_type=debug" >> $GITHUB_OUTPUT
+ ;;
+ saksham)
+ echo "flavor=Saksham" >> $GITHUB_OUTPUT
+ echo "environment=SAKSHAM_PRODUCTION" >> $GITHUB_OUTPUT
+ echo "build_type=release" >> $GITHUB_OUTPUT
+ ;;
+ xushrukha)
+ echo "flavor=Xushrukha" >> $GITHUB_OUTPUT
+ echo "environment=XUSHRUKHA_PRODUCTION" >> $GITHUB_OUTPUT
+ echo "build_type=release" >> $GITHUB_OUTPUT
+ ;;
+ niramay)
+ echo "flavor=Niramay" >> $GITHUB_OUTPUT
+ echo "environment=NIRAMAY_PRODUCTION" >> $GITHUB_OUTPUT
+ echo "build_type=release" >> $GITHUB_OUTPUT
+ ;;
+ mitaninStag)
+ echo "flavor=MitaninStag" >> $GITHUB_OUTPUT
+ echo "environment=MITANIN_STAG" >> $GITHUB_OUTPUT
+ echo "build_type=debug" >> $GITHUB_OUTPUT
+ ;;
+ mitaninUat)
+ echo "flavor=MitaninUat" >> $GITHUB_OUTPUT
+ echo "environment=MITANIN_UAT" >> $GITHUB_OUTPUT
+ echo "build_type=debug" >> $GITHUB_OUTPUT
+ ;;
+ mitanin)
+ echo "flavor=Mitanin" >> $GITHUB_OUTPUT
+ echo "environment=MITANIN_PRODUCTION" >> $GITHUB_OUTPUT
+ echo "build_type=release" >> $GITHUB_OUTPUT
+ ;;
+ *)
+ echo "::error::Unknown project: ${{ inputs.project }}"
+ exit 1
+ ;;
+ esac
+
+ - name: Display resolved configuration
+ run: |
+ echo "Project: ${{ inputs.project }}"
+ echo "Flavor: ${{ steps.resolve.outputs.flavor }}"
+ echo "Environment: ${{ steps.resolve.outputs.environment }}"
+ echo "Build Type: ${{ steps.resolve.outputs.build_type }}"
+ echo "Branch: ${{ inputs.branch }}"
+ echo "Version: ${{ inputs.version }}"
+ echo "Version Code: ${{ inputs.versionCode }}"
+
+ flw-build:
+ needs: resolve-config
+ permissions:
+ contents: read
+ uses: ./.github/workflows/build-distribute.yml
+ with:
+ branch: ${{ inputs.branch }}
+ environment: ${{ needs.resolve-config.outputs.environment }}
+ flavor: ${{ needs.resolve-config.outputs.flavor }}
+ build_type: ${{ needs.resolve-config.outputs.build_type }}
+ version: ${{ inputs.version }}
+ version_code: ${{ inputs.versionCode }}
+ secrets: inherit
diff --git a/.gitignore b/.gitignore
index 754ddaff4..69d935d49 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,5 +3,16 @@
/.gradle/
*.bin
*.lock
+!Gemfile.lock
/app/build/*
/app/release/*
+/local.properties
+/secrets.properties
+**/google-services.json
+app/src/main/res/raw/wildcard.crt
+app/src/main/cpp/native-lib.cpp
+keystore.properties
+app/keystore/*
+keystore.properties
+debug-keystore.jks
+debug-keystore-base64.txt
diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties
deleted file mode 100644
index c7d36898b..000000000
--- a/.gradle/buildOutputCleanup/cache.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-#Thu Aug 24 13:03:32 IST 2023
-gradle.version=8.0
diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties
deleted file mode 100644
index e69de29bb..000000000
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..2c1a28f15
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+amrit@piramalswasthya.org.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/FirebaseAppDistributionConfig/groups.txt b/FirebaseAppDistributionConfig/groups.txt
new file mode 100644
index 000000000..b51c52636
--- /dev/null
+++ b/FirebaseAppDistributionConfig/groups.txt
@@ -0,0 +1 @@
+trusted-testers
\ No newline at end of file
diff --git a/FirebaseAppDistributionConfig/release_notes.txt b/FirebaseAppDistributionConfig/release_notes.txt
new file mode 100644
index 000000000..a41f18007
--- /dev/null
+++ b/FirebaseAppDistributionConfig/release_notes.txt
@@ -0,0 +1 @@
+cuIn this version, we improved the user experience and fixed some bugs.
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 000000000..cdd3a6b34
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,6 @@
+source "https://rubygems.org"
+
+gem "fastlane"
+
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 000000000..f288702d2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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 .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/README.md b/README.md
index 7c93b0bd7..7a21f6383 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,161 @@
-# **Generating APK:**
+# FLW Mobile App
- - Information for the steps followed during the generation of APK’s for Sakhi Application from code
+[](https://deepwiki.com/PSMRI/FLW-Mobile-App)
-**Pre-Requesties:**
- - Clone the code repo into android studio and build the application
+## Overview
-**Environments**: We can generate the application for below environments based on requirements
- - Amrit Demo
- - UAT
- - Production
+The FLW Mobile App is designed for healthcare programs and consultation services rendered by ASHAs’ to serve pregnant women, mothers, and newborns in India. This eliminates pen and paperwork by ASHAs and allows them to enter beneficiaries data in a digital
+process with increased ease and accuracy of data. We named it as SAKHI for Bihar State and Utprerona for
+Assam State.
-**Configurations:**
- - In AppModule class there is a variable declared for base URL pointing to amrit demo or uat or production, we can use the URL we need and comment the rest for required APK
+## Functional Modules
+
+
+1. Household List
+
+2. New Household Registration
+
+3. All Beneficiaries List
+
+4. Beneficiary Registration
+
+5. Eligible Couple List
+
+6. Mother Care
+
+ • Pregnancy List (PMSMA Form: Pradhan Mantri Surakshit Matritva Abhiyan)
+
+ • Delivery stage List
+
+ • PNC Mother List
+
+ • Reproductive Age List
+
+7. Child Care
+
+ • Infant List
+
+ • Child List
+
+ • Adolescent List
+
+8. NCD
+
+ • NCD List
+
+ • NCD Eligible List
+
+ • NCD Priority List
+
+ • NCD Non-Eligible List
+
+9. Immunization due List
+
+10. HRP Cases
+
+11. General OP Care List
+
+12. Menopause Stage List
+
+13. Death Reports
+
+14. Village Level Forms
- `object AppModule {
+15. ASHA Dashboard
+
+ • Total ANC Women
+
+ • Delivery due list
+
+ • Total Delivery Women
+
+ • Total PNC Women
+
+16. ASHA To-do List (Scheduler)
+
+
+## Features
+
+- **User Authentication**: Secure login.
+- **Real-time Data**: Access to up-to-date information about beneficiaries.
+- **User-Friendly Interface**: Intuitive design for easy navigation.
+- **Offline Access**: Ability to use the app without an internet connection.
+- **Multilingual Support**: Ability to use app in different languages like English, Hindi, Assamese.
+
+## Technologies & Tools Used
+
+- **IDE**: Android Studio.
+- **Database**: Room
+- **Languages**: XML, Kotlin, SQL
+- **Architecture & Architectural Components**: MVVM, Android Architectural Components
+- **SDK**: Android SDK 23-34
+
+## Installation
+
+Make sure you have the following installed:
+
+- [Android Studio](https://developer.android.com/studio)
+
+To run this project, Follow these steps:
+
+1. Clone the repository to your local machine,
+ using: `git clone https://github.com/PSMRI/FLW-Mobile-App`.
+2. Open Android Studio.
+3. Click on 'Open an existing Android Studio project'.
+4. Navigate to the directory where you cloned the project and select the root folder.
+5. Wait for Android Studio to sync the project and download the dependencies.
+6. Once the sync is done, select build variant you want to work on like uatDebug, statingDebug or productionDebug
+7. create folder in \app\src named production, uat or staging as per build variant you want to work and add google JSON file in it.
+7. Clean Project and Rebuild and run project
+8. you can run the project on an emulator or a physical device.
+9. Try to login with valid Credentials if everything is fine you able to login successfully
+
+### Prerequisites
+
+- **Secrets**: Set the following secrets in your GitHub repository:
+ - `ENCODED_AES_KEY`
+ - `ENCODED_AES_IV`
+ - `GOOGLE_SERVICES_JSON_NIRAMAY_PRODUCTION`
+ - `GOOGLE_SERVICES_JSON_XUSHRUKHA_PRODUCTION`
+ - `GOOGLE_SERVICES_JSON_GENERIC`
+ - `FIREBASE_CREDENTIALS_JSON_SAKSHAM_ASSAM`
+ - `FIREBASE_CREDENTIALS_JSON_UTPRERONA_NIRAMAY`
+ - `FIREBASE_CREDENTIALS_JSON_UTPRERONA_XUSHRUKHA`
+ - `GOOGLE_PLAY_JSON_KEY`
+ - `KEYSTORE_FILE`
+ - `KEYSTORE_PASSWORD`
+ - `KEY_ALIAS`
+ - `KEY_PASSWORD`
+ - `FIREBASE_APP_ID`
+ - `BASE_TMC_URL`
+ - `ABHA_CLIENT_ID`
+ - `ABHA_CLIENT_SECRET`
+ - `BASE_ABHA_URL`
+ - `ABHA_TOKEN_URL`
+ - `ABHA_AUTH_URL`
+ - `CHAT_URL`
+
+- **Environment Variables**:
+ - `environment` (e.g., `NIRAMAY_PRODUCTION`, `XUSHRUKHA_PRODUCTION`, or other environments)
+
+- **Build Configuration**:
+ - `variant` (e.g., `Saksham`, `Niramay`, `Xushrukha`)
+ - `build_type` (e.g., `debug`, `release`)
+
+- **Files**:
+ - `google-services.json` for various environments
+ - `firebase_credentials.json` for different variants
+ - `google_play_service_account.json` for release builds
+ - `keystore.jks`
+
+
+
+
+**Configurations:**
+
+ - In App level build.gradle file productFlavors added. Based on which varient you want to work select build varient
- private const val baseTmcUrl =
- // "https://assamtmc.piramalswasthya.org/"
- // "http://uatamrit.piramalswasthya.org:8080/"
- https://amritdemo.piramalswasthya.org/
- `
- In IconDataset class we have the list of modules that we show on UI, we can comment, or un-comment modules based on requirement
- In AllBenFragment class we have a Boolean `showAbha` which can be used to toggle the visibility of abha button on beneficiary cards
@@ -46,14 +181,13 @@
+ https://developer.android.com/studio/publish/app-signing
+ Once the APK is generated android studio will notify with the location of APK,
- generally in release folder
-
-
+ generally in release folder
-
+## Filing Issues
-
+If you encounter any issues, bugs, or have feature requests, please file them in the [main AMRIT repository](https://github.com/PSMRI/AMRIT/issues). Centralizing all feedback helps us streamline improvements and address concerns efficiently.
-
+## Join Our Community
-
\ No newline at end of file
+We’d love to have you join our community discussions and get real-time support!
+Join our [Discord server](https://discord.gg/FVQWsf5ENS) to connect with contributors, ask questions, and stay updated.
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 000000000..e89122c2a
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1,4 @@
+/build
+/release
+.cxx
+.google-services.json
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 9f822daeb..65deedbef 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,5 +1,4 @@
plugins {
-
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'androidx.navigation.safeargs.kotlin'
@@ -7,75 +6,186 @@ plugins {
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'kotlin-kapt'
+ id 'kotlin-parcelize'
+ id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
+}
+apply from: rootProject.file('versioning.gradle')
+
+def keystoreProperties = new Properties()
+def keystorePropertiesFile = rootProject.file("keystore.properties")
+if (keystorePropertiesFile.exists()) {
+ keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
namespace 'org.piramalswasthya.sakhi'
- compileSdk 34
+ compileSdk 35
defaultConfig {
applicationId "org.piramalswasthya.sakhi"
- minSdk 21
- targetSdk 33
- versionCode 2
- versionName "2.0"
- resConfigs "en", "hi", "as"
+ minSdk 25
+ targetSdk 35
+ versionCode buildVersionCode()
+ versionName buildVersionName()
+ resourceConfigurations += ['en', 'hi', 'as']
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ }
+
+ splits {
+ abi {
+ enable true
+ reset()
+ include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
+ universalApk true
+ }
+ }
+
+ bundle {
+ language {
+ enableSplit = false
+ }
+ }
+
+ signingConfigs {
+ release {
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
+ storePassword keystoreProperties['storePassword']
+ }
}
buildTypes {
release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ minifyEnabled true
+ shrinkResources true
+ debuggable false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
+ 'proguard-rules.pro'
+ signingConfig signingConfigs.release
+ }
+
+ debug {
+ // uses default debug keystore; no changes needed
}
}
+ flavorDimensions "default"
+
+ productFlavors {
+
+ sakshamStag {
+ applicationIdSuffix ".saksham.stag"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "উৎপ্ৰেৰণা-Stag"
+ }
+
+ sakshamUat {
+ applicationIdSuffix ".saksham.uat"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "উৎপ্ৰেৰণা-Uat"
+ }
+
+ saksham {
+ applicationIdSuffix ".saksham"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "উৎপ্ৰেৰণা"
+ }
+
+ xushrukha {
+ applicationIdSuffix ".xushrukha"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "Xushrukha - শুশ্ৰূষা"
+ }
+
+ niramay {
+ applicationIdSuffix ".niramay"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "উৎপ্ৰেৰণা"
+ }
+
+ mitaninStag {
+ applicationIdSuffix ".mitanin.stag"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "मितानिन-Stag"
+ }
+
+ mitaninUat {
+ applicationIdSuffix ".mitanin.uat"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "मितानिन-Uat"
+ }
+
+ mitanin {
+ applicationIdSuffix ".mitanin"
+ applicationId "org.piramalswasthya.sakhi"
+ resValue "string", "app_native_name", "मितानिन"
+ }
+
+ }
+
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+ kapt {
+ correctErrorTypes true
+ }
+
kotlinOptions {
jvmTarget = '1.8'
}
- dataBinding{
- enabled=true
+ dataBinding {
+ enabled = true
}
- viewBinding{
- enabled=true
+ viewBinding {
+ enabled = true
}
buildFeatures {
viewBinding true
}
+
+ externalNativeBuild {
+ cmake {
+ path file("src/main/cpp/CMakeLists.txt")
+ }
+ }
+ ndkVersion '29.0.14033849'
+
}
dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'androidx.hilt:hilt-common:1.0.0'
- implementation platform('com.google.firebase:firebase-bom:31.2.2')
+ implementation platform('com.google.firebase:firebase-bom:32.7.0')
implementation 'com.google.firebase:firebase-crashlytics-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
- implementation 'androidx.room:room-testing:2.6.0'
- implementation 'androidx.test.ext:junit-ktx:1.1.5'
-
- def nav_version = "2.5.3"
- def frag_version = "1.5.5"
- def room_version = "2.5.0"
- def lifecycle_version = "2.5.1"
- def coroutine_version = "1.6.4"
- def work_version = "2.8.0"
- def hilt_version = "2.42"
- def retrofit_version = "2.9.0"
- def moshi_version = "1.13.0"
- def okhttp_version = "4.10.0"
+ implementation 'com.google.firebase:firebase-config-ktx'
+ implementation 'androidx.test.ext:junit-ktx:1.2.1'
+ implementation "androidx.security:security-crypto:1.0.0"
+ implementation 'com.google.crypto.tink:tink-android:1.18.0'
+ def nav_version = '2.5.3'
+ def frag_version = '1.8.8'
+ def room_version = "2.6.1"
+ def lifecycle_version = '2.6.2'//'2.9.1'
+ def coroutine_version = '1.7.3'
+ def work_version = '2.10.2'
+ def hilt_version = "2.48"
+ def retrofit_version = '2.9.0'
+ def moshi_version = '1.15.1'
+ def okhttp_version = '4.12.0'
def timber_version = "5.0.1"
- def gson_version = "2.9.0"
+ def gson_version = "2.11.0"
+
+ implementation 'androidx.core:core-ktx:1.12.0'
+ implementation 'androidx.appcompat:appcompat:1.7.1'
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
+ implementation 'androidx.recyclerview:recyclerview:1.4.0'
- implementation 'androidx.core:core-ktx:1.9.0'
- implementation 'androidx.appcompat:appcompat:1.6.1'
- implementation 'com.google.android.material:material:1.8.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
- implementation "androidx.recyclerview:recyclerview:1.3.1"
+ //Paging
+ implementation "androidx.paging:paging-runtime-ktx:3.2.1"
//Navigation
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
@@ -88,14 +198,24 @@ dependencies {
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
+ implementation "androidx.room:room-testing:$room_version"
+ implementation "androidx.room:room-paging:$room_version"
+
+ // implementation "org.jetbrains.kotlin:kotlin-metadata-jvm:2.2.0"
+
+ //firebase messaging
+ implementation 'com.google.firebase:firebase-messaging:21.0.1'
+// implementation platform('com.google.firebase:firebase-bom:28.4.0')
+ implementation 'com.google.firebase:firebase-analytics-ktx'
//Lifecycle
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
+
//Coroutine
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutine_version"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutine_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version"
//Work Manager
@@ -104,8 +224,9 @@ dependencies {
//Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"
- implementation 'androidx.hilt:hilt-work:1.0.0'
- kapt 'androidx.hilt:hilt-compiler:1.0.0'
+ implementation 'androidx.hilt:hilt-work:1.1.0'
+ kapt "androidx.hilt:hilt-compiler:1.1.0"
+ implementation 'androidx.hilt:hilt-common:1.1.0'
//retrofit
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
@@ -134,21 +255,42 @@ dependencies {
//Flexbox
implementation 'com.google.android.flexbox:flexbox:3.0.0'
-// //Encryption
-//// implementation 'javax.xml.bind:jaxb-api:2.3.0'
-// implementation('javax.xml.bind:jaxb-api:2.3.0')
-// implementation('javax.activation:activation:1.1')
-// implementation('org.glassfish.jaxb:jaxb-runtime:2.3.0')
-// implementation 'org.bouncycastle:bcpkix-jdk15on:1.68'
- testImplementation "com.google.truth:truth:1.1.3"
- androidTestImplementation 'androidx.test.ext:junit:1.1.5'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+
+ implementation("com.google.firebase:firebase-messaging:24.0.0")
+
+ // Unit Testing
+ testImplementation 'junit:junit:4.13.2'
+ testImplementation 'com.google.truth:truth:1.4.4'
+ testImplementation 'io.mockk:mockk:1.13.5'
+ testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
+ testImplementation 'androidx.arch.core:core-testing:2.2.0'
+ testImplementation 'app.cash.turbine:turbine:0.12.1'
+ testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
+ kaptTest "com.google.dagger:hilt-compiler:$hilt_version"
+ testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp_version"
+ testImplementation "androidx.work:work-testing:$work_version"
+
+ // Instrumented Testing
+ androidTestImplementation 'androidx.test.ext:junit:1.2.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
+ androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
+ kaptAndroidTest "com.google.dagger:hilt-compiler:$hilt_version"
+ androidTestImplementation 'io.mockk:mockk-android:1.13.8'
//Image compressor
implementation 'id.zelory:compressor:3.0.1'
-
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
-}
\ No newline at end of file
+ //Dimens Library
+ implementation 'com.intuit.sdp:sdp-android:1.1.1'
+
+ //In App Update
+ //implementation 'com.google.android.play:core:1.10.3'
+ implementation 'com.google.android.play:app-update:2.1.0'
+
+ implementation "net.zetetic:sqlcipher-android:4.13.0"
+ implementation "androidx.sqlite:sqlite:2.4.0"
+}
+
diff --git a/app/google-services.json b/app/google-services.json
deleted file mode 100644
index 66ae355ee..000000000
--- a/app/google-services.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "project_info": {
- "project_number": "289134290963",
- "project_id": "sakhi-1e7d2",
- "storage_bucket": "sakhi-1e7d2.appspot.com"
- },
- "client": [
- {
- "client_info": {
- "mobilesdk_app_id": "1:289134290963:android:6cd51e6329b3816144f7e6",
- "android_client_info": {
- "package_name": "org.piramalswasthya.sakhi"
- }
- },
- "oauth_client": [
- {
- "client_id": "289134290963-lskch73k1ujvh2ca3vgs09i2l7rqa4pd.apps.googleusercontent.com",
- "client_type": 3
- }
- ],
- "api_key": [
- {
- "current_key": "AIzaSyBHMkDJkxWgtIZN_T0fQjh5EXFvvY-9DiA"
- }
- ],
- "services": {
- "appinvite_service": {
- "other_platform_oauth_client": [
- {
- "client_id": "289134290963-lskch73k1ujvh2ca3vgs09i2l7rqa4pd.apps.googleusercontent.com",
- "client_type": 3
- }
- ]
- }
- }
- }
- ],
- "configuration_version": "1"
-}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 481bb4348..d02f93221 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -18,4 +18,118 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
+#-renamesourcefileattribute SourceFile
+-keep class com.squareup.moshi.** { *; }
+-keep class retrofit2.** { *; }
+-keep class okhttp3.** { *; }
+-keep class androidx.legacy.** { *; }
+-keep class com.google.firebase.** { *; }
+-keep class com.google.android.gms.** { *; }
+-keep class androidx.lifecycle.** { *; }
+-keepclassmembers class androidx.lifecycle.** { *; }
+-keep class androidx.work.** { *; }
+-keep class androidx.startup.** { *; }
+-keep class org.bouncycastle.** { *; }
+-keep class java.util.Locale { *; }
+# Prevent removal of resources used via reflection or dynamic access
+-keepclassmembers class ** {
+ public static ;
+}
+# Keep all string resource IDs and names
+-keepclassmembers class **.R$string {
+ *;
+}
+
+# --- ContextWrapper ---
+-keep class org.piramalswasthya.sakhi.** extends android.content.ContextWrapper { *; }
+
+# --- Assemblers ---
+-keep class org.piramalswasthya.sakhi.**Assembler { *; }
+-keepnames class org.piramalswasthya.sakhi.**Assembler
+
+# --- Hilt / DI Support ---
+-keep @dagger.hilt.EntryPoint interface * { *; }
+-keep class dagger.hilt.EntryPoints { *; }
+-keep class dagger.hilt.EntryPoint { *; }
+-keep class dagger.hilt.android.EntryPointAccessors { *; }
+-keep class **_HiltModules* { *; }
+-keep class *Module* { *; }
+
+# --- Annotations ---
+-keep @androidx.annotation.Keep class * { *; }
+-keepclassmembers class * {
+ @androidx.annotation.Keep *;
+}
+
+# --- Reflection Safety ---
+-keep class org.piramalswasthya.sakhi.** { *; }
+-keepnames class org.piramalswasthya.sakhi.**
+
+-dontwarn org.conscrypt.**
+-dontwarn org.bouncycastle.**
+-dontwarn org.openjsse.**
+-dontnote com.google.gson.**
+-keepattributes Signature
+-keepattributes *Annotation*
+
+# Application classes that will be serialized/deserialized over Gson
+-keep class com.google.gson.examples.android.model.** { *; }
+-keepclassmembers class org.piramalswasthya.**.databinding.** {
+ public ;
+}
+-keep class org.piramalswasthya.sakhi.model.** {*;}
+-keep class org.piramalswasthya.sakhi.network.** {*;}
+-keep class org.piramalswasthya.sakhi.repositories.** {*;}
+-dontusemixedcaseclassnames
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+# Keep all members in kotlinx.coroutines
+-keep class kotlinx.coroutines.** { *; }
+
+# Keep all methods in kotlinx.coroutines
+-keepclassmembers class kotlinx.coroutines.** { *; }
+
+# Keep Kotlin standard library functions
+-keep class kotlin.** { *; }
+-keepclassmembers class kotlin.** { *; }
+
+# Keep coroutines continuation classes and methods
+-keepclassmembers class kotlin.coroutines.Continuation {
+ *;
+}
+
+# Prevent warning for kotlinx.coroutines internal classes
+-dontwarn kotlinx.coroutines.internal.**
+
+# Prevent warning for kotlinx.coroutines implementation details
+-dontwarn kotlinx.coroutines.**
+
+# Keep all classes in the JNI package
+-keep class org.piramalswasthya.sakhi.jni.** { *; }
+
+# Keep all native methods
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+-assumenosideeffects class android.util.Log {
+ public static *** d(...);
+ public static *** v(...);
+ public static *** i(...);
+ public static *** w(...);
+ public static *** e(...);
+}
+
+# Timber calls are NOT stripped — SyncLogTree (planted in all builds)
+# intercepts sync-related logs for the Sync Dashboard logs tab.
+# DebugTree is only planted in debug builds, so release logs only
+# go to SyncLogManager (in-memory), never to logcat.
+#
+# -assumenosideeffects class timber.log.Timber {
+# public static *** d(...);
+# public static *** v(...);
+# public static *** i(...);
+# public static *** w(...);
+# }
+
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
deleted file mode 100644
index bb7473105..000000000
--- a/app/release/output-metadata.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "version": 3,
- "artifactType": {
- "type": "APK",
- "kind": "Directory"
- },
- "applicationId": "org.piramalswasthya.sakhi",
- "variantName": "release",
- "elements": [
- {
- "type": "SINGLE",
- "filters": [],
- "attributes": [],
- "versionCode": 2,
- "versionName": "2.0",
- "outputFile": "app-release.apk"
- }
- ],
- "elementType": "File"
-}
\ No newline at end of file
diff --git a/app/src/debug/res/drawable-anydpi/ic_females.xml b/app/src/debug/res/drawable-anydpi/ic_females.xml
new file mode 100644
index 000000000..ec6c8fb49
--- /dev/null
+++ b/app/src/debug/res/drawable-anydpi/ic_females.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/debug/res/drawable-mdpi/ic_edit.xml b/app/src/debug/res/drawable-mdpi/ic_edit.xml
index 9b586c386..b713ffe6c 100644
--- a/app/src/debug/res/drawable-mdpi/ic_edit.xml
+++ b/app/src/debug/res/drawable-mdpi/ic_edit.xml
@@ -4,10 +4,7 @@
android:viewportHeight="24.0"
android:viewportWidth="24.0"
android:width="24dp"
- android:tint="#333333"
- android:alpha="0.6"
-
- >
+ android:tint="#FFFFFF">
diff --git a/app/src/debug/res/drawable-mdpi/logo_circle_green.png b/app/src/debug/res/drawable-mdpi/logo_circle_green.png
new file mode 100644
index 000000000..3db5b3cbd
Binary files /dev/null and b/app/src/debug/res/drawable-mdpi/logo_circle_green.png differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 212c9f3b1..d788267cd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,12 +4,21 @@
+
-
-
+
+
+
+
+
+
+
+
+ android:exported="false"
+ android:windowSoftInputMode="adjustResize">
@@ -40,6 +53,18 @@
android:exported="false"
android:label="@string/title_activity_home"
android:screenOrientation="portrait"
+ android:windowSoftInputMode="adjustPan"
+ tools:ignore="LockedOrientationActivity">
+
+
+
@@ -62,6 +87,18 @@
android:value="" />
+
+
+
+
+
+
+
+
+
+
+
+
-
-
\ No newline at end of file
+
+
+
+
+
diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt
new file mode 100644
index 000000000..048367a74
--- /dev/null
+++ b/app/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,54 @@
+cmake_minimum_required(VERSION 3.11)
+project(Sakhi LANGUAGES CXX)
+
+# Fetch environment variables
+set(ENCRYPTED_PASS_KEY "$ENV{ENCRYPTED_PASS_KEY}")
+set(ABHA_CLIENT_SECRET "$ENV{ABHA_CLIENT_SECRET}")
+set(ABHA_CLIENT_ID "$ENV{ABHA_CLIENT_ID}")
+set(BASE_TMC_URL "$ENV{BASE_TMC_URL}")
+set(BASE_ABHA_URL "$ENV{BASE_ABHA_URL}")
+set(ABHA_TOKEN_URL "$ENV{ABHA_TOKEN_URL}")
+set(ABHA_AUTH_URL "$ENV{ABHA_AUTH_URL}")
+set(CHAT_URL "$ENV{CHAT_URL}")
+
+# Pass the values to the compiler using add_definitions
+add_definitions(
+ -DENCRYPTED_PASS_KEY=\"${ENCRYPTED_PASS_KEY}\"
+ -DABHA_CLIENT_SECRET=\"${ABHA_CLIENT_SECRET}\"
+ -DABHA_CLIENT_ID=\"${ABHA_CLIENT_ID}\"
+ -DBASE_TMC_URL=\"${BASE_TMC_URL}\"
+ -DBASE_ABHA_URL=\"${BASE_ABHA_URL}\"
+ -DABHA_TOKEN_URL=\"${ABHA_TOKEN_URL}\"
+ -DABHA_AUTH_URL=\"${ABHA_AUTH_URL}\"
+ -DCHAT_URL=\"${CHAT_URL}\"
+ -DIS_DEVELOPMENT=0
+)
+#DIS_DEVELOPMENT=0 -For Production use 0 , For Development use 1
+
+# Define the library name
+set(LIBRARY_NAME "sakhi")
+
+# Add the native-lib.cpp as the source file for the shared library
+add_library(
+ ${LIBRARY_NAME}
+ SHARED
+ native-lib.cpp
+)
+
+# Find the log library
+find_library(
+ log-lib
+ log
+)
+
+# Specifies libraries CMake should link to your target library.
+target_link_libraries(
+ ${LIBRARY_NAME}
+ ${log-lib}
+)
+
+# 16 KB page size alignment for Google Play compliance (Android 15+)
+target_link_options(${LIBRARY_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
+
+# Include directories
+# include_directories(${CMAKE_SOURCE_DIR}/include)
diff --git a/app/src/main/cpp/aes.cpp b/app/src/main/cpp/aes.cpp
new file mode 100644
index 000000000..4481f7b24
--- /dev/null
+++ b/app/src/main/cpp/aes.cpp
@@ -0,0 +1,572 @@
+/*
+
+This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
+Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
+
+The implementation is verified against the test vectors in:
+ National Institute of Standards and Technology Special Publication 800-38A 2001 ED
+
+ECB-AES128
+----------
+
+ plain-text:
+ 6bc1bee22e409f96e93d7e117393172a
+ ae2d8a571e03ac9c9eb76fac45af8e51
+ 30c81c46a35ce411e5fbc1191a0a52ef
+ f69f2445df4f9b17ad2b417be66c3710
+
+ key:
+ 2b7e151628aed2a6abf7158809cf4f3c
+
+ resulting cipher
+ 3ad77bb40d7a3660a89ecaf32466ef97
+ f5d3d58503b9699de785895a96fdbaaf
+ 43b1cd7f598ece23881b00e3ed030688
+ 7b0c785e27e8ad3f8223207104725dd4
+
+
+NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
+ You should pad the end of the string with zeros if this is not the case.
+ For AES192/256 the key size is proportionally larger.
+
+*/
+
+
+/*****************************************************************************/
+/* Includes: */
+/*****************************************************************************/
+#include // CBC mode, for memset
+#include "aes.h"
+
+/*****************************************************************************/
+/* Defines: */
+/*****************************************************************************/
+// The number of columns comprising a state in AES. This is a constant in AES. Value=4
+#define Nb 4
+
+#if defined(AES256) && (AES256 == 1)
+ #define Nk 8
+ #define Nr 14
+#elif defined(AES192) && (AES192 == 1)
+ #define Nk 6
+ #define Nr 12
+#else
+ #define Nk 4 // The number of 32 bit words in a key.
+ #define Nr 10 // The number of rounds in AES Cipher.
+#endif
+
+// jcallan@github points out that declaring Multiply as a function
+// reduces code size considerably with the Keil ARM compiler.
+// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
+#ifndef MULTIPLY_AS_A_FUNCTION
+ #define MULTIPLY_AS_A_FUNCTION 0
+#endif
+
+
+
+
+/*****************************************************************************/
+/* Private variables: */
+/*****************************************************************************/
+// state - array holding the intermediate results during decryption.
+typedef uint8_t state_t[4][4];
+
+
+
+// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
+// The numbers below can be computed dynamically trading ROM for RAM -
+// This can be useful in (embedded) bootloader applications, where ROM is often limited.
+static const uint8_t sbox[256] = {
+ //0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
+
+#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
+static const uint8_t rsbox[256] = {
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
+#endif
+
+// The round constant word array, Rcon[i], contains the values given by
+// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
+static const uint8_t Rcon[11] = {
+ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
+
+/*
+ * Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
+ * that you can remove most of the elements in the Rcon array, because they are unused.
+ *
+ * From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
+ *
+ * "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed),
+ * up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
+ */
+
+
+/*****************************************************************************/
+/* Private functions: */
+/*****************************************************************************/
+/*
+static uint8_t getSBoxValue(uint8_t num)
+{
+ return sbox[num];
+}
+*/
+#define getSBoxValue(num) (sbox[(num)])
+
+// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
+static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
+{
+ unsigned i, j, k;
+ uint8_t tempa[4]; // Used for the column/row operations
+
+ // The first round key is the key itself.
+ for (i = 0; i < Nk; ++i)
+ {
+ RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
+ RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
+ RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
+ RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
+ }
+
+ // All other round keys are found from the previous round keys.
+ for (i = Nk; i < Nb * (Nr + 1); ++i)
+ {
+ {
+ k = (i - 1) * 4;
+ tempa[0]=RoundKey[k + 0];
+ tempa[1]=RoundKey[k + 1];
+ tempa[2]=RoundKey[k + 2];
+ tempa[3]=RoundKey[k + 3];
+
+ }
+
+ if (i % Nk == 0)
+ {
+ // This function shifts the 4 bytes in a word to the left once.
+ // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
+
+ // Function RotWord()
+ {
+ const uint8_t u8tmp = tempa[0];
+ tempa[0] = tempa[1];
+ tempa[1] = tempa[2];
+ tempa[2] = tempa[3];
+ tempa[3] = u8tmp;
+ }
+
+ // SubWord() is a function that takes a four-byte input word and
+ // applies the S-box to each of the four bytes to produce an output word.
+
+ // Function Subword()
+ {
+ tempa[0] = getSBoxValue(tempa[0]);
+ tempa[1] = getSBoxValue(tempa[1]);
+ tempa[2] = getSBoxValue(tempa[2]);
+ tempa[3] = getSBoxValue(tempa[3]);
+ }
+
+ tempa[0] = tempa[0] ^ Rcon[i/Nk];
+ }
+#if defined(AES256) && (AES256 == 1)
+ if (i % Nk == 4)
+ {
+ // Function Subword()
+ {
+ tempa[0] = getSBoxValue(tempa[0]);
+ tempa[1] = getSBoxValue(tempa[1]);
+ tempa[2] = getSBoxValue(tempa[2]);
+ tempa[3] = getSBoxValue(tempa[3]);
+ }
+ }
+#endif
+ j = i * 4; k=(i - Nk) * 4;
+ RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
+ RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
+ RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
+ RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
+ }
+}
+
+void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
+{
+ KeyExpansion(ctx->RoundKey, key);
+}
+#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
+void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
+{
+ KeyExpansion(ctx->RoundKey, key);
+ memcpy (ctx->Iv, iv, AES_BLOCKLEN);
+}
+void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
+{
+ memcpy (ctx->Iv, iv, AES_BLOCKLEN);
+}
+#endif
+
+// This function adds the round key to state.
+// The round key is added to the state by an XOR function.
+static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
+{
+ uint8_t i,j;
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
+ }
+ }
+}
+
+// The SubBytes Function Substitutes the values in the
+// state matrix with values in an S-box.
+static void SubBytes(state_t* state)
+{
+ uint8_t i, j;
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ (*state)[j][i] = getSBoxValue((*state)[j][i]);
+ }
+ }
+}
+
+// The ShiftRows() function shifts the rows in the state to the left.
+// Each row is shifted with different offset.
+// Offset = Row number. So the first row is not shifted.
+static void ShiftRows(state_t* state)
+{
+ uint8_t temp;
+
+ // Rotate first row 1 columns to left
+ temp = (*state)[0][1];
+ (*state)[0][1] = (*state)[1][1];
+ (*state)[1][1] = (*state)[2][1];
+ (*state)[2][1] = (*state)[3][1];
+ (*state)[3][1] = temp;
+
+ // Rotate second row 2 columns to left
+ temp = (*state)[0][2];
+ (*state)[0][2] = (*state)[2][2];
+ (*state)[2][2] = temp;
+
+ temp = (*state)[1][2];
+ (*state)[1][2] = (*state)[3][2];
+ (*state)[3][2] = temp;
+
+ // Rotate third row 3 columns to left
+ temp = (*state)[0][3];
+ (*state)[0][3] = (*state)[3][3];
+ (*state)[3][3] = (*state)[2][3];
+ (*state)[2][3] = (*state)[1][3];
+ (*state)[1][3] = temp;
+}
+
+static uint8_t xtime(uint8_t x)
+{
+ return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
+}
+
+// MixColumns function mixes the columns of the state matrix
+static void MixColumns(state_t* state)
+{
+ uint8_t i;
+ uint8_t Tmp, Tm, t;
+ for (i = 0; i < 4; ++i)
+ {
+ t = (*state)[i][0];
+ Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
+ Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
+ Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
+ Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
+ Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
+ }
+}
+
+// Multiply is used to multiply numbers in the field GF(2^8)
+// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
+// The compiler seems to be able to vectorize the operation better this way.
+// See https://github.com/kokke/tiny-AES-c/pull/34
+#if MULTIPLY_AS_A_FUNCTION
+static uint8_t Multiply(uint8_t x, uint8_t y)
+{
+ return (((y & 1) * x) ^
+ ((y>>1 & 1) * xtime(x)) ^
+ ((y>>2 & 1) * xtime(xtime(x))) ^
+ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
+ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
+ }
+#else
+#define Multiply(x, y) \
+ ( ((y & 1) * x) ^ \
+ ((y>>1 & 1) * xtime(x)) ^ \
+ ((y>>2 & 1) * xtime(xtime(x))) ^ \
+ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
+ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
+
+#endif
+
+#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
+/*
+static uint8_t getSBoxInvert(uint8_t num)
+{
+ return rsbox[num];
+}
+*/
+#define getSBoxInvert(num) (rsbox[(num)])
+
+// MixColumns function mixes the columns of the state matrix.
+// The method used to multiply may be difficult to understand for the inexperienced.
+// Please use the references to gain more information.
+static void InvMixColumns(state_t* state)
+{
+ int i;
+ uint8_t a, b, c, d;
+ for (i = 0; i < 4; ++i)
+ {
+ a = (*state)[i][0];
+ b = (*state)[i][1];
+ c = (*state)[i][2];
+ d = (*state)[i][3];
+
+ (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
+ (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
+ (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
+ (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
+ }
+}
+
+
+// The SubBytes Function Substitutes the values in the
+// state matrix with values in an S-box.
+static void InvSubBytes(state_t* state)
+{
+ uint8_t i, j;
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ (*state)[j][i] = getSBoxInvert((*state)[j][i]);
+ }
+ }
+}
+
+static void InvShiftRows(state_t* state)
+{
+ uint8_t temp;
+
+ // Rotate first row 1 columns to right
+ temp = (*state)[3][1];
+ (*state)[3][1] = (*state)[2][1];
+ (*state)[2][1] = (*state)[1][1];
+ (*state)[1][1] = (*state)[0][1];
+ (*state)[0][1] = temp;
+
+ // Rotate second row 2 columns to right
+ temp = (*state)[0][2];
+ (*state)[0][2] = (*state)[2][2];
+ (*state)[2][2] = temp;
+
+ temp = (*state)[1][2];
+ (*state)[1][2] = (*state)[3][2];
+ (*state)[3][2] = temp;
+
+ // Rotate third row 3 columns to right
+ temp = (*state)[0][3];
+ (*state)[0][3] = (*state)[1][3];
+ (*state)[1][3] = (*state)[2][3];
+ (*state)[2][3] = (*state)[3][3];
+ (*state)[3][3] = temp;
+}
+#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
+
+// Cipher is the main function that encrypts the PlainText.
+static void Cipher(state_t* state, const uint8_t* RoundKey)
+{
+ uint8_t round = 0;
+
+ // Add the First round key to the state before starting the rounds.
+ AddRoundKey(0, state, RoundKey);
+
+ // There will be Nr rounds.
+ // The first Nr-1 rounds are identical.
+ // These Nr rounds are executed in the loop below.
+ // Last one without MixColumns()
+ for (round = 1; ; ++round)
+ {
+ SubBytes(state);
+ ShiftRows(state);
+ if (round == Nr) {
+ break;
+ }
+ MixColumns(state);
+ AddRoundKey(round, state, RoundKey);
+ }
+ // Add round key to last round
+ AddRoundKey(Nr, state, RoundKey);
+}
+
+#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
+static void InvCipher(state_t* state, const uint8_t* RoundKey)
+{
+ uint8_t round = 0;
+
+ // Add the First round key to the state before starting the rounds.
+ AddRoundKey(Nr, state, RoundKey);
+
+ // There will be Nr rounds.
+ // The first Nr-1 rounds are identical.
+ // These Nr rounds are executed in the loop below.
+ // Last one without InvMixColumn()
+ for (round = (Nr - 1); ; --round)
+ {
+ InvShiftRows(state);
+ InvSubBytes(state);
+ AddRoundKey(round, state, RoundKey);
+ if (round == 0) {
+ break;
+ }
+ InvMixColumns(state);
+ }
+
+}
+#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
+
+/*****************************************************************************/
+/* Public functions: */
+/*****************************************************************************/
+#if defined(ECB) && (ECB == 1)
+
+
+void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
+{
+ // The next function call encrypts the PlainText with the Key using AES algorithm.
+ Cipher((state_t*)buf, ctx->RoundKey);
+}
+
+void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
+{
+ // The next function call decrypts the PlainText with the Key using AES algorithm.
+ InvCipher((state_t*)buf, ctx->RoundKey);
+}
+
+
+#endif // #if defined(ECB) && (ECB == 1)
+
+
+
+
+
+#if defined(CBC) && (CBC == 1)
+
+
+static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
+{
+ uint8_t i;
+ for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
+ {
+ buf[i] ^= Iv[i];
+ }
+}
+
+void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length)
+{
+ size_t i;
+ uint8_t *Iv = ctx->Iv;
+ for (i = 0; i < length; i += AES_BLOCKLEN)
+ {
+ XorWithIv(buf, Iv);
+ Cipher((state_t*)buf, ctx->RoundKey);
+ Iv = buf;
+ buf += AES_BLOCKLEN;
+ }
+ /* store Iv in ctx for next call */
+ memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
+}
+
+void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
+{
+ size_t i;
+ uint8_t storeNextIv[AES_BLOCKLEN];
+ for (i = 0; i < length; i += AES_BLOCKLEN)
+ {
+ memcpy(storeNextIv, buf, AES_BLOCKLEN);
+ InvCipher((state_t*)buf, ctx->RoundKey);
+ XorWithIv(buf, ctx->Iv);
+ memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
+ buf += AES_BLOCKLEN;
+ }
+
+}
+
+#endif // #if defined(CBC) && (CBC == 1)
+
+
+
+#if defined(CTR) && (CTR == 1)
+
+/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
+void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
+{
+ uint8_t buffer[AES_BLOCKLEN];
+
+ size_t i;
+ int bi;
+ for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
+ {
+ if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
+ {
+
+ memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
+ Cipher((state_t*)buffer,ctx->RoundKey);
+
+ /* Increment Iv and handle overflow */
+ for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
+ {
+ /* inc will overflow */
+ if (ctx->Iv[bi] == 255)
+ {
+ ctx->Iv[bi] = 0;
+ continue;
+ }
+ ctx->Iv[bi] += 1;
+ break;
+ }
+ bi = 0;
+ }
+
+ buf[i] = (buf[i] ^ buffer[bi]);
+ }
+}
+
+#endif // #if defined(CTR) && (CTR == 1)
+
diff --git a/app/src/main/cpp/aes.h b/app/src/main/cpp/aes.h
new file mode 100644
index 000000000..b29b66835
--- /dev/null
+++ b/app/src/main/cpp/aes.h
@@ -0,0 +1,91 @@
+#ifndef _AES_H_
+#define _AES_H_
+
+#include
+#include
+
+// #define the macros below to 1/0 to enable/disable the mode of operation.
+//
+// CBC enables AES encryption in CBC-mode of operation.
+// CTR enables encryption in counter-mode.
+// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
+
+// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
+#ifndef CBC
+ #define CBC 1
+#endif
+
+#ifndef ECB
+ #define ECB 1
+#endif
+
+#ifndef CTR
+ #define CTR 1
+#endif
+
+
+#define AES128 1
+//#define AES192 1
+//#define AES256 1
+
+#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
+
+#if defined(AES256) && (AES256 == 1)
+ #define AES_KEYLEN 32
+ #define AES_keyExpSize 240
+#elif defined(AES192) && (AES192 == 1)
+ #define AES_KEYLEN 24
+ #define AES_keyExpSize 208
+#else
+ #define AES_KEYLEN 16 // Key length in bytes
+ #define AES_keyExpSize 176
+#endif
+
+struct AES_ctx
+{
+ uint8_t RoundKey[AES_keyExpSize];
+#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
+ uint8_t Iv[AES_BLOCKLEN];
+#endif
+};
+
+void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
+#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
+void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
+void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
+#endif
+
+#if defined(ECB) && (ECB == 1)
+// buffer size is exactly AES_BLOCKLEN bytes;
+// you need only AES_init_ctx as IV is not used in ECB
+// NB: ECB is considered insecure for most uses
+void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
+void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
+
+#endif // #if defined(ECB) && (ECB == !)
+
+
+#if defined(CBC) && (CBC == 1)
+// buffer size MUST be mutile of AES_BLOCKLEN;
+// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
+// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
+// no IV should ever be reused with the same key
+void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
+void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
+
+#endif // #if defined(CBC) && (CBC == 1)
+
+
+#if defined(CTR) && (CTR == 1)
+
+// Same function for encrypting as for decrypting.
+// IV is incremented for every block, and used after encryption as XOR-compliment for output
+// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
+// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
+// no IV should ever be reused with the same key
+void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
+
+#endif // #if defined(CTR) && (CTR == 1)
+
+
+#endif // _AES_H_
diff --git a/app/src/main/cpp/base64.cpp b/app/src/main/cpp/base64.cpp
new file mode 100644
index 000000000..843719ec9
--- /dev/null
+++ b/app/src/main/cpp/base64.cpp
@@ -0,0 +1,282 @@
+/*
+ base64.cpp and base64.h
+
+ base64 encoding and decoding with C++.
+ More information at
+ https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
+
+ Version: 2.rc.09 (release candidate)
+
+ Copyright (C) 2004-2017, 2020-2022 René Nyffenegger
+
+ This source code is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented; you must not
+ claim that you wrote the original source code. If you use this source code
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original source code.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ René Nyffenegger rene.nyffenegger@adp-gmbh.ch
+
+*/
+
+#include "base64.h"
+
+#include
+#include
+
+ //
+ // Depending on the url parameter in base64_chars, one of
+ // two sets of base64 characters needs to be chosen.
+ // They differ in their last two characters.
+ //
+static const char* base64_chars[2] = {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "+/",
+
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "-_"};
+
+static unsigned int pos_of_char(const unsigned char chr) {
+ //
+ // Return the position of chr within base64_encode()
+ //
+
+ if (chr >= 'A' && chr <= 'Z') return chr - 'A';
+ else if (chr >= 'a' && chr <= 'z') return chr - 'a' + ('Z' - 'A') + 1;
+ else if (chr >= '0' && chr <= '9') return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
+ else if (chr == '+' || chr == '-') return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters (
+ else if (chr == '/' || chr == '_') return 63; // Ditto for '/' and '_'
+ else
+ //
+ // 2020-10-23: Throw std::exception rather than const char*
+ //(Pablo Martin-Gomez, https://github.com/Bouska)
+ //
+ throw std::runtime_error("Input is not valid base64-encoded data.");
+}
+
+static std::string insert_linebreaks(std::string str, size_t distance) {
+ //
+ // Provided by https://github.com/JomaCorpFX, adapted by me.
+ //
+ if (!str.length()) {
+ return "";
+ }
+
+ size_t pos = distance;
+
+ while (pos < str.size()) {
+ str.insert(pos, "\n");
+ pos += distance + 1;
+ }
+
+ return str;
+}
+
+template
+static std::string encode_with_line_breaks(String s) {
+ return insert_linebreaks(base64_encode(s, false), line_length);
+}
+
+template
+static std::string encode_pem(String s) {
+ return encode_with_line_breaks(s);
+}
+
+template
+static std::string encode_mime(String s) {
+ return encode_with_line_breaks(s);
+}
+
+template
+static std::string encode(String s, bool url) {
+ return base64_encode(reinterpret_cast(s.data()), s.length(), url);
+}
+
+std::string base64_encode(unsigned char const* bytes_to_encode, size_t in_len, bool url) {
+
+ size_t len_encoded = (in_len +2) / 3 * 4;
+
+ unsigned char trailing_char = url ? '.' : '=';
+
+ //
+ // Choose set of base64 characters. They differ
+ // for the last two positions, depending on the url
+ // parameter.
+ // A bool (as is the parameter url) is guaranteed
+ // to evaluate to either 0 or 1 in C++ therefore,
+ // the correct character set is chosen by subscripting
+ // base64_chars with url.
+ //
+ const char* base64_chars_ = base64_chars[url];
+
+ std::string ret;
+ ret.reserve(len_encoded);
+
+ unsigned int pos = 0;
+
+ while (pos < in_len) {
+ ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]);
+
+ if (pos+1 < in_len) {
+ ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]);
+
+ if (pos+2 < in_len) {
+ ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]);
+ ret.push_back(base64_chars_[ bytes_to_encode[pos + 2] & 0x3f]);
+ }
+ else {
+ ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]);
+ ret.push_back(trailing_char);
+ }
+ }
+ else {
+
+ ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]);
+ ret.push_back(trailing_char);
+ ret.push_back(trailing_char);
+ }
+
+ pos += 3;
+ }
+
+
+ return ret;
+}
+
+template
+static std::string decode(String const& encoded_string, bool remove_linebreaks) {
+ //
+ // decode(…) is templated so that it can be used with String = const std::string&
+ // or std::string_view (requires at least C++17)
+ //
+
+ if (encoded_string.empty()) return std::string();
+
+ if (remove_linebreaks) {
+
+ std::string copy(encoded_string);
+
+ copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end());
+
+ return base64_decode(copy, false);
+ }
+
+ size_t length_of_string = encoded_string.length();
+ size_t pos = 0;
+
+ //
+ // The approximate length (bytes) of the decoded string might be one or
+ // two bytes smaller, depending on the amount of trailing equal signs
+ // in the encoded string. This approximation is needed to reserve
+ // enough space in the string to be returned.
+ //
+ size_t approx_length_of_decoded_string = length_of_string / 4 * 3;
+ std::string ret;
+ ret.reserve(approx_length_of_decoded_string);
+
+ while (pos < length_of_string) {
+ //
+ // Iterate over encoded input string in chunks. The size of all
+ // chunks except the last one is 4 bytes.
+ //
+ // The last chunk might be padded with equal signs or dots
+ // in order to make it 4 bytes in size as well, but this
+ // is not required as per RFC 2045.
+ //
+ // All chunks except the last one produce three output bytes.
+ //
+ // The last chunk produces at least one and up to three bytes.
+ //
+
+ size_t pos_of_char_1 = pos_of_char(encoded_string.at(pos+1) );
+
+ //
+ // Emit the first output byte that is produced in each chunk:
+ //
+ ret.push_back(static_cast( ( (pos_of_char(encoded_string.at(pos+0)) ) << 2 ) + ( (pos_of_char_1 & 0x30 ) >> 4)));
+
+ if ( ( pos + 2 < length_of_string ) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045)
+ encoded_string.at(pos+2) != '=' &&
+ encoded_string.at(pos+2) != '.' // accept URL-safe base 64 strings, too, so check for '.' also.
+ )
+ {
+ //
+ // Emit a chunk's second byte (which might not be produced in the last chunk).
+ //
+ unsigned int pos_of_char_2 = pos_of_char(encoded_string.at(pos+2) );
+ ret.push_back(static_cast( (( pos_of_char_1 & 0x0f) << 4) + (( pos_of_char_2 & 0x3c) >> 2)));
+
+ if ( ( pos + 3 < length_of_string ) &&
+ encoded_string.at(pos+3) != '=' &&
+ encoded_string.at(pos+3) != '.'
+ )
+ {
+ //
+ // Emit a chunk's third byte (which might not be produced in the last chunk).
+ //
+ ret.push_back(static_cast( ( (pos_of_char_2 & 0x03 ) << 6 ) + pos_of_char(encoded_string.at(pos+3)) ));
+ }
+ }
+
+ pos += 4;
+ }
+
+ return ret;
+}
+
+std::string base64_decode(std::string const& s, bool remove_linebreaks) {
+ return decode(s, remove_linebreaks);
+}
+
+std::string base64_encode(std::string const& s, bool url) {
+ return encode(s, url);
+}
+
+std::string base64_encode_pem (std::string const& s) {
+ return encode_pem(s);
+}
+
+std::string base64_encode_mime(std::string const& s) {
+ return encode_mime(s);
+}
+
+#if __cplusplus >= 201703L
+//
+// Interface with std::string_view rather than const std::string&
+// Requires C++17
+// Provided by Yannic Bonenberger (https://github.com/Yannic)
+//
+
+std::string base64_encode(std::string_view s, bool url) {
+ return encode(s, url);
+}
+
+std::string base64_encode_pem(std::string_view s) {
+ return encode_pem(s);
+}
+
+std::string base64_encode_mime(std::string_view s) {
+ return encode_mime(s);
+}
+
+std::string base64_decode(std::string_view s, bool remove_linebreaks) {
+ return decode(s, remove_linebreaks);
+}
+
+#endif // __cplusplus >= 201703L
diff --git a/app/src/main/cpp/base64.h b/app/src/main/cpp/base64.h
new file mode 100644
index 000000000..4860d63d8
--- /dev/null
+++ b/app/src/main/cpp/base64.h
@@ -0,0 +1,35 @@
+//
+// base64 encoding and decoding with C++.
+// Version: 2.rc.09 (release candidate)
+//
+
+#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
+#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A
+
+#include
+
+#if __cplusplus >= 201703L
+#include
+#endif // __cplusplus >= 201703L
+
+std::string base64_encode (std::string const& s, bool url = false);
+std::string base64_encode_pem (std::string const& s);
+std::string base64_encode_mime(std::string const& s);
+
+std::string base64_decode(std::string const& s, bool remove_linebreaks = false);
+std::string base64_encode(unsigned char const*, size_t len, bool url = false);
+
+#if __cplusplus >= 201703L
+//
+// Interface with std::string_view rather than const std::string&
+// Requires C++17
+// Provided by Yannic Bonenberger (https://github.com/Yannic)
+//
+std::string base64_encode (std::string_view s, bool url = false);
+std::string base64_encode_pem (std::string_view s);
+std::string base64_encode_mime(std::string_view s);
+
+std::string base64_decode(std::string_view s, bool remove_linebreaks = false);
+#endif // __cplusplus >= 201703L
+
+#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */
diff --git a/app/src/main/ic_mitanin_launcher-playstore.png b/app/src/main/ic_mitanin_launcher-playstore.png
new file mode 100644
index 000000000..717e93b00
Binary files /dev/null and b/app/src/main/ic_mitanin_launcher-playstore.png differ
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/SakhiApplication.kt b/app/src/main/java/org/piramalswasthya/sakhi/SakhiApplication.kt
index d18af9264..5175c3864 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/SakhiApplication.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/SakhiApplication.kt
@@ -1,11 +1,25 @@
package org.piramalswasthya.sakhi
import android.app.Application
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.os.Build
import android.os.StrictMode
import android.os.StrictMode.VmPolicy
+import androidx.appcompat.app.AppCompatDelegate
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
+import com.google.firebase.FirebaseApp
import dagger.hilt.android.HiltAndroidApp
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import org.piramalswasthya.sakhi.database.room.InAppDb
+import org.piramalswasthya.sakhi.helpers.CrashHandler
+import org.piramalswasthya.sakhi.helpers.SyncLogFileWriter
+import org.piramalswasthya.sakhi.helpers.SyncLogManager
+import org.piramalswasthya.sakhi.helpers.SyncLogTree
+import org.piramalswasthya.sakhi.utils.KeyUtils
import timber.log.Timber
import javax.inject.Inject
@@ -16,16 +30,129 @@ class SakhiApplication : Application(), Configuration.Provider {
@Inject
lateinit var workerFactory: HiltWorkerFactory
- override fun getWorkManagerConfiguration() =
- Configuration.Builder()
+ @Inject
+ lateinit var database: InAppDb
+
+ @Inject
+ lateinit var syncLogManager: SyncLogManager
+
+ @Inject
+ lateinit var syncLogFileWriter: SyncLogFileWriter
+
+ override val workManagerConfiguration: Configuration
+ get() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
override fun onCreate() {
super.onCreate()
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
val builder = VmPolicy.Builder()
StrictMode.setVmPolicy(builder.build())
- Timber.plant(Timber.DebugTree())
+ if (BuildConfig.DEBUG) {
+ Timber.plant(Timber.DebugTree())
+ }
+ Timber.plant(SyncLogTree(syncLogManager))
+ syncLogFileWriter.runRotation()
+ KeyUtils.encryptedPassKey()
+ KeyUtils.baseAbhaUrl()
+ KeyUtils.baseTMCUrl()
+ KeyUtils.abhaAuthUrl()
+ KeyUtils.abhaClientID()
+ KeyUtils.abhaClientSecret()
+ KeyUtils.abhaTokenUrl()
+ FirebaseApp.initializeApp(this)
+ createNotificationChannels()
+
+ Thread.setDefaultUncaughtExceptionHandler(CrashHandler(applicationContext))
+
+ // Recover any records orphaned in SYNCING state from a previous crash/kill
+ CoroutineScope(Dispatchers.IO).launch {
+ try {
+ recoverOrphanedSyncStates()
+ } catch (e: Exception) {
+ Timber.e(e, "Failed to recover orphaned SYNCING states")
+ }
+ }
}
+ /**
+ * Create notification channels early so that WorkManager workers always have
+ * a valid channel available — even after a device reboot when workers restart
+ * before LoginActivity.onCreate() runs.
+ */
+ private fun createNotificationChannels() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val nm = getSystemService(NotificationManager::class.java)
+
+ // Sync channel used by all push/pull/dynamic workers
+ nm.createNotificationChannel(
+ NotificationChannel(
+ getString(R.string.notification_sync_channel_id),
+ getString(R.string.notification_sync_channel_name),
+ NotificationManager.IMPORTANCE_DEFAULT
+ ).apply {
+ description = getString(R.string.notification_sync_channel_description)
+ }
+ )
+
+ // Download channel used by DownloadCardWorker
+ nm.createNotificationChannel(
+ NotificationChannel(
+ "download abha card",
+ "Download ABHA Card",
+ NotificationManager.IMPORTANCE_DEFAULT
+ ).apply {
+ description = "Notifications for ABHA card downloads"
+ }
+ )
+ }
+ }
+
+ private suspend fun recoverOrphanedSyncStates() {
+ // Reset all records stuck in SYNCING (ordinal 1) back to UNSYNCED (ordinal 0).
+ // No sync can be in progress at app startup, so any SYNCING record is orphaned.
+ database.benDao.resetSyncingToUnsynced()
+ database.cbacDao.resetSyncingToUnsynced()
+ database.pmsmaDao.resetSyncingToUnsynced()
+ database.deliveryOutcomeDao.resetSyncingToUnsynced()
+ database.pncDao.resetSyncingToUnsynced()
+ database.infantRegDao.resetSyncingToUnsynced()
+ database.vaccineDao.resetSyncingToUnsynced()
+ database.aesDao.resetSyncingToUnsynced()
+ database.adolescentHealthDao.resetSyncingToUnsynced()
+ database.filariaDao.resetSyncingToUnsynced()
+ database.kalaAzarDao.resetSyncingToUnsynced()
+ database.maaMeetingDao.resetSyncingToUnsynced()
+ database.saasBahuSammelanDao.resetSyncingToUnsynced()
+ database.uwinDao.resetSyncingToUnsynced()
+
+ // Multi-table DAOs
+ database.ecrDao.resetRegSyncingToUnsynced()
+ database.ecrDao.resetTrackingSyncingToUnsynced()
+ database.maternalHealthDao.resetPwrSyncingToUnsynced()
+ database.maternalHealthDao.resetAncSyncingToUnsynced()
+ database.leprosyDao.resetScreeningSyncingToUnsynced()
+ database.leprosyDao.resetFollowUpSyncingToUnsynced()
+ database.malariaDao.resetScreeningSyncingToUnsynced()
+ database.malariaDao.resetConfirmedSyncingToUnsynced()
+ database.tbDao.resetScreeningSyncingToUnsynced()
+ database.tbDao.resetSuspectedSyncingToUnsynced()
+ database.tbDao.resetConfirmedSyncingToUnsynced()
+ database.hrpDao.resetPregnantAssessSyncingToUnsynced()
+ database.hrpDao.resetPregnantTrackSyncingToUnsynced()
+ database.hrpDao.resetNonPregnantAssessSyncingToUnsynced()
+ database.hrpDao.resetNonPregnantTrackSyncingToUnsynced()
+ database.hrpDao.resetMicroBirthPlanSyncingToUnsynced()
+ database.vlfDao.resetVhndSyncingToUnsynced()
+ database.vlfDao.resetVhncSyncingToUnsynced()
+ database.vlfDao.resetPhcSyncingToUnsynced()
+ database.vlfDao.resetAhdSyncingToUnsynced()
+ database.vlfDao.resetDewormingSyncingToUnsynced()
+ database.vlfDao.resetPulsePolioSyncingToUnsynced()
+ database.vlfDao.resetOrsSyncingToUnsynced()
+ database.vlfDao.resetFilariaMdaSyncingToUnsynced()
+
+ Timber.d("Recovered orphaned SYNCING states at startup")
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AESMemberListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AESMemberListAdapter.kt
new file mode 100644
index 000000000..23c63e758
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AESMemberListAdapter.kt
@@ -0,0 +1,106 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemAesMembersListBinding
+import org.piramalswasthya.sakhi.model.BenWithAESScreeningDomain
+
+class AESMemberListAdapter(
+ private val clickListener: ClickListener? = null
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithAESScreeningDomain,
+ newItem: BenWithAESScreeningDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithAESScreeningDomain,
+ newItem: BenWithAESScreeningDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemAesMembersListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemAesMembersListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithAESScreeningDomain,
+ clickListener: ClickListener?,
+ ) {
+ binding.benWithAes = item
+ binding.ivSyncState.visibility = if (item.aes == null) View.GONE else View.VISIBLE
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+
+ binding.btnFormTb.visibility = if (item.aes == null && item.ben.isDeath) View.INVISIBLE else View.VISIBLE
+ binding.btnFormTb.text = if (item.aes == null) binding.root.resources.getString(R.string.register) else binding.root.resources.getString(R.string.view)
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.aes == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+
+ ) {
+ fun onClickForm(item: BenWithAESScreeningDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AHDAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AHDAdapter.kt
new file mode 100644
index 000000000..ac98fd50c
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AHDAdapter.kt
@@ -0,0 +1,55 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.LayoutAhdItemBinding
+import org.piramalswasthya.sakhi.model.AHDCache
+
+class AHDAdapter(
+ private val clickListener: AHDClickListener? = null,
+) : ListAdapter(BenDiffUtilCallBack) {
+
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: AHDCache,
+ newItem: AHDCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(
+ oldItem: AHDCache,
+ newItem: AHDCache
+ ) = oldItem == newItem
+ }
+
+ class AHDViewHolder private constructor(private val binding: LayoutAhdItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): AHDViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutAhdItemBinding.inflate(layoutInflater, parent, false)
+ return AHDViewHolder(binding)
+ }
+ }
+
+ fun bind(item: AHDCache, clickListener: AHDClickListener?) {
+ binding.ahd = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AHDViewHolder {
+ return AHDViewHolder.from(parent)
+ }
+
+ override fun onBindViewHolder(holder: AHDViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class AHDClickListener(val clickListener: (id: Int) -> Unit) {
+ fun onClick(id: Int) = clickListener(id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AadhaarConsentAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AadhaarConsentAdapter.kt
new file mode 100644
index 000000000..8ca1c515b
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AadhaarConsentAdapter.kt
@@ -0,0 +1,67 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvCardAbhaConcentBinding
+import org.piramalswasthya.sakhi.model.AadhaarConsentModel
+
+class AadhaarConsentAdapter(private val clickListener: ConsentClickListener) :
+ ListAdapter(
+ MyDiffUtilCallBack
+ ) {
+ private object MyDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: AadhaarConsentModel, newItem: AadhaarConsentModel
+ ) = oldItem.title == newItem.title
+
+ override fun areContentsTheSame(
+ oldItem: AadhaarConsentModel, newItem: AadhaarConsentModel
+ ) = oldItem == newItem
+
+ }
+
+ class AadhaarConsentViewHolder private constructor(private val binding: RvCardAbhaConcentBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): AadhaarConsentViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvCardAbhaConcentBinding.inflate(layoutInflater, parent, false)
+ return AadhaarConsentViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: AadhaarConsentModel, clickListener: ConsentClickListener
+ ) {
+ binding.item = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+
+ binding.checkBox.setOnCheckedChangeListener(null)
+ binding.checkBox.isChecked=item.checked
+ binding.checkBox.setOnCheckedChangeListener { _, isChecked ->
+ item.checked=isChecked
+ if (isChecked){
+ clickListener.onClicked(item.apply {
+ checked = true },position)
+ }else{
+ clickListener.onClicked(item.apply { checked = false },position)
+ }
+ }
+
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)= AadhaarConsentViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: AadhaarConsentViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class ConsentClickListener(val selectedListener: (selectedConsent: AadhaarConsentModel,position:Int) -> Unit) {
+ fun onClicked(selectedConsent: AadhaarConsentModel,position:Int) = selectedListener(selectedConsent,position)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AdolescentHealthListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AdolescentHealthListAdapter.kt
new file mode 100644
index 000000000..a7dd21d51
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AdolescentHealthListAdapter.kt
@@ -0,0 +1,142 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemAdolscentHealthListBinding
+import org.piramalswasthya.sakhi.model.BenWithAdolescentDomain
+
+
+class AdolescentHealthListAdapter(
+ private val clickListener: ClickListener? = null,
+ private val showBeneficiaries: Boolean = false,
+ private val showRegistrationDate: Boolean = false,
+ private val showSyncIcon: Boolean = false,
+ private val showAbha: Boolean = false,
+ private val role: Int? = 0
+) :
+ ListAdapter(BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithAdolescentDomain, newItem: BenWithAdolescentDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithAdolescentDomain, newItem: BenWithAdolescentDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemAdolscentHealthListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemAdolscentHealthListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithAdolescentDomain,
+ clickListener: ClickListener?,
+ showAbha: Boolean,
+ showSyncIcon: Boolean,
+ showRegistrationDate: Boolean,
+ showBeneficiaries: Boolean, role: Int?
+ ) {
+ binding.ivSyncState.visibility = if (item.adolescent == null) View.INVISIBLE else View.VISIBLE
+
+ binding.ben = item
+ binding.clickListener = clickListener
+ binding.showAbha = showAbha
+ binding.showRegistrationDate = showRegistrationDate
+ binding.registrationDate.visibility =
+ if (showRegistrationDate) View.VISIBLE else View.INVISIBLE
+ binding.blankSpace.visibility =
+ if (showRegistrationDate) View.VISIBLE else View.INVISIBLE
+ binding.hasAbha = !item.ben.abhaId.isNullOrEmpty()
+ binding.role = role
+
+ if (item.ben.gender == "MALE") {
+ binding.btnFormTb.visibility = View.GONE
+ } else {
+ binding.btnFormTb.visibility = View.VISIBLE
+ }
+
+ if (showBeneficiaries) {
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+ } else {
+ binding.father = false
+ binding.husband = false
+ binding.spouse = false
+ }
+ binding.btnFormTb.text = if (item.adolescent == null) binding.root.context.getString(R.string.register) else binding.root.context.getString(R.string.view)
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.adolescent == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+ }
+
+
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ) = BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(
+ getItem(position),
+ clickListener,
+ showAbha,
+ showSyncIcon,
+ showRegistrationDate,
+ showBeneficiaries,
+ role
+ )
+ }
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+
+ ) {
+ fun onClickForm(item: BenWithAdolescentDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncAbortionListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncAbortionListAdapter.kt
new file mode 100644
index 000000000..bf752014e
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncAbortionListAdapter.kt
@@ -0,0 +1,72 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemAbortionBinding
+import org.piramalswasthya.sakhi.model.BenWithAncListDomain
+
+class AncAbortionListAdapter(
+ private val clickListener: AbortionListClickListener? = null
+) : ListAdapter(DiffCallback) {
+
+ private object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithAncListDomain, newItem: BenWithAncListDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithAncListDomain, newItem: BenWithAncListDomain
+ ) = oldItem == newItem
+ }
+
+ class AbortionViewHolder private constructor(
+ private val binding: RvItemAbortionBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(item: BenWithAncListDomain, clickListener: AbortionListClickListener?) {
+ binding.visit = item
+ binding.clickListener = clickListener
+
+ binding.btnPmsma.text = if (item.isAbortionFormFilled) binding.root.resources.getString(
+ R.string.view) else binding.root.resources.getString(
+ R.string.add)
+ binding.btnPmsma.setBackgroundColor(
+ binding.root.resources.getColor(
+ if (item.isAbortionFormFilled) android.R.color.holo_green_dark
+ else android.R.color.holo_red_dark
+ )
+ )
+
+ binding.btnViewVisits.visibility =View.INVISIBLE
+ binding.executePendingBindings()
+ }
+
+ companion object {
+ fun from(parent: ViewGroup): AbortionViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemAbortionBinding.inflate(layoutInflater, parent, false)
+ return AbortionViewHolder(binding)
+ }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
+ AbortionViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: AbortionViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class AbortionListClickListener(
+ private val showVisits: (benId: Long) -> Unit,
+ private val addVisit: (benId: Long) -> Unit,
+ ) {
+ fun showVisits(item: BenWithAncListDomain) = showVisits(item.ben.benId)
+ fun addVisit(item: BenWithAncListDomain) = addVisit(item.ben.benId)
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncHomeVisitAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncHomeVisitAdapter.kt
new file mode 100644
index 000000000..2bd696284
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncHomeVisitAdapter.kt
@@ -0,0 +1,62 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.ItemAncHomeVisitBinding
+import org.piramalswasthya.sakhi.model.HomeVisitDomain
+
+class AncHomeVisitAdapter(
+ private val clickListener: HomeVisitClickListener? = null
+) : ListAdapter(MyDiffUtilCallBack) {
+
+ private object MyDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: HomeVisitDomain, newItem: HomeVisitDomain) =
+ oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: HomeVisitDomain, newItem: HomeVisitDomain) =
+ oldItem == newItem
+ }
+
+ class HomeVisitViewHolder private constructor(private val binding: ItemAncHomeVisitBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ companion object {
+ fun from(parent: ViewGroup): HomeVisitViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = ItemAncHomeVisitBinding.inflate(layoutInflater, parent, false)
+ return HomeVisitViewHolder(binding)
+ }
+ }
+
+ fun bind(item: HomeVisitDomain, clickListener: HomeVisitClickListener?) {
+ binding.visit = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+
+
+
+
+ binding.btnView.setOnClickListener {
+ clickListener?.onViewClick(item)
+ }
+
+ binding.executePendingBindings()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
+ HomeVisitViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: HomeVisitViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class HomeVisitClickListener(
+ private val onViewClick: (HomeVisitDomain) -> Unit
+ ) {
+ fun onViewClick(item: HomeVisitDomain) = onViewClick.invoke(item)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitAdapter.kt
index 97669204b..47fd52ac3 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitAdapter.kt
@@ -1,21 +1,24 @@
package org.piramalswasthya.sakhi.adapters
import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemPregnancyAncBinding
import org.piramalswasthya.sakhi.model.AncStatus
+import org.piramalswasthya.sakhi.utils.RoleConstants
-class AncVisitAdapter(private val clickListener: AncVisitClickListener) :
+class AncVisitAdapter(private val clickListener: AncVisitClickListener, private val pref: PreferenceDao? = null) :
ListAdapter(
MyDiffUtilCallBack
) {
private object MyDiffUtilCallBack : DiffUtil.ItemCallback() {
override fun areItemsTheSame(
oldItem: AncStatus, newItem: AncStatus
- ) = oldItem.benId == newItem.benId
+ ) = oldItem.benId == newItem.benId && oldItem.visitNumber == newItem.visitNumber
override fun areContentsTheSame(
oldItem: AncStatus, newItem: AncStatus
@@ -34,12 +37,23 @@ class AncVisitAdapter(private val clickListener: AncVisitClickListener) :
}
fun bind(
- item: AncStatus, clickListener: AncVisitClickListener
+ item: AncStatus, clickListener: AncVisitClickListener, pref: PreferenceDao?, isLastItem: Boolean
) {
+
+ if (pref?.getLoggedInUser()?.role.equals(RoleConstants.ROLE_ASHA_SUPERVISOR, true)) {
+ binding.btnView.visibility = View.GONE
+ } else {
+ binding.btnView.visibility = View.VISIBLE
+ }
+
binding.visit = item
binding.clickListener = clickListener
binding.executePendingBindings()
+ binding.btnView.setOnClickListener {
+ clickListener.onClickedVisit(item, isLastItem)
+ }
+
}
}
@@ -48,16 +62,16 @@ class AncVisitAdapter(private val clickListener: AncVisitClickListener) :
) = AncViewHolder.from(parent)
override fun onBindViewHolder(holder: AncViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener)
+ val isLastItem = position == itemCount - 1
+ holder.bind(getItem(position), clickListener, pref, isLastItem)
}
class AncVisitClickListener(
- private val clickedForm: (benId: Long, visitNumber: Int) -> Unit,
-
+ private val clickedForm: (benId: Long, visitNumber: Int, isLast: Boolean) -> Unit
) {
- fun onClickedVisit(item: AncStatus) = clickedForm(
- item.benId, item.visitNumber
+ fun onClickedVisit(item: AncStatus, isLast: Boolean) = clickedForm(
+ item.benId, item.visitNumber, isLast
)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitListAdapter.kt
index 561b55d30..6301e340c 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/AncVisitListAdapter.kt
@@ -6,26 +6,47 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemPregnancyVisitBinding
+import org.piramalswasthya.sakhi.model.BenBasicDomain
import org.piramalswasthya.sakhi.model.BenWithAncListDomain
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import org.piramalswasthya.sakhi.utils.RoleConstants
+import java.util.concurrent.TimeUnit
-class AncVisitListAdapter(private val clickListener: PregnancyVisitClickListener? = null) :
- ListAdapter(
- MyDiffUtilCallBack
- ) {
+private fun View.setVisibleIf(condition: Boolean) {
+ this.isEnabled = condition
+ this.alpha = if (condition) 1.0f else 0.5f
+}
+private fun View.setVisibleIfViewVisit(condition: Boolean) {
+ this.visibility = if (condition) View.VISIBLE else View.INVISIBLE
+}
+
+class AncVisitListAdapter(
+ private val clickListener: PregnancyVisitClickListener? = null,
+ private val showCall: Boolean = false,
+ private val pref: PreferenceDao? = null,
+ private val isHighRiskMode: Boolean = false,
+ private val hidePmsma: Boolean
+) : ListAdapter(
+ MyDiffUtilCallBack
+) {
private object MyDiffUtilCallBack : DiffUtil.ItemCallback() {
- override fun areItemsTheSame(
- oldItem: BenWithAncListDomain, newItem: BenWithAncListDomain
- ) = oldItem.ben.benId == newItem.ben.benId
+ override fun areItemsTheSame(oldItem: BenWithAncListDomain, newItem: BenWithAncListDomain) =
+ oldItem.ben.benId == newItem.ben.benId
override fun areContentsTheSame(
- oldItem: BenWithAncListDomain, newItem: BenWithAncListDomain
- ) = oldItem == newItem
-
+ oldItem: BenWithAncListDomain,
+ newItem: BenWithAncListDomain
+ ) =
+ oldItem == newItem
}
class PregnancyVisitViewHolder private constructor(private val binding: RvItemPregnancyVisitBinding) :
RecyclerView.ViewHolder(binding.root) {
+
companion object {
fun from(parent: ViewGroup): PregnancyVisitViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
@@ -35,46 +56,114 @@ class AncVisitListAdapter(private val clickListener: PregnancyVisitClickListener
}
fun bind(
- item: BenWithAncListDomain, clickListener: PregnancyVisitClickListener?
+ item: BenWithAncListDomain,
+ clickListener: PregnancyVisitClickListener?,
+ showCall: Boolean,
+ pref: PreferenceDao?,
+ isHighRiskMode: Boolean,
+ hidePmsma: Boolean
) {
+
+ if (pref?.getLoggedInUser()?.role.equals(RoleConstants.ROLE_ASHA_SUPERVISOR, true)) {
+ binding.btnPmsma.visibility = View.INVISIBLE
+ binding.btnAddAnc.visibility = View.INVISIBLE
+ binding.btnAddHomeVisit.visibility = View.INVISIBLE
+ } else {
+ binding.btnPmsma.visibility = View.VISIBLE
+ binding.btnAddAnc.visibility = View.VISIBLE
+ binding.btnAddHomeVisit.visibility = View.VISIBLE
+ }
+
+ if (item.ancDate == 0L) {
+ binding.ivFollowState.visibility = View.GONE
+ binding.llBenPwrTrackingDetails4.visibility = View.GONE
+ } else if (item.ancDate < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(90) &&
+ item.ancDate > System.currentTimeMillis() - TimeUnit.DAYS.toMillis(365)
+ ) {
+ binding.ivFollowState.visibility = View.VISIBLE
+ binding.llBenPwrTrackingDetails4.visibility = View.VISIBLE
+ binding.benVisitDate.text = HelperUtil.getDateStringFromLongStraight(item.ancDate)
+ } else {
+ binding.ivFollowState.visibility = View.GONE
+ binding.llBenPwrTrackingDetails4.visibility = View.VISIBLE
+ binding.benVisitDate.text = HelperUtil.getDateStringFromLongStraight(item.ancDate)
+ }
+
+ binding.btnAddHomeVisit.visibility =
+ if (item.showAddHomeVisit) View.VISIBLE else View.GONE
+
+ binding.btnViewHomeVisit.visibility =
+ if (item.showViewHomeVisit) View.VISIBLE else View.GONE
+
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true))
+ {
+ binding.btnAddHomeVisit.visibility = View.GONE
+ binding.btnViewHomeVisit.visibility = View.GONE
+
+
+ }
+
+ if (showCall) {
+ binding.ivCall.visibility = View.VISIBLE
+ } else {
+ binding.ivCall.visibility = View.GONE
+ }
+
binding.visit = item
- binding.btnAddAnc.visibility = if (item.showAddAnc) View.VISIBLE else View.INVISIBLE
- binding.btnPmsma.visibility = if (item.pmsmaFillable) View.VISIBLE else View.INVISIBLE
- binding.btnPmsma.text = if (item.hasPmsma) "View PMSMA" else "Add PMSMA"
- binding.btnPmsma.setBackgroundColor(binding.root.resources.getColor(if (item.hasPmsma) android.R.color.holo_green_dark else android.R.color.holo_red_dark))
- binding.btnViewVisits.visibility =
- if (item.anc.isEmpty()) View.INVISIBLE else View.VISIBLE
+ binding.llAnc.visibility = if (!isHighRiskMode) View.VISIBLE else View.GONE
+ binding.btnAddAnc.setVisibleIf(item.showAddAnc)
+ binding.btnPmsma.setVisibleIf(item.showAddAnc)
+ binding.btnViewVisits.setVisibleIfViewVisit(item.anc.isNotEmpty())
+ binding.btnViewVisitsPmsma.setVisibleIfViewVisit(item.anc.isNotEmpty())
+ if (hidePmsma) {
+ binding.btnPmsma.visibility = View.GONE
+ binding.btnViewVisitsPmsma.visibility = View.GONE
+ }
binding.clickListener = clickListener
binding.executePendingBindings()
-
}
}
- override fun onCreateViewHolder(
- parent: ViewGroup, viewType: Int
- ) = PregnancyVisitViewHolder.from(parent)
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
+ PregnancyVisitViewHolder.from(parent)
override fun onBindViewHolder(holder: PregnancyVisitViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener)
+ holder.bind(getItem(position), clickListener, showCall, pref, isHighRiskMode, hidePmsma)
}
-
class PregnancyVisitClickListener(
private val showVisits: (benId: Long) -> Unit,
- private val addVisit: (benId: Long, visitNumber: Int) -> Unit,
- private val pmsma: (benId: Long, hhId: Long) -> Unit,
+ private val showPmsmaVisits: (benId: Long, hhId: Long) -> Unit,
+ private val addVisit: (benId: Long, hhId: Long, visitNumber: Int) -> Unit,
+ private val pmsma: (benId: Long, hhId: Long, visitNumber: Int) -> Unit,
+ private val callBen: (ben: BenWithAncListDomain) -> Unit,
+ private val addHomeVisit: ((benId: Long) -> Unit)? = null,
+ private val showHomeVisit : ((benId: Long) -> Unit)? = null
+ ) {
+ fun showVisits(item: BenWithAncListDomain) = showVisits(item.ben.benId)
+ fun showPmsmaVisits(item: BenWithAncListDomain) =
+ showPmsmaVisits(item.ben.benId, item.ben.hhId)
- ) {
- fun showVisits(item: BenWithAncListDomain) = showVisits(
+ fun addVisit(item: BenWithAncListDomain) = addVisit(
item.ben.benId,
+ item.ben.hhId,
+ if (item.anc.isEmpty()) 1 else item.anc.maxOf { it.visitNumber } + 1
)
- fun addVisit(item: BenWithAncListDomain) = addVisit(item.ben.benId,
- if (item.anc.isEmpty()) 1 else item.anc.maxOf { it.visitNumber } + 1)
-
fun pmsma(item: BenWithAncListDomain) = pmsma(
- item.ben.benId, item.ben.hhId
+ item.ben.benId,
+ item.ben.hhId,
+ if (item.pmsma.isEmpty()) 1 else item.pmsma.maxOf { it.visitNumber } + 1
)
- }
-}
\ No newline at end of file
+ fun onClickedForCall(item: BenWithAncListDomain) = callBen(item)
+ fun addHomeVisit(item: BenWithAncListDomain) {
+ addHomeVisit?.invoke(
+ item.ben.benId,
+
+ )
+ }
+ fun showHomeVisit(item: BenWithAncListDomain) = showHomeVisit?.invoke(item.ben.benId)
+
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenChildImmunizationListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenChildImmunizationListAdapter.kt
new file mode 100644
index 000000000..7488467bb
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenChildImmunizationListAdapter.kt
@@ -0,0 +1,86 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvItemBenChildImmunizationBinding
+import org.piramalswasthya.sakhi.model.BenBasicDomain
+import org.piramalswasthya.sakhi.model.ImmunizationDetailsDomain
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+class BenChildImmunizationListAdapter(
+ private val clickListener: VaccinesClickListener? = null
+) : ListAdapter(
+ BenDiffUtilCallBack
+) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: ImmunizationDetailsDomain, newItem: ImmunizationDetailsDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: ImmunizationDetailsDomain, newItem: ImmunizationDetailsDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenVaccineViewHolder private constructor(private val binding: RvItemBenChildImmunizationBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenVaccineViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemBenChildImmunizationBinding.inflate(layoutInflater, parent, false)
+ return BenVaccineViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: ImmunizationDetailsDomain, clickListener: VaccinesClickListener?
+ ) {
+
+ binding.temp = item.ben
+ binding.clickListener = clickListener
+
+ var dob = getDateFromLong(item.ben.dob)
+ binding.tvDob.text = dob
+
+ binding.executePendingBindings()
+
+ }
+
+ fun getDateFromLong(dateLong: Long): String? {
+ if (dateLong == 0L) return null
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = dateLong
+ val f = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ return f.format(cal.time)
+ }
+ }
+
+
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ): BenVaccineViewHolder = BenVaccineViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenVaccineViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+
+ }
+
+
+ class VaccinesClickListener(
+ private val clickedVaccine: (benId: Long) -> Unit,
+
+ ) {
+ fun onClickedBen(item: BenBasicDomain) = clickedVaccine(
+ item.benId
+ )
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapter.kt
index 9be771ac3..e034d597e 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapter.kt
@@ -3,11 +3,19 @@ package org.piramalswasthya.sakhi.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemBenBinding
+import org.piramalswasthya.sakhi.helpers.getDateFromLong
+import org.piramalswasthya.sakhi.helpers.getPatientTypeByAge
import org.piramalswasthya.sakhi.model.BenBasicDomain
+import org.piramalswasthya.sakhi.model.Gender
+import org.piramalswasthya.sakhi.utils.RoleConstants
class BenListAdapter(
@@ -16,10 +24,16 @@ class BenListAdapter(
private val showRegistrationDate: Boolean = false,
private val showSyncIcon: Boolean = false,
private val showAbha: Boolean = false,
- private val role: Int? = 0
+ private val showCall: Boolean = false,
+ private val role: Int? = 0,
+ private val pref: PreferenceDao? = null,
+ var context: FragmentActivity,
+ private val isSoftDeleteEnabled: Boolean = false,
+ private val showActionButtons: Boolean = true,
) :
ListAdapter(BenDiffUtilCallBack) {
- private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+
+ object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
override fun areItemsTheSame(
oldItem: BenBasicDomain, newItem: BenBasicDomain
) = oldItem.benId == newItem.benId
@@ -46,8 +60,21 @@ class BenListAdapter(
showAbha: Boolean,
showSyncIcon: Boolean,
showRegistrationDate: Boolean,
- showBeneficiaries: Boolean, role: Int?
+ showBeneficiaries: Boolean, role: Int?,
+ showCall: Boolean,
+ isSoftDeleteEnabled: Boolean,
+ pref: PreferenceDao?,
+ context: FragmentActivity,
+ benIdList: List,
+ childCountMap: Map = emptyMap(),
+ showActionButtons: Boolean = true
) {
+
+ if (pref?.getLoggedInUser()?.role.equals(RoleConstants.ROLE_ASHA_SUPERVISOR, true)) {
+ binding.btnAbha.visibility = View.GONE
+ } else {
+ binding.btnAbha.visibility = View.VISIBLE
+ }
if (!showSyncIcon) item.syncState = null
binding.ben = item
binding.clickListener = clickListener
@@ -60,6 +87,147 @@ class BenListAdapter(
binding.hasAbha = !item.abhaId.isNullOrEmpty()
binding.role = role
+ if (showCall) {
+ binding.ivCall.visibility = View.VISIBLE
+ } else {
+ binding.ivCall.visibility = View.GONE
+ }
+
+ val isMatched = benIdList.contains(item.benId)
+ binding.isMatched = isMatched
+
+ binding.btnAbove30.text = if (isMatched) {
+ binding.root.context.getString(R.string.view_edit_eye_surgery)
+ } else {
+ binding.root.context.getString(R.string.add_eye_surgery)
+ }
+
+ binding.executePendingBindings()
+
+ var gender = item.gender.toString()
+
+ if (item.relToHeadId == 19) {
+ binding.HOF.visibility = View.VISIBLE
+ } else {
+ binding.HOF.visibility = View.GONE
+ }
+
+ if (item.dob != null) {
+ val type = getPatientTypeByAge(getDateFromLong(item.dob))
+ when (type) {
+
+ "new_born_baby" -> {
+ binding.ivHhLogo.setImageResource(R.drawable.ic_icon_baby)
+ }
+
+ "infant" -> {
+ binding.ivHhLogo.setImageResource(R.drawable.ic_infant)
+ }
+
+ "child", "adolescence" -> {
+ when (gender) {
+ Gender.MALE.name -> {
+ binding.ivHhLogo.setImageResource(R.drawable.ic_icon_boy_ben)
+ }
+
+ Gender.FEMALE.name -> {
+ binding.ivHhLogo.setImageResource(R.drawable.ic_girl)
+ }
+
+ else -> {
+ // Intentionally left blank (no icon change)
+ }
+ }
+ }
+
+ "adult" -> {
+ when (gender) {
+ Gender.MALE.name -> {
+ binding.ivHhLogo.setImageResource(R.drawable.ic_males)
+ }
+
+ Gender.FEMALE.name -> {
+ binding.ivHhLogo.setImageResource(R.drawable.ic_icon_female_2)
+ }
+
+ else -> {
+ binding.ivHhLogo.setImageResource(R.drawable.ic_unisex)
+ }
+ }
+ }
+ }
+
+ }
+
+ val effectiveChildCount = childCountMap[item.benId] ?: item.noOfChildren
+
+ when {
+ item.gender == "MALE" && !item.isSpouseAdded && item.isMarried -> {
+ binding.btnAddSpouse.visibility = View.VISIBLE
+ binding.btnAddChildren.visibility = View.INVISIBLE
+ binding.llAddSpouseBtn.visibility = View.VISIBLE
+ binding.btnAddSpouse.text = context.getString(R.string.add_wife)
+ binding.btnAddSpouse.setOnClickListener {
+ clickListener?.onClickedWifeBen(item)
+ }
+ }
+
+ // FEMALE + married + no spouse: show Add Husband only
+ item.gender == "FEMALE" && !item.isSpouseAdded && item.isMarried -> {
+ binding.btnAddSpouse.visibility = View.VISIBLE
+ binding.btnAddChildren.visibility = View.INVISIBLE
+ binding.llAddSpouseBtn.visibility = View.VISIBLE
+ binding.btnAddSpouse.text = context.getString(R.string.add_husband)
+ binding.btnAddSpouse.setOnClickListener {
+ clickListener?.onClickedHusbandBen(item)
+ }
+ }
+
+ // FEMALE + married + spouse added + 0 children + doYouHavechildren: Register Children
+ item.gender == "FEMALE" &&
+ item.isMarried &&
+ item.isSpouseAdded &&
+ item.doYouHavechildren &&
+ effectiveChildCount == 0 -> {
+
+ binding.btnAddChildren.visibility = View.VISIBLE
+ binding.btnAddChildren.text = context.getString(R.string.add_children)
+ binding.btnAddSpouse.visibility = View.GONE
+ binding.llAddSpouseBtn.visibility = View.VISIBLE
+ binding.btnAddChildren.setOnClickListener {
+ clickListener?.onClickChildBen(item)
+ }
+ }
+
+ // FEMALE + married + spouse added + >0 children: View Children
+ item.gender == "FEMALE" &&
+ item.isMarried &&
+ item.isSpouseAdded &&
+ effectiveChildCount > 0 -> {
+
+ binding.btnAddChildren.visibility = View.VISIBLE
+ binding.btnAddChildren.text = context.getString(R.string.view_children)
+ binding.btnAddSpouse.visibility = View.GONE
+ binding.llAddSpouseBtn.visibility = View.VISIBLE
+ binding.btnAddChildren.setOnClickListener {
+ clickListener?.onClickChildBen(item)
+ }
+ }
+
+ else -> {
+ binding.btnAddSpouse.visibility = View.GONE
+ binding.btnAddChildren.visibility = View.INVISIBLE
+ binding.llAddSpouseBtn.visibility = View.GONE
+ }
+ }
+
+ if (!showActionButtons) {
+ binding.btnAbove30.visibility = View.GONE
+ binding.btnAddSpouse.visibility = View.GONE
+ binding.btnAddChildren.visibility = View.GONE
+ binding.llAddSpouseBtn.visibility = View.GONE
+ }
+
if (showBeneficiaries) {
if (item.spouseName == "Not Available" && item.fatherName == "Not Available") {
binding.father = true
@@ -93,8 +261,76 @@ class BenListAdapter(
binding.husband = false
binding.spouse = false
}
- binding.executePendingBindings()
+ if (item.isDeath) {
+ binding.contentLayout.setBackgroundColor(
+ ContextCompat.getColor(
+ binding.contentLayout.context,
+ R.color.md_theme_dark_outline
+ )
+ )
+ binding.ivCall.visibility = View.GONE
+ binding.ivSyncState.visibility = View.GONE
+ binding.llAddSpouseBtn.visibility = View.GONE
+ binding.btnAbha.visibility = View.GONE
+ binding.ivSoftDelete.visibility = View.GONE
+ } else {
+ binding.contentLayout.setBackgroundColor(
+ ContextCompat.getColor(
+ binding.contentLayout.context,
+ R.color.md_theme_light_primary
+ )
+ )
+ }
+
+ if (isSoftDeleteEnabled) {
+ binding.ivSoftDelete.visibility = View.VISIBLE
+
+ if (item.isDeactivate) {
+ binding.contentLayout.setBackgroundColor(
+ ContextCompat.getColor(
+ binding.contentLayout.context,
+ R.color.Quartenary
+ )
+ )
+ binding.ivSoftDelete.visibility = View.GONE
+
+ binding.btnAbha.visibility = View.INVISIBLE
+ binding.tvTitleDuplicaterecord.visibility = View.VISIBLE
+ binding.ivCall.visibility = View.INVISIBLE
+ binding.ivSyncState.visibility = View.INVISIBLE
+ binding.llBenDetails4.visibility = View.GONE
+ binding.llAddSpouseBtn.visibility = View.GONE
+
+
+ } else {
+
+ if (!item.isDeath) {
+ binding.contentLayout.setBackgroundColor(
+ ContextCompat.getColor(
+ binding.contentLayout.context,
+ R.color.md_theme_light_primary
+ )
+ )
+
+ binding.btnAbha.visibility = View.VISIBLE
+ binding.tvTitleDuplicaterecord.visibility = View.GONE
+ binding.llBenDetails4.visibility = View.VISIBLE
+ binding.ivCall.visibility = View.VISIBLE
+ binding.ivSyncState.visibility = View.VISIBLE
+ binding.llAddSpouseBtn.visibility = View.VISIBLE
+
+ } else {
+ binding.ivSoftDelete.visibility = View.GONE
+
+ }
+ }
+
+ } else {
+ binding.ivSoftDelete.visibility = View.GONE
+ }
+
+ binding.executePendingBindings()
}
}
@@ -102,6 +338,8 @@ class BenListAdapter(
parent: ViewGroup, viewType: Int
) = BenViewHolder.from(parent)
+ private val benIds = mutableListOf()
+
override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
holder.bind(
getItem(position),
@@ -110,25 +348,79 @@ class BenListAdapter(
showSyncIcon,
showRegistrationDate,
showBeneficiaries,
- role
+ role,
+ showCall,
+ isSoftDeleteEnabled,
+ pref,
+ context,
+ benIds,
+ showActionButtons = showActionButtons
)
}
+ fun submitBenIds(list: List) {
+ val oldIds = benIds.toSet()
+ benIds.clear()
+ benIds.addAll(list)
+ val newIds = benIds.toSet()
+ val changed = (oldIds - newIds) + (newIds - oldIds)
+ if (changed.isNotEmpty()) {
+ currentList.forEachIndexed { index, item ->
+ if (item.benId in changed) {
+ notifyItemChanged(index)
+ }
+ }
+ }
+ }
+
class BenClickListener(
- private val clickedBen: (hhId: Long, benId: Long, relToHeadId: Int) -> Unit,
- private val clickedHousehold: (hhId: Long) -> Unit,
- private val clickedABHA: (benId: Long, hhId: Long) -> Unit,
+ private val clickedBen: (item: BenBasicDomain, hhId: Long, benId: Long, relToHeadId: Int) -> Unit,
+ private val clickedWifeBen: (item: BenBasicDomain, hhId: Long, benId: Long, relToHeadId: Int) -> Unit,
+ private val clickedHusbandBen: (item: BenBasicDomain, hhId: Long, benId: Long, relToHeadId: Int) -> Unit,
+ private val clickedChildben: (item: BenBasicDomain, hhId: Long, benId: Long, relToHeadId: Int) -> Unit,
+ private val clickedHousehold: (item: BenBasicDomain, hhId: Long) -> Unit,
+ private val clickedABHA: (item: BenBasicDomain, benId: Long, hhId: Long) -> Unit,
+ private val clickedAddAllBenBtn: (item: BenBasicDomain, benId: Long, hhId: Long, isViewMode: Boolean, isIFA: Boolean) -> Unit,
+ private val callBen: (ben: BenBasicDomain) -> Unit,
+ private val softDeleteBen: (ben: BenBasicDomain) -> Unit
) {
fun onClickedBen(item: BenBasicDomain) = clickedBen(
+ item,
item.hhId,
item.benId,
item.relToHeadId - 1
)
- fun onClickedHouseHold(item: BenBasicDomain) = clickedHousehold(item.hhId)
- fun onClickABHA(item: BenBasicDomain) = clickedABHA(item.benId, item.hhId)
- }
+ fun onClickedWifeBen(item: BenBasicDomain) = clickedWifeBen(
+ item,
+ item.hhId,
+ item.benId,
+ item.relToHeadId
+ )
+
+
+ fun onClickedHusbandBen(item: BenBasicDomain) = clickedHusbandBen(
+ item,
+ item.hhId,
+ item.benId,
+ item.relToHeadId
+ )
-}
\ No newline at end of file
+ fun onClickChildBen(item: BenBasicDomain) = clickedChildben(
+ item,
+ item.hhId,
+ item.benId,
+ item.relToHeadId
+ )
+
+ fun onClickedHouseHold(item: BenBasicDomain) = clickedHousehold(item, item.hhId)
+ fun onClickABHA(item: BenBasicDomain) = clickedABHA(item, item.benId, item.hhId)
+ fun clickedAddAllBenBtn(item: BenBasicDomain, isMatched: Boolean, isIFA: Boolean) =
+ clickedAddAllBenBtn(item, item.benId, item.hhId, isMatched, isIFA)
+
+ fun onClickedForCall(item: BenBasicDomain) = callBen(item)
+ fun onClickSoftDeleteBen(item: BenBasicDomain) = softDeleteBen(item)
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapterForForm.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapterForForm.kt
index a80bcec7c..963feda14 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapterForForm.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenListAdapterForForm.kt
@@ -7,13 +7,17 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemBenWithFormBinding
import org.piramalswasthya.sakhi.model.BenBasicDomainForForm
+import org.piramalswasthya.sakhi.utils.RoleConstants
class BenListAdapterForForm(
private val clickListener: ClickListener? = null,
private vararg val formButtonText: String,
- private val role: Int? = 0
+ private val role: Int? = 0,
+ private val pref: PreferenceDao? = null,
+ private val isGeneralForm: Boolean? = null
) :
ListAdapter
(BenDiffUtilCallBack) {
@@ -44,8 +48,27 @@ class BenListAdapterForForm(
item: BenBasicDomainForForm,
clickListener: ClickListener?,
vararg btnText: String,
- role: Int?
+ role: Int?,
+ pref: PreferenceDao?,
+ isGeneralForm: Boolean? = null
) {
+
+ binding.isGeneralForm = isGeneralForm == true
+
+ if (pref?.getLoggedInUser()?.role.equals(RoleConstants.ROLE_ASHA_SUPERVISOR, true)) {
+ binding.btnForm1.visibility = View.INVISIBLE
+ binding.btnForm2.visibility = View.INVISIBLE
+ binding.btnForm3.visibility = View.INVISIBLE
+ } else {
+ binding.btnForm1.visibility = View.VISIBLE
+ binding.btnForm2.visibility = View.VISIBLE
+ binding.btnForm3.visibility = View.VISIBLE
+ }
+
+
+
+
+
binding.ben = item
binding.clickListener = clickListener
if (btnText.isNotEmpty()) {
@@ -78,6 +101,13 @@ class BenListAdapterForForm(
}
binding.role = role
binding.hasLmp = !item.lastMenstrualPeriod.isNullOrEmpty()
+
+ if (isGeneralForm == true) {
+ binding.ivSyncState.visibility = View.GONE
+ binding.btnForm1.visibility = View.GONE
+ binding.btnForm2.visibility = View.GONE
+ binding.btnForm3.visibility = View.GONE
+ }
binding.executePendingBindings()
}
@@ -153,7 +183,14 @@ class BenListAdapterForForm(
BenViewHolder.from(parent)
override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener, btnText = formButtonText, role = role)
+ holder.bind(
+ getItem(position),
+ clickListener,
+ btnText = formButtonText,
+ role = role,
+ pref = pref,
+ isGeneralForm = isGeneralForm ?: false
+ )
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenPagingAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenPagingAdapter.kt
new file mode 100644
index 000000000..f4c43011c
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/BenPagingAdapter.kt
@@ -0,0 +1,82 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.ViewGroup
+import androidx.fragment.app.FragmentActivity
+import androidx.paging.PagingDataAdapter
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
+import org.piramalswasthya.sakhi.model.BenBasicDomain
+
+class BenPagingAdapter(
+ private val clickListener: BenListAdapter.BenClickListener? = null,
+ private val showBeneficiaries: Boolean = false,
+ private val showRegistrationDate: Boolean = false,
+ private val showSyncIcon: Boolean = false,
+ private val showAbha: Boolean = false,
+ private val showCall: Boolean = false,
+ private val role: Int? = 0,
+ private val pref: PreferenceDao? = null,
+ var context: FragmentActivity,
+ private val isSoftDeleteEnabled: Boolean = false,
+ private val showActionButtons: Boolean = true,
+) :
+ PagingDataAdapter(BenListAdapter.BenDiffUtilCallBack) {
+
+ private val benIds = mutableListOf()
+ private val childCountMap = mutableMapOf()
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ) = BenListAdapter.BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenListAdapter.BenViewHolder, position: Int) {
+ val item = getItem(position) ?: return
+ holder.bind(
+ item,
+ clickListener,
+ showAbha,
+ showSyncIcon,
+ showRegistrationDate,
+ showBeneficiaries,
+ role,
+ showCall,
+ isSoftDeleteEnabled,
+ pref,
+ context,
+ benIds,
+ childCountMap,
+ showActionButtons = showActionButtons
+ )
+ }
+
+ fun submitBenIds(list: List) {
+ val oldIds = benIds.toSet()
+ benIds.clear()
+ benIds.addAll(list)
+ val newIds = benIds.toSet()
+ val changed = (oldIds - newIds) + (newIds - oldIds)
+ if (changed.isNotEmpty()) {
+ val items = snapshot()
+ items.forEachIndexed { index, item ->
+ if (item != null && item.benId in changed) {
+ notifyItemChanged(index)
+ }
+ }
+ }
+ }
+
+ fun submitChildCounts(map: Map) {
+ val old = childCountMap.toMap()
+ childCountMap.clear()
+ childCountMap.putAll(map)
+ val changed = map.entries.filter { (k, v) -> old[k] != v }.map { it.key }.toSet() +
+ old.entries.filter { (k, v) -> map[k] != v }.map { it.key }.toSet()
+ if (changed.isNotEmpty()) {
+ val items = snapshot()
+ items.forEachIndexed { index, item ->
+ if (item != null && item.benId in changed) {
+ notifyItemChanged(index)
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/CUFYAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/CUFYAdapter.kt
new file mode 100644
index 000000000..c24a186a8
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/CUFYAdapter.kt
@@ -0,0 +1,86 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.ChildrenUnderFiveYearsItemBinding
+import org.piramalswasthya.sakhi.model.BenBasicDomain
+import org.piramalswasthya.sakhi.ui.home_activity.child_care.children_under_five_years.CUFYListViewModel
+import org.piramalswasthya.sakhi.utils.dynamicFormConstants.FormConstants
+
+class CUFYAdapter(
+ private val clickListener: ChildListClickListener,
+
+) :
+ ListAdapter(BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: CUFYListViewModel.BenWithSamStatus, newItem: CUFYListViewModel.BenWithSamStatus
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: CUFYListViewModel.BenWithSamStatus, newItem: CUFYListViewModel.BenWithSamStatus
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: ChildrenUnderFiveYearsItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = ChildrenUnderFiveYearsItemBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: CUFYListViewModel.BenWithSamStatus,
+ clickListener: ChildListClickListener
+ ) {
+ binding.ben = item.ben
+ binding.clickListener = clickListener
+ binding.samStatus = item.samStatus
+ binding.executePendingBindings()
+
+ }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ) = BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+
+ }
+
+ suspend fun updateSamStatus(benId: Long, status: String) {
+ val currentList = currentList.toMutableList()
+ val index = currentList.indexOfFirst { it.ben.benId == benId }
+ if (index != -1) {
+ val updatedItem = currentList[index].copy(samStatus = status)
+ currentList[index] = updatedItem
+ submitList(currentList.toList())
+ }
+ }
+
+
+ class ChildListClickListener(
+ val goToForm: (benId: Long, hhId: Long, dob: Long, type: String) -> Unit
+
+ ) {
+ fun onClickedSAM(item: BenBasicDomain) = goToForm(
+ item.benId, item.hhId, item.dob, FormConstants.SAM_FORM_NAME
+ )
+ fun onClickedORS(item: BenBasicDomain) = goToForm(
+ item.benId, item.hhId, item.dob, FormConstants.ORS_FORM_NAME
+ )
+ fun onClickedIFA(item: BenBasicDomain) = goToForm(
+ item.benId, item.hhId, item.dob, FormConstants.IFA_FORM_NAME
+ )
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildCareVisitListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildCareVisitListAdapter.kt
new file mode 100644
index 000000000..186df071a
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildCareVisitListAdapter.kt
@@ -0,0 +1,58 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvItemChildrenCareBottomSheetBinding
+import org.piramalswasthya.sakhi.model.ChildOption
+
+class ChildCareVisitListAdapter(
+ private val clickListener: ChildOptionsClickListener
+) : ListAdapter(
+ MyDiffUtilCallBack
+) {
+
+
+ private object MyDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: ChildOption, newItem: ChildOption): Boolean =
+ oldItem.formType == newItem.formType
+
+ override fun areContentsTheSame(oldItem: ChildOption, newItem: ChildOption): Boolean =
+ oldItem == newItem
+ }
+
+ class ChildOptionViewHolder private constructor(
+ private val binding: RvItemChildrenCareBottomSheetBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ companion object {
+ fun from(parent: ViewGroup): ChildOptionViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemChildrenCareBottomSheetBinding.inflate(layoutInflater, parent, false)
+ return ChildOptionViewHolder(binding)
+ }
+ }
+
+ fun bind(item: ChildOption, clickListener: ChildOptionsClickListener) {
+ binding.option = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChildOptionViewHolder =
+ ChildOptionViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: ChildOptionViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class ChildOptionsClickListener(
+ private val clickedOption: (formType: String, visitDay: String?, isViewMode: Boolean,formDataJson: String?, recordId: Int?) -> Unit
+ ) {
+ fun onAddClicked(item: ChildOption) = clickedOption(item.formType, null, false, null,null)
+ fun onViewClicked(item: ChildOption) = clickedOption(item.formType, item.visitDay, true,item.formDataJson,item.recordId)
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildImmunizationVaccineAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildImmunizationVaccineAdapter.kt
new file mode 100644
index 000000000..cc458ff17
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildImmunizationVaccineAdapter.kt
@@ -0,0 +1,133 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.ItemChildImmunizationDoseBinding
+import org.piramalswasthya.sakhi.model.VaccineDomain
+
+
+
+class ChildImmunizationVaccineAdapter (private val clickListener: ImmunizationClickListener? = null) :
+ ListAdapter(
+ ImmunizationIconDiffCallback
+ ) {
+ object ImmunizationIconDiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: VaccineDomain, newItem: VaccineDomain) =
+ oldItem.vaccineId == newItem.vaccineId
+
+ override fun areContentsTheSame(oldItem: VaccineDomain, newItem: VaccineDomain) =
+ (oldItem == newItem)
+
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
+ IconViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: IconViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class IconViewHolder private constructor(private val binding: ItemChildImmunizationDoseBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ companion object {
+ fun from(parent: ViewGroup): IconViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = ItemChildImmunizationDoseBinding.inflate(layoutInflater, parent, false)
+ return IconViewHolder(binding)
+ }
+ }
+
+ /*fun bind(
+ item: VaccineDomain,
+ clickListener: ImmunizationClickListener?
+ ) {
+ binding.vaccine = item
+ binding.clickListener = clickListener
+
+
+ binding.idSwitch.setOnCheckedChangeListener(null)
+ binding.idSwitch.isChecked = item.isSwitchChecked
+ if (item.state.name =="PENDING"||item.state.name =="OVERDUE"){
+ binding.idSwitch.isEnabled = true
+
+ }else if(item.state.name =="MISSED" ||item.state.name =="UNAVAILABLE"){
+ binding.idSwitch.isEnabled = false
+
+ }else{
+ //If state is DONE
+ binding.idSwitch.isEnabled = false
+ binding.idSwitch.isChecked = true
+ }
+
+
+ binding.idSwitch.setOnCheckedChangeListener { compoundButton, b ->
+ if (b){
+ clickListener?.onClicked(position,item.apply {
+ isSwitchChecked = true })
+ }else{
+ clickListener?.onClicked(position,item.apply { isSwitchChecked = false })
+ }
+
+ }
+ binding.executePendingBindings()
+
+
+ }*/
+
+ fun bind(
+ item: VaccineDomain,
+ clickListener: ImmunizationClickListener?
+ ) {
+ binding.vaccine = item
+ binding.clickListener = clickListener
+
+ // Reset listeners before re-binding
+ binding.idSwitch.setOnCheckedChangeListener(null)
+ binding.idSwitch.setOnClickListener(null)
+
+ // Set switch state
+ binding.idSwitch.isChecked = item.isSwitchChecked
+
+ when (item.state.name) {
+ "PENDING", "OVERDUE" -> {
+ binding.idSwitch.isEnabled = true
+ binding.idSwitch.setOnCheckedChangeListener { _, isChecked ->
+ clickListener?.onClicked(adapterPosition, item.apply { isSwitchChecked = isChecked })
+ }
+ }
+
+ "MISSED", "UNAVAILABLE" -> {
+ binding.idSwitch.isEnabled = true // keep it tappable
+ binding.idSwitch.isChecked = false
+ binding.idSwitch.setOnClickListener {
+ Toast.makeText(
+ binding.root.context,
+ "Immunization cannot be done as it is missed",
+ Toast.LENGTH_SHORT
+ ).show()
+ binding.idSwitch.isChecked = false // always force back to off
+ }
+ }
+
+ else -> { // DONE
+ binding.idSwitch.isEnabled = false
+ binding.idSwitch.isChecked = true
+ }
+ }
+
+ binding.executePendingBindings()
+ }
+
+ }
+
+
+ class ImmunizationClickListener(val selectedListener: (position:Int, vaccine: VaccineDomain) -> Unit) {
+ fun onClicked(position:Int,vaccine: VaccineDomain) = selectedListener(position,vaccine)
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildListAdapter.kt
index 439d11da6..179c5d9cb 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildListAdapter.kt
@@ -58,11 +58,11 @@ class ChildListAdapter(
class ChildListClickListener(
- val goToHbnc: (benId: Long, hhId: Long) -> Unit
+ val goToHbyc: (benId: Long, hhId: Long,dob:Long) -> Unit
) {
- fun onClickedHbnc(item: BenBasicDomain) = goToHbnc(
- item.benId, item.hhId
+ fun onClickedHbyc(item: BenBasicDomain) = goToHbyc(
+ item.benId, item.hhId,item.dob
)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildRegistrationAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildRegistrationAdapter.kt
index 4219ac94d..f75f477d5 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildRegistrationAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ChildRegistrationAdapter.kt
@@ -5,6 +5,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.databinding.RvItemBenChildRegBinding
import org.piramalswasthya.sakhi.model.ChildRegDomain
@@ -42,7 +43,7 @@ class ChildRegistrationAdapter(
clickListener: ClickListener?,
) {
binding.item = item
- binding.btnForm.text = if (item.childBen == null) "Register" else "View"
+ binding.btnForm.text = if (item.childBen == null) binding.root.resources.getString(R.string.register) else binding.root.resources.getString(R.string.view)
binding.btnForm.setBackgroundColor(binding.root.resources.getColor(if (item.childBen == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
binding.clickListener = clickListener
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/DewormingAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/DewormingAdapter.kt
new file mode 100644
index 000000000..cb1b192d2
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/DewormingAdapter.kt
@@ -0,0 +1,55 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.model.DewormingCache
+import org.piramalswasthya.sakhi.databinding.LayoutDewormingItemBinding
+
+class DewormingAdapter(
+ private val clickListener: DewormingClickListener? = null,
+) : ListAdapter(DewormingDiffUtilCallBack) {
+
+ private object DewormingDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: DewormingCache,
+ newItem: DewormingCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(
+ oldItem: DewormingCache,
+ newItem: DewormingCache
+ ) = oldItem == newItem
+ }
+
+ class DewormingViewHolder private constructor(private val binding: LayoutDewormingItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): DewormingViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutDewormingItemBinding.inflate(layoutInflater, parent, false)
+ return DewormingViewHolder(binding)
+ }
+ }
+
+ fun bind(item: DewormingCache, clickListener: DewormingClickListener?) {
+ binding.deworming = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DewormingViewHolder {
+ return DewormingViewHolder.from(parent)
+ }
+
+ override fun onBindViewHolder(holder: DewormingViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class DewormingClickListener(val clickListener: (id: Int) -> Unit) {
+ fun onClick(id: Int) = clickListener(id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECRegistrationAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECRegistrationAdapter.kt
index 35e6337a4..6e8f410d7 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECRegistrationAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECRegistrationAdapter.kt
@@ -6,8 +6,11 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.databinding.RvItemBenEcWithFormBinding
import org.piramalswasthya.sakhi.model.BenWithEcrDomain
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import java.util.concurrent.TimeUnit
class ECRegistrationAdapter(
private val clickListener: ClickListener? = null
@@ -43,10 +46,39 @@ class ECRegistrationAdapter(
) {
binding.benWithEcr = item
+ if (item.ecr == null) {
+ binding.llLmpDate.visibility = View.INVISIBLE
+ binding.llBenStatus.visibility = View.INVISIBLE
+ } else {
+ binding.llLmpDate.visibility = View.VISIBLE
+ binding.llBenStatus.visibility = View.VISIBLE
+ }
+
+ if (item.ecr?.lmpDate != null && item.ecr.lmpDate != 0L) {
+ binding.benLmpDate.text = HelperUtil.getDateStringFromLongStraight(item.ecr.lmpDate)
+ if (System.currentTimeMillis() - item.ecr.lmpDate > TimeUnit.DAYS.toMillis(35)) {
+ binding.ivMissState.visibility = View.VISIBLE
+ binding.benStatus.text = "Missed Period"
+ } else {
+ binding.ivMissState.visibility = View.GONE
+ binding.benStatus.text = "Under Review"
+ }
+ } else {
+ binding.ivMissState.visibility = View.GONE
+ binding.llLmpDate.visibility = View.INVISIBLE
+ binding.llBenStatus.visibility = View.INVISIBLE
+ }
+
binding.ivSyncState.visibility = if (item.ecr == null) View.INVISIBLE else View.VISIBLE
- binding.btnFormEc1.text = if (item.ecr == null) "Register" else "View"
+ binding.btnFormEc1.text =
+ if (item.ecr != null && item.ecr.lmpDate != 0L) {
+ binding.root.resources.getString(R.string.view)
+ } else {
+ binding.root.resources.getString(R.string.register)
+ }
- binding.btnFormEc1.setBackgroundColor(binding.root.resources.getColor(if (item.ecr == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+
+ binding.btnFormEc1.setBackgroundColor(binding.root.resources.getColor(if (item.ecr != null && item.ecr.lmpDate != 0L) android.R.color.holo_green_dark else android.R.color.holo_red_dark))
binding.clickListener = clickListener
binding.executePendingBindings()
@@ -67,9 +99,13 @@ class ECRegistrationAdapter(
class ClickListener(
- private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null,
+ private val clickedAddAllBenBtn: (item:BenWithEcrDomain,benId: Long, hhId: Long, isViewMode: Boolean, isIFA: Boolean) -> Unit,
+
- ) {
+
+ ) {
+ fun clickedAddAllBenBtn(item: BenWithEcrDomain, isMatched: Boolean, isIFA: Boolean) = clickedAddAllBenBtn(item,item.ben.benId, item.ben.hhId, isMatched,isIFA)
fun onClickForm(item: BenWithEcrDomain) =
clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECTrackingListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECTrackingListAdapter.kt
index abe5a50c7..a476ccca9 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECTrackingListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ECTrackingListAdapter.kt
@@ -1,12 +1,15 @@
package org.piramalswasthya.sakhi.adapters
import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import org.piramalswasthya.sakhi.databinding.RvItemEcTrackingListBinding
import org.piramalswasthya.sakhi.model.BenWithEctListDomain
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import java.util.concurrent.TimeUnit
class ECTrackingListAdapter(private val clickListener: ECTrackListClickListener) :
ListAdapter(
@@ -36,6 +39,41 @@ class ECTrackingListAdapter(private val clickListener: ECTrackListClickListener)
fun bind(
item: BenWithEctListDomain, clickListener: ECTrackListClickListener
) {
+
+ if (item.savedECTRecords.isEmpty()) {
+ binding.llEcTrackingDetails3.visibility = View.GONE
+ } else {
+ binding.llEcTrackingDetails3.visibility = View.VISIBLE
+ }
+
+ if (item.ectDate == 0L) {
+ binding.ivFollowState.visibility = View.GONE
+ binding.llVisitDate.visibility = View.INVISIBLE
+ } else if (item.ectDate < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(90) &&
+ item.ectDate > System.currentTimeMillis() - TimeUnit.DAYS.toMillis(365)) {
+ binding.ivFollowState.visibility = View.VISIBLE
+ binding.llVisitDate.visibility = View.VISIBLE
+ binding.benVisitDate.text = HelperUtil.getDateStringFromLongStraight(item.ectDate)
+ } else {
+ binding.ivFollowState.visibility = View.GONE
+ binding.llVisitDate.visibility = View.VISIBLE
+ binding.benVisitDate.text = HelperUtil.getDateStringFromLongStraight(item.ectDate)
+ }
+
+ if (item.lmpDate != 0L) {
+ binding.benLmpDate.text = HelperUtil.getDateStringFromLongStraight(item.lmpDate)
+ if (System.currentTimeMillis() - item.lmpDate > TimeUnit.DAYS.toMillis(35)) {
+ binding.ivMissState.visibility = View.VISIBLE
+ binding.benStatus.text = "Missed Period"
+ } else {
+ binding.ivMissState.visibility = View.GONE
+ binding.benStatus.text = "Under Review"
+ }
+ } else {
+ binding.ivMissState.visibility = View.GONE
+ binding.llEcTrackingDetails3.visibility = View.GONE
+ }
+
binding.item = item
binding.clickListener = clickListener
binding.executePendingBindings()
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FailedWorkerAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FailedWorkerAdapter.kt
new file mode 100644
index 000000000..5a79f9470
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FailedWorkerAdapter.kt
@@ -0,0 +1,42 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvItemFailedWorkerBinding
+import org.piramalswasthya.sakhi.model.FailedWorkerInfo
+
+class FailedWorkerAdapter :
+ ListAdapter(DiffCallback) {
+
+ private object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: FailedWorkerInfo, newItem: FailedWorkerInfo) =
+ oldItem.workerName == newItem.workerName
+
+ override fun areContentsTheSame(oldItem: FailedWorkerInfo, newItem: FailedWorkerInfo) =
+ oldItem == newItem
+ }
+
+ class ViewHolder(
+ private val binding: RvItemFailedWorkerBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(item: FailedWorkerInfo) {
+ binding.tvWorkerName.text = item.workerName
+ binding.tvErrorReason.text = item.error
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = RvItemFailedWorkerBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(getItem(position))
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FilariaMemberListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FilariaMemberListAdapter.kt
new file mode 100644
index 000000000..ef33d9ad7
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FilariaMemberListAdapter.kt
@@ -0,0 +1,121 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemFilariaMemberListBinding
+import org.piramalswasthya.sakhi.databinding.RvItemKalaAzarMemberListBinding
+import org.piramalswasthya.sakhi.model.BenWithFilariaScreeningDomain
+import org.piramalswasthya.sakhi.model.BenWithKALAZARScreeningDomain
+
+class FilariaMemberListAdapter(
+ private val clickListener: ClickListener? = null
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithFilariaScreeningDomain,
+ newItem: BenWithFilariaScreeningDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithFilariaScreeningDomain,
+ newItem: BenWithFilariaScreeningDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemFilariaMemberListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFilariaMemberListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithFilariaScreeningDomain,
+ clickListener: ClickListener?,
+ ) {
+ binding.benWithFilaria = item
+
+ /*if(item.tb?.historyOfTb == true){
+ binding.cvContent.visibility = View.GONE
+ }*/
+
+ binding.ivSyncState.visibility = if (item.filaria == null) View.GONE else View.VISIBLE
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+
+ if ( item.filaria != null && item.ben.isDeath) {
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.filaria == null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.filaria != null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else {
+ binding.btnFormTb.visibility = View.INVISIBLE
+ }
+ binding.btnFormTb.text = if (item.filaria == null) binding.root.resources.getString(R.string.register) else binding.root.resources.getString(R.string.view)
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.filaria == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+
+ ) {
+ fun onClickForm(item: BenWithFilariaScreeningDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FileListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FileListAdapter.kt
new file mode 100644
index 000000000..0a62ae3b6
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FileListAdapter.kt
@@ -0,0 +1,38 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.net.Uri
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.LayoutFileViewBinding
+
+class FileListAdapter(private var images: MutableList) : RecyclerView.Adapter() {
+
+
+ fun updateFileList(newList: MutableList) {
+ this.images.clear()
+ this.images.addAll(newList)
+ notifyDataSetChanged()
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileVH {
+ val v = LayoutInflater.from(parent.context)
+ .inflate(R.layout.layout_file_view, parent, false)
+
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutFileViewBinding.inflate(layoutInflater, parent, false)
+ return FileVH(binding)
+ }
+
+ override fun getItemCount() = images.size
+
+ override fun onBindViewHolder(holder: FileVH, position: Int) {
+ val file = images.get(position)
+ holder.binding.ivPreview.setImageURI(file)
+ }
+
+ class FileVH(var binding: LayoutFileViewBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FollowUpDatesAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FollowUpDatesAdapter.kt
new file mode 100644
index 000000000..724c92d0f
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FollowUpDatesAdapter.kt
@@ -0,0 +1,59 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.ItemFollowUpDateBinding
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.LeprosyFollowUpCache
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import java.text.SimpleDateFormat
+import java.util.*
+
+class FollowUpDatesAdapter :
+ ListAdapter(DiffCallback) {
+
+ private val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FollowUpViewHolder {
+ val binding = ItemFollowUpDateBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ return FollowUpViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: FollowUpViewHolder, position: Int) {
+ val followUp = getItem(position)
+ holder.bind(followUp)
+ }
+
+ inner class FollowUpViewHolder(private val binding: ItemFollowUpDateBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(followUp: LeprosyFollowUpCache) {
+ binding.tvFollowUpDate.text = dateFormat.format(Date(followUp.followUpDate))
+ val ctx = binding.root.context
+ val englishArray = HelperUtil.getLocalizedResources(ctx, Languages.ENGLISH)
+ .getStringArray(R.array.leprosy_treatment_status_before_time)
+ val localizedArray = ctx.resources.getStringArray(R.array.leprosy_treatment_status_before_time)
+ val idx = englishArray.indexOf(followUp.treatmentStatus)
+ binding.tvTreatmentStatus.text = if (idx >= 0) localizedArray[idx]
+ else ctx.getString(R.string.pending)
+ }
+ }
+
+ companion object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: LeprosyFollowUpCache, newItem: LeprosyFollowUpCache): Boolean {
+ return oldItem.id == newItem.id
+ }
+
+ override fun areContentsTheSame(oldItem: LeprosyFollowUpCache, newItem: LeprosyFollowUpCache): Boolean {
+ return oldItem == newItem
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapter.kt
index 949fd361b..ecaba4258 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapter.kt
@@ -2,12 +2,16 @@ package org.piramalswasthya.sakhi.adapters
import android.app.DatePickerDialog
import android.app.TimePickerDialog
+import android.content.Context
import android.content.Context.INPUT_METHOD_SERVICE
import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Color
+import android.net.Uri
import android.os.Build
import android.text.Editable
+import android.text.InputFilter
+import android.text.InputFilter.AllCaps
import android.text.Spannable
import android.text.SpannableString
import android.text.TextWatcher
@@ -23,26 +27,36 @@ import android.widget.CheckBox
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup
+import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.children
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.textfield.TextInputEditText
+import com.google.android.material.textfield.TextInputLayout
import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.LayoutMultiFileUploadBinding
+import org.piramalswasthya.sakhi.databinding.LayoutUploafFormBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormAgePickerViewV2Binding
+import org.piramalswasthya.sakhi.databinding.RvItemFormBtnBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormCheckV2Binding
import org.piramalswasthya.sakhi.databinding.RvItemFormDatepickerV2Binding
import org.piramalswasthya.sakhi.databinding.RvItemFormDropdownV2Binding
import org.piramalswasthya.sakhi.databinding.RvItemFormEditTextV2Binding
import org.piramalswasthya.sakhi.databinding.RvItemFormHeadlineV2Binding
import org.piramalswasthya.sakhi.databinding.RvItemFormImageViewV2Binding
+import org.piramalswasthya.sakhi.databinding.RvItemFormNumberPickerBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormRadioV2Binding
import org.piramalswasthya.sakhi.databinding.RvItemFormTextViewV2Binding
import org.piramalswasthya.sakhi.databinding.RvItemFormTimepickerV2Binding
import org.piramalswasthya.sakhi.helpers.Konstants
import org.piramalswasthya.sakhi.helpers.getDateString
+import org.piramalswasthya.sakhi.helpers.isInternetAvailable
import org.piramalswasthya.sakhi.model.AgeUnitDTO
import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
import org.piramalswasthya.sakhi.model.InputType.AGE_PICKER
import org.piramalswasthya.sakhi.model.InputType.CHECKBOXES
import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
@@ -55,25 +69,30 @@ import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
import org.piramalswasthya.sakhi.model.InputType.TIME_PICKER
import org.piramalswasthya.sakhi.model.InputType.values
import org.piramalswasthya.sakhi.ui.home_activity.all_ben.new_ben_registration.AgePickerDialog
+import org.piramalswasthya.sakhi.ui.home_activity.all_ben.new_ben_registration.ben_form.NewBenRegViewModel.Companion.isOtpVerified
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import org.piramalswasthya.sakhi.utils.HelperUtil.findFragmentActivity
import org.piramalswasthya.sakhi.utils.HelperUtil.getAgeStrFromAgeUnit
import org.piramalswasthya.sakhi.utils.HelperUtil.getDobFromAge
import org.piramalswasthya.sakhi.utils.HelperUtil.getLongFromDate
import org.piramalswasthya.sakhi.utils.HelperUtil.updateAgeDTO
import timber.log.Timber
import java.util.Calendar
+import java.util.Locale
class FormInputAdapter(
private val imageClickListener: ImageClickListener? = null,
private val ageClickListener: AgeClickListener? = null,
+ private val sendOtpClickListener: SendOtpClickListener? = null,
private val formValueListener: FormValueListener? = null,
- private val isEnabled: Boolean = true
+ private val isEnabled: Boolean = true,
+ private val selectImageClickListener: SelectUploadImageClickListener? = null,
+ private val viewDocumentListner: ViewDocumentOnClick? = null,
+ var fileList: MutableList? = null,
) : ListAdapter(FormInputDiffCallBack) {
+ var disableUpload = false
- // @Inject
-// lateinit var preferenceDao: PreferenceDao
-// @Inject
-// lateinit var context: Context
object FormInputDiffCallBack : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: FormElement, newItem: FormElement) =
oldItem.id == newItem.id
@@ -108,6 +127,28 @@ class FormInputAdapter(
} else {
binding.et.isClickable = true
binding.et.isFocusable = true
+ binding.et.isFocusableInTouchMode = true
+ }
+ if (isOtpVerified && item.id == 44 && item.title.equals("Contact Number")) {
+ binding.et.isClickable = false
+ binding.et.isFocusable = false
+ }
+
+ if (item.title.contains("first name", true) ||
+ item.title.contains("last name", true) ||
+ item.title.contains("father's name", true) ||
+ item.title.contains("mother's name", true)
+ ) {
+// edittext.setFilters(arrayOf(AllCaps()))
+ val editFilters = binding.et.filters
+ var newFilters = arrayOfNulls(editFilters.size + 1)
+ editFilters.forEachIndexed { index, inputFilter ->
+ newFilters[index] = editFilters[index]
+ }
+ newFilters[editFilters.size] = AllCaps()
+// newFilters.set(editFilters.size, AllCaps())
+// binding.et.filters = arrayOf(AllCaps())
+ binding.et.filters = newFilters
}
binding.form = item
if (item.errorText == null) binding.tilEditText.isErrorEnabled = false
@@ -155,7 +196,7 @@ class FormInputAdapter(
binding.tilEditText.isErrorEnabled = item.errorText != null
binding.tilEditText.error = item.errorText
}
-// binding.tilEditText.error = null
+// binding.tilEditText.error = null
// else if(item.errorText!= null && binding.tilEditText.error==null)
// binding.tilEditText.error = item.errorText
@@ -240,16 +281,32 @@ class FormInputAdapter(
}
}
binding.et.setOnFocusChangeListener { _, hasFocus ->
- if (hasFocus) binding.et.addTextChangedListener(textWatcher)
- else {
+ if (hasFocus){
+ binding.et.requestFocus()
+ binding.et.addTextChangedListener(textWatcher)
+ val imm =
+ binding.root.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
+ imm!!.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
+ } else {
binding.et.removeTextChangedListener(textWatcher)
+ binding.et.clearFocus()
val imm =
binding.root.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
imm!!.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
}
}
+ binding.et.setOnEditorActionListener { v, actionId, _ ->
+ if (actionId == android.view.inputmethod.EditorInfo.IME_ACTION_DONE ||
+ actionId == android.view.inputmethod.EditorInfo.IME_ACTION_NEXT) {
+ v.clearFocus()
+ val imm = v.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
+ imm?.hideSoftInputFromWindow(v.windowToken, 0)
+ true
+ } else false
+ }
binding.et.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_ENTER && (event.action == KeyEvent.ACTION_UP || event.action == KeyEvent.ACTION_DOWN)) {
+ v.clearFocus()
return@OnKeyListener true
}
false
@@ -293,6 +350,11 @@ class FormInputAdapter(
}
fun bind(item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?) {
+ binding.tilRvDropdown.clearFocus()
+ binding.tilEditText.clearFocus()
+ binding.et.clearFocus()
+ binding.actvRvDropdown.clearFocus()
+ binding.actvRvDropdown.showSoftInputOnFocus = false
binding.form = item
if (item.errorText == null) {
binding.tilRvDropdown.error = null
@@ -307,7 +369,11 @@ class FormInputAdapter(
return
}
+ hideKeyboardImmediately()
+
+
binding.actvRvDropdown.setOnItemClickListener { _, _, index, _ ->
+ hideKeyboardWithRetry()
item.value = item.entries?.get(index)
Timber.d("Item DD : $item")
// if (item.hasDependants || item.hasAlertError) {
@@ -317,10 +383,34 @@ class FormInputAdapter(
binding.tilRvDropdown.error = item.errorText
}
+ binding.actvRvDropdown.setOnClickListener {
+ hideKeyboardWithRetry()
+ }
+
item.errorText?.let { binding.tilRvDropdown.error = it }
binding.executePendingBindings()
}
+
+ private fun hideKeyboardImmediately() {
+ val imm = binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
+ }
+
+ private fun hideKeyboardWithRetry() {
+ val imm = binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+
+ imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
+
+ binding.root.postDelayed({
+ imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
+ }, 50)
+
+ binding.root.postDelayed({
+ imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
+ }, 200)
+ }
+
}
class RadioInputViewHolder private constructor(private val binding: RvItemFormRadioV2Binding) :
@@ -398,6 +488,10 @@ class FormInputAdapter(
if (item.value == it) rdBtn.isChecked = true
rdBtn.setOnCheckedChangeListener { _, b ->
if (b) {
+ // Clear focus from any previously focused EditText to prevent auto-scroll
+ binding.root.rootView.findFocus()?.clearFocus()
+ val imm = binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
item.value = it
if (item.hasDependants || item.hasAlertError) {
Timber.d(
@@ -480,76 +574,106 @@ class FormInputAdapter(
}
fun bind(
- item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?
+ item: FormElement,
+ isEnabled: Boolean,
+ formValueListener: FormValueListener?
) {
binding.form = item
-
- if (item.errorText != null) binding.clRi.setBackgroundResource(R.drawable.state_errored)
- else binding.clRi.setBackgroundResource(0)
binding.llChecks.removeAllViews()
- binding.llChecks.apply {
- item.entries?.let { items ->
- orientation = item.orientation ?: LinearLayout.VERTICAL
- weightSum = items.size.toFloat()
- items.forEachIndexed { index, it ->
- val cbx = CheckBox(this.context)
- cbx.layoutParams = RadioGroup.LayoutParams(
- RadioGroup.LayoutParams.MATCH_PARENT,
- RadioGroup.LayoutParams.WRAP_CONTENT,
- 1.0F
- )
- if (!isEnabled) {
- cbx.isClickable = false
- cbx.isFocusable = false
- }
- cbx.id = View.generateViewId()
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) cbx.setTextAppearance(
- context, android.R.style.TextAppearance_Material_Medium
- )
- else cbx.setTextAppearance(android.R.style.TextAppearance_Material_Subhead)
- cbx.text = it
- addView(cbx)
- if (item.value?.contains(it) == true) cbx.isChecked = true
- cbx.setOnCheckedChangeListener { _, b ->
- if (b) {
- if (item.value != null) item.value = item.value + it
- else item.value = it
- if (item.hasDependants || item.hasAlertError) {
- Timber.d(
- "listener trigger : ${item.id} ${
- item.entries!!.indexOf(
- it
- )
- } $it"
- )
-// formValueListener?.onValueChanged(
-// item, item.entries!!.indexOf(it)
-// )
- }
- } else {
- if (item.value?.contains(it) == true) {
- item.value = item.value?.replace(it, "")
- }
- }
- formValueListener?.onValueChanged(
- item, index * (if (b) 1 else -1)
- )
- if (item.value.isNullOrBlank()) {
- item.value = null
- } else {
- Timber.d("Called here!")
- item.errorText = null
- binding.clRi.setBackgroundResource(0)
- }
- Timber.d("Checkbox value : ${item.value}")
- }
+ val selectedIndexes = item.value
+ ?.split("|")
+ ?.mapNotNull { it.toIntOrNull() }
+ ?.toMutableSet()
+ ?: mutableSetOf()
+
+ item.entries?.forEachIndexed { index, text ->
+
+ val cbx = CheckBox(binding.root.context)
+ cbx.text = text
+ cbx.isEnabled = isEnabled
+ cbx.isChecked = selectedIndexes.contains(index)
+ cbx.setOnCheckedChangeListener { _, isChecked ->
+
+ if (isChecked) {
+ selectedIndexes.add(index)
+ } else {
+ selectedIndexes.remove(index)
}
+
+ item.value =
+ if (selectedIndexes.isEmpty()) null
+ else selectedIndexes.sorted().joinToString("|")
+
+ item.errorText = null
+ binding.clRi.setBackgroundResource(0)
+
+ formValueListener?.onValueChanged(item, index)
}
+
+ binding.llChecks.addView(cbx)
}
+
binding.executePendingBindings()
+ }
+
+ }
+
+ class ButtonInputViewHolder private constructor(private val binding: RvItemFormBtnBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormBtnBinding.inflate(layoutInflater, parent, false)
+ return ButtonInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormElement, isEnabled: Boolean, formValueListener: SendOtpClickListener?) {
+ binding.form = item
+ isOtpVerified(isEnabled, isInternetAvailable(binding.root.context))
+
+ binding.generateOtp.setOnClickListener {
+ formValueListener!!.onButtonClick(item,binding.generateOtp,binding.timerInSec,binding.tilEditText,isEnabled,adapterPosition,binding.et)
+ }
+
+
+
+ }
+
+ private fun isOtpVerified(isEnabled: Boolean, internetAvailable: Boolean) {
+ if(isOtpVerified) {
+ binding.generateOtp.text = binding.generateOtp.resources.getString(R.string.verified)
+ binding.generateOtp.isEnabled = isEnabled
+
+ } else {
+ binding.generateOtp.text = binding.generateOtp.resources.getString(R.string.send_otp)
+ if (internetAvailable){
+ binding.generateOtp.isEnabled = isEnabled
+ } else {
+ binding.generateOtp.isEnabled = !isEnabled
+
+ }
+
+ }
}
+
+
+ }
+
+
+
+ class SelectUploadImageClickListener(private val selectImageClick: (formId: Int) -> Unit) {
+
+ fun onSelectImageClick(form: FormElement) = selectImageClick(form.id)
+
+ }
+
+ class ViewDocumentOnClick(private val viewDocument: (formId: Int) -> Unit) {
+
+ fun onViewDocumentClick(form: FormElement) = viewDocument(form.id)
+
}
class DatePickerInputViewHolder private constructor(private val binding: RvItemFormDatepickerV2Binding) :
@@ -581,6 +705,11 @@ class FormInputAdapter(
item.errorText?.also { binding.tilEditText.error = it }
?: run { binding.tilEditText.error = null }
binding.et.setOnClickListener {
+ val activity = binding.et.context.findFragmentActivity()
+ ?: return@setOnClickListener
+ val originalLocale = Locale.getDefault()
+ HelperUtil.setEnLocaleForDatePicker(activity)
+
item.value?.let { value ->
thisYear = value.substring(6).toInt()
thisMonth = value.substring(3, 5).trim().toInt() - 1
@@ -599,18 +728,20 @@ class FormInputAdapter(
item.value = getDateString(item.max)
else
item.value = getDateString(millis)
-// "${if (day > 9) day else "0$day"}-${if (month > 8) month + 1 else "0${month + 1}"}-$year"
binding.invalidateAll()
if (item.hasDependants) formValueListener?.onValueChanged(item, -1)
}, thisYear, thisMonth, thisDay
)
item.errorText = null
binding.tilEditText.error = null
- datePickerDialog.datePicker.maxDate = item.max ?: 0
- datePickerDialog.datePicker.minDate = item.min ?: 0
+ item.min?.let { datePickerDialog.datePicker.minDate = it }
+ item.max?.let { datePickerDialog.datePicker.maxDate = it }
if (item.showYearFirstInDatePicker)
datePickerDialog.datePicker.touchables[0].performClick()
datePickerDialog.show()
+ datePickerDialog.setOnDismissListener {
+ HelperUtil.setOriginalLocaleForDatePicker(activity,originalLocale)
+ }
}
binding.executePendingBindings()
@@ -754,6 +885,8 @@ class FormInputAdapter(
getDobFromAge(ageUnitDTO)
binding.etDate.setText(getDateString(calDob.timeInMillis))
item.value = getDateString(calDob.timeInMillis)
+ item.errorText = null
+ binding.tilEditTextDate.error = null
if (item.hasDependants) formValueListener?.onValueChanged(item, -1)
}
}
@@ -775,6 +908,11 @@ class FormInputAdapter(
item.errorText?.also { binding.tilEditTextDate.error = it }
?: run { binding.tilEditTextDate.error = null }
binding.etDate.setOnClickListener {
+ val activity = binding.etDate.context.findFragmentActivity()
+ ?: return@setOnClickListener
+ val originalLocale = Locale.getDefault()
+ HelperUtil.setEnLocaleForDatePicker(activity)
+
item.value?.let { value ->
thisYear = value.substring(6).toInt()
thisMonth = value.substring(3, 5).trim().toInt() - 1
@@ -803,11 +941,14 @@ class FormInputAdapter(
)
item.errorText = null
binding.tilEditTextDate.error = null
- datePickerDialog.datePicker.maxDate = item.max ?: 0
- datePickerDialog.datePicker.minDate = item.min ?: 0
+ item.min?.let { datePickerDialog.datePicker.minDate = it }
+ item.max?.let { datePickerDialog.datePicker.maxDate = it }
if (item.showYearFirstInDatePicker)
datePickerDialog.datePicker.touchables[0].performClick()
datePickerDialog.show()
+ datePickerDialog.setOnDismissListener {
+ HelperUtil.setOriginalLocaleForDatePicker(activity,originalLocale)
+ }
}
binding.executePendingBindings()
@@ -839,8 +980,20 @@ class FormInputAdapter(
}
class ImageClickListener(private val imageClick: (formId: Int) -> Unit) {
-
fun onImageClick(form: FormElement) = imageClick(form.id)
+ }
+
+ class SendOtpClickListener(private val btnClick: (formId: Int,generateOtp:MaterialButton,timerInsec: TextView,tilEditText:TextInputLayout, isEnabled: Boolean,adapterPosition:Int,otpField: TextInputEditText) -> Unit) {
+
+ fun onButtonClick(
+ form: FormElement,
+ generateOtp: MaterialButton,
+ timerInSec: TextView,
+ tilEditText: TextInputLayout,
+ isEnabled: Boolean,
+ adapterPosition: Int,
+ otpField: TextInputEditText
+ ) = btnClick(form.id,generateOtp,timerInSec,tilEditText,isEnabled,adapterPosition,otpField)
}
@@ -858,11 +1011,171 @@ class FormInputAdapter(
}
}
+ class NumberPickerInputViewHolder private constructor(
+ private val binding: RvItemFormNumberPickerBinding
+ ) : ViewHolder(binding.root) {
+
+ private var textWatcher: TextWatcher? = null
+ private var internalUpdate = false
+
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormNumberPickerBinding.inflate(layoutInflater, parent, false)
+ return NumberPickerInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement,
+ isEnabled: Boolean,
+ formValueListener: FormValueListener?
+ ) {
+ binding.form = item
+
+ binding.etNumberInput.isEnabled = isEnabled
+ binding.btnDecrement.isEnabled = isEnabled
+ binding.btnIncrement.isEnabled = isEnabled
+ if (!isEnabled) {
+ hideError()
+ return
+ }
+
+ val minValue = item.min?.toInt() ?: 0
+ val maxValue = item.max?.toInt()
+ val allowNegative = item.minDecimal != null && item.minDecimal!! < 0
+
+ binding.etNumberInput.setText(minValue.toString())
+ binding.etNumberInput.setSelection(binding.etNumberInput.text!!.length)
+ var currentValue = item.value?.toIntOrNull() ?: minValue
+
+ textWatcher?.let { binding.etNumberInput.removeTextChangedListener(it) }
+
+ textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
+ // No action required for this implementation.
+ // This method is implemented to satisfy the interface contract.
+
+
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ // No action required for this implementation.
+ // This method is implemented to satisfy the interface contract.
+
+ }
+
+
+
+
+ override fun afterTextChanged(editable: Editable?) {
+
+ if (internalUpdate) return
+ if (editable.isNullOrBlank()) {
+ item.errorText = binding.root.resources.getString(R.string.value_cannot_be_empty)
+ showError(item.errorText!!)
+ return
+ }
+
+ val inputValue = editable.toString().toIntOrNull()
+ if (inputValue == null) {
+ item.errorText = binding.root.resources.getString(R.string.enter_a_valid_number)
+ showError(item.errorText!!)
+ return
+ }
+
+ val validated = validateValue(inputValue, minValue, maxValue, allowNegative)
+
+ if (validated != inputValue) {
+ val msg = if (maxValue != null)
+ binding.root.resources.getString(R.string.allowed_range, minValue, maxValue)
+ else
+ binding.root.resources.getString(R.string.minimum_allowed_value, minValue)
+ item.errorText = msg
+ showError(msg)
+
+ updateDisplay(validated)
+ updateValue(validated, item, formValueListener)
+ return
+ }
+
+ item.errorText = null
+ hideError()
+
+ currentValue = validated
+ updateValue(currentValue, item, formValueListener)
+ }
+ }
+
+ updateDisplay(currentValue)
+
+ binding.etNumberInput.addTextChangedListener(textWatcher)
+
+
+
+ binding.btnDecrement.setOnClickListener {
+ currentValue = (item.value?.toIntOrNull() ?: minValue) - 1
+ currentValue = validateValue(currentValue, minValue, maxValue, allowNegative)
+ hideError()
+ updateValue(currentValue, item, formValueListener)
+ updateDisplay(currentValue)
+ }
+
+ binding.btnIncrement.setOnClickListener {
+ currentValue = (item.value?.toIntOrNull() ?: minValue) + 1
+ currentValue = validateValue(currentValue, minValue, maxValue, allowNegative)
+ hideError()
+ updateValue(currentValue, item, formValueListener)
+ updateDisplay(currentValue)
+ }
+ }
+
+
+ private fun validateValue(value: Int, min: Int, max: Int?, allowNegative: Boolean): Int {
+ var newValue = value
+
+ if (!allowNegative && newValue < min) newValue = min
+ if (max != null && newValue > max) newValue = max
+
+ return newValue
+ }
+
+ private fun updateDisplay(value: Int) {
+ internalUpdate = true
+ binding.etNumberInput.setText(value.toString())
+ binding.etNumberInput.setSelection(binding.etNumberInput.text!!.length)
+ internalUpdate = false
+
+ }
+
+ private fun updateValue(
+ newValue: Int,
+ item: FormElement,
+ formValueListener: FormValueListener?
+ ) {
+ item.value = newValue.toString()
+ formValueListener?.onValueChanged(item,newValue)
+ }
+
+ private fun showError(message: String) {
+ binding.tvError.apply {
+ text = message
+ visibility = View.VISIBLE
+ }
+ }
+
+ private fun hideError() {
+ binding.tvError.visibility = View.GONE
+ }
+ }
+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inputTypes = values()
- return when (inputTypes[viewType]) {
+ val safeType = inputTypes.getOrNull(viewType) ?: TEXT_VIEW
+
+ return when (safeType) {
EDIT_TEXT -> EditTextInputViewHolder.from(parent)
DROPDOWN -> DropDownInputViewHolder.from(parent)
RADIO -> RadioInputViewHolder.from(parent)
@@ -873,46 +1186,158 @@ class FormInputAdapter(
TIME_PICKER -> TimePickerInputViewHolder.from(parent)
HEADLINE -> HeadlineViewHolder.from(parent)
AGE_PICKER -> AgePickerViewInputViewHolder.from(parent)
+ InputType.BUTTON -> ButtonInputViewHolder.from(parent)
+ InputType.FILE_UPLOAD -> FileUploadInputViewHolder.from(parent)
+ InputType.NUMBER_PICKER -> NumberPickerInputViewHolder.from(parent)
+ InputType.MULTIFILE_UPLOAD -> MultiFileUploadInputViewHolder.from(parent)
}
}
+ fun updateFileList(newList: List) {
+ this.fileList?.addAll(newList)
+ notifyDataSetChanged()
+ }
+ class MultiFileUploadInputViewHolder private constructor(private val binding: LayoutMultiFileUploadBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutMultiFileUploadBinding.inflate(layoutInflater, parent, false)
+ return MultiFileUploadInputViewHolder(binding)
+ }
+ }
+
+ private lateinit var fileAdapter: FileListAdapter
+
+ fun bind(
+ item: FormElement,
+ clickListener: SelectUploadImageClickListener?,
+ documentOnClick: ViewDocumentOnClick?,
+ isEnabled: Boolean,
+ fileList : MutableList?
+ ) {
+ val items = fileList ?: mutableListOf()
+ fileAdapter = FileListAdapter(items)
+ binding.rvFiles.adapter = fileAdapter
+ fileAdapter.updateFileList(items)
+ fileAdapter.notifyDataSetChanged()
+
+ binding.btnSelectFiles.isEnabled = isEnabled
+ binding.btnSelectFiles.alpha = if (isEnabled) 1f else 0.5f
+
+ binding.btnSelectFiles.setOnClickListener {
+ clickListener?.onSelectImageClick(item)
+ }
+ }
+
+ }
+
+
+
+ class FileUploadInputViewHolder private constructor(private val binding: LayoutUploafFormBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutUploafFormBinding.inflate(layoutInflater, parent, false)
+ return FileUploadInputViewHolder(binding)
+ }
+ }
+
+
+ fun bind(
+ item: FormElement,
+ clickListener: SelectUploadImageClickListener?,
+ documentOnClick: ViewDocumentOnClick?,
+ isEnabled: Boolean
+ ) {
+ binding.form = item
+ binding.tvTitle.text = item.title
+ binding.clickListener = clickListener
+ binding.documentclickListener = documentOnClick
+ binding.btnView.visibility = if (!item.value.isNullOrEmpty()) View.VISIBLE else View.GONE
+
+ if (isEnabled) {
+ binding.addFile.visibility = View.VISIBLE
+// binding.addFile.isEnabled = true
+// binding.addFile.alpha = 1f
+ } else {
+ binding.addFile.visibility = View.GONE
+// binding.addFile.isEnabled = false
+// binding.addFile.alpha = 0.5f
+ }
+ }
+
+ }
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = getItem(position)
- val isEnabled = if (isEnabled) item.isEnabled else false
- when (item.inputType) {
- EDIT_TEXT -> (holder as EditTextInputViewHolder).bind(
- item, isEnabled, formValueListener
- )
-
- DROPDOWN -> (holder as DropDownInputViewHolder).bind(item, isEnabled, formValueListener)
- RADIO -> (holder as RadioInputViewHolder).bind(item, isEnabled, formValueListener)
- DATE_PICKER -> (holder as DatePickerInputViewHolder).bind(
- item, isEnabled, formValueListener
- )
-
- TEXT_VIEW -> (holder as TextViewInputViewHolder).bind(item)
- IMAGE_VIEW -> (holder as ImageViewInputViewHolder).bind(
- item, imageClickListener, isEnabled
- )
-
- CHECKBOXES -> (holder as CheckBoxesInputViewHolder).bind(
- item,
- isEnabled,
- formValueListener
- )
-
- TIME_PICKER -> (holder as TimePickerInputViewHolder).bind(item, isEnabled)
- HEADLINE -> (holder as HeadlineViewHolder).bind(item, formValueListener)
- AGE_PICKER -> (holder as AgePickerViewInputViewHolder).bind(
- item,
- isEnabled,
- formValueListener
- )
+// I was getting crash that's why i have moved this line inside try block
+// val isEnabled = if (isEnabled) item.isEnabled else false
+ try {
+ val isEnabled = if (isEnabled) item.isEnabled else false
+ when (item.inputType) {
+ EDIT_TEXT -> (holder as EditTextInputViewHolder).bind(
+ item, isEnabled, formValueListener
+ )
+
+ DROPDOWN -> (holder as DropDownInputViewHolder).bind(
+ item,
+ isEnabled,
+ formValueListener
+ )
+
+ RADIO -> (holder as RadioInputViewHolder).bind(item, isEnabled, formValueListener)
+ DATE_PICKER -> (holder as DatePickerInputViewHolder).bind(
+ item, isEnabled, formValueListener
+ )
+
+ TEXT_VIEW -> (holder as TextViewInputViewHolder).bind(item)
+ IMAGE_VIEW -> (holder as ImageViewInputViewHolder).bind(
+ item, imageClickListener, isEnabled
+ )
+
+ CHECKBOXES -> (holder as CheckBoxesInputViewHolder).bind(
+ item,
+ isEnabled,
+ formValueListener
+ )
+
+ TIME_PICKER -> (holder as TimePickerInputViewHolder).bind(item, isEnabled)
+ HEADLINE -> (holder as HeadlineViewHolder).bind(item, formValueListener)
+ AGE_PICKER -> (holder as AgePickerViewInputViewHolder).bind(
+ item,
+ isEnabled,
+ formValueListener
+ )
+ InputType.BUTTON -> (holder as ButtonInputViewHolder).bind(
+ item,
+ isEnabled,
+ sendOtpClickListener
+ )
+
+ InputType.FILE_UPLOAD -> (holder as FileUploadInputViewHolder).bind(item,selectImageClickListener,viewDocumentListner,isEnabled = !disableUpload)
+ InputType.MULTIFILE_UPLOAD -> (holder as MultiFileUploadInputViewHolder).bind(item,selectImageClickListener,viewDocumentListner,isEnabled = !disableUpload,fileList)
+
+ InputType.NUMBER_PICKER -> (holder as NumberPickerInputViewHolder).bind(
+ item, isEnabled, formValueListener
+ )
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+
}
}
- override fun getItemViewType(position: Int) = getItem(position).inputType.ordinal
+ //override fun getItemViewType(position: Int) = getItem(position).inputType.ordinal
+ //THis changes done to solve crashalytics issue
+ override fun getItemViewType(position: Int): Int {
+ if (position < 0 || position >= itemCount) {
+ return TEXT_VIEW.ordinal // fallback view type
+ }
+ val item = getItem(position) ?: return TEXT_VIEW.ordinal
+ return item.inputType.ordinal
+ }
/**
* Validation Result : -1 -> all good
* else index of element creating trouble
@@ -945,4 +1370,7 @@ class FormInputAdapter(
}
return retVal
}
+
+
+
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapterOld.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapterOld.kt
index 0490528fb..f26ea3b02 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapterOld.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapterOld.kt
@@ -2,6 +2,9 @@ package org.piramalswasthya.sakhi.adapters
import android.app.DatePickerDialog
import android.app.TimePickerDialog
+import android.content.Context
+import android.net.Uri
+import android.os.CountDownTimer
import android.text.Editable
import android.text.InputFilter
import android.text.InputFilter.AllCaps
@@ -11,39 +14,55 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup
+import android.widget.TextView
import androidx.core.view.children
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import com.google.android.material.button.MaterialButton
import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.adapters.FormInputAdapter.SelectUploadImageClickListener
+import org.piramalswasthya.sakhi.adapters.FormInputAdapter.ViewDocumentOnClick
import org.piramalswasthya.sakhi.configuration.FormEditTextDefaultInputFilter
+import org.piramalswasthya.sakhi.databinding.RvItemFormBtnBinding
+import org.piramalswasthya.sakhi.databinding.LayoutMultiFileUploadBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormCheckBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormDatepickerBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormDropdownBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormEditTextBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormHeadlineBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormImageViewBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormNumberPickerBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormRadioBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormTextViewBinding
import org.piramalswasthya.sakhi.databinding.RvItemFormTimepickerBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormUploadImageBinding
import org.piramalswasthya.sakhi.helpers.Konstants
+import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.FormInputOld
import org.piramalswasthya.sakhi.model.InputType.AGE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.BUTTON
import org.piramalswasthya.sakhi.model.InputType.CHECKBOXES
import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.FILE_UPLOAD
import org.piramalswasthya.sakhi.model.InputType.HEADLINE
import org.piramalswasthya.sakhi.model.InputType.IMAGE_VIEW
import org.piramalswasthya.sakhi.model.InputType.RADIO
import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
import org.piramalswasthya.sakhi.model.InputType.TIME_PICKER
+import org.piramalswasthya.sakhi.model.InputType.NUMBER_PICKER
import org.piramalswasthya.sakhi.model.InputType.values
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import org.piramalswasthya.sakhi.utils.HelperUtil.findFragmentActivity
import timber.log.Timber
import java.util.Calendar
+import java.util.Locale
class FormInputAdapterOld(
private val imageClickListener: ImageClickListener? = null,
@@ -245,6 +264,124 @@ class FormInputAdapterOld(
}
}
+ class ButtonInputViewHolder private constructor(private val binding: RvItemFormBtnBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormBtnBinding.inflate(layoutInflater, parent, false)
+ return ButtonInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormInputOld, isEnabled: Boolean) {
+
+
+ }
+ }
+
+
+ class MultiFileUploadInputViewHolder private constructor(private val binding: LayoutMultiFileUploadBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutMultiFileUploadBinding.inflate(layoutInflater, parent, false)
+ return MultiFileUploadInputViewHolder(binding)
+ }
+ }
+ var selectedFiles = mutableListOf()
+
+ private lateinit var fileAdapter: FileListAdapter
+
+ fun bind(
+ item: FormElement,
+ clickListener: SelectUploadImageClickListener?,
+ documentOnClick: ViewDocumentOnClick?,
+ isEnabled: Boolean
+ ) {
+ /* binding.form = item
+ binding.tvTitle.text = item.title
+ binding.clickListener = clickListener
+ binding.documentclickListener = documentOnClick
+ binding.btnView.visibility = if (item.value != null) View.VISIBLE else View.GONE
+
+ if (isEnabled) {
+ binding.addFile.isEnabled = true
+ binding.addFile.alpha = 1f
+ } else {
+ binding.addFile.isEnabled = false
+ binding.addFile.alpha = 0.5f
+ }*/
+
+ fileAdapter = FileListAdapter(selectedFiles)
+ binding.rvFiles.adapter = fileAdapter
+
+ binding.btnSelectFiles.isEnabled = isEnabled
+ binding.btnSelectFiles.alpha = if (isEnabled) 1f else 0.5f
+
+ binding.btnSelectFiles.setOnClickListener {
+ clickListener?.onSelectImageClick(item)
+ }
+
+ // Show view button only if images exist
+// binding.btnView.visibility = if (selectedFiles.isNotEmpty()) View.VISIBLE else View.GONE
+
+ /*binding.btnView.setOnClickListener {
+ documentOnClick?.onViewDocumentClicked(selectedFiles)
+ }*/
+ }
+
+ fun updateSelectedFiles(files: List) {
+ selectedFiles.clear()
+ selectedFiles.addAll(files)
+ fileAdapter.notifyDataSetChanged()
+// binding.btnView.visibility = if (files.isNotEmpty()) View.VISIBLE else View.GONE
+
+ }
+
+ }
+
+
+ class FileUploadInputViewHolder private constructor(private val binding: RvItemFormUploadImageBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormUploadImageBinding.inflate(layoutInflater, parent, false)
+ return FileUploadInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormInputOld, isEnabled: Boolean) {
+
+ }
+
+ private lateinit var countDownTimer : CountDownTimer
+ private var countdownTimers : HashMap = HashMap()
+
+ private fun formatTimeInSeconds(millis: Long) : String {
+ val seconds = millis / 1000
+ return "${seconds} sec"
+ }
+ private fun startTimer(timerInSec: TextView, generateOtp: MaterialButton) {
+ countDownTimer = object : CountDownTimer(60000, 1000) {
+ override fun onTick(millisUntilFinished: Long) {
+ timerInSec.visibility = View.VISIBLE
+ timerInSec.text = formatTimeInSeconds(millisUntilFinished)
+ }
+ override fun onFinish() {
+ timerInSec.visibility = View.INVISIBLE
+ timerInSec.text = ""
+ generateOtp.isEnabled = true
+ generateOtp.text = timerInSec.resources.getString(R.string.resend_otp)
+ }
+ }.start()
+
+ countdownTimers[adapterPosition] = countDownTimer
+
+ }
+ }
class RadioInputViewHolder private constructor(private val binding: RvItemFormRadioBinding) :
ViewHolder(binding.root) {
companion object {
@@ -289,6 +426,10 @@ class FormInputAdapterOld(
rdBtn.isChecked = true
rdBtn.setOnCheckedChangeListener { _, b ->
if (b) {
+ // Clear focus from any previously focused EditText to prevent auto-scroll
+ binding.root.rootView.findFocus()?.clearFocus()
+ val imm = binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
item.value.value = it
}
item.errorText = null
@@ -375,6 +516,11 @@ class FormInputAdapterOld(
item.errorText?.also { binding.tilEditText.error = it }
?: run { binding.tilEditText.error = null }
binding.et.setOnClickListener {
+ val activity = binding.et.context.findFragmentActivity()
+ ?: return@setOnClickListener
+ val originalLocale = Locale.getDefault()
+ HelperUtil.setEnLocaleForDatePicker(activity)
+
item.value.value?.let { value ->
thisYear = value.substring(6).toInt()
thisMonth = value.substring(3, 5).trim().toInt() - 1
@@ -390,10 +536,13 @@ class FormInputAdapterOld(
)
item.errorText = null
binding.tilEditText.error = null
- datePickerDialog.datePicker.maxDate = item.max ?: 0
- datePickerDialog.datePicker.minDate = item.min ?: 0
+ item.min?.let { datePickerDialog.datePicker.minDate = it }
+ item.max?.let { datePickerDialog.datePicker.maxDate = it }
datePickerDialog.datePicker.touchables[0].performClick()
datePickerDialog.show()
+ datePickerDialog.setOnDismissListener {
+ HelperUtil.setOriginalLocaleForDatePicker(activity,originalLocale)
+ }
}
binding.executePendingBindings()
@@ -511,6 +660,151 @@ class FormInputAdapterOld(
}
+ class NumberPickerInputViewHolder private constructor(
+ private val binding: RvItemFormNumberPickerBinding
+ ) : ViewHolder(binding.root) {
+
+ private var textWatcher: TextWatcher? = null
+ private var internalUpdate = false
+
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormNumberPickerBinding.inflate(layoutInflater, parent, false)
+ return NumberPickerInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement,
+ isEnabled: Boolean,
+ formValueListener: FormInputAdapterOld.FormValueListener?
+ ) {
+ binding.form = item
+
+ val minValue = item.min?.toInt() ?: 0
+ val maxValue = item.max?.toInt()
+ val allowNegative = item.minDecimal != null && item.minDecimal!! < 0
+
+ binding.etNumberInput.setText(minValue.toString())
+ binding.etNumberInput.setSelection(binding.etNumberInput.text!!.length)
+ var currentValue = item.value?.toIntOrNull() ?: minValue
+
+ textWatcher?.let { binding.etNumberInput.removeTextChangedListener(it) }
+
+ textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+
+ }
+
+
+
+
+ override fun afterTextChanged(editable: Editable?) {
+
+ if (internalUpdate) return
+ if (editable.isNullOrBlank()) {
+ showError(binding.root.context.getString(R.string.value_cannot_be_empty))
+ return
+ }
+
+ val inputValue = editable.toString().toIntOrNull()
+ if (inputValue == null) {
+ showError(binding.root.context.getString(R.string.enter_a_valid_number))
+ return
+ }
+
+ val validated = validateValue(inputValue, minValue, maxValue, allowNegative)
+
+ if (validated != inputValue) {
+ showError(binding.root.context.getString(R.string.allowed_range, minValue, maxValue))
+
+ updateDisplay(validated)
+ updateValue(validated, item, formValueListener)
+ return
+ }
+
+ hideError()
+
+ currentValue = validated
+ updateValue(currentValue, item, formValueListener)
+ }
+ }
+
+ updateDisplay(currentValue)
+
+ binding.etNumberInput.addTextChangedListener(textWatcher)
+
+
+
+ binding.btnDecrement.setOnClickListener {
+ currentValue = (item.value?.toIntOrNull() ?: minValue) - 1
+ currentValue = validateValue(currentValue, minValue, maxValue, allowNegative)
+ hideError()
+ updateValue(currentValue, item, formValueListener)
+ updateDisplay(currentValue)
+ }
+
+ binding.btnIncrement.setOnClickListener {
+ currentValue = (item.value?.toIntOrNull() ?: minValue) + 1
+ currentValue = validateValue(currentValue, minValue, maxValue, allowNegative)
+ hideError()
+ updateValue(currentValue, item, formValueListener)
+ updateDisplay(currentValue)
+ }
+ }
+
+
+ private fun validateValue(value: Int, min: Int, max: Int?, allowNegative: Boolean): Int {
+ var newValue = value
+
+ if (!allowNegative && newValue < min) newValue = min
+ if (max != null && newValue > max) newValue = max
+
+ return newValue
+ }
+
+ private fun updateDisplay(value: Int) {
+ internalUpdate = true
+ binding.etNumberInput.setText(value.toString())
+ binding.etNumberInput.setSelection(binding.etNumberInput.text!!.length)
+ internalUpdate = false
+ }
+
+ private fun updateValue(
+ newValue: Int,
+ item: FormElement,
+ formValueListener: FormInputAdapterOld.FormValueListener?
+ ) {
+ item.value = newValue.toString()
+ formValueListener?.onValueChanged(item,newValue)
+ }
+
+ private fun showError(message: String) {
+ binding.tvError.apply {
+ text = message
+ visibility = View.VISIBLE
+ }
+ }
+
+ private fun hideError() {
+ binding.tvError.visibility = View.GONE
+ }
+ }
+
+
+
+ class FormValueListener(private val valueChanged: (id: Int, value: Int) -> Unit) {
+
+ fun onValueChanged(form: FormElement, index: Int) {
+ valueChanged(form.id, index)
+
+ }
+
+ }
+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inputTypes = values()
@@ -525,6 +819,10 @@ class FormInputAdapterOld(
TIME_PICKER -> TimePickerInputViewHolder.from(parent)
HEADLINE -> HeadlineViewHolder.from(parent)
AGE_PICKER -> FormInputAdapter.AgePickerViewInputViewHolder.from(parent)
+ BUTTON -> FormInputAdapter.ButtonInputViewHolder.from(parent)
+ FILE_UPLOAD -> FileUploadInputViewHolder.from(parent)
+ org.piramalswasthya.sakhi.model.InputType.MULTIFILE_UPLOAD -> MultiFileUploadInputViewHolder.from(parent)
+ NUMBER_PICKER ->NumberPickerInputViewHolder.from(parent)
}
}
@@ -546,6 +844,11 @@ class FormInputAdapterOld(
TIME_PICKER -> (holder as TimePickerInputViewHolder).bind(item, isEnabled)
HEADLINE -> (holder as HeadlineViewHolder).bind(item)
AGE_PICKER -> null
+ BUTTON -> (holder as ButtonInputViewHolder).bind(item, isEnabled)
+ FILE_UPLOAD -> (holder as FileUploadInputViewHolder).bind(item, isEnabled)
+ org.piramalswasthya.sakhi.model.InputType.MULTIFILE_UPLOAD -> (holder as FileUploadInputViewHolder).bind(item, isEnabled)
+ NUMBER_PICKER -> null
+
}
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapterWithBgIcon.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapterWithBgIcon.kt
new file mode 100644
index 000000000..38fc92e80
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/FormInputAdapterWithBgIcon.kt
@@ -0,0 +1,1238 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.app.DatePickerDialog
+import android.app.TimePickerDialog
+import android.content.Context
+import android.content.Context.INPUT_METHOD_SERVICE
+import android.content.res.ColorStateList
+import android.content.res.Resources
+import android.graphics.Color
+import android.net.Uri
+import android.os.Build
+import android.os.CountDownTimer
+import android.text.Editable
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.TextWatcher
+import android.text.style.ForegroundColorSpan
+import android.view.Gravity
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.inputmethod.InputMethodManager
+import android.widget.CheckBox
+import android.widget.LinearLayout
+import android.widget.RadioButton
+import android.widget.RadioGroup
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.content.res.AppCompatResources
+import androidx.core.view.children
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import com.google.android.material.button.MaterialButton
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.LayoutMultiFileUploadBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormAgePickerViewV2Binding
+import org.piramalswasthya.sakhi.databinding.RvItemFormBtnBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormCheckV2Binding
+import org.piramalswasthya.sakhi.databinding.RvItemFormDatepickerWithBgIconBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormDropdownWithBgIconBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormEditTextWithBgIconBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormHeadlineV2Binding
+import org.piramalswasthya.sakhi.databinding.RvItemFormImageViewWithBgIconBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormNumberPickerBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormRadioWithBgIconBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormTextViewWithBgIconBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormTimepickerWithBgIconBinding
+import org.piramalswasthya.sakhi.databinding.RvItemFormUploadImageBinding
+import org.piramalswasthya.sakhi.helpers.Konstants
+import org.piramalswasthya.sakhi.helpers.getDateString
+import org.piramalswasthya.sakhi.model.AgeUnitDTO
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.AGE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.BUTTON
+import org.piramalswasthya.sakhi.model.InputType.CHECKBOXES
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.FILE_UPLOAD
+import org.piramalswasthya.sakhi.model.InputType.HEADLINE
+import org.piramalswasthya.sakhi.model.InputType.IMAGE_VIEW
+import org.piramalswasthya.sakhi.model.InputType.RADIO
+import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
+import org.piramalswasthya.sakhi.model.InputType.TIME_PICKER
+import org.piramalswasthya.sakhi.model.InputType.values
+import org.piramalswasthya.sakhi.ui.home_activity.all_ben.new_ben_registration.AgePickerDialog
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import org.piramalswasthya.sakhi.utils.HelperUtil.findFragmentActivity
+import org.piramalswasthya.sakhi.utils.HelperUtil.getAgeStrFromAgeUnit
+import org.piramalswasthya.sakhi.utils.HelperUtil.getDobFromAge
+import org.piramalswasthya.sakhi.utils.HelperUtil.getLongFromDate
+import org.piramalswasthya.sakhi.utils.HelperUtil.updateAgeDTO
+import timber.log.Timber
+import java.util.Calendar
+import java.util.Locale
+
+class FormInputAdapterWithBgIcon (
+ private val imageClickListener: ImageClickListener? = null,
+ private val ageClickListener: AgeClickListener? = null,
+ private val formValueListener: FormValueListener? = null,
+ private val selectImageClickListener: SelectUploadImageClickListener? = null,
+ private val viewDocumentListner: ViewDocumentOnClick? = null,
+ private val isEnabled: Boolean = true
+) : ListAdapter(FormInputDiffCallBack) {
+
+ object FormInputDiffCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: FormElement, newItem: FormElement) =
+ oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: FormElement, newItem: FormElement): Boolean {
+ Timber.d("${oldItem.id} ${oldItem.errorText} ${newItem.errorText}")
+ return oldItem.errorText == newItem.errorText
+ }
+ }
+
+ class EditTextInputViewHolder private constructor(private val binding: RvItemFormEditTextWithBgIconBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormEditTextWithBgIconBinding.inflate(layoutInflater, parent, false)
+ return EditTextInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?) {
+ Timber.d("binding triggered!!! $isEnabled ${item.id}")
+ if (!isEnabled) {
+ binding.et.isClickable = false
+ binding.et.isFocusable = false
+ handleHintLength(item)
+ binding.form = item
+ binding.et.setText(item.value)
+ binding.executePendingBindings()
+ return
+ } else {
+ binding.et.isClickable = true
+ binding.et.isFocusable = true
+ }
+ val param = binding.tilEditText.layoutParams as ViewGroup.MarginLayoutParams
+// param.setMargins(60,0,0,0)
+ binding.tilEditText.layoutParams = param
+ binding.form = item
+ if (item.errorText == null) binding.tilEditText.isErrorEnabled = false
+ Timber.d("Bound EditText item ${item.title} with ${item.required}")
+ binding.tilEditText.error = item.errorText
+ handleHintLength(item)
+ if (item.hasSpeechToText) {
+ binding.tilEditText.endIconDrawable =
+ AppCompatResources.getDrawable(binding.root.context, R.drawable.ic_mic)
+ binding.tilEditText.setEndIconOnClickListener {
+ formValueListener?.onValueChanged(item, Konstants.micClickIndex)
+ }
+ } else {
+ binding.tilEditText.endIconDrawable = null
+ binding.tilEditText.setEndIconOnClickListener(null)
+ }
+
+
+ val textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(
+ s: CharSequence?, start: Int, count: Int, after: Int
+ ) {
+ }
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+ }
+
+ override fun afterTextChanged(editable: Editable?) {
+
+ item.value = editable?.toString()
+ Timber.d("editable : $editable Current value : ${item.value} isNull: ${item.value == null} isEmpty: ${item.value == ""}")
+ formValueListener?.onValueChanged(item, -1)
+ if (item.errorText != binding.tilEditText.error) {
+ binding.tilEditText.isErrorEnabled = item.errorText != null
+ binding.tilEditText.error = item.errorText
+ }
+
+ }
+ }
+ binding.et.setOnFocusChangeListener { _, hasFocus ->
+ if (hasFocus) binding.et.addTextChangedListener(textWatcher)
+ else {
+ binding.et.removeTextChangedListener(textWatcher)
+ val imm =
+ binding.root.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager?
+ imm!!.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
+ }
+ }
+ binding.et.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
+ if (keyCode == KeyEvent.KEYCODE_ENTER && (event.action == KeyEvent.ACTION_UP || event.action == KeyEvent.ACTION_DOWN)) {
+ return@OnKeyListener true
+ }
+ false
+ })
+
+ binding.executePendingBindings()
+ }
+
+ private fun handleHintLength(item: FormElement) {
+ if (item.title.length > Konstants.editTextHintLimit) {
+ binding.tvHint.visibility = View.VISIBLE
+ binding.et.hint = null
+ binding.tilEditText.hint = null
+ binding.tilEditText.isHintEnabled = false
+ } else {
+ binding.tvHint.visibility = View.GONE
+ binding.tilEditText.isHintEnabled = true
+ }
+ }
+ }
+
+ class SelectUploadImageClickListener(private val selectImageClick: (formId: Int) -> Unit) {
+
+ fun onSelectImageClick(form: FormElement) = selectImageClick(form.id)
+
+ }
+
+ class ViewDocumentOnClick(private val viewDocument: (formId: Int) -> Unit) {
+
+ fun onViewDocumentClick(form: FormElement) = viewDocument(form.id)
+
+ }
+
+
+ class DropDownInputViewHolder private constructor(private val binding: RvItemFormDropdownWithBgIconBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormDropdownWithBgIconBinding.inflate(layoutInflater, parent, false)
+ return DropDownInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?) {
+ binding.form = item
+ if (item.errorText == null) {
+ binding.tilRvDropdown.error = null
+ binding.tilRvDropdown.isErrorEnabled = false
+ }
+ if (!isEnabled) {
+ binding.tilRvDropdown.visibility = View.GONE
+// binding.ivIconBg.visibility = View.GONE
+// binding.ivIconTemperature.visibility = View.GONE
+
+ binding.tilEditText.visibility = View.VISIBLE
+ binding.ivIconBg1.visibility = View.VISIBLE
+ binding.ivIconTemperature1.visibility = View.VISIBLE
+
+ binding.et.isFocusable = false
+ binding.et.isClickable = false
+ binding.executePendingBindings()
+ return
+ }
+
+ binding.actvRvDropdown.setOnItemClickListener { _, _, index, _ ->
+ item.value = item.entries?.get(index)
+ Timber.d("Item DD : $item")
+ formValueListener?.onValueChanged(item, index)
+ binding.tilRvDropdown.isErrorEnabled = item.errorText != null
+ binding.tilRvDropdown.error = item.errorText
+ }
+
+ item.errorText?.let { binding.tilRvDropdown.error = it }
+ binding.executePendingBindings()
+
+ }
+ }
+
+ class RadioInputViewHolder private constructor(private val binding: RvItemFormRadioWithBgIconBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormRadioWithBgIconBinding.inflate(layoutInflater, parent, false)
+ return RadioInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?
+ ) {
+ if (!isEnabled) {
+ binding.rg.isClickable = false
+ binding.rg.isFocusable = false
+ }
+ binding.invalidateAll()
+ binding.form = item
+
+ binding.rg.removeAllViews()
+
+ binding.rg.apply {
+ item.entries?.let { items ->
+ orientation = item.orientation ?: LinearLayout.HORIZONTAL
+ weightSum = items.size.toFloat()
+ val layoutParamsRg = binding.rg.layoutParams as ViewGroup.MarginLayoutParams
+
+ items.forEach {
+ val rdBtn = RadioButton(this.context)
+ rdBtn.layoutParams = RadioGroup.LayoutParams(
+ RadioGroup.LayoutParams.WRAP_CONTENT,
+ RadioGroup.LayoutParams.WRAP_CONTENT,
+ 1.0F
+
+ ).apply {
+
+ if (item.id == 23 && item.title == " " || item.id == 9 && item.title == " ") {
+ val density = binding.root.resources.displayMetrics.density
+ layoutParamsRg.topMargin = (-25 * density).toInt()
+ gravity = Gravity.START
+ rdBtn.textSize = 16f
+ } else {
+ layoutParamsRg.topMargin = (0 * binding.root.resources.displayMetrics.density).toInt()
+ gravity = Gravity.CENTER_HORIZONTAL
+ rdBtn.textSize = 14f
+ }
+
+ }
+ rdBtn.id = View.generateViewId()
+ val colorStateList = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ ColorStateList(
+ arrayOf(
+ intArrayOf(-android.R.attr.state_checked),
+ intArrayOf(android.R.attr.state_checked)
+ ), intArrayOf(
+ binding.root.resources.getColor(
+ android.R.color.darker_gray,
+ binding.root.context.theme
+ ), // disabled
+ binding.root.resources.getColor(
+ android.R.color.darker_gray,
+ binding.root.context.theme
+ ) // enabled
+ )
+ )
+ } else {
+ ColorStateList(
+ arrayOf(
+ intArrayOf(-android.R.attr.state_checked),
+ intArrayOf(android.R.attr.state_checked)
+ ), intArrayOf(
+ binding.root.resources.getColor(
+ android.R.color.darker_gray,
+ ), // disabled
+ binding.root.resources.getColor(
+ android.R.color.darker_gray,
+ ) // enabled
+ )
+ )
+ }
+
+ if (!isEnabled) rdBtn.buttonTintList = colorStateList
+ rdBtn.text = it
+ addView(rdBtn)
+ if (item.value == it) rdBtn.isChecked = true
+ rdBtn.setOnCheckedChangeListener { _, b ->
+ if (b) {
+ // Clear focus from any previously focused EditText to prevent auto-scroll
+ binding.root.rootView.findFocus()?.clearFocus()
+ val imm = binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
+ item.value = it
+ if (item.hasDependants || item.hasAlertError) {
+ Timber.d(
+ "listener trigger : ${item.id} ${
+ item.entries!!.indexOf(
+ it
+ )
+ } $it"
+ )
+ formValueListener?.onValueChanged(
+ item, item.entries!!.indexOf(it)
+ )
+ }
+ }
+ item.errorText = null
+ binding.llContent.setBackgroundResource(0)
+ }
+ }
+ }
+ }
+
+ if (!isEnabled) {
+ binding.rg.children.forEach {
+ it.isClickable = false
+ }
+ }
+ if (item.errorText != null) binding.llContent.setBackgroundResource(R.drawable.state_errored)
+ else binding.llContent.setBackgroundResource(0)
+
+ binding.executePendingBindings()
+ val str = binding.tvNullable.text
+ val spannableString = SpannableString(str)
+
+ val colorSpan = ForegroundColorSpan(Color.parseColor("#B00020"))
+
+ if (item.required && item.doubleStar) {
+ spannableString.setSpan(
+ colorSpan,
+ str.length - 2,
+ str.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ binding.tvNullable.text = spannableString
+ binding.tvNullableHr.text = spannableString
+ } else if (item.required) {
+ spannableString.setSpan(
+ colorSpan,
+ str.length - 1,
+ str.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ binding.tvNullableHr.text = spannableString
+ binding.tvNullable.text = spannableString
+ }
+
+ }
+ }
+
+ class CheckBoxesInputViewHolder private constructor(private val binding: RvItemFormCheckV2Binding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormCheckV2Binding.inflate(layoutInflater, parent, false)
+ return CheckBoxesInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?
+ ) {
+ binding.form = item
+
+ if (item.errorText != null) binding.clRi.setBackgroundResource(R.drawable.state_errored)
+ else binding.clRi.setBackgroundResource(0)
+ binding.llChecks.removeAllViews()
+ binding.llChecks.apply {
+ item.entries?.let { items ->
+ orientation = item.orientation ?: LinearLayout.VERTICAL
+ weightSum = items.size.toFloat()
+ items.forEachIndexed { index, it ->
+ val cbx = CheckBox(this.context)
+ cbx.layoutParams = RadioGroup.LayoutParams(
+ RadioGroup.LayoutParams.MATCH_PARENT,
+ RadioGroup.LayoutParams.WRAP_CONTENT,
+ 1.0F
+ )
+ if (!isEnabled) {
+ cbx.isClickable = false
+ cbx.isFocusable = false
+ }
+ cbx.id = View.generateViewId()
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) cbx.setTextAppearance(
+ context, android.R.style.TextAppearance_Material_Medium
+ )
+ else cbx.setTextAppearance(android.R.style.TextAppearance_Material_Subhead)
+ cbx.text = it
+ addView(cbx)
+ if (item.value?.contains(it) == true) cbx.isChecked = true
+ cbx.setOnCheckedChangeListener { _, b ->
+ if (b) {
+ if (item.value != null) item.value = item.value + it
+ else item.value = it
+ if (item.hasDependants || item.hasAlertError) {
+ Timber.d(
+ "listener trigger : ${item.id} ${
+ item.entries!!.indexOf(
+ it
+ )
+ } $it"
+ )
+ }
+ } else {
+ if (item.value?.contains(it) == true) {
+ item.value = item.value?.replace(it, "")
+ }
+ }
+ formValueListener?.onValueChanged(
+ item, index * (if (b) 1 else -1)
+ )
+ if (item.value.isNullOrBlank()) {
+ item.value = null
+ } else {
+ Timber.d("Called here!")
+ item.errorText = null
+ binding.clRi.setBackgroundResource(0)
+ }
+ Timber.d("Checkbox value : ${item.value}")
+
+ }
+ }
+ }
+ }
+ binding.executePendingBindings()
+
+ }
+ }
+
+ class DatePickerInputViewHolder private constructor(private val binding: RvItemFormDatepickerWithBgIconBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormDatepickerWithBgIconBinding.inflate(layoutInflater, parent, false)
+ return DatePickerInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?
+ ) {
+ binding.form = item
+ binding.invalidateAll()
+ if (!isEnabled) {
+ binding.et.isFocusable = false
+ binding.et.isClickable = false
+ binding.executePendingBindings()
+ return
+ }
+ val today = Calendar.getInstance()
+ var thisYear = today.get(Calendar.YEAR)
+ var thisMonth = today.get(Calendar.MONTH)
+ var thisDay = today.get(Calendar.DAY_OF_MONTH)
+
+ item.errorText?.also { binding.tilEditText.error = it }
+ ?: run { binding.tilEditText.error = null }
+ binding.et.setOnClickListener {
+ val activity = binding.et.context.findFragmentActivity()
+ ?: return@setOnClickListener
+ val originalLocale = Locale.getDefault()
+ HelperUtil.setEnLocaleForDatePicker(activity)
+
+ item.value?.let { value ->
+ thisYear = value.substring(6).toInt()
+ thisMonth = value.substring(3, 5).trim().toInt() - 1
+ thisDay = value.substring(0, 2).trim().toInt()
+ }
+ val datePickerDialog = DatePickerDialog(
+ it.context, { _, year, month, day ->
+ val millis = Calendar.getInstance().apply {
+ set(Calendar.YEAR, year)
+ set(Calendar.MONTH, month)
+ set(Calendar.DAY_OF_MONTH, day)
+ }.timeInMillis
+ if (item.min != null && millis < item.min!!) {
+ item.value = getDateString(item.min)
+ } else if (item.max != null && millis > item.max!!)
+ item.value = getDateString(item.max)
+ else
+ item.value = getDateString(millis)
+// "${if (day > 9) day else "0$day"}-${if (month > 8) month + 1 else "0${month + 1}"}-$year"
+ binding.invalidateAll()
+ if (item.hasDependants) formValueListener?.onValueChanged(item, -1)
+ }, thisYear, thisMonth, thisDay
+ )
+ item.errorText = null
+ binding.tilEditText.error = null
+ item.min?.let { datePickerDialog.datePicker.minDate = it }
+ item.max?.let { datePickerDialog.datePicker.maxDate = it }
+ if (item.showYearFirstInDatePicker)
+ datePickerDialog.datePicker.touchables[0].performClick()
+ val canShow = when {
+ item.max == null || item.min == null -> true
+ else -> item.max!! > item.min!!
+ }
+ if (canShow){
+ datePickerDialog.show()
+ }else{
+ Toast.makeText(binding.root.context,"Something went wrong",Toast.LENGTH_SHORT).show()
+ HelperUtil.setOriginalLocaleForDatePicker(activity,originalLocale)
+ }
+ datePickerDialog.setOnDismissListener {
+ HelperUtil.setOriginalLocaleForDatePicker(activity,originalLocale)
+ }
+ }
+ binding.executePendingBindings()
+
+ }
+ }
+
+ class TimePickerInputViewHolder private constructor(private val binding: RvItemFormTimepickerWithBgIconBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormTimepickerWithBgIconBinding.inflate(layoutInflater, parent, false)
+ return TimePickerInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement, isEnabled: Boolean
+ ) {
+ binding.form = item
+ binding.et.isEnabled = isEnabled
+ binding.et.setOnClickListener {
+ val hour: Int
+ val minute: Int
+ if (item.value == null) {
+ val currentTime = Calendar.getInstance()
+ hour = currentTime.get(Calendar.HOUR_OF_DAY)
+ minute = currentTime.get(Calendar.MINUTE)
+ } else {
+ hour = item.value!!.substringBefore(":").toInt()
+ minute = item.value!!.substringAfter(":").toInt()
+ Timber.d("Time picker hour min : $hour $minute")
+ }
+ val mTimePicker = TimePickerDialog(it.context, { _, hourOfDay, minuteOfHour ->
+ item.value = "$hourOfDay:$minuteOfHour"
+ binding.invalidateAll()
+
+ }, hour, minute, false)
+ mTimePicker.setTitle("Select Time")
+ mTimePicker.show()
+ }
+ binding.executePendingBindings()
+
+ }
+ }
+
+ class TextViewInputViewHolder private constructor(private val binding: RvItemFormTextViewWithBgIconBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormTextViewWithBgIconBinding.inflate(layoutInflater, parent, false)
+ return TextViewInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormElement) {
+ binding.form = item
+ binding.executePendingBindings()
+ }
+ }
+
+ class ImageViewInputViewHolder private constructor(private val binding: RvItemFormImageViewWithBgIconBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormImageViewWithBgIconBinding.inflate(layoutInflater, parent, false)
+ return ImageViewInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement, clickListener: ImageClickListener?, isEnabled: Boolean
+ ) {
+ binding.form = item
+ if (isEnabled) {
+ binding.clickListener = clickListener
+ if (item.errorText != null) binding.clRi.setBackgroundResource(R.drawable.state_errored)
+ else binding.clRi.setBackgroundResource(0)
+ }
+ binding.executePendingBindings()
+
+ }
+ }
+
+ class ButtonInputViewHolder private constructor(private val binding: RvItemFormBtnBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormBtnBinding.inflate(layoutInflater, parent, false)
+ return ButtonInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?) {
+ binding.form = item
+ binding.generateOtp.isEnabled = isEnabled
+ binding.generateOtp.text = binding.generateOtp.resources.getString(R.string.generate_otp)
+ binding.generateOtp.setOnClickListener {
+ binding.generateOtp.isEnabled = !isEnabled
+ startTimer(binding.timerInSec,binding.generateOtp)
+ binding.tilEditText.visibility = View.VISIBLE
+ }
+
+
+ }
+
+ private lateinit var countDownTimer : CountDownTimer
+ private var countdownTimers : HashMap = HashMap()
+
+ class MultiFileUploadInputViewHolder private constructor(private val binding: LayoutMultiFileUploadBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutMultiFileUploadBinding.inflate(layoutInflater, parent, false)
+ return MultiFileUploadInputViewHolder(binding)
+ }
+ }
+ var selectedFiles = mutableListOf()
+
+ private lateinit var fileAdapter: FileListAdapter
+
+ fun bind(
+ item: FormElement,
+ clickListener: SelectUploadImageClickListener?,
+ documentOnClick: ViewDocumentOnClick?,
+ isEnabled: Boolean
+ ) {
+ /* binding.form = item
+ binding.tvTitle.text = item.title
+ binding.clickListener = clickListener
+ binding.documentclickListener = documentOnClick
+ binding.btnView.visibility = if (item.value != null) View.VISIBLE else View.GONE
+
+ if (isEnabled) {
+ binding.addFile.isEnabled = true
+ binding.addFile.alpha = 1f
+ } else {
+ binding.addFile.isEnabled = false
+ binding.addFile.alpha = 0.5f
+ }*/
+
+ fileAdapter = FileListAdapter(selectedFiles)
+ binding.rvFiles.adapter = fileAdapter
+
+ binding.btnSelectFiles.isEnabled = isEnabled
+ binding.btnSelectFiles.alpha = if (isEnabled) 1f else 0.5f
+
+ binding.btnSelectFiles.setOnClickListener {
+ clickListener?.onSelectImageClick(item)
+ }
+ }
+
+ }
+ private fun formatTimeInSeconds(millis: Long) : String {
+ val seconds = millis / 1000
+ return "${seconds} sec"
+ }
+ private fun startTimer(timerInSec: TextView, generateOtp: MaterialButton) {
+ countDownTimer = object : CountDownTimer(60000, 1000) {
+ override fun onTick(millisUntilFinished: Long) {
+ timerInSec.visibility = View.VISIBLE
+ timerInSec.text = formatTimeInSeconds(millisUntilFinished)
+ }
+ override fun onFinish() {
+ timerInSec.visibility = View.INVISIBLE
+ timerInSec.text = ""
+ generateOtp.isEnabled = true
+ generateOtp.text = timerInSec.resources.getString(R.string.resend_otp)
+ }
+ }.start()
+
+ countdownTimers[adapterPosition] = countDownTimer
+
+ }
+ }
+
+ class MultiFileUploadInputViewHolder private constructor(private val binding: LayoutMultiFileUploadBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutMultiFileUploadBinding.inflate(layoutInflater, parent, false)
+ return MultiFileUploadInputViewHolder(binding)
+ }
+ }
+ var selectedFiles = mutableListOf()
+
+ private lateinit var fileAdapter: FileListAdapter
+
+ fun bind(
+ item: FormElement,
+ clickListener: SelectUploadImageClickListener?,
+ documentOnClick: ViewDocumentOnClick?,
+ isEnabled: Boolean,
+ ) {
+ /* binding.form = item
+ binding.tvTitle.text = item.title
+ binding.clickListener = clickListener
+ binding.documentclickListener = documentOnClick
+ binding.btnView.visibility = if (item.value != null) View.VISIBLE else View.GONE
+
+ if (isEnabled) {
+ binding.addFile.isEnabled = true
+ binding.addFile.alpha = 1f
+ } else {
+ binding.addFile.isEnabled = false
+ binding.addFile.alpha = 0.5f
+ }*/
+
+ fileAdapter = FileListAdapter(selectedFiles)
+ binding.rvFiles.adapter = fileAdapter
+
+ binding.btnSelectFiles.isEnabled = isEnabled
+ binding.btnSelectFiles.alpha = if (isEnabled) 1f else 0.5f
+
+ binding.btnSelectFiles.setOnClickListener {
+ clickListener?.onSelectImageClick(item)
+ }
+ }
+
+ }
+
+ class FileUploadInputViewHolder private constructor(private val binding: RvItemFormUploadImageBinding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormUploadImageBinding.inflate(layoutInflater, parent, false)
+ return FileUploadInputViewHolder(binding)
+ }
+ }
+
+ fun bind(item: FormElement, clickListener: SelectUploadImageClickListener?, documentOnClick: ViewDocumentOnClick?, isEnabled: Boolean) {
+
+ binding.form = item
+ binding.tvTitle.text = item.title
+ binding.clickListener = clickListener
+ binding.documentclickListener = documentOnClick
+ if (item.value != null) binding.btnView.visibility = View.VISIBLE
+ else binding.btnView.visibility = View.GONE
+
+ }
+
+ private lateinit var countDownTimer : CountDownTimer
+ private var countdownTimers : HashMap = HashMap()
+
+ private fun formatTimeInSeconds(millis: Long) : String {
+ val seconds = millis / 1000
+ return "${seconds} sec"
+ }
+ private fun startTimer(timerInSec: TextView, generateOtp: MaterialButton) {
+ countDownTimer = object : CountDownTimer(60000, 1000) {
+ override fun onTick(millisUntilFinished: Long) {
+ timerInSec.visibility = View.VISIBLE
+ timerInSec.text = formatTimeInSeconds(millisUntilFinished)
+ }
+ override fun onFinish() {
+ timerInSec.visibility = View.INVISIBLE
+ timerInSec.text = ""
+ generateOtp.isEnabled = true
+ generateOtp.text = timerInSec.resources.getString(R.string.resend_otp)
+ }
+ }.start()
+
+ countdownTimers[adapterPosition] = countDownTimer
+
+ }
+ }
+
+ class NumberPickerInputViewHolder private constructor(
+ private val binding: RvItemFormNumberPickerBinding
+ ) : ViewHolder(binding.root) {
+
+ private var textWatcher: TextWatcher? = null
+ private var internalUpdate = false
+
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormNumberPickerBinding.inflate(layoutInflater, parent, false)
+ return NumberPickerInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement,
+ isEnabled: Boolean,
+ formValueListener: FormInputAdapterWithBgIcon.FormValueListener?
+ ) {
+ binding.form = item
+
+ val minValue = item.min?.toInt() ?: 0
+ val maxValue = item.max?.toInt()
+ val allowNegative = item.minDecimal != null && item.minDecimal!! < 0
+
+ binding.etNumberInput.setText(minValue.toString())
+ binding.etNumberInput.setSelection(binding.etNumberInput.text!!.length)
+ var currentValue = item.value?.toIntOrNull() ?: minValue
+
+ textWatcher?.let { binding.etNumberInput.removeTextChangedListener(it) }
+
+ textWatcher = object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
+
+ }
+
+
+
+
+ override fun afterTextChanged(editable: Editable?) {
+
+ if (internalUpdate) return
+ if (editable.isNullOrBlank()) {
+ showError(binding.root.context.getString(R.string.value_cannot_be_empty))
+ return
+ }
+
+ val inputValue = editable.toString().toIntOrNull()
+ if (inputValue == null) {
+ showError(binding.root.context.getString(R.string.enter_a_valid_number))
+ return
+ }
+
+ val validated = validateValue(inputValue, minValue, maxValue, allowNegative)
+
+ if (validated != inputValue) {
+ showError(binding.root.context.getString(R.string.allowed_range, minValue, maxValue))
+
+ updateDisplay(validated)
+ updateValue(validated, item, formValueListener)
+ return
+ }
+
+ hideError()
+
+ currentValue = validated
+ updateValue(currentValue, item, formValueListener)
+ }
+ }
+
+ updateDisplay(currentValue)
+
+ binding.etNumberInput.addTextChangedListener(textWatcher)
+
+
+
+ binding.btnDecrement.setOnClickListener {
+ currentValue = (item.value?.toIntOrNull() ?: minValue) - 1
+ currentValue = validateValue(currentValue, minValue, maxValue, allowNegative)
+ hideError()
+ updateValue(currentValue, item, formValueListener)
+ updateDisplay(currentValue)
+ }
+
+ binding.btnIncrement.setOnClickListener {
+ currentValue = (item.value?.toIntOrNull() ?: minValue) + 1
+ currentValue = validateValue(currentValue, minValue, maxValue, allowNegative)
+ hideError()
+ updateValue(currentValue, item, formValueListener)
+ updateDisplay(currentValue)
+ }
+ }
+
+
+ private fun validateValue(value: Int, min: Int, max: Int?, allowNegative: Boolean): Int {
+ var newValue = value
+
+ if (!allowNegative && newValue < min) newValue = min
+ if (max != null && newValue > max) newValue = max
+
+ return newValue
+ }
+
+ private fun updateDisplay(value: Int) {
+ internalUpdate = true
+ binding.etNumberInput.setText(value.toString())
+ binding.etNumberInput.setSelection(binding.etNumberInput.text!!.length)
+ internalUpdate = false
+ }
+
+ private fun updateValue(
+ newValue: Int,
+ item: FormElement,
+ formValueListener: FormInputAdapterWithBgIcon.FormValueListener?
+ ) {
+ item.value = newValue.toString()
+ formValueListener?.onValueChanged(item,newValue)
+ }
+
+ private fun showError(message: String) {
+ binding.tvError.apply {
+ text = message
+ visibility = View.VISIBLE
+ }
+ }
+
+ private fun hideError() {
+ binding.tvError.visibility = View.GONE
+ }
+ }
+
+
+
+ class AgePickerViewInputViewHolder private constructor(private val binding: RvItemFormAgePickerViewV2Binding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding =
+ RvItemFormAgePickerViewV2Binding.inflate(layoutInflater, parent, false)
+ return AgePickerViewInputViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement, isEnabled: Boolean, formValueListener: FormValueListener?
+ ) {
+ binding.form = item
+ binding.invalidateAll()
+ val agePicker = AgePickerDialog(binding.root.context)
+
+ val calDob = Calendar.getInstance()
+ val ageUnitDTO = AgeUnitDTO(0, 0, 0)
+ val isOk = true
+ item.value?.let {
+ calDob.timeInMillis = getLongFromDate(it)
+ updateAgeDTO(ageUnitDTO, calDob)
+ binding.etNum.setText(getAgeStrFromAgeUnit(ageUnitDTO))
+
+ }
+
+ if (isEnabled) {
+ binding.etNum.setOnClickListener {
+ val calNow = Calendar.getInstance()
+ val calMin = Calendar.getInstance()
+ val calMax = Calendar.getInstance()
+ item.min?.let {
+ calMin.timeInMillis = it
+ }
+ item.max?.let {
+ calMax.timeInMillis = it
+ }
+
+ agePicker.setLimitsAndShow(
+ calNow.get(Calendar.YEAR) - calMax.get(Calendar.YEAR),
+ calNow.get(Calendar.YEAR) - calMin.get(Calendar.YEAR),
+ 0,
+ 11,
+ 0,
+ 30,
+ ageUnitDTO,
+ isOk
+ )
+ }
+ agePicker.setOnDismissListener {
+ binding.etNum.setText(getAgeStrFromAgeUnit(ageUnitDTO))
+ calDob.timeInMillis =
+ getDobFromAge(ageUnitDTO)
+ binding.etDate.setText(getDateString(calDob.timeInMillis))
+ item.value = getDateString(calDob.timeInMillis)
+ if (item.hasDependants) formValueListener?.onValueChanged(item, -1)
+ }
+ }
+
+
+ if (!isEnabled) {
+ binding.etDate.isFocusable = false
+ binding.etNum.isFocusable = false
+ binding.etDate.isClickable = false
+ binding.etNum.isClickable = false
+ binding.executePendingBindings()
+ return
+ }
+ val today = Calendar.getInstance()
+ var thisYear = today.get(Calendar.YEAR)
+ var thisMonth = today.get(Calendar.MONTH)
+ var thisDay = today.get(Calendar.DAY_OF_MONTH)
+
+ item.errorText?.also { binding.tilEditTextDate.error = it }
+ ?: run { binding.tilEditTextDate.error = null }
+ binding.etDate.setOnClickListener {
+ val activity = binding.etDate.context.findFragmentActivity()
+ ?: return@setOnClickListener
+ val originalLocale = Locale.getDefault()
+ HelperUtil.setEnLocaleForDatePicker(activity)
+
+ item.value?.let { value ->
+ thisYear = value.substring(6).toInt()
+ thisMonth = value.substring(3, 5).trim().toInt() - 1
+ thisDay = value.substring(0, 2).trim().toInt()
+ }
+ val datePickerDialog = DatePickerDialog(
+ it.context, { _, year, month, day ->
+ val millisCal = Calendar.getInstance().apply {
+ set(Calendar.YEAR, year)
+ set(Calendar.MONTH, month)
+ set(Calendar.DAY_OF_MONTH, day)
+ }
+ val millis = millisCal.timeInMillis
+ if (item.min != null && millis < item.min!!) {
+ item.value = getDateString(item.min)
+ } else if (item.max != null && millis > item.max!!)
+ item.value = getDateString(item.max)
+ else
+ item.value = getDateString(millis)
+
+ updateAgeDTO(ageUnitDTO, millisCal)
+ binding.etNum.setText(getAgeStrFromAgeUnit(ageUnitDTO))
+ binding.invalidateAll()
+ if (item.hasDependants) formValueListener?.onValueChanged(item, -1)
+ }, thisYear, thisMonth, thisDay
+ )
+ item.errorText = null
+ binding.tilEditTextDate.error = null
+ item.min?.let { datePickerDialog.datePicker.minDate = it }
+ item.max?.let { datePickerDialog.datePicker.maxDate = it }
+ if (item.showYearFirstInDatePicker)
+ datePickerDialog.datePicker.touchables[0].performClick()
+ datePickerDialog.show()
+ datePickerDialog.setOnDismissListener {
+ HelperUtil.setOriginalLocaleForDatePicker(activity,originalLocale)
+ }
+ }
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ class HeadlineViewHolder private constructor(private val binding: RvItemFormHeadlineV2Binding) :
+ ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemFormHeadlineV2Binding.inflate(layoutInflater, parent, false)
+ return HeadlineViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: FormElement,
+ formValueListener: FormValueListener?,
+ ) {
+ binding.form = item
+ if (item.subtitle == null)
+ binding.textView8.visibility = View.GONE
+ formValueListener?.onValueChanged(item, -1)
+ binding.executePendingBindings()
+
+ }
+ }
+
+ class ImageClickListener(private val imageClick: (formId: Int) -> Unit) {
+
+ fun onImageClick(form: FormElement) = imageClick(form.id)
+
+ }
+
+ class AgeClickListener(private val ageClick: (formId: Int) -> Unit) {
+
+ fun onAgeClick(form: FormElement) = ageClick(form.id)
+
+ }
+
+ class FormValueListener(private val valueChanged: (id: Int, value: Int) -> Unit) {
+
+ fun onValueChanged(form: FormElement, index: Int) {
+ valueChanged(form.id, index)
+
+ }
+
+ }
+
+
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val inputTypes = values()
+ return when (inputTypes[viewType]) {
+ EDIT_TEXT -> EditTextInputViewHolder.from(parent)
+ DROPDOWN -> DropDownInputViewHolder.from(parent)
+ RADIO -> RadioInputViewHolder.from(parent)
+ DATE_PICKER -> DatePickerInputViewHolder.from(parent)
+ TEXT_VIEW -> TextViewInputViewHolder.from(parent)
+ IMAGE_VIEW -> ImageViewInputViewHolder.from(parent)
+ CHECKBOXES -> CheckBoxesInputViewHolder.from(parent)
+ TIME_PICKER -> TimePickerInputViewHolder.from(parent)
+ HEADLINE -> HeadlineViewHolder.from(parent)
+ AGE_PICKER -> AgePickerViewInputViewHolder.from(parent)
+ BUTTON -> ButtonInputViewHolder.from(parent)
+ FILE_UPLOAD -> FileUploadInputViewHolder.from(parent)
+ InputType.NUMBER_PICKER -> NumberPickerInputViewHolder.from(parent)
+ InputType.MULTIFILE_UPLOAD -> MultiFileUploadInputViewHolder.from(parent)
+
+
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val item = getItem(position)
+ val isEnabled = if (isEnabled) item.isEnabled else false
+ when (item.inputType) {
+ EDIT_TEXT -> (holder as EditTextInputViewHolder).bind(
+ item, isEnabled, formValueListener
+ )
+
+ DROPDOWN -> (holder as DropDownInputViewHolder).bind(item, isEnabled, formValueListener)
+ RADIO -> (holder as RadioInputViewHolder).bind(item, isEnabled, formValueListener)
+ DATE_PICKER -> (holder as DatePickerInputViewHolder).bind(
+ item, isEnabled, formValueListener
+ )
+
+ TEXT_VIEW -> (holder as TextViewInputViewHolder).bind(item)
+ IMAGE_VIEW -> (holder as ImageViewInputViewHolder).bind(
+ item, imageClickListener, isEnabled
+ )
+
+ CHECKBOXES -> (holder as CheckBoxesInputViewHolder).bind(
+ item,
+ isEnabled,
+ formValueListener
+ )
+
+ TIME_PICKER -> (holder as TimePickerInputViewHolder).bind(item, isEnabled)
+ HEADLINE -> (holder as HeadlineViewHolder).bind(item, formValueListener)
+ AGE_PICKER -> (holder as AgePickerViewInputViewHolder).bind(
+ item,
+ isEnabled,
+ formValueListener
+ )
+ BUTTON -> (holder as ButtonInputViewHolder).bind(item, isEnabled,formValueListener)
+ FILE_UPLOAD -> (holder as FileUploadInputViewHolder).bind(item,selectImageClickListener,viewDocumentListner, isEnabled)
+ InputType.MULTIFILE_UPLOAD -> (holder as MultiFileUploadInputViewHolder).bind(item,selectImageClickListener,viewDocumentListner, isEnabled )
+
+ InputType.NUMBER_PICKER -> (holder as NumberPickerInputViewHolder).bind(
+ item, isEnabled, formValueListener
+ )
+ }
+ }
+
+ override fun getItemViewType(position: Int) = getItem(position).inputType.ordinal
+
+ /**
+ * Validation Result : -1 -> all good
+ * else index of element creating trouble
+ */
+ fun validateInput(resources: Resources): Int {
+ var retVal = -1
+ if (!isEnabled) return retVal
+ currentList.forEachIndexed { index, it ->
+ Timber.d("Error text for ${it.title} ${it.errorText}")
+ if (it.inputType != TEXT_VIEW && it.errorText != null) {
+ retVal = index
+ return@forEachIndexed
+ }
+ }
+ Timber.d("Validation : $retVal")
+ if (retVal != -1) return retVal
+ currentList.forEachIndexed { index, it ->
+ if (it.inputType != TEXT_VIEW && it.required) {
+ if (it.value.isNullOrBlank()) {
+ Timber.d("validateInput called for item $it, with index ${index}")
+ it.errorText = resources.getString(R.string.form_input_empty_error)
+ notifyItemChanged(index)
+ if (retVal == -1) retVal = index
+ }
+ }
+ }
+ return retVal
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/GeneralOPDAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/GeneralOPDAdapter.kt
new file mode 100644
index 000000000..3abb97bb1
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/GeneralOPDAdapter.kt
@@ -0,0 +1,124 @@
+package org.piramalswasthya.sakhi.adapters
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvGeneralOpdBenBinding
+import org.piramalswasthya.sakhi.model.BenBasicDomain
+import org.piramalswasthya.sakhi.model.GeneralOPEDBeneficiary
+
+class GeneralOPDAdapter(
+ private val clickListener: CallClickListener? = null,
+ private val showBeneficiaries: Boolean = false,
+ private val showRegistrationDate: Boolean = false,
+ private val showSyncIcon: Boolean = false,
+ private val showAbha: Boolean = false,
+ private val role: Int? = 0
+) :
+ ListAdapter(BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: GeneralOPEDBeneficiary, newItem: GeneralOPEDBeneficiary
+ ) = oldItem.beneficiaryId == newItem.beneficiaryId
+
+ override fun areContentsTheSame(
+ oldItem: GeneralOPEDBeneficiary, newItem: GeneralOPEDBeneficiary
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvGeneralOpdBenBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvGeneralOpdBenBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: GeneralOPEDBeneficiary,
+ clickListener: CallClickListener?,
+ showAbha: Boolean,
+ showSyncIcon: Boolean,
+ showRegistrationDate: Boolean,
+ showBeneficiaries: Boolean, role: Int?
+ ) {
+// if (!showSyncIcon) item.syncState = null
+ binding.ben = item
+ binding.callclickListener = clickListener
+ binding.showAbha = showAbha
+ binding.showRegistrationDate = showRegistrationDate
+ binding.registrationDate.visibility =
+ if (showRegistrationDate) View.VISIBLE else View.INVISIBLE
+// binding.hasAbha = !item.abhaId.isNullOrEmpty()
+ binding.role = role
+
+ if (showBeneficiaries) {
+ if (item.spouseName == "Not Available" && item.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.genderName == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.genderName == "FEMALE") {
+ if (item.ben_age_val!! > 15) {
+ binding.father =
+ item.fatherName != "Not Available" && item.spouseName == "Not Available"
+ binding.husband = item.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.fatherName != "Not Available" && item.spouseName == "Not Available"
+ binding.spouse = item.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+ } else {
+ binding.father = false
+ binding.husband = false
+ binding.spouse = false
+ }
+ binding.executePendingBindings()
+
+ }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ) = BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(
+ getItem(position),
+ clickListener,
+ showAbha,
+ showSyncIcon,
+ showRegistrationDate,
+ showBeneficiaries,
+ role
+ )
+ }
+
+
+ class CallClickListener(
+ private val clickedCall: (benId: Long, mobileno: String) -> Unit,
+ ) {
+
+ fun onClickCall(item: GeneralOPEDBeneficiary) = clickedCall(item.beneficiaryId,
+ item.preferredPhoneNum.toString()
+ )
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/HRPAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/HRPAdapter.kt
index 640e5724f..e205cc15e 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/HRPAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/HRPAdapter.kt
@@ -4,16 +4,21 @@ import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.LinearLayout
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemBenWithHrpaFormBinding
import org.piramalswasthya.sakhi.model.BenWithHRPADomain
+import org.piramalswasthya.sakhi.utils.RoleConstants
class HRPAdapter(
private val clickListener: HRPAClickListener? = null,
private vararg val formButtonText: String,
- private val role: Int? = 0
+ private val role: Int? = 0,
+ private val pref: PreferenceDao? = null
) :
ListAdapter
(BenDiffUtilCallBack) {
@@ -44,8 +49,20 @@ class HRPAdapter(
item: BenWithHRPADomain,
clickListener: HRPAClickListener?,
vararg btnText: String,
- role: Int?
+ role: Int?,
+ pref: PreferenceDao?
) {
+
+ if (pref?.getLoggedInUser()?.role.equals(RoleConstants.ROLE_ASHA_SUPERVISOR, true)) {
+ binding.btnForm3.visibility = View.INVISIBLE
+ binding.btnForm2.visibility = View.INVISIBLE
+ binding.btnForm1.visibility = View.INVISIBLE
+ } else {
+ binding.btnForm3.visibility = View.VISIBLE
+ binding.btnForm2.visibility = View.VISIBLE
+ binding.btnForm1.visibility = View.VISIBLE
+ }
+
binding.benWithhrpa = item
binding.hasLmp = false
item.assess?.let {
@@ -82,6 +99,10 @@ class HRPAdapter(
var hasForm: Boolean = false
var completelyFilled: Boolean = false
var formEnabled: Boolean = false
+ buttonFlexibleWidth()
+ binding.btnForm3.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_whatsapp, 0);
+
+
val formButton = when (formNumber) {
1 -> {
binding.btnForm1.also {
@@ -111,14 +132,27 @@ class HRPAdapter(
3 -> {
binding.btnForm3.also {
-// hasForm = item.assess.noOfDeliveries.form3Filled
-// formEnabled = item.ben.form3Enabled
+ hasForm = item.mbp != null
+ if (hasForm) {
+
+ formEnabled = true
+ buttonFlexibleWidth()
+
+ } else {
+
+ formEnabled = false
+ (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.8f
+ (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+
+ }
+
}
}
else -> throw IllegalStateException("FormNumber>3")
}
- formButton.visibility = if (formEnabled) View.VISIBLE else View.INVISIBLE
+ formButton.visibility = if (formEnabled) View.VISIBLE else View.GONE
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (hasForm) {
@@ -137,11 +171,17 @@ class HRPAdapter(
)
)
}
+ binding.btnForm3.setBackgroundColor(
+ binding.btnForm3.resources.getColor(
+ android.R.color.holo_purple,
+ binding.root.context.theme
+ )
+ )
} else {
formButton.setBackgroundColor(
binding.root.resources.getColor(
- android.R.color.holo_red_light,
+ android.R.color.holo_red_dark,
binding.root.context.theme
)
)
@@ -153,7 +193,7 @@ class HRPAdapter(
else
formButton.setBackgroundColor(
binding.root.resources.getColor(
- android.R.color.holo_red_light,
+ android.R.color.holo_red_dark,
)
)
@@ -165,6 +205,12 @@ class HRPAdapter(
)
}
+
+ private fun buttonFlexibleWidth() {
+ (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+ (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=0.8f
+ (binding.btnForm3.layoutParams as LinearLayout.LayoutParams).weight=1.0f
+ }
}
override fun onCreateViewHolder(
@@ -174,7 +220,7 @@ class HRPAdapter(
HRPAViewHolder.from(parent)
override fun onBindViewHolder(holder: HRPAViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener, btnText = formButtonText, role = role)
+ holder.bind(getItem(position), clickListener, btnText = formButtonText, role = role, pref = pref)
}
@@ -185,7 +231,6 @@ class HRPAdapter(
private val clickedForm3: ((hhId: Long, benId: Long) -> Unit)? = null
) {
- // fun onClickedBen(item: HRPAViewHolder) = clickedBen?.let { it() }(item.benId)
fun onClickForm1(item: BenWithHRPADomain) =
clickedForm1?.let { it(item.ben.hhId, item.ben.benId) }
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/HouseHoldListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/HouseHoldListAdapter.kt
index 53f7bc004..31637bc11 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/HouseHoldListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/HouseHoldListAdapter.kt
@@ -1,18 +1,27 @@
package org.piramalswasthya.sakhi.adapters
+import android.content.res.ColorStateList
import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
+import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.configuration.IconDataset
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemHouseholdBinding
import org.piramalswasthya.sakhi.model.HouseHoldBasicDomain
+import org.piramalswasthya.sakhi.ui.getTitle
+import org.piramalswasthya.sakhi.ui.getTitleRes
-class HouseHoldListAdapter(private val clickListener: HouseholdClickListener) :
+class HouseHoldListAdapter(private val diseaseType: String, private var isDisease: Boolean, val pref: PreferenceDao,private val isSoftDeleteEnabled:Boolean = false, private val clickListener: HouseholdClickListener) :
ListAdapter(
HouseHoldDiffUtilCallBack
) {
+
private object HouseHoldDiffUtilCallBack : DiffUtil.ItemCallback() {
override fun areItemsTheSame(
oldItem: HouseHoldBasicDomain,
@@ -36,11 +45,66 @@ class HouseHoldListAdapter(private val clickListener: HouseholdClickListener) :
}
}
- fun bind(item: HouseHoldBasicDomain, clickListener: HouseholdClickListener) {
+ fun bind(
+ item: HouseHoldBasicDomain,
+ clickListener: HouseholdClickListener,
+ isDisease: Boolean,
+ pref: PreferenceDao,
+ diseaseType: String,
+ isSoftDeleteEnabled: Boolean
+ ) {
binding.household = item
binding.clickListener = clickListener
binding.executePendingBindings()
+
+ if (isDisease) {
+ binding.button4.visibility = View.GONE
+ if (diseaseType == IconDataset.Disease.FILARIA.getTitle(binding.root.context) ) {
+ binding.button4.visibility = View.INVISIBLE
+ binding.btnMda.visibility = View.VISIBLE
+ } else {
+ binding.btnMda.visibility = View.GONE
+ }
+ } else if (!isDisease) {
+ binding.button4.visibility = View.VISIBLE
+ binding.btnMda.visibility = View.GONE
+ } else {
+ binding.button4.visibility = View.GONE
+ binding.btnMda.visibility = View.GONE
+ }
+
+
+ if (isSoftDeleteEnabled){
+ binding.ivSoftDelete.visibility = View.VISIBLE
+
+ if (item.isDeactivate){
+ //binding.ivSoftDelete.setImageResource(R.drawable.ic_group_on)
+ binding.parentCard.setBackgroundColor(ContextCompat.getColor(binding.parentCard.context, R.color.Quartenary))
+
+ binding.ivSoftDelete.visibility = View.GONE
+ binding.button4.visibility = View.INVISIBLE
+ binding.tvTitleDuplicaterecord.visibility = View.VISIBLE
+ binding.button3.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(binding.root.context, R.color.md_theme_dark_outline))
+
+ } else{
+ // binding.ivSoftDelete.setImageResource(R.drawable.ic_group_off)
+ binding.parentCard.setBackgroundColor(ContextCompat.getColor(binding.parentCard.context, R.color.md_theme_light_primary))
+
+ binding.ivSoftDelete.visibility = View.VISIBLE
+ binding.button4.visibility = View.VISIBLE
+ binding.tvTitleDuplicaterecord.visibility = View.GONE
+ binding.button3.backgroundTintList = ColorStateList.valueOf(ContextCompat.getColor(binding.root.context, R.color.holo_green_dark))
+
+ }
+
+ } else {
+ binding.ivSoftDelete.visibility = View.GONE
+ }
+
+
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
}
}
@@ -50,18 +114,21 @@ class HouseHoldListAdapter(private val clickListener: HouseholdClickListener) :
}
override fun onBindViewHolder(holder: HouseHoldViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener)
+ holder.bind(getItem(position), clickListener,isDisease, pref, diseaseType,isSoftDeleteEnabled)
}
class HouseholdClickListener(
- val hhDetails: (hhId: Long) -> Unit,
- val showMember: (hhId: Long) -> Unit,
- val newBen: (hh: HouseHoldBasicDomain) -> Unit
+ val hhDetails: (hh: HouseHoldBasicDomain) -> Unit,
+ val showMember: (hh: HouseHoldBasicDomain) -> Unit,
+ val newBen: (hh: HouseHoldBasicDomain) -> Unit,
+ val addMDA: (hh: HouseHoldBasicDomain) -> Unit,
+ val softDeleteHh: (hh: HouseHoldBasicDomain) -> Unit,
) {
- fun onClickedForHHDetails(item: HouseHoldBasicDomain) = hhDetails(item.hhId)
- fun onClickedForMembers(item: HouseHoldBasicDomain) = showMember(item.hhId)
+ fun onClickedForHHDetails(item: HouseHoldBasicDomain) = hhDetails(item)
+ fun onClickedForMembers(item: HouseHoldBasicDomain) = showMember(item)
fun onClickedForNewBen(item: HouseHoldBasicDomain) = newBen(item)
-
+ fun onClickedAddMDA(item: HouseHoldBasicDomain) = addMDA(item)
+ fun onClickSoftDeleteHh(item: HouseHoldBasicDomain) = softDeleteHh(item)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationBenListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationBenListAdapter.kt
index c5c5d3623..aff98c998 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationBenListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationBenListAdapter.kt
@@ -1,16 +1,20 @@
package org.piramalswasthya.sakhi.adapters
import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemImmunizationBenBinding
import org.piramalswasthya.sakhi.model.BenBasicDomain
+import org.piramalswasthya.sakhi.model.BenWithAncListDomain
import org.piramalswasthya.sakhi.model.ImmunizationDetailsDomain
class ImmunizationBenListAdapter(
- private val clickListener: VaccinesClickListener? = null
+ private val clickListener: VaccinesClickListener? = null,
+ private val pref: PreferenceDao? = null
) : ListAdapter(
BenDiffUtilCallBack
) {
@@ -36,8 +40,9 @@ class ImmunizationBenListAdapter(
}
fun bind(
- item: ImmunizationDetailsDomain, clickListener: VaccinesClickListener?
+ item: ImmunizationDetailsDomain, clickListener: VaccinesClickListener?, pref: PreferenceDao?
) {
+
binding.temp = item.ben
binding.clickListener = clickListener
binding.executePendingBindings()
@@ -45,22 +50,27 @@ class ImmunizationBenListAdapter(
}
}
+
+
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int
): BenVaccineViewHolder = BenVaccineViewHolder.from(parent)
override fun onBindViewHolder(holder: BenVaccineViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener)
+ holder.bind(getItem(position), clickListener, pref)
+
}
class VaccinesClickListener(
private val clickedVaccine: (benId: Long) -> Unit,
+ private val callBen: (ben: BenBasicDomain) -> Unit
) {
fun onClickedBen(item: BenBasicDomain) = clickedVaccine(
item.benId
)
+ fun onClickedForCall(item: BenBasicDomain) = callBen(item)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationBirthDoseCategoryAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationBirthDoseCategoryAdapter.kt
new file mode 100644
index 000000000..f0d3e8d23
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationBirthDoseCategoryAdapter.kt
@@ -0,0 +1,69 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvTabBinding
+import org.piramalswasthya.sakhi.ui.home_activity.immunization_due.child_immunization.list.ChildImmunizationListViewModel
+
+
+class ImmunizationBirthDoseCategoryAdapter(
+ private val catDataList: ArrayList,
+ private val clickListener: CategoryClickListener? = null,
+ var viewModel: ChildImmunizationListViewModel
+) : RecyclerView.Adapter(){
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
+ CategoryViewHolder.from(parent)
+
+
+ override fun onBindViewHolder(
+ holder: CategoryViewHolder,
+ position: Int,
+ ) {
+
+ holder.bind(catDataList[position])
+ holder.binding.cMainLayout.setOnClickListener {
+ viewModel.selectedPosition = position
+ clickListener?.onClicked(catDataList[position])
+ notifyDataSetChanged()
+
+ }
+ if (viewModel.selectedPosition == position) {
+ holder.binding.cMainLayout.setBackgroundResource(R.drawable.tab_selection)
+ } else {
+ holder.binding.cMainLayout.setBackgroundResource(R.drawable.tab_unselection)
+ }
+
+ }
+
+
+ class CategoryViewHolder private constructor(val binding: RvTabBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): CategoryViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvTabBinding.inflate(layoutInflater, parent, false)
+ return CategoryViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ catDataList: String,
+ ) {
+
+ binding.monthText.text = catDataList
+
+ }
+
+ }
+ override fun getItemCount(): Int {
+ return catDataList.size
+ }
+
+ fun interface CategoryClickListener
+ {
+ fun onClicked(catDataList: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationCategoryAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationCategoryAdapter.kt
index 9d3c686d9..ef112786a 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationCategoryAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationCategoryAdapter.kt
@@ -1,8 +1,10 @@
package org.piramalswasthya.sakhi.adapters
+import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager
@@ -45,9 +47,14 @@ class ImmunizationCategoryAdapter(private val clickListener: ImmunizationIconCli
fun bind(item: VaccineCategoryDomain, clickListener: ImmunizationIconClickListener?) {
binding.category = item
binding.clickListener = clickListener
- val layoutManager = FlexboxLayoutManager(binding.root.context)
+ // val layoutManager = FlexboxLayoutManager(binding.root.context)
+ val layoutManager = LinearLayoutManager(binding.root.context)
+
+ Log.d("ImmnunigationVaccineAdapter", "isDeath: ${item.isBenDeath}")
+
+
binding.rvVaccine.layoutManager = layoutManager
- val adapter = ImmunizationVaccineAdapter(
+ val adapter = ImmunizationVaccineAdapter(item.isBenDeath,
clickListener
)
binding.rvVaccine.adapter = adapter
@@ -66,10 +73,11 @@ class ImmunizationCategoryAdapter(private val clickListener: ImmunizationIconCli
override fun onBindViewHolder(holder: VaccineCategoryViewHolder, position: Int) {
holder.bind(getItem(position), clickListener)
- }
+ Log.d("ImmnunigationVaccineAdapter", "onBindViewHolder called at position $position")
- class ImmunizationIconClickListener(val selectedListener: (vaccineId: Int) -> Unit) {
- fun onClicked(vaccine: VaccineDomain) = selectedListener(vaccine.vaccineId)
+ }
+ class ImmunizationIconClickListener(val selectedListener: (vaccineId: VaccineDomain) -> Unit) {
+ fun onClicked(vaccine: VaccineDomain) = selectedListener(vaccine)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationVaccineAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationVaccineAdapter.kt
index d42fc3759..ce9e36f23 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationVaccineAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ImmunizationVaccineAdapter.kt
@@ -1,5 +1,6 @@
package org.piramalswasthya.sakhi.adapters
+import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
@@ -7,8 +8,9 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import org.piramalswasthya.sakhi.databinding.RvItemImmVaccineBinding
import org.piramalswasthya.sakhi.model.VaccineDomain
+import org.piramalswasthya.sakhi.model.VaccineState
-class ImmunizationVaccineAdapter(private val clickListener: ImmunizationCategoryAdapter.ImmunizationIconClickListener? = null) :
+class ImmunizationVaccineAdapter(var isDeath: Boolean,private val clickListener: ImmunizationCategoryAdapter.ImmunizationIconClickListener? = null) :
ListAdapter(
ImmunizationIconDiffCallback
) {
@@ -35,11 +37,13 @@ class ImmunizationVaccineAdapter(private val clickListener: ImmunizationCategory
fun bind(
item: VaccineDomain,
- clickListener: ImmunizationCategoryAdapter.ImmunizationIconClickListener?
+ clickListener: ImmunizationCategoryAdapter.ImmunizationIconClickListener?,isDeath: Boolean
) {
binding.vaccine = item
+ binding.isDeath = isDeath
binding.clickListener = clickListener
binding.executePendingBindings()
+
}
}
@@ -48,6 +52,6 @@ class ImmunizationVaccineAdapter(private val clickListener: ImmunizationCategory
IconViewHolder.from(parent)
override fun onBindViewHolder(holder: IconViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener)
+ holder.bind(getItem(position), clickListener,isDeath)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/IncentiveGroupedAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/IncentiveGroupedAdapter.kt
new file mode 100644
index 000000000..32c17f02e
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/IncentiveGroupedAdapter.kt
@@ -0,0 +1,56 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.databinding.RvItemIncentiveGroupedBinding
+import org.piramalswasthya.sakhi.model.IncentiveGrouped
+
+class IncentiveGroupedAdapter(
+ private val onItemClick: (Long, String) -> Unit
+) :
+ ListAdapter(
+ IncentiveGroupedDiffUtilCallBack
+ ) {
+
+ private object IncentiveGroupedDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: IncentiveGrouped, newItem: IncentiveGrouped) =
+ oldItem.activityName == newItem.activityName
+
+ override fun areContentsTheSame(oldItem: IncentiveGrouped, newItem: IncentiveGrouped) =
+ oldItem == newItem
+ }
+
+ class IncentiveGroupedViewHolder( private val binding: RvItemIncentiveGroupedBinding, private val onItemClick: (Long, String) -> Unit) :
+ RecyclerView.ViewHolder(binding.root) {
+ private val isMitanin = BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)
+
+
+ fun bind(item: IncentiveGrouped, clickListener: (Long, String) -> Unit,serialNo : Int) {
+ binding.item = item
+ binding.serialNo = serialNo
+ binding.clickListener = clickListener
+ binding.isMitanin = isMitanin
+
+ if (isMitanin) {
+ binding.guideline75.setGuidelinePercent(0.9f)
+ }
+ binding.executePendingBindings()
+
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IncentiveGroupedViewHolder {
+ val binding = RvItemIncentiveGroupedBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return IncentiveGroupedViewHolder(binding,onItemClick)
+ }
+
+ override fun onBindViewHolder(holder: IncentiveGroupedViewHolder, position: Int) {
+ holder.bind(getItem(position),onItemClick,position+ 1)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/IncentiveListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/IncentiveListAdapter.kt
index e63424d89..392625abb 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/IncentiveListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/IncentiveListAdapter.kt
@@ -5,12 +5,15 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.databinding.RvItemIncentiveBinding
import org.piramalswasthya.sakhi.model.IncentiveDomain
-class IncentiveListAdapter :
+class IncentiveListAdapter( private val fileClickListener: FileClickListener) :
ListAdapter(IncentiveDiffUtilCallBack) {
+ private val isMitanin = BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)
+
private object IncentiveDiffUtilCallBack : DiffUtil.ItemCallback() {
override fun areItemsTheSame(
oldItem: IncentiveDomain, newItem: IncentiveDomain
@@ -33,9 +36,13 @@ class IncentiveListAdapter :
}
fun bind(
- item: IncentiveDomain,
+ item: IncentiveDomain,serialNo : Int, clickListener: FileClickListener,isMitanin: Boolean
) {
binding.item = item
+ binding.serialNo = serialNo
+ binding.clickListener = clickListener
+ binding.isMitanin = isMitanin
+
binding.executePendingBindings()
}
@@ -47,10 +54,21 @@ class IncentiveListAdapter :
override fun onBindViewHolder(holder: IncentiveViewHolder, position: Int) {
holder.bind(
- getItem(position)
+ getItem(position),position+1,fileClickListener,isMitanin
+
)
}
+ class FileClickListener(
+ private val onUpload: (item: IncentiveDomain) -> Unit,
+ private val onView: (item: IncentiveDomain) -> Unit,
+ private val onSubmit: (item: IncentiveDomain) -> Unit
+ ) {
+ fun onUploadClick(item: IncentiveDomain) = onUpload(item)
+ fun onViewClick(item: IncentiveDomain) = onView(item)
+ fun onSubmitClick(item: IncentiveDomain) = onSubmit(item)
+ }
+
//
// class BenClickListener(
// private val clickedBen: (hhId: Long, benId: Long, relToHeadId: Int) -> Unit,
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantListAdapter.kt
index 19706c8a5..f3cd42403 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantListAdapter.kt
@@ -1,12 +1,14 @@
package org.piramalswasthya.sakhi.adapters
import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import org.piramalswasthya.sakhi.databinding.RvItemBenChildCareInfantBinding
import org.piramalswasthya.sakhi.model.BenBasicDomain
+import java.util.concurrent.TimeUnit
class InfantListAdapter(
@@ -44,8 +46,20 @@ class InfantListAdapter(
binding.ben = item
binding.clickListener = clickListener
binding.executePendingBindings()
-
+ setOverDueStatus(item.dob)
}
+
+ private fun setOverDueStatus(dob: Long) {
+
+ val diffLong = System.currentTimeMillis() - dob
+ if (TimeUnit.MILLISECONDS.toDays(diffLong).toInt() > 42) {
+ binding.dueIcon.visibility = View.VISIBLE
+ } else {
+ binding.dueIcon.visibility = View.GONE
+ }
+
+ }
+
}
override fun onCreateViewHolder(
@@ -54,6 +68,7 @@ class InfantListAdapter(
override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
holder.bind(getItem(position), clickListener, showSyncIcon)
+
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantRegistrationAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantRegistrationAdapter.kt
index 06577e447..28b988679 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantRegistrationAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/InfantRegistrationAdapter.kt
@@ -5,6 +5,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.databinding.RvItemBenInfantRegBinding
import org.piramalswasthya.sakhi.model.InfantRegDomain
@@ -42,7 +43,7 @@ class InfantRegistrationAdapter(
clickListener: ClickListener?,
) {
binding.item = item
- binding.btnFormEc1.text = if (item.savedIr == null) "Register" else "View"
+ binding.btnFormEc1.text = if (item.savedIr == null) binding.root.resources.getString(R.string.register) else binding.root.resources.getString(R.string.view)
binding.btnFormEc1.setBackgroundColor(binding.root.resources.getColor(if (item.savedIr == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
binding.clickListener = clickListener
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/IrsRoundListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/IrsRoundListAdapter.kt
new file mode 100644
index 000000000..1197e11d7
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/IrsRoundListAdapter.kt
@@ -0,0 +1,57 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvItemIrsRoundBinding
+import org.piramalswasthya.sakhi.model.BenWithScreeningRoundDomain
+import org.piramalswasthya.sakhi.model.IRSRoundScreening
+
+class IrsRoundListAdapter () :
+ ListAdapter(
+ MyDiffUtilCallBack
+ ) {
+ private object MyDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: IRSRoundScreening, newItem: IRSRoundScreening
+ ) = oldItem.householdId == newItem.householdId
+
+ override fun areContentsTheSame(
+ oldItem: IRSRoundScreening, newItem: IRSRoundScreening
+ ) = oldItem == newItem
+
+ }
+
+ class ViewHolder private constructor(private val binding: RvItemIrsRoundBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemIrsRoundBinding.inflate(layoutInflater, parent, false)
+ return ViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: IRSRoundScreening
+ ) {
+ binding.irs = item
+ binding.position = position
+ binding.executePendingBindings()
+
+ }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ) = ViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(getItem(position))
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/KalaAzarMemberListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/KalaAzarMemberListAdapter.kt
new file mode 100644
index 000000000..b7dfc29c0
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/KalaAzarMemberListAdapter.kt
@@ -0,0 +1,119 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemKalaAzarMemberListBinding
+import org.piramalswasthya.sakhi.model.BenWithKALAZARScreeningDomain
+
+class KalaAzarMemberListAdapter(
+ private val clickListener: ClickListener? = null
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithKALAZARScreeningDomain,
+ newItem: BenWithKALAZARScreeningDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithKALAZARScreeningDomain,
+ newItem: BenWithKALAZARScreeningDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemKalaAzarMemberListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemKalaAzarMemberListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithKALAZARScreeningDomain,
+ clickListener: ClickListener?,
+ ) {
+ binding.benWithKalaAzar = item
+
+ /*if(item.tb?.historyOfTb == true){
+ binding.cvContent.visibility = View.GONE
+ }*/
+
+ binding.ivSyncState.visibility = if (item.kala == null) View.GONE else View.VISIBLE
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+ if ( item.kala != null && item.ben.isDeath) {
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.kala == null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.kala != null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ }
+ else {
+ binding.btnFormTb.visibility = View.INVISIBLE
+ }
+ binding.btnFormTb.text = if (item.kala == null) binding.root.resources.getString(R.string.register) else binding.root.resources.getString(R.string.view)
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.kala == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+
+ ) {
+ fun onClickForm(item: BenWithKALAZARScreeningDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/LeprosyMemberListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/LeprosyMemberListAdapter.kt
new file mode 100644
index 000000000..75369c311
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/LeprosyMemberListAdapter.kt
@@ -0,0 +1,168 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemLeprosyMemberListBinding
+import org.piramalswasthya.sakhi.model.BenWithKALAZARScreeningDomain
+import org.piramalswasthya.sakhi.model.BenWithLeprosyScreeningDomain
+
+class LeprosyMemberListAdapter(
+ private val clickListener: ClickListener? = null,
+ private val showExtraButton: Boolean? = null
+
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithLeprosyScreeningDomain,
+ newItem: BenWithLeprosyScreeningDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithLeprosyScreeningDomain,
+ newItem: BenWithLeprosyScreeningDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemLeprosyMemberListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemLeprosyMemberListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithLeprosyScreeningDomain,
+ clickListener: ClickListener?,
+ showExtraButton: Boolean?
+ ) {
+ binding.benWithLeprosy = item
+
+ if(showExtraButton == true && item.leprosy != null && item.leprosy.currentVisitNumber >1)
+ {
+ binding.btnVisits.visibility = View.VISIBLE
+
+ val green = ContextCompat.getColor(
+ binding.root.context,
+ android.R.color.holo_green_dark
+ )
+ binding.btnVisits.setBackgroundColor(green)
+ }
+ else
+ {
+ binding.btnVisits.visibility = View.GONE
+ }
+
+ /*if(item.tb?.historyOfTb == true){
+ binding.cvContent.visibility = View.GONE
+ }*/
+
+
+ binding.ivSyncState.visibility = if (item.leprosy == null) View.GONE else View.VISIBLE
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+ if ( item.leprosy != null && item.ben.isDeath) {
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.leprosy == null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.leprosy != null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else {
+ binding.btnFormTb.visibility = View.INVISIBLE
+ }
+ val (text, colorRes) = when {
+
+ item.leprosy == null -> {
+ R.string.screening to android.R.color.holo_green_dark
+ }
+ item.leprosy.leprosySymptomsPosition == 1 -> {
+ R.string.screening to android.R.color.holo_green_dark
+ }
+ item.leprosy.leprosySymptomsPosition == 0 && item.leprosy.isConfirmed -> {
+ R.string.follow_up to android.R.color.holo_red_dark
+ }
+ item.leprosy.leprosySymptomsPosition == 0 -> {
+ R.string.suspected to android.R.color.holo_red_dark
+ }
+ else -> {
+ R.string.view to android.R.color.holo_green_dark
+ }
+ }
+
+ binding.btnFormTb.text = binding.root.context.getString(text)
+ binding.btnFormTb.setBackgroundColor(
+ binding.root.resources.getColor(colorRes, binding.root.context.theme)
+ )
+ /* binding.btnFormTb.text = if (item.leprosy == null) "Register" else "View"
+ item.leprosy.leprosySymptomsPosition
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.leprosy == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))*/
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener,showExtraButton)
+ }
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null,
+ private val clickedVisits: ((benWithLeprosy: BenWithLeprosyScreeningDomain) -> Unit)? = null
+
+
+ ) {
+ fun onClickForm(item: BenWithLeprosyScreeningDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+
+ fun onClickVisits(item: BenWithLeprosyScreeningDomain) =
+ clickedVisits?.let { it(item) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/MaaMeetingAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/MaaMeetingAdapter.kt
new file mode 100644
index 000000000..aed4368f6
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/MaaMeetingAdapter.kt
@@ -0,0 +1,56 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.LayoutMaameetingItemBinding
+import org.piramalswasthya.sakhi.model.MaaMeetingEntity
+
+class MaaMeetingAdapter(
+ private val clickListener: MaaMeetingAdapterClickListener? = null,
+) : ListAdapter(BenDiffUtilCallBack) {
+
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: MaaMeetingEntity,
+ newItem: MaaMeetingEntity
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(
+ oldItem: MaaMeetingEntity,
+ newItem: MaaMeetingEntity
+ ) = oldItem == newItem
+ }
+
+ class MaaMeetingViewHolder private constructor(private val binding: LayoutMaameetingItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): MaaMeetingViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutMaameetingItemBinding.inflate(layoutInflater, parent, false)
+ return MaaMeetingViewHolder(binding)
+ }
+ }
+
+ fun bind(item: MaaMeetingEntity, clickListener: MaaMeetingAdapterClickListener?) {
+ binding.maaMeeting = item
+
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MaaMeetingViewHolder {
+ return MaaMeetingViewHolder.from(parent)
+ }
+
+ override fun onBindViewHolder(holder: MaaMeetingViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class MaaMeetingAdapterClickListener(val clickListener: (id: Long) -> Unit) {
+ fun onClick(id: Long) = clickListener(id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/MalariaConfirmedCasesListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/MalariaConfirmedCasesListAdapter.kt
new file mode 100644
index 000000000..ced1e3cc6
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/MalariaConfirmedCasesListAdapter.kt
@@ -0,0 +1,142 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemMalariaCasesConfirmedListBinding
+import org.piramalswasthya.sakhi.model.BenWithMalariaConfirmedDomain
+
+class MalariaConfirmedCasesListAdapter(
+ private val clickListener: ClickListener? = null
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithMalariaConfirmedDomain,
+ newItem: BenWithMalariaConfirmedDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithMalariaConfirmedDomain,
+ newItem: BenWithMalariaConfirmedDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemMalariaCasesConfirmedListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemMalariaCasesConfirmedListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithMalariaConfirmedDomain,
+ clickListener: ClickListener?,
+ ) {
+ binding.benWithMalariaConfirmed = item
+
+
+ binding.ivSyncState.visibility = if (item.malariaConfirmed == null) View.GONE else View.VISIBLE
+
+/* try {
+ if(item.malariaConfirmed!!.caseStatus != null) {
+ binding.ivMalariaStatus.visibility = View.VISIBLE
+ if (item.malariaConfirmed.caseStatus == "Confirmed") {
+ Glide.with(binding.ivSyncState).load(R.drawable.mosquito).into(binding.ivMalariaStatus)
+ } else if (item.malariaConfirmed.caseStatus == "Suspected") {
+ Glide.with(binding.ivSyncState).load(R.drawable.warning).into(binding.ivMalariaStatus)
+ }else if (item.malariaConfirmed.caseStatus == "Not Confirmed") {
+ Glide.with(binding.ivSyncState).load(R.drawable.ic_check_circle).into(binding.ivMalariaStatus)
+ } else if (item.malariaConfirmed.caseStatus == "Treatment Started"){
+ Glide.with(binding.ivSyncState).load(R.drawable.pill).into(binding.ivMalariaStatus)
+ } else {
+ Glide.with(binding.ivSyncState).load(R.drawable.warning).into(binding.ivMalariaStatus)
+
+ }
+
+ } else {
+ binding.ivMalariaStatus.visibility = View.INVISIBLE
+ }
+ } catch (e:Exception) {
+ Timber.d("Exception at case status : $e collected")
+
+ }*/
+
+
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+ if ( item.malariaConfirmed != null && item.ben.isDeath) {
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.malariaConfirmed == null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.malariaConfirmed != null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else {
+ binding.btnFormTb.visibility = View.INVISIBLE
+ }
+
+ binding.btnFormTb.text = if (item.malariaConfirmed == null) binding.root.resources.getString(R.string.follow_up) else item.malariaConfirmed.day
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.malariaConfirmed == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+
+ ) {
+ fun onClickForm(item: BenWithMalariaConfirmedDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/MalariaMemberListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/MalariaMemberListAdapter.kt
new file mode 100644
index 000000000..2d973978e
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/MalariaMemberListAdapter.kt
@@ -0,0 +1,165 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemMalariaMembersListBinding
+import org.piramalswasthya.sakhi.model.BenWithMalariaScreeningDomain
+import timber.log.Timber
+
+class MalariaMemberListAdapter(
+ private val clickListener: ClickListener? = null
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithMalariaScreeningDomain,
+ newItem: BenWithMalariaScreeningDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithMalariaScreeningDomain,
+ newItem: BenWithMalariaScreeningDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemMalariaMembersListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemMalariaMembersListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithMalariaScreeningDomain,
+ clickListener: ClickListener?,
+ ) {
+ binding.benWithMalaria = item
+
+ /*if(item.tb?.historyOfTb == true){
+ binding.cvContent.visibility = View.GONE
+ }*/
+
+ binding.ivSyncState.visibility = if (item.tb == null) View.INVISIBLE else View.VISIBLE
+ try {
+ if (item.tb == null) {
+ binding.btnFormTb.text = binding.root.resources.getString(R.string.screening)
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_red_dark))
+
+ } else {
+ if(item.tb.caseStatus != null) {
+
+ binding.ivMalariaStatus.visibility = View.VISIBLE
+ if (item.tb.caseStatus == "Confirmed") {
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_green_dark))
+ Glide.with(binding.ivSyncState).load(R.drawable.mosquito).into(binding.ivMalariaStatus)
+ binding.btnFormTb.text = binding.root.resources.getString(R.string.malaria_confirmed)
+ } else if (item.tb.caseStatus == "Suspected") {
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_orange_light))
+ Glide.with(binding.ivSyncState).load(R.drawable.warning).into(binding.ivMalariaStatus)
+ binding.btnFormTb.text = binding.root.resources.getString(R.string.suspected)
+ }else if (item.tb.caseStatus == "Not Confirmed") {
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(android.R.color.tertiary_text_light))
+ Glide.with(binding.ivSyncState).load(R.drawable.ic_check_circle).into(binding.ivMalariaStatus)
+ binding.btnFormTb.text = binding.root.resources.getString(R.string.malaria_not_confirmed)
+ } else if (item.tb.caseStatus == "Treatment Started"){
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_purple))
+ Glide.with(binding.ivSyncState).load(R.drawable.pill).into(binding.ivMalariaStatus)
+ binding.btnFormTb.text = binding.root.resources.getString(R.string.malaria_treatment_started)
+
+ } else {
+ Glide.with(binding.ivSyncState).load(R.drawable.warning).into(binding.ivMalariaStatus)
+ }
+
+ } else {
+
+ binding.ivMalariaStatus.visibility = View.INVISIBLE
+ binding.btnFormTb.text = binding.root.resources.getString(R.string.view)
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_green_dark))
+
+ }
+ }
+
+ } catch (e:Exception) {
+ Timber.d("Exception at case status : $e collected")
+
+ }
+
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+
+ if ( item.tb != null && item.ben.isDeath) {
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.tb == null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else if (item.tb != null && !item.ben.isDeath){
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else {
+ binding.btnFormTb.visibility = View.INVISIBLE
+ }
+// binding.btnFormTb.text = if (item.tb == null) "Screening" else "View"
+// binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.tb == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+
+ ) {
+ fun onClickForm(item: BenWithMalariaScreeningDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/NCDCategoryAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/NCDCategoryAdapter.kt
new file mode 100644
index 000000000..27652e0f8
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/NCDCategoryAdapter.kt
@@ -0,0 +1,68 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvTabBinding
+import org.piramalswasthya.sakhi.ui.home_activity.non_communicable_diseases.ncd_eligible_list.NcdEligibleListViewModel
+
+class NCDCategoryAdapter(
+ private val dataList: ArrayList,
+ private val listener: ClickListener? = null,
+ var viewModel: NcdEligibleListViewModel
+) : RecyclerView.Adapter(){
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
+ ViewHolder.from(parent)
+
+
+ override fun onBindViewHolder(
+ holder: ViewHolder,
+ position: Int,
+ ) {
+
+ holder.bind(dataList[position])
+ holder.binding.cMainLayout.setOnClickListener {
+ viewModel.clickedPosition = position
+ listener?.onClicked(dataList[position])
+ notifyDataSetChanged()
+
+ }
+ if (viewModel.clickedPosition == position) {
+ holder.binding.cMainLayout.setBackgroundResource(R.drawable.tab_selection)
+ } else {
+ holder.binding.cMainLayout.setBackgroundResource(R.drawable.tab_unselection)
+ }
+
+ }
+
+
+ class ViewHolder private constructor(val binding: RvTabBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvTabBinding.inflate(layoutInflater, parent, false)
+ return ViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ dataObject: String,
+ ) {
+
+ binding.monthText.text = dataObject
+
+ }
+
+ }
+ override fun getItemCount(): Int {
+ return dataList.size
+ }
+
+ fun interface ClickListener
+ {
+ fun onClicked(catDataList: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/NCDReferTypeFilterAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/NCDReferTypeFilterAdapter.kt
new file mode 100644
index 000000000..20b723a3f
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/NCDReferTypeFilterAdapter.kt
@@ -0,0 +1,68 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvTabBinding
+import org.piramalswasthya.sakhi.ui.home_activity.non_communicable_diseases.ncd_referred.list.NcdRefferedListViewModel
+
+class NCDReferTypeFilterAdapter(
+ private val catDataList: ArrayList,
+ private val clickListener: CategoryClickListener? = null,
+ var viewModel: NcdRefferedListViewModel
+) : RecyclerView.Adapter(){
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
+ CategoryViewHolder.from(parent)
+
+
+ override fun onBindViewHolder(
+ holder: CategoryViewHolder,
+ position: Int,
+ ) {
+
+ holder.bind(catDataList[position])
+ holder.binding.cMainLayout.setOnClickListener {
+ viewModel.selectedPosition = position
+ clickListener?.onClicked(catDataList[position])
+ notifyDataSetChanged()
+
+ }
+ if (viewModel.selectedPosition == position) {
+ holder.binding.cMainLayout.setBackgroundResource(R.drawable.tab_selection)
+ } else {
+ holder.binding.cMainLayout.setBackgroundResource(R.drawable.tab_unselection)
+ }
+
+ }
+
+
+ class CategoryViewHolder private constructor(val binding: RvTabBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): CategoryViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvTabBinding.inflate(layoutInflater, parent, false)
+ return CategoryViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ catDataList: String,
+ ) {
+
+ binding.monthText.text = catDataList
+
+ }
+
+ }
+ override fun getItemCount(): Int {
+ return catDataList.size
+ }
+
+ fun interface CategoryClickListener
+ {
+ fun onClicked(catDataList: String)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/NcdReferListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/NcdReferListAdapter.kt
new file mode 100644
index 000000000..c5b3c7d76
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/NcdReferListAdapter.kt
@@ -0,0 +1,106 @@
+ package org.piramalswasthya.sakhi.adapters
+
+ import android.view.LayoutInflater
+ import android.view.View
+ import android.view.ViewGroup
+ import androidx.recyclerview.widget.DiffUtil
+ import androidx.recyclerview.widget.ListAdapter
+ import androidx.recyclerview.widget.RecyclerView
+ import org.piramalswasthya.sakhi.databinding.RvItemNcdReferBinding
+ import org.piramalswasthya.sakhi.model.BenBasicDomain
+ import org.piramalswasthya.sakhi.model.BenWithCbacReferDomain
+
+ class NcdReferListAdapter(var userName: String, private val listener: NcdReferallickListener, private val visible: Boolean ) : ListAdapter(
+ BenDiffUtilCallBack
+ ) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithCbacReferDomain, newItem: BenWithCbacReferDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithCbacReferDomain, newItem: BenWithCbacReferDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenCbacViewHolder private constructor(private val binding: RvItemNcdReferBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenCbacViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemNcdReferBinding.inflate(layoutInflater, parent, false)
+ return BenCbacViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithCbacReferDomain,
+ userName: String,
+ listener: NcdReferallickListener,
+ visible: Boolean
+ ) {
+ binding.benWithCbac = item
+ binding.referredFrom.text = userName
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+
+ binding.executePendingBindings()
+ binding.btnFollowUp.visibility = if (visible) View.VISIBLE else View.GONE
+ binding.btnFollowUp.setOnClickListener {
+ listener.onClickedFollowUp(item.ben)
+ }
+
+
+ }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ): BenCbacViewHolder = BenCbacViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenCbacViewHolder, position: Int) {
+ holder.bind(getItem(position) , userName,listener,visible)
+ }
+
+
+
+ class NcdReferallickListener(
+ val goToFollowUp: (benId: Long,hhId:Long) -> Unit
+
+ ) {
+ fun onClickedFollowUp(item: BenBasicDomain) = goToFollowUp(
+ item.benId,item.hhId
+ )
+ }
+
+
+
+
+ }
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/ORSCampaignAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ORSCampaignAdapter.kt
new file mode 100644
index 000000000..616035c97
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/ORSCampaignAdapter.kt
@@ -0,0 +1,61 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.LayoutOrsCampaignItemBinding
+import org.piramalswasthya.sakhi.model.ORSCampaignCache
+import org.piramalswasthya.sakhi.utils.HelperUtil
+
+class ORSCampaignAdapter(
+ private val clickListener: ORSCampaignClickListener? = null,
+) : ListAdapter(BenDiffUtilCallBack) {
+
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: ORSCampaignCache,
+ newItem: ORSCampaignCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(
+ oldItem: ORSCampaignCache,
+ newItem: ORSCampaignCache
+ ) = oldItem == newItem
+ }
+
+ class ORSCampaignViewHolder private constructor(private val binding: LayoutOrsCampaignItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): ORSCampaignViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutOrsCampaignItemBinding.inflate(layoutInflater, parent, false)
+ return ORSCampaignViewHolder(binding)
+ }
+ }
+
+ fun bind(item: ORSCampaignCache, clickListener: ORSCampaignClickListener?) {
+ binding.orsCampaign = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ val startDate = HelperUtil.extractFieldValue(item.formDataJson,"start_date")
+ val numberOfChildren = HelperUtil.extractFieldValue(item.formDataJson,"number_of_families")
+ binding.tvDate.text = startDate
+ binding.numberOfChildren.text = binding.root.context.getString(R.string.number_of_families_label, numberOfChildren)
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ORSCampaignViewHolder {
+ return ORSCampaignViewHolder.from(parent)
+ }
+
+ override fun onBindViewHolder(holder: ORSCampaignViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class ORSCampaignClickListener(val clickListener: (id: Int) -> Unit) {
+ fun onClick(id: Int) = clickListener(id)
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PHCAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PHCAdapter.kt
new file mode 100644
index 000000000..c8bf4b71b
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PHCAdapter.kt
@@ -0,0 +1,182 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.LayoutPhcReviewItemBinding
+import org.piramalswasthya.sakhi.databinding.LayoutVhncItemBinding
+import org.piramalswasthya.sakhi.model.PHCReviewMeetingCache
+import org.piramalswasthya.sakhi.model.VHNCCache
+
+class PHCAdapter(
+ private val clickListener: PHCClickListener? = null,
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: PHCReviewMeetingCache,
+ newItem: PHCReviewMeetingCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: PHCReviewMeetingCache, newItem: PHCReviewMeetingCache)= oldItem == newItem
+
+
+ }
+
+ class PHCViewHolder private constructor(private val binding: LayoutPhcReviewItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): PHCViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutPhcReviewItemBinding.inflate(layoutInflater, parent, false)
+ return PHCViewHolder(binding)
+ }
+ }
+ fun bind(item: PHCReviewMeetingCache, clickListener: PHCClickListener?,) {
+ binding.phc = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+
+ }
+
+
+
+// private fun setFormButtonColor(formNumber: Int, item: BenWithHRPADomain, role: Int?) {
+// var hasForm: Boolean = false
+// var completelyFilled: Boolean = false
+// var formEnabled: Boolean = false
+// buttonFlexibleWidth()
+//// binding.btnForm3.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_whatsapp, 0);
+//
+//
+//// val formButton = when (formNumber) {
+//// 1 -> {
+//// binding.btnForm1.also {
+//// hasForm = item.assess != null
+//// item.assess?.let {
+//// completelyFilled =
+//// it.noOfDeliveries != null &&
+//// it.timeLessThan18m != null &&
+//// it.heightShort != null &&
+//// it.age != null &&
+//// it.rhNegative != null &&
+//// it.homeDelivery != null &&
+//// it.badObstetric != null &&
+//// it.multiplePregnancy != null
+//// }
+////
+//// formEnabled = true
+//// }
+//// }
+////
+////// 2 -> {
+////// binding.btnForm2.also {
+////// hasForm = item.mbp != null
+////// formEnabled = true
+////// }
+////// }
+//////
+////// 3 -> {
+////// binding.btnForm3.also {
+////// hasForm = item.mbp != null
+////// if (hasForm) {
+//////
+////// formEnabled = true
+////// buttonFlexibleWidth()
+//////
+////// } else {
+//////
+////// formEnabled = false
+////// (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.8f
+////// (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+//////
+////// }
+//////
+////// }
+////// }
+////
+//// else -> throw IllegalStateException("FormNumber>3")
+//// }
+//// formButton.visibility = if (formEnabled) View.VISIBLE else View.GONE
+//
+//
+//// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+//// if (hasForm) {
+//// if (completelyFilled) {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_green_dark,
+//// binding.root.context.theme
+//// )
+//// )
+//// } else {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_orange_dark,
+//// binding.root.context.theme
+//// )
+//// )
+//// }
+//// binding.btnForm3.setBackgroundColor(
+//// binding.btnForm3.resources.getColor(
+//// android.R.color.holo_purple,
+//// binding.root.context.theme
+//// )
+//// )
+////
+//// } else {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_red_light,
+//// binding.root.context.theme
+//// )
+//// )
+//// }
+////
+//// } else
+//// if (hasForm)
+//// formButton.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_green_dark))
+//// else
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_red_light,
+//// )
+//// )
+////
+//// formButton.setTextColor(
+//// binding.root.resources.getColor(
+//// com.google.android.material.R.color.design_default_color_on_primary,
+//// binding.root.context.theme
+//// )
+//// )
+//
+// }
+
+// private fun buttonFlexibleWidth() {
+// (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+// (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=0.8f
+// (binding.btnForm3.layoutParams as LinearLayout.LayoutParams).weight=1.0f
+// }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ PHCViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: PHCViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class PHCClickListener(
+ private val clickedForm: ((id: Int) -> Unit)? = null
+ ) {
+ fun onClickForm1(item: PHCReviewMeetingCache) = clickedForm?.let { it(item.id!!) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PmsmaVisitAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PmsmaVisitAdapter.kt
new file mode 100644
index 000000000..6e3cfac96
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PmsmaVisitAdapter.kt
@@ -0,0 +1,69 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvItemPregnancyAncBinding
+import org.piramalswasthya.sakhi.databinding.RvItemPregnancyAncPmsmaBinding
+import org.piramalswasthya.sakhi.model.AncStatus
+
+class PmsmaVisitAdapter(private val clickListener: PmsmaVisitClickListener) :
+ ListAdapter(
+ MyDiffUtilCallBack
+ ) {
+ private object MyDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: AncStatus, newItem: AncStatus
+ ) = oldItem.benId == newItem.benId
+
+ override fun areContentsTheSame(
+ oldItem: AncStatus, newItem: AncStatus
+ ) = oldItem == newItem
+
+ }
+
+ class AncViewHolder private constructor(private val binding: RvItemPregnancyAncPmsmaBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): AncViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemPregnancyAncPmsmaBinding.inflate(layoutInflater, parent, false)
+ return AncViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: AncStatus, clickListener: PmsmaVisitClickListener, isLastItem: Boolean
+ ) {
+ binding.visit = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+
+ binding.btnView.setOnClickListener {
+ clickListener.onClickedVisit(item, true)
+ }
+
+ }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup, viewType: Int
+ ) = AncViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: AncViewHolder, position: Int) {
+ val isLastItem = position == itemCount - 1
+ holder.bind(getItem(position), clickListener, isLastItem)
+ }
+
+
+ class PmsmaVisitClickListener(
+ private val clickedForm: (benId: Long, visitNumber: Int, isLast: Boolean) -> Unit
+ ) {
+ fun onClickedVisit(item: AncStatus, isLast: Boolean) = clickedForm(
+ item.benId, item.visitNumber, isLast
+ )
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PncVisitListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PncVisitListAdapter.kt
index 76005d1f5..70c7a235e 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PncVisitListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PncVisitListAdapter.kt
@@ -1,13 +1,17 @@
package org.piramalswasthya.sakhi.adapters
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.Toast
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import org.piramalswasthya.sakhi.databinding.RvItemPncVisitBinding
import org.piramalswasthya.sakhi.model.BenPncDomain
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import java.util.concurrent.TimeUnit
class PncVisitListAdapter(private val clickListener: PncVisitClickListener? = null) :
ListAdapter(
@@ -37,11 +41,26 @@ class PncVisitListAdapter(private val clickListener: PncVisitClickListener? = nu
fun bind(
item: BenPncDomain, clickListener: PncVisitClickListener?
) {
+
+ if (item.pncDate == 0L) {
+ binding.ivFollowState.visibility = View.GONE
+ binding.llBenPwrTrackingDetails3.visibility = View.GONE
+ } else if (item.pncDate < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(90) &&
+ item.pncDate > System.currentTimeMillis() - TimeUnit.DAYS.toMillis(365)) {
+ binding.ivFollowState.visibility = View.VISIBLE
+ binding.llBenPwrTrackingDetails3.visibility = View.VISIBLE
+ binding.benVisitDate.text = HelperUtil.getDateStringFromLongStraight(item.pncDate)
+ } else {
+ binding.ivFollowState.visibility = View.GONE
+ binding.llBenPwrTrackingDetails3.visibility = View.VISIBLE
+ binding.benVisitDate.text = HelperUtil.getDateStringFromLongStraight(item.pncDate)
+ }
+
binding.visit = item
binding.btnViewVisits.visibility =
if (item.savedPncRecords.isEmpty()) View.INVISIBLE else View.VISIBLE
binding.btnAddPnc.visibility =
- if (item.allowFill) View.INVISIBLE else View.VISIBLE
+ if (item.allowFill) View.VISIBLE else View.INVISIBLE
binding.clickListener = clickListener
binding.executePendingBindings()
@@ -59,14 +78,15 @@ class PncVisitListAdapter(private val clickListener: PncVisitClickListener? = nu
class PncVisitClickListener(
private val showVisits: (benId: Long) -> Unit,
- private val addVisit: (benId: Long, visitNumber: Int) -> Unit,
+ private val addVisit: (benId: Long, hhId: Long ,visitNumber: Int) -> Unit,
) {
fun showVisits(item: BenPncDomain) = showVisits(
item.ben.benId,
+
)
- fun addVisit(item: BenPncDomain) = addVisit(item.ben.benId,
+ fun addVisit(item: BenPncDomain) = addVisit(item.ben.benId,item.ben.hhId,
if (item.savedPncRecords.isEmpty()) 1 else item.savedPncRecords.maxOf { it.pncPeriod } + 1)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PreviewAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PreviewAdapter.kt
new file mode 100644
index 000000000..d998b5e6f
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PreviewAdapter.kt
@@ -0,0 +1,55 @@
+package org.piramalswasthya.sakhi.adapters
+
+
+import android.net.Uri
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.model.PreviewItem
+
+class PreviewAdapter(
+ private val items: List,
+ private val imageLoader: ((ImageView, Uri?) -> Unit)? = null // injectable for production (Glide/Picasso)
+) : RecyclerView.Adapter() {
+
+ class PreviewVH(view: View) : RecyclerView.ViewHolder(view) {
+ val tvLabel: TextView = view.findViewById(R.id.tvLabel)
+ val tvValue: TextView = view.findViewById(R.id.tvValue)
+ val ivImage: ImageView = view.findViewById(R.id.ivPreviewImage)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PreviewVH {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.item_preview_row, parent, false)
+ return PreviewVH(v)
+ }
+
+ override fun onBindViewHolder(holder: PreviewVH, position: Int) {
+ val it = items[position]
+ holder.tvLabel.text = it.label
+ if (it.isImage) {
+ // show image view, hide text value
+ holder.tvValue.visibility = View.GONE
+ holder.ivImage.visibility = View.VISIBLE
+ imageLoader?.invoke(holder.ivImage, it.imageUri) ?: run {
+ // Minimal default loader (URI -> ImageView). Use Glide/Picasso in prod.
+ try {
+ it.imageUri?.let { uri ->
+ holder.ivImage.setImageURI(uri)
+ } ?: holder.ivImage.setImageResource(android.R.color.darker_gray)
+ } catch (e: Exception) {
+ holder.ivImage.setImageResource(android.R.color.darker_gray)
+ }
+ }
+ } else {
+ holder.ivImage.visibility = View.GONE
+ holder.tvValue.visibility = View.VISIBLE
+ holder.tvValue.text = it.value
+ }
+ }
+
+ override fun getItemCount(): Int = items.size
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PulsePolioCampaignAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PulsePolioCampaignAdapter.kt
new file mode 100644
index 000000000..b8e36bda1
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PulsePolioCampaignAdapter.kt
@@ -0,0 +1,61 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.LayoutPulsePolioCampaignItemBinding
+import org.piramalswasthya.sakhi.model.PulsePolioCampaignCache
+import org.piramalswasthya.sakhi.utils.HelperUtil
+
+class PulsePolioCampaignAdapter(
+ private val clickListener: PulsePolioCampaignClickListener? = null,
+) : ListAdapter(BenDiffUtilCallBack) {
+
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: PulsePolioCampaignCache,
+ newItem: PulsePolioCampaignCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(
+ oldItem: PulsePolioCampaignCache,
+ newItem: PulsePolioCampaignCache
+ ) = oldItem == newItem
+ }
+
+ class PulsePolioCampaignViewHolder private constructor(private val binding: LayoutPulsePolioCampaignItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): PulsePolioCampaignViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutPulsePolioCampaignItemBinding.inflate(layoutInflater, parent, false)
+ return PulsePolioCampaignViewHolder(binding)
+ }
+ }
+
+ fun bind(item: PulsePolioCampaignCache, clickListener: PulsePolioCampaignClickListener?) {
+ binding.pulsePolioCampaign = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ val startDate = HelperUtil.extractFieldValue(item.formDataJson,"start_date")
+ val numberOfChildren = HelperUtil.extractFieldValue(item.formDataJson,"children_vaccinated")
+ binding.tvDate.text = startDate
+ binding.numberOfChildren.text = binding.root.context.getString(R.string.number_of_children_label, numberOfChildren)
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PulsePolioCampaignViewHolder {
+ return PulsePolioCampaignViewHolder.from(parent)
+ }
+
+ override fun onBindViewHolder(holder: PulsePolioCampaignViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class PulsePolioCampaignClickListener(val clickListener: (id: Int) -> Unit) {
+ fun onClick(id: Int) = clickListener(id)
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PwRegistrationListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PwRegistrationListAdapter.kt
index 7dd1fa1cd..3568fb5b5 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/PwRegistrationListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/PwRegistrationListAdapter.kt
@@ -6,11 +6,15 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemBenPwRegistrationListWithFormBinding
import org.piramalswasthya.sakhi.model.BenWithPwrDomain
+import org.piramalswasthya.sakhi.utils.RoleConstants
class PwRegistrationListAdapter(
- private val clickListener: ClickListener? = null
+ private val clickListener: ClickListener? = null,
+ private val pref: PreferenceDao? = null
) :
ListAdapter
(BenDiffUtilCallBack) {
@@ -44,10 +48,18 @@ class PwRegistrationListAdapter(
fun bind(
item: BenWithPwrDomain,
clickListener: ClickListener?,
+ pref: PreferenceDao?
) {
+
+ if (pref?.getLoggedInUser()?.role.equals(RoleConstants.ROLE_ASHA_SUPERVISOR, true)) {
+ binding.btnFormEc1.visibility = View.GONE
+ } else {
+ binding.btnFormEc1.visibility = View.VISIBLE
+ }
+
binding.benWithPwr = item
binding.ivSyncState.visibility = if (item.pwr == null) View.INVISIBLE else View.VISIBLE
- binding.btnFormEc1.text = if (item.pwr == null) "Register" else "View"
+ binding.btnFormEc1.text = if (item.pwr == null) binding.root.resources.getString(R.string.register) else binding.root.resources.getString(R.string.view)
binding.btnFormEc1.setBackgroundColor(binding.root.resources.getColor(if (item.pwr == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
binding.clickListener = clickListener
@@ -65,7 +77,7 @@ class PwRegistrationListAdapter(
BenViewHolder.from(parent)
override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener)
+ holder.bind(getItem(position), clickListener, pref)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/SaasBahuSammelanAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/SaasBahuSammelanAdapter.kt
new file mode 100644
index 000000000..5fafd0508
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/SaasBahuSammelanAdapter.kt
@@ -0,0 +1,55 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.LayoutSaasBahuListBinding
+import org.piramalswasthya.sakhi.model.SaasBahuSammelanCache
+
+class SaasBahuSammelanAdapter(
+ private val clickListener: SaasBahuSammelanAdapterClickListener? = null,
+) : ListAdapter(BenDiffUtilCallBack) {
+
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: SaasBahuSammelanCache,
+ newItem: SaasBahuSammelanCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(
+ oldItem: SaasBahuSammelanCache,
+ newItem: SaasBahuSammelanCache
+ ) = oldItem == newItem
+ }
+
+ class SaasBahuSammelanViewHolder private constructor(private val binding: LayoutSaasBahuListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): SaasBahuSammelanViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutSaasBahuListBinding.inflate(layoutInflater, parent, false)
+ return SaasBahuSammelanViewHolder(binding)
+ }
+ }
+
+ fun bind(item: SaasBahuSammelanCache, clickListener: SaasBahuSammelanAdapterClickListener?) {
+ binding.maaMeeting = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SaasBahuSammelanViewHolder {
+ return SaasBahuSammelanViewHolder.from(parent)
+ }
+
+ override fun onBindViewHolder(holder: SaasBahuSammelanViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class SaasBahuSammelanAdapterClickListener(val clickListener: (id: Long) -> Unit) {
+ fun onClick(id: Long) = clickListener(id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/SyncDashboardStatusAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/SyncDashboardStatusAdapter.kt
new file mode 100644
index 000000000..29ace8741
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/SyncDashboardStatusAdapter.kt
@@ -0,0 +1,44 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvItemSyncDashboardStatusBinding
+import org.piramalswasthya.sakhi.model.SyncStatusDomain
+
+class SyncDashboardStatusAdapter :
+ ListAdapter(DiffCallback) {
+
+ private object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: SyncStatusDomain, newItem: SyncStatusDomain) =
+ oldItem.name == newItem.name
+
+ override fun areContentsTheSame(oldItem: SyncStatusDomain, newItem: SyncStatusDomain) =
+ oldItem == newItem
+ }
+
+ class ViewHolder(
+ private val binding: RvItemSyncDashboardStatusBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(item: SyncStatusDomain) {
+ binding.tvEntityName.text = item.name
+ binding.tvSynced.text = item.synced.toString()
+ binding.tvUnsynced.text = item.notSynced.toString()
+ binding.tvSyncing.text = item.syncing.toString()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = RvItemSyncDashboardStatusBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(getItem(position))
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/SyncLogAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/SyncLogAdapter.kt
new file mode 100644
index 000000000..9d98b5e2c
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/SyncLogAdapter.kt
@@ -0,0 +1,73 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.graphics.Color
+import android.graphics.drawable.GradientDrawable
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.RvItemSyncLogBinding
+import org.piramalswasthya.sakhi.model.LogLevel
+import org.piramalswasthya.sakhi.model.SyncLogEntry
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+
+class SyncLogAdapter :
+ ListAdapter(DiffCallback) {
+
+ companion object {
+ private const val MAX_DISPLAY_LENGTH = 500
+ }
+
+ private object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: SyncLogEntry, newItem: SyncLogEntry) =
+ oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: SyncLogEntry, newItem: SyncLogEntry) =
+ oldItem == newItem
+ }
+
+ private val timeFormat = SimpleDateFormat("HH:mm:ss.SSS", Locale.US)
+
+ class ViewHolder(
+ private val binding: RvItemSyncLogBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(item: SyncLogEntry, timeFormat: SimpleDateFormat) {
+ val (label, bgColor, textColor) = when (item.level) {
+ LogLevel.ERROR -> Triple("E", Color.parseColor("#D32F2F"), Color.parseColor("#D32F2F"))
+ LogLevel.WARN -> Triple("W", Color.parseColor("#F57C00"), Color.parseColor("#F57C00"))
+ LogLevel.INFO -> Triple("I", Color.parseColor("#1976D2"), Color.parseColor("#333333"))
+ LogLevel.DEBUG -> Triple("D", Color.parseColor("#757575"), Color.parseColor("#757575"))
+ }
+
+ binding.tvLevel.text = label
+ val bg = GradientDrawable().apply {
+ shape = GradientDrawable.RECTANGLE
+ cornerRadius = 4f
+ setColor(bgColor)
+ }
+ binding.tvLevel.background = bg
+
+ binding.tvTimestamp.text = "${timeFormat.format(Date(item.timestamp))} ${item.tag}"
+ binding.tvMessage.text = if (item.message.length > MAX_DISPLAY_LENGTH)
+ item.message.substring(0, MAX_DISPLAY_LENGTH) + "…"
+ else
+ item.message
+ binding.tvMessage.setTextColor(textColor)
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = RvItemSyncLogBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(getItem(position), timeFormat)
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/TBFollowUpDatesAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TBFollowUpDatesAdapter.kt
new file mode 100644
index 000000000..a84a684ac
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TBFollowUpDatesAdapter.kt
@@ -0,0 +1,58 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.annotation.SuppressLint
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.adapters.FollowUpDatesAdapter
+import org.piramalswasthya.sakhi.databinding.ItemFollowUpDateBinding
+import org.piramalswasthya.sakhi.model.LeprosyFollowUpCache
+import org.piramalswasthya.sakhi.model.TBConfirmedTreatmentCache
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+
+class TBFollowUpDatesAdapter :
+ ListAdapter(DiffCallback) {
+
+ private val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FollowUpViewHolder {
+ val binding = ItemFollowUpDateBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ return FollowUpViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: FollowUpViewHolder, position: Int) {
+ val followUp = getItem(position)
+ holder.bind(followUp)
+ }
+
+ inner class FollowUpViewHolder(private val binding: ItemFollowUpDateBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ @SuppressLint("SuspiciousIndentation")
+ fun bind(followUp: TBConfirmedTreatmentCache) {
+ if(followUp.followUpDate!=null)
+ { binding.tvFollowUpDate.text = dateFormat.format(Date(followUp.followUpDate!!))}
+ binding.tvTreatmentStatus.visibility = View.GONE
+ binding.tvLastFollowUpDate.visibility = View.VISIBLE
+ }
+ }
+
+ companion object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: TBConfirmedTreatmentCache, newItem: TBConfirmedTreatmentCache): Boolean {
+ return oldItem.id == newItem.id
+ }
+
+ override fun areContentsTheSame(oldItem: TBConfirmedTreatmentCache, newItem: TBConfirmedTreatmentCache): Boolean {
+ return oldItem == newItem
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbConfirmedListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbConfirmedListAdapter.kt
new file mode 100644
index 000000000..c76698dbf
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbConfirmedListAdapter.kt
@@ -0,0 +1,128 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
+import org.piramalswasthya.sakhi.databinding.RvItemTbConfirmedListBinding
+import org.piramalswasthya.sakhi.databinding.RvItemTbSuspectedListBinding
+import org.piramalswasthya.sakhi.model.BenWithTbSuspectedDomain
+
+class TbConfirmedListAdapter( private val clickListener: ClickListener? = null,
+private val pref: PreferenceDao? = null
+) :
+ListAdapter
+(BenDiffUtilCallBack) {
+
+
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: BenWithTbSuspectedDomain,
+ newItem: BenWithTbSuspectedDomain
+ ) = oldItem.ben.benId == newItem.ben.benId
+
+ override fun areContentsTheSame(
+ oldItem: BenWithTbSuspectedDomain,
+ newItem: BenWithTbSuspectedDomain
+ ) = oldItem == newItem
+
+ }
+
+ class BenViewHolder private constructor(private val binding: RvItemTbConfirmedListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): BenViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = RvItemTbConfirmedListBinding.inflate(layoutInflater, parent, false)
+ return BenViewHolder(binding)
+ }
+ }
+
+ fun bind(
+ item: BenWithTbSuspectedDomain,
+ clickListener: ClickListener?,
+ pref: PreferenceDao?
+ ) {
+
+ if (pref?.getLoggedInUser()?.role.equals("asha", true)) {
+ binding.btnFormTb.visibility = View.VISIBLE
+ } else {
+ binding.btnFormTb.visibility = View.INVISIBLE
+ }
+
+ binding.benWithTb = item
+
+ binding.ivSyncState.visibility = if (item.tbConfirmedList == null) View.INVISIBLE else View.VISIBLE
+
+ if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else {
+ if (item.ben.gender == "MALE") {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ } else if (item.ben.gender == "FEMALE") {
+ if (item.ben.ageInt > 15) {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.husband = item.ben.spouseName != "Not Available"
+ binding.spouse = false
+ } else {
+ binding.father = true
+ binding.husband = false
+ binding.spouse = false
+ }
+ } else {
+ binding.father =
+ item.ben.fatherName != "Not Available" && item.ben.spouseName == "Not Available"
+ binding.spouse = item.ben.spouseName != "Not Available"
+ binding.husband = false
+ }
+ }
+
+
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.tbConfirmedList == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.clickListener = clickListener
+
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ )= BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(
+ holder: BenViewHolder,
+ position: Int
+ ) {
+ holder.bind(getItem(position), clickListener, pref) }
+
+ /*override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ BenViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener, pref)
+ }*/
+
+
+ class ClickListener(
+ private val clickedForm: ((hhId: Long, benId: Long) -> Unit)? = null
+
+ ) {
+ fun onClickForm(item: BenWithTbSuspectedDomain) =
+ clickedForm?.let { it(item.ben.hhId, item.ben.benId) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbScreeningListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbScreeningListAdapter.kt
index c7dcda306..4f8c948b0 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbScreeningListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbScreeningListAdapter.kt
@@ -6,6 +6,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.databinding.RvItemTbScreeningListBinding
import org.piramalswasthya.sakhi.model.BenWithTbScreeningDomain
@@ -43,6 +44,10 @@ class TbScreeningListAdapter(
) {
binding.benWithTb = item
+ if(item.tb?.historyOfTb == true){
+ binding.cvContent.visibility = View.GONE
+ }
+
binding.ivSyncState.visibility = if (item.tb == null) View.INVISIBLE else View.VISIBLE
if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
@@ -73,7 +78,7 @@ class TbScreeningListAdapter(
}
}
- binding.btnFormTb.text = if (item.tb == null) "Screen" else "View Screen"
+ binding.btnFormTb.text = if (item.tb == null) binding.root.context.getString(R.string.screen) else binding.root.context.getString(R.string.view_screen)
binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.tb == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
binding.clickListener = clickListener
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbSuspectedListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbSuspectedListAdapter.kt
index de2229263..380394b2c 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbSuspectedListAdapter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/TbSuspectedListAdapter.kt
@@ -6,11 +6,15 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.databinding.RvItemTbSuspectedListBinding
import org.piramalswasthya.sakhi.model.BenWithTbSuspectedDomain
+import org.piramalswasthya.sakhi.utils.RoleConstants
class TbSuspectedListAdapter(
- private val clickListener: ClickListener? = null
+ private val clickListener: ClickListener? = null,
+ private val pref: PreferenceDao? = null
) :
ListAdapter
(BenDiffUtilCallBack) {
@@ -40,10 +44,18 @@ class TbSuspectedListAdapter(
fun bind(
item: BenWithTbSuspectedDomain,
clickListener: ClickListener?,
+ pref: PreferenceDao?
) {
+
+ if (pref?.getLoggedInUser()?.role.equals(RoleConstants.ROLE_ASHA_SUPERVISOR, true)) {
+ binding.btnFormTb.visibility = View.INVISIBLE
+ } else {
+ binding.btnFormTb.visibility = View.VISIBLE
+ }
+
binding.benWithTb = item
- binding.ivSyncState.visibility = if (item.tb == null) View.INVISIBLE else View.VISIBLE
+ binding.ivSyncState.visibility = if (item.tbSuspected == null) View.INVISIBLE else View.VISIBLE
if (item.ben.spouseName == "Not Available" && item.ben.fatherName == "Not Available") {
binding.father = true
@@ -73,8 +85,8 @@ class TbSuspectedListAdapter(
}
}
- binding.btnFormTb.text = if (item.tb == null) "Track" else "View"
- binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.tb == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
+ binding.btnFormTb.text = if (item.tbSuspected == null) binding.root.resources.getString(R.string.track) else binding.root.resources.getString(R.string.view)
+ binding.btnFormTb.setBackgroundColor(binding.root.resources.getColor(if (item.tbSuspected == null) android.R.color.holo_red_dark else android.R.color.holo_green_dark))
binding.clickListener = clickListener
binding.executePendingBindings()
@@ -90,7 +102,7 @@ class TbSuspectedListAdapter(
BenViewHolder.from(parent)
override fun onBindViewHolder(holder: BenViewHolder, position: Int) {
- holder.bind(getItem(position), clickListener)
+ holder.bind(getItem(position), clickListener, pref)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/UwinListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/UwinListAdapter.kt
new file mode 100644
index 000000000..d1e476356
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/UwinListAdapter.kt
@@ -0,0 +1,53 @@
+package org.piramalswasthya.sakhi.adapters
+
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.ItemUwinListBinding
+import org.piramalswasthya.sakhi.model.UwinCache
+
+class UwinListAdapter(
+ private val clickListener: UwinClickListener? = null
+) : ListAdapter(UwinDiffUtilCallback) {
+
+ private object UwinDiffUtilCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: UwinCache, newItem: UwinCache): Boolean =
+ oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: UwinCache, newItem: UwinCache): Boolean =
+ oldItem == newItem
+ }
+
+ class UwinViewHolder private constructor(private val binding: ItemUwinListBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(item: UwinCache, clickListener: UwinClickListener?) {
+ binding.uwin = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+ }
+
+ companion object {
+ fun from(parent: ViewGroup): UwinViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = ItemUwinListBinding.inflate(layoutInflater, parent, false)
+ return UwinViewHolder(binding)
+ }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UwinViewHolder {
+ return UwinViewHolder.from(parent)
+ }
+
+ override fun onBindViewHolder(holder: UwinViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+ class UwinClickListener(val clickListener: (id: Int) -> Unit) {
+ fun onClick(id: Int) = clickListener(id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/VHNCAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VHNCAdapter.kt
new file mode 100644
index 000000000..e192093bb
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VHNCAdapter.kt
@@ -0,0 +1,180 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.LayoutVhncItemBinding
+import org.piramalswasthya.sakhi.model.VHNCCache
+
+class VHNCAdapter(
+ private val clickListener: VHNCClickListener? = null,
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: VHNCCache,
+ newItem: VHNCCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: VHNCCache, newItem: VHNCCache)= oldItem == newItem
+
+
+ }
+
+ class VHNCViewHolder private constructor(private val binding: LayoutVhncItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): VHNCViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutVhncItemBinding.inflate(layoutInflater, parent, false)
+ return VHNCViewHolder(binding)
+ }
+ }
+ fun bind(item: VHNCCache, clickListener: VHNCClickListener?,) {
+ binding.vhnd = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+
+ }
+
+
+
+// private fun setFormButtonColor(formNumber: Int, item: BenWithHRPADomain, role: Int?) {
+// var hasForm: Boolean = false
+// var completelyFilled: Boolean = false
+// var formEnabled: Boolean = false
+// buttonFlexibleWidth()
+//// binding.btnForm3.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_whatsapp, 0);
+//
+//
+//// val formButton = when (formNumber) {
+//// 1 -> {
+//// binding.btnForm1.also {
+//// hasForm = item.assess != null
+//// item.assess?.let {
+//// completelyFilled =
+//// it.noOfDeliveries != null &&
+//// it.timeLessThan18m != null &&
+//// it.heightShort != null &&
+//// it.age != null &&
+//// it.rhNegative != null &&
+//// it.homeDelivery != null &&
+//// it.badObstetric != null &&
+//// it.multiplePregnancy != null
+//// }
+////
+//// formEnabled = true
+//// }
+//// }
+////
+////// 2 -> {
+////// binding.btnForm2.also {
+////// hasForm = item.mbp != null
+////// formEnabled = true
+////// }
+////// }
+//////
+////// 3 -> {
+////// binding.btnForm3.also {
+////// hasForm = item.mbp != null
+////// if (hasForm) {
+//////
+////// formEnabled = true
+////// buttonFlexibleWidth()
+//////
+////// } else {
+//////
+////// formEnabled = false
+////// (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.8f
+////// (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+//////
+////// }
+//////
+////// }
+////// }
+////
+//// else -> throw IllegalStateException("FormNumber>3")
+//// }
+//// formButton.visibility = if (formEnabled) View.VISIBLE else View.GONE
+//
+//
+//// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+//// if (hasForm) {
+//// if (completelyFilled) {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_green_dark,
+//// binding.root.context.theme
+//// )
+//// )
+//// } else {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_orange_dark,
+//// binding.root.context.theme
+//// )
+//// )
+//// }
+//// binding.btnForm3.setBackgroundColor(
+//// binding.btnForm3.resources.getColor(
+//// android.R.color.holo_purple,
+//// binding.root.context.theme
+//// )
+//// )
+////
+//// } else {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_red_light,
+//// binding.root.context.theme
+//// )
+//// )
+//// }
+////
+//// } else
+//// if (hasForm)
+//// formButton.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_green_dark))
+//// else
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_red_light,
+//// )
+//// )
+////
+//// formButton.setTextColor(
+//// binding.root.resources.getColor(
+//// com.google.android.material.R.color.design_default_color_on_primary,
+//// binding.root.context.theme
+//// )
+//// )
+//
+// }
+
+// private fun buttonFlexibleWidth() {
+// (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+// (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=0.8f
+// (binding.btnForm3.layoutParams as LinearLayout.LayoutParams).weight=1.0f
+// }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ VHNCViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: VHNCViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class VHNCClickListener(
+ private val clickedForm: ((id: Int) -> Unit)? = null
+ ) {
+ fun onClickForm1(item: VHNCCache) = clickedForm?.let { it(item.id!!) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/VHNDAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VHNDAdapter.kt
new file mode 100644
index 000000000..f1c358b3a
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VHNDAdapter.kt
@@ -0,0 +1,180 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.LayoutVhndItemBinding
+import org.piramalswasthya.sakhi.model.VHNDCache
+
+class VHNDAdapter(
+ private val clickListener: VHNDClickListener? = null,
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: VHNDCache,
+ newItem: VHNDCache
+ ) = oldItem.id == newItem.id
+
+ override fun areContentsTheSame(oldItem: VHNDCache, newItem: VHNDCache)= oldItem == newItem
+
+
+ }
+
+ class VHNDViewHolder private constructor(private val binding: LayoutVhndItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): VHNDViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutVhndItemBinding.inflate(layoutInflater, parent, false)
+ return VHNDViewHolder(binding)
+ }
+ }
+ fun bind(item: VHNDCache, clickListener: VHNDClickListener?,) {
+ binding.vhnd = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+
+ }
+
+
+
+// private fun setFormButtonColor(formNumber: Int, item: BenWithHRPADomain, role: Int?) {
+// var hasForm: Boolean = false
+// var completelyFilled: Boolean = false
+// var formEnabled: Boolean = false
+// buttonFlexibleWidth()
+//// binding.btnForm3.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_whatsapp, 0);
+//
+//
+//// val formButton = when (formNumber) {
+//// 1 -> {
+//// binding.btnForm1.also {
+//// hasForm = item.assess != null
+//// item.assess?.let {
+//// completelyFilled =
+//// it.noOfDeliveries != null &&
+//// it.timeLessThan18m != null &&
+//// it.heightShort != null &&
+//// it.age != null &&
+//// it.rhNegative != null &&
+//// it.homeDelivery != null &&
+//// it.badObstetric != null &&
+//// it.multiplePregnancy != null
+//// }
+////
+//// formEnabled = true
+//// }
+//// }
+////
+////// 2 -> {
+////// binding.btnForm2.also {
+////// hasForm = item.mbp != null
+////// formEnabled = true
+////// }
+////// }
+//////
+////// 3 -> {
+////// binding.btnForm3.also {
+////// hasForm = item.mbp != null
+////// if (hasForm) {
+//////
+////// formEnabled = true
+////// buttonFlexibleWidth()
+//////
+////// } else {
+//////
+////// formEnabled = false
+////// (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.8f
+////// (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+//////
+////// }
+//////
+////// }
+////// }
+////
+//// else -> throw IllegalStateException("FormNumber>3")
+//// }
+//// formButton.visibility = if (formEnabled) View.VISIBLE else View.GONE
+//
+//
+//// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+//// if (hasForm) {
+//// if (completelyFilled) {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_green_dark,
+//// binding.root.context.theme
+//// )
+//// )
+//// } else {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_orange_dark,
+//// binding.root.context.theme
+//// )
+//// )
+//// }
+//// binding.btnForm3.setBackgroundColor(
+//// binding.btnForm3.resources.getColor(
+//// android.R.color.holo_purple,
+//// binding.root.context.theme
+//// )
+//// )
+////
+//// } else {
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_red_light,
+//// binding.root.context.theme
+//// )
+//// )
+//// }
+////
+//// } else
+//// if (hasForm)
+//// formButton.setBackgroundColor(binding.root.resources.getColor(android.R.color.holo_green_dark))
+//// else
+//// formButton.setBackgroundColor(
+//// binding.root.resources.getColor(
+//// android.R.color.holo_red_light,
+//// )
+//// )
+////
+//// formButton.setTextColor(
+//// binding.root.resources.getColor(
+//// com.google.android.material.R.color.design_default_color_on_primary,
+//// binding.root.context.theme
+//// )
+//// )
+//
+// }
+
+// private fun buttonFlexibleWidth() {
+// (binding.btnForm2.layoutParams as LinearLayout.LayoutParams).weight=1.2f
+// (binding.btnForm1.layoutParams as LinearLayout.LayoutParams).weight=0.8f
+// (binding.btnForm3.layoutParams as LinearLayout.LayoutParams).weight=1.0f
+// }
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ VHNDViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: VHNDViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class VHNDClickListener(
+ private val clickedForm: ((id: Int) -> Unit)? = null
+ ) {
+ fun onClickForm1(item: VHNDCache) = clickedForm?.let { it(item.id!!) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/VisitsAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VisitsAdapter.kt
new file mode 100644
index 000000000..08fc872c5
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VisitsAdapter.kt
@@ -0,0 +1,39 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+
+class VisitsAdapter(
+ private val visitNumbers: List,
+ private val onVisitClick: (Int) -> Unit
+) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VisitViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_visit, parent, false)
+ return VisitViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: VisitViewHolder, position: Int) {
+ val visitNumber = visitNumbers[position]
+ holder.bind(visitNumber)
+ }
+
+ override fun getItemCount() = visitNumbers.size
+
+ inner class VisitViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ private val textView: TextView = itemView.findViewById(R.id.tvVisitNumber)
+ private val container: View = itemView.findViewById(R.id.container)
+
+ fun bind(visitNumber: Int) {
+ textView.text = "Visit $visitNumber"
+ container.setOnClickListener {
+ onVisitClick(visitNumber)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/VisitsListAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VisitsListAdapter.kt
new file mode 100644
index 000000000..c27da6014
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/VisitsListAdapter.kt
@@ -0,0 +1,60 @@
+package org.piramalswasthya.sakhi.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.databinding.RvItemVisitsBinding
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.MalariaScreeningCache
+import org.piramalswasthya.sakhi.model.getDateStrFromLong
+import org.piramalswasthya.sakhi.utils.HelperUtil
+import java.text.SimpleDateFormat
+import java.util.Locale
+
+
+class VisitsListAdapter :
+ ListAdapter(DiffCallback) {
+ private val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FollowUpViewHolder {
+ val binding = RvItemVisitsBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ return FollowUpViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: FollowUpViewHolder, position: Int) {
+ val followUp = getItem(position)
+ holder.bind(followUp)
+ }
+
+ inner class FollowUpViewHolder(private val binding: RvItemVisitsBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(followUp: MalariaScreeningCache) {
+ val ctx = binding.root.context
+ val englishArray = HelperUtil.getLocalizedResources(ctx, Languages.ENGLISH)
+ .getStringArray(R.array.dc_case_status)
+ val localizedArray = ctx.resources.getStringArray(R.array.dc_case_status)
+ val idx = englishArray.indexOf(followUp.caseStatus)
+ binding.tvVisitNumber.text = ctx.getString(R.string.visit_format, followUp.visitId)
+ binding.tvFollowUpDate.text = getDateStrFromLong(followUp.caseDate)
+ binding.tvTreatmentStatus.text = if (idx >= 0) localizedArray[idx] else localizedArray[0]
+ }
+ }
+
+ companion object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: MalariaScreeningCache, newItem: MalariaScreeningCache): Boolean {
+ return oldItem.id == newItem.id
+ }
+
+ override fun areContentsTheSame(oldItem: MalariaScreeningCache, newItem: MalariaScreeningCache): Boolean {
+ return oldItem == newItem
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/BottleAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/BottleAdapter.kt
new file mode 100644
index 000000000..64f14467e
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/BottleAdapter.kt
@@ -0,0 +1,36 @@
+package org.piramalswasthya.sakhi.adapters.dynamicAdapter
+
+import android.annotation.SuppressLint
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.model.BottleItem
+
+class BottleAdapter(private val items: List) :
+ RecyclerView.Adapter() {
+
+ inner class BottleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val tvSrNo = itemView.findViewById(R.id.tvSrNo)
+ val tvBottleNumber = itemView.findViewById(R.id.tvBottleNumber)
+ val tvDate = itemView.findViewById(R.id.tvDate)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BottleViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_bottle_row, parent, false)
+ return BottleViewHolder(view)
+ }
+
+ @SuppressLint("SetTextI18n")
+ override fun onBindViewHolder(holder: BottleViewHolder, position: Int) {
+ val item = items[position]
+ holder.tvSrNo.text = (position+1).toString()
+ holder.tvBottleNumber.text = item.bottleNumber
+ holder.tvDate.text = item.dateOfProvision
+ }
+
+ override fun getItemCount(): Int = items.size
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FilariaMdaCampaignAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FilariaMdaCampaignAdapter.kt
new file mode 100644
index 000000000..7296ce258
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FilariaMdaCampaignAdapter.kt
@@ -0,0 +1,62 @@
+package org.piramalswasthya.sakhi.adapters.dynamicAdapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.LayoutMdaCampaignItemBinding
+import org.piramalswasthya.sakhi.model.dynamicModel.MDACampaignItem
+
+class FilariaMdaCampaignAdapter (
+ private val clickListener: MdaClickListener? = null,
+) :
+ ListAdapter
+ (BenDiffUtilCallBack) {
+ private object BenDiffUtilCallBack : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: MDACampaignItem,
+ newItem: MDACampaignItem
+ ) = oldItem.srNo == newItem.srNo
+
+ override fun areContentsTheSame(oldItem: MDACampaignItem, newItem: MDACampaignItem)= oldItem == newItem
+
+
+ }
+
+ class PHCViewHolder private constructor(private val binding: LayoutMdaCampaignItemBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ companion object {
+ fun from(parent: ViewGroup): PHCViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val binding = LayoutMdaCampaignItemBinding.inflate(layoutInflater, parent, false)
+ return PHCViewHolder(binding)
+ }
+ }
+ fun bind(item: MDACampaignItem, clickListener: MdaClickListener?,) {
+ binding.phc = item
+ binding.clickListener = clickListener
+ binding.executePendingBindings()
+
+ }
+
+ }
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ) =
+ PHCViewHolder.from(parent)
+
+ override fun onBindViewHolder(holder: PHCViewHolder, position: Int) {
+ holder.bind(getItem(position), clickListener)
+ }
+
+
+ class MdaClickListener(
+ private val clickedForm: ((date: String) -> Unit)? = null
+ ) {
+ fun onClickForm1(item: MDACampaignItem) = clickedForm?.let { it(item.startDate!!) }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FollowUpVisitAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FollowUpVisitAdapter.kt
new file mode 100644
index 000000000..41b844d49
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FollowUpVisitAdapter.kt
@@ -0,0 +1,101 @@
+package org.piramalswasthya.sakhi.adapters.dynamicAdapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.databinding.ItemFollowUpHeaderBinding
+import org.piramalswasthya.sakhi.databinding.ItemFollowUpVisitBinding
+
+class FollowUpVisitAdapter : ListAdapter(
+ DiffCallback
+) {
+
+ sealed class FollowUpVisitItem {
+ object Header : FollowUpVisitItem()
+ data class VisitDate(val sno: String, val date: String) : FollowUpVisitItem()
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return when (getItem(position)) {
+ is FollowUpVisitItem.Header -> TYPE_HEADER
+ is FollowUpVisitItem.VisitDate -> TYPE_ITEM
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ TYPE_HEADER -> {
+ val binding = ItemFollowUpHeaderBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ HeaderViewHolder(binding)
+ }
+ TYPE_ITEM -> {
+ val binding = ItemFollowUpVisitBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ VisitDateViewHolder(binding)
+ }
+ else -> throw IllegalArgumentException("Unknown view type: $viewType")
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is HeaderViewHolder -> holder.bind()
+ is VisitDateViewHolder -> {
+ val item = getItem(position) as FollowUpVisitItem.VisitDate
+ holder.bind(item)
+ }
+ }
+ }
+
+ class HeaderViewHolder(private val binding: ItemFollowUpHeaderBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ fun bind() {
+ binding.executePendingBindings()
+ }
+ }
+
+ class VisitDateViewHolder(private val binding: ItemFollowUpVisitBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(item: FollowUpVisitItem.VisitDate) {
+ binding.sno = item.sno
+ binding.visitDate = item.date
+ binding.executePendingBindings()
+ }
+ }
+
+ companion object {
+ private const val TYPE_HEADER = 0
+ private const val TYPE_ITEM = 1
+
+ object DiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(oldItem: FollowUpVisitItem, newItem: FollowUpVisitItem): Boolean {
+ return when {
+ oldItem is FollowUpVisitItem.Header && newItem is FollowUpVisitItem.Header -> true
+ oldItem is FollowUpVisitItem.VisitDate && newItem is FollowUpVisitItem.VisitDate ->
+ oldItem.sno == newItem.sno && oldItem.date == newItem.date
+ else -> false
+ }
+ }
+
+ override fun areContentsTheSame(oldItem: FollowUpVisitItem, newItem: FollowUpVisitItem): Boolean {
+ return when {
+ oldItem is FollowUpVisitItem.Header && newItem is FollowUpVisitItem.Header -> true
+ oldItem is FollowUpVisitItem.VisitDate && newItem is FollowUpVisitItem.VisitDate ->
+ oldItem.sno == newItem.sno && oldItem.date == newItem.date
+ else -> false
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FormRendererAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FormRendererAdapter.kt
new file mode 100644
index 000000000..5b94f3264
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/FormRendererAdapter.kt
@@ -0,0 +1,1142 @@
+ package org.piramalswasthya.sakhi.adapters.dynamicAdapter
+
+ import android.app.AlertDialog
+ import android.app.DatePickerDialog
+ import android.content.ActivityNotFoundException
+ import android.content.Context
+ import android.content.Intent
+ import android.graphics.BitmapFactory
+ import android.graphics.Color
+ import android.graphics.Typeface
+ import android.net.Uri
+ import android.text.*
+ import android.text.style.ForegroundColorSpan
+ import android.view.*
+ import android.view.inputmethod.InputMethodManager
+ import android.util.Base64
+ import android.widget.*
+ import androidx.appcompat.content.res.AppCompatResources
+ import androidx.core.content.ContextCompat
+ import androidx.core.content.FileProvider
+ import androidx.recyclerview.widget.RecyclerView
+ import com.google.android.material.textfield.TextInputEditText
+ import com.google.android.material.textfield.TextInputLayout
+ import kotlinx.coroutines.CoroutineScope
+ import kotlinx.coroutines.Dispatchers
+ import kotlinx.coroutines.Job
+ import kotlinx.coroutines.MainScope
+ import kotlinx.coroutines.cancelChildren
+ import kotlinx.coroutines.delay
+ import kotlinx.coroutines.launch
+ import org.piramalswasthya.sakhi.R
+ import org.piramalswasthya.sakhi.configuration.dynamicDataSet.FormField
+ import org.piramalswasthya.sakhi.utils.HelperUtil
+ import org.piramalswasthya.sakhi.utils.HelperUtil.findFragmentActivity
+ import org.piramalswasthya.sakhi.utils.dynamicFormConstants.FormConstants
+ import timber.log.Timber
+ import java.io.File
+ import java.io.FileOutputStream
+ import java.text.SimpleDateFormat
+ import java.util.*
+
+ class FormRendererAdapter(
+ private val fields: MutableList,
+ private val isViewOnly: Boolean = false,
+ private val minVisitDate: Date? = null,
+ private val maxVisitDate: Date? = null,
+ private val isSNCU: Boolean = false,
+ private val onValueChanged: (FormField, Any?) -> Unit,
+ private val onShowAlert: ((String, String) -> Unit)? = null,
+ private val formId: String? =null ,
+
+
+
+ ) : RecyclerView.Adapter() {
+
+ fun getUpdatedFields(): List = fields
+
+ fun getCurrentFields(): List = fields
+ fun updateFields(newFields: List) {
+ if (fields.size != newFields.size) {
+ fields.clear()
+ fields.addAll(newFields)
+ notifyDataSetChanged()
+ return
+ }
+
+ newFields.forEachIndexed { index, newField ->
+ val oldField = fields.getOrNull(index)
+
+ val shouldUpdate = oldField == null ||
+ oldField.value != newField.value ||
+ oldField.errorMessage != newField.errorMessage ||
+ oldField.visible != newField.visible
+
+ if (shouldUpdate) {
+ fields[index] = newField
+ notifyItemChanged(index)
+ }
+ }
+ }
+
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FormViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_form_field, parent, false)
+ return FormViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: FormViewHolder, position: Int) {
+ val field = fields[position]
+ holder.itemView.visibility = View.VISIBLE
+ try {
+ holder.bind(field)
+ } catch (e: Exception) {
+ Timber.tag("FormRendererAdapter").e(e, "Error binding field: " + field.fieldId)
+ }
+ }
+
+ override fun onViewRecycled(holder: FormViewHolder) {
+ holder.clear()
+ super.onViewRecycled(holder)
+ }
+
+ override fun onViewDetachedFromWindow(holder: FormViewHolder) {
+ holder.clear()
+ super.onViewDetachedFromWindow(holder)
+ }
+
+ override fun getItemCount(): Int = fields.size
+
+ inner class FormViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ private val label: TextView = view.findViewById(R.id.tvLabel)
+ private val inputContainer: ViewGroup = view.findViewById(R.id.inputContainer)
+ private val viewHolderScope = MainScope()
+ private var muacDebounceJob: Job? = null
+
+ private fun loadImageFromPath(context: android.content.Context, filePath: String, imageView: ImageView) {
+ if (filePath.isBlank()) {
+ imageView.setImageResource(R.drawable.ic_doc_upload)
+ return
+ }
+
+ try {
+ when {
+ filePath.endsWith(".pdf", ignoreCase = true) ||
+ (filePath.startsWith("content://") &&
+ context.contentResolver.getType(Uri.parse(filePath))?.contains("pdf") == true) -> {
+ imageView.setImageResource(R.drawable.ic_doc_upload)
+ imageView.setOnClickListener {
+ val uri = Uri.parse(filePath)
+ val intent = Intent(Intent.ACTION_VIEW).apply {
+ setDataAndType(uri, "application/pdf")
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ }
+ try {
+ context.startActivity(intent)
+ } catch (e: ActivityNotFoundException) {
+ Toast.makeText(context, "No app found to open PDF", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ filePath.startsWith("JVBERi0") || filePath.startsWith("%PDF") -> {
+ imageView.setImageResource(R.drawable.ic_doc_upload)
+ imageView.setOnClickListener {
+ try {
+ val decodedBytes = Base64.decode(filePath, Base64.DEFAULT)
+ val tempPdf = File.createTempFile("decoded_pdf_", ".pdf", context.cacheDir)
+ FileOutputStream(tempPdf).use { it.write(decodedBytes) }
+
+ val uri = FileProvider.getUriForFile(
+ context,
+ "${context.packageName}.provider",
+ tempPdf
+ )
+
+ val intent = Intent(Intent.ACTION_VIEW).apply {
+ setDataAndType(uri, "application/pdf")
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ }
+ context.startActivity(intent)
+ } catch (e: Exception) {
+ Toast.makeText(context, "Failed to open PDF", Toast.LENGTH_SHORT).show()
+ Timber.e(e, "Failed to open Base64 PDF")
+ }
+ }
+ }
+
+ filePath.startsWith("data:image", ignoreCase = true) ||
+ filePath.startsWith("/9j/") ||
+ filePath.startsWith("iVBOR") ||
+ (filePath.length > 100 &&
+ !filePath.startsWith("content://") &&
+ !filePath.startsWith("file://")) -> {
+ try {
+ val base64String = filePath.substringAfter(",", filePath)
+ val decodedBytes = Base64.decode(base64String, Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size)
+ imageView.setImageBitmap(bitmap)
+ } catch (e: Exception) {
+ Timber.e(e, "Failed to decode base64 image")
+ imageView.setImageResource(R.drawable.ic_person)
+ }
+ }
+
+ else -> {
+ val uri = Uri.parse(filePath)
+ imageView.setImageURI(uri)
+ }
+ }
+ } catch (e: Exception) {
+ Timber.tag("FormRendererAdapter").e(e, "Failed to load file: $filePath")
+ imageView.setImageResource(R.drawable.ic_doc_upload)
+ }
+ }
+
+ fun clear() {
+ muacDebounceJob?.cancel()
+ muacDebounceJob = null
+ viewHolderScope.coroutineContext.cancelChildren()
+ }
+
+ fun bind(field: FormField) {
+
+ itemView.visibility = View.VISIBLE
+ if (!field.visible) {
+ itemView.visibility = View.GONE
+ return
+ } else {
+ itemView.visibility = View.VISIBLE
+ }
+ if (field.isRequired) {
+ val labelText = "${field.label} *"
+ val spannable = SpannableString(labelText)
+ spannable.setSpan(
+ ForegroundColorSpan(Color.RED),
+ labelText.length - 1,
+ labelText.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ label.text = spannable
+ } else {
+ label.text = field.label
+ }
+
+
+ inputContainer.removeAllViews()
+
+ fun addWithError(inputView: View, field: FormField) {
+ val wrapper = LinearLayout(itemView.context).apply {
+ orientation = LinearLayout.VERTICAL
+ layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+ }
+
+ wrapper.addView(inputView)
+
+ val errorTextView = TextView(itemView.context).apply {
+ tag = "field_error_tv"
+ setTextColor(android.graphics.Color.RED)
+ textSize = 12f
+ text = field.errorMessage ?: ""
+ visibility = if (field.errorMessage.isNullOrBlank()) View.GONE else View.VISIBLE
+ }
+
+ wrapper.addView(errorTextView)
+
+ inputContainer.removeAllViews()
+ inputContainer.addView(wrapper)
+
+ }
+
+
+
+
+ when (field.type) {
+ "label" -> {
+ val context = itemView.context
+ val value = field.defaultValue.toString()
+
+ if (!value.isNullOrEmpty()) {
+ val textView = TextView(context).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply {
+ setMargins(0, 16, 0, 8)
+ }
+
+ text = value
+ setTypeface(typeface, Typeface.BOLD)
+ setTextColor(ContextCompat.getColor(context, android.R.color.black))
+ setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_TitleMedium)
+ }
+
+ addWithError(textView, field)
+ }
+
+ }
+
+
+ "multicheckbox" -> {
+ val context = itemView.context
+
+ val container = LinearLayout(context).apply {
+ orientation = LinearLayout.VERTICAL
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply { setMargins(0, 8, 0, 8) }
+ }
+
+ val selectedValues: MutableSet = when (val v = field.value) {
+ is Set<*> -> v.filterIsInstance().toMutableSet()
+ is List<*> -> v.filterIsInstance().toMutableSet()
+ is String -> v.split(",").map { it.trim() }.toMutableSet()
+ else -> mutableSetOf()
+ }
+ field.options?.forEach { option ->
+ val checkBox = CheckBox(context).apply {
+ text = option.label
+ isChecked = selectedValues.contains(option.value)
+ isEnabled = !isViewOnly && field.isEditable
+ layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ).apply { setMargins(0, 4, 0, 4) }
+ }
+
+ if (!isViewOnly && field.isEditable) {
+ checkBox.setOnCheckedChangeListener { _, isChecked ->
+ if (isChecked) {
+ selectedValues.add(option.value)
+ } else {
+ selectedValues.remove(option.value)
+ }
+ field.value = selectedValues
+ onValueChanged(field, selectedValues)
+ }
+ }
+
+ container.addView(checkBox)
+ }
+
+ // Error TextView
+ val errorTextView = TextView(context).apply {
+ tag = "field_error_tv"
+ setTextColor(Color.RED)
+ textSize = 12f
+ text = field.errorMessage ?: ""
+ visibility = if (field.errorMessage.isNullOrBlank()) View.GONE else View.VISIBLE
+ }
+
+ container.addView(errorTextView)
+
+ inputContainer.removeAllViews()
+ inputContainer.addView(container)
+ }
+
+
+ "text" -> {
+ val context = itemView.context
+
+ val textInputLayout = TextInputLayout(
+ context,
+ null,
+ com.google.android.material.R.style.Widget_Material3_TextInputLayout_OutlinedBox
+ ).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply {
+ setMargins(0, 16, 0, 8)
+ }
+
+ hint = field.placeholder ?: "Enter ${field.label}"
+ boxBackgroundMode = TextInputLayout.BOX_BACKGROUND_OUTLINE
+ boxStrokeColor = ContextCompat.getColor(context, R.color.md_theme_light_primary)
+ boxStrokeWidthFocused = 2
+ setBoxCornerRadii(12f, 12f, 12f, 12f)
+ }
+
+ val editText = TextInputEditText(context).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ setPadding(32, 24, 32, 24)
+
+ background = null
+ setText(field.value as? String ?: "")
+ inputType = InputType.TYPE_CLASS_TEXT
+ isEnabled = !isViewOnly
+ setTextColor(ContextCompat.getColor(context, android.R.color.black))
+ setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyLarge)
+ }
+
+ if (!isViewOnly) {
+ editText.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+ val normalized = org.piramalswasthya.sakhi.utils.StringMappingUtil.convertDigits(s.toString())
+ val value = normalized.toFloatOrNull()
+ field.value = value
+ onValueChanged(field, s.toString())
+
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
+ })
+ }
+
+ textInputLayout.addView(editText)
+ addWithError(textInputLayout, field)
+ }
+
+
+
+ /* "number" -> {
+ val context = itemView.context
+
+ val textInputLayout = TextInputLayout(
+ context,
+ null,
+ com.google.android.material.R.style.Widget_Material3_TextInputLayout_OutlinedBox
+ ).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply {
+ setMargins(0, 16, 0, 8)
+ }
+
+ hint = field.placeholder ?: "Enter ${field.label}"
+ boxBackgroundMode = TextInputLayout.BOX_BACKGROUND_OUTLINE
+ boxStrokeColor = ContextCompat.getColor(context, R.color.md_theme_light_primary)
+ boxStrokeWidthFocused = 2
+ setBoxCornerRadii(12f, 12f, 12f, 12f)
+ }
+
+ val editText = TextInputEditText(context).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ setPadding(32, 24, 32, 24)
+
+ background = null
+ setText(field.value?.let { if (it is Number) it.toString() else it.toString() } ?: "")
+ inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
+ isEnabled = !isViewOnly
+ setTextColor(ContextCompat.getColor(context, android.R.color.black))
+ setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyLarge)
+ }
+
+ if (!isViewOnly) {
+
+ editText.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+ val normalized = org.piramalswasthya.sakhi.utils.StringMappingUtil.convertDigits(s.toString())
+ val value = normalized.toFloatOrNull()
+ field.value = value
+ if (field.fieldId.contains("muac", ignoreCase = true)) {
+ muacDebounceJob?.cancel()
+ muacDebounceJob = CoroutineScope(Dispatchers.Main).launch {
+ delay(1500)
+ onValueChanged(field, value)
+ }
+ } else {
+ onValueChanged(field, value)
+ }
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
+ })
+ }
+
+ textInputLayout.addView(editText)
+ addWithError(textInputLayout, field)
+ }*/
+ "number" -> {
+ val context = itemView.context
+
+ val textInputLayout = TextInputLayout(
+ context,
+ null,
+ com.google.android.material.R.style.Widget_Material3_TextInputLayout_OutlinedBox
+ ).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply {
+ setMargins(0, 16, 0, 8)
+ }
+
+ hint = field.placeholder ?: "Enter ${field.label}"
+ boxBackgroundMode = TextInputLayout.BOX_BACKGROUND_OUTLINE
+ boxStrokeColor = ContextCompat.getColor(context, R.color.md_theme_light_primary)
+ boxStrokeWidthFocused = 2
+ setBoxCornerRadii(12f, 12f, 12f, 12f)
+ }
+
+ val editText = TextInputEditText(context).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ setPadding(32, 24, 32, 24)
+
+ background = null
+ setText(field.value?.let { if (it is Number) it.toString() else it.toString() } ?: "")
+ inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
+
+ val isIFABottleCount = field.fieldId == "ifa_bottle_count"
+ val isEditable = !isViewOnly && !isIFABottleCount
+
+ isEnabled = isEditable
+
+ if (isIFABottleCount && !isEditable) {
+ setTextColor(ContextCompat.getColor(context, R.color.md_theme_light_onSurfaceVariant))
+ } else {
+ setTextColor(ContextCompat.getColor(context, android.R.color.black))
+ }
+
+ setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyLarge)
+ }
+
+ if (editText.isEnabled) {
+ editText.addTextChangedListener(object : TextWatcher {
+ override fun afterTextChanged(s: Editable?) {
+ val normalized = org.piramalswasthya.sakhi.utils.StringMappingUtil.convertDigits(s.toString())
+ val value = normalized.toFloatOrNull()
+ field.value = value
+ if (field.fieldId.contains("muac", ignoreCase = true)) {
+ muacDebounceJob?.cancel()
+ muacDebounceJob = viewHolderScope.launch {
+ delay(1500)
+ onValueChanged(field, value)
+ }
+ } else {
+ onValueChanged(field, value)
+ }
+ }
+
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
+ })
+ }
+
+ textInputLayout.addView(editText)
+ addWithError(textInputLayout, field)
+ }
+
+ "dropdown" -> {
+ val context = itemView.context
+ val isEditableField = field.fieldId != "visit_day" && field.isEditable && !isViewOnly
+
+ val textInputLayout = TextInputLayout(
+ context,
+ null,
+ com.google.android.material.R.style.Widget_Material3_TextInputLayout_OutlinedBox
+ ).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply {
+ setMargins(0, 16, 0, 8)
+ }
+ hint = field.placeholder ?: context.getString(R.string.dynamic_form_select, field.label)
+ boxBackgroundMode = TextInputLayout.BOX_BACKGROUND_OUTLINE
+ boxStrokeColor = ContextCompat.getColor(context, R.color.md_theme_light_primary)
+ boxStrokeWidthFocused = 2
+ setBoxCornerRadii(12f, 12f, 12f, 12f)
+ }
+
+ val editText = TextInputEditText(context).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ isFocusable = false
+ isClickable = isEditableField
+ isEnabled = isEditableField
+ val displayText = field.options?.find { it.value == field.value?.toString() }?.label
+ ?: field.value?.toString() ?: ""
+ setText(displayText)
+ background = null
+ setTextColor(ContextCompat.getColor(context, android.R.color.black))
+ setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyLarge)
+ setPadding(16, 24, 16, 24)
+ val dropdownIcon = AppCompatResources.getDrawable(
+ context,
+ R.drawable.ic_arrow_drop_down
+ )
+ dropdownIcon?.setTint(
+ ContextCompat.getColor(
+ context,
+ if (isEnabled) R.color.md_theme_light_primary else android.R.color.darker_gray
+ )
+ )
+ setCompoundDrawablesWithIntrinsicBounds(null, null, dropdownIcon, null)
+ compoundDrawablePadding = 16
+ }
+
+ if (isEditableField) {
+ editText.setOnClickListener {
+ val options = field.options ?: emptyList()
+ val labels = options.map { it.label }.toTypedArray()
+ val builder = AlertDialog.Builder(context)
+ builder.setTitle(context.getString(R.string.dynamic_form_select, field.label))
+ builder.setItems(labels) { _, which ->
+ val selected = options[which]
+ editText.setText(selected.label)
+ field.value = selected.value
+ onValueChanged(field, selected.value)
+ }
+ builder.show()
+ }
+ }
+
+ textInputLayout.addView(editText)
+ addWithError(textInputLayout, field)
+ }
+
+
+ "date" -> {
+ val context = itemView.context
+ val sdf = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val today = Calendar.getInstance().time
+ val todayStr = sdf.format(today)
+
+ if (field.fieldId == "visit_date" &&
+ (field.value == null || (field.value as? String)?.isBlank() == true)
+ ) {
+ field.value = todayStr
+ }
+
+ val isFieldDisabled = field.fieldId == "due_date"
+ val isFieldEditable = field.isEditable && !isViewOnly && !isFieldDisabled
+
+ val textInputLayout = TextInputLayout(
+ context, null,
+ com.google.android.material.R.style.Widget_Material3_TextInputLayout_OutlinedBox
+ ).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply { setMargins(0, 16, 0, 8) }
+
+ hint = field.placeholder ?: context.getString(R.string.dynamic_form_select, field.label)
+ boxBackgroundMode = TextInputLayout.BOX_BACKGROUND_OUTLINE
+ boxStrokeColor = ContextCompat.getColor(context, R.color.md_theme_light_primary)
+ boxStrokeWidthFocused = 2
+ setBoxCornerRadii(12f, 12f, 12f, 12f)
+ }
+
+ val editText = TextInputEditText(context).apply {
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ setPadding(32, 24, 32, 24)
+ background = null
+ setText(field.value as? String ?: "")
+ isFocusable = false
+ isClickable = isFieldEditable
+ isEnabled = isFieldEditable
+ setCompoundDrawablesWithIntrinsicBounds(
+ null, null,
+ ContextCompat.getDrawable(context, R.drawable.ic_calendar),
+ null
+ )
+ compoundDrawablePadding = 24
+ setTextColor(ContextCompat.getColor(context, android.R.color.black))
+ setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyLarge)
+ }
+
+ textInputLayout.addView(editText)
+
+ fun getDate(fieldId: String): Date? {
+ val v = fields.find { it.fieldId == fieldId }?.value as? String
+ return try { sdf.parse(v ?: "") } catch (e: Exception) { null }
+ }
+
+ fun setError(fieldId: String, msg: String) {
+ val f = fields.find { it.fieldId == fieldId }
+ f?.errorMessage = msg
+ val idx = fields.indexOf(f)
+ if (idx >= 0) notifyItemChanged(idx)
+ }
+
+ fun clearError(fieldId: String) {
+ val f = fields.find { it.fieldId == fieldId }
+ if (f?.errorMessage != null) {
+ f.errorMessage = null
+ val idx = fields.indexOf(f)
+ if (idx >= 0) notifyItemChanged(idx)
+ }
+ }
+
+ if (isFieldEditable) {
+ editText.setOnClickListener {
+ val activity = editText.context.findFragmentActivity()
+ ?: return@setOnClickListener
+ val originalLocale = Locale.getDefault()
+ HelperUtil.setEnLocaleForDatePicker(activity)
+
+ val calendar = Calendar.getInstance()
+
+ var minDate: Date? = null
+ var maxDate: Date? = null
+
+ if (field.fieldId == "ifa_provision_date") {
+ minDate = minVisitDate
+ maxDate = maxVisitDate
+
+ if (minDate == null) {
+ calendar.time = today
+ calendar.add(Calendar.MONTH, -2)
+ minDate = calendar.time
+ }
+ if (maxDate == null) {
+ maxDate = today
+ }
+ }
+ else {
+
+
+ if (formId == FormConstants.IFA_DISTRIBUTION_FORM_ID|| formId == FormConstants.ANC_FORM_ID || formId == FormConstants.MDA_DISTRIBUTION_FORM_ID) {
+ minDate = minVisitDate
+ maxDate = maxVisitDate
+
+ if (minDate == null) {
+ calendar.time = today
+ calendar.add(Calendar.MONTH, -2)
+ minDate = calendar.time
+ }
+ if (maxDate == null) {
+ maxDate = today
+ }
+ } else if (formId == FormConstants.PULSE_POLIO_CAMPAIGN_FORM_ID ||
+ formId == FormConstants.ORS_CAMPAIGN_FORM_ID || formId == FormConstants.LF_MDA_CAMPAIGN ) {
+ if (field.fieldId == "end_date") {
+ val startDateValue = getDate("start_date")
+ if (startDateValue != null) {
+ val minDateCalendar = Calendar.getInstance()
+ minDateCalendar.time = startDateValue
+ minDateCalendar.add(Calendar.DAY_OF_MONTH, 1)
+ minDate = minDateCalendar.time
+ } else {
+ minDate = minVisitDate
+ }
+ } else {
+ minDate = minVisitDate
+ }
+
+ maxDate = maxVisitDate
+
+ if (minDate == null) {
+ calendar.time = today
+ calendar.add(Calendar.MONTH, -2)
+ minDate = calendar.time
+ }
+ if (maxDate == null) {
+ maxDate = today
+ }
+ }
+ else{
+ minDate = when (field.fieldId) {
+ "visit_date" -> {
+ if (formId == FormConstants.HBNC_FORM_ID || formId == FormConstants.HBYC_FORM_ID) {
+ val dueDate = getDate("due_date")
+ when {
+ dueDate != null && minVisitDate != null ->
+ if (dueDate.after(minVisitDate)) dueDate else minVisitDate
+ dueDate != null -> dueDate
+ minVisitDate != null -> minVisitDate
+ else -> null
+ }
+ } else {
+ null
+ }
+ }
+ "nrc_admission_date" -> getDate("visit_date")
+ "nrc_discharge_date" -> getDate("nrc_admission_date")
+ "follow_up_visit_date" -> getDate("nrc_discharge_date")
+ else -> null
+ }
+ maxDate = today
+ }
+
+ }
+
+ DatePickerDialog(
+ context,
+ { _, year, month, dayOfMonth ->
+ try {
+ val dateStr = String.format(
+ Locale.ENGLISH,
+ "%02d-%02d-%04d",
+ dayOfMonth,
+ month + 1,
+ year
+ )
+
+ editText.setText(dateStr)
+ field.value = dateStr
+ field.errorMessage = null
+ onValueChanged(field, dateStr)
+
+ if (field.fieldId == "ifa_provision_date") {
+ val selectedDate = sdf.parse(dateStr)
+ if (minDate != null && selectedDate.before(minDate)) {
+ field.errorMessage = "Date cannot be before ${sdf.format(minDate)}"
+ } else if (maxDate != null && selectedDate.after(maxDate)) {
+ field.errorMessage = "Date cannot be after ${sdf.format(maxDate)}"
+ }
+ notifyItemChanged(adapterPosition)
+ }
+
+ if (formId == FormConstants.PULSE_POLIO_CAMPAIGN_FORM_ID ||
+ formId == FormConstants.ORS_CAMPAIGN_FORM_ID || formId == FormConstants.LF_MDA_CAMPAIGN) {
+ val selectedDate = sdf.parse(dateStr)
+ if (minDate != null && selectedDate.before(minDate)) {
+ field.errorMessage = "Date cannot be before ${sdf.format(minDate)}"
+ } else if (maxDate != null && selectedDate.after(maxDate)) {
+ field.errorMessage = "Date cannot be after ${sdf.format(maxDate)}"
+ }
+
+ if (field.fieldId == "end_date") {
+ val startDateValue = getDate("start_date")
+ if (startDateValue != null) {
+ val minEndDate = Calendar.getInstance()
+ minEndDate.time = startDateValue
+ minEndDate.add(Calendar.DAY_OF_MONTH, 1)
+ minEndDate.set(Calendar.HOUR_OF_DAY, 0)
+ minEndDate.set(Calendar.MINUTE, 0)
+ minEndDate.set(Calendar.SECOND, 0)
+ minEndDate.set(Calendar.MILLISECOND, 0)
+
+ val selectedDateCal = Calendar.getInstance()
+ selectedDateCal.time = selectedDate
+ selectedDateCal.set(Calendar.HOUR_OF_DAY, 0)
+ selectedDateCal.set(Calendar.MINUTE, 0)
+ selectedDateCal.set(Calendar.SECOND, 0)
+ selectedDateCal.set(Calendar.MILLISECOND, 0)
+
+ val startDateCal = Calendar.getInstance()
+ startDateCal.time = startDateValue
+ startDateCal.set(Calendar.HOUR_OF_DAY, 0)
+ startDateCal.set(Calendar.MINUTE, 0)
+ startDateCal.set(Calendar.SECOND, 0)
+ startDateCal.set(Calendar.MILLISECOND, 0)
+
+ if (selectedDateCal.before(minEndDate) || selectedDateCal.time == startDateCal.time) {
+ field.errorMessage = "End date must be at least 1 day after start date (${sdf.format(minEndDate.time)})"
+ }
+ }
+ }
+
+ if (field.errorMessage != null) {
+ notifyItemChanged(adapterPosition)
+ }
+ }
+
+ when (field.fieldId) {
+ "start_date" -> {
+ if (formId == FormConstants.PULSE_POLIO_CAMPAIGN_FORM_ID ||
+ formId == FormConstants.ORS_CAMPAIGN_FORM_ID) {
+ val endDateField = fields.find { it.fieldId == "end_date" }
+ if (endDateField != null) {
+ val startDateParsed = sdf.parse(dateStr)
+ if (startDateParsed != null) {
+ val minEndDate = Calendar.getInstance()
+ minEndDate.time = startDateParsed
+ minEndDate.add(Calendar.DAY_OF_MONTH, 1)
+ endDateField.validation?.minDate = sdf.format(minEndDate.time)
+ val endIdx = fields.indexOf(endDateField)
+ if (endIdx >= 0) notifyItemChanged(endIdx)
+
+ val existingEndDate = getDate("end_date")
+ if (existingEndDate != null) {
+ val existingEndDateCal = Calendar.getInstance()
+ existingEndDateCal.time = existingEndDate
+ existingEndDateCal.set(Calendar.HOUR_OF_DAY, 0)
+ existingEndDateCal.set(Calendar.MINUTE, 0)
+ existingEndDateCal.set(Calendar.SECOND, 0)
+ existingEndDateCal.set(Calendar.MILLISECOND, 0)
+
+ val startDateCal = Calendar.getInstance()
+ startDateCal.time = startDateParsed
+ startDateCal.set(Calendar.HOUR_OF_DAY, 0)
+ startDateCal.set(Calendar.MINUTE, 0)
+ startDateCal.set(Calendar.SECOND, 0)
+ startDateCal.set(Calendar.MILLISECOND, 0)
+
+ if (existingEndDateCal.before(minEndDate) || existingEndDateCal.time == startDateCal.time) {
+ setError("end_date", "End date must be at least 1 day after start date")
+ } else {
+ clearError("end_date")
+ }
+ }
+ }
+ }
+ }
+ }
+
+ "visit_date" -> {
+ val admission = fields.find { it.fieldId == "nrc_admission_date" }
+ admission?.validation?.minDate = dateStr
+ val admIdx = fields.indexOf(admission)
+ if (admIdx >= 0) notifyItemChanged(admIdx)
+ clearError("nrc_admission_date")
+ }
+
+ "nrc_admission_date" -> {
+ val discharge = fields.find { it.fieldId == "nrc_discharge_date" }
+ discharge?.validation?.minDate = dateStr
+ val disIdx = fields.indexOf(discharge)
+ if (disIdx >= 0) notifyItemChanged(disIdx)
+
+ val dischargeDate = getDate("nrc_discharge_date")
+ val admissionDate = sdf.parse(dateStr)
+
+ if (dischargeDate != null && dischargeDate.before(admissionDate)) {
+ setError("nrc_discharge_date", "Discharge cannot be before admission")
+ } else {
+ clearError("nrc_discharge_date")
+ }
+ }
+
+ "nrc_discharge_date" -> {
+ val followUp = fields.find { it.fieldId == "follow_up_visit_date" }
+ followUp?.validation?.minDate = dateStr
+ val fuIdx = fields.indexOf(followUp)
+ if (fuIdx >= 0) notifyItemChanged(fuIdx)
+
+ val followDate = getDate("follow_up_visit_date")
+ val dischargeDate = sdf.parse(dateStr)
+
+ if (followDate != null && followDate.before(dischargeDate)) {
+ setError("follow_up_visit_date", "Follow-up cannot be before discharge")
+ } else {
+ clearError("follow_up_visit_date")
+ }
+ }
+ }
+ } catch (e: Exception) {
+ Timber.tag("FormRendererAdapter").e(e, "Error in DatePicker callback for field: ${field.fieldId}")
+ }
+ },
+ calendar.get(Calendar.YEAR),
+ calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH)
+ ).apply {
+ try {
+ datePicker.minDate = 0
+ maxDate?.let { datePicker.maxDate = it.time }
+ if (minDate != null && maxDate != null && minDate.after(maxDate)) {
+ datePicker.minDate = maxDate.time
+ } else {
+ minDate?.let { datePicker.minDate = it.time }
+ }
+ } catch (e: Exception) {
+ Timber.tag("FormRendererAdapter").e(e, "Error setting date constraints for field: ${field.fieldId}")
+ }
+
+ setOnDismissListener {
+ HelperUtil.setOriginalLocaleForDatePicker(activity,originalLocale)
+ }
+
+ }.show()
+ }
+ }
+
+ addWithError(textInputLayout, field)
+ }
+
+ "radio" -> {
+ val context = itemView.context
+
+ val radioGroup = RadioGroup(context).apply {
+ orientation = RadioGroup.HORIZONTAL
+ layoutParams = LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply { setMargins(0, 8, 0, 8) }
+ }
+
+ val isFieldDisabled = field.fieldId == "discharged_from_sncu" &&
+ fields.find { it.fieldId == "is_baby_alive" }?.value == "Yes" &&
+ isSNCU
+
+ if (isFieldDisabled && field.value != "Yes") {
+ field.value = "Yes"
+ onValueChanged(field, "Yes")
+ notifyItemChanged(adapterPosition)
+ }
+
+ field.options?.forEachIndexed { index, option ->
+ val radioButton = RadioButton(context).apply {
+ id = View.generateViewId()
+ text = option.label
+ isEnabled = !isViewOnly && !isFieldDisabled
+ layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ).apply { setMargins(0, 0, if (index != field.options!!.lastIndex) 24 else 0, 0) }
+ }
+ radioGroup.addView(radioButton)
+ }
+
+ // Set checked state AFTER all buttons are added to the group
+ field.options?.forEachIndexed { index, option ->
+ val rb = radioGroup.getChildAt(index) as RadioButton
+ if (field.value?.toString() == option.value) {
+ radioGroup.check(rb.id)
+ }
+ }
+
+ if (!isViewOnly && !isFieldDisabled) {
+ radioGroup.setOnCheckedChangeListener { group, checkedId ->
+ // Clear focus from any previously focused EditText to prevent auto-scroll
+ itemView.rootView.findFocus()?.clearFocus()
+ val imm = itemView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(itemView.windowToken, 0)
+ val checkedIndex = (0 until group.childCount).firstOrNull { (group.getChildAt(it) as RadioButton).id == checkedId } ?: return@setOnCheckedChangeListener
+ val selectedOption = field.options?.getOrNull(checkedIndex) ?: return@setOnCheckedChangeListener
+ if (field.value?.toString() != selectedOption.value) {
+ field.value = selectedOption.value
+ onValueChanged(field, selectedOption.value)
+ }
+ }
+ }
+
+ val wrapper = LinearLayout(itemView.context).apply {
+ orientation = LinearLayout.VERTICAL
+ layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+ }
+ wrapper.addView(radioGroup)
+
+ val errorTextView = TextView(itemView.context).apply {
+ tag = "field_error_tv"
+ setTextColor(Color.RED)
+ textSize = 12f
+ text = field.errorMessage ?: ""
+ visibility = if (field.errorMessage.isNullOrBlank()) View.GONE else View.VISIBLE
+ }
+ wrapper.addView(errorTextView)
+
+ inputContainer.removeAllViews()
+ inputContainer.addView(wrapper)
+ }
+
+
+ "image" -> {
+ val context = itemView.context
+ val isCampaignPhotos = field.fieldId == "campaign_photos" || field.fieldId == "campaignPhotos" || field.fieldId == "mda_photos"
+
+ val container = LinearLayout(context).apply {
+ orientation = LinearLayout.VERTICAL
+ }
+
+ if (isCampaignPhotos) {
+ val imageList: List = when (val value = field.value) {
+ is List<*> -> value.filterIsInstance()
+ is Array<*> -> value.filterIsInstance().toList()
+ is String -> {
+ try {
+ val jsonArray = org.json.JSONArray(value)
+ (0 until jsonArray.length()).mapNotNull { jsonArray.optString(it).takeIf { it.isNotEmpty() } }
+ } catch (e: Exception) {
+ if (value.isNotEmpty()) listOf(value) else emptyList()
+ }
+ }
+ else -> emptyList()
+ }
+ val imagesContainer = LinearLayout(context).apply {
+ orientation = LinearLayout.HORIZONTAL
+ layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ).apply { setMargins(0, 8, 0, 8) }
+ }
+
+ imageList.takeLast(2).forEach { imagePath ->
+ val imageView = ImageView(context).apply {
+ layoutParams = LinearLayout.LayoutParams(300, 300).apply {
+ setMargins(0, 0, 8, 0)
+ }
+ scaleType = ImageView.ScaleType.CENTER_CROP
+ loadImageFromPath(context, imagePath, this)
+ }
+ imagesContainer.addView(imageView)
+ }
+
+ container.addView(imagesContainer)
+
+ if (!isViewOnly && field.isEditable) {
+ val pickButton = Button(context).apply {
+ text = context.getString(R.string.pick_image)
+ layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ).apply { setMargins(0, 8, 0, 0) }
+ setOnClickListener {
+ onValueChanged(field, "pick_image")
+ }
+ }
+ container.addView(pickButton)
+ }
+ } else {
+ val imageView = ImageView(context).apply {
+ layoutParams = LinearLayout.LayoutParams(300, 300)
+ scaleType = ImageView.ScaleType.CENTER_CROP
+
+ val filePath = field.value?.toString()
+ if (!filePath.isNullOrBlank()) {
+ loadImageFromPath(context, filePath, this)
+ } else {
+ setImageResource(R.drawable.ic_doc_upload)
+ }
+ }
+
+ val pickButton = Button(context).apply {
+ text = context.getString(R.string.pick_image)
+ isEnabled = !isViewOnly && field.isEditable
+ setOnClickListener {
+ if (!isViewOnly && field.isEditable) {
+ onValueChanged(field, "pick_image")
+ }
+ }
+ }
+
+ container.addView(imageView)
+ if (!isViewOnly && field.isEditable) container.addView(pickButton)
+ }
+
+ addWithError(container, field)
+ }
+ else -> {
+ inputContainer.addView(TextView(itemView.context).apply {
+ text = field.value?.toString() ?: ""
+ textSize = 16f
+ })
+ }
+ }
+ }
+ }
+
+ init {
+ setHasStableIds(false)
+ }
+
+
+ }
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/VisitCardAdapter.kt b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/VisitCardAdapter.kt
new file mode 100644
index 000000000..77f7faeb7
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/adapters/dynamicAdapter/VisitCardAdapter.kt
@@ -0,0 +1,148 @@
+package org.piramalswasthya.sakhi.adapters.dynamicAdapter
+
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.style.ForegroundColorSpan
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.core.content.ContextCompat
+import androidx.recyclerview.widget.RecyclerView
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.model.dynamicModel.VisitCard
+
+class VisitCardAdapter(
+ private var visits: List,
+ private var isBenDead: Boolean,
+ private val onVisitClick: (VisitCard) -> Unit
+) : RecyclerView.Adapter() {
+
+ inner class VisitViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val tvVisitDay: TextView = view.findViewById(R.id.tvVisitDay)
+ val tvVisitDate: TextView = view.findViewById(R.id.tvVisitDate)
+ val tvVisitOption: TextView = view.findViewById(R.id.tvOptionalLabel)
+ val btnView: View = view.findViewById(R.id.btnView)
+ val btnAddVisit: View = view.findViewById(R.id.btnAddVisit)
+ init {
+ btnView.setOnClickListener {
+ val position = bindingAdapterPosition
+ if (position != RecyclerView.NO_POSITION) {
+ onVisitClick(visits[position])
+ }
+ }
+ btnAddVisit.setOnClickListener {
+ val position = bindingAdapterPosition
+ if (position != RecyclerView.NO_POSITION) {
+ onVisitClick(visits[position])
+ }
+ }
+ }
+
+ }
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VisitViewHolder {
+ val view =
+ LayoutInflater.from(parent.context).inflate(R.layout.item_visit_card, parent, false)
+ return VisitViewHolder(view)
+ }
+
+ fun updateVisits(newVisits: List) {
+ visits = newVisits
+ notifyDataSetChanged()
+ }
+
+ fun updateDeathStatus(dead: Boolean) {
+ isBenDead = dead
+ notifyDataSetChanged()
+ }
+ override fun onBindViewHolder(holder: VisitViewHolder, position: Int) {
+ val visit = visits[position]
+ val ctx = holder.itemView.context
+ holder.tvVisitDay.text = when {
+ visit.visitDay.endsWith("Day") -> {
+ val englishDays = listOf("1st Day", "3rd Day", "7th Day", "14th Day", "21st Day", "28th Day", "42nd Day")
+ val localizedDays = ctx.resources.getStringArray(R.array.hbnc_visit_days)
+ val idx = englishDays.indexOf(visit.visitDay)
+ if (idx >= 0) localizedDays[idx] else visit.visitDay
+ }
+ visit.visitDay.endsWith("Months") -> {
+ val month = visit.visitDay.substringBefore(" ").toIntOrNull()
+ val localizedMonths = ctx.resources.getStringArray(R.array.hbyc_month_array)
+ val idx = if (month != null) month - 3 else -1
+ if (idx >= 0 && idx < localizedMonths.size) localizedMonths[idx] else visit.visitDay
+ }
+ else -> visit.visitDay
+ }
+ holder.tvVisitDate.text = visit.visitDate
+ holder.btnView.visibility = View.GONE
+ holder.btnAddVisit.visibility = View.GONE
+
+
+
+// holder.tvVisitOption.visibility = if (visit.visitDay in listOf("14th Day", "21st Day", "28th Day")) {
+// View.VISIBLE
+// } else {
+// View.GONE
+// }
+
+
+ holder.tvVisitOption.apply {
+
+ when (visit.visitDay) {
+ "14th Day", "21st Day", "28th Day" -> {
+ visibility = View.VISIBLE
+ text = context.getString(R.string.optional_)
+ setTextColor(context.getColor(R.color.read_only))
+ }
+ "1st Day", "3rd Day", "7th Day", "42nd Day" -> {
+ visibility = View.VISIBLE
+ val mandatoryText = context.getString(R.string.mandatory).replace("*", "")
+ val spannable = SpannableString("$mandatoryText*")
+ val redColor = ContextCompat.getColor(context, R.color.Quartenary)
+ spannable.setSpan(
+ ForegroundColorSpan(redColor),
+ spannable.length - 1,
+ spannable.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ text = spannable
+ }
+
+ }
+ }
+
+ when {
+ visit.isCompleted -> {
+ holder.btnView.visibility = View.VISIBLE
+ holder.btnView.setBackgroundResource(R.color.Quartenary)
+ holder.itemView.setBackgroundResource(R.color.md_theme_dark_inversePrimary)
+ holder.itemView.isEnabled = true
+ holder.btnView.isEnabled = true
+ }
+
+ visit.isEditable -> {
+ val enabled = !isBenDead
+ holder.itemView.isEnabled = enabled
+ holder.btnAddVisit.isEnabled = enabled
+ holder.btnView.isEnabled = enabled
+
+ holder.btnAddVisit.visibility = if (enabled) View.VISIBLE else View.GONE
+ holder.btnAddVisit.setBackgroundResource(if (enabled) R.color.Quartenary else R.color.read_only)
+ holder.itemView.setBackgroundResource(
+ if (enabled) R.color.md_theme_dark_inversePrimary else R.color.read_only
+ )
+ }
+
+
+ else -> {
+ holder.itemView.setBackgroundResource(R.color.read_only)
+ holder.itemView.isEnabled = false
+ holder.btnView.isEnabled = false
+ holder.tvVisitOption.visibility= View.GONE
+ holder.btnAddVisit.isEnabled = false
+ }
+ }
+ }
+
+ override fun getItemCount(): Int = visits.size
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/AESJEFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AESJEFormDataset.kt
new file mode 100644
index 000000000..cd3be74a9
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AESJEFormDataset.kt
@@ -0,0 +1,328 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.AESScreeningCache
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+
+class AESJEFormDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.visit_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = false
+
+ )
+ private val beneficiaryStatus = FormElement(
+ id = 2,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.beneficiary_status),
+ arrayId = R.array.benificary_case_status_kalaazar,
+ entries = resources.getStringArray(R.array.benificary_case_status_kalaazar),
+ required = true,
+ hasDependants = false
+
+ )
+ private val dateOfDeath = FormElement(
+ id = 3,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.death_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+ private val placeOfDeath = FormElement(
+ id = 4,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_Death),
+ arrayId = R.array.death_place,
+ entries = resources.getStringArray(R.array.death_place),
+ required = true,
+ hasDependants = true
+
+ )
+
+ private var otherPlaceOfDeath = FormElement(
+ id = 5,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_place),
+ required = true,
+ hasDependants = false
+ )
+
+ private val reasonOfDeath = FormElement(
+ id = 6,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.reason_of_Death),
+ arrayId = R.array.reason_death,
+ entries = resources.getStringArray(R.array.reason_death),
+ required = true,
+ hasDependants = true
+
+ )
+ private var otherReasonOfDeath = FormElement(
+ id = 7,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_reason),
+ required = true,
+ hasDependants = false
+ )
+
+
+ private val caseStatus = FormElement(
+ id = 8,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.aes_case_status_date),
+ arrayId = R.array.dc_case_status,
+ entries = resources.getStringArray(R.array.dc_case_status),
+ required = false,
+ hasDependants = true
+
+ )
+
+ private var followUpPoint = FormElement(
+ id = 9,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.follow_up),
+ arrayId = R.array.follow_up_array,
+ entries = resources.getStringArray(R.array.follow_up_array),
+ required = false,
+ hasDependants = true
+ )
+
+ private var referredTo = FormElement(
+ id = 10,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.refer_to),
+ arrayId = R.array.dc_refer,
+ entries = resources.getStringArray(R.array.dc_refer),
+ required = false,
+ hasDependants = true
+ )
+ private var other = FormElement(
+ id = 11,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other),
+ required = true,
+ hasDependants = false
+ )
+
+
+
+
+
+
+
+ suspend fun setUpPage(ben: BenRegCache?, saved: AESScreeningCache?) {
+ val list = mutableListOf(
+ dateOfCase,
+ beneficiaryStatus,
+
+
+ )
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ beneficiaryStatus.value = resources.getStringArray(R.array.benificary_case_status_kalaazar)[0]
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[0]
+ } else {
+
+ dateOfCase.value = getDateFromLong(saved.visitDate)
+
+
+ if (saved.aesJeCaseStatus != null) {
+ caseStatus.value =
+ getLocalValueInArray(R.array.dc_case_status, saved.aesJeCaseStatus)
+ }
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ list.add(list.indexOf(referredTo) + 1, other)
+ }
+ beneficiaryStatus.value =
+ getLocalValueInArray(beneficiaryStatus.arrayId, saved.beneficiaryStatus)
+ other.value = saved.otherReferredFacility
+ if (beneficiaryStatus.value == beneficiaryStatus.entries!![beneficiaryStatus.entries!!.size - 2]) {
+ list.add(list.indexOf(beneficiaryStatus) + 1, dateOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 2, placeOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 3, reasonOfDeath)
+ dateOfDeath.value =
+ getDateFromLong(saved.dateOfDeath)
+ placeOfDeath.value =
+ getLocalValueInArray(placeOfDeath.arrayId, saved.placeOfDeath)
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ otherPlaceOfDeath.value = saved.otherPlaceOfDeath
+ }
+
+ reasonOfDeath.value =
+ getLocalValueInArray(reasonOfDeath.arrayId, saved.reasonForDeath)
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ list.add(list.indexOf(reasonOfDeath) + 1, otherReasonOfDeath)
+ otherReasonOfDeath.value = saved.otherReasonForDeath
+ }
+ } else {
+ list.add(list.indexOf(beneficiaryStatus) + 1, caseStatus)
+ list.add(list.indexOf(beneficiaryStatus) + 2, followUpPoint)
+ list.add(list.indexOf(beneficiaryStatus) + 3, referredTo)
+
+
+
+
+ }
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ list.add(list.indexOf(referredTo) + 1, other)
+ }
+
+ other.value = saved.otherReferredFacility
+ }
+
+
+ setUpPage(list)
+
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ beneficiaryStatus.id -> {
+ if (beneficiaryStatus.value == beneficiaryStatus.entries!![beneficiaryStatus.entries!!.size - 2]
+ ) {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(dateOfDeath, placeOfDeath, reasonOfDeath),
+ removeItems = listOf(
+ caseStatus,followUpPoint, referredTo,
+ )
+ )
+ } else {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(
+ caseStatus, referredTo
+ ),
+ removeItems = listOf(dateOfDeath, placeOfDeath, reasonOfDeath,otherPlaceOfDeath,otherReasonOfDeath)
+ )
+ }
+ 0
+ }
+
+ referredTo.id -> {
+ if (referredTo.value == referredTo.entries!!.last()) {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(other),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(),
+ removeItems = listOf(other)
+ )
+ }
+ 0
+ }
+
+ placeOfDeath.id -> {
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(otherPlaceOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherPlaceOfDeath)
+ )
+ }
+ 0
+ }
+ otherPlaceOfDeath.id -> {
+ validateEmptyOnEditText(otherPlaceOfDeath)
+ }
+ other.id -> {
+ validateEmptyOnEditText(other)
+ }
+
+
+
+ reasonOfDeath.id -> {
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(otherReasonOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherReasonOfDeath)
+ )
+ }
+ 0
+ }
+
+ otherReasonOfDeath.id -> {
+ validateEmptyOnEditText(otherReasonOfDeath)
+ }
+ else -> {
+ -1
+ }
+ }
+ }
+
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as AESScreeningCache).let { form ->
+ form.visitDate = getLongFromDate(dateOfCase.value)
+ form.referToName = getEnglishValueInArray(referredTo.arrayId, referredTo.value) ?: referredTo.value
+ form.referredTo = referredTo.getPosition()
+ form.beneficiaryStatus = getEnglishValueInArray(beneficiaryStatus.arrayId, beneficiaryStatus.value)
+ form.beneficiaryStatusId = beneficiaryStatus.getPosition()
+ form.reasonForDeath = getEnglishValueInArray(reasonOfDeath.arrayId, reasonOfDeath.value)
+ form.aesJeCaseStatus = getEnglishValueInArray(R.array.dc_case_status, caseStatus.value)
+ form.otherPlaceOfDeath = otherPlaceOfDeath.value
+ form.otherReasonForDeath = otherReasonOfDeath.value
+ form.dateOfDeath = getLongFromDate(dateOfDeath.value)
+ form.placeOfDeath = getEnglishValueInArray(placeOfDeath.arrayId, placeOfDeath.value)
+ form.otherReferredFacility = other.value
+ form.diseaseTypeID = 3
+ form.createdDate = getLongFromDate(dateOfCase.value)
+ form.followUpPoint = followUpPoint.value?.toIntOrNull() ?: 0
+
+ }
+ }
+
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/AHDDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AHDDataset.kt
new file mode 100644
index 000000000..a85f004d4
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AHDDataset.kt
@@ -0,0 +1,174 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.AHDCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
+import org.piramalswasthya.sakhi.model.InputType.IMAGE_VIEW
+import org.piramalswasthya.sakhi.model.InputType.RADIO
+
+class AHDDataset(
+ var context: Context,
+ currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+ private val formElementList = mutableListOf()
+
+ private val mobilizedForAHD = FormElement(
+ id = 5,
+ inputType = RADIO,
+ title = resources.getString(R.string.mobilized_for_ahd),
+ entries = resources.getStringArray(R.array.yes_no_options),
+ required = true,
+ hasDependants = true
+ )
+
+ private val ahdPlace = FormElement(
+ id = 4,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.ahd_place),
+ entries = resources.getStringArray(R.array.ahd_place_options),
+ required = true,
+ isEnabled = true,
+
+ )
+
+ private val ahdDate = FormElement(
+ id = 3,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ahd_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis(),
+ max = System.currentTimeMillis(),
+ isEnabled = true
+ )
+
+ private val pic1 = FormElement(
+ id = 1,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.nbr_image),
+ subtitle = resources.getString(R.string.nbr_image_sub),
+ arrayId = -1,
+ required = false
+ )
+
+ private val pic2 = FormElement(
+ id = 2,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.nbr_image),
+ subtitle = resources.getString(R.string.nbr_image_sub),
+ arrayId = -1,
+ required = false
+ )
+
+ suspend fun setUpPage(ahd: AHDCache?) {
+
+ if (pic1.value.isNullOrBlank()) {
+ pic1.value = "default"
+ }
+
+ if (pic2.value.isNullOrBlank()) {
+ pic2.value = "default"
+ }
+ formElementList.clear()
+ val list = mutableListOf(
+ mobilizedForAHD,
+ pic1,
+ pic2
+ )
+
+ ahd?.let { loadCachedData(it,list) }
+ formElementList.addAll(list)
+ setUpPage(list)
+
+ }
+ fun getFormElementList(): List = formElementList
+
+ private fun loadCachedData(ahd: AHDCache, list: MutableList) {
+ mobilizedForAHD.value = getLocalValueInArray(R.array.yes_no_options, ahd.mobilizedForAHD)
+ ahdPlace.value = getLocalValueInArray(R.array.ahd_place_options, ahd.ahdPlace)
+ ahdDate.value = ahd.ahdDate
+ pic1.value = ahd.image1
+ pic2.value = ahd.image2
+ if(mobilizedForAHD.value == mobilizedForAHD.entries!!.first()) {
+ list.add(mobilizedForAHD.getPosition() ,ahdPlace)
+ list.add(mobilizedForAHD.getPosition() + 1,ahdDate)
+ }
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+
+ return when (formId) {
+
+ mobilizedForAHD.id -> {
+ if (mobilizedForAHD.value == mobilizedForAHD.entries!!.first()) {
+ if (!formElementList.contains(ahdPlace)) {
+ formElementList.add(ahdPlace)
+ }
+ if (!formElementList.contains(ahdDate)) {
+ formElementList.add(ahdDate)
+ }
+ }
+ else{
+ formElementList.remove(ahdPlace)
+ formElementList.remove(ahdDate)
+ }
+ triggerDependants(
+ source = mobilizedForAHD,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = listOf(ahdPlace,ahdDate),
+ )
+
+
+ }
+
+ ahdPlace.id -> validateEmptyOnSpinner(ahdPlace)
+ else -> -1
+ }
+
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as AHDCache).let { form ->
+
+ form.mobilizedForAHD = getEnglishValueInArray(R.array.yes_no_options, mobilizedForAHD.value) ?: mobilizedForAHD.value!!
+ form.ahdPlace = getEnglishValueInArray(R.array.ahd_place_options, ahdPlace.value)
+ form.ahdDate = ahdDate.value
+ form.image1 = pic1.value
+ form.image2 = pic2.value
+
+ }
+ }
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+
+ when (lastImageFormId) {
+ pic1.id -> {
+ pic1.value = dpUri.toString()
+ pic1.errorText = null
+ }
+ pic2.id -> {
+ pic2.value = dpUri.toString()
+ pic2.errorText = null
+ }
+ }
+
+
+ }
+
+ private fun validateEmptyOnSpinner(formElement: FormElement): Int {
+ if (formElement.value.isNullOrEmpty()) {
+ formElement.errorText = resources.getString(R.string.please_select_value)
+ return formElement.id
+ }
+ formElement.errorText = null
+ return -1
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/AdolescentHealthFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AdolescentHealthFormDataset.kt
new file mode 100644
index 000000000..782a90ec7
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AdolescentHealthFormDataset.kt
@@ -0,0 +1,314 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import android.text.InputType
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.AdolescentHealthCache
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.RADIO
+import org.piramalswasthya.sakhi.model.TBScreeningCache
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+class AdolescentHealthFormDataset(context: Context, language: Languages) : Dataset(context, language) {
+
+ companion object {
+ private fun getCurrentDateString(): String {
+ val calendar = Calendar.getInstance()
+ val mdFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ return mdFormat.format(calendar.time)
+ }
+
+ private fun getCurrentDateMillis(): Long {
+ return Calendar.getInstance().timeInMillis
+ }
+ }
+
+
+ private val visitDate = FormElement(
+ id = 3,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.visit_date),
+ arrayId = -1,
+ required = true,
+ max = getCurrentDateMillis()
+ )
+
+ private val healthStatus = FormElement(
+ id = 4,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.ahd_health_status),
+ arrayId = R.array.ahd_health_status_array,
+ entries = resources.getStringArray(R.array.ahd_health_status_array),
+ required = true,
+ hasDependants = true
+ )
+
+ private val ifaTabletDistribution = FormElement(
+ id = 5,
+ inputType = RADIO,
+ title = resources.getString(R.string.ahd_ifa_tablet_distribution),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true,
+ hasDependants = true
+ )
+
+ private val ifaTabletQuantity = FormElement(
+ id = 6,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.ahd_ifa_tablet_quantity),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ min = 1L,
+ max = 100L
+ )
+
+ private val menstrualHygieneAwareness = FormElement(
+ id = 7,
+ inputType = RADIO,
+ title = resources.getString(R.string.ahd_menstrual_hygiene_awareness),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false
+ )
+
+ private val sanitaryNapkinDistributed = FormElement(
+ id = 8,
+ inputType = RADIO,
+ title = resources.getString(R.string.ahd_sanitary_napkin_distributed),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true,
+ hasDependants = true
+ )
+
+ private val noOfPacketsDistributed = FormElement(
+ id = 9,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.ahd_no_of_packets_distributed),
+ arrayId = -1,
+ required = true,
+ min = 1L,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ max = 20L
+ )
+
+ private val place = FormElement(
+ id = 10,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.place),
+ arrayId = R.array.ahd_place_array,
+ entries = resources.getStringArray(R.array.ahd_place_array),
+ required = true
+ )
+
+
+ private val referredToHealthFacility = FormElement(
+ id = 12,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.ahd_referred_to_health_facility),
+ arrayId = -1,
+ required = false,
+ )
+
+ private val counselingProvided = FormElement(
+ id = 13,
+ inputType = RADIO,
+ title = resources.getString(R.string.ahd_counseling_provided),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true
+ )
+
+ private val counselingType = FormElement(
+ id = 14,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.ahd_counseling_type),
+ arrayId = R.array.ahd_counseling_type_array,
+ entries = resources.getStringArray(R.array.ahd_counseling_type_array),
+ required = false
+ )
+
+ private val followUpDate = FormElement(
+ id = 15,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ahd_follow_up_date),
+ arrayId = -1,
+ required = false,
+ max = getCurrentDateMillis()
+ )
+
+ private val referralStatus = FormElement(
+ id = 16,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.ahd_referral_status),
+ arrayId = R.array.ahd_referral_status_array,
+ entries = resources.getStringArray(R.array.ahd_referral_status_array),
+ required = false
+ )
+
+ private val sDate = FormElement(
+ id = 15,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ahd_distribution_date),
+ arrayId = -1,
+ required = false,
+ max = getCurrentDateMillis()
+ )
+
+ private val firstPage: List by lazy {
+ listOf(
+ visitDate,
+ healthStatus,
+ ifaTabletDistribution,
+ menstrualHygieneAwareness,
+ sanitaryNapkinDistributed,
+ counselingProvided,
+ counselingType,
+ followUpDate,
+ referralStatus
+ )
+ }
+
+ suspend fun setFirstPage(ben: BenRegCache?, saved: AdolescentHealthCache?) {
+ val list = firstPage.toMutableList()
+ if (visitDate.value == null) {
+ visitDate.value = getCurrentDateString()
+ }
+ saved?.let { saved ->
+ visitDate.value = saved.visitDate?.let { getDateFromLong(it) }
+ healthStatus.value = getLocalValueInArray(R.array.ahd_health_status_array, saved.healthStatus)
+ ifaTabletDistribution.value = if (saved.ifaTabletDistributed == true) ifaTabletDistribution.entries!![0] else ifaTabletDistribution.entries!![1]
+ ifaTabletQuantity.value = saved.quantityOfIfaTablets?.toString()
+ menstrualHygieneAwareness.value = if (saved.menstrualHygieneAwarenessGiven == true) menstrualHygieneAwareness.entries!![0] else menstrualHygieneAwareness.entries!![1]
+ sanitaryNapkinDistributed.value = if (saved.sanitaryNapkinDistributed == true) sanitaryNapkinDistributed.entries!![0] else sanitaryNapkinDistributed.entries!![1]
+ noOfPacketsDistributed.value = saved.noOfPacketsDistributed?.toString()
+ place.value = getLocalValueInArray(R.array.ahd_place_array, saved.place)
+ sDate.value = saved.distributionDate?.let { getDateFromLong(it) }
+ referredToHealthFacility.value = saved.referredToHealthFacility
+ counselingProvided.value = if (saved.counselingProvided == true) counselingProvided.entries!![0] else counselingProvided.entries!![1]
+ counselingType.value = getLocalValueInArray(R.array.ahd_counseling_type_array, saved.counselingType)
+ followUpDate.value = saved.followUpDate?.let { getDateFromLong(it) }
+ referralStatus.value = getLocalValueInArray(R.array.ahd_referral_status_array, saved.referralStatus)
+ }
+
+ if (ifaTabletDistribution.value == ifaTabletDistribution.entries!![0]) {
+ list.add(list.indexOf(ifaTabletDistribution) + 1, ifaTabletQuantity)
+
+ }
+
+ if (sanitaryNapkinDistributed.value == sanitaryNapkinDistributed.entries!![0]) {
+ list.add(list.indexOf(sanitaryNapkinDistributed) + 1, noOfPacketsDistributed)
+ list.add(list.indexOf(noOfPacketsDistributed) + 1, place)
+ list.add(list.indexOf(place) + 1, sDate)
+ }
+
+ if (healthStatus.value == healthStatus.entries!![1] || healthStatus.value == healthStatus.entries!![2]) {
+ referredToHealthFacility.required = true
+ list.add(list.indexOf(healthStatus) + 1, referredToHealthFacility)
+ }
+
+ setUpPage(list)
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+
+ visitDate.id -> {
+ validateEmptyOnEditText(visitDate)
+ -1
+ }
+ healthStatus.id -> {
+ referredToHealthFacility.required = (index == 1 || index == 2)
+ triggerDependants(
+ source = healthStatus,
+ addItems = if (index == 1 || index == 2) listOf(referredToHealthFacility) else emptyList(),
+ removeItems = listOf(referredToHealthFacility)
+ )
+ }
+ ifaTabletDistribution.id -> {
+ triggerDependants(
+ source = ifaTabletDistribution,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = ifaTabletQuantity
+ )
+ }
+ ifaTabletQuantity.id -> {
+ validateEmptyOnEditText(ifaTabletQuantity)
+ validateIntMinMax(ifaTabletQuantity)
+ }
+
+ sanitaryNapkinDistributed.id -> {
+ triggerDependants(
+ source = sanitaryNapkinDistributed,
+ triggerIndex = 0,
+ passedIndex = index,
+ target = listOf(noOfPacketsDistributed,place,sDate)
+
+ )
+ }
+ menstrualHygieneAwareness.id -> -1
+
+ noOfPacketsDistributed.id -> {
+ validateEmptyOnEditText(noOfPacketsDistributed)
+ validateIntMinMax(noOfPacketsDistributed)
+ }
+
+ referredToHealthFacility.id -> {
+ validateEmptyOnEditText(referredToHealthFacility)
+ }
+
+
+
+ counselingProvided.id ->-1
+ place.id -> {
+ validateEmptyOnEditText(place)
+ -1
+ }
+ counselingType.id -> -1
+ followUpDate.id -> {
+ validateEmptyOnEditText(visitDate)
+ -1
+ }
+
+ referralStatus.id -> -1
+ else -> -1
+ }
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as AdolescentHealthCache).let { ben ->
+ //ben.benId = ben.benId
+ ben.visitDate = getLongFromDate(visitDate.value)
+ ben.healthStatus = healthStatus.getEnglishStringFromPosition(healthStatus.getPosition())
+ ben.ifaTabletDistributed = ifaTabletDistribution.value == resources.getStringArray(
+ R.array.yes_no)[0]
+ ben.quantityOfIfaTablets = ifaTabletQuantity.value?.toInt()
+ ben.menstrualHygieneAwarenessGiven = menstrualHygieneAwareness.value == menstrualHygieneAwareness.entries!![0]
+ ben.sanitaryNapkinDistributed = sanitaryNapkinDistributed.value == sanitaryNapkinDistributed.entries!![0]
+ ben.noOfPacketsDistributed = noOfPacketsDistributed.value?.toInt()
+ ben.place = place.getEnglishStringFromPosition(place.getPosition())
+ ben.distributionDate = getLongFromDate(sDate.value)
+ ben.referredToHealthFacility = referredToHealthFacility.value
+ ben.counselingProvided = counselingProvided.value == counselingProvided.entries!![0]
+ ben.counselingType = counselingType.getEnglishStringFromPosition(counselingType.getPosition())
+ ben.followUpDate = getLongFromDate(followUpDate.value)
+ ben.referralStatus = referralStatus.getEnglishStringFromPosition(referralStatus.getPosition())
+ }
+ }
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/AshaProfileDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AshaProfileDataset.kt
new file mode 100644
index 000000000..f09de618a
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/AshaProfileDataset.kt
@@ -0,0 +1,498 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.ImageUtils
+import org.piramalswasthya.sakhi.helpers.Konstants
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenBasicCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.ProfileActivityCache
+import org.piramalswasthya.sakhi.model.User
+import org.piramalswasthya.sakhi.repositories.AshaProfileRepo
+import org.piramalswasthya.sakhi.utils.StringMappingUtil
+
+class AshaProfileDataset(
+ context: Context, currentLanguage: Languages,var ashaProfileRepo: AshaProfileRepo
+) : Dataset(context, currentLanguage) {
+
+ private val pic = FormElement(
+ id = 1,
+ inputType = InputType.IMAGE_VIEW,
+ title = resources.getString(R.string.nbr_image),
+ subtitle = resources.getString(R.string.nbr_image_sub),
+ arrayId = -1,
+ required = false
+ )
+
+ private var ashaName = FormElement(
+ id = 1,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.ashaname),
+ required = true,
+ allCaps = true,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+
+ )
+
+ private val village = FormElement(
+ id = 2,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.village),
+ required = false,
+ )
+
+ private val loginuserName = FormElement(
+ id = 2,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.loginusername),
+ required = false,
+ )
+
+ private val userId = FormElement(
+ id = 3,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.asha_empid),
+ required = false,
+ etMaxLength = 12
+
+ )
+
+ private val dob = FormElement(
+ id = 4,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.date_of_birth),
+ required = false,
+ max = BenGenRegFormDataset.getMaxDobMillis(),
+ min = BenGenRegFormDataset.getMinDobMillis(),
+ )
+
+ private val ages = FormElement(
+ id = 5,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.age),
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForGenBen.toLong(),
+ min = Konstants.minAgeForGenBen.toLong(),
+ )
+
+ private val mobileNumber = FormElement(
+ id = 5,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.mobile_number),
+ required = true,
+ isMobileNumber = true,
+ etMaxLength = 10,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+
+
+ )
+
+ private val alternameMobileNumber = FormElement(
+ id = 6,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.alternate_mobile_no),
+ required = false,
+ etMaxLength = 10,
+ isMobileNumber = true,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+
+ )
+
+ private val fatherOrspouse = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.father_or_spouse),
+ required = false,
+ arrayId = R.array.fathers_spouse,
+ value = resources.getStringArray(R.array.fathers_spouse)[0],
+ entries = resources.getStringArray(R.array.fathers_spouse),
+ hasDependants = true,
+ )
+
+ private val spouseOrFatherNameEdt = FormElement(
+ id = 8,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.father_or_spouse),
+ required = false,
+ arrayId = R.array.fathers_spouse,
+ hasDependants = true,
+ allCaps = true,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val dateOfJoining = FormElement(
+ id = 9,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.date_of_joining),
+ required = false,
+
+ )
+
+
+ private val bankAccount = FormElement(
+ id = 10,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.bank_acc),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 18,
+ max = 999999999999999999L,
+ min = 100000000L,
+ showDrawable = false
+ )
+ private val Ifsc = FormElement(
+ id = 11,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.ifsc_code),
+ required = false,
+ etMaxLength = 11
+ )
+ private val populationCovered = FormElement(
+ id = 12,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.population_covered_under_asha),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ required = false,
+ etMaxLength = 4,
+ )
+ private val ashaSupervisorName = FormElement(
+ id = 13,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.asha_supervisor_name),
+ required = false,
+ allCaps = true,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+
+ )
+ private val ashaSupervisorContactNumber = FormElement(
+ id = 14,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.asha_supervisor_contact_no),
+ required = false,
+ etMaxLength = 10,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+
+ )
+ private val ChoName = FormElement(
+ id = 15,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.cho_name),
+ required = false,
+ allCaps = true,
+
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ private val ChoMobileNo = FormElement(
+ id = 16,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.mobile_no_of_cho),
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 10,
+ )
+ private val nameOfAWW = FormElement(
+ id = 17,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.name_of_aww),
+ required = false,
+ allCaps = true,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ private val mobieNoOfAWW = FormElement(
+ id = 18,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.mobile_no_aww),
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 10,
+ )
+ private val nameOfANM1 = FormElement(
+ id = 19,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.name_of_anm1),
+ required = false,
+ allCaps = true,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ private val mobileNoOfANM1 = FormElement(
+ id = 20,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.mobile_number_of_anm1),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ required = false,
+ etMaxLength = 10,
+ )
+ private val nameOfANM2 = FormElement(
+ id = 21,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.name_of_anm2),
+ required = false,
+ allCaps = true,
+
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ private val mobileNoOfANM2 = FormElement(
+ id = 22,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.mobile_number_of_anm2),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ required = false,
+ etMaxLength = 10,
+ )
+ private val abhaNumber = FormElement(
+ id = 23,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.abha_number),
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 14,
+ min = 10000000000000L,
+ max = 99999999999999L
+
+
+ )
+// private val ashaHouseholdRegistrationNo = FormElement(
+// id = 24,
+// inputType = InputType.TEXT_VIEW,
+// title = "Asha Household registration",
+// required = false,
+// )
+// private val ashaFamilymember = FormElement(
+// id = 25,
+// inputType = InputType.EDIT_TEXT,
+// title = "Asha Family member",
+// required = false,
+// )
+
+
+ suspend fun setUpPage(
+ currentUser: User,
+ ashaProfile: ProfileActivityCache?,
+ ) {
+ val list = mutableListOf(
+ pic,
+ ashaName,
+ village,
+ loginuserName,
+ userId,
+ dob,
+ ages,
+ mobileNumber,
+ alternameMobileNumber,
+ fatherOrspouse,
+ spouseOrFatherNameEdt,
+ dateOfJoining,
+ bankAccount,
+ Ifsc,
+ populationCovered,
+ ashaSupervisorName,
+ ashaSupervisorContactNumber,
+ ChoName,
+ ChoMobileNo,
+ nameOfAWW,
+ mobieNoOfAWW,
+ nameOfANM1,
+ mobileNoOfANM1,
+ nameOfANM2,
+ mobileNoOfANM2,
+ abhaNumber
+// ashaHouseholdRegistrationNo,
+// ashaFamilymember
+
+
+ )
+
+ ashaName.value = ashaProfile?.name
+ pic.value = ashaProfile?.profileImage
+ village.value = currentUser.villages[0].name
+ loginuserName.value = currentUser.userName
+ userId.value = ashaProfile?.employeeId.toString()
+ mobileNumber.value = ashaProfile?.mobileNumber.toString()
+ alternameMobileNumber.value = ashaProfile?.alternateMobileNumber.toString()
+ dateOfJoining.value = ashaProfile?.dateOfJoining.toString()
+ bankAccount.value = ashaProfile?.bankAccount.toString()
+ Ifsc.value = ashaProfile?.ifsc.toString()
+ dob.value =dateFormate(ashaProfile?.dob.toString())
+ ages.value = ashaProfile?.dob?.let { BenBasicCache.getAgeFromDob(getLongFromDate(dateFormate(ashaProfile?.dob.toString()))).toString() }
+ populationCovered.value = ashaProfile?.populationCovered.toString()
+ spouseOrFatherNameEdt.value = ashaProfile?.fatherOrSpouseName.toString()
+ fatherOrspouse.value = fatherOrspouse.getStringSpauseFromPosition(if(ashaProfile?.isFatherOrSpouse==true) 1 else 0)
+ ashaSupervisorName.value = ashaProfile?.supervisorName.toString()
+ ashaSupervisorContactNumber.value = ashaProfile?.supervisorMobile.toString()
+ ChoName.value = ashaProfile?.choName.toString()
+ ChoMobileNo.value = ashaProfile?.choMobile.toString()
+ nameOfAWW.value = ashaProfile?.awwName.toString()
+ mobieNoOfAWW.value = ashaProfile?.awwMobile.toString()
+ nameOfANM1.value = ashaProfile?.anm1Name.toString()
+ mobileNoOfANM1.value = ashaProfile?.anm1Mobile.toString()
+ nameOfANM2.value = ashaProfile?.anm2Name.toString()
+ mobileNoOfANM2.value = ashaProfile?.anm2Mobile.toString()
+ abhaNumber.value = ashaProfile?.abhaNumber.toString()
+// ashaHouseholdRegistrationNo.value = ashaProfile?.ashaHouseholdRegistration.toString()
+// ashaFamilymember.value = ashaProfile?.ashaFamilyMember.toString()
+ setUpPage(list)
+
+ }
+
+
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ ashaName.id -> {
+ validateEmptyOnEditText(ashaName)
+ validateAllCapsOrSpaceOnEditText(ashaName)
+ }
+
+ spouseOrFatherNameEdt.id -> {
+ validateEmptyOnEditText(spouseOrFatherNameEdt)
+ validateAllCapsOrSpaceOnEditText(spouseOrFatherNameEdt)
+ }
+ ashaSupervisorName.id -> {
+ validateEmptyOnEditText(ashaSupervisorName)
+ validateAllCapsOrSpaceOnEditText(ashaSupervisorName)
+ }
+
+ nameOfAWW.id -> {
+ validateEmptyOnEditText(nameOfAWW)
+ validateAllCapsOrSpaceOnEditText(nameOfAWW)
+ }
+
+ nameOfANM1.id -> {
+ validateEmptyOnEditText(nameOfANM1)
+ validateAllCapsOrSpaceOnEditText(nameOfANM1)
+ }
+
+ nameOfANM2.id -> {
+ validateEmptyOnEditText(nameOfANM2)
+ validateAllCapsOrSpaceOnEditText(nameOfANM2)
+ }
+
+ ChoName.id -> {
+ validateEmptyOnEditText(ChoName)
+ validateAllCapsOrSpaceOnEditText(ChoName)
+ }
+
+ mobileNumber.id -> {
+ validateEmptyOnEditText(mobileNumber)
+ validateMobileNumberOnEditText(mobileNumber)
+ }
+ alternameMobileNumber.id -> {
+ validateEmptyOnEditText(alternameMobileNumber)
+ validateMobileNumberOnEditText(alternameMobileNumber)
+ }
+ bankAccount.id -> {
+ validateIntMinMax(bankAccount)
+ }
+ ashaSupervisorContactNumber.id -> {
+ validateEmptyOnEditText(ashaSupervisorContactNumber)
+ validateMobileNumberOnEditText(ashaSupervisorContactNumber)
+ }
+ mobileNoOfANM1.id -> {
+ validateEmptyOnEditText(mobileNoOfANM1)
+ validateMobileNumberOnEditText(mobileNoOfANM1)
+ }
+ mobileNoOfANM2.id -> {
+ validateEmptyOnEditText(mobileNoOfANM2)
+ validateMobileNumberOnEditText(mobileNoOfANM2)
+ }
+ mobieNoOfAWW.id -> {
+ validateEmptyOnEditText(mobieNoOfAWW)
+ validateMobileNumberOnEditText(mobieNoOfAWW)
+ }
+ ChoMobileNo.id -> {
+ validateEmptyOnEditText(ChoMobileNo)
+ validateMobileNumberOnEditText(ChoMobileNo)
+ }
+ Ifsc.id -> {
+ validateIFSCEditText(Ifsc)
+ }
+
+ abhaNumber.id -> {
+ validateABHANumberEditText(abhaNumber)
+
+ }
+ dob.id -> {
+ assignValuesToAgeFromDob(getLongFromDate(dob.value), ages)
+ ages.value?.takeIf { it.isNotEmpty() }?.toLong()?.let { }
+ -1
+ }
+
+ else -> 1
+ }
+ }
+
+ suspend fun mapProfileValues(cacheModel: ProfileActivityCache,context: Context){
+ (cacheModel).let { dataModel ->
+ dataModel.name = ashaName.value
+ val imageUri = pic.value?.toString() ?: ""
+ val alreadyPersisted = imageUri.isNotEmpty() &&
+ imageUri.contains(context.filesDir.absolutePath)
+ if (imageUri.isNotEmpty() && !alreadyPersisted) {
+ val persistedUri = ImageUtils.saveBenImageFromCameraToStorage(
+ context = context,
+ uriString = imageUri,
+ benId = dataModel.employeeId.toLong()
+ )
+ dataModel.profileImage = persistedUri ?: imageUri
+ pic.value = dataModel.profileImage
+ } else {
+ dataModel.profileImage = imageUri
+ }
+ dataModel.village = village.value.toString()
+ dataModel.dob = dateReverseFormat(dob.value.toString()).toString()
+ dataModel.age = ages.value!!.toInt()
+ dataModel.mobileNumber = mobileNumber.value.toString()
+ dataModel.alternateMobileNumber = StringMappingUtil.convertDigits(alternameMobileNumber.value.toString())
+ dataModel.fatherOrSpouseName = spouseOrFatherNameEdt.value.toString()
+ dataModel.supervisorName = ashaSupervisorName.value.toString()
+ dataModel.supervisorMobile = StringMappingUtil.convertDigits(ashaSupervisorContactNumber.value.toString())
+ dataModel.dateOfJoining = dateOfJoining.value.toString()
+ dataModel.bankAccount = StringMappingUtil.convertDigits(bankAccount.value.toString())
+ dataModel.ifsc = StringMappingUtil.convertDigits(Ifsc.value.toString())
+ dataModel.populationCovered = StringMappingUtil.convertDigits(populationCovered.value?.takeIf { it.isNotEmpty() })?.toIntOrNull() ?: 0
+ dataModel.choName = ChoName.value.toString()
+ dataModel.choMobile = StringMappingUtil.convertDigits(ChoMobileNo.value.toString())
+ dataModel.awwName = nameOfAWW.value.toString()
+ dataModel.awwMobile = StringMappingUtil.convertDigits(mobieNoOfAWW.value.toString())
+ dataModel.anm1Name = nameOfANM1.value.toString()
+ dataModel.anm1Mobile = StringMappingUtil.convertDigits(mobileNoOfANM1.value.toString())
+ dataModel.anm2Name = nameOfANM2.value.toString()
+ dataModel.anm2Mobile = StringMappingUtil.convertDigits(mobileNoOfANM2.value.toString())
+ dataModel.abhaNumber = StringMappingUtil.convertDigits(abhaNumber.value.toString())
+// dataModel.ashaHouseholdRegistration = ashaHouseholdRegistrationNo.value.toString()
+// dataModel.ashaFamilyMember = ashaFamilymember.value.toString()
+ dataModel.isFatherOrSpouse = when (fatherOrspouse.value) {
+ fatherOrspouse.entries!![0] -> true
+ fatherOrspouse.entries!![1] -> false
+ else -> false
+ }
+
+
+ }
+ ashaProfileRepo.postDataToAmritServer(cacheModel)
+ }
+
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+
+ }
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ pic.id -> {
+ pic.value = dpUri.toString()
+ pic.errorText = null
+ }
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenGenRegFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenGenRegFormDataset.kt
index f8d4cc351..2379cbe4f 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenGenRegFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenGenRegFormDataset.kt
@@ -34,13 +34,13 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
}
- private fun getMinDobMillis(): Long {
+ fun getMinDobMillis(): Long {
val cal = Calendar.getInstance()
cal.add(Calendar.YEAR, -1 * maxAgeForGenBen)
return cal.timeInMillis
}
- private fun getMaxDobMillis(): Long {
+ fun getMaxDobMillis(): Long {
val cal = Calendar.getInstance()
cal.add(Calendar.YEAR, -1 * minAgeForGenBen)
return cal.timeInMillis
@@ -140,7 +140,6 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
required = true,
allCaps = true,
hasSpeechToText = true,
-
etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
private val wifeName = FormElement(
@@ -191,7 +190,7 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
inputType = EDIT_TEXT,
title = resources.getString(R.string.father_s_name),
arrayId = -1,
- required = true,
+ required = false,
allCaps = true,
hasSpeechToText = true,
@@ -202,7 +201,7 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
inputType = EDIT_TEXT,
title = resources.getString(R.string.mother_s_name),
arrayId = -1,
- required = true,
+ required = false,
allCaps = true,
hasSpeechToText = true,
@@ -362,8 +361,8 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
id = 28,
inputType = DROPDOWN,
title = resources.getString(R.string.reproductive_status),
- arrayId = R.array.nbr_reproductive_status_array,
- entries = resources.getStringArray(R.array.nbr_reproductive_status_array),
+ arrayId = R.array.nbr_reproductive_status_array2,
+ entries = resources.getStringArray(R.array.nbr_reproductive_status_array2),
required = true,
hasDependants = true
)
@@ -517,11 +516,14 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
return when (formId) {
firstName.id -> {
validateEmptyOnEditText(firstName)
- validateAllCapsOrSpaceOnEditText(firstName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(firstName)
+ // validateAllCapsOrSpaceOnEditText(firstName)
+
}
lastName.id -> {
- validateAllCapsOrSpaceOnEditText(lastName)
+ // validateAllCapsOrSpaceOnEditText(lastName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(lastName)
}
dob.id -> {
@@ -597,8 +599,8 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
} else {
when (maritalStatus.value) {
maritalStatus.entries!![0] -> {
- fatherName.required = true
- motherName.required = true
+ fatherName.required = false
+ motherName.required = false
return triggerDependants(
source = maritalStatus,
addItems = emptyList(),//listOf(fatherName, motherName),
@@ -612,13 +614,8 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
}
maritalStatus.entries!![1] -> {
- if (gender.value == gender.entries!![1]) {
- fatherName.required = false
- motherName.required = false
- } else {
- fatherName.required = true
- motherName.required = true
- }
+ fatherName.required = false
+ motherName.required = false
husbandName.required = true
wifeName.required = true
return triggerDependants(
@@ -638,8 +635,8 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
else -> {
husbandName.required = maritalStatus.value != maritalStatus.entries!![2]
wifeName.required = maritalStatus.value != maritalStatus.entries!![2]
- fatherName.required = true
- motherName.required = true
+ fatherName.required = false
+ motherName.required = false
// ().let {
//// wifeName.required = it
//// husbandName.required = it
@@ -667,6 +664,7 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
ageAtMarriage.id -> age.value?.takeIf { it.isNotEmpty() && it.isDigitsOnly() && !ageAtMarriage.value.isNullOrEmpty() }
?.toInt()?.let {
validateEmptyOnEditText(ageAtMarriage)
+ ageAtMarriage.max = it.toLong()
validateIntMinMax(ageAtMarriage)
if (it == ageAtMarriage.value?.toInt()) {
val cal = Calendar.getInstance()
@@ -685,27 +683,32 @@ class BenGenRegFormDataset(context: Context, language: Languages) : Dataset(cont
fatherName.id -> {
validateEmptyOnEditText(fatherName)
- validateAllCapsOrSpaceOnEditText(fatherName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(fatherName)
+ // validateAllCapsOrSpaceOnEditText(fatherName)
}
motherName.id -> {
validateEmptyOnEditText(motherName)
- validateAllCapsOrSpaceOnEditText(motherName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(motherName)
+ // validateAllCapsOrSpaceOnEditText(motherName)
}
husbandName.id -> {
validateEmptyOnEditText(husbandName)
- validateAllCapsOrSpaceOnEditText(husbandName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(husbandName)
+ // validateAllCapsOrSpaceOnEditText(husbandName)
}
wifeName.id -> {
validateEmptyOnEditText(wifeName)
- validateAllCapsOrSpaceOnEditText(wifeName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(wifeName)
+ // validateAllCapsOrSpaceOnEditText(wifeName)
}
spouseName.id -> {
validateEmptyOnEditText(spouseName)
- validateAllCapsOrSpaceOnEditText(spouseName)
+ //validateAllCapsOrSpaceOnEditText(spouseName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(spouseName)
}
contactNumber.id -> {
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegCHODataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegCHODataset.kt
index 614f586b5..22af0f932 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegCHODataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegCHODataset.kt
@@ -131,11 +131,13 @@ class BenRegCHODataset(
}
name.id -> {
- validateAllCapsOrSpaceOnEditText(name)
+ // validateAllCapsOrSpaceOnEditText(name)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(name)
}
husbandName.id -> {
- validateAllCapsOrSpaceOnEditText(husbandName)
+ // validateAllCapsOrSpaceOnEditText(husbandName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(husbandName)
}
age.id -> {
@@ -171,7 +173,7 @@ class BenRegCHODataset(
if (isPregnant.value == resources.getStringArray(R.array.yes_no)[0]) {
form.genDetails?.let {
it.reproductiveStatus =
- englishResources.getStringArray(R.array.nbr_reproductive_status_array)[1]
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
it.reproductiveStatusId = 2
}
form.processed = "N"
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegFormDataset.kt
index 5b4a27c4d..57909bffc 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/BenRegFormDataset.kt
@@ -3,15 +3,23 @@ package org.piramalswasthya.sakhi.configuration
import android.content.Context
import android.net.Uri
import android.text.InputType
+import android.util.Log
import android.util.Range
import android.widget.LinearLayout
+import org.piramalswasthya.sakhi.BuildConfig
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.room.SyncState
import org.piramalswasthya.sakhi.helpers.Konstants
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
import org.piramalswasthya.sakhi.model.AgeUnit
import org.piramalswasthya.sakhi.model.BenBasicCache.Companion.getAgeFromDob
+import org.piramalswasthya.sakhi.model.BenBasicCache.Companion.getYearsFromDate
import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.BenStatus
+import org.piramalswasthya.sakhi.model.EligibleCoupleRegCache
import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.Gender
import org.piramalswasthya.sakhi.model.Gender.FEMALE
@@ -22,10 +30,15 @@ import org.piramalswasthya.sakhi.model.InputType.CHECKBOXES
import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.FILE_UPLOAD
import org.piramalswasthya.sakhi.model.InputType.IMAGE_VIEW
import org.piramalswasthya.sakhi.model.InputType.RADIO
import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
+import org.piramalswasthya.sakhi.ui.home_activity.all_ben.new_ben_registration.ben_form.NewBenRegViewModel.Companion.isOtpVerified
+import java.lang.IllegalStateException
import java.text.SimpleDateFormat
+import java.time.LocalDate
+import java.time.ZoneId
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
@@ -34,6 +47,24 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
companion object {
+ fun calculateMaxSonAge(
+ parentYears: Int,
+ parentMonths: Int,
+ marriageYears: Int,
+ marriageMonths: Int
+ ): Pair {
+ val parentTotalMonths = parentYears * 12 + parentMonths
+ val bufferTotalMonths = marriageYears * 12 + marriageMonths
+
+ val diffMonths = (parentTotalMonths - bufferTotalMonths).coerceAtLeast(0)
+
+ val years = diffMonths / 12
+ val months = diffMonths % 12
+
+ return Pair(years, months)
+ }
+
+
private fun getCurrentDateString(): String {
val calendar = Calendar.getInstance()
val mdFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
@@ -46,6 +77,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
return cal.timeInMillis
}
+
private fun getHoFMinDobMillis(): Long {
val cal = Calendar.getInstance()
cal.add(Calendar.YEAR, -1 * Konstants.maxAgeForGenBen)
@@ -58,13 +90,24 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
return cal.timeInMillis
}
+ private fun getAgeStringFromDob(dob: Long): String {
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = dob
+ val ageUnitDTO = org.piramalswasthya.sakhi.model.AgeUnitDTO(0, 0, 0)
+ org.piramalswasthya.sakhi.utils.HelperUtil.updateAgeDTO(ageUnitDTO, cal)
+ return org.piramalswasthya.sakhi.utils.HelperUtil.getAgeStrFromAgeUnit(ageUnitDTO)
+ }
}
private var familyHeadPhoneNo: String? = null
private var timeStampDateOfMarriageFromSpouse: Long? = null
private var isHoF: Boolean = false
+ private var isAddSppouse: Int = 0
+
+ private var isAddSpouse: Boolean = false
private var hof: BenRegCache? = null
+ private var benIfDataExist: BenRegCache? = null
private var minAgeYear: Int = 0
private var maxAgeYear: Int = Konstants.maxAgeForGenBen
@@ -109,16 +152,6 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
hasSpeechToText = true,
etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS,
)
-
- // val ageUnit = FormElement(
-// id = 5,
-// inputType = DROPDOWN,
-// title = resources.getString(R.string.nbr_nb_age_unit),
-// arrayId = -1,
-// entries = resources.getStringArray(R.array.nbr_age_unit_array),
-// required = true,
-// hasDependants = true,
-// )
private val agePopup = FormElement(
id = 115,
inputType = org.piramalswasthya.sakhi.model.InputType.AGE_PICKER,
@@ -129,30 +162,15 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
allCaps = true,
hasSpeechToText = true,
hasDependants = true,
- etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL
+ )
+ private val dobReadOnly = FormElement(
+ id = 116,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.nbr_dob),
+ required = false,
)
- // val age = FormElement(
-// id = 7,
-// inputType = EDIT_TEXT,
-// title = resources.getString(R.string.nbr_age),
-// arrayId = -1,
-// required = true,
-// hasDependants = true,
-// etMaxLength = 2,
-// etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
-// max = Konstants.maxAgeForGenBen.toLong(),
-// min = Konstants.minAgeForGenBen.toLong(),
-// )
-// val dob = FormElement(
-// id = 8,
-// inputType = DATE_PICKER,
-// title = resources.getString(R.string.nbr_dob),
-// arrayId = -1,
-// required = true,
-// showYearFirstInDatePicker = true,
-// hasDependants = true,
-// )
val gender = FormElement(
id = 9,
inputType = RADIO,
@@ -208,10 +226,10 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
hasSpeechToText = true,
etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
- private val ageAtMarriage = FormElement(
+ var ageAtMarriage = FormElement(
id = 1012,
inputType = EDIT_TEXT,
- title = resources.getString(R.string.age_at_marriage),
+ title = resources.getString(R.string.age_at_marriagee),
etMaxLength = 2,
arrayId = -1,
required = true,
@@ -235,7 +253,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
inputType = EDIT_TEXT,
title = resources.getString(R.string.nbr_father_name),
arrayId = -1,
- required = true,
+ required = false,
allCaps = true,
hasSpeechToText = true,
etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
@@ -245,7 +263,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
inputType = EDIT_TEXT,
title = resources.getString(R.string.nbr_mother_name),
arrayId = -1,
- required = true,
+ required = false,
allCaps = true,
hasSpeechToText = true,
etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
@@ -364,6 +382,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
)
+
val rchId = FormElement(
id = 23,
inputType = EDIT_TEXT,
@@ -404,12 +423,13 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
private val reproductiveStatus = FormElement(
id = 1028,
- inputType = DROPDOWN,
+ inputType = TEXT_VIEW,
title = resources.getString(R.string.reproductive_status),
- arrayId = R.array.nbr_reproductive_status_array,
- entries = resources.getStringArray(R.array.nbr_reproductive_status_array),
+ arrayId = R.array.nbr_reproductive_status_array2,
+ entries = resources.getStringArray(R.array.nbr_reproductive_status_array2),
required = true,
- hasDependants = false
+ hasDependants = false,
+// isEnabled = false
)
private val birthCertificateNumber = FormElement(
id = 1029,
@@ -418,6 +438,91 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
arrayId = -1,
required = false,
)
+
+ private val sendOtpBtn = FormElement(
+ id = 42,
+ inputType = org.piramalswasthya.sakhi.model.InputType.BUTTON,
+ title = resources.getString(R.string.send_otp),
+ required = false,
+ isEnabled = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = false,
+ )
+
+ private val otpField = FormElement(
+ id = 43,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.enter_otp),
+ arrayId = -1,
+ required = false,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = false,
+ etMaxLength = 6,
+ max = 9999999999,
+ min = 6000000000
+ )
+ private val tempraryContactNo = FormElement(
+ id = 44,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.contact_number),
+ arrayId = -1,
+ required = false,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 10,
+ max = 9999999999,
+ min = 6000000000
+ )
+
+ private val tempraryContactNoBelongsto = FormElement(
+ id = 45,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.nbr_mobile_number_of),
+ arrayId = R.array.temp_mobile_no_relation_array,
+ entries = resources.getStringArray(R.array.temp_mobile_no_relation_array),
+ required = false,
+ hasDependants = true,
+ )
+
+ private val headLine = FormElement(
+ id = 45,
+ inputType = org.piramalswasthya.sakhi.model.InputType.HEADLINE,
+ title = resources.getString(R.string.cr_birth_cert_uploads),
+ headingLine = false,
+ required = false,
+ )
+ private val fileUploadFront = FormElement(
+ id = 46,
+ inputType = FILE_UPLOAD,
+ title = resources.getString(R.string.front_side),
+ required = false,
+ )
+ private val fileUploadBack = FormElement(
+ id = 47,
+ inputType = FILE_UPLOAD,
+ title = resources.getString(R.string.back_side),
+ required = false,
+ )
+
+ private val haveChildren = FormElement(
+ id = 48,
+ inputType = RADIO,
+ title = resources.getString(R.string.childrens),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true,
+ hasDependants = true,
+ )
+ fun getIndexOfBirthCertificateFrontPath() = getIndexById(fileUploadFront.id)
+ fun getIndexOfBirthCertificateBackPath() = getIndexById(fileUploadBack.id)
+
+ private val _isAddingChildren = MutableStateFlow(false)
+ val isAddingChildren = _isAddingChildren.asStateFlow()
+
+ fun setIsAddingChildren(value: Boolean) {
+ _isAddingChildren.value = value
+ }
+
val firstPage by lazy {
listOf(
pic,
@@ -425,9 +530,6 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
firstName,
lastName,
agePopup,
-// dob,
-// age,
-// ageUnit,
gender,
fatherName,
motherName,
@@ -446,9 +548,6 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
firstName,
lastName,
agePopup,
-// dob,
-// age,
-// ageUnit,
gender,
maritalStatus,
fatherName,
@@ -459,30 +558,36 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
community,
religion,
rchId,
-// hasAadharNo,
)
+
this.familyHeadPhoneNo = familyHeadPhoneNo?.toString()
+
ben?.takeIf { !it.isDraft }?.let { saved ->
+
+ if (ben.isDeath) {
+ initializeDeathFields(list, saved, list.indexOf(lastName))
+ }
+
pic.value = saved.userImage
dateOfReg.value = getDateFromLong(saved.regDate)
firstName.value = saved.firstName
lastName.value = saved.lastName
agePopup.value = getDateFromLong(saved.dob)
-// dob.value = getDateFromLong(saved.dob)
-// age.value = getAgeFromDob(saved.dob).toString()
-// ageUnit.value = ageUnit.getStringFromPosition(saved.ageUnitId)
+ fileUploadFront.value = saved?.kidDetails?.birthCertificateFileFrontView
+ fileUploadBack.value = saved?.kidDetails?.birthCertificateFileBackView
gender.value = gender.getStringFromPosition(saved.genderId)
- gender.inputType = TEXT_VIEW
+// gender.inputType = TEXT_VIEW
+
fatherName.value = saved.fatherName
- saved.fatherName?.let {
- if (it.isNotEmpty()) fatherName.inputType = TEXT_VIEW
- }
+ saved.fatherName?.takeIf { it.isNotEmpty() }?.let { fatherName.inputType = TEXT_VIEW }
+
motherName.value = saved.motherName
- saved.motherName?.let {
- if (it.isNotEmpty()) motherName.inputType = TEXT_VIEW
+ saved.motherName?.takeIf { it.isNotEmpty() }?.let { motherName.inputType = TEXT_VIEW }
+
+ if (saved.isSpouseAdded || saved.isChildrenAdded || saved.doYouHavechildren) {
+ maritalStatus.inputType = TEXT_VIEW
}
saved.genDetails?.spouseName?.let {
- maritalStatus.inputType = TEXT_VIEW
when (saved.genderId) {
1 -> {
wifeName.value = it
@@ -500,6 +605,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
}
}
}
+
maritalStatus.entries = when (saved.gender) {
MALE -> maritalStatusMale
FEMALE -> maritalStatusFemale
@@ -511,125 +617,130 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
else -> R.array.nbr_marital_status_male_array
}
maritalStatus.value =
- maritalStatus.getStringFromPosition(saved.genDetails?.maritalStatusId ?: 0)
- ageAtMarriage.value = saved.genDetails?.ageAtMarriage.toString()
- dateOfMarriage.value = getDateFromLong(
- saved.genDetails?.marriageDate ?: 0
- )
+ saved.genDetails?.maritalStatusId?.let { maritalStatus.getStringFromPosition(it) }
+
+ ageAtMarriage.value = calculateAgeAtMarriage(saved.dob, saved.genDetails?.marriageDate)?.toString()
+ dateOfMarriage.value = getDateFromLong(saved.genDetails?.marriageDate ?: 0)
+
mobileNoOfRelation.value =
mobileNoOfRelation.getStringFromPosition(saved.mobileNoOfRelationId)
otherMobileNoOfRelation.value = saved.mobileOthers
contactNumber.value = saved.contactNumber.toString()
- relationToHead.value = relationToHeadListDefault[saved.familyHeadRelationPosition - 1]
+
+ val relationIndex = (saved.familyHeadRelationPosition - 1).coerceIn(
+ 0,
+ relationToHeadListDefault.lastIndex
+ )
+ relationToHead.value = relationToHeadListDefault.getOrNull(relationIndex)
+
otherRelationToHead.value = saved.familyHeadRelationOther
community.value = community.getStringFromPosition(saved.communityId)
religion.value = religion.getStringFromPosition(saved.religionId)
otherReligion.value = saved.religionOthers
+
childRegisteredAtAwc.value = childRegisteredAtAwc.getStringFromPosition(
saved.kidDetails?.childRegisteredSchoolId ?: 0
)
-// saved.kidDetails?.childRegisteredAWCId?.takeIf { it > 0 }
-// ?.let { childRegisteredAtAwc.entries?.get(it - 1) }
childRegisteredAtSchool.value = childRegisteredAtSchool.getStringFromPosition(
saved.kidDetails?.childRegisteredSchoolId ?: 0
)
-// saved.kidDetails?.childRegisteredSchoolId?.takeIf { it > 0 }
-// ?.let { childRegisteredAtSchool.entries?.get(it - 1) }
typeOfSchool.value =
typeOfSchool.getStringFromPosition(saved.kidDetails?.typeOfSchoolId ?: 0)
-// saved.kidDetails?.typeOfSchoolId?.takeIf { it > 0 }
-// ?.let { typeOfSchool.entries?.get(it - 1) }
rchId.value = saved.rchId
-
-// relationToHead.entries = when (saved.gender) {
-// MALE -> relationToHeadListMale
-// FEMALE -> relationToHeadListFemale
-// TRANSGENDER -> relationToHeadListDefault
-// null -> null
-// }
-// relationToHead.arrayId = when (saved.gender) {
-// MALE -> R.array.nbr_relationship_to_head_male
-// FEMALE -> R.array.nbr_relationship_to_head_female
-// TRANSGENDER -> R.array.nbr_relationship_to_head
-// null -> -1
+ reproductiveStatus.value = saved.genDetails?.reproductiveStatus
+// reproductiveStatus.value = saved.genDetails?.reproductiveStatusId?.let {
+// reproductiveStatus.getStringFromPosition(it)
// }
-// hasAadharNo.value = hasAadharNo.getStringFromPosition(saved.hasAadharId)
-// aadharNo.value = saved.aadharNum
- rchId.value = saved.rchId
- reproductiveStatus.value = saved.genDetails?.reproductiveStatusId?.let {
- reproductiveStatus.getStringFromPosition(it)
+
+ // Restore haveChildren value for married females
+ val maritalStatusIdForChildren = saved.genDetails?.maritalStatusId
+ if (saved.genderId == 2 && maritalStatusIdForChildren != null && maritalStatusIdForChildren >= 2) {
+ haveChildren.value = if (saved.doYouHavechildren) haveChildren.entries?.get(0) else haveChildren.entries?.get(1)
+ _isAddingChildren.value = saved.doYouHavechildren
}
}
- if (maritalStatus.value != null && maritalStatus.value != maritalStatus.entries!![0] && gender.value != null) {
-// if(maritalStatus.value ==maritalStatus.entries!![1])
-// list.removeAll(listOf(fatherName, motherName))
- list.add(
- list.indexOf(maritalStatus) + 3, when (gender.value) {
- gender.entries!![0] -> wifeName
- gender.entries!![1] -> husbandName
- gender.entries!![2] -> spouseName
- else -> throw java.lang.IllegalStateException("Gender unspecified with non empty marital status value!")
+
+ val maritalIndex = list.indexOf(maritalStatus)
+ if (!maritalStatus.value.isNullOrEmpty() && maritalStatus.entries != null && gender.value != null && maritalIndex >= 0 && maritalStatus.value == maritalStatus.getStringFromPosition(2)) {
+ val genderField = when (gender.value) {
+ gender.entries!![0] -> wifeName
+ gender.entries!![1] -> husbandName
+ gender.entries!![2] -> spouseName
+ else -> null
+ }
+ genderField?.let {
+ list.add(maritalIndex + 3, it)
+ list.add(maritalIndex + 4, ageAtMarriage)
+ // Add haveChildren for females (gender.entries!![1])
+ if (gender.value == gender.entries!![1]) {
+ list.add(maritalIndex + 5, haveChildren)
}
- )
- list.add(
- list.indexOf(maritalStatus) + 4,
- ageAtMarriage
- )
+ }
+ } else {
+ listOf(
+ husbandName,
+ wifeName,
+ spouseName,
+ ageAtMarriage
+ ).forEach { list.remove(it) }
}
- if (maritalStatus.value == maritalStatus.entries!![1] && gender.value == gender.entries!![1]) {
+
+ if (maritalStatus.entries != null && maritalStatus.value == maritalStatus.entries!![1] && gender.value == gender.entries!![1]) {
fatherName.required = false
motherName.required = false
-
}
- if (maritalStatus.value == maritalStatus.entries!![2]) {
+
+ if (maritalStatus.entries != null && maritalStatus.value == maritalStatus.entries!![2]) {
husbandName.required = false
wifeName.required = false
spouseName.required = false
-
}
+
ageAtMarriage.value?.takeIf {
- it.isNotEmpty() && it == (getAgeFromDob(
- getLongFromDate(agePopup.value)
- )).toString()
+ it.isNotEmpty() && it == getAgeFromDob(getLongFromDate(agePopup.value)).toString()
}?.let {
- if (!list.contains(dateOfMarriage))
- list.add(list.indexOf(ageAtMarriage) + 1, dateOfMarriage)
+ if (!list.contains(dateOfMarriage)) {
+ val ageIndex = list.indexOf(ageAtMarriage)
+ if (ageIndex >= 0) list.add(ageIndex + 1, dateOfMarriage)
+ }
}
- if (mobileNoOfRelation.value == mobileNoOfRelation.entries!!.last()) {
- list.add(list.indexOf(mobileNoOfRelation) + 1, otherMobileNoOfRelation)
+
+ val mobileIndex = list.indexOf(mobileNoOfRelation)
+ if (mobileNoOfRelation.entries != null && mobileNoOfRelation.value == mobileNoOfRelation.entries!!.last() && mobileIndex >= 0) {
+ list.add(mobileIndex + 1, otherMobileNoOfRelation)
}
- if (relationToHead.value == relationToHead.entries!!.last()) {
- list.add(list.indexOf(relationToHead) + 1, otherRelationToHead)
+
+ val relationHeadIndex = list.indexOf(relationToHead)
+ if (relationToHead.entries != null && relationToHead.value == relationToHead.entries!!.last() && relationHeadIndex >= 0) {
+ list.add(relationHeadIndex + 1, otherRelationToHead)
}
- if (religion.value == religion.entries!![7]) {
- list.add(list.indexOf(religion) + 1, otherReligion)
+
+ val religionIndex = list.indexOf(religion)
+ if (religion.entries != null && religion.value == religion.entries!![7] && religionIndex >= 0) {
+ list.add(religionIndex + 1, otherReligion)
}
-// if (ageUnit.value == ageUnit.entries?.last() && (age.value?.toInt() ?: 0) in 3..5) {
-// list.add((list.indexOf(rchId)), childRegisteredAtAwc)
-// }
- if ((getAgeFromDob(getLongFromDate(agePopup.value))) in 4..14) {
- list.add((list.indexOf(rchId)), childRegisteredAtSchool)
+
+ val dob = agePopup.value?.takeIf { it.isNotEmpty() }?.let { getLongFromDate(it) }
+ val rchIndex = list.indexOf(rchId)
+ if (dob != null && getAgeFromDob(dob) in 4..14 && rchIndex >= 0) {
+ list.add(rchIndex, childRegisteredAtSchool)
}
- if (childRegisteredAtSchool.value == childRegisteredAtSchool.entries?.first()) list.add(
- list.indexOf(
- childRegisteredAtSchool
- ) + 1, typeOfSchool
- )
+
+ val schoolIndex = list.indexOf(childRegisteredAtSchool)
+ if (childRegisteredAtSchool.entries != null && childRegisteredAtSchool.value == childRegisteredAtSchool.entries?.first() && schoolIndex >= 0) {
+ list.add(schoolIndex + 1, typeOfSchool)
+ }
+
+
birthCertificateNumber.value = ben?.kidDetails?.birthCertificateNumber
placeOfBirth.value =
ben?.kidDetails?.birthPlaceId?.let { placeOfBirth.getStringFromPosition(it) }
-// if (hasAadharNo.value == hasAadharNo.entries!!.first()) {
-// aadharNo.inputType = TEXT_VIEW
-// list.add(
-// list.indexOf(hasAadharNo) + 1, aadharNo
-// )
-// }
- if (hasThirdPage())
- list.add(reproductiveStatus)
+
+ if (hasThirdPage()) list.add(reproductiveStatus)
+
if (isKid()) {
- list.removeAll(
- listOf(
+ listOf(
maritalStatus,
husbandName,
wifeName,
@@ -637,32 +748,61 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
ageAtMarriage,
dateOfMarriage,
reproductiveStatus
- )
- )
+ ).forEach { list.remove(it) }
list.addAll(
listOf(
birthCertificateNumber,
- placeOfBirth
+ placeOfBirth,
+ headLine,
+ fileUploadFront,
+ fileUploadBack
)
)
}
- if (!isKid() and !hasThirdPage()) {
+
+ if (!isKid() && !hasThirdPage()) {
list.remove(rchId)
}
setUpPage(list)
}
+ private fun calculateMarriageDate(marriageAge: Int, dob: Long): Long {
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = dob
+ calendar.add(Calendar.YEAR, marriageAge)
+ return calendar.timeInMillis
+ }
+
+ private fun calculateAgeAtMarriage(dob: Long, marriageDate: Long?): Int? {
+ if (marriageDate == null || marriageDate <= 0L) return null
+ val doB = Calendar.getInstance()
+ doB.timeInMillis = dob
+ val marriageDatE = Calendar.getInstance()
+ marriageDatE.timeInMillis = marriageDate
+ var ageAtMarriage = marriageDatE.get(Calendar.YEAR) - doB.get(Calendar.YEAR)
+ if (marriageDatE.get(Calendar.DAY_OF_YEAR) < doB.get(Calendar.DAY_OF_YEAR)) {
+ ageAtMarriage--
+ }
+ Log.d("marriage age", ageAtMarriage.toString())
+ return ageAtMarriage.takeIf { it >= Konstants.minAgeForMarriage }
+ }
+
+
+ private val isMitaninVariant = BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)
+
suspend fun setPageForHof(ben: BenRegCache?, household: HouseholdCache) {
val list = mutableListOf(
pic,
dateOfReg,
firstName,
lastName,
+ )
+ if (!isMitaninVariant) {
+ list.addAll(listOf(tempraryContactNo, tempraryContactNoBelongsto, sendOtpBtn))
+ }
+ list.addAll(listOf(
agePopup,
-// dob,
-// age,
-// ageUnit,
gender,
maritalStatus,
fatherName,
@@ -671,55 +811,87 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
community,
religion,
rchId,
-// hasAadharNo,
- )
+ ))
this.familyHeadPhoneNo = household.family?.familyHeadPhoneNo?.toString()
+ if (!isMitaninVariant) {
+ tempraryContactNoBelongsto.value =
+ tempraryContactNoBelongsto.getStringFromPosition(1)
+ tempraryContactNo.value = familyHeadPhoneNo
+ }
this.isHoF = true
if (dateOfReg.value == null)
dateOfReg.value = getCurrentDateString()
contactNumber.value = familyHeadPhoneNo
+// household.family?.let {
+// firstName.value = it.familyHeadName?.also {
+// firstName.inputType = TEXT_VIEW
+// }
+//
+// lastName.value = it.familyName?.also {
+// lastName.inputType = TEXT_VIEW
+// }
+//
+// contactNumber.value = it.familyHeadPhoneNo?.toString()?.also {
+// contactNumber.inputType = TEXT_VIEW
+// }
+// }
household.family?.let {
- firstName.value = it.familyHeadName?.also {
- firstName.inputType = TEXT_VIEW
- }
- lastName.value = it.familyName/*?.also {
- lastName.inputType = TEXT_VIEW
- }*/
- contactNumber.value = it.familyHeadPhoneNo?.toString()?.also {
- contactNumber.inputType = TEXT_VIEW
- }
+ firstName.value = it.familyHeadName
+
+ lastName.value = it.familyName
+
+ contactNumber.value = it.familyHeadPhoneNo?.toString()
}
agePopup.min = getHoFMinDobMillis()
agePopup.max = getHofMaxDobMillis()
+ ben?.takeIf { !it.isDraft }?.let { saved ->
+ list.add(list.indexOf(lastName) + 1, beneficiaryStatus)
+ if (saved.isDeath) {
+ list.add(list.indexOf(beneficiaryStatus) + 1, dateOfDeath)
+ list.add(list.indexOf(dateOfDeath) + 1, timeOfDeath)
+ list.add(list.indexOf(timeOfDeath) + 1, reasonOfDeath)
+ list.add(list.indexOf(reasonOfDeath) + 1, placeOfDeath)
+ placeOfDeath.entries?.indexOf(saved.placeOfDeath)?.takeIf { it >= 0 }
+ ?.let { index ->
+ if (index == 8) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ }
+ }
-// ageUnit.apply {
-// inputType = TEXT_VIEW
-// value = ageUnit.entries!!.last()
-// }
-// dob.min = getHoFMinDobMillis()
-// dob.max = getHofMaxDobMillis()
-// age.min = Konstants.minAgeForGenBen.toLong().also {
-// minAgeYear = it.toInt()
-// }
-// age.max = Konstants.maxAgeForGenBen.toLong().also {
-// maxAgeYear = it.toInt()
-// }
+ }
+
+ beneficiaryStatus.value = when (saved.isDeath) {
+ true -> BenStatus.Death.name
+ false -> BenStatus.Alive.name
+ null -> null
+ }
+ dateOfDeath.value = saved.dateOfDeath
+ timeOfDeath.value = saved.timeOfDeath
+ reasonOfDeath.value = saved.reasonOfDeath
+ placeOfDeath.value = saved.placeOfDeath
+ otherPlaceOfDeath.value = saved.otherPlaceOfDeath
+
- ben?.takeIf { !it.isDraft }?.let { saved ->
pic.value = saved.userImage
dateOfReg.value = getDateFromLong(saved.regDate)
firstName.value = saved.firstName
lastName.value = saved.lastName
agePopup.value = getDateFromLong(saved.dob)
-// dob.value = getDateFromLong(saved.dob)
-// age.value = getAgeFromDob(saved.dob).toString()
-// ageUnit.value = ageUnit.getStringFromPosition(saved.ageUnitId)
gender.value = gender.getStringFromPosition(saved.genderId)
- gender.inputType = TEXT_VIEW
+ if (ben.isSpouseAdded || ben.isChildrenAdded || ben.doYouHavechildren || !ben.genDetails?.spouseName.isNullOrEmpty()) {
+ gender.inputType = TEXT_VIEW
+ agePopup.inputType = TEXT_VIEW
+ agePopup.value = getAgeStringFromDob(saved.dob)
+ dobReadOnly.value = getDateFromLong(saved.dob)
+ list.add(list.indexOf(agePopup) + 1, dobReadOnly)
+ maritalStatus.inputType = TEXT_VIEW
+ }
fatherName.value = saved.fatherName
+ fileUploadFront.value = saved.kidDetails?.birthCertificateFileFrontView
+ fileUploadBack.value = saved.kidDetails?.birthCertificateFileBackView
saved.fatherName?.let {
if (it.isNotEmpty()) fatherName.inputType = TEXT_VIEW
}
@@ -746,12 +918,23 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
}
maritalStatus.value =
maritalStatus.getStringFromPosition(saved.genDetails?.maritalStatusId ?: 0)
- ageAtMarriage.value = saved.genDetails?.ageAtMarriage.toString()
+ ageAtMarriage.value = calculateAgeAtMarriage(saved.dob, saved.genDetails?.marriageDate)?.toString()
+ ageAtMarriage.max = getAgeFromDob(saved.dob).toLong()
dateOfMarriage.value = getDateFromLong(
saved.genDetails?.marriageDate ?: 0
)
+ val maritalIndex = list.indexOf(maritalStatus)
+ if (maritalStatus.value == maritalStatus.entries!![1]) {
+ list.add(maritalIndex + 1, ageAtMarriage)
+ }
mobileNoOfRelation.value =
mobileNoOfRelation.getStringFromPosition(saved.mobileNoOfRelationId)
+ if (!isMitaninVariant) {
+ tempraryContactNoBelongsto.value =
+ tempraryContactNoBelongsto.getStringFromPosition(saved.tempMobileNoOfRelationId)
+ tempraryContactNoBelongsto.isEnabled = false
+ tempraryContactNo.value = saved.contactNumber.toString()
+ }
otherMobileNoOfRelation.value = saved.mobileOthers
contactNumber.value = saved.contactNumber.toString()
relationToHead.value = relationToHeadListDefault[saved.familyHeadRelationPosition - 1]
@@ -762,45 +945,20 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
childRegisteredAtAwc.value = childRegisteredAtAwc.getStringFromPosition(
saved.kidDetails?.childRegisteredSchoolId ?: 0
)
-// saved.kidDetails?.childRegisteredAWCId?.takeIf { it > 0 }
-// ?.let { childRegisteredAtAwc.entries?.get(it - 1) }
childRegisteredAtSchool.value = childRegisteredAtSchool.getStringFromPosition(
saved.kidDetails?.childRegisteredSchoolId ?: 0
)
-// saved.kidDetails?.childRegisteredSchoolId?.takeIf { it > 0 }
-// ?.let { childRegisteredAtSchool.entries?.get(it - 1) }
typeOfSchool.value =
typeOfSchool.getStringFromPosition(saved.kidDetails?.typeOfSchoolId ?: 0)
-// saved.kidDetails?.typeOfSchoolId?.takeIf { it > 0 }
-// ?.let { typeOfSchool.entries?.get(it - 1) }
rchId.value = saved.rchId
-
-// relationToHead.entries = when (saved.gender) {
-// MALE -> relationToHeadListMale
-// FEMALE -> relationToHeadListFemale
-// TRANSGENDER -> relationToHeadListDefault
-// null -> null
-// }
-// relationToHead.arrayId = when (saved.gender) {
-// MALE -> R.array.nbr_relationship_to_head_male
-// FEMALE -> R.array.nbr_relationship_to_head_female
-// TRANSGENDER -> R.array.nbr_relationship_to_head
-// null -> -1
-// }
}
if (mobileNoOfRelation.value == mobileNoOfRelation.entries!!.last()) {
list.add(list.indexOf(mobileNoOfRelation) + 1, otherMobileNoOfRelation)
}
-// if (relationToHead.value == relationToHead.entries!!.last()) {
-// list.add(list.indexOf(relationToHead) + 1, otherRelationToHead)
-// }
if (religion.value == religion.entries!![7]) {
list.add(list.indexOf(religion) + 1, otherReligion)
}
-// if (ageUnit.value == ageUnit.entries?.last() && (age.value?.toInt() ?: 0) in 3..5) {
-// list.add((list.indexOf(rchId)), childRegisteredAtAwc)
-// }
if ((getAgeFromDob(getLongFromDate(agePopup.value))) in 4..14) {
list.add((list.indexOf(rchId)), childRegisteredAtSchool)
}
@@ -810,6 +968,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
) + 1, typeOfSchool
)
+
if (!isKid() and !hasThirdPage()) {
list.remove(rchId)
}
@@ -822,17 +981,21 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
hoF: BenRegCache?,
benGender: Gender,
relationToHeadId: Int,
- hoFSpouse: List = emptyList()
+ hoFSpouse: List = emptyList(),
+ selectedben: BenRegCache?,
+ isAddspouse: Int,
) {
val list = mutableListOf(
pic,
dateOfReg,
firstName,
lastName,
+ )
+ if (!isMitaninVariant) {
+ list.addAll(listOf(tempraryContactNo, tempraryContactNoBelongsto, sendOtpBtn))
+ }
+ list.addAll(listOf(
agePopup,
-// dob,
-// age,
-// ageUnit,
gender,
maritalStatus,
fatherName,
@@ -842,16 +1005,24 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
contactNumber,
community,
religion,
- rchId,
-// hasAadharNo,
- )
+ rchId
+ ))
this.familyHeadPhoneNo = household.family?.familyHeadPhoneNo?.toString()
+ this.isAddSppouse = isAddspouse
+ if (!isMitaninVariant) {
+ tempraryContactNoBelongsto.value =
+ tempraryContactNoBelongsto.getStringFromPosition(1)
+ }
this.hof = hoF
+ this.benIfDataExist = ben
if (ben == null) {
dateOfReg.value = getCurrentDateString()
// ageUnit.value = ageUnit.entries!!.last()
mobileNoOfRelation.value = mobileNoOfRelation.entries!![4]
contactNumber.value = familyHeadPhoneNo
+ if (!isMitaninVariant) {
+ tempraryContactNo.value = familyHeadPhoneNo
+ }
community.value = hoF?.communityId?.let { community.getStringFromPosition(it) }
religion.value = hoF?.religionId?.let { religion.getStringFromPosition(it) }
gender.value = when (benGender) {
@@ -869,18 +1040,34 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
FEMALE -> R.array.nbr_marital_status_female_array
TRANSGENDER -> R.array.nbr_marital_status_male_array
}
- gender.inputType = TEXT_VIEW
+// gender.inputType = TEXT_VIEW
relationToHead.value = relationToHead.getStringFromPosition(relationToHeadId + 1)
if (relationToHeadId == relationToHead.entries!!.lastIndex) {
list.add(list.indexOf(relationToHead) + 1, otherRelationToHead)
}
+ list.remove(reproductiveStatus)
}
agePopup.min = getMinDobMillis()
agePopup.max = System.currentTimeMillis()
-// dob.min = getMinDobMillis()
-// dob.max = System.currentTimeMillis()
+ if (isAddspouse == 1) {
+ isAddSpouse = true
+ gender.inputType = TEXT_VIEW
+ maritalStatus.inputType = TEXT_VIEW
+ reproductiveStatus.inputType = DROPDOWN
+ }
if (relationToHeadId == 4 || relationToHeadId == 5) hoF?.let {
- setUpForSpouse(it, hoFSpouse)
+ isAddSpouse = true
+// agePopup.inputType = TEXT_VIEW
+ gender.inputType = TEXT_VIEW
+ maritalStatus.inputType = TEXT_VIEW
+ reproductiveStatus.inputType = DROPDOWN
+ setUpForSpouse(it, hoFSpouse,list)
+ }
+ if (relationToHeadId == 9 || relationToHeadId == 19 || relationToHeadId == 13 ||
+ relationToHeadId == 11 || relationToHeadId == 17 || relationToHeadId == 2 ||
+ relationToHeadId == 18 || relationToHeadId == 14 ||
+ relationToHeadId == 10 || relationToHeadId == 12 || relationToHeadId == 16) hoF?.let {
+ setUpPageforOthers(it,hoFSpouse,selectedben,list)
}
if (relationToHeadId == 8 || relationToHeadId == 9) hoF?.let {
setUpForChild(it, hoFSpouse.firstOrNull())
@@ -893,18 +1080,57 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
ben?.takeIf { !it.isDraft }?.let { saved ->
+ list.add(list.indexOf(lastName) + 1, beneficiaryStatus)
+
+ if (saved.isDeath) {
+ list.add(list.indexOf(beneficiaryStatus) + 1, dateOfDeath)
+ list.add(list.indexOf(dateOfDeath) + 1, timeOfDeath)
+ list.add(list.indexOf(timeOfDeath) + 1, reasonOfDeath)
+ list.add(list.indexOf(reasonOfDeath) + 1, placeOfDeath)
+ placeOfDeath.entries?.indexOf(saved.placeOfDeath)?.takeIf { it >= 0 }
+ ?.let { index ->
+ if (index == 8) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ }
+ }
+
+
+ }
+
+ beneficiaryStatus.value = when (saved.isDeath) {
+ true -> BenStatus.Death.name
+ false -> BenStatus.Alive.name
+ null -> null
+ }
+ dateOfDeath.value = saved.dateOfDeath
+ timeOfDeath.value = saved.timeOfDeath
+ reasonOfDeath.value = saved.reasonOfDeath
+ placeOfDeath.value = saved.placeOfDeath
+ otherPlaceOfDeath.value = saved.otherPlaceOfDeath
+
+ try {
+ handleForAgeDob(formId = agePopup.id)
+ } catch(e: Exception) {
+ e.printStackTrace()
+ }
pic.value = saved.userImage
dateOfReg.value = getDateFromLong(saved.regDate)
firstName.value = saved.firstName
lastName.value = saved.lastName
agePopup.value = getDateFromLong(saved.dob)
ageAtMarriage.max = getAgeFromDob(saved.dob).toLong()
-// dob.value = getDateFromLong(saved.dob)
-// age.value = getAgeFromDob(saved.dob).toString()
-// ageUnit.value = ageUnit.getStringFromPosition(saved.ageUnitId)
gender.value = gender.getStringFromPosition(saved.genderId)
- gender.inputType = TEXT_VIEW
+ if (ben.isSpouseAdded || ben.isChildrenAdded || ben.doYouHavechildren || !ben.genDetails?.spouseName.isNullOrEmpty()) {
+ gender.inputType = TEXT_VIEW
+ agePopup.inputType = TEXT_VIEW
+ agePopup.value = getAgeStringFromDob(saved.dob)
+ dobReadOnly.value = getDateFromLong(saved.dob)
+ list.add(list.indexOf(agePopup) + 1, dobReadOnly)
+ maritalStatus.inputType = TEXT_VIEW
+ }
fatherName.value = saved.fatherName
+ fileUploadFront.value = saved.kidDetails?.birthCertificateFileFrontView
+ fileUploadBack.value = saved.kidDetails?.birthCertificateFileBackView
saved.fatherName?.let {
if (it.isNotEmpty()) fatherName.inputType = TEXT_VIEW
}
@@ -921,12 +1147,22 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
}
maritalStatus.value =
maritalStatus.getStringFromPosition(saved.genDetails?.maritalStatusId ?: 0)
- ageAtMarriage.value = saved.genDetails?.ageAtMarriage.toString()
+ ageAtMarriage.value = calculateAgeAtMarriage(saved.dob, saved.genDetails?.marriageDate)?.toString()
dateOfMarriage.value = getDateFromLong(
saved.genDetails?.marriageDate ?: 0
)
+ val maritalIndex = list.indexOf(maritalStatus)
+ if (maritalStatus.value == maritalStatus.entries!![1]) {
+ list.add(maritalIndex + 1, ageAtMarriage)
+ }
mobileNoOfRelation.value =
mobileNoOfRelation.getStringFromPosition(saved.mobileNoOfRelationId)
+ if (!isMitaninVariant) {
+ tempraryContactNoBelongsto.value =
+ tempraryContactNoBelongsto.getStringFromPosition(saved.tempMobileNoOfRelationId)
+ tempraryContactNoBelongsto.isEnabled = false
+ tempraryContactNo.value = saved.contactNumber.toString()
+ }
otherMobileNoOfRelation.value = saved.mobileOthers
contactNumber.value = saved.contactNumber.toString()
// relationToHead.entries = relationToHeadListDefault
@@ -941,19 +1177,19 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
childRegisteredAtAwc.value = childRegisteredAtAwc.getStringFromPosition(
saved.kidDetails?.childRegisteredSchoolId ?: 0
)
-// saved.kidDetails?.childRegisteredAWCId?.takeIf { it > 0 }
-// ?.let { childRegisteredAtAwc.entries?.get(it - 1) }
childRegisteredAtSchool.value = childRegisteredAtSchool.getStringFromPosition(
saved.kidDetails?.childRegisteredSchoolId ?: 0
)
-// saved.kidDetails?.childRegisteredSchoolId?.takeIf { it > 0 }
-// ?.let { childRegisteredAtSchool.entries?.get(it - 1) }
typeOfSchool.value =
typeOfSchool.getStringFromPosition(saved.kidDetails?.typeOfSchoolId ?: 0)
-// saved.kidDetails?.typeOfSchoolId?.takeIf { it > 0 }
-// ?.let { typeOfSchool.entries?.get(it - 1) }
rchId.value = saved.rchId
+ // Restore haveChildren value for married females
+ val maritalStatusId = saved.genDetails?.maritalStatusId
+ if (saved.genderId == 2 && maritalStatusId != null && maritalStatusId >= 2) {
+ haveChildren.value = if (saved.doYouHavechildren) haveChildren.entries?.get(0) else haveChildren.entries?.get(1)
+ _isAddingChildren.value = saved.doYouHavechildren
+ }
relationToHead.entries = when (saved.gender) {
MALE -> relationToHeadListMale
@@ -970,21 +1206,22 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
}
if (maritalStatus.value != null && maritalStatus.value != maritalStatus.entries!![0] && gender.value != null) {
-// if(maritalStatus.value ==maritalStatus.entries!![1])
-// list.removeAll(listOf(fatherName, motherName))
list.add(
list.indexOf(maritalStatus) + 3, when (gender.value) {
gender.entries!![0] -> wifeName
gender.entries!![1] -> husbandName
gender.entries!![2] -> spouseName
- else -> throw java.lang.IllegalStateException("Gender unspecified with non empty marital status value!")
+ else -> throw IllegalStateException("Gender unspecified with non empty marital status value!")
}
)
+ // Add haveChildren for females if not already in list
+ if (gender.value == gender.entries!![1] && !list.contains(haveChildren)) {
+ val ageAtMarriageIndex = list.indexOf(ageAtMarriage)
+ if (ageAtMarriageIndex >= 0) {
+ list.add(ageAtMarriageIndex + 1, haveChildren)
+ }
+ }
-// list.add(
-// list.indexOf(maritalStatus) + 4,
-// ageAtMarriage
-// )
}
if (maritalStatus.value == maritalStatus.entries!![1] && gender.value == gender.entries!![1]) {
@@ -1009,15 +1246,9 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
if (mobileNoOfRelation.value == mobileNoOfRelation.entries!!.last()) {
list.add(list.indexOf(mobileNoOfRelation) + 1, otherMobileNoOfRelation)
}
-// if (relationToHead.value == relationToHead.entries!!.last()) {
-// list.add(list.indexOf(relationToHead) + 1, otherRelationToHead)
-// }
if (religion.value == religion.entries!![7]) {
list.add(list.indexOf(religion) + 1, otherReligion)
}
-// if (ageUnit.value == ageUnit.entries?.last() && (age.value?.toInt() ?: 0) in 3..5) {
-// list.add((list.indexOf(rchId)), childRegisteredAtAwc)
-// }
if ((getAgeFromDob(getLongFromDate(agePopup.value))) in 4..14) {
list.add((list.indexOf(rchId)), childRegisteredAtSchool)
}
@@ -1033,24 +1264,47 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
if (relationToHeadId == 4 || relationToHeadId == 5) hoF?.let {
if (it.genDetails?.maritalStatusId == 2) {
- agePopup.min = getHoFMinDobMillis()
- agePopup.max = getHofMaxDobMillis()
+ if (benIfDataExist != null) {
+ try {
+ handleForAgeDob(formId = reproductiveStatus.id)
+ } catch(e: Exception) {
+ e.printStackTrace()
+ }
+// handleForAgeDob(formId = reproductiveStatus.id)
+ } else {
+ agePopup.min = getHoFMinDobMillis()
+ agePopup.max = getHofMaxDobMillis()
+ }
+
}
}
if (relationToHeadId == 8 || relationToHeadId == 9) hoF?.let {
- val hoFAge = getAgeFromDob(it.dob)
+
+ val hoFAge = getAgeFromDob(hoF.dob)
val hoFSpouseAge = hoFSpouse.firstOrNull()?.dob?.let { h -> getAgeFromDob(h) }
- val maxAge = (if (hoFSpouseAge == null) hoFAge else minOf(
- hoFAge,
- hoFSpouseAge
- )) - Konstants.minAgeForGenBen
+ val minParentAge = hoFSpouseAge?.let { minOf(hoFAge, it) } ?: hoFAge
+
+ val hofAgeAtMarriage = hoF.genDetails?.ageAtMarriage ?: 0
+ var hoFSpouseAgeAtMarriage = hoFSpouse.firstOrNull()?.genDetails?.ageAtMarriage
+ val minAgeAtMarriage =
+ hoFSpouseAgeAtMarriage?.let { minOf(hofAgeAtMarriage, it) } ?: hofAgeAtMarriage
+
+ val (maxSonYears, maxSonMonths) = calculateMaxSonAge(
+ parentYears = minParentAge,
+ parentMonths = 0,
+ marriageYears = minAgeAtMarriage,
+ marriageMonths = 7
+ )
- agePopup.min = Calendar.getInstance().setToStartOfTheDay().let { cal ->
- cal.add(Calendar.YEAR, -1 * maxAge)
- cal.timeInMillis
- }
- maxAgeYear = maxAge
+ val totalMonthsToSubtract = maxSonYears * 12 + maxSonMonths
+ val maxAllowedDobMillis = Calendar.getInstance().setToStartOfTheDay().apply {
+ add(Calendar.MONTH, -totalMonthsToSubtract)
+ }.timeInMillis
+
+ agePopup.min = maxAllowedDobMillis
+
+ maxAgeYear = maxSonYears
}
if (relationToHeadId == 0 || relationToHeadId == 1) hoF?.let {
@@ -1064,8 +1318,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
ageAtMarriage.max = getAgeFromDob(it.dob).toLong()
}
if (isKid()) {
- list.removeAll(
- listOf(
+ listOf(
maritalStatus,
husbandName,
wifeName,
@@ -1073,34 +1326,42 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
ageAtMarriage,
dateOfMarriage,
reproductiveStatus
- )
- )
+ ).forEach { list.remove(it) }
list.addAll(
listOf(
birthCertificateNumber,
- placeOfBirth
+ placeOfBirth,
+ headLine,
+ fileUploadFront,
+ fileUploadBack
)
)
}
if (!isKid() and !hasThirdPage()) {
list.remove(rchId)
}
+ if (hasThirdPage()) list.add(reproductiveStatus)
setUpPage(list)
}
- private fun setUpForChild(hoF: BenRegCache, hoFSpouse: BenRegCache?) {
+ private fun setUpForChild(
+ hoF: BenRegCache,
+ hoFSpouse: BenRegCache?,
+ ) {
if (hoF.gender == MALE) {
fatherName.value = "${hoF.firstName} ${hoF.lastName ?: ""}"
motherName.value = hoFSpouse?.let {
"${it.firstName} ${it.lastName ?: ""}"
} ?: hoF.genDetails?.spouseName
+
fatherName.value?.let {
if (it.isNotEmpty()) fatherName.inputType = TEXT_VIEW
}
motherName.value?.let {
if (it.isNotEmpty()) motherName.inputType = TEXT_VIEW
}
+
} else {
motherName.value = "${hoF.firstName} ${hoF.lastName ?: ""}"
fatherName.value = hoFSpouse?.let {
@@ -1113,23 +1374,33 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
if (it.isNotEmpty()) motherName.inputType = TEXT_VIEW
}
}
+ fileUploadFront.value = hof?.kidDetails?.birthCertificateFileFrontView
+ fileUploadBack.value = hof?.kidDetails?.birthCertificateFileBackView
val hoFAge = getAgeFromDob(hoF.dob)
- val hoFSpouseAge = hoFSpouse?.dob?.let { getAgeFromDob(it) }
- val maxAge = (if (hoFSpouseAge == null) hoFAge else minOf(
- hoFAge,
- hoFSpouseAge
- )) - Konstants.minAgeForGenBen
-// age.max = maxAge.toLong()
-// dob.min = Calendar.getInstance().setToStartOfTheDay().let {
-// it.add(Calendar.YEAR, -1 * maxAge)
-// it.timeInMillis
-// }
+ val hoFSpouseAge = hoFSpouse?.dob?.let { h -> getAgeFromDob(h) }
+ val minParentAge = hoFSpouseAge?.let { minOf(hoFAge, it) } ?: hoFAge
+
+ val hofAgeAtMarriage = hoF.genDetails?.ageAtMarriage ?: 0
+ var hoFSpouseAgeAtMarriage = hoFSpouse?.genDetails?.ageAtMarriage
+ val minAgeAtMarriage =
+ hoFSpouseAgeAtMarriage?.let { minOf(hofAgeAtMarriage, it) } ?: hofAgeAtMarriage
+
+
+ val (maxSonYears, maxSonMonths) = calculateMaxSonAge(
+ parentYears = minParentAge,
+ parentMonths = 0,
+ marriageYears = minAgeAtMarriage,
+ marriageMonths = 7
+ )
+
+ val totalMonthsToSubtract = maxSonYears * 12 + maxSonMonths
+ val maxAllowedDobMillis = Calendar.getInstance().setToStartOfTheDay().apply {
+ add(Calendar.MONTH, -totalMonthsToSubtract)
+ }.timeInMillis
+ agePopup.min = maxAllowedDobMillis
+
+ maxAgeYear = maxSonYears
- agePopup.min = Calendar.getInstance().setToStartOfTheDay().let {
- it.add(Calendar.YEAR, -1 * maxAge)
- it.timeInMillis
- }
- maxAgeYear = maxAge
lastName.value = hoF.lastName
}
@@ -1144,57 +1415,107 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
minAgeYear = minAge
firstName.value =
when (benGender) {
- MALE -> hoF.fatherName?.also { firstName.inputType = TEXT_VIEW }
- FEMALE -> hoF.motherName?.also { firstName.inputType = TEXT_VIEW }
+ MALE -> hoF.fatherName?.takeIf { it.isNotEmpty() }?.also { firstName.inputType = TEXT_VIEW }
+ FEMALE -> hoF.motherName?.takeIf { it.isNotEmpty() }?.also { firstName.inputType = TEXT_VIEW }
else -> null
}
if (benGender == MALE) wifeName.value = hof?.motherName
if (benGender == FEMALE) husbandName.value = hof?.fatherName
- lastName.value = hoF.lastName?.also { firstName.inputType = TEXT_VIEW }
+ maritalStatus.value = maritalStatus.getStringFromPosition(2)
+
+ if (hoF.isSpouseAdded || hoF.isChildrenAdded || hoF.doYouHavechildren) {
+ maritalStatus.inputType = TEXT_VIEW
+ agePopup.inputType = TEXT_VIEW
+ }
+
+ lastName.value = hoF.lastName?.also { lastName.inputType = TEXT_VIEW }
ageAtMarriage.max = getAgeFromDob(hoF.dob).toLong()
}
- private fun setUpForSpouse(hoFSpouse: BenRegCache, hoFSpouse1: List) {
+ private fun setUpForSpouse(
+ hoFSpouse: BenRegCache,
+ hoFSpouse1: List,
+ list1: MutableList
+ ) {
if (hoFSpouse.genDetails?.maritalStatusId == 2) {
if (hoFSpouse1.isEmpty()) {
firstName.value = hoFSpouse.genDetails?.spouseName
firstName.inputType = TEXT_VIEW
lastName.value = hoFSpouse.lastName
- lastName.inputType = TEXT_VIEW
+ lastName.inputType = EDIT_TEXT
+ } else {
+ lastName.value = hoFSpouse.lastName
+ lastName.inputType = EDIT_TEXT
}
if (hoFSpouse.gender == FEMALE) {
wifeName.value = "${hoFSpouse.firstName} ${hoFSpouse.lastName ?: ""}"
wifeName.inputType = TEXT_VIEW
+
} else {
husbandName.value = "${hoFSpouse.firstName} ${hoFSpouse.lastName ?: ""}"
husbandName.inputType = TEXT_VIEW
}
-// ageUnit.value = ageUnit.entries!!.last()
-// ageUnit.inputType = TEXT_VIEW
+
maritalStatus.value = maritalStatus.getStringFromPosition(2)
- maritalStatus.inputType = TEXT_VIEW
-// ageAtMarriage.inputType = TEXT_VIEW
+ if (hoFSpouse.isSpouseAdded || hoFSpouse.isChildrenAdded || hoFSpouse.doYouHavechildren) {
+ maritalStatus.inputType = TEXT_VIEW
+ }
+// maritalStatus.inputType = TEXT_VIEW
+ if (hoFSpouse.gender == MALE) {
+ list1.add(list1.indexOf(maritalStatus) + 1 ,haveChildren)
+ }
+
+
timeStampDateOfMarriageFromSpouse = hoFSpouse.genDetails?.marriageDate
-// dob.min = getHoFMinDobMillis()
-// dob.max = getHofMaxDobMillis()
-// age.min = Konstants.minAgeForGenBen.toLong().also {
-// minAgeYear = it.toInt()
-// }
-// age.max = Konstants.maxAgeForGenBen.toLong().also {
-// maxAgeYear = it.toInt()
-// }
+ agePopup.min = getHoFMinDobMillis()
+ agePopup.max = getHofMaxDobMillis()
+// reproductiveStatus.isEnabled = true
+ }
+ }
+ private fun setUpPageforOthers(
+ hoFSpouse: BenRegCache, hoFSpouse1: List,
+ selectedben: BenRegCache?,
+ list1: MutableList
+ ) {
+ if (selectedben?.genDetails?.maritalStatusId == 2) {
+
+ firstName.value = selectedben?.genDetails?.spouseName
+ if (firstName.value?.isNotEmpty()!!) {
+ firstName.inputType = TEXT_VIEW
+
+ }
+ lastName.value = selectedben?.lastName
+ lastName.inputType = EDIT_TEXT
+
+ if (selectedben?.gender == FEMALE) {
+ wifeName.value = "${selectedben?.firstName} ${selectedben?.lastName ?: ""}"
+ wifeName.inputType = TEXT_VIEW
+ } else {
+ husbandName.value = "${selectedben?.firstName} ${selectedben?.lastName ?: ""}"
+ husbandName.inputType = TEXT_VIEW
+ }
+ maritalStatus.value = maritalStatus.getStringFromPosition(2)
+ if (selectedben.isSpouseAdded || selectedben.isChildrenAdded || selectedben.doYouHavechildren) {
+ maritalStatus.inputType = TEXT_VIEW
+ }
+// maritalStatus.inputType = TEXT_VIEW
+ if (selectedben?.gender == MALE) {
+ list1.add(list1.indexOf(maritalStatus) + 1 ,haveChildren)
+
+ }
+ timeStampDateOfMarriageFromSpouse = selectedben?.genDetails?.marriageDate
agePopup.min = getHoFMinDobMillis()
agePopup.max = getHofMaxDobMillis()
}
}
private fun hasThirdPage(): Boolean {
- return ((getAgeFromDob(getLongFromDate(agePopup.value))) >= Konstants.minAgeForGenBen &&
+ val result = ((getAgeFromDob(getLongFromDate(agePopup.value))) >= Konstants.minAgeForGenBen &&
(gender.value == gender.entries!![1]))
-
+ return result
}
- private fun isKid(): Boolean {
+ fun isKid(): Boolean {
return ((getAgeFromDob(getLongFromDate(agePopup.value))) < 15)
}
@@ -1346,7 +1667,6 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
)
private val motherOfChild = FormElement(
id = 41, inputType = DROPDOWN, title = resources.getString(R.string.mother_of_the_child),
-// entries = pncMotherList?.toTypedArray(),
arrayId = -1,
required = true
)
@@ -1372,6 +1692,59 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL,
etMaxLength = 4
)
+ private val beneficiaryStatus = FormElement(
+ id = 50,
+ inputType = RADIO,
+ title = context.getString(R.string.beneficiary_status),
+ arrayId = R.array.beneficiary_status,
+ entries = resources.getStringArray(R.array.beneficiary_status),
+ required = false,
+ hasDependants = true,
+ )
+
+ private val dateOfDeath = FormElement(
+ id = 51,
+ arrayId = -1,
+ inputType = DATE_PICKER,
+ title = context.getString(R.string.date_of_death),
+ max = System.currentTimeMillis(),
+ required = true,
+ )
+
+ private val timeOfDeath = FormElement(
+ id = 52,
+ inputType = org.piramalswasthya.sakhi.model.InputType.TIME_PICKER,
+ title = context.getString(R.string.time_of_death),
+ required = false,
+ )
+
+ private val reasonOfDeath = FormElement(
+ id = 53,
+ inputType = DROPDOWN,
+ title = context.getString(R.string.reason_for_death),
+ arrayId = R.array.reason_of_death_array,
+ entries = resources.getStringArray(R.array.reason_of_death_array),
+ required = true
+ )
+
+
+ private val placeOfDeath = FormElement(
+ id = 54,
+ inputType = DROPDOWN,
+ title = context.getString(R.string.place_of_death),
+ arrayId = R.array.death_place_array,
+ entries = resources.getStringArray(R.array.death_place_array),
+ required = true,
+ )
+
+ private val otherPlaceOfDeath = FormElement(
+ id = 55,
+ inputType = EDIT_TEXT,
+ title = context.getString(R.string.other_place_of_death),
+ required = true,
+ hasDependants = true,
+ )
+
private val deathRemoveList by lazy {
listOf(
@@ -1462,68 +1835,217 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
if (whoConductedDelivery.value == whoConductedDelivery.entries!!.last()) list.add(
list.indexOf(whoConductedDelivery) + 1, otherWhoConductedDelivery
)
- if (complicationsDuringDelivery.value == complicationsDuringDelivery.entries!![4]) list.removeAll(
- deathRemoveList
- )
+ if (complicationsDuringDelivery.value == complicationsDuringDelivery.entries!![4]) deathRemoveList.forEach { list.remove(it) }
setUpPage(list)
}
+
+
override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
return when (formId) {
+
+
firstName.id -> {
validateEmptyOnEditText(firstName)
- validateAllCapsOrSpaceOnEditText(firstName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(firstName)
}
- lastName.id -> {
- validateAllCapsOrSpaceOnEditText(lastName)
+ beneficiaryStatus.id -> {
+ val isDeath = beneficiaryStatus.value == BenStatus.Death.name
+
+ if (isDeath) {
+ dateOfDeath.min = getMinDateFromRegistration(dateOfReg.value!!)
+ val gender = gender.value
+ val age = agePopup.value
+ val showMaternal = shouldShowMaternalDeath(gender, age)
+ reasonOfDeath.entries = if (showMaternal) {
+ resources.getStringArray(R.array.reason_of_death_array_with_maternal)
+ } else {
+ resources.getStringArray(R.array.reason_of_death_array)
+ }
+ }
+
+ return triggerDependants(
+ source = beneficiaryStatus,
+ passedIndex = if (isDeath) 1 else 0,
+ triggerIndex = 1,
+ target = if (isDeath) {
+ listOf(dateOfDeath, timeOfDeath, reasonOfDeath, placeOfDeath)
+ } else {
+ listOf(
+ dateOfDeath,
+ timeOfDeath,
+ reasonOfDeath,
+ placeOfDeath,
+ otherPlaceOfDeath
+ )
+ }
+ )
}
- agePopup.id -> {
- assignValuesToAgeAndAgeUnitFromDob(
- getLongFromDate(agePopup.value),
-// age,
-// ageUnit,
- ageAtMarriage,
- timeStampDateOfMarriageFromSpouse
+
+ placeOfDeath.id -> {
+ val index = placeOfDeath.entries?.indexOf(placeOfDeath.value).takeIf { it!! >= 0 }
+ ?: return -1
+ val triggerIndex = 8
+ return triggerDependants(
+ source = placeOfDeath,
+ passedIndex = index,
+ triggerIndex = triggerIndex,
+ target = otherPlaceOfDeath
)
- handleForAgeDob(formId = agePopup.id)
+ }
+ lastName.id -> {
+ // validateAllCapsOrSpaceOnEditText(lastName)
+ validateEmptyOnEditText(lastName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(lastName)
}
-// ageUnit.id, age.id -> {
-// if (age.value.isNullOrEmpty() || ageUnit.value == null) {
-// validateEmptyOnEditText(age)
-// validateEmptyOnEditText(ageUnit)
-// return -1
-// }
-// handleForAgeDob(formId = age.id)
-// }
+ agePopup.id -> {
+// assignValuesToAgeAndAgeUnitFromDob(
+// getLongFromDate(agePopup.value),
+// ageAtMarriage,
+// timeStampDateOfMarriageFromSpouse
+// )
+
+ if (benIfDataExist != null || !isAddSpouse) {
+ if (gender.value != null) {
+ // Gender already set (editing OR add member with pre-selected relation)
+ // Preserve gender, maritalStatus, relationToHead
+ // reproductiveStatus will be handled in updateReproductiveOptionsBasedOnAgeGender
+
+ val genderIndex = when (gender.value) {
+ gender.entries?.get(0) -> 0 // Male
+ gender.entries?.get(1) -> 1 // Female
+ else -> 2 // Transgender/Other
+ }
+
+ maritalStatus.entries = when (genderIndex) {
+ 1 -> maritalStatusFemale
+ else -> maritalStatusMale
+ }
+ maritalStatus.arrayId = when (genderIndex) {
+ 1 -> R.array.nbr_marital_status_female_array
+ else -> R.array.nbr_marital_status_male_array
+ }
+ relationToHead.entries = when (genderIndex) {
+ 0 -> relationToHeadListMale
+ 1 -> relationToHeadListFemale
+ else -> relationToHeadListDefault
+ }
+ relationToHead.arrayId = when (genderIndex) {
+ 0 -> R.array.nbr_relationship_to_head_male
+ 1 -> R.array.nbr_relationship_to_head_female
+ else -> R.array.nbr_relationship_to_head
+ }
+ } else {
+ // Gender not set yet: reset all values
+ gender.value = null
+ relationToHead.value = null
+ maritalStatus.value = null
+ reproductiveStatus.value = null
+
+ maritalStatus.inputType = DROPDOWN
+ reproductiveStatus.inputType = DROPDOWN
+ relationToHead.inputType = DROPDOWN
+
+ maritalStatus.entries = when (index) {
+ 1 -> maritalStatusFemale
+ else -> maritalStatusMale
+ }
+ maritalStatus.arrayId = when (index) {
+ 1 -> R.array.nbr_marital_status_female_array
+ else -> R.array.nbr_marital_status_male_array
+ }
+ relationToHead.entries = when (index) {
+ 0 -> relationToHeadListMale
+ 1 -> relationToHeadListFemale
+ else -> relationToHeadListDefault
+ }
+ relationToHead.arrayId = when (index) {
+ 0 -> R.array.nbr_relationship_to_head_male
+ 1 -> R.array.nbr_relationship_to_head_female
+ else -> R.array.nbr_relationship_to_head
+ }
+ }
+ }
+
+ if (isAddSpouse) {
+ ageAtMarriage.max = getAgeFromDob(getLongFromDate(agePopup.value)).toLong()
+ ageAtMarriage.value = calculateAgeAtMarriage(getLongFromDate(agePopup.value), timeStampDateOfMarriageFromSpouse)?.toString()
+ ?: Konstants.minAgeForMarriage.toString()
+ dateOfMarriage.value = getDateFromLong(
+ timeStampDateOfMarriageFromSpouse ?: 0
+ )
+ triggerDependants(
+ source = agePopup,
+ addItems = listOf(ageAtMarriage),
+ removeItems = emptyList(),
+ position = 13
+ )
+
+ }
+
+ try {
+ return updateReproductiveOptionsBasedOnAgeGender(formId = agePopup.id)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ return 1
+ }
+
+ }
ageAtMarriage.id -> {
- (getAgeFromDob(getLongFromDate(agePopup.value))).takeIf { it > 0 && !ageAtMarriage.value.isNullOrEmpty() }
- ?.toInt()?.let {
+ val dobMillis = getLongFromDate(agePopup.value)
+ val currentAge = getAgeFromDob(dobMillis)
+
+ currentAge.takeIf { it > 0 && !ageAtMarriage.value.isNullOrEmpty() }
+ ?.let {
+
validateEmptyOnEditText(ageAtMarriage)
+ ageAtMarriage.max = currentAge.toLong()
validateIntMinMax(ageAtMarriage)
- if (it == ageAtMarriage.value?.toInt()) {
- val cal = Calendar.getInstance()
- dateOfMarriage.max = cal.timeInMillis
- cal.add(Calendar.YEAR, -1)
- dateOfMarriage.min = cal.timeInMillis
+ val enteredAgeAtMarriage = ageAtMarriage.value!!.toIntOrNull() ?: return@let
+
+ val dobCal = Calendar.getInstance()
+ dobCal.timeInMillis = dobMillis
+
+ val birthYear = dobCal.get(Calendar.YEAR)
+
+ val marriageYear = birthYear + enteredAgeAtMarriage
+
+
+ val marriageCal = Calendar.getInstance().apply {
+ timeInMillis = dobMillis
+ set(Calendar.YEAR, marriageYear)
}
+
+
+ dateOfMarriage.value = getDateFromLong(marriageCal.timeInMillis)
+
+ dateOfMarriage.max = Calendar.getInstance().timeInMillis
+
+ dateOfMarriage.min = marriageCal.timeInMillis
+
triggerDependants(
source = ageAtMarriage,
- passedIndex = ageAtMarriage.value!!.toInt(),
+ passedIndex = it,
triggerIndex = it,
target = dateOfMarriage
)
} ?: -1
+
+ return 0
}
childRegisteredAtSchool.id -> {
+ if ((getAgeFromDob(getLongFromDate(agePopup.value))) in 3..6) {
+ typeOfSchool.required = true
+ }
triggerDependants(
source = childRegisteredAtSchool,
passedIndex = index,
@@ -1535,6 +2057,12 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
gender.id -> {
relationToHead.value = null
maritalStatus.value = null
+ reproductiveStatus.value = null
+
+ maritalStatus.inputType = DROPDOWN
+ reproductiveStatus.inputType = DROPDOWN
+ relationToHead.inputType = DROPDOWN
+
maritalStatus.entries = when (index) {
1 -> maritalStatusFemale
else -> maritalStatusMale
@@ -1543,6 +2071,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
maritalStatus.arrayId = when (index) {
1 -> R.array.nbr_marital_status_female_array
else -> R.array.nbr_marital_status_male_array
+
}
relationToHead.entries = when (index) {
@@ -1550,12 +2079,26 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
1 -> relationToHeadListFemale
else -> relationToHeadListDefault
}
- val listChanged = if (hasThirdPage()) triggerDependants(
- source = rchId,
- addItems = listOf(reproductiveStatus),
- removeItems = emptyList(),
- position = -2
- ) else {
+
+ relationToHead.arrayId = when (index) {
+ 0 -> R.array.nbr_relationship_to_head_male
+ 1 -> R.array.nbr_relationship_to_head_female
+ else -> R.array.nbr_relationship_to_head
+ }
+ val listChanged = if (hasThirdPage()) {
+
+ Log.e("ThirdPage","isThird")
+ updateReproductiveOptionsBasedOnAgeGender(formId = gender.id)
+ triggerDependants(
+ source = rchId,
+ addItems = listOf(reproductiveStatus),
+ removeItems = emptyList(),
+ position = -2
+ )
+ } else {
+ fatherName.required = false
+ motherName.required = false
+
triggerDependants(
source = rchId,
removeItems = listOf(reproductiveStatus),
@@ -1577,43 +2120,48 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
if (index == 0 && isBenParentOfHoF()) {
maritalStatus.errorText = "Parents cannot be unmarried!"
}
+
+
+
when (maritalStatus.value) {
maritalStatus.entries!![0] -> {
- fatherName.required = true
- motherName.required = true
+ fatherName.required = false
+ motherName.required = false
+ updateReproductiveOptionsBasedOnAgeGender(formId = maritalStatus.id)
return triggerDependants(
source = maritalStatus,
- addItems = emptyList(),//listOf(fatherName, motherName),
+ addItems = emptyList(),
removeItems = listOf(
spouseName,
husbandName,
wifeName,
ageAtMarriage,
+ haveChildren,
)
)
}
maritalStatus.entries!![1] -> {
- if (gender.value == gender.entries!![1]) {
- fatherName.required = false
- motherName.required = false
- } else {
- fatherName.required = true
- motherName.required = true
- }
+ fatherName.required = false
+ motherName.required = false
husbandName.required = true
wifeName.required = true
+ wifeName.allCaps = true
+ husbandName.inputType = EDIT_TEXT
+ wifeName.inputType = EDIT_TEXT
+ updateReproductiveOptionsBasedOnAgeGender(formId = maritalStatus.id)
return triggerDependants(
- source = maritalStatus, addItems = when (gender.value) {
+ source = motherName, addItems = when (gender.value) {
gender.entries!![0] -> listOf(wifeName, ageAtMarriage)
- gender.entries!![1] -> listOf(husbandName, ageAtMarriage)
+ gender.entries!![1] -> listOf(husbandName, ageAtMarriage, haveChildren)
else -> listOf(spouseName, ageAtMarriage)
}, removeItems = listOf(
wifeName,
husbandName,
spouseName,
- ageAtMarriage
+ ageAtMarriage,
+ haveChildren
)
).also {
if (relationToHead.value == relationToHead.entries!![0]) {
@@ -1628,29 +2176,35 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
else -> {
husbandName.required = maritalStatus.value != maritalStatus.entries!![2]
wifeName.required = maritalStatus.value != maritalStatus.entries!![2]
- fatherName.required = true
- motherName.required = true
-// ().let {
-//// wifeName.required = it
-//// husbandName.required = it
-// spouseName.required = it
-// }
+ wifeName.allCaps = true
+ fatherName.required = false
+ motherName.required = false
+ updateReproductiveOptionsBasedOnAgeGender(formId = maritalStatus.id)
return triggerDependants(
- source = maritalStatus, addItems = when (gender.value) {
+ source = motherName, addItems = when (gender.value) {
gender.entries!![0] -> listOf(wifeName, ageAtMarriage)
- gender.entries!![1] -> listOf(husbandName, ageAtMarriage)
+ gender.entries!![1] -> listOf(husbandName, ageAtMarriage, haveChildren)
else -> listOf(spouseName, ageAtMarriage)
}, removeItems = listOf(
wifeName,
husbandName,
spouseName,
- ageAtMarriage
+ ageAtMarriage,
+ haveChildren
)
)
}
}
}
+ haveChildren.id -> {
+ if (haveChildren.entries != null) {
+ val yesIndex = 0
+ val current = haveChildren.getPosition()
+ setIsAddingChildren(current == yesIndex)
+ }
+ 0
+ }
otherRelationToHead.id -> {
validateEmptyOnEditText(otherRelationToHead)
}
@@ -1661,27 +2215,57 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
fatherName.id -> {
validateEmptyOnEditText(fatherName)
- validateAllCapsOrSpaceOnEditText(fatherName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(fatherName)
}
motherName.id -> {
validateEmptyOnEditText(motherName)
- validateAllCapsOrSpaceOnEditText(motherName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(motherName)
}
husbandName.id -> {
validateEmptyOnEditText(husbandName)
- validateAllCapsOrSpaceOnEditText(husbandName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(husbandName)
}
wifeName.id -> {
validateEmptyOnEditText(wifeName)
- validateAllCapsOrSpaceOnEditText(wifeName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(wifeName)
}
spouseName.id -> {
validateEmptyOnEditText(spouseName)
- validateAllCapsOrSpaceOnEditText(spouseName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(spouseName)
+ }
+
+ tempraryContactNo.id -> {
+ if (!isMitaninVariant) {
+ validateEmptyOnEditText(tempraryContactNo)
+ validateMobileNumberOnEditText(tempraryContactNo)
+ if (tempraryContactNo.value!!.isEmpty()) {
+ triggerforHide(
+ source = tempraryContactNoBelongsto,
+ passedIndex = index,
+ triggerIndex = index,
+ target = sendOtpBtn
+ )
+ } else if (tempraryContactNo.value!!.length >= 10) {
+ triggerDependants(
+ source = tempraryContactNoBelongsto,
+ passedIndex = index,
+ triggerIndex = index,
+ target = sendOtpBtn
+ )
+ } else {
+ triggerforHide(
+ source = tempraryContactNoBelongsto,
+ passedIndex = index,
+ triggerIndex = index,
+ target = sendOtpBtn
+ )
+ }
+ }
+ -1
}
contactNumber.id -> {
@@ -1689,6 +2273,18 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
validateMobileNumberOnEditText(contactNumber)
}
+ sendOtpBtn.id -> {
+ if (!isMitaninVariant && sendOtpBtn.isEnabled) {
+ triggerDependants(
+ source = sendOtpBtn,
+ passedIndex = index,
+ triggerIndex = index,
+ target = otpField
+ )
+ }
+ return 0
+ }
+
mobileNoOfRelation.id -> {
contactNumber.value = null
when (index) {
@@ -1709,7 +2305,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
triggerDependants(
source = mobileNoOfRelation,
removeItems = listOf(otherMobileNoOfRelation),
- addItems = emptyList(),//listOf(contactNumber)
+ addItems = emptyList(),
)
}
@@ -1717,7 +2313,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
val ret = triggerDependants(
source = mobileNoOfRelation,
- addItems = emptyList(),// listOf(contactNumber),
+ addItems = emptyList(),
removeItems = listOf(otherMobileNoOfRelation)
)
contactNumber.errorText = null
@@ -1730,7 +2326,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
contactNumber.errorText = null
triggerDependants(
source = mobileNoOfRelation,
- removeItems = emptyList(),//listOf(contactNumber),
+ removeItems = emptyList(),
addItems = listOf(otherMobileNoOfRelation)
)
}
@@ -1755,12 +2351,6 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
otherReligion.id -> validateEmptyOnEditText(otherReligion)
rchId.id -> validateRchIdOnEditText(rchId)
-
-// hasAadharNo.id -> triggerDependants(
-// source = hasAadharNo, passedIndex = index, triggerIndex = 0, target = aadharNo
-// )
-//
-// aadharNo.id -> validateAadharNoOnEditText(aadharNo)
birthCertificateNumber.id -> validateNoAlphabetSpaceOnEditText(birthCertificateNumber)
else -> -1
@@ -1769,120 +2359,287 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
private fun handleForAgeDob(formId: Int): Int {
if (formId == agePopup.id) {
-// when (ageUnit.value) {
-// ageUnit.entries?.get(0) -> {
-// age.min = 0
-// age.max = 31
-// }
-//
-// ageUnit.entries?.get(1) -> {
-// age.min = 1
-// age.max = 11
-// }
-//
-// ageUnit.entries?.get(2) -> {
-// age.min = minAgeYear.toLong()
-// age.max = maxAgeYear.toLong()
-// }
-//
-// else -> return -1
-// }
-
-// validateIntMinMax(age)
if (agePopup.errorText == null) {
ageAtMarriage.value = null
val ageAtMarriageMax = if (isBenParentOfHoF())
- getAgeFromDob(getLongFromDate(agePopup.value)) - getAgeFromDob(
- hof!!.dob
- ) else getAgeFromDob(getLongFromDate(agePopup.value))
+ getAgeFromDob(getLongFromDate(agePopup.value)) - (hof?.dob?.let {
+ getAgeFromDob(
+ it
+ )
+ } ?: 0)
+ else
+ getAgeFromDob(getLongFromDate(agePopup.value))
ageAtMarriage.max = ageAtMarriageMax.toLong()
-
}
-// when (ageUnit.value) {
-// ageUnit.entries?.get(2) -> {
-// ageAtMarriage.value = null
-// ageAtMarriage.max =
-// if (isBenParentOfHoF())
-// age.value!!.toLong() - getAgeFromDob(
-// hof!!.dob
-// ) else age.value!!.toLong()
-// cal.add(
-// Calendar.YEAR, -1 * age.value!!.toInt()
-// )
+ val age = getAgeFromDob(getLongFromDate(agePopup.value))
+ val genderIsFemale = gender.value == gender.entries?.get(1)
+
+ if (benIfDataExist == null) {
+
+ reproductiveStatus.inputType = DROPDOWN
+
+ when {
+
+ !genderIsFemale -> {
+ reproductiveStatus.entries = emptyList().toTypedArray()
+ }
+
+ age in 15..19 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array1)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array1
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ }
+
+ age in 20..49 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array3)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array3
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ }
+
+ age >= 50 -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array5)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array5
+ }
+
+ else -> reproductiveStatus.entries = emptyList().toTypedArray()
+
+ }
+
+// val updatedReproductiveOptions = when {
+// !genderIsFemale -> emptyList()
+// age in 15..19 -> when (maritalStatus.value) {
+// maritalStatus.entries!![0] -> {
+// listOf(
+// "Adolescent Girl"
+// )
+// }
+// maritalStatus.entries!![1] -> {
+// listOf(
+// "Adolescent Girl", "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
+// else -> {
+// listOf(
+// "Adolescent Girl", "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
// }
//
-// ageUnit.entries?.get(1) -> {
-// cal.add(
-// Calendar.MONTH, -1 * age.value!!.toInt()
-// )
+// age in 20..49 -> when (maritalStatus.value) {
+// maritalStatus.entries!![0] -> {
+// listOf(
+// "Not Applicable"
+// )
+// }
+// maritalStatus.entries!![1] -> {
+// listOf(
+// "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
+// else -> {
+// listOf(
+// "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
// }
//
-// ageUnit.entries?.get(0) -> {
-// cal.add(
-// Calendar.DAY_OF_YEAR, -1 * age.value!!.toInt()
-// )
- }
+// age >= 50 -> listOf("Elderly Woman")
+// else -> emptyList()
// }
-// val year = cal.get(Calendar.YEAR)
-// val month = cal.get(Calendar.MONTH) + 1
-// val day = cal.get(Calendar.DAY_OF_MONTH)
-// val newDob =
-// "${if (day > 9) day else "0$day"}-${if (month > 9) month else "0$month"}-$year"
-// if (dob.value != newDob) {
-// dob.value = newDob
-// dob.errorText = null
+//
+// reproductiveStatus.entries = updatedReproductiveOptions.toTypedArray()
+
+ reproductiveStatus.value = null
+ if (reproductiveStatus.entries?.size == 1) {
+ reproductiveStatus.value = reproductiveStatus.entries?.get(0)
+ }
+
+ } else {
+
+ val saved = benIfDataExist
+ if (saved != null) {
+ val storedEnglishStatus = saved.genDetails?.reproductiveStatus
+ reproductiveStatus.value = if (storedEnglishStatus != null) {
+ listOf(
+ R.array.nbr_reproductive_status_array1,
+ R.array.nbr_reproductive_status_array2,
+ R.array.nbr_reproductive_status_array3,
+ R.array.nbr_reproductive_status_array4,
+ R.array.nbr_reproductive_status_array5
+ ).firstNotNullOfOrNull { getLocalValueInArray(it, storedEnglishStatus) } ?: storedEnglishStatus
+ } else null
+ }
+ reproductiveStatus.inputType = DROPDOWN
+
+// when (reproductiveStatus.value) {
+// "Adolescent Girl" -> {
+// agePopup.max = yearsAgo(15)
+// agePopup.min = yearsAgo(19)
+// }
+//
+// "Eligible Couple" -> {
+// agePopup.max = yearsAgo(15)
+// agePopup.min = yearsAgo(49)
+// }
+//
+// "Pregnant Woman", "Postnatal Mother", "Permanently Sterilised" -> {
+// agePopup.max = yearsAgo(20)
+// agePopup.min = yearsAgo(49)
+// }
+//
+// "Elderly Woman" -> {
+// agePopup.max = yearsAgo(50)
+// agePopup.min = yearsAgo(100)
+// }
// }
-// }
-// }
+
+ when {
+
+ !genderIsFemale -> {
+ reproductiveStatus.entries = emptyList().toTypedArray()
+ }
+
+ age in 15..19 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array1)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array1
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ }
+
+ age in 20..49 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array3)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array3
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ }
+
+ age >= 50 -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array5)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array5
+ }
+
+ else -> reproductiveStatus.entries = emptyList().toTypedArray()
+
+ }
+
+// reproductiveStatus.entries = updatedReproductiveOptions.toTypedArray()
+
+ }
+ }
+
val listChanged = if (hasThirdPage()) triggerDependants(
source = rchId,
addItems = listOf(reproductiveStatus),
removeItems = emptyList(),
position = -2
) else {
+ fatherName.required = false
+ motherName.required = false
triggerDependants(
source = rchId,
removeItems = listOf(reproductiveStatus),
addItems = emptyList()
)
} != -1
+
val listChanged2 = triggerDependants(
age = getAgeFromDob(getLongFromDate(agePopup.value)),
-// ageUnit = ageUnit,
ageTriggerRange = Range(4, 14),
-// ageUnitTriggerIndex = 2,
target = childRegisteredAtSchool,
placeAfter = religion,
targetSideEffect = listOf(typeOfSchool)
) != -1
+
val listChanged3 =
if (maritalStatus.inputType == TEXT_VIEW) -1 else {
- if (getAgeFromDob(getLongFromDate(agePopup.value)) <= Konstants.maxAgeForAdolescent) triggerDependants(
- source = rchId,
- addItems = listOf(birthCertificateNumber, placeOfBirth),
- removeItems = listOf(
- husbandName,
- wifeName,
- spouseName,
- ageAtMarriage,
- dateOfMarriage,
- maritalStatus
- ),
- position = -2
- ) else {
+
+ if (getYearsFromDate(agePopup.value.toString()) <= Konstants.maxAgeForAdolescent) {
+ fatherName.required = false
+ motherName.required = false
+
+ triggerDependants(
+ source = rchId,
+ addItems = listOf(birthCertificateNumber, placeOfBirth),
+ removeItems = listOf(
+ husbandName,
+ wifeName,
+ spouseName,
+ ageAtMarriage,
+ dateOfMarriage,
+ maritalStatus,
+ reproductiveStatus,
+ haveChildren
+ ),
+ position = -2
+ )
+
+ } else {
maritalStatus.value = null
triggerDependants(
source = gender,
removeItems = listOf(birthCertificateNumber, placeOfBirth),
addItems = listOf(maritalStatus)
)
+ if (gender.value == gender.entries!![1]) {
+ triggerDependants(
+ source = rchId,
+ removeItems = listOf(),
+ addItems = listOf(reproductiveStatus),
+ position = -2
+ )
+
+ } else {
+ triggerDependants(
+ source = rchId,
+ removeItems = listOf(reproductiveStatus),
+ addItems = listOf()
+ )
+ }
}
} != -1
val listChanged4 =
if (maritalStatus.inputType == TEXT_VIEW) -1 else {
- if (getAgeFromDob(getLongFromDate(agePopup.value)) <= Konstants.maxAgeForAdolescent || gender.value == gender.entries!![1]) {
+ if (getYearsFromDate(agePopup.value.toString()) <= Konstants.maxAgeForAdolescent || gender.value == gender.entries!![1]) {
triggerDependants(
source = religion,
removeItems = emptyList(),
@@ -1896,23 +2653,81 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
)
}
} != -1
- return if (listChanged || listChanged2 || listChanged3 || listChanged4)
- 1
- else
- -1
+
+ return if (listChanged || listChanged2 || listChanged3 || listChanged4) 1 else -1
}
- private fun isBenParentOfHoF() =
- relationToHead.value == relationToHead.entries!![0] || relationToHead.value == relationToHead.entries!![1]
+ private fun getReproductiveStatusEnglishValue(): String {
+ val localized = reproductiveStatus.value?.trim() ?: return ""
+ return listOf(
+ R.array.nbr_reproductive_status_array1,
+ R.array.nbr_reproductive_status_array2,
+ R.array.nbr_reproductive_status_array3,
+ R.array.nbr_reproductive_status_array4,
+ R.array.nbr_reproductive_status_array5
+ ).firstNotNullOfOrNull { getEnglishValueInArray(it, localized) } ?: localized
+ }
+
+ private fun validateReproductiveStatusField(genderIsFemale: Boolean, age: Int): Int {
+ val reproEnglish = getReproductiveStatusEnglishValue()
+ if ((genderIsFemale &&
+ age in 15..19 &&
+ maritalStatus.value == maritalStatus.entries!![1] &&
+ reproEnglish == "Adolescent Girl") ||
+ (genderIsFemale &&
+ age in 20..49 &&
+ maritalStatus.value == maritalStatus.entries!![1] &&
+ reproEnglish == "Not Applicable")) {
+ reproductiveStatus.inputType = DROPDOWN
+
+ }
+// reproductiveStatus.isEnabled = (genderIsFemale &&
+// age in 15..19 &&
+// maritalStatus.value == maritalStatus.entries!![1] &&
+// reproductiveStatus.value == "Adolescent Girl") ||
+// (genderIsFemale &&
+// age in 20..49 &&
+// maritalStatus.value == maritalStatus.entries!![1] &&
+// reproductiveStatus.value == "Not Applicable")
+
+ return 1
+ }
+
+ private fun isBenParentOfHoF(): Boolean {
+ val value = relationToHead.value ?: return false
+ val parentRelations = setOf(
+ relationToHeadListDefault[0], // Mother
+ relationToHeadListDefault[1], // Father
+ relationToHeadListDefault[10], // Grand Father
+ relationToHeadListDefault[11], // Grand Mother
+ relationToHeadListDefault[12], // Father in Law
+ relationToHeadListDefault[13], // Mother in Law
+ )
+ return value in parentRelations
+ }
fun getIndexOfAgeAtMarriage() = getIndexOfElement(ageAtMarriage)
fun getIndexOfContactNumber() = getIndexOfElement(contactNumber)
fun getIndexOfMaritalStatus() = getIndexOfElement(maritalStatus)
+ fun getTempMobileNoStatus() = getIndexOfElement(tempraryContactNo)
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as BenRegCache).let { ben ->
// Page 001
+ ben.isDeathValue = beneficiaryStatus.value
+ ben.isDeath = beneficiaryStatus.entries?.indexOf(beneficiaryStatus.value ?: "") == 1
+ ben.dateOfDeath = dateOfDeath.value
+ ben.timeOfDeath = timeOfDeath.value
+ ben.reasonOfDeath = reasonOfDeath.value
+ ben.reasonOfDeathId =
+ reasonOfDeath.entries?.indexOf(reasonOfDeath.value ?: "")?.takeIf { it != -1 } ?: -1
+ ben.placeOfDeath = placeOfDeath.value
+ ben.placeOfDeathId =
+ placeOfDeath.entries?.indexOf(placeOfDeath.value ?: "")?.takeIf { it != -1 } ?: -1
+ ben.otherPlaceOfDeath = otherPlaceOfDeath.value
+
+
ben.userImage = pic.value
ben.regDate = getLongFromDate(dateOfReg.value!!)
ben.firstName = firstName.value
@@ -1921,22 +2736,8 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
ben.age = (getAgeFromDob(getLongFromDate(agePopup.value)))
ben.ageUnitId = 3
ben.ageUnit = AgeUnit.YEARS
-// ben.ageUnitId = when (ageUnit.value) {
-// ageUnit.entries!![2] -> 3
-// ageUnit.entries!![1] -> 2
-// ageUnit.entries!![0] -> 1
-// else -> 0
-// }
-// ben.ageUnit = when (ben.ageUnitId) {
-// 3 -> AgeUnit.YEARS
-// 2 -> AgeUnit.MONTHS
-// 1 -> AgeUnit.DAYS
-// else -> null
-// }
ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
ben.isKid = !ben.isAdult
-
-// ben.registrationType = getTypeFromAge(ben.age, ben.ageUnit)
ben.genderId = when (gender.value) {
gender.entries!![0] -> 1
gender.entries!![1] -> 2
@@ -1958,8 +2759,11 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
getEnglishValueInArray(R.array.nbr_relationship_to_head_src, relationToHead.value)
ben.familyHeadRelationOther = otherRelationToHead.value
ben.mobileNoOfRelationId = if (isHoF) 1 else mobileNoOfRelation.getPosition()
+ ben.tempMobileNoOfRelationId = if (isMitaninVariant) 0 else if (isHoF) 1 else tempraryContactNoBelongsto.getPosition()
ben.mobileNoOfRelation =
mobileNoOfRelation.getEnglishStringFromPosition(ben.mobileNoOfRelationId)
+ /* ben.mobileNoOfRelation =
+ tempraryContactNoBelongsto.getEnglishStringFromPosition(ben.mobileNoOfRelationId)*/
ben.mobileOthers = otherMobileNoOfRelation.value
ben.contactNumber =
if (ben.mobileNoOfRelationId == 5) familyHeadPhoneNo!!.toLong() else contactNumber.value!!.toLong()
@@ -1976,18 +2780,7 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
ben.kidDetails?.typeOfSchool =
typeOfSchool.getEnglishStringFromPosition(typeOfSchool.getPosition())
ben.rchId = rchId.value
-// ben.hasAadhar = hasAadharNo.value?.let {
-// it == hasAadharNo.entries!!.first()
-// }?.also {
-// if (it)
-// ben.hasAadharId = 1
-// else
-// ben.hasAadharId = 2
-// if (it)
-// ben.aadharNum = aadharNo.value?.let {
-// "*".repeat(8) + it.takeLast(4)
-// }
-// }
+
ben.genDetails?.maritalStatusId = maritalStatus.getPosition()
ben.genDetails?.maritalStatus =
maritalStatus.getEnglishStringFromPosition(ben.genDetails?.maritalStatusId ?: 0)
@@ -1996,26 +2789,39 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
?: spouseName.value.takeIf { !it.isNullOrEmpty() }
ben.genDetails?.ageAtMarriage =
ageAtMarriage.value?.toInt() ?: 0
- ben.genDetails?.marriageDate =
- timeStampDateOfMarriageFromSpouse.takeIf { it != null }?.also {
- ben.genDetails?.ageAtMarriage =
- (TimeUnit.MILLISECONDS.toDays(it - ben.dob) / 365).toInt()
- } ?: run {
- dateOfMarriage.value?.let { getLongFromDate(it) }
- ?: run {
- ben.genDetails?.ageAtMarriage?.takeIf { it > 0 }?.let {
- getDoMFromDoR(
- if (ben.genDetails?.ageAtMarriage == null) 0 else (ben.age - ben.genDetails!!.ageAtMarriage),
- ben.regDate
- )
- }
- }
- }
+ ben.genDetails?.marriageDate = calculateMarriageDate(ben.genDetails?.ageAtMarriage!!, ben.dob)
+// ben.genDetails?.marriageDate =
+// timeStampDateOfMarriageFromSpouse.takeIf { it != null }?.also {
+// ben.genDetails?.ageAtMarriage =
+// (TimeUnit.MILLISECONDS.toDays(it - ben.dob) / 365).toInt()
+// } ?: run {
+// dateOfMarriage.value?.let { getLongFromDate(it) }
+// ?: run {
+// ben.genDetails?.ageAtMarriage?.takeIf { it > 0 }?.let {
+// getDoMFromDoR(
+// if (ben.genDetails?.ageAtMarriage == null) 0 else (ben.age - ben.genDetails!!.ageAtMarriage),
+// ben.regDate
+// )
+// }
+// }
+// }
ben.genDetails?.let { gen ->
- gen.reproductiveStatusId = reproductiveStatus.getPosition()
- gen.reproductiveStatus =
- reproductiveStatus.getEnglishStringFromPosition(gen.reproductiveStatusId)
+ val selectedValue = getReproductiveStatusEnglishValue()
+ val reproductiveMap = mapOf(
+ "Eligible Couple" to 1,
+ "Pregnant Woman" to 2,
+ "Postnatal Mother" to 3,
+ "Elderly Woman" to 4,
+ "Adolescent Girl" to 5,
+ "Permanently Sterilised" to 6,
+ "Not Applicable" to 7
+ )
+
+ val selectedId = reproductiveMap[selectedValue] ?: 0
+
+ gen.reproductiveStatusId = selectedId
+ gen.reproductiveStatus = selectedValue
}
ben.kidDetails?.birthCertificateNumber =
@@ -2094,7 +2900,23 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
babyWeight.value?.takeIf { it.isNotEmpty() }?.toDouble() ?: 0.0
+ ben.kidDetails?.birthCertificateFileBackView = fileUploadBack.value
+ ben.kidDetails?.birthCertificateFileFrontView = fileUploadFront.value
ben.isDraft = false
+ ben.isConsent = isOtpVerified
+ ben.isSpouseAdded = if (isAddSppouse == 1) {
+ true
+ } else {
+ when (ben.familyHeadRelationPosition) {
+ 5 -> true
+ 6 -> true
+ else -> false
+ }
+ }
+ ben.isChildrenAdded = false
+ ben.isMarried = (maritalStatus.getPosition() == 2)
+ ben.doYouHavechildren = (haveChildren.getPosition() == 1)
+
}
}
@@ -2105,14 +2927,418 @@ class BenRegFormDataset(context: Context, language: Languages) : Dataset(context
}
fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
- when (lastImageFormId) {
- pic.id -> {
- pic.value = dpUri.toString()
- pic.errorText = null
+
+ if (lastImageFormId == 46) {
+ fileUploadFront.value = dpUri.toString()
+ fileUploadFront.errorText = null
+
+ } else if (lastImageFormId == 47){
+ fileUploadBack.value = dpUri.toString()
+ fileUploadBack.errorText = null
+
+ } else {
+
+ pic.value = dpUri.toString()
+ pic.errorText = null
+
+
+ }
+
+
+ }
+
+
+ fun yearsAgo(years: Int): Long {
+ return Calendar.getInstance().apply {
+ val today = Calendar.getInstance().setToStartOfTheDay()
+ timeInMillis = today.timeInMillis
+ add(Calendar.YEAR, -years)
+ }.timeInMillis
+ }
+
+ private fun updateReproductiveOptionsBasedOnAgeGender(formId: Int): Int {
+ val age = getAgeFromDob(getLongFromDate(agePopup.value))
+ val genderIsFemale = gender.value == gender.entries?.get(1)
+
+ if (benIfDataExist == null) {
+ if (genderIsFemale) {
+ reproductiveStatus.inputType = DROPDOWN
+ }
+// reproductiveStatus.isEnabled = genderIsFemale
+
+ when {
+
+ !genderIsFemale -> {
+ reproductiveStatus.entries = emptyList().toTypedArray()
+ }
+
+ age in 15..19 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array1)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array1
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ }
+
+ age in 20..49 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array3)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array3
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ }
+
+ age >= 50 -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array5)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array5
+ }
+
+ else -> reproductiveStatus.entries = emptyList().toTypedArray()
+
+ }
+
+ val oldReproductiveValue = reproductiveStatus.value
+ reproductiveStatus.value = null
+ if (reproductiveStatus.entries?.size == 1) {
+ reproductiveStatus.value = reproductiveStatus.entries?.get(0)
+ } else if (oldReproductiveValue != null && reproductiveStatus.entries?.contains(oldReproductiveValue) == true) {
+ reproductiveStatus.value = oldReproductiveValue
}
+ if (maritalStatus.value != null) {
+ reproductiveStatus.inputType = DROPDOWN
+// reproductiveStatus.isEnabled = true
+ }
+ } else {
+
+// val updatedReproductiveOptions = when {
+// !genderIsFemale -> emptyList()
+// age in 15..19 -> when (maritalStatus.value) {
+// maritalStatus.entries!![0] -> {
+// listOf(
+// "Adolescent Girl"
+// )
+// }
+// maritalStatus.entries!![1] -> {
+// listOf(
+// "Adolescent Girl", "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
+// else -> {
+// listOf(
+// "Adolescent Girl", "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
+// }
+//
+// age in 20..49 -> when (maritalStatus.value) {
+// maritalStatus.entries!![0] -> {
+// listOf(
+// "Not Applicable"
+// )
+// }
+// maritalStatus.entries!![1] -> {
+// listOf(
+// "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
+// else -> {
+// listOf(
+// "Eligible Couple", "Pregnant Woman",
+// "Postnatal Mother", "Permanently Sterilised"
+// )
+// }
+// }
+//
+// age >= 50 -> listOf("Elderly Woman")
+// else -> emptyList()
+// }
+
+ when {
+
+ !genderIsFemale -> {
+ reproductiveStatus.entries = emptyList().toTypedArray()
+ }
+
+ age in 15..19 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array1)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array1
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array2)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array2
+ }
+ }
+
+ age in 20..49 -> when (maritalStatus.value) {
+ maritalStatus.entries!![0] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array3)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array3
+ }
+ maritalStatus.entries!![1] -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ else -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array4)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array4
+ }
+ }
+
+ age >= 50 -> {
+ reproductiveStatus.entries = resources.getStringArray(R.array.nbr_reproductive_status_array5)
+ reproductiveStatus.arrayId = R.array.nbr_reproductive_status_array5
+ }
+
+ else -> reproductiveStatus.entries = emptyList().toTypedArray()
+
+ }
+
+ val oldReproductiveValue2 = reproductiveStatus.value
+ reproductiveStatus.value = null
+// reproductiveStatus.entries = updatedReproductiveOptions.toTypedArray()
+ if (reproductiveStatus.entries?.size == 1) {
+ reproductiveStatus.value = reproductiveStatus.entries?.get(0)
+ } else if (oldReproductiveValue2 != null && reproductiveStatus.entries?.contains(oldReproductiveValue2) == true) {
+ reproductiveStatus.value = oldReproductiveValue2
+ }
+ validateReproductiveStatusField(genderIsFemale, age)
+
+ // Set DOB constraints based on existing reproductive status
+// when (reproductiveStatus.value) {
+// "Adolescent Girl" -> {
+// agePopup.max = yearsAgo(15)
+// agePopup.min = yearsAgo(19)
+// }
+//
+// "Eligible Couple", "Pregnant Woman", "Postnatal Mother", "Permanently Sterilised" -> {
+// agePopup.max = yearsAgo(20)
+// agePopup.min = yearsAgo(49)
+// }
+//
+// "Elderly Woman" -> {
+// agePopup.max = yearsAgo(50)
+// agePopup.min = yearsAgo(100)
+// }
+// }
+ }
+
+ if (formId == agePopup.id) {
+
+ val listChanged = if (hasThirdPage()) triggerDependants(
+ source = rchId,
+ addItems = listOf(reproductiveStatus),
+ removeItems = emptyList(),
+ position = -2
+ ) else {
+ fatherName.required = false
+ motherName.required = false
+ triggerDependants(
+ source = rchId,
+ removeItems = listOf(reproductiveStatus),
+ addItems = emptyList()
+ )
+ } != -1
+
+ val listChanged2 = triggerDependants(
+ age = getAgeFromDob(getLongFromDate(agePopup.value)),
+ ageTriggerRange = Range(4, 14),
+ target = childRegisteredAtSchool,
+ placeAfter = religion,
+ targetSideEffect = listOf(typeOfSchool)
+ ) != -1
+
+ val listChanged3 =
+ if (maritalStatus.inputType == TEXT_VIEW) -1 else {
+
+ if (getYearsFromDate(agePopup.value.toString()) <= Konstants.maxAgeForAdolescent) {
+ fatherName.required = false
+ motherName.required = false
+
+ triggerDependants(
+ source = rchId,
+ addItems = listOf(birthCertificateNumber, placeOfBirth),
+ removeItems = listOf(
+ husbandName,
+ wifeName,
+ spouseName,
+ ageAtMarriage,
+ dateOfMarriage,
+ maritalStatus,
+ reproductiveStatus,
+ haveChildren
+ ),
+ position = -2
+ )
+
+ } else {
+ if (gender.value == null) {
+ maritalStatus.value = null
+ }
+ triggerDependants(
+ source = gender,
+ removeItems = listOf(birthCertificateNumber, placeOfBirth),
+ addItems = listOf(maritalStatus)
+ )
+ if (gender.value == gender.entries!![1]) {
+ triggerDependants(
+ source = rchId,
+ removeItems = listOf(),
+ addItems = listOf(reproductiveStatus),
+ position = -2
+ )
+
+ } else {
+ triggerDependants(
+ source = rchId,
+ removeItems = listOf(reproductiveStatus),
+ addItems = listOf()
+ )
+ }
+ }
+ } != -1
+
+ val listChanged4 =
+ if (maritalStatus.inputType == TEXT_VIEW) -1 else {
+ if (getYearsFromDate(agePopup.value.toString()) <= Konstants.maxAgeForAdolescent || gender.value == gender.entries!![1]) {
+ triggerDependants(
+ source = religion,
+ removeItems = emptyList(),
+ addItems = listOf(rchId)
+ )
+ } else {
+ triggerDependants(
+ source = religion,
+ removeItems = listOf(rchId),
+ addItems = emptyList()
+ )
+ }
+ } != -1
+
+ return if (listChanged || listChanged2 || listChanged3 || listChanged4) 1 else -1
+
+ } else {
+
+ val listChanged = if (hasThirdPage()) triggerDependants(
+ source = rchId,
+ addItems = listOf(reproductiveStatus),
+ removeItems = emptyList(),
+ position = -2
+ ) else {
+ // fatherName.required = true
+ // motherName.required = true
+ triggerDependants(
+ source = rchId,
+ removeItems = listOf(reproductiveStatus),
+ addItems = emptyList()
+ )
+ }
+
+ return listChanged
+
}
}
+ private fun shouldShowMaternalDeath(gender: String?, dob: String?): Boolean {
+ Log.v("valuesOfData", "dob:$dob")
+
+ if (gender != "Female") return false
+ val age = dob?.let { dobString ->
+ val sdf = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ try {
+ val date = sdf.parse(dobString)
+ val dobInMillis = date?.time ?: return false
+ getAgeFromDob(dobInMillis)
+ } catch (e: Exception) {
+ return false
+ }
+ } ?: return false
+ return age in 15..49
+ }
+
+ private fun getMinDateFromRegistration(registrationDate: String): Long {
+ return try {
+
+ val sdf = SimpleDateFormat("dd-MM-yyyy", Locale.US)
+ val date = sdf.parse(registrationDate)
+ date?.time ?: 0L
+ } catch (e: Exception) {
+ 0L
+ }
+ }
+
+
+ private fun initializeDeathFields(
+ list: MutableList,
+ saved: BenRegCache?,
+ lastNameIndex: Int
+ ) {
+ list.add(lastNameIndex + 1, beneficiaryStatus)
+ if (saved?.isDeath == true) {
+ list.add(list.indexOf(beneficiaryStatus) + 1, dateOfDeath)
+ list.add(list.indexOf(dateOfDeath) + 1, timeOfDeath)
+ list.add(list.indexOf(timeOfDeath) + 1, reasonOfDeath)
+ list.add(list.indexOf(reasonOfDeath) + 1, placeOfDeath)
+ placeOfDeath.entries?.indexOf(saved.placeOfDeath)?.takeIf { it >= 0 }?.let { index ->
+ if (index == 8) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ }
+ }
+ }
+
+ beneficiaryStatus.value = when (saved?.isDeath) {
+ true -> BenStatus.Death.name
+ false -> BenStatus.Alive.name
+ null -> null
+ }
+ dateOfDeath.value = saved?.dateOfDeath
+ timeOfDeath.value = saved?.timeOfDeath
+ reasonOfDeath.value = saved?.reasonOfDeath
+ placeOfDeath.value = saved?.placeOfDeath
+ otherPlaceOfDeath.value = saved?.otherPlaceOfDeath
+ }
+
+ fun mapValueToBen(ben: BenRegCache?): Boolean {
+ var isUpdated = false
+ val rchIdFromBen = ben?.rchId?.takeIf { it.isNotEmpty() }?.toLong()
+ val aadharNoFromBen = ben?.aadharNum?.takeIf { it.isNotEmpty() }
+ rchId.value?.takeIf {
+ it.isNotEmpty()
+ }?.toLong()?.let {
+ if (it != rchIdFromBen) {
+ ben?.rchId = it.toString()
+ isUpdated = true
+ }
+ }
+
+ if (isUpdated) {
+ if (ben?.processed != "N")
+ ben?.processed = "U"
+ ben?.syncState = SyncState.UNSYNCED
+ }
+ return isUpdated
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/CDRFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/CDRFormDataset.kt
index ca26d5422..87e769d94 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/CDRFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/CDRFormDataset.kt
@@ -1,34 +1,41 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
-import android.widget.LinearLayout
+import android.net.Uri
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.model.BenBasicCache
import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.CDRCache
import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.InputType
+import timber.log.Timber
+import java.text.SimpleDateFormat
+import java.util.Locale
class CDRFormDataset(
- context: Context, currentLanguage: Languages
+ context: Context, currentLanguage: Languages,
+ val preferences: PreferenceDao
) : Dataset(context, currentLanguage) {
private val childName = FormElement(
id = 1,
inputType = InputType.TEXT_VIEW,
- title = "Name of the Child",
+ title = resources.getString(R.string.name_of_the_child),
required = false
)
private val dateOfBirth = FormElement(
id = 2,
inputType = InputType.TEXT_VIEW,
- title = "Date of Birth",
+ title = resources.getString(R.string.date_of_birth),
required = false
)
private val age = FormElement(
id = 3,
inputType = InputType.TEXT_VIEW,
- title = "Age",
+ title = resources.getString(R.string.age),
required = false
)
private val visitDate = FormElement(
@@ -36,55 +43,55 @@ class CDRFormDataset(
inputType = InputType.DATE_PICKER,
min = 0L,
max = System.currentTimeMillis(),
- title = "Visit Date",
+ title = resources.getString(R.string.visit_date),
required = true
)
private val gender = FormElement(
id = 5,
inputType = InputType.TEXT_VIEW,
- title = "Gender",
+ title = resources.getString(R.string.gender),
required = false
)
private val motherName = FormElement(
id = 6,
inputType = InputType.TEXT_VIEW,
- title = "Mother’s Name",
+ title = resources.getString(R.string.mother_s_name),
required = false
)
private val fatherName = FormElement(
id = 7,
inputType = InputType.TEXT_VIEW,
- title = "Father’s Name",
+ title =resources.getString(R.string.father_s_name),
required = false
)
private val address = FormElement(
id = 8,
inputType = InputType.TEXT_VIEW,
- title = "Address",
+ title = resources.getString(R.string.address),
required = false
)
private val houseNumber = FormElement(
id = 9,
- inputType = InputType.EDIT_TEXT,
- title = "House number",
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.house_number),
required = false
)
private val mohalla = FormElement(
id = 10,
- inputType = InputType.EDIT_TEXT,
- title = "Mohalla/Colony ",
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.mohalla_colony),
required = false
)
private val landmarks = FormElement(
id = 11,
- inputType = InputType.EDIT_TEXT,
- title = "Landmarks, if any ",
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.landmarks_if_any),
required = false
)
private val pincode = FormElement(
id = 12,
- inputType = InputType.EDIT_TEXT,
- title = "Pincode",
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.pincode),
etMaxLength = 6,
min = 100000,
max = 999999,
@@ -94,7 +101,7 @@ class CDRFormDataset(
private val landline = FormElement(
id = 13,
inputType = InputType.EDIT_TEXT,
- title = "Landline",
+ title = resources.getString(R.string.landline),
etMaxLength = 12,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
required = false
@@ -102,13 +109,13 @@ class CDRFormDataset(
private val mobileNumber = FormElement(
id = 14,
inputType = InputType.TEXT_VIEW,
- title = "Mobile number",
+ title = resources.getString(R.string.mobile_number),
required = false
)
private val dateOfDeath = FormElement(
id = 15,
- inputType = InputType.DATE_PICKER,
- title = "Date of death",
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.date_of_death),
min = 0L,
max = System.currentTimeMillis(),
required = true
@@ -116,38 +123,80 @@ class CDRFormDataset(
private val timeOfDeath = FormElement(
id = 16,
inputType = InputType.TIME_PICKER,
- title = "Time",
+ title = resources.getString(R.string.time),
required = false
)
private val placeOfDeath = FormElement(
id = 17,
- inputType = InputType.RADIO,
- title = "Place of Death",
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.place_of_death),
required = true,
- orientation = LinearLayout.VERTICAL,
- entries = arrayOf("Home", "Hospital", "In transit")
)
private val firstInformant = FormElement(
id = 18,
inputType = InputType.TEXT_VIEW,
- title = "Name of First Informant ",
+ title = resources.getString(R.string.name_of_first_informant),
required = false
)
private val ashaSign = FormElement(
id = 19,
inputType = InputType.EDIT_TEXT,
- title = "Signature/Name of ASHA",
+ title = resources.getString(R.string.signature_name_of_asha),
required = false
)
private val dateOfNotification = FormElement(
id = 20,
inputType = InputType.DATE_PICKER,
- title = "Date of Notification ",
+ title = resources.getString(R.string.date_of_notification),
min = 0L,
max = System.currentTimeMillis(),
required = false
)
+ private val cdrFileUpload1 = FormElement(
+ id = 21,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.cdr_form_from_anm_1),
+ required = false,
+ )
+ private val cdrFileUpload2 = FormElement(
+ id = 22,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.cdr_form_from_anm_2),
+ required = false,
+ )
+ private val cdrDeathFileUpload = FormElement(
+ id = 23,
+ inputType = InputType.FILE_UPLOAD,
+ title =resources.getString(R.string.death_certificate),
+ required = false,
+ )
+
+ private val state = FormElement(
+ id = 24,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.state),
+ required = false
+ )
+ private val district = FormElement(
+ id = 25,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.district_tehsil),
+ required = false
+ )
+ private val block = FormElement(
+ id = 26,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.block),
+ required = false
+ )
+ private val village = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.village_town_city),
+ required = false
+ )
+
suspend fun setUpPage(
ben: BenRegCache,
currentAddress: String?,
@@ -155,7 +204,7 @@ class CDRFormDataset(
currentMohalla: String?,
saved: CDRCache?
) {
- val list = listOf(
+ val list = mutableListOf(
childName,
dateOfBirth,
age,
@@ -164,19 +213,44 @@ class CDRFormDataset(
motherName,
fatherName,
address,
+ state,
+ district,
+ block,
+ village,
houseNumber,
mohalla,
- landmarks,
- pincode,
+// landmarks,
+// pincode,
landline,
mobileNumber,
dateOfDeath,
- timeOfDeath,
placeOfDeath,
firstInformant,
- ashaSign,
- dateOfNotification
+// ashaSign,
+ timeOfDeath,
+
+ dateOfNotification,
+ cdrFileUpload1, cdrFileUpload2, cdrDeathFileUpload
)
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(cdrFileUpload1)
+ list.remove(cdrFileUpload2)
+ list.remove(cdrDeathFileUpload)
+ }
+
+ val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val deathDateMillis = ben.dateOfDeath?.let {
+ try {
+ dateFormat.parse(it)?.time
+ } catch (e: Exception) {
+ Timber.tag("CDRFormDataset").e(e, "Failed to parse death date: " + it)
+ null
+ }
+ } ?: System.currentTimeMillis()
+ dateOfNotification.min = deathDateMillis
+ dateOfNotification.max = System.currentTimeMillis()
+
childName.value = "${ben.firstName} ${ben.lastName}"
dateOfBirth.value = getDateFromLong(ben.dob)
age.value =
@@ -188,16 +262,28 @@ class CDRFormDataset(
address.value = currentAddress
houseNumber.value = currentHouseNumber
mohalla.value = currentMohalla
+ dateOfDeath.value = ben.dateOfDeath
+// timeOfDeath.value =ben.timeOfDeath
+ placeOfDeath.value = ben.placeOfDeath
mobileNumber.value = ben.contactNumber.toString()
+ val user = preferences.getLoggedInUser()
+ firstInformant.value = user?.userName ?: ""
+ state.value = user?.state?.name ?: ""
+ district.value = user?.district?.name ?: ""
+ block.value = user?.block?.name ?: ""
+ village.value = user!!.villages[0].name
saved?.let { savedCdr ->
visitDate.value = savedCdr.visitDate?.let { it1 -> getDateFromLong(it1) }
landmarks.value = savedCdr.landmarks
+ cdrFileUpload2.value = savedCdr.cdr2File
+ cdrFileUpload1.value = savedCdr.cdr1File
+ cdrDeathFileUpload.value = savedCdr.cdrDeathCertFile
pincode.value = savedCdr.pincode?.toString()
landline.value = savedCdr.landline?.toString()
mobileNumber.value = savedCdr.mobileNumber.toString()
- dateOfDeath.value = getDateFromLong(savedCdr.dateOfDeath)
+// dateOfDeath.value = getDateFromLong(savedCdr.dateOfDeath)
timeOfDeath.value = savedCdr.timeOfDeath?.let { getDateFromLong(it) }
- placeOfDeath.value = savedCdr.placeOfDeath
+// placeOfDeath.value = savedCdr.placeOfDeath
firstInformant.value = savedCdr.firstInformant
ashaSign.value = savedCdr.ashaSign
dateOfNotification.value = savedCdr.dateOfNotification?.let { getDateFromLong(it) }
@@ -218,6 +304,9 @@ class CDRFormDataset(
cdr.motherName = motherName.value
cdr.fatherName = fatherName.value
cdr.address = address.value
+ cdr.cdr1File = cdrFileUpload1.value
+ cdr.cdr2File = cdrFileUpload2.value
+ cdr.cdrDeathCertFile = cdrDeathFileUpload.value
cdr.houseNumber = houseNumber.value
cdr.mohalla = mohalla.value
cdr.landmarks = landmarks.value
@@ -225,11 +314,57 @@ class CDRFormDataset(
cdr.landline = landline.value?.toLong()
cdr.mobileNumber = mobileNumber.value!!.toLong()
cdr.dateOfDeath = getLongFromDate(dateOfDeath.value)
- cdr.timeOfDeath = timeOfDeath.value?.let { getLongFromDate(it) }
+ cdr.timeOfDeath = convertTimeToLong(timeOfDeath.value)
cdr.placeOfDeath = placeOfDeath.value
cdr.firstInformant = firstInformant.value
cdr.ashaSign = ashaSign.value
cdr.dateOfNotification = dateOfNotification.value?.let { getLongFromDate(it) }
}
}
+
+ fun getIndexOfCDR1() = getIndexById(cdrFileUpload1.id)
+ fun getIndexOfCDR2() = getIndexById(cdrFileUpload2.id)
+ fun getIndexOfIsDeathCertificate() = getIndexById(cdrDeathFileUpload.id)
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+
+ when (lastImageFormId) {
+ 21 -> {
+ cdrFileUpload1.value = dpUri.toString()
+ cdrFileUpload1.errorText = null
+ }
+
+ 22 -> {
+ cdrFileUpload2.value = dpUri.toString()
+ cdrFileUpload2.errorText = null
+ }
+
+ 23 -> {
+ cdrDeathFileUpload.value = dpUri.toString()
+ cdrDeathFileUpload.errorText = null
+ }
+
+ }
+ }
+
+ private fun convertTimeToLong(value: Any?): Long {
+ return when (value) {
+ is Long -> value
+ is String -> {
+ try {
+ val parts = value.split(":")
+ val hours = parts.getOrNull(0)?.toIntOrNull() ?: return 0L
+ val minutes = parts.getOrNull(1)?.toIntOrNull() ?: return 0L
+ return (hours * 60 * 60 * 1000 + minutes * 60 * 1000).toLong()
+ } catch (e: Exception) {
+ 0L
+ }
+ }
+
+ else -> 0L
+ }
+ }
+
+
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/ChildFormData.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/ChildFormData.kt
new file mode 100644
index 000000000..feaea18c7
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/ChildFormData.kt
@@ -0,0 +1,8 @@
+package org.piramalswasthya.sakhi.configuration
+
+data class ChildFormData(
+ val firstName: String,
+ val dob: String,
+ val age: Int,
+ val gender: String
+)
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/ChildRegistrationDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/ChildRegistrationDataset.kt
index 14971a939..5dc0caa89 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/ChildRegistrationDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/ChildRegistrationDataset.kt
@@ -1,6 +1,7 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.database.room.SyncState
import org.piramalswasthya.sakhi.helpers.Languages
@@ -22,7 +23,7 @@ class ChildRegistrationDataset(
private val dateOfReg = FormElement(
id = 1,
inputType = InputType.DATE_PICKER,
- title = context.getString(R.string.nbr_dor),
+ title = resources.getString(R.string.nbr_dor),
arrayId = -1,
required = true,
min = getMinDateOfReg(),
@@ -32,14 +33,14 @@ class ChildRegistrationDataset(
private val childName = FormElement(
id = 2,
inputType = InputType.EDIT_TEXT,
- title = "Name of Child",
+ title = resources.getString(R.string.str_name_of_child),
required = false,
hasDependants = false
)
private val rchId = FormElement(
id = 3,
inputType = InputType.EDIT_TEXT,
- title = "RCH ID No. of Child",
+ title = resources.getString(R.string.str_rch_id_of_child),
arrayId = -1,
required = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
@@ -50,7 +51,7 @@ class ChildRegistrationDataset(
private val dob = FormElement(
id = 4,
inputType = InputType.DATE_PICKER,
- title = "Date of Birth",
+ title = resources.getString(R.string.nbr_dob),
arrayId = -1,
required = true,
min = getMinDateOfReg(),
@@ -61,8 +62,8 @@ class ChildRegistrationDataset(
private val childGender = FormElement(
id = 5,
inputType = InputType.RADIO,
- title = "Sex of Child",
- entries = arrayOf("Male", "Female"),
+ title = resources.getString(R.string.str_sex_of_child),
+ entries = arrayOf(resources.getString(R.string.male), resources.getString(R.string.female)),
isEnabled = false,
required = false,
hasDependants = false
@@ -72,7 +73,7 @@ class ChildRegistrationDataset(
private val motherName = FormElement(
id = 6,
inputType = InputType.EDIT_TEXT,
- title = "Mother's Name",
+ title = resources.getString(R.string.mother_s_name),
arrayId = -1,
required = true,
allCaps = true,
@@ -84,7 +85,7 @@ class ChildRegistrationDataset(
private val fatherName = FormElement(
id = 7,
inputType = InputType.EDIT_TEXT,
- title = "Father's Name",
+ title = resources.getString(R.string.father_s_name),
arrayId = -1,
required = true,
allCaps = true,
@@ -97,12 +98,8 @@ class ChildRegistrationDataset(
private val mobileNumberOf = FormElement(
id = 8,
inputType = InputType.RADIO,
- title = "Whose Mobile Number",
- entries = arrayOf(
- "Mother",
- "Father",
- "Others"
- ),
+ title = resources.getString(R.string.str_whose_mobile_number),
+ entries = resources.getStringArray(R.array.cr_mobile_no_of_array),
isEnabled = false,
required = false,
@@ -112,7 +109,7 @@ class ChildRegistrationDataset(
private val mobileNumber = FormElement(
id = 9,
inputType = InputType.EDIT_TEXT,
- title = "Mobile No.",
+ title = resources.getString(R.string.str_mobile_no),
arrayId = -1,
required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
@@ -126,7 +123,7 @@ class ChildRegistrationDataset(
private val rchIdMother = FormElement(
id = 10,
inputType = InputType.EDIT_TEXT,
- title = "RCH ID No. of Mother",
+ title = resources.getString(R.string.str_rch_id_of_mother),
arrayId = -1,
required = false,
isEnabled = false,
@@ -140,43 +137,66 @@ class ChildRegistrationDataset(
private val birthCertificateNo = FormElement(
id = 11,
inputType = InputType.EDIT_TEXT,
- title = "Birth Certificate Number",
+ title = resources.getString(R.string.str_birth_cert_number),
arrayId = -1,
required = false,
)
- private val weightAtBirth = FormElement(
+
+ private var weightAtBirth = FormElement(
+ id = 11,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.str_weight_at_birth_gram),
+ required = false,
+ hasDependants = false,
+ etMaxLength = 4,
+ min = 500,
+ max = 6000,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+ /* private val weightAtBirth = FormElement(
id = 12,
inputType = InputType.EDIT_TEXT,
- title = "Weight at Birth (kg)",
+ title = resources.getString(R.string.str_weight_at_birth),
arrayId = -1,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL,
minDecimal = 0.5,
maxDecimal = 7.0,
etMaxLength = 3,
required = false,
- )
+ )*/
private val placeOfBirth = FormElement(
id = 13,
inputType = InputType.DROPDOWN,
- title = "Place of Birth",
- entries = arrayOf(
- "District Hospital",
- "Community Health Centre",
- "Primary Health Centre",
- "Sub Centre",
- "Other Public Facility",
- "Accredited Private Hospital",
- "Other Private Hospital ",
- "Home",
- "Sub District Hospital",
- "Medical College Hospital",
- "In Transit"
- ),
+ title = resources.getString(R.string.str_place_of_birth),
+ arrayId = R.array.cr_place_of_birth_array,
+ entries = resources.getStringArray(R.array.cr_place_of_birth_array),
required = false,
hasDependants = false
)
+ private val headLine = FormElement(
+ id = 13,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.cr_birth_cert_uploads),
+ headingLine = false,
+ required = false,
+ )
+ private val fileUploadFront = FormElement(
+ id = 14,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.front_side),
+ required = false,
+ )
+ private val fileUploadBack = FormElement(
+ id = 15,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.back_side),
+ required = false,
+ )
+
+ fun getIndexOfBirthCertificateFrontPath() = getIndexById(fileUploadFront.id)
+ fun getIndexOfBirthCertificateBackPath() = getIndexById(fileUploadBack.id)
suspend fun setUpPage(
motherBen: BenRegCache?,
@@ -196,7 +216,11 @@ class ChildRegistrationDataset(
rchIdMother,
birthCertificateNo,
weightAtBirth,
- placeOfBirth
+ placeOfBirth,
+ headLine,
+ fileUploadFront,
+ fileUploadBack
+
)
dateOfReg.value = getDateFromLong(System.currentTimeMillis())
dateOfReg.min = deliveryOutcomeCache?.dateOfDelivery
@@ -205,24 +229,36 @@ class ChildRegistrationDataset(
fatherName.value = it
} ?: run {
fatherName.inputType = InputType.EDIT_TEXT
+ fatherName.isEnabled = true
}
motherName.value = "${it.firstName} ${it.lastName ?: ""}"
mobileNumberOf.value = mobileNumberOf.entries?.first()
mobileNumber.value = it.contactNumber.toString()
rchIdMother.value = it.rchId
+ } ?: run {
+ motherName.isEnabled = true
+ fatherName.isEnabled = true
+ mobileNumber.isEnabled = true
+ mobileNumberOf.isEnabled = true
}
deliveryOutcomeCache?.dateOfDelivery?.let {
dob.value = getDateFromLong(it)
+ } ?: run {
+ dob.isEnabled = true
}
deliveryOutcomeCache?.placeOfDelivery?.let {
- placeOfBirth.value = it
+ placeOfBirth.value = getLocalValueInArray(R.array.cr_place_of_birth_array, it) ?: it
}
infantRegCache?.let { infant ->
childName.value = infant.babyName
- weightAtBirth.value = infant.weight?.toString()
+ weightAtBirth.value =formatWeightInGrams(infant.weight)
infant.gender?.let {
childGender.value = childGender.entries?.get(it.ordinal)
+ } ?: run {
+ childGender.isEnabled = true
}
+ } ?: run {
+ childGender.isEnabled = true
}
@@ -231,6 +267,16 @@ class ChildRegistrationDataset(
}
+ fun formatWeightInGrams(weight: Double?): String {
+ if (weight == null) return ""
+ val grams = if (weight < 50) weight * 1000 else weight
+ return if (grams % 1 == 0.0) {
+ "${grams.toInt()}"
+ } else {
+ "${grams}"
+ }
+ }
+
override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
return when (formId) {
childName.id -> validateAllCapsOrSpaceOnEditText(childName)
@@ -238,7 +284,8 @@ class ChildRegistrationDataset(
rchIdMother.id -> validateRchIdOnEditText(rchIdMother)
mobileNumber.id -> validateMobileNumberOnEditText(mobileNumber)
fatherName.id -> validateAllCapsOrSpaceOnEditText(fatherName)
- weightAtBirth.id -> validateDoubleMinMax(weightAtBirth)
+ weightAtBirth.id -> validateWeightOnEditText(weightAtBirth)
+ //validateDoubleMinMax(weightAtBirth)
birthCertificateNo.id -> validateNoAlphabetSpaceOnEditText(birthCertificateNo)
else -> -1
@@ -271,6 +318,17 @@ class ChildRegistrationDataset(
return BenRegCache(
ashaId = user.userId,
beneficiaryId = 0,
+ isDeath = motherBen.isDeath,
+ isDeathValue=motherBen.isDeathValue,
+ dateOfDeath=motherBen.dateOfDeath,
+ timeOfDeath=motherBen.timeOfDeath,
+ reasonOfDeath=motherBen.reasonOfDeath,
+ reasonOfDeathId=motherBen.reasonOfDeathId,
+ placeOfDeath=motherBen.placeOfDeath,
+ placeOfDeathId=motherBen.placeOfDeathId,
+ otherPlaceOfDeath=motherBen.otherPlaceOfDeath,
+
+
createdDate = System.currentTimeMillis(),
updatedBy = user.userName,
createdBy = user.userName,
@@ -306,10 +364,13 @@ class ChildRegistrationDataset(
processed = "N",
kidDetails = BenRegKid(
childName = childName.value,
- birthPlace = placeOfBirth.value,
+ birthPlace = getEnglishValueInArray(R.array.cr_place_of_birth_array, placeOfBirth.value),
birthPlaceId = placeOfBirth.getPosition(),
- birthCertificateNumber = birthCertificateNo.value
- )
+ birthCertificateNumber = birthCertificateNo.value,
+ birthCertificateFileFrontView = fileUploadFront.value.toString(),
+ birthCertificateFileBackView = fileUploadBack.value.toString()
+ ),
+ isConsent = false
)
}
@@ -326,4 +387,18 @@ class ChildRegistrationDataset(
else
10
}
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ if (lastImageFormId == 14) {
+ fileUploadFront.value = dpUri.toString()
+ fileUploadFront.errorText = null
+
+ } else {
+ fileUploadBack.value = dpUri.toString()
+ fileUploadBack.errorText = null
+
+ }
+
+
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/Dataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/Dataset.kt
index 30f00b00e..8c453482f 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/Dataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/Dataset.kt
@@ -2,11 +2,15 @@ package org.piramalswasthya.sakhi.configuration
import android.content.Context
import android.content.res.Resources
+import android.util.Log
import android.util.Range
import androidx.annotation.StringRes
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Konstants.english
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
import org.piramalswasthya.sakhi.model.FormElement
@@ -18,13 +22,14 @@ import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
+import kotlin.math.abs
/**
* Base class to be extended to use as a sandwich between viewModel and repository objects.
* @see org.piramalswasthya.sakhi.adapters.FormInputAdapter
*/
-abstract class Dataset(context: Context, currentLanguage: Languages) {
+abstract class Dataset(context: Context, val currentLanguage: Languages) {
/**
* Resource object of currently selected language. To be used to get language specific strings from strings.xml.
@@ -41,13 +46,18 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
* Helper function to get resource instance chosen language.
*/
- protected companion object {
+ companion object {
fun getLongFromDate(dateString: String?): Long {
+ if (dateString.isNullOrEmpty()) return 0L
val f = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
- val date = dateString?.let { f.parse(it) }
- return date?.time ?: 0L
+ return try {
+ f.parse(dateString)?.time ?: 0L
+ } catch (e: java.text.ParseException) {
+ 0L
+ }
}
+
fun getFinancialYear(dateString: String?): String? {
val f = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
val date = dateString?.let { f.parse(it) }
@@ -80,6 +90,30 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
+ fun dateFormate(dateStr: String): String? {
+ val inputFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
+ val outputFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+
+ val dateResponse = inputFormat.parse(dateStr)
+ return outputFormat.format(dateResponse!!)
+
+
+ }
+
+ fun dateReverseFormat(dateStr: String): String? {
+ if (dateStr.isEmpty()) return null
+
+ return try {
+ val inputFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val outputFormat = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
+
+ val dateResponse = inputFormat.parse(dateStr) ?: return null
+ outputFormat.format(dateResponse)
+ } catch (e: Exception) {
+ null
+ }
+ }
+
fun getMinDateOfReg(): Long {
return Calendar.getInstance().apply {
set(Calendar.YEAR, 2020)
@@ -91,6 +125,7 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
+ private val listMutex = Mutex()
private val list = mutableListOf()
private val _listFlow = MutableStateFlow>(emptyList())
@@ -108,11 +143,18 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
protected fun FormElement.getStringFromPosition(position: Int): String? {
- return if (position <= 0) null else entries?.get(position - 1)
+ return if (position <= 0) null else entries?.getOrNull(position - 1)
+ }
+
+ protected fun FormElement.getStringSpauseFromPosition(position: Int): String? {
+ return if (position <= 0) entries?.getOrNull(1) else entries?.getOrNull(position - 1)
}
protected fun FormElement.getEnglishStringFromPosition(position: Int): String? {
- return if (position <= 0) null else englishResources.getStringArray(arrayId)[position - 1]
+ return if (position <= 0) null else {
+ val array = englishResources.getStringArray(arrayId)
+ return if (position in 1..array.size) array[position - 1] else null
+ }
}
@@ -121,29 +163,37 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
abstract fun mapValues(cacheModel: FormDataModel, pageNumber: Int = 0)
protected fun getIndexOfElement(element: FormElement) = list.indexOf(element)
suspend fun updateList(formId: Int, index: Int) {
- list.find { it.id == formId }?.let {
- if (it.inputType == InputType.DROPDOWN) {
- it.errorText = null
+ listMutex.withLock {
+ list.find { it.id == formId }?.let {
+ if (it.inputType == InputType.DROPDOWN) {
+ it.errorText = null
+ }
}
- }
- val updateIndex = handleListOnValueChanged(formId, index)
- if (updateIndex != -1) {
- val newList = list.toMutableList()
+ val updateIndex = handleListOnValueChanged(formId, index)
+ if (updateIndex != -1) {
+ val newList = list.toMutableList()
// if (updateUIForCurrentElement) {
// Timber.d("Updating UI element ...")
// newList[updateIndex] = list[updateIndex].cloneForm()
// updateUIForCurrentElement = false
// }
- Timber.d("Emitting ${newList}}")
+ Timber.d("Emitting ${newList}}")
// _listFlow.emit(emptyList())
- _listFlow.emit(newList)
+ _listFlow.emit(newList)
+ }
}
}
protected suspend fun setUpPage(mList: List) {
- list.clear()
- list.addAll(mList)
- _listFlow.emit(list.toMutableList())
+ listMutex.withLock {
+ try {
+ list.clear()
+ list.addAll(mList)
+ _listFlow.emit(list.toMutableList())
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
}
@@ -163,9 +213,8 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
listIndex
} else -1
} else {
- val anyRemoved = list.removeAll(
- target
- )
+ var anyRemoved = false
+ target.forEach { if (list.remove(it)) anyRemoved = true }
if (anyRemoved) {
targetSideEffect?.let { sideEffectList ->
@@ -173,7 +222,7 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
it.value = null
it.errorText = null
}
- list.removeAll(sideEffectList)
+ sideEffectList.forEach { list.remove(it) }
}
target.forEach {
it.value = null
@@ -200,15 +249,14 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
listIndex
} else -1
} else {
- val anyRemoved = list.removeAll(
- target
- )
+ var anyRemoved = false
+ target.forEach { if (list.remove(it)) anyRemoved = true }
if (anyRemoved) {
target.forEach {
it.value = null
}
targetSideEffect?.let { sideEffectList ->
- list.removeAll(sideEffectList)
+ sideEffectList.forEach { list.remove(it) }
sideEffectList.forEach { it.value = null }
}
list.indexOf(source)
@@ -227,26 +275,52 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
return if (passedIndex == triggerIndex) {
if (!list.contains(target)) {
val listIndex = list.indexOf(source)
- list.add(
- listIndex + 1, target
- )
+ val safeIndex = (listIndex + 1).coerceAtMost(list.size)
+ list.add(safeIndex, target)
listIndex
- } else -1
+ } else {
+ -1
+ }
} else {
- val anyRemoved = list.remove(
- target
- )
+ val anyRemoved = list.remove(target)
if (anyRemoved) {
+ target.value = null
+ targetSideEffect?.forEach { element ->
+ if (list.contains(element)) {
+ list.remove(element)
+ element.value = null
+ }
+ }
+ list.indexOf(source)
+ } else {
+ -1
+ }
+ }
+ }
+
+
+
+ protected fun triggerforHide(
+ source: FormElement,
+ passedIndex: Int,
+ triggerIndex: Int,
+ target: FormElement,
+ targetSideEffect: List? = null
+ ): Int {
+ val anyRemoved = list.remove(target)
+ return if (anyRemoved) {
target.value = null
targetSideEffect?.let { sideEffectList ->
- list.removeAll(sideEffectList)
+ sideEffectList.forEach { list.remove(it) }
sideEffectList.forEach { it.value = null }
}
list.indexOf(source)
} else -1
- }
+
+
}
+
protected fun triggerDependants(
age: Int,
// ageUnit: FormElement,
@@ -276,7 +350,7 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
if (anyRemoved) {
target.value = null
targetSideEffect?.let { sideEffectList ->
- list.removeAll(sideEffectList)
+ sideEffectList.forEach { list.remove(it) }
sideEffectList.forEach { it.value = null }
}
302
@@ -284,6 +358,28 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
}
+ protected fun infantTriggerDependants(
+ source: FormElement,
+ removeItems: List,
+ addItems: List,
+ position: Int = -1,
+ ): Int {
+
+ removeItems.forEach { it.value = null }
+ removeItems.forEach { list.remove(it) }
+
+ addItems.forEach {
+ if (list.contains(it)) list.remove(it)
+ }
+
+ // FORCE ADD AT BOTTOM → correct sequence always
+ val addPosition = list.lastIndex + 1
+
+ list.addAll(addPosition, addItems)
+
+ return addPosition
+ }
+
protected fun triggerDependants(
source: FormElement,
removeItems: List,
@@ -293,7 +389,7 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
removeItems.forEach {
it.value = null
}
- list.removeAll(removeItems)
+ removeItems.forEach { list.remove(it) }
// list.removeAll(addItems)
addItems.forEach {
if (list.contains(it)) list.remove(it)
@@ -364,11 +460,19 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
add(Calendar.WEEK_OF_YEAR, 40)
}.timeInMillis
+ protected fun getANCMaxFromLmp(lmp: Long) =
+
+ Calendar.getInstance().apply {
+ timeInMillis = lmp
+ add(Calendar.DAY_OF_YEAR, 294)
+ // add(Calendar.WEEK_OF_YEAR, 42)
+ }.timeInMillis
+
protected fun getMinFromMaxForLmp(lmp: Long) =
Calendar.getInstance().apply {
timeInMillis = lmp
- add(Calendar.WEEK_OF_YEAR, -40)
+ add(Calendar.WEEK_OF_YEAR, -57)
}.timeInMillis
@@ -487,15 +591,57 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
?: false
protected fun validateAllCapsOrSpaceOnEditText(formElement: FormElement): Int {
+ if (currentLanguage.toString() == english) {
+ if (formElement.allCaps) {
+ formElement.value?.takeIf { it.isNotEmpty() }?.isAllUppercaseOrSpace()?.let {
+ Timber.d("Is ok : $it")
+ formElement.errorText = if (it) null
+ else resources.getString(R.string.form_input_upper_case_error)
+ } ?: run {
+ if (!formElement.required) formElement.errorText = null
+ }
+ }
+ }
+ return -1
+ }
+
+ protected fun validateAllCapsOrSpaceOnEditTextWithHindiEnabled(formElement: FormElement): Int {
+ val value = formElement.value.orEmpty().trim()
+
+ // Function to check if a character is Hindi or Assamese
+ fun Char.isHindiOrAssamese(): Boolean {
+ return this in '\u0900'..'\u097F' || this in '\u0980'..'\u09FF'
+ }
+
+ // Function to check if a string contains only uppercase English letters or spaces
+ fun String.isAllUppercaseOrSpace(): Boolean {
+ return this.all { it.isUpperCase() || it.isWhitespace() || it.isHindiOrAssamese() }
+ }
+
if (formElement.allCaps) {
- formElement.value?.takeIf { it.isNotEmpty() }?.isAllUppercaseOrSpace()?.let {
- Timber.d("Is ok : $it")
- formElement.errorText = if (it) null
- else resources.getString(R.string.form_input_upper_case_error)
- } ?: run {
- if (!formElement.required) formElement.errorText = null
+ when {
+ value.isEmpty() -> {
+ if (formElement.required) {
+ formElement.errorText = resources.getString(R.string.form_input_empty_error)
+ } else {
+ formElement.errorText = null
+ }
+ return -1
+ }
+ !value.isAllUppercaseOrSpace() -> {
+ formElement.errorText = resources.getString(R.string.form_input_upper_case_error)
+ return -1
+ }
}
+
+ // Convert only English letters to uppercase, keep Hindi/Assamese as is
+ val transformedValue = value.map {
+ if (it.isLowerCase() && !it.isHindiOrAssamese()) it.uppercaseChar() else it
+ }.joinToString("")
+
+ formElement.value = transformedValue
}
+
return -1
}
@@ -537,6 +683,21 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
return -1
}
+ protected fun validateAllAlphabetsSpecialAndNumericOnEditText(formElement: FormElement): Int {
+ formElement.value?.takeIf { it.isNotEmpty() }?.let { input ->
+ val regex = "^[\\p{L}\\p{M}0-9\\s\\p{Punct}]+$".toRegex() // allows Unicode letters, combining marks (vowel signs, anusvara, nukta), numbers, spaces, and special characters
+
+ val isValid = regex.matches(input)
+ if (!isValid) {
+ formElement.errorText = resources.getString(R.string.form_input_alphabet_special__digit_only_error)
+ } else {
+ formElement.errorText = null
+ }
+ }
+ return -1
+ }
+
+
protected fun validateAllAlphaNumericSpaceOnEditText(formElement: FormElement): Int {
formElement.value?.takeIf { it.isNotEmpty() }?.let {
val isValid = it.isAllAlphaNumericAndSpace()
@@ -550,6 +711,23 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
return -1
}
+ fun String.isValid(): Boolean {
+ return this.matches(Regex("^\\d{14}$"))
+ }
+
+ protected fun validateABHANumberEditText(formElement: FormElement): Int {
+ formElement.value?.takeIf { it.isNotEmpty() }?.let {
+ val isValid = it.isValid()
+ if (formElement.errorText != null && formElement.errorText != resources.getString(R.string.abha_number_digit))
+ return@let
+ if (isValid) formElement.errorText = null
+ else formElement.errorText =
+ resources.getString(R.string.abha_number_digit)
+ } ?: kotlin.run {
+ formElement.errorText = null
+ }
+ return -1
+ }
protected fun validateAllAlphaNumericOnEditText(formElement: FormElement): Int {
formElement.value?.takeIf { it.isNotEmpty() }?.let {
@@ -564,6 +742,23 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
return -1
}
+ private fun String.isValidFormat() = takeIf {
+ matches(Regex("^[A-Z]{4}[0-9]{7}$"))
+ } != null
+
+ protected fun validateIFSCEditText(formElement: FormElement): Int {
+ formElement.value?.takeIf { it.isNotEmpty() }?.let {
+ val isValid = it.isValidFormat()
+ if (formElement.errorText != null && formElement.errorText != resources.getString(R.string.ifsc))
+ return@let
+ if (isValid) formElement.errorText = null
+ else formElement.errorText =
+ resources.getString(R.string.ifsc)
+ } ?: kotlin.run {
+ formElement.errorText = null
+ }
+ return -1
+ }
protected fun validateNoAlphabetSpaceOnEditText(formElement: FormElement): Int {
formElement.value?.takeIf { it.isNotEmpty() }?.isAnyAlphabetOrSpace()?.let {
@@ -590,7 +785,29 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
return -1
}
- protected fun validateIntMinMax(formElement: FormElement): Int {
+ protected fun validateUploads(
+ uploads: List,
+ minRequired: Int = 2
+ ): Int {
+ val uploadCount = uploads.count { !it.value.isNullOrEmpty() }
+
+ return if (uploadCount < minRequired) {
+ uploads.forEach {
+ if (it.value.isNullOrEmpty()) {
+ it.errorText = resources.getString(R.string.form_input_empty_error)
+ }
+ }
+ 0
+ } else {
+ uploads.forEach { it.errorText = null }
+ -1
+ }
+ }
+
+
+
+
+ /* protected fun validateIntMinMax(formElement: FormElement): Int {
formElement.errorText = formElement.value?.takeIf { it.isNotEmpty() }?.toLong()?.let {
formElement.min?.let { min ->
formElement.max?.let { max ->
@@ -606,15 +823,44 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
}
}
+ return -1
+ }*/
+
+ protected fun validateIntMinMax(formElement: FormElement): Int {
+ val inputValue = formElement.value
+
+ val longValue = inputValue?.takeIf { it.isNotEmpty() }?.toLongOrNull()
+
+ formElement.errorText = if (longValue == null) {
+ null
+ } else {
+ formElement.min?.let { min ->
+ formElement.max?.let { max ->
+ when {
+ longValue < min -> resources.getString(
+ R.string.form_input_min_limit_error, formElement.title, min
+ )
+
+ longValue > max -> resources.getString(
+ R.string.form_input_max_limit_error, formElement.title, max
+ )
+
+ else -> null
+ }
+ }
+ }
+ }
+
return -1
}
+
protected fun validateDoubleMinMax(formElement: FormElement): Int {
formElement.errorText = formElement.value?.takeIf { it.isNotEmpty() }?.let {
if (it.first() == '.')
"0$it"
else it
- }?.toDouble()?.let {
+ }?. toDoubleOrNull()?.let {
formElement.minDecimal?.let { min ->
formElement.maxDecimal?.let { max ->
if (it < min) {
@@ -659,7 +905,7 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
protected fun validateMobileNumberOnEditText(formElement: FormElement): Int {
- formElement.errorText = formElement.value?.takeIf { it.isNotEmpty() }?.toLong()?.let {
+ formElement.errorText = formElement.value?.takeIf { it.isNotEmpty() }?.toLongOrNull()?.let {
if (it < 6_000_000_000L || it == 6666666666L || it == 7777777777L || it == 8888888888L
|| it == 9999999999L
) resources.getString(R.string.form_input_error_invalid_mobile) else null
@@ -667,6 +913,18 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
return -1
}
+// protected fun validateNumberOnEditText(formElement: FormElement): Int {
+// val input = formElement.value?.trim() ?: ""
+//
+// formElement.errorText = when {
+//// input.isEmpty() -> resources.getString(R.string.form_input_error_mandatory)
+//// input.any { !it.isDigit() } -> resources.getString(R.string.form_input_error_numeric_only)
+// input.length > 4 -> resources.getString(R.string.form_input_error_max_digits)
+// else -> null
+// }
+//
+// return -1
+// }
protected fun validateRchIdOnEditText(formElement: FormElement): Int {
formElement.errorText = formElement.value?.takeIf { it.isNotEmpty() }?.let { text ->
@@ -692,6 +950,41 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
return -1
}
+ protected fun validateWeightOnEditText(formElement: FormElement): Int {
+ val value = formElement.value?.trim()
+
+ if (value.isNullOrEmpty()) {
+ formElement.errorText = null
+ return -1
+ }
+
+ val weight = value.toDoubleOrNull()
+ if (weight == null) {
+ formElement.errorText = resources.getString(R.string.weight_enter_in_grams)
+ return -1
+ }
+
+ when {
+ weight <= 0 -> {
+ formElement.errorText = resources.getString(R.string.weight_cannot_be_zero)
+ }
+ weight in 1.0..10.0 -> {
+ formElement.errorText = resources.getString(R.string.weight_enter_in_grams_example)
+ }
+ weight < 500 -> {
+ formElement.errorText = resources.getString(R.string.weight_min_500)
+ }
+ weight > 7000 -> {
+ formElement.errorText = resources.getString(R.string.weight_max_7000)
+ }
+ else -> {
+ formElement.errorText = null
+ }
+ }
+
+ return -1
+ }
+
protected fun validateMcpOnEditText(formElement: FormElement): Int {
formElement.errorText = formElement.value?.takeIf { it.isNotEmpty() }?.let {
@@ -724,15 +1017,15 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
}
val matchResult = bpRegex.matchEntire(bp.value!!)
if (matchResult == null)
- bp.errorText = "Invalid format. Should be like 123/56"
+ bp.errorText = resources.getString(R.string.bp_invalid_format)
else {
val sys = matchResult.groupValues[1].toInt()
val dia = matchResult.groupValues[2].toInt()
- bp.errorText = if (sys < minSys) "Systole should not be less than $minSys"
- else if (sys > maxSys) "Systole should not be greater than $maxSys"
- else if (dia < minDia) "Diastole should not be less then $minDia"
- else if (dia > maxDia) "Diastole should not be greater than $maxDia"
- else if (dia > sys) "Diastole cannot be greater than systole"
+ bp.errorText = if (sys < minSys) resources.getString(R.string.bp_systole_less_than, minSys)
+ else if (sys > maxSys) resources.getString(R.string.bp_systole_greater_than, maxSys)
+ else if (dia < minDia) resources.getString(R.string.bp_diastole_less_than, minDia)
+ else if (dia > maxDia) resources.getString(R.string.bp_diastole_greater_than, maxDia)
+ else if (dia > sys) resources.getString(R.string.bp_diastole_greater_than_systole)
else null
}
return -1
@@ -772,21 +1065,113 @@ abstract class Dataset(context: Context, currentLanguage: Languages) {
return dob.timeInMillis
}
+
fun getLocalValueInArray(arrayId: Int, entry: String?): String? {
- return if (entry.isNullOrEmpty()) {
- null
- } else {
- resources.getStringArray(arrayId)[englishResources.getStringArray(arrayId)
- .indexOf(entry)]
+ if (entry.isNullOrEmpty()) return null
+
+ val englishArray = englishResources.getStringArray(arrayId)
+ val localizedArray = resources.getStringArray(arrayId)
+
+ // Try English lookup first (value was stored in English)
+ val englishIndex = englishArray.indexOf(entry)
+ if (englishIndex in englishArray.indices) {
+ return localizedArray[englishIndex]
}
+
+ // Fallback: value was stored in localized language, find it directly
+ val localIndex = localizedArray.indexOf(entry)
+ if (localIndex in localizedArray.indices) {
+ return localizedArray[localIndex]
+ }
+
+ Log.w("Dataset", "Entry '$entry' not found in array for ID $arrayId")
+ return null
}
+
+
+ /* fun getLocalValueInArray(arrayId: Int, entry: String?): String? {
+ return if (entry.isNullOrEmpty()) {
+ null
+ } else {
+ resources.getStringArray(arrayId)[englishResources.getStringArray(arrayId)
+ .indexOf(entry)]
+ }
+ }*/
+
fun getEnglishValueInArray(arrayId: Int, entry: String?): String? {
- entry?.let {
- return englishResources.getStringArray(arrayId)[resources.getStringArray(arrayId)
- .indexOf(it)]
+ if (entry.isNullOrEmpty()) return null
+
+ val localizedArray = resources.getStringArray(arrayId)
+ val englishArray = englishResources.getStringArray(arrayId)
+ val index = localizedArray.indexOf(entry)
+
+ return if (index in localizedArray.indices) {
+ englishArray[index]
+ } else {
+ Log.w("Dataset", "Entry '$entry' not found in localized array for ID $arrayId")
+ null
}
- return null
+ }
+
+ fun getEnglishCheckboxValues(arrayId: Int, indexValues: String?): String? {
+ if (indexValues.isNullOrEmpty()) return null
+ val englishArray = englishResources.getStringArray(arrayId)
+ return indexValues.split("|")
+ .mapNotNull { it.trim().toIntOrNull() }
+ .filter { it in englishArray.indices }
+ .joinToString("|") { englishArray[it] }
+ .ifEmpty { null }
+ }
+
+ fun getCheckboxIndexesFromValues(arrayId: Int, storedValues: String?): String? {
+ if (storedValues.isNullOrEmpty()) return null
+ val parts = storedValues.split("|")
+ if (parts.all { it.trim().toIntOrNull() != null }) return storedValues
+ val englishArray = englishResources.getStringArray(arrayId)
+ val localizedArray = resources.getStringArray(arrayId)
+ return parts.mapNotNull { value ->
+ val trimmed = value.trim()
+ val englishIdx = englishArray.indexOf(trimmed)
+ if (englishIdx >= 0) englishIdx
+ else {
+ val localIdx = localizedArray.indexOf(trimmed)
+ if (localIdx >= 0) localIdx else null
+ }
+ }.sorted().joinToString("|") { it.toString() }.ifEmpty { null }
+ }
+
+ fun isValidChildGap(formElement: FormElement, firstDobStr: String?/*, secondDobStr: String?*/): Int {
+ val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ try {
+ val firstDob = dateFormat.parse(firstDobStr)
+ val secondDob = dateFormat.parse(formElement.value)
+
+ if (firstDob == null || secondDob == null) {
+ formElement.errorText = null //return false
+ }
+
+ // If twins (same DOB), it's valid
+ if (firstDob == secondDob){
+ formElement.errorText = null
+ return -1
+ } //true
+
+ val diffInMillis = abs(secondDob.time - firstDob.time)
+ val diffInDays = diffInMillis / (1000 * 60 * 60 * 24)
+
+ // Valid if gap is 365 days (approx. 12 months) or more
+ if (diffInDays >= 365){
+ formElement.errorText = null
+ }else{
+ formElement.errorText = "Invalid date of birth! The minimum age difference should be at least 12 months."
+ }
+
+ } catch (e: Exception) {
+ formElement.errorText = "Invalid date format or parsing error"//null // Invalid date format or parsing error
+ }
+
+ return -1
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/DeliveryOutcomeDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/DeliveryOutcomeDataset.kt
index 1e1a04a64..13f9ee2c5 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/DeliveryOutcomeDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/DeliveryOutcomeDataset.kt
@@ -1,19 +1,44 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
+import java.util.Locale
+import android.util.Log
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenStatus
import org.piramalswasthya.sakhi.model.DeliveryOutcomeCache
import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
import org.piramalswasthya.sakhi.model.PregnantWomanAncCache
import org.piramalswasthya.sakhi.model.PregnantWomanRegistrationCache
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Date
import java.util.concurrent.TimeUnit
open class DeliveryOutcomeDataset(
context: Context, currentLanguage: Languages
) : Dataset(context, currentLanguage) {
+ companion object{
+ @Throws(Exception::class)
+ fun getOneMonthLater(deliveryDate: String?): String {
+ val sdf: SimpleDateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val date: Date = sdf.parse(deliveryDate)
+
+ val calendar: Calendar = Calendar.getInstance()
+ calendar.setTime(date)
+ calendar.add(Calendar.MONTH, 1) // Add 1 month
+
+ return sdf.format(calendar.getTime())
+ }
+ }
+
private val dateOfDelivery = FormElement(
id = 1,
inputType = InputType.DATE_PICKER,
@@ -38,7 +63,7 @@ open class DeliveryOutcomeDataset(
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.do_delivery_place),
entries = resources.getStringArray(R.array.do_place_of_delivery_array),
- required = false,
+ required = true,
hasDependants = false
)
@@ -47,7 +72,7 @@ open class DeliveryOutcomeDataset(
inputType = InputType.RADIO,
title = resources.getString(R.string.do_delivery_type),
entries = resources.getStringArray(R.array.do_type_of_delivery_array),
- required = false,
+ required = true,
hasDependants = false
)
@@ -78,6 +103,7 @@ open class DeliveryOutcomeDataset(
hasDependants = true
)
+
private var otherCauseOfDeath = FormElement(
id = 8,
inputType = InputType.EDIT_TEXT,
@@ -88,6 +114,30 @@ open class DeliveryOutcomeDataset(
hasDependants = false
)
+ private val dateOfDeath = FormElement(
+ id = 51,
+ inputType = DATE_PICKER,
+ title = context.getString(R.string.date_of_death),
+ max = System.currentTimeMillis(),
+ required = true,
+ )
+
+ private val placeOfDeath = FormElement(
+ id = 54,
+ inputType = DROPDOWN,
+ title = context.getString(R.string.place_of_death),
+ arrayId = R.array.death_place_array,
+ entries = resources.getStringArray(R.array.death_place_array),
+ required = true,
+ )
+ private val otherPlaceOfDeath = FormElement(
+ id = 55,
+ inputType = EDIT_TEXT,
+ title = context.getString(R.string.other_place_of_death),
+ required = true,
+ hasDependants = true,
+ )
+
private var otherComplication = FormElement(
id = 9,
inputType = InputType.EDIT_TEXT,
@@ -102,7 +152,7 @@ open class DeliveryOutcomeDataset(
id = 10,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.do_delivery_outcome),
- required = false,
+ required = true,
hasDependants = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 1,
@@ -114,7 +164,7 @@ open class DeliveryOutcomeDataset(
id = 11,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.do_live_birth),
- required = false,
+ required = true,
hasDependants = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 1,
@@ -126,7 +176,7 @@ open class DeliveryOutcomeDataset(
id = 12,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.do_still_birth),
- required = false,
+ required = true,
hasDependants = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 1,
@@ -161,7 +211,27 @@ open class DeliveryOutcomeDataset(
title = resources.getString(R.string.do_is_jsy_beneficiary),
entries = resources.getStringArray(R.array.do_is_jsy_beneficiary_array),
required = false,
- hasDependants = false
+ hasDependants = true
+ )
+
+ private val mcpFileUpload1 = FormElement(
+ id = 21,
+ inputType = InputType.FILE_UPLOAD,
+ title = context.getString(R.string.mcp_card_1),
+ required = false,
+ )
+ private val mcpFileUpload2 = FormElement(
+ id = 22,
+ inputType = InputType.FILE_UPLOAD,
+ title = context.getString(R.string.mcp_card_2),
+ required = false,
+ )
+ private val jsyFileUpload = FormElement(
+ id = 23,
+ inputType = InputType.FILE_UPLOAD,
+ title = context.getString(R.string.jsy_payment_voucher),
+ required = false,
+ hasDependants = true
)
suspend fun setUpPage(
@@ -184,11 +254,22 @@ open class DeliveryOutcomeDataset(
stillBirth,
dateOfDischarge,
timeOfDischarge,
- isJSYBenificiary
+ isJSYBenificiary,
+ mcpFileUpload1,
+ mcpFileUpload2
)
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(mcpFileUpload1)
+ list.remove(mcpFileUpload2)
+ }
if (saved == null) {
dateOfDelivery.value = getDateFromLong(System.currentTimeMillis())
- dateOfDischarge.min = System.currentTimeMillis()
+ //dateOfDischarge.min = System.currentTimeMillis()
+ stillBirth.value = "0"
+
+ dateOfDischarge.min = getLongFromDate(dateOfDelivery.value)
+ dateOfDischarge.max =getLongFromDate(getOneMonthLater(dateOfDelivery.value))
} else {
list = mutableListOf(
dateOfDelivery,
@@ -205,15 +286,55 @@ open class DeliveryOutcomeDataset(
stillBirth,
dateOfDischarge,
timeOfDischarge,
- isJSYBenificiary
+ isJSYBenificiary,
+ mcpFileUpload1,
+ mcpFileUpload2
)
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(mcpFileUpload1)
+ list.remove(mcpFileUpload2)
+ }
+// hadComplications.value = if (saved.hadComplications == true) "Yes" else "No"
+ if (saved.hadComplications == true) {
+ list.add(list.indexOf(hadComplications) + 1 ,complication)
+ hadComplications.value = hadComplications.entries!![0]
+ } else {
+ hadComplications.value = hadComplications.entries!![1]
+ }
+
+
+ if(saved.complication.equals("Other Delivery Complication", ignoreCase = true))
+ {
+ list.add(list.indexOf(complication) + 1 ,otherComplication)
+ }
+ if(saved.complication.equals("DEATH", ignoreCase = true))
+ {
+ list.add(list.indexOf(complication) + 1 ,causeOfDeath)
+ list.add(list.indexOf(causeOfDeath) + 1 ,dateOfDeath)
+ list.add(list.indexOf(dateOfDeath) + 1 ,placeOfDeath)
+ val localPlaceOfDeath = getLocalValueInArray(R.array.death_place_array, saved.placeOfDeath)
+ placeOfDeath.entries?.indexOf(localPlaceOfDeath)?.takeIf { it >= 0 }?.let { index ->
+ if (index == 8) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ }
+ }
+
+ }
+ mcpFileUpload1.value=saved.mcp1File
+ mcpFileUpload2.value=saved.mcp2File
+ jsyFileUpload.value=saved.jsyFile
+ dateOfDeath.value=saved.dateOfDeath
+ placeOfDeath.value=getLocalValueInArray(R.array.death_place_array, saved.placeOfDeath)
+ otherPlaceOfDeath.value=saved.otherPlaceOfDeath
+
+
dateOfDelivery.value = saved.dateOfDelivery?.let { getDateFromLong(it) }
timeOfDelivery.value = saved.timeOfDelivery
placeOfDelivery.value =
getLocalValueInArray(R.array.do_place_of_delivery_array, saved.placeOfDelivery)
typeOfDelivery.value =
getLocalValueInArray(R.array.do_type_of_delivery_array, saved.typeOfDelivery)
- hadComplications.value = if (saved.hadComplications == true) "Yes" else "No"
+// hadComplications.value = if (saved.hadComplications == true) "Yes" else "No"
complication.value =
getLocalValueInArray(R.array.do_complications_array, saved.complication)
causeOfDeath.value =
@@ -225,14 +346,21 @@ open class DeliveryOutcomeDataset(
stillBirth.value = saved.stillBirth.toString()
dateOfDischarge.value = saved.dateOfDischarge?.let { getDateFromLong(it) }
timeOfDischarge.value = saved.timeOfDischarge
- isJSYBenificiary.value = if (saved.isJSYBenificiary == true) "Yes" else "No"
+ if (saved.isJSYBenificiary == true) {
+ list.add(list.indexOf(isJSYBenificiary) + 1 ,jsyFileUpload)
+ isJSYBenificiary.value = isJSYBenificiary.entries!![0]
+ } else {
+ isJSYBenificiary.value = isJSYBenificiary.entries!![1]
+ }
}
+ dateOfDeath.min=pwr.lmpDate
dateOfDelivery.min = maxOf(pwr.lmpDate + TimeUnit.DAYS.toMillis(21 * 7), anc.ancDate)
dateOfDelivery.max =
minOf(
System.currentTimeMillis(),
getEddFromLmp(pwr.lmpDate) + TimeUnit.DAYS.toMillis(25)
)
+
setUpPage(list)
}
@@ -241,6 +369,7 @@ open class DeliveryOutcomeDataset(
return when (formId) {
dateOfDelivery.id -> {
dateOfDischarge.min = getLongFromDate(dateOfDelivery.value)
+ dateOfDischarge.max =getLongFromDate(getOneMonthLater(dateOfDelivery.value))
-1
}
@@ -250,16 +379,33 @@ open class DeliveryOutcomeDataset(
passedIndex = index,
triggerIndex = 0,
target = complication,
- targetSideEffect = listOf(causeOfDeath, otherComplication, otherCauseOfDeath)
+ targetSideEffect = listOf(causeOfDeath, otherComplication, otherCauseOfDeath,dateOfDeath,placeOfDeath,otherPlaceOfDeath)
+ )
+ }
+ placeOfDeath.id -> {
+ val index = placeOfDeath.entries?.indexOf(placeOfDeath.value).takeIf { it!! >= 0 } ?: return -1
+ val triggerIndex = 8
+ return triggerDependants(
+ source = placeOfDeath,
+ passedIndex = index,
+ triggerIndex = triggerIndex,
+ target = otherPlaceOfDeath
)
}
complication.id -> {
if (index == 6) {
+ liveBirth.value = "0"
+ liveBirth.isEnabled =false
+
+ handleListOnValueChanged(liveBirth.id, 0)
+
triggerDependants(
source = complication,
- addItems = listOf(causeOfDeath),
- removeItems = listOf(otherComplication, otherCauseOfDeath)
+ addItems = listOf(causeOfDeath,dateOfDeath,placeOfDeath),
+ removeItems = listOf(otherComplication, otherCauseOfDeath, dateOfDischarge,
+ timeOfDischarge,
+ isJSYBenificiary)
)
} else if (index == 7) {
triggerDependants(
@@ -271,7 +417,7 @@ open class DeliveryOutcomeDataset(
triggerDependants(
source = complication,
addItems = listOf(),
- removeItems = listOf(otherComplication, otherCauseOfDeath, causeOfDeath)
+ removeItems = listOf(otherComplication, otherCauseOfDeath, causeOfDeath,dateOfDeath,placeOfDeath,otherPlaceOfDeath)
)
}
}
@@ -285,6 +431,21 @@ open class DeliveryOutcomeDataset(
)
}
+ isJSYBenificiary.id -> {
+ val isYes = isJSYBenificiary.value == isJSYBenificiary.entries!![0]
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ triggerDependants(
+ source = isJSYBenificiary,
+ passedIndex = index,
+ triggerIndex = if (isYes) index else -1,
+ target = jsyFileUpload
+ )
+ }
+ return -1
+ }
+
+
+
otherCauseOfDeath.id -> {
validateAllAlphabetsSpecialOnEditText(otherCauseOfDeath)
}
@@ -331,6 +492,10 @@ open class DeliveryOutcomeDataset(
if (deliveryOutcome.value!!.toInt() != liveBirth.value!!.toInt() + stillBirth.value!!.toInt()) {
formElement.errorText =
"Outcome of Delivery should be equal to sum of Live and Still births"
+ }else{
+ deliveryOutcome.errorText = null
+ liveBirth.errorText = null
+ stillBirth.errorText = null
}
}
if (!deliveryOutcome.value.isNullOrEmpty()) {
@@ -343,22 +508,61 @@ open class DeliveryOutcomeDataset(
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as DeliveryOutcomeCache).let { form ->
form.dateOfDelivery = getLongFromDate(dateOfDelivery.value)
+ form.mcp1File = mcpFileUpload1.value
+ form.mcp2File = mcpFileUpload2.value
+ form.jsyFile = jsyFileUpload.value
+ form.dateOfDeath=dateOfDeath.value
+ form.placeOfDeath=getEnglishValueInArray(R.array.death_place_array, placeOfDeath.value)
+ form.otherPlaceOfDeath=otherPlaceOfDeath.value
+ val englishComplication = getEnglishValueInArray(R.array.do_complications_array, complication.value)
+ if (englishComplication.equals("Death", ignoreCase = true)){
+ form.isDeath=true
+ form.isDeathValue="Death"
+ }
+ form.placeOfDeathId = placeOfDeath.entries?.indexOf(placeOfDeath.value ?: "")
+ ?.takeIf { it != -1 }
+
form.timeOfDelivery = timeOfDelivery.value
- form.placeOfDelivery = placeOfDelivery.value
- form.typeOfDelivery = typeOfDelivery.value
- form.hadComplications = hadComplications.value == "Yes"
- form.complication = complication.value
- form.causeOfDeath = causeOfDeath.value
+ form.placeOfDelivery = getEnglishValueInArray(R.array.do_place_of_delivery_array, placeOfDelivery.value)
+ form.typeOfDelivery = getEnglishValueInArray(R.array.do_type_of_delivery_array, typeOfDelivery.value)
+ form.hadComplications = hadComplications.value == hadComplications.entries!![0]
+ form.complication = englishComplication
+ form.causeOfDeath = getEnglishValueInArray(R.array.do_cause_of_death_array, causeOfDeath.value)
form.otherCauseOfDeath = otherCauseOfDeath.value
form.otherComplication = otherComplication.value
form.deliveryOutcome = deliveryOutcome.value?.toInt()
form.liveBirth = liveBirth.value?.toInt()
form.stillBirth = stillBirth.value?.toInt()
- form.dateOfDischarge = (dateOfDischarge.value?.let {
+ form.dateOfDischarge = dateOfDischarge.value?.takeIf { it.isNotBlank() }?.let {
getLongFromDate(it)
- })
+ }
form.timeOfDischarge = timeOfDischarge.value
- form.isJSYBenificiary = isJSYBenificiary.value == "Yes"
+ form.isJSYBenificiary = isJSYBenificiary.value == isJSYBenificiary.entries!![0]
+ }
+ }
+ fun getIndexOfMCP1() = getIndexById(mcpFileUpload1.id)
+ fun getIndexOfMCP2() = getIndexById(mcpFileUpload2.id)
+ fun getIndexOfIsjsyFileUpload() = getIndexById(jsyFileUpload.id)
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+
+ when (lastImageFormId) {
+ 21 -> {
+ mcpFileUpload1.value = dpUri.toString()
+ mcpFileUpload1.errorText = null
+ }
+
+ 22 -> {
+ mcpFileUpload2.value = dpUri.toString()
+ mcpFileUpload2.errorText = null
+ }
+
+ 23 -> {
+ jsyFileUpload.value = dpUri.toString()
+ jsyFileUpload.errorText = null
+ }
+
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/DewormingDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/DewormingDataset.kt
new file mode 100644
index 000000000..c19760a08
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/DewormingDataset.kt
@@ -0,0 +1,178 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import android.text.InputType
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.AHDCache
+import org.piramalswasthya.sakhi.model.DewormingCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType.*
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Date
+import java.util.Locale
+
+class DewormingDataset(
+ context: Context,
+ currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+
+ companion object {
+
+ fun getMinDate(): Long {
+ return Calendar.getInstance().apply {
+ add(Calendar.MONTH, -1)
+ }.timeInMillis
+ }
+
+ fun getMaxDate(): Long {
+ return Calendar.getInstance().timeInMillis
+ }
+ }
+
+ private val formElementList = mutableListOf()
+ private val dewormingDone = FormElement(
+ id = 6,
+ inputType = RADIO,
+ title = resources.getString(R.string.was_the_deworming_round_conducted),
+ entries = resources.getStringArray(R.array.yes_no_options),
+ required = true,
+ hasDependants = true
+ )
+
+ private val dewormingDate = FormElement(
+ id = 5,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.date_of_ndd),
+ required = true,
+ min = getMinDate(),
+ max = getMaxDate(),
+ )
+
+ private val dewormingLocation = FormElement(
+ id = 4,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.place_of_ndd),
+ entries = resources.getStringArray(R.array.deworming_location_options),
+ required = true,
+ )
+
+ private val ageGroup = FormElement(
+ id = 3,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_out_of_school_children_sent_to_anganwad),
+ etMaxLength = 2,
+ etInputType = InputType.TYPE_CLASS_NUMBER,
+ required = true
+ )
+
+ private val pic1 = FormElement(
+ id = 1,
+ inputType = org.piramalswasthya.sakhi.model.InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false
+ )
+
+ private val pic2 = FormElement(
+ id = 2,
+ inputType = org.piramalswasthya.sakhi.model.InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false
+ )
+
+ suspend fun setUpPage(deworming: DewormingCache?) {
+
+ if (pic1.value.isNullOrBlank()) {
+ pic1.value = "default"
+ }
+
+ if (pic2.value.isNullOrBlank()) {
+ pic2.value = "default"
+ }
+ val list = mutableListOf(
+ dewormingDone,
+ ageGroup,
+ pic1,
+ pic2
+ )
+ deworming?.let { loadCachedData(it,list) }
+ formElementList.addAll(list)
+ setUpPage(list)
+ }
+ fun getFormElementList(): List = formElementList
+ private fun loadCachedData(deworming: DewormingCache, list: MutableList) {
+ dewormingDone.value = getLocalValueInArray(R.array.yes_no_options, deworming.dewormingDone)
+ dewormingDate.value = deworming.dewormingDate
+ dewormingLocation.value = getLocalValueInArray(R.array.deworming_location_options, deworming.dewormingLocation)
+ ageGroup.value = deworming.ageGroup?.toString()
+ pic1.value = deworming.image1
+ pic2.value = deworming.image2
+
+ if (dewormingDone.value == dewormingDone.entries!!.first()) {
+ list.add(dewormingDone.getPosition() ,dewormingDate)
+ list.add(dewormingDone.getPosition() + 1,dewormingLocation)
+ }
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ dewormingDone.id -> {
+ if (dewormingDone.value == dewormingDone.entries!!.first()) {
+ if (!formElementList.contains(dewormingDate)) {
+ formElementList.add(dewormingDate)
+ }
+ if (!formElementList.contains(dewormingLocation)) {
+ formElementList.add(dewormingLocation)
+ }
+ }
+ else{
+ formElementList.remove(dewormingDate)
+ formElementList.remove(dewormingLocation)
+ }
+ triggerDependants(
+ source = dewormingDone,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = listOf(dewormingDate,dewormingLocation),
+ )
+ }
+ ageGroup.id -> {
+ validateEmptyOnEditText(ageGroup)
+ }
+ else -> -1
+ }
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as DewormingCache).let { form ->
+ val formatter = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val currentDate = formatter.format(Date())
+ form.dewormingDone = getEnglishValueInArray(R.array.yes_no_options, dewormingDone.value) ?: dewormingDone.value!!
+ form.dewormingDate = dewormingDate.value
+ form.dewormingLocation = getEnglishValueInArray(R.array.deworming_location_options, dewormingLocation.value)
+ form.ageGroup = ageGroup.value?.toInt()
+ form.image1 = pic1.value
+ form.image2 = pic2.value
+ form.regDate = currentDate
+ }
+ }
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ pic1.id -> {
+ pic1.value = dpUri.toString()
+ pic1.errorText = null
+ }
+ pic2.id -> {
+ pic2.value = dpUri.toString()
+ pic2.errorText = null
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleRegistrationDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleRegistrationDataset.kt
index d8df66614..c3d0bdcb9 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleRegistrationDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleRegistrationDataset.kt
@@ -1,13 +1,15 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
import android.text.InputType
+import androidx.lifecycle.MutableLiveData
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.database.room.SyncState
import org.piramalswasthya.sakhi.helpers.Konstants
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
-import org.piramalswasthya.sakhi.model.AgeUnit
import org.piramalswasthya.sakhi.model.BenBasicCache
import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.EligibleCoupleRegCache
@@ -25,7 +27,12 @@ import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
-class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
+class EligibleCoupleRegistrationDataset(
+ var reqContext: Context,
+ var context: Context,
+ language: Languages,
+ var showDialogEvent: MutableLiveData
+) :
Dataset(context, language) {
companion object {
@@ -41,6 +48,12 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
return date?.time ?: throw IllegalStateException("Invalid date for dateReg")
}
+ private fun getMinLmpMillis(): Long {
+ val cal = Calendar.getInstance()
+ cal.add(Calendar.DAY_OF_YEAR, -1 * 400) //before it is 280
+ return cal.timeInMillis
+ }
+
private fun getMinDobMillis(): Long {
val cal = Calendar.getInstance()
cal.add(Calendar.YEAR, -15)
@@ -51,6 +64,28 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
private fun getMaxDobMillis(): Long {
return System.currentTimeMillis()
}
+
+ fun getMinimumSecondChildDob(firstChildDobStr: String?): String {
+
+ val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val firstChildDob = dateFormat.parse(firstChildDobStr)
+
+ val calendar = Calendar.getInstance()
+ calendar.time = firstChildDob!!
+
+ // Instead of adding 12 months as minimum, allow same day or after 12 months
+ // So minimum acceptable DOB is the same date
+ return dateFormat.format(calendar.time)
+
+ /* val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault())
+ val firstChildDob = dateFormat.parse(firstChildDobStr)
+
+ val calendar = Calendar.getInstance()
+ calendar.time = firstChildDob!!
+ calendar.add(Calendar.DAY_OF_YEAR, 365) // Add 365 days (approx. 12 months)
+
+ return dateFormat.format(calendar.time)*/
+ }
}
//////////////////////////////// First Page /////////////////////////////////////////
@@ -63,7 +98,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
required = true,
max = System.currentTimeMillis(),
min = 0L,
- hasDependants = true
+ hasDependants = true,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_anc_date,
+ showDrawable = true
)
private val rchId = FormElement(
@@ -76,7 +114,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
isMobileNumber = true,
etMaxLength = 12,
max = 999999999999L,
- min = 0L
+ min = 0L,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_rch_id_no,
+ showDrawable = true
)
private val name = FormElement(
@@ -88,7 +129,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
allCaps = true,
hasSpeechToText = false,
etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS,
- isEnabled = false
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_women,
+ showDrawable = true
)
private val husbandName = FormElement(
@@ -100,7 +144,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
allCaps = true,
hasSpeechToText = false,
etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS,
- isEnabled = false
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_husbund,
+ showDrawable = true
)
private val age = FormElement(
@@ -113,6 +160,9 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
etMaxLength = 2,
max = Konstants.maxAgeForGenBen.toLong(),
min = Konstants.minAgeForGenBen.toLong(),
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic__reproductive_age,
+ showDrawable = true
)
private val ageAtMarriage = FormElement(
@@ -125,9 +175,68 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
etMaxLength = 2,
max = Konstants.maxAgeForGenBen.toLong(),
min = Konstants.minAgeForGenBen.toLong(),
- isEnabled = false
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_age_of_women_at_marriage,
+ showDrawable = true
+ )
+
+ private var lmpDate = FormElement(
+ id = 73,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.lmp_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = getMinLmpMillis(),
+ hasDependants = true,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_anc_date,
+ showDrawable = true
)
+ private val nayiPahelKitHandOver = FormElement(
+ id = 78,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_is_nai_pahel_kit_handover),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val kithandOverDate = FormElement(
+ id = 74,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_is_nai_pahel_kit_handover_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = 0L,
+ hasDependants = true,
+ showDrawable = true
+ )
+
+ private val ashaPhotoTitle = FormElement(
+ id = 77,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.asha_photo),
+ arrayId = -1,
+ required = false
+ )
+
+ private val kitPhotoUploadOne = FormElement(
+ id = 75,
+ inputType = org.piramalswasthya.sakhi.model.InputType.FILE_UPLOAD,
+ title = context.getString(R.string.asha_photo_one),
+ required = false,
+ )
+ private val kitPhotoUploadTwo = FormElement(
+ id = 76,
+ inputType = org.piramalswasthya.sakhi.model.InputType.FILE_UPLOAD,
+ title = context.getString(R.string.asha_photo_two),
+ required = false,
+ )
private val womanDetails = FormElement(
id = 6,
inputType = HEADLINE,
@@ -157,9 +266,12 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
required = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
isMobileNumber = true,
- etMaxLength = 18,
+ etMaxLength = 20,
max = 999999999999999999L,
- min = 0L
+ min = 10000000L,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_bank_acc_no,
+ showDrawable = true
)
private val bankName = FormElement(
@@ -168,7 +280,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_bank_name),
arrayId = -1,
required = false,
- etMaxLength = 50
+ etMaxLength = 50,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_bank_name,
+ showDrawable = true
)
private val branchName = FormElement(
@@ -177,7 +292,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_branch_name),
arrayId = -1,
required = false,
- etMaxLength = 50
+ etMaxLength = 50,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_branch_name,
+ showDrawable = true
)
private val ifsc = FormElement(
@@ -187,6 +305,9 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = false,
etMaxLength = 11,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_ifsc_code,
+ showDrawable = true
)
private val noOfChildren = FormElement(
@@ -194,11 +315,16 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = EDIT_TEXT,
title = resources.getString(R.string.ecrdset_ttl_child_born),
arrayId = -1,
- required = true,
+ required = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 1,
max = 9,
min = 0,
+ value = "0",
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_total_no_child_born,
+ showDrawable = true
)
private val noOfLiveChildren = FormElement(
@@ -206,11 +332,16 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = EDIT_TEXT,
title = resources.getString(R.string.ecrdset_no_live_child),
arrayId = -1,
- required = true,
+ required = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 1,
max = 9,
- min = 0
+ value = "0",
+ isEnabled = false,
+ min = 0,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_no_of_live_child,
+ showDrawable = true
)
private val numMale = FormElement(
@@ -223,6 +354,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
etMaxLength = 1,
max = 9,
min = 0,
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_male,
+ showDrawable = true
)
private val numFemale = FormElement(
@@ -231,10 +366,15 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_female),
arrayId = -1,
required = false,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 1,
max = 9,
min = 0,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_female,
+ showDrawable = true
+
)
private val firstChildDetails = FormElement(
@@ -242,7 +382,8 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = HEADLINE,
title = resources.getString(R.string.ecrdset_dls_1_child),
arrayId = -1,
- required = false
+ required = false,
+
)
private val dob1 = FormElement(
@@ -254,6 +395,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
hasDependants = true,
max = getMaxDobMillis(),
min = getMinDobMillis(),
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_anc_date,
+ showDrawable = true
)
private val age1 = FormElement(
@@ -263,10 +408,14 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = Konstants.maxAgeForAdolescent.toLong(),
min = 0,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_no_of_live_child,
+ showDrawable = true
)
private val gender1 = FormElement(
@@ -274,6 +423,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = RADIO,
title = resources.getString(R.string.ecrdset_1_child_sex),
arrayId = -1,
+ isEnabled = false,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
hasDependants = true,
@@ -289,6 +439,10 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
etMaxLength = 2,
max = 99,
min = 0,
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_gap_bet_marriage_child,
+ showDrawable = true
)
private val secondChildDetails = FormElement(
@@ -306,6 +460,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
max = getMaxDobMillis(),
min = getMinDobMillis(),
)
@@ -317,6 +472,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = Konstants.maxAgeForAdolescent.toLong(),
@@ -328,6 +484,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = RADIO,
title = resources.getString(R.string.ecrdset_2_child_sex),
arrayId = -1,
+ isEnabled = false,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
hasDependants = true,
@@ -339,6 +496,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_gap_1_child_2_child),
arrayId = -1,
required = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = 99,
@@ -360,6 +518,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
max = getMaxDobMillis(),
min = getMinDobMillis(),
)
@@ -371,6 +530,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = Konstants.maxAgeForAdolescent.toLong(),
@@ -382,6 +542,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = RADIO,
title = resources.getString(R.string.ecrdset_3_child_sex),
arrayId = -1,
+ isEnabled = false,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
hasDependants = true,
@@ -393,6 +554,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_gap_bet_2_3_child_sex),
arrayId = -1,
required = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = 99,
@@ -414,6 +576,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
max = getMaxDobMillis(),
min = getMinDobMillis(),
)
@@ -425,6 +588,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = Konstants.maxAgeForAdolescent.toLong(),
@@ -436,6 +600,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = RADIO,
title = resources.getString(R.string.ecrdset_4_child_sex),
arrayId = -1,
+ isEnabled = false,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
hasDependants = true,
@@ -446,6 +611,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = TEXT_VIEW,
title = resources.getString(R.string.ecrdset_bet_3_4_child),
arrayId = -1,
+ isEnabled = false,
required = true,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
@@ -465,6 +631,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 37,
inputType = DATE_PICKER,
title = resources.getString(R.string.ecrdset_5_child_bth),
+ isEnabled = false,
arrayId = -1,
required = true,
hasDependants = true,
@@ -475,6 +642,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
private val age5 = FormElement(
id = 38,
inputType = TEXT_VIEW,
+ isEnabled = false,
title = resources.getString(R.string.ecrdset_5_child_age_yrs),
arrayId = -1,
required = true,
@@ -489,6 +657,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 39,
inputType = RADIO,
title = resources.getString(R.string.ecrdset_5_child_sex),
+ isEnabled = false,
arrayId = -1,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
@@ -501,6 +670,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_gap_4_5_child),
arrayId = -1,
required = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = 99,
@@ -519,6 +689,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 42,
inputType = DATE_PICKER,
title = resources.getString(R.string.ecrdset_dts_6_bth),
+ isEnabled = false,
arrayId = -1,
required = true,
hasDependants = true,
@@ -532,6 +703,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_6_child_age),
arrayId = -1,
required = true,
+ isEnabled = false,
hasDependants = true,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
@@ -543,6 +715,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 44,
inputType = RADIO,
title = resources.getString(R.string.ecrdset_6_child_sex),
+ isEnabled = false,
arrayId = -1,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
@@ -555,6 +728,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_gap_5_6_child),
arrayId = -1,
required = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = 99,
@@ -573,6 +747,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 47,
inputType = DATE_PICKER,
title = resources.getString(R.string.ecrdset_7_child_bth),
+ isEnabled = false,
arrayId = -1,
required = true,
hasDependants = true,
@@ -587,6 +762,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = Konstants.maxAgeForAdolescent.toLong(),
@@ -598,6 +774,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
inputType = RADIO,
title = resources.getString(R.string.ecrdset_7_child_sex),
arrayId = -1,
+ isEnabled = false,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
hasDependants = true,
@@ -609,6 +786,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_gap_6_7_child),
arrayId = -1,
required = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = 99,
@@ -629,6 +807,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_8_child_bth),
arrayId = -1,
required = true,
+ isEnabled = false,
hasDependants = true,
max = getMaxDobMillis(),
min = getMinDobMillis(),
@@ -641,6 +820,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
arrayId = -1,
required = true,
hasDependants = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = Konstants.maxAgeForAdolescent.toLong(),
@@ -651,6 +831,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 54,
inputType = RADIO,
title = resources.getString(R.string.ecrdset_8_child_sex),
+ isEnabled = false,
arrayId = -1,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
@@ -663,6 +844,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
title = resources.getString(R.string.ecrdset_gap_7_8_child),
arrayId = -1,
required = true,
+ isEnabled = false,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
max = 99,
@@ -680,6 +862,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
private val dob9 = FormElement(
id = 57,
inputType = DATE_PICKER,
+ isEnabled = false,
title = resources.getString(R.string.ecrdset_9_bth),
arrayId = -1,
required = true,
@@ -692,6 +875,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 58,
inputType = TEXT_VIEW,
title = resources.getString(R.string.ecrdset_9_age_yrs),
+ isEnabled = false,
arrayId = -1,
required = true,
hasDependants = true,
@@ -705,6 +889,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 59,
inputType = RADIO,
title = resources.getString(R.string.ecrdset_9_child_sex),
+ isEnabled = false,
arrayId = -1,
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
@@ -716,6 +901,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
id = 60,
inputType = TEXT_VIEW,
title = resources.getString(R.string.ecrdset_gap_8_9_child),
+ isEnabled = false,
arrayId = -1,
required = true,
etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
@@ -834,10 +1020,17 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
private var lastDeliveryDate = 0L
+
+ fun getIndexofAshaKitPhotoOne() = getIndexById(kitPhotoUploadOne.id)
+ fun getIndexofAshaKitPhoto() = getIndexById(kitPhotoUploadTwo.id)
+
+
+
suspend fun setUpPage(
ben: BenRegCache?,
assess: HRPNonPregnantAssessCache?,
- saved: EligibleCoupleRegCache?
+ saved: EligibleCoupleRegCache?,
+ childList: List,
) {
val list = mutableListOf(
dateOfReg,
@@ -846,13 +1039,11 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
husbandName,
// age,
ageAtMarriage,
+ lmpDate,
+ nayiPahelKitHandOver,
womanDetails,
// aadharNo,
- bankAccount,
- bankName,
- branchName,
- ifsc,
- noOfChildren,
+// noOfChildren,
noOfLiveChildren,
numMale,
numFemale,
@@ -870,6 +1061,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
pastCSection,
)
dateOfReg.value = getDateFromLong(System.currentTimeMillis())
+// lmpDate.value = getDateFromLong(1735237800000L)
// dateOfReg.value?.let {
// val long = Dataset.getLongFromDate(it)
// dateOfhivTestDone.min = long
@@ -922,18 +1114,86 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
|| medicalIssues.value == resources.getStringArray(R.array.yes_no)[0] || pastCSection.value == resources.getStringArray(
R.array.yes_no
)[0])
+
+ }
+ var insertIndex = list.indexOf(noOfLiveChildren) + 1
+
+ noOfLiveChildren.value = childList.size.coerceAtMost(9).toString()
+ val limitedChildList = childList.take(9)
+ numFemale.value = limitedChildList.count { it.gender == Gender.FEMALE }.toString()
+ numMale.value = limitedChildList.count { it.gender == Gender.MALE }.toString()
+ childList.take(9).forEachIndexed { index, child ->
+ val bundle = children[index]
+ bundle.dob.value = getDateFromLong(child.dob)
+ bundle.age.value = child.age?.toString()
+
+ bundle.gender.value = getLocalValueInArray(
+ R.array.ecr_gender_array,
+ child.gender?.name
+ ?.lowercase()
+ ?.replaceFirstChar { it.uppercase() }
+ )
+
+ if (index == 0) {
+ setSiblingAgeDiff(timeAtMarriage, child.dob, bundle.gap)
+ } else {
+ setSiblingAgeDiff(
+ childList[index - 1].dob,
+ child.dob,
+ bundle.gap
+ )
+ }
+
+ val childViews = listOf(
+ bundle.dob,
+ bundle.age,
+ bundle.gender,
+ bundle.gap
+ )
+
+ list.addAll(insertIndex, childViews)
+
+ insertIndex += childViews.size
}
+
saved?.let { ecCache ->
dateOfReg.value = getDateFromLong(ecCache.dateOfReg)
bankAccount.value = ecCache.bankAccount?.toString()
bankName.value = ecCache.bankName
branchName.value = ecCache.branchName
ifsc.value = ecCache.ifsc
- noOfChildren.value = ecCache.noOfChildren.toString()
- noOfLiveChildren.value = ecCache.noOfLiveChildren.toString()
- numMale.value = ecCache.noOfMaleChildren.toString()
- numFemale.value = ecCache.noOfFemaleChildren.toString()
- if (ecCache.noOfLiveChildren > 0) {
+// noOfChildren.value = ecCache.noOfChildren.toString()
+// noOfLiveChildren.value = ecCache.noOfLiveChildren.toString()
+ lmpDate.value = getDateFromLong(ecCache.lmpDate)
+// numMale.value = ecCache.noOfMaleChildren.toString()
+// numFemale.value = ecCache.noOfFemaleChildren.toString()
+ val isKitHandedOver = ecCache.isKitHandedOver == true
+ nayiPahelKitHandOver.value = if (isKitHandedOver) nayiPahelKitHandOver.entries!![0] else nayiPahelKitHandOver.entries!![1]
+ if (isKitHandedOver) {
+ list.addAll(
+ list.indexOf(nayiPahelKitHandOver) + 1,
+ listOf(kithandOverDate)
+ )
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.addAll(
+ list.indexOf(kithandOverDate) + 1,
+ listOf(ashaPhotoTitle,kitPhotoUploadOne, kitPhotoUploadTwo)
+ )
+ }
+
+
+
+
+ ecCache.kitHandedOverDate?.let { kithandOverDate.value = getDateFromLong(it) }
+ kitPhotoUploadOne.value = ecCache.kitPhoto1
+ kitPhotoUploadTwo.value = ecCache.kitPhoto2
+ } else {
+ kitPhotoUploadOne.value = null
+ kitPhotoUploadTwo.value = null
+ }
+
+
+ /* if (ecCache.noOfLiveChildren > 0) {
ecCache.dob1?.let {
dob1.value = getDateFromLong(it)
age1.value = if (BenBasicCache.getAgeUnitFromDob(it)
@@ -1118,12 +1378,13 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
list.indexOf(seventhAndEighthChildGap) + 1,
listOf(ninthChildDetails, dob9, age9, gender9, eighthAndNinthChildGap)
)
- }
+ }*/
}
setUpPage(list)
}
+
override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
return when (formId) {
@@ -1133,6 +1394,41 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
// updateAgeCheck(dateOfBirth, getLongFromDate(dateOfReg.value))
// handleListOnValueChanged(ageCheck.id, 0)
// }
+ nayiPahelKitHandOver.id -> {
+ nayiPahelKitHandOver.isEnabled = true
+ if (nayiPahelKitHandOver.value == resources.getStringArray(R.array.yes_no)[0] )
+ {
+
+ showDialogEvent.value = "Please upload photo of \"couple with Nayi Pahal kit\", to claim your Incentive."
+ var list1: List = emptyList()
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list1 = listOf(
+ kithandOverDate,
+ ashaPhotoTitle,
+ kitPhotoUploadOne,
+ kitPhotoUploadTwo
+ )
+ } else {
+ list1 = listOf(kithandOverDate)
+ }
+ triggerDependants(
+ source = nayiPahelKitHandOver,
+ passedIndex = index,
+ triggerIndex = 0,
+ target =list1 //listOf(kithandOverDate, ashaPhotoTitle,kitPhotoUploadOne, kitPhotoUploadTwo),
+ )
+ } else if (nayiPahelKitHandOver.value == resources.getStringArray(R.array.yes_no)[1]) {
+ triggerforHide(
+ source = nayiPahelKitHandOver,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = kithandOverDate,
+ targetSideEffect = listOf(kithandOverDate,ashaPhotoTitle, kitPhotoUploadOne, kitPhotoUploadTwo),
+ )
+ }
+ 0
+ }
+
rchId.id -> {
validateRchIdOnEditText(rchId)
}
@@ -1142,7 +1438,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
}
bankAccount.id -> {
- validateAllZerosOnEditText(bankAccount)
+ validateIntMinMax(bankAccount)
}
bankName.id -> {
@@ -1157,6 +1453,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
validateAllAlphaNumericOnEditText(ifsc)
}
+
ageAtMarriage.id -> {
if (ageAtMarriage.value.isNullOrEmpty()) {
validateEmptyOnEditText(ageAtMarriage)
@@ -1211,97 +1508,107 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
assignValuesToAgeFromDob(dob1Long, age1)
validateIntMinMax(age1)
setSiblingAgeDiff(timeAtMarriage, dob1Long, marriageFirstChildGap)
- dob2.min = dob1Long
+ // dob2.min = dob1Long
+ dob2.min = getLongFromDate(getMinimumSecondChildDob(dob1.value))
updateTimeLessThan18()
}
-1
}
dob2.id -> {
+ // dob2.inputType = EDIT_TEXT
+ isValidChildGap(dob2,dob1.value)
if (dob1.value != null && dob2.value != null) {
val dob2Long = getLongFromDate(dob2.value)
val dob1Long = getLongFromDate(dob1.value)
assignValuesToAgeFromDob(dob2Long, age2)
setSiblingAgeDiff(dob1Long, dob2Long, firstAndSecondChildGap)
- dob3.min = dob2Long
+ dob3.min = getLongFromDate(getMinimumSecondChildDob(dob2.value)) //dob2Long
updateTimeLessThan18()
}
-1
}
dob3.id -> {
+ isValidChildGap(dob3,dob2.value)
if (dob2.value != null && dob3.value != null) {
val dob2Long = getLongFromDate(dob2.value)
val dob3Long = getLongFromDate(dob3.value)
assignValuesToAgeFromDob(dob3Long, age3)
setSiblingAgeDiff(dob2Long, dob3Long, secondAndThirdChildGap)
- dob4.min = dob3Long
+ dob4.min = getLongFromDate(getMinimumSecondChildDob(dob3.value))//dob3Long
updateTimeLessThan18()
}
-1
}
dob4.id -> {
+ isValidChildGap(dob4,dob3.value)
if (dob3.value != null && dob4.value != null) {
val dob3Long = getLongFromDate(dob3.value)
val dob4Long = getLongFromDate(dob4.value)
assignValuesToAgeFromDob(dob4Long, age4)
setSiblingAgeDiff(dob3Long, dob4Long, thirdAndFourthChildGap)
- dob5.min = dob4Long
+ dob5.min = getLongFromDate(getMinimumSecondChildDob(dob4.value))//dob4Long
updateTimeLessThan18()
}
-1
}
dob5.id -> {
+ isValidChildGap(dob5,dob4.value)
if (dob4.value != null && dob5.value != null) {
val dob4Long = getLongFromDate(dob4.value)
val dob5Long = getLongFromDate(dob5.value)
assignValuesToAgeFromDob(dob5Long, age5)
setSiblingAgeDiff(dob4Long, dob5Long, fourthAndFifthChildGap)
- dob6.min = dob5Long
+ dob6.min = getLongFromDate(getMinimumSecondChildDob(dob5.value)) //dob5Long
updateTimeLessThan18()
}
-1
}
dob6.id -> {
+ isValidChildGap(dob6,dob5.value)
if (dob5.value != null && dob6.value != null) {
val dob5Long = getLongFromDate(dob5.value)
val dob6Long = getLongFromDate(dob6.value)
assignValuesToAgeFromDob(dob6Long, age6)
setSiblingAgeDiff(dob5Long, dob6Long, fifthAndSixthChildGap)
- dob7.min = dob6Long
+ dob7.min = getLongFromDate(getMinimumSecondChildDob(dob6.value)) //dob6Long
updateTimeLessThan18()
}
-1
}
dob7.id -> {
+ isValidChildGap(dob7,dob6.value)
if (dob6.value != null && dob7.value != null) {
val dob6Long = getLongFromDate(dob6.value)
val dob7Long = getLongFromDate(dob7.value)
assignValuesToAgeFromDob(dob7Long, age7)
setSiblingAgeDiff(dob6Long, dob7Long, sixthAndSeventhChildGap)
- dob8.min = dob7Long
+ dob8.min =getLongFromDate(getMinimumSecondChildDob(dob7.value))// dob7Long
updateTimeLessThan18()
}
-1
}
dob8.id -> {
+ isValidChildGap(dob8,dob7.value)
if (dob7.value != null && dob8.value != null) {
val dob7Long = getLongFromDate(dob7.value)
val dob8Long = getLongFromDate(dob8.value)
assignValuesToAgeFromDob(dob8Long, age8)
setSiblingAgeDiff(dob7Long, dob8Long, seventhAndEighthChildGap)
- dob9.min = dob8Long
+ dob9.min =getLongFromDate(getMinimumSecondChildDob(dob8.value)) // dob8Long
updateTimeLessThan18()
}
-1
}
dob9.id -> {
+ isValidChildGap(dob9,dob8.value)
if (dob8.value != null && dob9.value != null) {
val dob8Long = getLongFromDate(dob8.value)
val dob9Long = getLongFromDate(dob9.value)
@@ -1720,12 +2027,15 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
timeInMillis = new
}
val diff = getDiffYears(calOld, calNew)
- target.value = diff.toString()
+ target.value = "${diff.toString()} years"
}
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as EligibleCoupleRegCache).let { ecr ->
ecr.dateOfReg = getLongFromDate(dateOfReg.value!!)
+ lmpDate.value?.let {
+ ecr.lmpDate = getLongFromDate(it)
+ }
ecr.bankAccount = bankAccount.value?.takeIf { it.isNotBlank() }?.toLong()
ecr.bankName = bankName.value
ecr.branchName = branchName.value
@@ -1741,8 +2051,12 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender1.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.marriageFirstChildGap =
- marriageFirstChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.isKitHandedOver = nayiPahelKitHandOver.value == nayiPahelKitHandOver.entries!![0]
+ ecr.kitHandedOverDate = getLongFromDate(kithandOverDate.value)
+ ecr.kitPhoto1 = kitPhotoUploadOne.value
+ ecr.kitPhoto2 = kitPhotoUploadTwo.value
+ ecr.marriageFirstChildGap =marriageFirstChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ // marriageFirstChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
if (noOfLiveChildren.value?.toInt()!! > 1) {
ecr.dob2 = getLongFromDate(dob2.value)
ecr.age2 = age2.value?.toInt()
@@ -1751,8 +2065,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender2.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.firstAndSecondChildGap =
- firstAndSecondChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.firstAndSecondChildGap =firstAndSecondChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
if (noOfLiveChildren.value?.toInt()!! > 2) {
ecr.dob3 = getLongFromDate(dob3.value)
@@ -1762,8 +2075,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender3.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.secondAndThirdChildGap =
- secondAndThirdChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.secondAndThirdChildGap =secondAndThirdChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
if (noOfLiveChildren.value?.toInt()!! > 3) {
ecr.dob4 = getLongFromDate(dob4.value)
@@ -1773,8 +2085,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender4.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.thirdAndFourthChildGap =
- thirdAndFourthChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.thirdAndFourthChildGap =thirdAndFourthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
if (noOfLiveChildren.value?.toInt()!! > 4) {
ecr.dob5 = getLongFromDate(dob5.value)
@@ -1784,8 +2095,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender5.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.fourthAndFifthChildGap =
- fourthAndFifthChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.fourthAndFifthChildGap =fourthAndFifthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
if (noOfLiveChildren.value?.toInt()!! > 5) {
ecr.dob6 = getLongFromDate(dob6.value)
@@ -1795,8 +2105,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender6.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.fifthANdSixthChildGap =
- fifthAndSixthChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.fifthANdSixthChildGap =fifthAndSixthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
if (noOfLiveChildren.value?.toInt()!! > 6) {
ecr.dob7 = getLongFromDate(dob7.value)
@@ -1806,8 +2115,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender7.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.sixthAndSeventhChildGap =
- sixthAndSeventhChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.sixthAndSeventhChildGap =sixthAndSeventhChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
if (noOfLiveChildren.value?.toInt()!! > 7) {
ecr.dob8 = getLongFromDate(dob8.value)
@@ -1817,8 +2125,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender8.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.seventhAndEighthChildGap =
- seventhAndEighthChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.seventhAndEighthChildGap = seventhAndEighthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
if (noOfLiveChildren.value?.toInt()!! > 8) {
ecr.dob9 = getLongFromDate(dob9.value)
@@ -1828,8 +2135,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
gender9.entries!![1] -> Gender.FEMALE
else -> null
}
- ecr.eighthAndNinthChildGap =
- eighthAndNinthChildGap.value?.takeIf { it.isNotBlank() }?.toInt()
+ ecr.eighthAndNinthChildGap = eighthAndNinthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
}
}
}
@@ -1846,21 +2152,7 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
isUpdated = true
}
}
-// aadharNo.value?.takeIf {
-// aadharNo.inputType == EDIT_TEXT &&
-// it.isNotEmpty()
-// }?.let {
-// val last4 = "*".repeat(8) + it.takeLast(4)
-// if (
-// last4
-// != aadharNoFromBen
-// ) {
-// ben?.hasAadhar = true
-// ben?.hasAadharId = 1
-// ben?.aadharNum = last4
-// isUpdated = true
-// }
-// }
+
isHighRisk().let { highRisk ->
if (highRisk) {
ben?.isHrpStatus = true
@@ -1960,4 +2252,51 @@ class EligibleCoupleRegistrationDataset(context: Context, language: Languages) :
fun getIndexOfGap9() = getIndexById(eighthAndNinthChildGap.id)
fun getIndexOfTimeLessThan18() = getIndexById(timeLessThan18m.id)
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ if (lastImageFormId == 75) {
+ kitPhotoUploadOne.value = dpUri.toString()
+ kitPhotoUploadOne.errorText = null
+
+ } else {
+ kitPhotoUploadTwo.value = dpUri.toString()
+ kitPhotoUploadTwo.errorText = null
+
+ }
+
+ }
+
+ private val children = listOf(
+ ChildBundle(firstChildDetails, dob1, age1, gender1, marriageFirstChildGap),
+ ChildBundle(secondChildDetails, dob2, age2, gender2, firstAndSecondChildGap),
+ ChildBundle(thirdChildDetails, dob3, age3, gender3, secondAndThirdChildGap),
+ ChildBundle(fourthChildDetails, dob4, age4, gender4, thirdAndFourthChildGap),
+ ChildBundle(fifthChildDetails, dob5, age5, gender5, fourthAndFifthChildGap),
+ ChildBundle(sixthChildDetails, dob6, age6, gender6, fifthAndSixthChildGap),
+ ChildBundle(seventhChildDetails, dob7, age7, gender7, sixthAndSeventhChildGap),
+ ChildBundle(eighthChildDetails, dob8, age8, gender8, seventhAndEighthChildGap),
+ ChildBundle(ninthChildDetails, dob9, age9, gender9, eighthAndNinthChildGap)
+ )
+
+ data class ChildBundle(
+ val details: FormElement,
+ val dob: FormElement,
+ val age: FormElement,
+ val gender: FormElement,
+ val gap: FormElement
+ ) {
+ fun isEmpty(): Boolean {
+ return dob.value.isNullOrEmpty() &&
+ age.value.isNullOrEmpty() &&
+ gender.value.isNullOrEmpty()
+ }
+ fun toFormList() = listOf(details, dob, age, gender, gap)
+ fun clearValues() {
+
+ dob.value = null
+ age.value = null
+ gender.value = null
+ gap.value = null
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleTrackingDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleTrackingDataset.kt
index 84099366a..b893fc144 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleTrackingDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/EligibleCoupleTrackingDataset.kt
@@ -1,7 +1,10 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.configuration.PregnantWomanRegistrationDataset.Companion.getMinLmpMillis
import org.piramalswasthya.sakhi.database.room.SyncState
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
@@ -9,12 +12,17 @@ import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.EligibleCoupleTrackingCache
import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.InputType
+import java.text.SimpleDateFormat
import java.util.Calendar
+import java.util.Locale
class EligibleCoupleTrackingDataset(
context: Context, currentLanguage: Languages
) : Dataset(context, currentLanguage) {
+ var antraDoseValue="N/A"
+ var noOfChildrens=-1
+
private var dateOfVisit = FormElement(
id = 1,
inputType = InputType.DATE_PICKER,
@@ -26,6 +34,35 @@ class EligibleCoupleTrackingDataset(
)
+ private var dateOfSterilisation = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date_of_sterilisation),
+ arrayId = -1,
+ required = true,
+ min = Calendar.getInstance().apply {
+ set(Calendar.DAY_OF_MONTH, 1)
+ set(Calendar.HOUR_OF_DAY, 0)
+ set(Calendar.MINUTE, 0)
+ set(Calendar.SECOND, 0)
+ set(Calendar.MILLISECOND, 0)
+ }.timeInMillis,
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+ private var lmpDate = FormElement(
+ id = 11,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.lmp_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = getMinLmpMillis(),
+ hasDependants = true
+ )
+
private val financialYear = FormElement(
id = 2,
inputType = InputType.TEXT_VIEW,
@@ -77,9 +114,27 @@ class EligibleCoupleTrackingDataset(
required = false,
hasDependants = true
)
+ // Q2 – Only for Mitanin
+ private val usingFamilyPlanningMitanin = FormElement(
+ id = 8,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.ectdset_fly_plan_mthd_mitanin),
+ entries = resources.getStringArray(R.array.ectdset_yes_no),
+ required = false,
+ hasDependants = true
+ )
+
+ private val wantToUseFamilyPlanning = FormElement(
+ id = 9,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.ectdset_want_to_use_fly_plan_mthd_mitanin),
+ entries = resources.getStringArray(R.array.ectdset_yes_no),
+ required = false,
+ hasDependants = true
+ )
private val methodOfContraception = FormElement(
- id = 8,
+ id = 10,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.ectdset_mthd_conpt),
arrayId = R.array.method_of_contraception,
@@ -89,8 +144,19 @@ class EligibleCoupleTrackingDataset(
)
+ private val antraDoses = FormElement(
+ id = 11,
+ inputType = InputType.DROPDOWN,
+ title = "Antra injection",
+ arrayId = R.array.antra_doses,
+ entries = resources.getStringArray(R.array.antra_doses),
+ required = true,
+ hasDependants = true
+
+ )
+
private val anyOtherMethod = FormElement(
- id = 9,
+ id = 12,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.ectdset_other_mthd),
required = true,
@@ -98,23 +164,74 @@ class EligibleCoupleTrackingDataset(
etMaxLength = 50
)
+ private var dateOfAntraInjection = FormElement(
+ id = 13,
+ inputType = InputType.DATE_PICKER,
+ title = context.getString(R.string.date_of_antra_injection),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+ private var dueDateOfAntraInjection = FormElement(
+ id = 14,
+ inputType = InputType.TEXT_VIEW,
+ title = context.getString(R.string.due_date_of_next_injection),
+ required = false,
+
+ )
+ private val mpaFileUpload1 = FormElement(
+ id = 23,
+ inputType = InputType.FILE_UPLOAD,
+ title = context.getString(R.string.mpa_card),
+ required = false,
+ )
+
+
+ private val deliveryDischargeSummary1 = FormElement(
+ id = 60,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.ectdset_discharge_summary_1),
+ required = false
+
+ )
+ private val deliveryDischargeSummary2 = FormElement(
+ id =61,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.ectdset_discharge_summary_2),
+ required = false
+ )
+ var lastDose: String? = null
+ var lastDateofDose: String? = null
fun getIndexOfIsPregnant() = getIndexById(isPregnant.id)
suspend fun setUpPage(
ben: BenRegCache?,
dateOfReg: Long,
lastTrack: EligibleCoupleTrackingCache?,
- saved: EligibleCoupleTrackingCache?
+ saved: EligibleCoupleTrackingCache?,
+ noOfChildren: Int?
) {
+ noOfChildrens = noOfChildren!!
+ lastDose = lastTrack?.antraDose
+ lastDateofDose = lastTrack?.dateOfAntraInjection
+
+ methodOfContraception.entries =
+ if (noOfChildren == 0)
+ resources.getStringArray(R.array.method_of_contraception_for_zero_child)
+ else
+ resources.getStringArray(R.array.method_of_contraception)
+
val list = mutableListOf(
dateOfVisit,
+ lmpDate,
financialYear,
month,
isPregnancyTestDone,
- isPregnant,
-// usingFamilyPlanning,
)
+
if (saved == null) {
dateOfVisit.value = getDateFromLong(System.currentTimeMillis())
dateOfVisit.value?.let {
@@ -123,6 +240,10 @@ class EligibleCoupleTrackingDataset(
resources.getStringArray(R.array.visit_months)[Companion.getMonth(it)!!]
}
+ if (ben != null) {
+ dateOfAntraInjection.min = ben.regDate
+ }
+
dateOfVisit.min = lastTrack?.let {
Calendar.getInstance().apply {
timeInMillis = it.visitDate
@@ -137,111 +258,524 @@ class EligibleCoupleTrackingDataset(
setToStartOfTheDay()
}.timeInMillis
} ?: dateOfReg
+
} else {
+
+ // -------- EDIT ENTRY --------
+
dateOfVisit.value = getDateFromLong(saved.visitDate)
+ dateOfSterilisation.value = getDateFromLong(saved.dateOfSterilisation)
+ lmpDate.value =
+ if (saved.lmpDate != null)
+ getDateFromLong(saved.lmpDate)
+ else
+ getDateFromLong(System.currentTimeMillis())
+
financialYear.value = getFinancialYear(dateString = dateOfVisit.value)
month.value =
resources.getStringArray(R.array.visit_months)[Companion.getMonth(dateOfVisit.value)!!]
+
isPregnancyTestDone.value =
getLocalValueInArray(R.array.yes_no, saved.isPregnancyTestDone)
+
if (isPregnancyTestDone.value == resources.getStringArray(R.array.yes_no)[0]) {
+
list.add(list.indexOf(isPregnancyTestDone) + 1, pregnancyTestResult)
- pregnancyTestResult.value = saved.pregnancyTestResult
- }
- isPregnant.value = getLocalValueInArray(R.array.yes_no, saved.isPregnant)
- if (isPregnant.value == resources.getStringArray(R.array.yes_no)[1]) {
- list.add(usingFamilyPlanning)
- saved.usingFamilyPlanning?.let {
+ pregnancyTestResult.value = getLocalValueInArray(R.array.ectdset_po_neg, saved.pregnancyTestResult)
+
+ } else {
+
+ // Restore FP answers
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+
usingFamilyPlanning.value =
- if (it) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
- R.array.yes_no
- )[1]
+ if (saved.usingFamilyPlanning == true)
+ resources.getStringArray(R.array.yes_no)[0]
+ else
+ resources.getStringArray(R.array.yes_no)[1]
+
+ if (saved.usingFamilyPlanning == true) {
+ list.add(methodOfContraception)
+ }
+
+ } else {
+
+ usingFamilyPlanningMitanin.value =
+ if (saved.usingFamilyPlanning == true)
+ resources.getStringArray(R.array.ectdset_yes_no)[0]
+ else
+ resources.getStringArray(R.array.ectdset_yes_no)[1]
+
+ if (saved.usingFamilyPlanning == true) {
+ list.add(methodOfContraception)
+ } else {
+ list.add(wantToUseFamilyPlanning)
+
+ if (saved.methodOfContraception != null) {
+ wantToUseFamilyPlanning.value =
+ resources.getStringArray(R.array.ectdset_yes_no)[0]
+ list.add(methodOfContraception)
+ }
+ }
}
- usingFamilyPlanning.value =
- if (saved.usingFamilyPlanning == true) resources.getStringArray(R.array.yes_no)[1] else resources.getStringArray(
- R.array.yes_no
- )[1]
- if (saved.usingFamilyPlanning == true) {
- list.add(methodOfContraception)
- if (saved.methodOfContraception in resources.getStringArray(R.array.method_of_contraception)) {
- methodOfContraception.value = saved.methodOfContraception
- } else if (saved.methodOfContraception != null) {
- methodOfContraception.value =
- resources.getStringArray(R.array.method_of_contraception).last()
- list.add(anyOtherMethod)
- anyOtherMethod.value = saved.methodOfContraception
+
+ // Restore FP method details
+ saved.methodOfContraception?.let { method ->
+ val methods = resources.getStringArray(R.array.method_of_contraception)
+ val sterilizationIndices = listOf(7, 8)
+ val methodPart = method.split("/")[0]
+ val localMethodPart = getLocalValueInArray(R.array.method_of_contraception, methodPart) ?: methodPart
+
+ when {
+ localMethodPart in methods && !method.contains("/") -> {
+ methodOfContraception.value = localMethodPart
+ val selectedIndex = methods.indexOf(localMethodPart)
+
+ if (selectedIndex in sterilizationIndices &&
+ !BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)
+ ) {
+ list.add(deliveryDischargeSummary1)
+ list.add(deliveryDischargeSummary2)
+ deliveryDischargeSummary1.value = saved.dischargeSummary1
+ deliveryDischargeSummary2.value = saved.dischargeSummary2
+ }
+ }
+
+ localMethodPart == methods[1] -> {
+ methodOfContraception.value = methods[1]
+ list.add(antraDoses)
+ list.add(dateOfAntraInjection)
+ list.add(dueDateOfAntraInjection)
+
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.add(mpaFileUpload1)
+ mpaFileUpload1.value = saved.mpaFile
+ }
+
+ dateOfAntraInjection.value = saved.dateOfAntraInjection
+ dueDateOfAntraInjection.value = saved.dueDateOfAntraInjection
+
+ if (saved.antraDose != null) {
+ antraDoseValue = saved.antraDose!!
+ antraDoses.value = saved.antraDose
+ }
+ }
+
+ else -> {
+ methodOfContraception.value = methods.last()
+ list.add(anyOtherMethod)
+ anyOtherMethod.value = method
+ }
}
}
}
+ isPregnant.value = getLocalValueInArray(R.array.yes_no, saved.isPregnant)
}
- setUpPage(list)
+ val nextDose = getNextDose(lastDose, lastDateofDose, dateOfVisit.value!!)
+ antraDoses.value = nextDose
+ antraDoseValue = nextDose
+ antraDoses.isEnabled = false
+
+ setUpPage(list)
}
+
override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
return when (formId) {
dateOfVisit.id -> {
financialYear.value = Companion.getFinancialYear(dateOfVisit.value)
- month.value =
- resources.getStringArray(R.array.visit_months)[Companion.getMonth(dateOfVisit.value)!!]
+ month.value = resources.getStringArray(R.array.visit_months)[Companion.getMonth(dateOfVisit.value)!!]
+ val nextDose = getNextDose(lastDose, lastDateofDose, dateOfVisit.value!!)
+ antraDoses.value = nextDose
+ antraDoseValue=nextDose
+ antraDoses.isEnabled = false
+ -1
+ }
+ dateOfAntraInjection.id -> {
+ val injectionDate = dateOfAntraInjection.value ?: ""
+
+ val (minDate, maxDate) = calculateNextInjectionDate(injectionDate, 76, 120)
+
+ dueDateOfAntraInjection.value =
+ if (minDate.isNotEmpty() && maxDate.isNotEmpty()) {
+ "$minDate to $maxDate"
+ } else {
+ resources.getString(R.string.invalid_injection_date)
+ }
-1
}
isPregnancyTestDone.id -> {
+ antraDoses.value = antraDoseValue
isPregnant.isEnabled = true
- triggerDependants(
- source = isPregnancyTestDone,
- passedIndex = index,
- triggerIndex = 0,
- target = pregnancyTestResult
- )
+ if (isPregnancyTestDone.value == resources.getStringArray(R.array.ectdset_yes_no_dont)[0]) {
+ triggerDependants(
+ source = isPregnancyTestDone,
+ removeItems = listOf(isPregnant,usingFamilyPlanning,usingFamilyPlanningMitanin,wantToUseFamilyPlanning,methodOfContraception,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,anyOtherMethod,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2),
+ addItems = listOf(pregnancyTestResult)
+ )
+ }
+ else{
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ triggerDependants(
+ source = isPregnancyTestDone,
+ removeItems = listOf(isPregnant,pregnancyTestResult,usingFamilyPlanningMitanin,wantToUseFamilyPlanning,methodOfContraception,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,anyOtherMethod,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2),
+ addItems = listOf(usingFamilyPlanning)
+ )
+ }else{
+ triggerDependants(
+ source = isPregnancyTestDone,
+ removeItems = listOf(isPregnant,pregnancyTestResult,usingFamilyPlanning,methodOfContraception,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,anyOtherMethod,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2,wantToUseFamilyPlanning),
+ addItems = listOf(usingFamilyPlanningMitanin)
+ )
+ }
+ }
+
+ return 0
}
pregnancyTestResult.id -> {
+ antraDoses.value = antraDoseValue
if (pregnancyTestResult.value == resources.getStringArray(R.array.ectdset_po_neg)[0]) {
isPregnant.value = resources.getStringArray(R.array.yes_no)[0]
isPregnant.isEnabled = false
- } else {
+
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ triggerDependants(
+ source = pregnancyTestResult,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = isPregnant,
+ targetSideEffect = listOf(isPregnant,usingFamilyPlanning,methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+ triggerforHide(
+ source = pregnancyTestResult,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanning,
+ targetSideEffect = listOf(usingFamilyPlanning,methodOfContraception,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,anyOtherMethod,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+ }else{
+
+ triggerDependants(
+ source = pregnancyTestResult,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = isPregnant,
+ targetSideEffect = listOf(isPregnant,usingFamilyPlanningMitanin,wantToUseFamilyPlanning,methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+ triggerforHide(
+ source = pregnancyTestResult,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanningMitanin,
+ targetSideEffect = listOf(usingFamilyPlanningMitanin,wantToUseFamilyPlanning,methodOfContraception,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,anyOtherMethod,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+ }
+ }
+ else if (pregnancyTestResult.value == resources.getStringArray(R.array.ectdset_po_neg)[1]) {
+ isPregnant.isEnabled = false
+ isPregnant.value = resources.getStringArray(R.array.yes_no)[1]
+
+
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ triggerDependants(
+ source = pregnancyTestResult,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = isPregnant,
+ targetSideEffect = listOf(isPregnant,usingFamilyPlanning,methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanning,
+ targetSideEffect = listOf(methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+ }else{
+
+ triggerDependants(
+ source = pregnancyTestResult,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = isPregnant,
+ targetSideEffect = listOf(isPregnant,usingFamilyPlanningMitanin,wantToUseFamilyPlanning,methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanningMitanin,
+ targetSideEffect = listOf(wantToUseFamilyPlanning,methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ )
+
+ }
+
+
+ }
+ else {
isPregnant.value = null
isPregnant.isEnabled = true
}
- handleListOnValueChanged(isPregnant.id, 0)
+ return 0
}
isPregnant.id -> {
- triggerDependants(
- source = isPregnant,
- passedIndex = index,
- triggerIndex = 1,
- target = usingFamilyPlanning,
- targetSideEffect = listOf(methodOfContraception, anyOtherMethod)
- )
+ antraDoses.value = antraDoseValue
+ var list1: List = emptyList()
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list1=listOf(methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+ }else{
+ list1= listOf(methodOfContraception,anyOtherMethod,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,wantToUseFamilyPlanning,dateOfSterilisation,deliveryDischargeSummary1,deliveryDischargeSummary2)
+
+ }
+ if (isPregnant.value == resources.getStringArray(R.array.ectdset_yes_no_dont)[0]) {
+
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanning,
+ targetSideEffect = list1
+ )
+ }else{
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanningMitanin,
+ targetSideEffect = list1
+ )
+ }
+ }
+ else if (isPregnant.value == resources.getStringArray(R.array.ectdset_yes_no_dont)[1]) {
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanning,
+ targetSideEffect = list1
+ )
+ }else{
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = usingFamilyPlanningMitanin,
+ targetSideEffect = list1
+ )
+ }
+ }
+ else {
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 2,
+ target = usingFamilyPlanning,
+ targetSideEffect = list1 )
+ }else{
+ triggerDependants(
+ source = isPregnant,
+ passedIndex = index,
+ triggerIndex = 2,
+ target = usingFamilyPlanningMitanin,
+ targetSideEffect = list1 )
+ }
+ }
+ return 0
+
+
}
usingFamilyPlanning.id -> {
- triggerDependants(
- source = usingFamilyPlanning,
- passedIndex = index,
- triggerIndex = 0,
- target = methodOfContraception,
- targetSideEffect = listOf(anyOtherMethod)
- )
+ antraDoses.value = antraDoseValue
+ methodOfContraception.inputType= InputType.DROPDOWN
+ methodOfContraception.entries =
+ if (noOfChildrens == 0)
+ resources.getStringArray(R.array.method_of_contraception_for_zero_child)
+ else
+ resources.getStringArray(R.array.method_of_contraception)
+ if (usingFamilyPlanning.value == resources.getStringArray(R.array.ectdset_yes_no)[0]) {
+ triggerDependants(
+ source = usingFamilyPlanning,
+ removeItems = emptyList(),
+ addItems = listOf(methodOfContraception)
+ )
+
+ }
+ else{
+ triggerDependants(
+ source = usingFamilyPlanning,
+ removeItems = listOf(methodOfContraception,dateOfSterilisation,antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,anyOtherMethod,mpaFileUpload1,deliveryDischargeSummary1,deliveryDischargeSummary2),
+ addItems = emptyList()
+ )
+ }
+
}
methodOfContraception.id -> {
- triggerDependants(
- source = methodOfContraception,
- passedIndex = index,
- triggerIndex = methodOfContraception.entries!!.lastIndex,
- target = anyOtherMethod
- )
+ antraDoses.value = antraDoseValue
+ when (methodOfContraception.value) {
+
+ resources.getStringArray(R.array.method_of_contraception)[1] -> {
+ var list1: List = emptyList()
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list1=listOf(antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1)
+
+ }else{
+ list1= listOf(antraDoses,dateOfAntraInjection,dueDateOfAntraInjection)
+
+ }
+
+ triggerDependants(
+ source = methodOfContraception,
+ addItems = list1,
+ removeItems = listOf(anyOtherMethod,dateOfSterilisation,deliveryDischargeSummary1,
+ deliveryDischargeSummary2),
+ position = getIndexById(methodOfContraception.id) + 1
+ )
+ }
+
+ resources.getStringArray(R.array.method_of_contraception).last() -> {
+ triggerDependants(
+ source = methodOfContraception,
+ addItems = listOf(anyOtherMethod),
+ removeItems = listOf(antraDoses,dateOfAntraInjection,dueDateOfAntraInjection,deliveryDischargeSummary1,
+ deliveryDischargeSummary2,mpaFileUpload1,dateOfSterilisation),
+ position = getIndexById(methodOfContraception.id) + 1
+ )
+ }
+
+ else -> {
+
+ if(noOfChildrens!=0)
+ {
+ val methods = resources.getStringArray(R.array.method_of_contraception).toMutableList()
+ val sterilizationIndices = listOf(7, 8)
+ val selectedIndex = methods.indexOf(methodOfContraception.value)
+ if (selectedIndex in sterilizationIndices) {
+ triggerDependants(
+ source = methodOfContraception,
+ addItems =
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true))
+ listOf(dateOfSterilisation,deliveryDischargeSummary1, deliveryDischargeSummary2)
+ else
+ listOf(dateOfSterilisation),
+ removeItems = listOf(
+ antraDoses,
+ anyOtherMethod,
+ dateOfAntraInjection,
+ dueDateOfAntraInjection,
+ mpaFileUpload1,
+ ),
+ position = -1
+ )
+ }
+ else{
+ triggerDependants(
+ source = methodOfContraception,
+ addItems = emptyList(),
+ removeItems = listOf(antraDoses,dateOfSterilisation, anyOtherMethod,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1, deliveryDischargeSummary1,
+ deliveryDischargeSummary2),
+ position = -1
+ )
+ }
+ }else{
+ triggerDependants(
+ source = methodOfContraception,
+ addItems = emptyList(),
+ removeItems = listOf(antraDoses,dateOfSterilisation, anyOtherMethod,dateOfAntraInjection,dueDateOfAntraInjection,mpaFileUpload1, deliveryDischargeSummary1,
+ deliveryDischargeSummary2),
+ position = -1
+ )
+ }
+
+ }
+ }
+ return 0
}
+
anyOtherMethod.id -> {
validateAllAlphabetsSpaceOnEditText(anyOtherMethod)
}
+ usingFamilyPlanningMitanin.id -> {
+ antraDoses.value = antraDoseValue
+ methodOfContraception.inputType = InputType.DROPDOWN
+ methodOfContraception.entries =
+ if (noOfChildrens == 0)
+ resources.getStringArray(R.array.method_of_contraception_for_zero_child)
+ else
+ resources.getStringArray(R.array.method_of_contraception)
+
+ if (usingFamilyPlanningMitanin.value ==
+ resources.getStringArray(R.array.ectdset_yes_no)[0]
+ ) {
+
+ triggerDependants(
+ source = usingFamilyPlanningMitanin,
+ removeItems = listOf(wantToUseFamilyPlanning),
+ addItems = listOf(methodOfContraception)
+ )
+
+ methodOfContraception.value = methodOfContraception.value
+
+ } else {
+ triggerDependants(
+ source = usingFamilyPlanningMitanin,
+ removeItems = listOf(
+ methodOfContraception,
+ antraDoses,
+ dateOfSterilisation,
+ dateOfAntraInjection,
+ dueDateOfAntraInjection,
+ anyOtherMethod,
+ mpaFileUpload1,
+ deliveryDischargeSummary1,
+ deliveryDischargeSummary2
+ ),
+ addItems = listOf(wantToUseFamilyPlanning)
+ )
+ }
+ return 0
+ }
+
+ wantToUseFamilyPlanning.id -> {
+ antraDoses.value = antraDoseValue
+ if (wantToUseFamilyPlanning.value == resources.getStringArray(R.array.ectdset_yes_no)[0]) {
+ // YES → show FP Methods
+ triggerDependants(
+ source = wantToUseFamilyPlanning,
+ removeItems = emptyList(),
+ addItems = listOf(methodOfContraception)
+ )
+ } else {
+ triggerDependants(
+ source = wantToUseFamilyPlanning,
+ removeItems = listOf(
+ methodOfContraception,
+ antraDoses,
+ dateOfAntraInjection,
+ dueDateOfAntraInjection,
+ anyOtherMethod,
+ mpaFileUpload1,
+ dateOfSterilisation,
+ deliveryDischargeSummary1,
+ deliveryDischargeSummary2
+ ),
+ addItems = emptyList()
+ )
+ }
+ return 0
+ }
+
else -> -1
}
@@ -249,18 +783,36 @@ class EligibleCoupleTrackingDataset(
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as EligibleCoupleTrackingCache).let { form ->
+ form.dateOfSterilisation = getLongFromDate(dateOfSterilisation.value)
form.visitDate = getLongFromDate(dateOfVisit.value)
- form.isPregnancyTestDone = isPregnancyTestDone.value
- form.pregnancyTestResult = pregnancyTestResult.value
- form.isPregnant = isPregnant.value
+ form.lmpDate = getLongFromDate(lmpDate.value)
+ form.dateOfAntraInjection=dateOfAntraInjection.value
+ form.dueDateOfAntraInjection=dueDateOfAntraInjection.value
+ form.mpaFile=mpaFileUpload1.value
+ form.antraDose=antraDoses.value
+ form.isPregnancyTestDone = getEnglishValueInArray(R.array.yes_no, isPregnancyTestDone.value) ?: isPregnancyTestDone.value
+ form.pregnancyTestResult = getEnglishValueInArray(R.array.ectdset_po_neg, pregnancyTestResult.value)
+ form.isPregnant = getEnglishValueInArray(R.array.yes_no, isPregnant.value)
+ form.dischargeSummary1 = deliveryDischargeSummary1.value
+ form.dischargeSummary2 = deliveryDischargeSummary2.value
+
+
form.usingFamilyPlanning =
- usingFamilyPlanning.value?.let { it == resources.getStringArray(R.array.yes_no)[0] }
- if (methodOfContraception.value == resources.getStringArray(R.array.method_of_contraception)
- .last()
- ) {
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ usingFamilyPlanningMitanin.value == resources.getStringArray(R.array.ectdset_yes_no)[0] ||
+ wantToUseFamilyPlanning.value == resources.getStringArray(R.array.ectdset_yes_no)[0]
+ } else {
+ usingFamilyPlanning.value == resources.getStringArray(R.array.yes_no)[0]
+ }
+
+ val methods = resources.getStringArray(R.array.method_of_contraception)
+ if (methodOfContraception.value == methods.last()) {
form.methodOfContraception = anyOtherMethod.value
+ } else if (methodOfContraception.value == methods[1]) {
+ val englishMethod = getEnglishValueInArray(R.array.method_of_contraception, methodOfContraception.value) ?: methodOfContraception.value
+ form.methodOfContraception = "${englishMethod}/${antraDoses.value}"
} else {
- form.methodOfContraception = methodOfContraception.value
+ form.methodOfContraception = getEnglishValueInArray(R.array.method_of_contraception, methodOfContraception.value)
}
}
}
@@ -268,10 +820,79 @@ class EligibleCoupleTrackingDataset(
fun updateBen(benRegCache: BenRegCache) {
benRegCache.genDetails?.let {
it.reproductiveStatus =
- englishResources.getStringArray(R.array.nbr_reproductive_status_array)[1]
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
it.reproductiveStatusId = 2
}
if (benRegCache.processed != "N") benRegCache.processed = "U"
benRegCache.syncState = SyncState.UNSYNCED
}
+
+
+ fun getIndexOfMPA() = getIndexById(mpaFileUpload1.id)
+ fun getIndexDeliveryDischargeSummary1 () = getIndexById(deliveryDischargeSummary1.id)
+ fun getIndexDeliveryDischargeSummary2 () = getIndexById(deliveryDischargeSummary2.id)
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+
+ when (lastImageFormId) {
+ 21 -> {
+ mpaFileUpload1.value = dpUri.toString()
+ mpaFileUpload1.errorText = null
+ }
+ 58 -> {
+ deliveryDischargeSummary1.value = dpUri.toString()
+ deliveryDischargeSummary1.errorText = null
+ }
+ 59 -> {
+ deliveryDischargeSummary2.value = dpUri.toString()
+ deliveryDischargeSummary2.errorText = null
+ }
+
+ }
+ }
+ private fun calculateNextInjectionDate(
+ injectionDate: String?,
+ minDays: Int,
+ maxDays: Int
+ ): Pair {
+ return try {
+ val sdf = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val date = sdf.parse(injectionDate ?: "") ?: return "" to ""
+
+ val cal = Calendar.getInstance()
+ cal.time = date
+
+ cal.add(Calendar.DAY_OF_YEAR, minDays)
+ val minDate = sdf.format(cal.time)
+
+ cal.time = date
+ cal.add(Calendar.DAY_OF_YEAR, maxDays)
+ val maxDate = sdf.format(cal.time)
+
+ minDate to maxDate
+ } catch (e: Exception) {
+ "" to ""
+ }
+ }
+
+
+ private fun getNextDose(lastDose: String?, lastDate: String?, visitDate: String): String {
+
+ if (lastDose == null || lastDate == null) {
+ return "Dose-1"
+ }
+
+ val sdf = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+
+ val last = sdf.parse(lastDate) ?: return "Dose-1"
+ val visit = sdf.parse(visitDate) ?: return "Dose-1"
+
+ val diffDays = ((visit.time - last.time) / (1000 * 60 * 60 * 24))
+ if (diffDays > 120) {
+ return "Dose-1"
+ }
+ val doseNum = lastDose.filter { it.isDigit() }.toIntOrNull() ?: 0
+ val next = doseNum + 1
+ return if (next in 1..10) "Dose-$next" else "No More Doses"
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/FilariaFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/FilariaFormDataset.kt
new file mode 100644
index 000000000..9072311f8
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/FilariaFormDataset.kt
@@ -0,0 +1,303 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FilariaScreeningCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.Gender
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.utils.HelperUtil.parseSelections
+import java.util.Calendar
+
+class FilariaFormDataset(
+ context: Context,
+ currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.home_visit_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ hasDependants = true
+ )
+
+ private val isSuffering = FormElement(
+ id = 2,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.suffering_from_filaries),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ )
+
+ private val whichPartOfBodyMale = FormElement(
+ id = 3,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.body_part),
+ arrayId = R.array.body_part_male,
+ entries = resources.getStringArray(R.array.body_part_male),
+ required = false,
+ hasDependants = true
+ )
+
+ private val whichPartOfBodyFemale = FormElement(
+ id = 4,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.body_part),
+ arrayId = R.array.body_part_female,
+ entries = resources.getStringArray(R.array.body_part_female),
+ required = false,
+ hasDependants = true
+ )
+
+ private val decAndAlbDoseStatus = FormElement(
+ id = 5,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.is_medicine_distributed),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ )
+
+ private val medicineSideEffect = FormElement(
+ id = 7,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.medicine_side_effect),
+ arrayId = R.array.side_effect_of_medicine,
+ entries = resources.getStringArray(R.array.side_effect_of_medicine),
+ required = false,
+ hasDependants = true
+ )
+
+ private val sideEffectOther = FormElement(
+ id = 8,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other),
+ required = true,
+ hasDependants = false
+ )
+
+ var isMale = false
+ var benAge = 0L
+
+ fun isMaleFemale(ben: BenRegCache?): Boolean {
+ return when (ben?.gender) {
+ Gender.MALE -> {
+ isMale = true
+ true
+ }
+ Gender.FEMALE -> {
+ isMale = false
+ false
+ }
+ else -> false
+ }
+ }
+
+ private fun toCsv(rawValue: String?, entries: Array): String {
+ return parseSelections(rawValue, entries).joinToString(", ")
+ }
+
+ suspend fun setUpPage(ben: BenRegCache?, saved: FilariaScreeningCache?) {
+
+ val list = mutableListOf(dateOfCase, isSuffering)
+
+ isMaleFemale(ben)
+ benAge = ben!!.dob
+ decAndAllDoseFieldValidation(benAge)
+
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ } else {
+ dateOfCase.value = getDateFromLong(saved.mdaHomeVisitDate)
+ isSuffering.value =
+ getLocalValueInArray(
+ R.array.yes_no,
+ if (saved.sufferingFromFilariasis == true) "Yes" else "No"
+ )
+
+ if (isSuffering.value == isSuffering.entries!!.first()) {
+
+ val bodyField = if (isMale) whichPartOfBodyMale else whichPartOfBodyFemale
+
+ list.add(list.indexOf(isSuffering) + 1, bodyField)
+ list.add(list.indexOf(isSuffering) + 2, decAndAlbDoseStatus)
+ list.add(list.indexOf(isSuffering) + 3, medicineSideEffect)
+
+ val parsedList = parseSelections(saved.affectedBodyPart, bodyField.entries!!)
+
+ bodyField.value = if (parsedList.isNotEmpty()) {
+ parsedList.joinToString(", ")
+ } else {
+ saved.affectedBodyPart ?: ""
+ }
+
+ bodyField.isEnabled = true
+
+ decAndAlbDoseStatus.value =
+ getLocalValueInArray(decAndAlbDoseStatus.arrayId, saved.doseStatus)
+
+ medicineSideEffect.value =
+ getLocalValueInArray(medicineSideEffect.arrayId, saved.medicineSideEffect)
+
+ if (medicineSideEffect.value ==
+ medicineSideEffect.entries!![medicineSideEffect.entries!!.size - 2]
+ ) {
+ list.add(list.indexOf(medicineSideEffect) + 1, sideEffectOther)
+ sideEffectOther.value = saved.otherSideEffectDetails
+ sideEffectOther.isEnabled = false
+ }
+ }
+ }
+
+ setUpPage(list)
+ }
+
+ private fun decAndAllDoseFieldValidation(age: Long) {
+ if (isYoung(age)) {
+ decAndAlbDoseStatus.isEnabled = false
+ decAndAlbDoseStatus.value =
+ getLocalValueInArray(decAndAlbDoseStatus.arrayId, "Yes")
+ } else {
+ decAndAlbDoseStatus.isEnabled = true
+ }
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ when (formId) {
+
+ isSuffering.id -> {
+ isSuffering.isEnabled = true
+
+ if (isSuffering.value == resources.getStringArray(R.array.yes_no)[0]) {
+
+ if (isMale) {
+ triggerDependants(
+ source = isSuffering,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = listOf(whichPartOfBodyMale, decAndAlbDoseStatus, medicineSideEffect)
+ )
+ } else {
+ triggerDependants(
+ source = isSuffering,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = listOf(whichPartOfBodyFemale, decAndAlbDoseStatus, medicineSideEffect)
+ )
+ whichPartOfBodyFemale.isEnabled = true
+ decAndAlbDoseStatus.isEnabled = true
+ decAndAllDoseFieldValidation(benAge)
+ }
+
+ } else {
+
+ val targetField =
+ if (isMale) whichPartOfBodyMale else whichPartOfBodyFemale
+
+ triggerforHide(
+ source = isSuffering,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = targetField,
+ targetSideEffect = listOf(
+ targetField,
+ decAndAlbDoseStatus,
+ medicineSideEffect,
+ sideEffectOther
+ )
+ )
+ }
+
+ return 0
+ }
+
+ medicineSideEffect.id -> {
+ if (medicineSideEffect.value ==
+ medicineSideEffect.entries!![medicineSideEffect.entries!!.size - 2]
+ ) {
+ triggerDependants(
+ source = medicineSideEffect,
+ addItems = listOf(sideEffectOther),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = medicineSideEffect,
+ addItems = listOf(),
+ removeItems = listOf(sideEffectOther)
+ )
+ }
+ return 0
+ }
+
+ sideEffectOther.id -> {
+ validateEmptyOnEditText(sideEffectOther)
+ return 0
+ }
+ }
+ return -1
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as FilariaScreeningCache).let { form ->
+
+ form.mdaHomeVisitDate = getLongFromDate(dateOfCase.value)
+ form.createdDate = getLongFromDate(dateOfCase.value)
+ form.sufferingFromFilariasis = isSuffering()
+ form.diseaseTypeID = 4
+
+ val bodyField = if (isMale) whichPartOfBodyMale else whichPartOfBodyFemale
+
+ form.affectedBodyPart = toCsv(bodyField.value, bodyField.entries!!)
+
+ form.otherSideEffectDetails = sideEffectOther.value
+ form.doseStatus = getEnglishValueInArray(R.array.yes_no, decAndAlbDoseStatus.value)
+ form.medicineSideEffect =
+ getEnglishValueInArray(R.array.side_effect_of_medicine, medicineSideEffect.value)
+ }
+ }
+
+ fun isSuffering(): Boolean {
+ return isSuffering.value == isSuffering.entries!!.first()
+ }
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+
+ fun isYoung(age: Long): Boolean {
+ val calDob = Calendar.getInstance().apply { timeInMillis = age }
+ val calNow = Calendar.getInstance()
+
+ val years = calNow.get(Calendar.YEAR) - calDob.get(Calendar.YEAR)
+ val months = calNow.get(Calendar.MONTH) - calDob.get(Calendar.MONTH)
+ val days = calNow.get(Calendar.DAY_OF_MONTH) - calDob.get(Calendar.DAY_OF_MONTH)
+
+ var totalYears = years
+ var totalMonths = months
+
+ if (totalMonths < 0 || (totalMonths == 0 && days < 0)) {
+ totalYears--
+ totalMonths += 12
+ }
+
+ return totalYears < 2
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBNCFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBNCFormDataset.kt
index dcdd714a4..687731883 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBNCFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBNCFormDataset.kt
@@ -99,7 +99,7 @@ class HBNCFormDataset(
if (currentDay == null) {
dateOfHomeVisit.value = getDateFromLong(System.currentTimeMillis())
firstDay?.let {
- childImmunizationStatus.value = it.babyImmunizationStatus
+ childImmunizationStatus.value = getCheckboxIndexesFromValues(R.array.hbnc_child_immunization_status, it.babyImmunizationStatus)
}
} else {
setExistingValuesForVisitPage(currentDay, list)
@@ -146,7 +146,7 @@ class HBNCFormDataset(
healthSubCenterName.id -> {
healthSubCenterName.value?.let {
if (it.length > 10 && healthSubCenterName.errorText == null) {
- healthSubCenterName.errorText = "Yay, it is working!!!"
+ healthSubCenterName.errorText = resources.getString(R.string.str_yay_it_is_working)
Timber.d("Yay, it is working!!!")
return -1
}
@@ -411,7 +411,7 @@ class HBNCFormDataset(
timeOfMotherDeath = timeOfMotherDeath.value,
placeOfMotherDeath = placeOfMotherDeath.getPosition(),
otherPlaceOfMotherDeath = otherPlaceOfMotherDeath.value,
- motherAnyProblem = motherProblems.value,
+ motherAnyProblem = getEnglishCheckboxValues(R.array.hbnc_mother_problems, motherProblems.value),
babyFirstFed = babyFedAfterBirth.getPosition(),
otherBabyFirstFed = otherBabyFedAfterBirth.value,
timeBabyFirstFed = whenBabyFirstFed.value,
@@ -462,7 +462,7 @@ class HBNCFormDataset(
babyWeight = babyWeight.value,
babyTemperature = babyTemperature.value,
babyYellow = yellowJaundice.getPosition(),
- babyImmunizationStatus = childImmunizationStatus.value,
+ babyImmunizationStatus = getEnglishCheckboxValues(R.array.hbnc_child_immunization_status, childImmunizationStatus.value),
babyReferred = babyReferred.getPosition(),
dateOfBabyReferral = getLongFromDate(dateOfBabyReferral.value),
placeOfBabyReferral = placeOfBabyReferral.getPosition(),
@@ -502,7 +502,7 @@ class HBNCFormDataset(
private val healthSubCenterName = FormElement(
id = 2,
inputType = InputType.EDIT_TEXT,
- title = "Health Subcenter Name ",
+ title = resources.getString(R.string.str_health_subcenter_name),
arrayId = -1,
// etMaxLength = 6,
required = false,
@@ -512,14 +512,14 @@ class HBNCFormDataset(
private val motherName = FormElement(
id = 4,
inputType = InputType.TEXT_VIEW,
- title = "Mother Name",
+ title = resources.getString(R.string.mother_name),
arrayId = -1,
required = false
)
private val fatherName = FormElement(
id = 5,
inputType = InputType.TEXT_VIEW,
- title = "Father Name",
+ title = resources.getString(R.string.tv_father_name_ph),
arrayId = -1,
required = false
)
@@ -527,7 +527,7 @@ class HBNCFormDataset(
private val dateOfDelivery = FormElement(
id = 6,
inputType = InputType.DATE_PICKER,
- title = "Date of Delivery",
+ title = resources.getString(R.string.str_date_of_delivery),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -537,48 +537,35 @@ class HBNCFormDataset(
private val placeOfDelivery = FormElement(
id = 7,
inputType = InputType.DROPDOWN,
- title = "Place of Delivery",
+ title = resources.getString(R.string.str_place_of_delivery),
arrayId = -1,
- entries = arrayOf(
- "House",
- "Health center",
- "CHC",
- "PHC",
- ),
+ entries = resources.getStringArray(R.array.hbnc_place_of_delivery_array),
required = false
)
private val gender = FormElement(
- id = 8, inputType = InputType.RADIO, title = "Baby Gender", arrayId = -1, entries = arrayOf(
- "Male",
- "Female",
- "Transgender",
- ), required = false
+ id = 8, inputType = InputType.RADIO, title = resources.getString(R.string.str_baby_gender), arrayId = -1, entries = resources.getStringArray(R.array.hbnc_baby_gender), required = false
)
private val typeOfDelivery = FormElement(
id = 9,
inputType = InputType.RADIO,
- title = "Type of Delivery",
+ title = resources.getString(R.string.str_type_of_delivery),
arrayId = -1,
- entries = arrayOf(
- "Normal Delivery", "C - Section", "Assisted"
- ),
+ entries = resources.getStringArray(R.array.hbnc_type_of_delivery),
required = false
)
private val startedBreastFeeding = FormElement(
id = 10,
inputType = InputType.DROPDOWN,
- title = "Started Breastfeeding",
+ title = resources.getString(R.string.str_started_breastfeeding),
arrayId = -1,
- entries = arrayOf(
- "Within an hour", "1 - 4 hours", "4.1 - 24 hours", "After 24 hours"
- ),
+ entries = resources.getStringArray(R.array.hbnc_started_breastfeeding),
required = false
)
private val weightAtBirth = FormElement(
id = 11,
inputType = InputType.EDIT_TEXT,
- title = "Weight at birth ( grams )",
+ title = resources.getString(R.string.str_weight_at_birth_gram),
arrayId = -1,
required = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL
@@ -586,7 +573,7 @@ class HBNCFormDataset(
private val dateOfDischargeFromHospitalMother = FormElement(
id = 12,
inputType = InputType.DATE_PICKER,
- title = "Discharge Date of Mother",
+ title = resources.getString(R.string.str_discharge_date_of_mother),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -595,7 +582,7 @@ class HBNCFormDataset(
private val dateOfDischargeFromHospitalBaby = FormElement(
id = 13,
inputType = InputType.DATE_PICKER,
- title = "Discharge Date of Baby",
+ title = resources.getString(R.string.str_discharge_date_of_baby),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -604,7 +591,7 @@ class HBNCFormDataset(
private val registrationOfBirth = FormElement(
id = 15,
inputType = InputType.RADIO,
- title = "Registration Of Birth",
+ title = resources.getString(R.string.str_registration_of_birth),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -616,27 +603,18 @@ class HBNCFormDataset(
private val childImmunizationStatus = FormElement(
id = 18,
inputType = InputType.CHECKBOXES,
- title = "Child Immunization Status",
+ title = resources.getString(R.string.str_child_immunizaation_status),
arrayId = -1,
- entries = arrayOf(
- "BCG", "Polio", "DPT 1", "Hepatitis-B"
- ),
+ entries = resources.getStringArray(R.array.hbnc_child_immunization_status),
required = false
)
private val babyFedAfterBirth = FormElement(
id = 26,
inputType = InputType.DROPDOWN,
- title = "What was the baby fed after birth ",
+ title =resources.getString(R.string.str_child_feed_after_birth),
arrayId = -1,
- entries = arrayOf(
- "Mother Milk",
- "Water",
- "Honey",
- "Mishri water",
- "Goat Milk",
- "Other",
- ),
+ entries =resources.getStringArray(R.array.hbnc_feeding_of_baby),
required = false,
hasDependants = true
)
@@ -644,30 +622,23 @@ class HBNCFormDataset(
private val howBabyTookFirstFeed = FormElement(
id = 27,
inputType = InputType.DROPDOWN,
- title = "How did the baby breastfeed? ",
+ title = resources.getString(R.string.str_how_did_the_baby_breastfeed),
arrayId = -1,
- entries = arrayOf(
- "Forcefully",
- "Weakly ",
- "Could not breastfeed but had to be fed with spoon",
- "Could neither breast-feed nor could take milk given by spoon",
- ),
+ entries = resources.getStringArray(R.array.hbnc_how_breastfeed_baby),
required = false
)
private val babyEyeCondition = FormElement(
id = 32,
inputType = InputType.RADIO,
- title = "Baby eye condition",
+ title =resources.getString(R.string.str_baby_eye_condition),
arrayId = -1,
- entries = arrayOf(
- "Normal ", "Swelling", "oozing pus"
- ),
+ entries = resources.getStringArray(R.array.hbnc_baby_eye_condition),
required = false
)
private val babyBleedUmbilicalCord = FormElement(
id = 33,
inputType = InputType.RADIO,
- title = "Is there bleeding from the baby umbilical cord ",
+ title = resources.getString(R.string.str_is_there_bleeding),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -678,25 +649,23 @@ class HBNCFormDataset(
private val babyWeightColor = FormElement(
id = 34,
inputType = InputType.RADIO,
- title = "Weighing machine scale color",
+ title = resources.getString(R.string.str_weighing_machine_scale_coloer),
arrayId = -1,
- entries = arrayOf(
- "Red", "Yellow", "Green"
- ),
+ entries = resources.getStringArray(R.array.hbnc_scale_color),
required = false
)
private val titleBabyPhysicalCondition = FormElement(
id = 35,
inputType = InputType.HEADLINE,
- title = "Enter the child physical condition",
+ title = resources.getString(R.string.str_child_physical_condition),
arrayId = -1,
required = false
)
private val allLimbsLimp = FormElement(
id = 36,
inputType = InputType.RADIO,
- title = "All limbs limp",
+ title = resources.getString(R.string.str_all_limbs_limp),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -704,7 +673,7 @@ class HBNCFormDataset(
private val feedingLessStop = FormElement(
id = 37,
inputType = InputType.RADIO,
- title = "Feeding less/stop",
+ title =resources.getString(R.string.str_feeding_less_stop),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -712,7 +681,7 @@ class HBNCFormDataset(
private val wrapClothKeptMother = FormElement(
id = 45,
inputType = InputType.RADIO,
- title = "The child is wrapped in cloth and kept to the mother",
+ title = resources.getString(R.string.str_the_child_is_wrapped_in_cloth),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -720,7 +689,7 @@ class HBNCFormDataset(
private val onlyBreastMilk = FormElement(
id = 46,
inputType = InputType.RADIO,
- title = "Started breastfeeding only/ only given breast milk",
+ title = resources.getString(R.string.str_started_breastfeeding_only),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -732,7 +701,7 @@ class HBNCFormDataset(
private val titleAskMotherA = FormElement(
id = 48,
inputType = InputType.HEADLINE,
- title = "Newborn first training (A) Ask mother",
+ title = resources.getString(R.string.str_newborn_first_training),
arrayId = -1,
required = false
)
@@ -740,7 +709,7 @@ class HBNCFormDataset(
private val timesMotherFed24hr = FormElement(
id = 49,
inputType = InputType.EDIT_TEXT,
- title = "How many times the mother feeds her stomach in 24 hours. Action – If the mother does not eat full stomach or eat less than 4 times, advise mother to do so",
+ title = resources.getString(R.string.str_baby_stomach_feeding),
arrayId = -1,
required = false,
hasAlertError = true,
@@ -752,7 +721,7 @@ class HBNCFormDataset(
private val timesPadChanged = FormElement(
id = 50,
inputType = InputType.EDIT_TEXT,
- title = "How many pads have been changed in a day for bleeding? Action – If more than 2 pad, refer the mother to the hospital.",
+ title = resources.getString(R.string.str_baby_pad_changed),
arrayId = -1,
required = false,
hasAlertError = true,
@@ -763,7 +732,7 @@ class HBNCFormDataset(
private val babyKeptWarmWinter = FormElement(
id = 51,
inputType = InputType.RADIO,
- title = "During the winter season, is the baby kept warm? (Closer to the mother, dressed well and wrapped). - If it is not being done, ask the mother to do it.",
+ title =resources.getString(R.string.str_baby_in_winter),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -772,7 +741,7 @@ class HBNCFormDataset(
private val babyBreastFedProperly = FormElement(
id = 52,
inputType = InputType.RADIO,
- title = "Is the child breastfed properly? (Whenever feeling hungry or breastfeeding at least 7 – 8 times in 24 hours). Action – if it is not being done then ask the mother to do it. ",
+ title = resources.getString(R.string.str_baby_breastfed_properly),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -780,7 +749,7 @@ class HBNCFormDataset(
private val babyCryContinuously = FormElement(
id = 53,
inputType = InputType.RADIO,
- title = "Does the child cry continuously or urinate less than 6 times a day? Action – Advice the mother for breast-feeding",
+ title = resources.getString(R.string.str_baby_urination_per_day),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -789,7 +758,7 @@ class HBNCFormDataset(
private val motherBodyTemperature = FormElement(
id = 55,
inputType = InputType.EDIT_TEXT,
- title = "Measure and check the temperature. Action – Give the patient paracetamol tablet if the temperature is 102°F (38.9°C) and refer to the hospital if the temperature is higher than this.",
+ title = resources.getString(R.string.str_mother_body_temperature),
arrayId = -1,
required = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
@@ -798,7 +767,7 @@ class HBNCFormDataset(
private val motherWaterDischarge = FormElement(
id = 56,
inputType = InputType.RADIO,
- title = "Water discharge with foul smell and fever 102 degree Fahrenheit (38.9 degree C). ",
+ title = resources.getString(R.string.str_water_discharge),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -806,7 +775,7 @@ class HBNCFormDataset(
private val motherSpeakAbnormalFits = FormElement(
id = 57,
inputType = InputType.RADIO,
- title = "Is mother speaking abnormally or having fits?",
+ title = resources.getString(R.string.str_is_mother_speaking_abnormally),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -814,7 +783,7 @@ class HBNCFormDataset(
private val motherNoOrLessMilk = FormElement(
id = 58,
inputType = InputType.RADIO,
- title = "Mothers milk is not being produced after delivery or she thinks less milk is being produced.",
+ title =resources.getString(R.string.str_mother_milk_is_not_produced),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -822,7 +791,7 @@ class HBNCFormDataset(
private val motherBreastProblem = FormElement(
id = 59,
inputType = InputType.RADIO,
- title = "Does the mother have cracked nipple / pain and / or hard breasts",
+ title = resources.getString(R.string.str_mother_cracked_nipple),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -831,7 +800,7 @@ class HBNCFormDataset(
private val babyEyesSwollen = FormElement(
id = 61,
inputType = InputType.RADIO,
- title = "Are the eyes swollen / Are there pus from the eyes?",
+ title = resources.getString(R.string.str_are_the_eyes_swollen),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -839,7 +808,7 @@ class HBNCFormDataset(
private val babyWeight = FormElement(
id = 62,
inputType = InputType.EDIT_TEXT,
- title = "Weight on Day ${if (nthDay > 0) nthDay else 1}",
+ title = "${resources.getString(R.string.str_weight_on_day)} ${if (nthDay > 0) nthDay else 1}",
arrayId = -1,
required = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL,
@@ -850,7 +819,7 @@ class HBNCFormDataset(
private val yellowJaundice = FormElement(
id = 66,
inputType = InputType.RADIO,
- title = "Yellowing of the eye/palm/sole/skin (jaundice)",
+ title = resources.getString(R.string.str_yellowing_of_eye),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false
@@ -860,7 +829,7 @@ class HBNCFormDataset(
private val breathFast = FormElement(
id = 68,
inputType = InputType.RADIO,
- title = "Respiratory rate more than 60 per minute",
+ title = resources.getString(R.string.str_respiratory_rate),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -869,8 +838,8 @@ class HBNCFormDataset(
private val titleSepsisD = FormElement(
id = 70,
inputType = InputType.HEADLINE,
- title = "(D) Sepsis",
- subtitle = "Examine the following symptoms of sepsis. If symptoms are present, then write, Yes, if symptoms are not present, then do not write. Enter the symptoms seen from the health check-up on the first day of the newborns birth.",
+ title =resources.getString(R.string.str_d_sepsis),
+ subtitle = resources.getString(R.string.str_symptoms_of_sepsis),
arrayId = -1,
required = false
)
@@ -878,7 +847,7 @@ class HBNCFormDataset(
private val bloatedStomach = FormElement(
id = 74,
inputType = InputType.RADIO,
- title = "Distended abdomen or mother says baby vomits often",
+ title = resources.getString(R.string.str_distended_abdomen),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -889,7 +858,7 @@ class HBNCFormDataset(
private val childColdOnTouch = FormElement(
id = 75,
inputType = InputType.RADIO,
- title = "The mother tells that the child feels cold when touching or the temperature of the child is more than 89 degrees Fahrenheit (37.5 degrees C)",
+ title = resources.getString(R.string.str_child_feels_cold),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -901,7 +870,7 @@ class HBNCFormDataset(
private val childChestDrawing = FormElement(
id = 76,
inputType = InputType.RADIO,
- title = "and the chest is pulled inward while breathing.",
+ title = resources.getString(R.string.str_chest_is_pulled),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -914,35 +883,35 @@ class HBNCFormDataset(
private val pusNavel = FormElement(
id = 77,
inputType = InputType.EDIT_TEXT,
- title = "Pus in the navel",
+ title = resources.getString(R.string.str_pus_in_the_navel),
arrayId = -1,
required = false
)
private val ashaName = FormElement(
id = 78,
inputType = InputType.TEXT_VIEW,
- title = "ASHA NAME",
+ title = resources.getString(R.string.str_asha_name),
arrayId = -1,
required = false
)
private val villageName = FormElement(
id = 79,
inputType = InputType.TEXT_VIEW,
- title = "Village Name",
+ title = resources.getString(R.string.str_village_name),
arrayId = -1,
required = false
)
private val blockName = FormElement(
id = 80,
inputType = InputType.TEXT_VIEW,
- title = "Block Name",
+ title = resources.getString(R.string.str_block_name),
arrayId = -1,
required = false
)
private val stillBirth = FormElement(
id = 81,
inputType = InputType.RADIO,
- title = "Still Birth",
+ title = resources.getString(R.string.str_still_birth),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -953,7 +922,7 @@ class HBNCFormDataset(
private val supRemark = FormElement(
id = 82,
inputType = InputType.EDIT_TEXT,
- title = "Supervisors Remark ",
+ title = resources.getString(R.string.str_supervisors_remark),
arrayId = -1,
required = false,
etMaxLength = 500,
@@ -962,19 +931,15 @@ class HBNCFormDataset(
private val sup = FormElement(
id = 83,
inputType = InputType.DROPDOWN,
- title = "Supervisor",
+ title = resources.getString(R.string.str_supervisor),
arrayId = -1,
- entries = arrayOf(
- "ASHA Facilitator",
- "ANM",
- "MPW",
- ),
+ entries = resources.getStringArray(R.array.hbnc_supervisor),
required = false
)
private val supName = FormElement(
id = 84,
inputType = InputType.EDIT_TEXT,
- title = "Supervisor name",
+ title = resources.getString(R.string.str_supervisor_name),
arrayId = -1,
required = false,
allCaps = true,
@@ -983,7 +948,7 @@ class HBNCFormDataset(
private val dateOfSupSig = FormElement(
id = 86,
inputType = InputType.DATE_PICKER,
- title = "Signature with Date of Supervisor",
+ title = resources.getString(R.string.str_signature_with_date),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -993,14 +958,14 @@ class HBNCFormDataset(
private val titleVisitCard = FormElement(
id = 87,
inputType = InputType.HEADLINE,
- title = "Mother-Newborn Home Visit Card",
+ title = resources.getString(R.string.str_mother_newborn_home_visit_card),
arrayId = -1,
required = false
)
private val titleVisitCardDischarge = FormElement(
id = 88,
inputType = InputType.HEADLINE,
- title = "Discharge of Institutional Delivery",
+ title = resources.getString(R.string.str_discharge_of_institutinal_delivery),
arrayId = -1,
required = false
)
@@ -1008,14 +973,14 @@ class HBNCFormDataset(
private val dateOfHomeVisit = FormElement(
id = 89,
inputType = InputType.TEXT_VIEW,
- title = "Date of Home Visit",
+ title = resources.getString(R.string.str_date_of_home_visit),
arrayId = -1,
required = false
)
private val babyAlive = FormElement(
id = 90,
inputType = InputType.RADIO,
- title = "Is the baby alive?",
+ title = resources.getString(R.string.str_baby_alive),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1027,7 +992,7 @@ class HBNCFormDataset(
private val dateOfBabyDeath = FormElement(
id = 91,
inputType = InputType.DATE_PICKER,
- title = "Date of death of baby",
+ title = resources.getString(R.string.str_date_of_death_of_baby),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -1036,36 +1001,30 @@ class HBNCFormDataset(
private val timeOfBabyDeath = FormElement(
id = 92,
inputType = InputType.TIME_PICKER,
- title = "Time of death of baby",
+ title = resources.getString(R.string.str_time_of_death),
arrayId = -1,
required = false
)
private val placeOfBabyDeath = FormElement(
id = 93,
inputType = InputType.DROPDOWN,
- title = "Place of Baby Death",
+ title = resources.getString(R.string.str_place_of_baby_death),
arrayId = -1,
- entries = arrayOf(
- "Home",
- "Sub-center",
- "PHC",
- "CHC",
- "Other",
- ),
+ entries = resources.getStringArray(R.array.hbnc_place_of_baby_death),
required = false,
hasDependants = true,
)
private val otherPlaceOfBabyDeath = FormElement(
id = 94,
inputType = InputType.EDIT_TEXT,
- title = "Other place of Baby Death",
+ title = resources.getString(R.string.str_other_place_of_baby_death),
arrayId = -1,
required = false
)
private val babyPreterm = FormElement(
id = 95,
inputType = InputType.RADIO,
- title = "Is the baby preterm?",
+ title =resources.getString(R.string.str_is_baby_preterm),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1078,21 +1037,17 @@ class HBNCFormDataset(
private val gestationalAge = FormElement(
id = 96,
inputType = InputType.RADIO,
- title = "How many weeks has it been since baby born (Gestational Age)",
+ title = resources.getString(R.string.str_how_many_weeks),
// orientation = LinearLayout.VERTICAL,
arrayId = -1,
- entries = arrayOf(
- "24 – 34 Weeks",
- "34 – 36 Weeks",
- "36 – 38 Weeks",
- ),
+ entries = resources.getStringArray(R.array.hbnc_gestational_age),
required = true,
hasAlertError = true,
)
private val dateOfBabyFirstExamination = FormElement(
id = 97,
inputType = InputType.DATE_PICKER,
- title = "Date of First examination of baby",
+ title = resources.getString(R.string.str_date_of_first_examination),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -1101,7 +1056,7 @@ class HBNCFormDataset(
private val timeOfBabyFirstExamination = FormElement(
id = 98,
inputType = InputType.TIME_PICKER,
- title = "Time of First examination of baby",
+ title = resources.getString(R.string.str_time_of_first_examination),
arrayId = -1,
required = false
)
@@ -1110,7 +1065,7 @@ class HBNCFormDataset(
private val motherAlive = FormElement(
id = 99,
inputType = InputType.RADIO,
- title = "Is the mother alive?",
+ title = resources.getString(R.string.str_is_the_mother_alive),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1122,7 +1077,7 @@ class HBNCFormDataset(
private val dateOfMotherDeath = FormElement(
id = 100,
inputType = InputType.DATE_PICKER,
- title = "Date of death of mother",
+ title = resources.getString(R.string.str_date_of_death_of_mother),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -1131,29 +1086,23 @@ class HBNCFormDataset(
private val timeOfMotherDeath = FormElement(
id = 101,
inputType = InputType.TIME_PICKER,
- title = "Time of death of mother",
+ title = resources.getString(R.string.str_time_of_death_of_mother),
arrayId = -1,
required = false
)
private val placeOfMotherDeath = FormElement(
id = 102,
inputType = InputType.DROPDOWN,
- title = "Place of mother Death",
+ title = resources.getString(R.string.str_place_of_mother_death),
arrayId = -1,
- entries = arrayOf(
- "Home",
- "Sub-center",
- "PHC",
- "CHC",
- "Other",
- ),
+ entries = resources.getStringArray(R.array.hbnc_place_of_mother_death),
required = false,
hasDependants = true,
)
private val otherPlaceOfMotherDeath = FormElement(
id = 103,
inputType = InputType.EDIT_TEXT,
- title = "Other place of mother Death",
+ title = resources.getString(R.string.str_other_place_of_mother_death),
arrayId = -1,
required = false,
hasDependants = true
@@ -1161,12 +1110,9 @@ class HBNCFormDataset(
private val motherProblems = FormElement(
id = 104,
inputType = InputType.CHECKBOXES,
- title = "Does Mother have any problems",
+ title = resources.getString(R.string.str_does_mother_have_any_problem),
arrayId = -1,
- entries = arrayOf(
- "Excessive Bleeding",
- "Unconscious / Fits",
- ),
+ entries = resources.getStringArray(R.array.hbnc_mother_problems),
required = false,
hasAlertError = true
)
@@ -1174,21 +1120,21 @@ class HBNCFormDataset(
private val otherBabyFedAfterBirth = FormElement(
id = 105,
inputType = InputType.EDIT_TEXT,
- title = "Other - What was given as the first feed to baby after birth?",
+ title = resources.getString(R.string.str_first_feed_to_baby),
arrayId = -1,
required = false
)
private val whenBabyFirstFed = FormElement(
id = 106,
inputType = InputType.TIME_PICKER,
- title = "When was the baby first fed",
+ title = resources.getString(R.string.str_when_first_feed_to_baby),
arrayId = -1,
required = false
)
private val motherHasBreastFeedProblem = FormElement(
id = 107,
inputType = InputType.RADIO,
- title = "Does the mother have breastfeeding problem?",
+ title = resources.getString(R.string.str_does_the_mother_have_breatfeeding),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -1197,7 +1143,7 @@ class HBNCFormDataset(
private val motherBreastFeedProblem = FormElement(
id = 108,
inputType = InputType.EDIT_TEXT,
- title = "Write the problem, if there is any problem in breast feeding, help the mother to overcome it",
+ title = resources.getString(R.string.str_write_the_problem),
arrayId = -1,
required = false
)
@@ -1207,14 +1153,14 @@ class HBNCFormDataset(
private val titleBabyFirstHealthCheckup = FormElement(
id = 109,
inputType = InputType.HEADLINE,
- title = "Part 2: Baby first health check-up",
+ title =resources.getString(R.string.str_baby_first_health_checkup),
arrayId = -1,
required = false
)
private val babyTemperature = FormElement(
id = 110,
inputType = InputType.EDIT_TEXT,
- title = "Temperature of the baby",
+ title = resources.getString(R.string.str_temperature_ot_the_baby),
arrayId = -1,
required = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
@@ -1224,7 +1170,7 @@ class HBNCFormDataset(
private val actionUmbilicalBleed = FormElement(
id = 111,
inputType = InputType.RADIO,
- title = "If yes, either ASHA, ANM/MPW or TBA can tie again with a clean thread. Action taken? ",
+ title = resources.getString(R.string.str_tie_again_with_clean_thread),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1235,7 +1181,7 @@ class HBNCFormDataset(
private val babyWeigntMatchesColor = FormElement(
id = 112,
inputType = InputType.RADIO,
- title = "Weighing matches with the colour?",
+ title = resources.getString(R.string.str_weighing_matches),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1246,14 +1192,14 @@ class HBNCFormDataset(
private val titleRoutineNewBornCare = FormElement(
id = 113,
inputType = InputType.HEADLINE,
- title = "Routine Newborn Care: whether the task was performed",
+ title = resources.getString(R.string.str_routine_newborn_care),
arrayId = -1,
required = false
)
private val babyDry = FormElement(
id = 114,
inputType = InputType.RADIO,
- title = "Dry the baby",
+ title =resources.getString(R.string.str_dry_the_baby),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1264,7 +1210,7 @@ class HBNCFormDataset(
private val cryWeakStopped = FormElement(
id = 115,
inputType = InputType.RADIO,
- title = "Cry weak/ stopped",
+ title = resources.getString(R.string.str_cry_weak_stopped),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1275,7 +1221,7 @@ class HBNCFormDataset(
private val cordCleanDry = FormElement(
id = 116,
inputType = InputType.RADIO,
- title = "Keep the cord clean and dry",
+ title = resources.getString(R.string.str_keep_the_cord_clean_and_dry),
arrayId = -1,
entries = arrayOf(
"Yes",
@@ -1287,16 +1233,16 @@ class HBNCFormDataset(
private val unusualWithBaby = FormElement(
id = 117,
inputType = InputType.RADIO,
- title = "Was there anything unusual with the baby?",
+ title = resources.getString(R.string.str_was_there_anything_unusual),
arrayId = -1,
- entries = arrayOf("Curved limbs", "cleft lip", "Other"),
+ entries = resources.getStringArray(R.array.hbnc_unusual_with_the_baby),
required = false,
hasDependants = true,
)
private val otherUnusualWithBaby = FormElement(
id = 118,
inputType = InputType.EDIT_TEXT,
- title = "Other - unusual with the baby",
+ title = resources.getString(R.string.str_other_unusual_with_the_baby),
arrayId = -1,
required = false
)
@@ -1306,14 +1252,14 @@ class HBNCFormDataset(
private val titleWashHands = FormElement(
id = 119,
inputType = InputType.HEADLINE,
- title = "ASHA should wash hands with soap and water before touching the baby during each visit",
+ title = resources.getString(R.string.str_asha_hygeine),
arrayId = -1,
required = false
)
private val babyReferred = FormElement(
id = 120,
inputType = InputType.RADIO,
- title = "Baby referred for any reason?",
+ title = resources.getString(R.string.str_baby_referred_for_any_reason),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -1322,7 +1268,7 @@ class HBNCFormDataset(
private val dateOfBabyReferral = FormElement(
id = 121,
inputType = InputType.DATE_PICKER,
- title = "Date of baby referral",
+ title = resources.getString(R.string.str_date_of_baby_referral),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -1331,34 +1277,23 @@ class HBNCFormDataset(
private val placeOfBabyReferral = FormElement(
id = 122,
inputType = InputType.DROPDOWN,
- title = "Place of baby referral",
+ title = resources.getString(R.string.str_place_of_baby_referral),
arrayId = -1,
- entries = arrayOf(
- "Sub-Centre",
- "PHC",
- "CHC",
- "Sub-District Hospital",
- "District Hospital",
- "Medical College Hospital",
- "In Transit",
- "Private Hospital",
- "Accredited Private Hospital",
- "Other",
- ),
+ entries = resources.getStringArray(R.array.hbnc_place_of_baby_referral),
required = false,
hasDependants = true
)
private val otherPlaceOfBabyReferral = FormElement(
id = 123,
inputType = InputType.EDIT_TEXT,
- title = "Other -Place of baby referral",
+ title = resources.getString(R.string.str_other_place_of_baby_referral),
arrayId = -1,
required = false
)
private val motherReferred = FormElement(
id = 124,
inputType = InputType.RADIO,
- title = "Mother referred for any reason?",
+ title = resources.getString(R.string.str_mother_referred_for_any_reason),
arrayId = -1,
entries = arrayOf("Yes", "No"),
required = false,
@@ -1367,7 +1302,7 @@ class HBNCFormDataset(
private val dateOfMotherReferral = FormElement(
id = 125,
inputType = InputType.DATE_PICKER,
- title = "Date of mother referral",
+ title = resources.getString(R.string.str_date_of_mother_referral),
arrayId = -1,
required = false,
max = System.currentTimeMillis(),
@@ -1376,27 +1311,16 @@ class HBNCFormDataset(
private val placeOfMotherReferral = FormElement(
id = 126,
inputType = InputType.DROPDOWN,
- title = "Place of mother referral",
+ title = resources.getString(R.string.str_place_of_mother_referral),
arrayId = -1,
- entries = arrayOf(
- "Sub-Centre",
- "PHC",
- "CHC",
- "Sub-District Hospital",
- "District Hospital",
- "Medical College Hospital",
- "In Transit",
- "Private Hospital",
- "Accredited Private Hospital",
- "Other",
- ),
+ entries = resources.getStringArray(R.array.hbnc_place_of_mother_referral),
required = false,
hasDependants = true
)
private val otherPlaceOfMotherReferral = FormElement(
id = 127,
inputType = InputType.EDIT_TEXT,
- title = "Other -Place of mother referral",
+ title = resources.getString(R.string.str_other_place_of_mother_referral),
arrayId = -1,
required = false
)
@@ -1491,7 +1415,7 @@ class HBNCFormDataset(
dateOfBabyFirstExamination.value = getDateFromLong(it.dateOfFirstExamination)
timeOfBabyFirstExamination.value = it.timeOfFirstExamination
motherAlive.value = motherAlive.getStringFromPosition(it.motherAlive)
- motherProblems.value = it.motherAnyProblem
+ motherProblems.value = getCheckboxIndexesFromValues(R.array.hbnc_mother_problems, it.motherAnyProblem)
babyFedAfterBirth.value = babyFedAfterBirth.getStringFromPosition(it.babyFirstFed)
otherBabyFedAfterBirth.value = it.otherBabyFirstFed
whenBabyFirstFed.value = it.timeBabyFirstFed
@@ -1684,7 +1608,7 @@ class HBNCFormDataset(
babyWeight.value = it.babyWeight
babyTemperature.value = it.babyTemperature
yellowJaundice.value = yellowJaundice.getStringFromPosition(it.babyYellow)
- childImmunizationStatus.value = it.babyImmunizationStatus
+ childImmunizationStatus.value = getCheckboxIndexesFromValues(R.array.hbnc_child_immunization_status, it.babyImmunizationStatus)
babyReferred.value = babyReferred.getStringFromPosition(it.babyReferred)
motherReferred.value = motherReferred.getStringFromPosition(it.motherReferred)
allLimbsLimp.value = allLimbsLimp.getStringFromPosition(it.allLimbsLimp)
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBYCFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBYCFormDataset.kt
index 8b358cbf3..9ab05bfc3 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBYCFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HBYCFormDataset.kt
@@ -9,6 +9,7 @@ import org.piramalswasthya.sakhi.model.HBYCCache
import org.piramalswasthya.sakhi.model.InputType
import org.piramalswasthya.sakhi.model.getDateStrFromLong
import java.text.SimpleDateFormat
+import java.util.Calendar
import java.util.Locale
class HBYCFormDataset(
@@ -26,47 +27,47 @@ class HBYCFormDataset(
private val month = FormElement(
id = 1,
inputType = InputType.EDIT_TEXT,
- title = "Month",
+ title = resources.getString(R.string.month),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
required = false
)
private val subCenterName = FormElement(
id = 2,
inputType = InputType.EDIT_TEXT,
- title = "Subcenter name ",
+ title = resources.getString(R.string.str_sub_center),
required = false
)
private val year = FormElement(
id = 3,
inputType = InputType.EDIT_TEXT,
- title = "Year",
+ title = resources.getString(R.string.mdsr_year),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
required = false
)
private val primaryHealthCenterName = FormElement(
id = 4,
inputType = InputType.EDIT_TEXT,
- title = "Primary Health Center Name ",
+ title = resources.getString(R.string.str_primary_health_center_name),
required = false
)
private val villagePopulation = FormElement(
id = 5,
inputType = InputType.EDIT_TEXT,
- title = "Village Population",
+ title = resources.getString(R.string.str_village_population),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
required = false
)
private val infantPopulation = FormElement(
id = 6,
inputType = InputType.EDIT_TEXT,
- title = "Total number of children aged 3 to 15 months in villages",
+ title = resources.getString(R.string.str_total_no_of_childrens),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
required = false
)
private val visitDate = FormElement(
id = 7,
inputType = InputType.DATE_PICKER,
- title = "Visit Date",
+ title = resources.getString(R.string.str_visit),
required = false,
min = 0L,
max = System.currentTimeMillis()
@@ -74,155 +75,141 @@ class HBYCFormDataset(
private val hbycAgeCategory = FormElement(
id = 8,
inputType = InputType.DROPDOWN,
- title = "H.B.Y.C by age Tour",
+ title = resources.getString(R.string.str_hyyc_by_age_tour),
required = false,
entries = arrayOf("3", "6", "9", "12", "15")
)
private val orsPacketDelivered = FormElement(
id = 9,
inputType = InputType.RADIO,
- title = "O.R.S. Packet delivered ",
+ title = resources.getString(R.string.str_ors_packet_delivered),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val ironFolicAcidGiven = FormElement(
id = 10,
inputType = InputType.RADIO,
- title = "Iron folic acid syrup given (after six months of childbirth)",
+ title = resources.getString(R.string.str_Iron_folic_acid),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val isVaccinatedByAge = FormElement(
id = 11,
inputType = InputType.RADIO,
- title = "Child vaccinated by age",
+ title = resources.getString(R.string.str_child_vaccinated_by_age),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val wasIll = FormElement(
id = 12,
inputType = InputType.RADIO,
- title = "The child was ill",
+ title =resources.getString(R.string.str_child_was_ill),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val referred = FormElement(
id = 13,
inputType = InputType.RADIO,
- title = "If yes refer hospital",
+ title = resources.getString(R.string.str_if_yes_refer_hospital),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val supplementsGiven = FormElement(
id = 14,
inputType = InputType.RADIO,
- title = "Supplements given to the child according to age",
+ title = resources.getString(R.string.str_suppliments_given_to_child),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val byHeightLength = FormElement(
id = 15,
inputType = InputType.RADIO,
- title = "By height / length (color inscribed in mcp card)",
+ title = resources.getString(R.string.str_by_height_length),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val childrenWeighingLessReferred = FormElement(
id = 16,
inputType = InputType.RADIO,
- title = "Number of children weighing less than –3SD orange color indicated in MCCP card referred to VHSND/PHC/NRC",
+ title = resources.getString(R.string.str_no_of_children_weighing_less),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val weightAccordingToAge = FormElement(
id = 17,
inputType = InputType.RADIO,
- title = "Weight according to child’s age (color inscribed in MCP card)",
+ title = resources.getString(R.string.str_weight_acc_to_child),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val delayInDevelopment = FormElement(
id = 18,
inputType = InputType.RADIO,
- title = "Delay / constraint found in the physical and mental development of the child according to age",
+ title = resources.getString(R.string.str_delay_constraint_found),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val referredToHealthInstitite = FormElement(
id = 19,
inputType = InputType.RADIO,
- title = "If yes then Health Institute R.B.S.K. Team / A.N.M. referred to",
+ title = resources.getString(R.string.str_if_yes_then_health_institute),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val vitaminASupplementsGiven = FormElement(
id = 20,
inputType = InputType.RADIO,
- title = "Vitamin – A supplements given to the child according to age",
+ title = resources.getString(R.string.str_vit_a_suppliment),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val deathAge = FormElement(
id = 21,
inputType = InputType.DROPDOWN,
- title = "Mark age (in month) at the time of death",
+ title = resources.getString(R.string.str_mark_age),
required = false,
- entries = arrayOf(
- "3 Month",
- "4 Month",
- "5 Month",
- "6 Month",
- "7 Month",
- "8 Month",
- "9 Month",
- "10 Month",
- "11 Month",
- "12 Month",
- "13 Month",
- "14 Month",
- "15 Month",
- )
+ entries = resources.getStringArray(R.array.hbyc_month_array)
)
private val deathCause = FormElement(
id = 22,
inputType = InputType.EDIT_TEXT,
- title = "Cause of death",
+ title = resources.getString(R.string.mdsr_cause),
required = false
)
private val qmOrAnmInformed = FormElement(
id = 23,
inputType = InputType.RADIO,
- title = "Q.M/A.N.M was informed",
+ title = resources.getString(R.string.str_qm_informed),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val deathPlace = FormElement(
id = 24,
inputType = InputType.DROPDOWN,
- title = "Place of death",
+ title = resources.getString(R.string.str_place_of_death),
required = false,
- entries = arrayOf("Home", "Health Center", "On the Way")
+ entries = resources.getStringArray(R.array.do_cause_of_death_array)
)
private val superVisorOn = FormElement(
id = 25,
inputType = InputType.RADIO,
- title = "Supervisor from block/district/state level in last on",
+ title =resources.getString(R.string.str_supervisor_from_block),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val orsShortage = FormElement(
id = 26,
inputType = InputType.RADIO,
- title = "ORS in last one month Packet shortage",
+ title = resources.getString(R.string.str_ors_in_last_one_month),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
private val ifaDecreased = FormElement(
id = 27,
inputType = InputType.RADIO,
- title = "IFA in last one month Decreased syrup",
+ title = resources.getString(R.string.str_ifa_last_month),
required = false,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no_options)
)
val firstPage by lazy {
@@ -290,6 +277,18 @@ class HBYCFormDataset(
month.value = monthVal
+ ben?.let { benReg ->
+ val monthInt = monthVal.toIntOrNull() ?: 0
+ if (monthInt > 0 && benReg.dob > 0) {
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = benReg.dob
+ cal.add(Calendar.MONTH, monthInt)
+ visitDate.min = cal.timeInMillis
+ } else if (benReg.dob > 0) {
+ visitDate.min = benReg.dob
+ }
+ }
+
saved?.let { hbycCache ->
month.value = hbycCache.month
subCenterName.value = hbycCache.subcenterName
@@ -300,43 +299,43 @@ class HBYCFormDataset(
visitDate.value = getDateStrFromLong(hbycCache.visitdate)
hbycAgeCategory.value = hbycCache.hbycAgeCategory
orsPacketDelivered.value =
- if (hbycCache.orsPacketDelivered == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.orsPacketDelivered - 1]
+ if (hbycCache.orsPacketDelivered == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.orsPacketDelivered - 1]
ironFolicAcidGiven.value =
- if (hbycCache.ironFolicAcidGiven == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.ironFolicAcidGiven - 1]
+ if (hbycCache.ironFolicAcidGiven == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.ironFolicAcidGiven - 1]
isVaccinatedByAge.value =
- if (hbycCache.isVaccinatedByAge == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.isVaccinatedByAge - 1]
+ if (hbycCache.isVaccinatedByAge == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.isVaccinatedByAge - 1]
wasIll.value =
- if (hbycCache.wasIll == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.wasIll - 1]
+ if (hbycCache.wasIll == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.wasIll - 1]
referred.value =
- if (hbycCache.referred == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.referred - 1]
+ if (hbycCache.referred == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.referred - 1]
supplementsGiven.value =
- if (hbycCache.supplementsGiven == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.supplementsGiven - 1]
+ if (hbycCache.supplementsGiven == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.supplementsGiven - 1]
byHeightLength.value =
- if (hbycCache.byHeightLength == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.byHeightLength - 1]
+ if (hbycCache.byHeightLength == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.byHeightLength - 1]
childrenWeighingLessReferred.value =
if (hbycCache.childrenWeighingLessReferred == 0) null else resources.getStringArray(
R.array.yes_no
)[hbycCache.childrenWeighingLessReferred - 1]
weightAccordingToAge.value =
- if (hbycCache.weightAccordingToAge == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.weightAccordingToAge - 1]
+ if (hbycCache.weightAccordingToAge == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.weightAccordingToAge - 1]
delayInDevelopment.value =
- if (hbycCache.delayInDevelopment == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.delayInDevelopment - 1]
+ if (hbycCache.delayInDevelopment == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.delayInDevelopment - 1]
referredToHealthInstitite.value =
- if (hbycCache.referredToHealthInstitite == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.referredToHealthInstitite - 1]
+ if (hbycCache.referredToHealthInstitite == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.referredToHealthInstitite - 1]
vitaminASupplementsGiven.value =
- if (hbycCache.vitaminASupplementsGiven == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.vitaminASupplementsGiven - 1]
+ if (hbycCache.vitaminASupplementsGiven == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.vitaminASupplementsGiven - 1]
deathAge.value = hbycCache.deathAge
deathCause.value = hbycCache.deathCause
qmOrAnmInformed.value =
- if (hbycCache.qmOrAnmInformed == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.qmOrAnmInformed - 1]
+ if (hbycCache.qmOrAnmInformed == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.qmOrAnmInformed - 1]
deathPlace.value =
if (hbycCache.deathPlace != null) resources.getStringArray(R.array.do_cause_of_death_array)[hbycCache.deathPlace!!] else null
superVisorOn.value =
- if (hbycCache.superVisorOn == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.superVisorOn - 1]
+ if (hbycCache.superVisorOn == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.superVisorOn - 1]
orsShortage.value =
- if (hbycCache.orsShortage == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.orsShortage - 1]
+ if (hbycCache.orsShortage == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.orsShortage - 1]
ifaDecreased.value =
- if (hbycCache.ifaDecreased == 0) null else resources.getStringArray(R.array.yes_no)[hbycCache.ifaDecreased - 1]
+ if (hbycCache.ifaDecreased == 0) null else resources.getStringArray(R.array.yes_no_options)[hbycCache.ifaDecreased - 1]
}
setUpPage(list)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPMicroBirthPlanDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPMicroBirthPlanDataset.kt
index 70a6c18e6..08c944f3b 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPMicroBirthPlanDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPMicroBirthPlanDataset.kt
@@ -7,6 +7,7 @@ import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.HRPMicroBirthPlanCache
import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
class HRPMicroBirthPlanDataset(
context: Context, currentLanguage: Languages
@@ -15,7 +16,6 @@ class HRPMicroBirthPlanDataset(
id = 1,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.name_of_the_pw),
- arrayId = -1,
required = true,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -24,8 +24,7 @@ class HRPMicroBirthPlanDataset(
id = 2,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.nearest_sc_hwc),
- arrayId = -1,
- required = true,
+ required = false,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -40,10 +39,10 @@ class HRPMicroBirthPlanDataset(
private val contactNumber1 = FormElement(
id = 4,
- inputType = InputType.EDIT_TEXT,
+ inputType = InputType.TEXT_VIEW,
title = resources.getString(R.string.contact_number_1),
- arrayId = -1,
required = true,
+ isEnabled = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
isMobileNumber = true,
etMaxLength = 10,
@@ -55,8 +54,7 @@ class HRPMicroBirthPlanDataset(
id = 5,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.contact_number_2),
- arrayId = -1,
- required = true,
+ required = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
isMobileNumber = true,
etMaxLength = 10,
@@ -67,38 +65,25 @@ class HRPMicroBirthPlanDataset(
id = 6,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.sc_hwc_tg_hosp),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 100,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
private val block = FormElement(
id = 7,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.block),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 100,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
- private val bankac = FormElement(
- id = 8,
- inputType = InputType.EDIT_TEXT,
- title = resources.getString(R.string.bank_acc_no),
- arrayId = -1,
- required = true,
- etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
- isMobileNumber = true,
- etMaxLength = 12,
- max = 999999999999,
- min = 100000000000
- )
-
private val nearestPhc = FormElement(
id = 9,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.nearest_24x7_phc),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 100,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -106,8 +91,8 @@ class HRPMicroBirthPlanDataset(
id = 10,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.nearest_fru),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 100,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -115,8 +100,8 @@ class HRPMicroBirthPlanDataset(
id = 11,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.blood_donors_identified_1),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 50,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -124,8 +109,8 @@ class HRPMicroBirthPlanDataset(
id = 12,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.blood_donors_identified_2),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 50,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -133,8 +118,8 @@ class HRPMicroBirthPlanDataset(
id = 13,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.birth_companion),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 50,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -142,8 +127,9 @@ class HRPMicroBirthPlanDataset(
id = 14,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.person_who_will_take_care_of_children_if_any_when_the_pw_is_admitted_for_delivery),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 50,
+
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -151,8 +137,8 @@ class HRPMicroBirthPlanDataset(
id = 15,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.name_of_vhsnd_community_member_for_support_during_emergency),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 100,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -160,8 +146,7 @@ class HRPMicroBirthPlanDataset(
id = 16,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.contact_number_of_vhsnd_community_member_for_support_during_emergency),
- arrayId = -1,
- required = true,
+ required = false,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
isMobileNumber = true,
etMaxLength = 10,
@@ -172,16 +157,16 @@ class HRPMicroBirthPlanDataset(
id = 17,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.mode_of_transportation_in_case_of_labour_pain),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 20,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
private val usg = FormElement(
id = 18,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.nearest_usg_centre),
- arrayId = -1,
- required = true,
+ required = false,
+ etMaxLength = 100,
etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
)
@@ -189,10 +174,18 @@ class HRPMicroBirthPlanDataset(
id = 19,
inputType = InputType.HEADLINE,
title = resources.getString(R.string.micro_birth_plan_for_all_pregnant_women),
- arrayId = -1,
required = false
)
+ private val husbandName = FormElement(
+ id = 20,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.husband_s_name),
+ required = true,
+ isEnabled = false,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
suspend fun setUpPage(ben: BenRegCache?, saved: HRPMicroBirthPlanCache?) {
val list = mutableListOf(
mbp_label,
@@ -203,27 +196,29 @@ class HRPMicroBirthPlanDataset(
scHosp,
usg,
block,
- bankac,
+ husbandName,
nearestPhc,
nearestFru,
bloodDonors1,
bloodDonors2,
birthCompanion,
-// careTaker,
-// communityMember,
-// communityMemberContact,
+ careTaker,
+ communityMember,
+ communityMemberContact,
modeOfTransportation
)
+
+ contactNumber1.value=ben?.contactNumber.toString()
+ husbandName.value= ben?.genDetails?.spouseName.toString()
saved?.let {
nearestSc.value = it.nearestSc
bloodGroup.value =
getLocalValueInArray(R.array.maternal_health_blood_group, it.bloodGroup)
- contactNumber1.value = it.contactNumber1
+ contactNumber1.value = ben?.contactNumber?.toString()
contactNumber2.value = it.contactNumber2
scHosp.value = it.scHosp
block.value = it.block
- bankac.value = it.bankac
nearestPhc.value = it.nearestPhc
nearestFru.value = it.nearestFru
bloodDonors1.value = it.bloodDonors1
@@ -266,10 +261,6 @@ class HRPMicroBirthPlanDataset(
validateAllAlphaNumericSpaceOnEditText(block)
}
- bankac.id -> {
- validateIntMinMax(bankac)
- }
-
nearestPhc.id -> {
validateAllAlphaNumericSpaceOnEditText(nearestPhc)
}
@@ -302,9 +293,6 @@ class HRPMicroBirthPlanDataset(
validateMobileNumberOnEditText(communityMemberContact)
}
- modeOfTransportation.id -> {
- validateAllAlphabetsSpaceOnEditText(modeOfTransportation)
- }
else -> {
-1
@@ -321,7 +309,6 @@ class HRPMicroBirthPlanDataset(
form.contactNumber2 = contactNumber2.value
form.scHosp = scHosp.value
form.block = block.value
- form.bankac = bankac.value
form.nearestPhc = nearestPhc.value
form.nearestFru = nearestFru.value
form.bloodDonors1 = bloodDonors1.value
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPNonPregnantTrackDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPNonPregnantTrackDataset.kt
index 581a1ce6e..48348b5a1 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPNonPregnantTrackDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPNonPregnantTrackDataset.kt
@@ -143,9 +143,11 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.systolic),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
- etMaxLength = 3
+ etMaxLength = 3,
+ min = 50,
+ max = 300
)
private val diastolic = FormElement(
@@ -153,9 +155,11 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.diastolic),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
- etMaxLength = 4
+ etMaxLength = 3,
+ min = 30,
+ max = 200
)
private val bloodGlucoseTest = FormElement(
@@ -163,7 +167,7 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.RADIO,
title = resources.getString(R.string.blood_glucose_test),
entries = resources.getStringArray(R.array.sugar_test_types),
- required = false,
+ required = true,
hasDependants = true
)
@@ -172,7 +176,7 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.random_blood_glucose),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -182,7 +186,7 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.fasting_glucose_test),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -192,7 +196,7 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.post_prandial_glucose_test),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -202,9 +206,11 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.hemoglobin_test),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL,
- etMaxLength = 4
+ etMaxLength = 4,
+ minDecimal = 2.0,
+ maxDecimal = 15.0
)
private val ifaGiven = FormElement(
@@ -221,7 +227,7 @@ class HRPNonPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.issued_quantity_ifa),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -418,10 +424,49 @@ class HRPNonPregnantTrackDataset(
1
}
+ systolic.id->{
+ validateIntMinMax(systolic)
+ 1
+ }
+ diastolic.id->{
+ validateIntMinMax(diastolic)
+ 1
+ }
+ rbg.id->{
+ validateInput(rbg)
+ 1
+ }
+ fbg.id->{
+ validateInput(fbg)
+ 1
+ }
+ ppbg.id->{
+ validateInput(ppbg)
+ 1
+ }
+ hemoglobinTest.id->{
+ validateDoubleMinMax(hemoglobinTest)
+ 1
+ }
+
+
else -> -1
}
}
+ private fun validateInput(formElement: FormElement): Int {
+ formElement.errorText = if (formElement.value.isNullOrEmpty()){
+ resources.getString(
+ R.string.form_input_empty_error
+ )
+
+ }else{
+ null
+ }
+
+ return -1
+ }
+
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as HRPNonPregnantTrackCache).let { form ->
form.visitDate = getLongFromDate(dateOfVisit.value)
@@ -463,7 +508,7 @@ class HRPNonPregnantTrackDataset(
fun updateBen(benRegCache: BenRegCache) {
benRegCache.genDetails?.let {
it.reproductiveStatus =
- englishResources.getStringArray(R.array.nbr_reproductive_status_array)[1]
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
it.reproductiveStatusId = 2
it.lastMenstrualPeriod = getLongFromDate(lmp.value)
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPPregnantTrackDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPPregnantTrackDataset.kt
index c7a63b104..79603008c 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPPregnantTrackDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HRPPregnantTrackDataset.kt
@@ -152,9 +152,11 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.systolic),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
- etMaxLength = 3
+ etMaxLength = 3,
+ min = 50,
+ max = 300
)
private val diastolic = FormElement(
@@ -162,9 +164,11 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.diastolic),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
- etMaxLength = 4
+ etMaxLength = 3,
+ min = 30,
+ max = 200
)
private val bloodGlucoseTest = FormElement(
@@ -172,7 +176,7 @@ class HRPPregnantTrackDataset(
inputType = InputType.RADIO,
title = resources.getString(R.string.blood_glucose_test),
entries = resources.getStringArray(R.array.sugar_test_preg_types),
- required = false,
+ required = true,
hasDependants = true
)
@@ -181,7 +185,7 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.random_blood_glucose),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -191,7 +195,7 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.fasting_glucose_test),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -201,7 +205,7 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.post_prandial_glucose_test),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -210,7 +214,7 @@ class HRPPregnantTrackDataset(
id = 22,
inputType = InputType.HEADLINE,
title = resources.getString(R.string.using_75gm_ogtt),
- required = false
+ required = true
)
private val fastingGlucose = FormElement(
@@ -218,7 +222,7 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.fasting_glucose_test),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -228,7 +232,7 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.after_2hrs),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -238,9 +242,11 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.hemoglobin_test),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL,
- etMaxLength = 4
+ etMaxLength = 4,
+ minDecimal = 2.0,
+ maxDecimal = 15.0
)
private val ifaGiven = FormElement(
@@ -257,7 +263,7 @@ class HRPPregnantTrackDataset(
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.issued_quantity_ifa_or_folic_acid),
arrayId = -1,
- required = false,
+ required = true,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
etMaxLength = 3
)
@@ -550,10 +556,51 @@ class HRPPregnantTrackDataset(
1
}
+ systolic.id -> {
+ validateIntMinMax(systolic)
+ 1
+ }
+ diastolic.id -> {
+ validateIntMinMax(diastolic)
+ 1
+ }
+ hemoglobinTest.id->{
+ validateDoubleMinMax(hemoglobinTest)
+ 1
+ }
+
+ rbg.id->{
+ validateInput(rbg)
+ 1
+ }
+ fbg.id->{
+ validateInput(fbg)
+ 1
+
+ }
+ ppbg.id->{
+ validateInput(ppbg)
+ 1
+ }
+
else -> -1
}
}
+
+ private fun validateInput(formElement: FormElement): Int {
+ formElement.errorText = if (formElement.value.isNullOrEmpty()){
+ resources.getString(
+ R.string.form_input_empty_error
+ )
+
+ }else{
+ null
+ }
+
+ return -1
+ }
+
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as HRPPregnantTrackCache).let { form ->
form.visitDate = getLongFromDate(dateOfVisit.value)
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HouseholdFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HouseholdFormDataset.kt
index 96f422f6d..6f11be028 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/HouseholdFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/HouseholdFormDataset.kt
@@ -14,6 +14,7 @@ import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
import org.piramalswasthya.sakhi.model.InputType.HEADLINE
import org.piramalswasthya.sakhi.model.InputType.RADIO
+import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Calendar
@@ -147,6 +148,9 @@ class HouseholdFormDataset(context: Context, language: Languages) : Dataset(cont
firstNameHeadOfFamily.value = saved.familyHeadName
lastNameHeadOfFamily.value = saved.familyName
mobileNoHeadOfFamily.value = saved.familyHeadPhoneNo.toString()
+ saved.familyHeadName.takeIf { it!!.isNotEmpty() }?.let { firstNameHeadOfFamily.inputType = TEXT_VIEW }
+ saved.familyName.takeIf { it!!.isNotEmpty() }?.let { lastNameHeadOfFamily.inputType = TEXT_VIEW }
+ saved.familyHeadPhoneNo.takeIf { it != null }?.let { mobileNoHeadOfFamily.inputType = TEXT_VIEW }
houseNo.value = saved.houseNo
wardNo.value = saved.wardNo
wardName.value = saved.wardName
@@ -435,10 +439,17 @@ class HouseholdFormDataset(context: Context, language: Languages) : Dataset(cont
return when (formId) {
firstNameHeadOfFamily.id -> {
validateEmptyOnEditText(firstNameHeadOfFamily)
- validateAllCapsOrSpaceOnEditText(firstNameHeadOfFamily)
+ // validateAllCapsOrSpaceOnEditText(firstNameHeadOfFamily)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(firstNameHeadOfFamily)
+ }
+ /*These validations commented because Hindi and Asamese language name and sirname should store in db
+ *
+ * */
+ lastNameHeadOfFamily.id ->{
+ validateEmptyOnEditText(lastNameHeadOfFamily)
+ // validateAllCapsOrSpaceOnEditText(lastNameHeadOfFamily)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(lastNameHeadOfFamily)
}
-
- lastNameHeadOfFamily.id -> validateAllCapsOrSpaceOnEditText(lastNameHeadOfFamily)
mobileNoHeadOfFamily.id -> {
validateEmptyOnEditText(mobileNoHeadOfFamily)
validateMobileNumberOnEditText(mobileNoHeadOfFamily)
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/IRSRoundDataSet.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/IRSRoundDataSet.kt
new file mode 100644
index 000000000..57808f920
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/IRSRoundDataSet.kt
@@ -0,0 +1,96 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.util.Log
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.IRSRoundScreening
+import org.piramalswasthya.sakhi.model.InputType
+
+class IRSRoundDataSet(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private val headline = FormElement(
+ id = 1,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.irs_round),
+ headingLine = false,
+ required = false,
+ hasDependants = false
+
+
+ )
+
+ private val dateOfCase = FormElement(
+ id = 2,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date),
+ required = false,
+ min = System.currentTimeMillis(),
+ max = System.currentTimeMillis(),
+ hasDependants = false
+
+ )
+
+
+ private val rounds = FormElement(
+ id = 3,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.round),
+ arrayId = R.array.irs_rounds,
+ entries = resources.getStringArray(R.array.irs_rounds),
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ hasDependants = false
+ )
+
+
+ suspend fun setUpPage(
+ saved: IRSRoundScreening?,
+ ) {
+ val list = mutableListOf(
+ headline,
+ dateOfCase,
+ rounds,
+ )
+ if(saved != null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ val index = saved.rounds
+ val localizedArray = resources.getStringArray(R.array.irs_rounds)
+ if (index in localizedArray.indices) {
+ rounds.value = localizedArray[index]
+ }
+
+ } else {
+
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+
+ }
+
+
+ setUpPage(list)
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ /* return when (formId) {
+
+
+
+
+ }*/
+ return -1
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as IRSRoundScreening).let { form ->
+ form.rounds = rounds.getPosition()
+ form.date = getLongFromDate(dateOfCase.value)
+ }
+ }
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/IconDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/IconDataset.kt
index d25deee75..48603527e 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/IconDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/IconDataset.kt
@@ -2,16 +2,25 @@ package org.piramalswasthya.sakhi.configuration
import android.content.res.Resources
import dagger.hilt.android.scopes.ActivityRetainedScoped
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.model.Icon
+import org.piramalswasthya.sakhi.repositories.AdolescentHealthRepo
import org.piramalswasthya.sakhi.repositories.RecordsRepo
+import org.piramalswasthya.sakhi.ui.asha_supervisor.supervisor.SupervisorFragmentDirections
+import org.piramalswasthya.sakhi.ui.getTitleRes
import org.piramalswasthya.sakhi.ui.home_activity.child_care.ChildCareFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.communicable_diseases.CdFragmentDirections
+import org.piramalswasthya.sakhi.ui.home_activity.death_reports.DeathReportsFragmentDirections
+import org.piramalswasthya.sakhi.ui.home_activity.disease_control.DiseaseControlFragmentDirections
+import org.piramalswasthya.sakhi.ui.home_activity.disease_control.leprosy.LeprosyFragmentDirections
+import org.piramalswasthya.sakhi.ui.home_activity.disease_control.malaria.form.MalariaIconsFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.eligible_couple.EligibleCoupleFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.home.HomeFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.hrp_cases.HrpCasesFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.immunization_due.ImmunizationDueTypeFragmentDirections
+import org.piramalswasthya.sakhi.ui.home_activity.lms.LmsFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.maternal_health.MotherCareFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.non_communicable_diseases.NcdFragmentDirections
import org.piramalswasthya.sakhi.ui.home_activity.village_level_forms.VillageLevelFormsFragmentDirections
@@ -21,18 +30,31 @@ import javax.inject.Inject
@ActivityRetainedScoped
class IconDataset @Inject constructor(
private val recordsRepo: RecordsRepo,
- private val preferenceDao: PreferenceDao
+ private val preferenceDao: PreferenceDao,
+ private val adolescentHealthRepo: AdolescentHealthRepo
) {
enum class Modules {
ALL,
HRP
+
+ }
+
+ enum class Disease {
+ MALARIA, KALA_AZAR, AES_JE, FILARIA, LEPROSY, DEWARMING
}
fun getHomeIconDataset(resources: Resources): List {
val showAll = preferenceDao.isDevModeEnabled
+ val vlfTitle = resources.getString(R.string.icon_title_vlf)
+
Timber.d("currently : $showAll")
- val showModules = Modules.ALL
+ lateinit var showModules:Modules
+ if (BuildConfig.FLAVOR.equals("xushrukha", true)) {
+ showModules = Modules.HRP
+ }else{
+ showModules = Modules.ALL
+ }
return when (showModules) {
Modules.ALL -> listOf(
Icon(
@@ -45,7 +67,7 @@ class IconDataset @Inject constructor(
R.drawable.ic__ben,
resources.getString(R.string.icon_title_ben),
recordsRepo.allBenListCount,
- HomeFragmentDirections.actionNavHomeToAllBenFragment(),
+ HomeFragmentDirections.actionNavHomeToAllBenFragment(0),
),
Icon(
R.drawable.ic__eligible_couple,
@@ -67,9 +89,9 @@ class IconDataset @Inject constructor(
),
Icon(
R.drawable.ic__ncd,
- resources.getString(R.string.icon_title_ncd),
+ resources.getString(R.string.icon_title_disease),
null,
- HomeFragmentDirections.actionNavHomeToNcdFragment(),
+ HomeFragmentDirections.actionHomeFragmentToDiseaseControlFragment()
),
Icon(
R.drawable.ic__ncd,
@@ -78,7 +100,7 @@ class IconDataset @Inject constructor(
HomeFragmentDirections.actionHomeFragmentToCdFragment()
),
Icon(
- R.drawable.ic__immunization,
+ R.drawable.ic_vaccines,
resources.getString(R.string.icon_title_imm),
null,
HomeFragmentDirections.actionNavHomeToImmunizationDueFragment(),
@@ -106,11 +128,12 @@ class IconDataset @Inject constructor(
),
Icon(
R.drawable.ic__village_level_form,
- resources.getString(R.string.icon_title_vlf),
+ vlfTitle,
null,
HomeFragmentDirections.actionNavHomeToVillageLevelFormsFragment()
),
- )
+
+ )
Modules.HRP -> listOf(
Icon(
@@ -123,7 +146,7 @@ class IconDataset @Inject constructor(
R.drawable.ic__ben,
resources.getString(R.string.icon_title_ben),
recordsRepo.allBenListCount,
- HomeFragmentDirections.actionNavHomeToAllBenFragment(),
+ HomeFragmentDirections.actionNavHomeToAllBenFragment(0),
),
Icon(
R.drawable.ic__eligible_couple,
@@ -147,6 +170,7 @@ class IconDataset @Inject constructor(
)
)
+
}.apply {
forEachIndexed { index, icon ->
icon.colorPrimary = index % 2 == 0
@@ -190,6 +214,79 @@ class IconDataset @Inject constructor(
),
)
+ fun getSupervisorIconsDataset(resources: Resources) = listOf(
+ Icon(
+ R.drawable.ic__hh,
+ resources.getString(R.string.sup_households),
+ recordsRepo.hhListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToAllHouseholdFragments()
+ ),
+ Icon(
+ R.drawable.ic__ben,
+ resources.getString(R.string.sup_beneficiaries),
+ recordsRepo.allBenListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToAllBenFragments(0)
+ ),
+ Icon(
+ R.drawable.ic__eligible_couple,
+ resources.getString(R.string.sup_eligible_couples),
+ recordsRepo.eligibleCoupleTrackingListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToEligibleCoupleTrackingListFragments()
+ ),
+ Icon(
+ R.drawable.ic__maternal_health,
+ resources.getString(R.string.sup_pregnant_women),
+ recordsRepo.getPregnantWomenListCount(),
+ SupervisorFragmentDirections.actionNavSupervisorToPwRegistrationFragments()
+ ),
+ Icon(
+ R.drawable.ic__anc_visit,
+ resources.getString(R.string.sup_anc_visits),
+ recordsRepo.getRegisteredPregnantWomanListCount(),
+ SupervisorFragmentDirections.actionNavSupervisorToPwAncVisitsFragments()
+ ),
+ Icon(
+ R.drawable.ic__hrp,
+ resources.getString(R.string.sup_hrp_woman),
+ recordsRepo.hrpPregnantWomenListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToPregnantListFragments()
+ ),
+ Icon(
+ R.drawable.ic__delivery_outcome,
+ resources.getString(R.string.sup_deliveries),
+ recordsRepo.getDeliveredWomenListCount(),
+ SupervisorFragmentDirections.actionNavSupervisorToDeliveryOutcomeListFragments()
+ ),
+ Icon(
+ R.drawable.ic__immunization,
+ resources.getString(R.string.sup_routine_immunization),
+ recordsRepo.childrenImmunizationListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToChildImmunizationListFragments()
+ ),
+ Icon(
+ R.drawable.ic__ncd_list,
+ resources.getString(R.string.sup_ncd_screened),
+ recordsRepo.ncdListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToNcdListFragments()
+ ),
+ Icon(
+ R.drawable.ic__ncd_priority,
+ resources.getString(R.string.sup_ncd_priority),
+ recordsRepo.getNcdPriorityListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToNcdPriorityListFragments()
+ ),
+ Icon(
+ R.drawable.ic__death,
+ resources.getString(R.string.sup_tb_cases),
+ recordsRepo.tbSuspectedListCount,
+ SupervisorFragmentDirections.actionNavSupervisorToTBSuspectedListFragments()
+ )
+ ).apply {
+ forEachIndexed { index, icon ->
+ icon.colorPrimary = index % 3 == 0
+ }
+ }
+
fun getHRPPregnantWomenDataset(resources: Resources) = listOf(
Icon(
R.drawable.ic__assess_high_risk,
@@ -205,6 +302,118 @@ class IconDataset @Inject constructor(
)
)
+ fun getVLFDataset(resources: Resources): List {
+
+ val phcReviewIcon = Icon(
+ R.drawable.phc_meeting_s2,
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true))
+ resources.getString(R.string.cluster_review)
+ else
+ resources.getString(R.string.phc_review),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToPHCReviewListFragement()
+ )
+
+ val list = mutableListOf(
+ Icon(
+ R.drawable.ic__vhnd_s1,
+ resources.getString(R.string.vhnd),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToVHNDListFragement()
+ ),
+ Icon(
+ R.drawable.ic__vhnsc,
+ resources.getString(R.string.vnhc),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToVHNCListFragement()
+ ),
+ phcReviewIcon,
+ Icon(
+ R.drawable.ic__ahd,
+ resources.getString(R.string.ahd),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToAHDListFragment()
+ )
+ )
+
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.add(
+ Icon(
+ R.drawable.ic__sass_bahu_sammelan,
+ resources.getString(R.string.saas_samelan),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToSaasBahuListFragment()
+ )
+ )
+ }
+
+
+ list.addAll(
+ listOf(
+ Icon(
+ R.drawable.ic__national_deworming_s1,
+ resources.getString(R.string.national_deworming_day),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToDewormingListFragment()
+ ),
+ Icon(
+ R.drawable.ic__maa_meeting_1,
+ resources.getString(R.string.maa_meeting),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToAllMaaMeetingFragment()
+ ),
+ Icon(
+ R.drawable.ic__pulse_polio,
+ resources.getString(R.string.pulse_polio_campaign),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToPulsePolioCampaignListFragment()
+ ),
+ Icon(
+ R.drawable.ic__ors,
+ resources.getString(R.string.ors_distribution_campaign),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToORSCampaignListFragment()
+ ),
+ Icon(
+ R.drawable.filaria,
+ resources.getString(R.string.mda_title),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToFilariaMdaCampaignHistoryFragment()
+ )
+ )
+ )
+
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.add(
+ Icon(
+ R.drawable.ic__u_win,
+ resources.getString(R.string.u_win_session),
+ null,
+ VillageLevelFormsFragmentDirections
+ .actionVillageLevelFormsFragmentToUwinListFragment()
+ )
+ )
+ }
+
+ return list.apply {
+ forEachIndexed { index, icon ->
+ icon.colorPrimary = index % 2 == 0
+ }
+ }
+ }
+
+
+
fun getHRPNonPregnantWomenDataset(resources: Resources) = listOf(
Icon(
R.drawable.ic__assess_high_risk,
@@ -236,6 +445,30 @@ class IconDataset @Inject constructor(
resources.getString(R.string.icon_title_acc),
recordsRepo.adolescentListCount,
ChildCareFragmentDirections.actionChildCareFragmentToAdolescentListFragment()
+ ),
+ Icon(
+ R.drawable.ic__adolescent,
+ resources.getString(R.string.children_under_five_years),
+ recordsRepo.childFilteredListCount,
+ ChildCareFragmentDirections.actionChildCareFragmentToChildrenUnderFiveYearListFragment()
+ )
+ ).apply {
+ forEachIndexed { index, icon ->
+ icon.colorPrimary = index % 2 == 0
+ }
+ }
+
+ fun getLmsDataset(resources: Resources) = listOf(
+ Icon(
+ R.drawable.ic_guide_icon,
+ resources.getString(R.string.icon_title_user_guid),
+ null,
+ EligibleCoupleFragmentDirections.actionEligibleCoupleFragmentToEligibleCoupleListFragment()
+ ), Icon(
+ R.drawable.ic_video_icon,
+ resources.getString(R.string.icon_title_video_tutorial),
+ null,
+ LmsFragmentDirections.actionLmsFragmentToVideoTutorialFragmet()
)
).apply {
forEachIndexed { index, icon ->
@@ -261,6 +494,117 @@ class IconDataset @Inject constructor(
}
}
+
+ fun getLeprosyDataset(resources: Resources) = listOf(
+ Icon(
+ R.drawable.leprocy,
+ resources.getString(R.string.leprosy_screening),
+ recordsRepo.tbScreeningListCount,
+ LeprosyFragmentDirections.actionLeprosyFragmentToAllHouseHoldDiseaseControlFragment(
+ resources.getString(Disease.LEPROSY.getTitleRes())
+ )
+ ),
+ Icon(
+ R.drawable.leprocy,
+ resources.getString(R.string.leprosy_suspected),
+ recordsRepo.leprosySuspectedListCount,
+ LeprosyFragmentDirections.actionLeprosyFragmenToLeprosySuspectedListFragment()
+ ),
+ Icon(
+ R.drawable.leprocy,
+ resources.getString(R.string.leprosy_confirmed),
+ recordsRepo.leprosyConfirmedCasesListCount,
+ LeprosyFragmentDirections.actionLeprosyDragmentToLeprosyConfirmedListFragment()
+ ),
+
+ )
+
+
+ fun getDiseaseControlDataset(resources: Resources) = listOf(
+ Icon(
+ R.drawable.ic__ncd,
+ resources.getString(R.string.icon_title_ncd),
+ null,
+ DiseaseControlFragmentDirections.actionDiseaseControlFragmentToNcdFragment(),
+
+ ),
+ Icon(
+ R.drawable.maleria,
+ resources.getString(R.string.icon_title_maleria),
+ recordsRepo.tbScreeningListCount,
+ DiseaseControlFragmentDirections.actionDiseaseControlFragmentToMalariaIconsFragment(
+
+ )
+ ), Icon(
+ R.drawable.kala,
+ resources.getString(R.string.icon_title_ka),
+ recordsRepo.tbScreeningListCount,
+ DiseaseControlFragmentDirections.actionDiseaseControlFragmentToAllHouseHoldDiseaseControlFragment(
+ resources.getString(Disease.KALA_AZAR.getTitleRes()))
+ ),
+
+ Icon(
+ R.drawable.aes,
+ resources.getString(R.string.icon_title_aes),
+ recordsRepo.tbScreeningListCount,
+ DiseaseControlFragmentDirections.actionDiseaseControlFragmentToAllHouseHoldDiseaseControlFragment(
+ resources.getString(Disease.AES_JE.getTitleRes()))
+ ),
+ Icon(
+ R.drawable.filaria,
+ resources.getString(R.string.icon_title_filaria),
+ recordsRepo.tbScreeningListCount,
+ DiseaseControlFragmentDirections.actionDiseaseControlFragmentToAllHouseHoldDiseaseControlFragment(
+ resources.getString(Disease.FILARIA.getTitleRes())
+ )
+ ),
+ Icon(
+ R.drawable.leprocy,
+ resources.getString(R.string.icon_title_leprosy),
+ recordsRepo.tbScreeningListCount,
+ DiseaseControlFragmentDirections.actionDiseaseControlFragmentToLeprosyFragment()
+ ),
+ /*Icon(
+ R.drawable.ic__eligible_couple,
+ resources.getString(R.string.icon_title_dearming),
+ recordsRepo.eligibleCoupleTrackingListCount,
+ DiseaseControlFragmentDirections.actionDiseaseControlFragmentToAllHouseHoldDiseaseControlFragment(
+ Disease.DEWARMING.toString()
+ )
+ )*/
+ ).apply {
+ forEachIndexed { index, icon ->
+ icon.colorPrimary = index % 2 == 0
+ }
+ }
+
+ fun getDeathReportDataset(resources: Resources) = listOf(
+ Icon(
+ R.drawable.ic__general_death,
+ resources.getString(R.string.general_deaths),
+ recordsRepo.getGeneralDeathCount(),
+ DeathReportsFragmentDirections.actionDeathReportsFragmentToGdrListFragment()
+ ),
+ Icon(
+ R.drawable.maternal_death_s1,
+ resources.getString(R.string.maternal_deaths),
+ recordsRepo.getMaternalDeathCount(),
+ DeathReportsFragmentDirections.actionDeathReportsFragmentToMdsrListFragment()
+ ),
+ Icon(
+ R.drawable.non_maternal_death_s1,
+ resources.getString(R.string.non_maternal_deaths),
+ recordsRepo.getNonMaternalDeathCount(),
+ DeathReportsFragmentDirections.actionDeathReportsFragmentToNmdsrListFragment()
+ ),
+ Icon(
+ R.drawable.ic__child_death,
+ resources.getString(R.string.child_deaths),
+ recordsRepo.getChildDeathCount(),
+ DeathReportsFragmentDirections.actionDeathReportsFragmentToCdrListFragment()
+ )
+ )
+
fun getMotherCareDataset(resources: Resources) = listOf(
Icon(
R.drawable.ic__pwr,
@@ -287,7 +631,7 @@ class IconDataset @Inject constructor(
MotherCareFragmentDirections.actionMotherCareFragmentToPncMotherListFragment()
),
Icon(
- R.drawable.ic__infant_registration,
+ R.drawable.ic__newborn,
resources.getString(R.string.icon_title_pmir),
recordsRepo.getInfantRegisterCount(),
MotherCareFragmentDirections.actionMotherCareFragmentToInfantRegListFragment()
@@ -298,6 +642,24 @@ class IconDataset @Inject constructor(
recordsRepo.getRegisteredInfantsCount(),
MotherCareFragmentDirections.actionMotherCareFragmentToChildRegListFragment()
),
+ Icon(
+ R.drawable.ic__abortion_1,
+ resources.getString(R.string.icon_title_abortion),
+ recordsRepo.getAbortionPregnantWomanCount(),
+ MotherCareFragmentDirections.actionMotherCareFragmentToAbortionListFragment()
+ ),
+ Icon(
+ R.drawable.ic__pmsma,
+ resources.getString(R.string.icon_title_pmsma),
+ recordsRepo.getHighRiskWomenCount(),
+ MotherCareFragmentDirections.actionMotherCareFragmentToPmsmaHighRiskListFragment()
+ ),
+ Icon(
+ R.drawable.ic__hwc_referal_1,
+ resources.getString(R.string.hwc_referred_list),
+ recordsRepo.getHwcReferedListCount,
+ MotherCareFragmentDirections.actionMotherCareFragmentToHwcReferredListFragment()
+ ),
).apply {
forEachIndexed { index, icon ->
icon.colorPrimary = index % 2 == 0
@@ -305,12 +667,12 @@ class IconDataset @Inject constructor(
}
fun getNCDDataset(resources: Resources) = listOf(
- Icon(
- R.drawable.ic__ncd_list,
- resources.getString(R.string.icon_title_ncd_list),
- recordsRepo.ncdListCount,
- NcdFragmentDirections.actionNcdFragmentToNcdListFragment()
- ),
+// Icon(
+// R.drawable.ic__ncd_list,
+// resources.getString(R.string.icon_title_ncd_list),
+// recordsRepo.ncdListCount,
+// NcdFragmentDirections.actionNcdFragmentToNcdListFragment()
+// ),
Icon(
R.drawable.ic__ncd_eligibility,
resources.getString(R.string.icon_title_ncd_eligible_list),
@@ -329,21 +691,27 @@ class IconDataset @Inject constructor(
recordsRepo.getNcdNonEligibleListCount,
NcdFragmentDirections.actionNcdFragmentToNcdNonEligibleListFragment()
),
+ Icon(
+ R.drawable.ic_ncd_noneligible,
+ resources.getString(R.string.ncd_refer_list),
+ recordsRepo.getNcdrefferedListCount,
+ NcdFragmentDirections.actionNcdFragmentToNcdReferredListFragment()
+ ),
).apply {
forEachIndexed { index, icon ->
icon.colorPrimary = index % 2 == 0
}
}
- fun getImmunizationDataset() = listOf(
+ fun getImmunizationDataset(resources : Resources) = listOf(
Icon(
- R.drawable.ic__immunization,
- "Child Immunization",
+ R.drawable.ic_vaccines,
+ resources.getString(R.string.child_immunization),
recordsRepo.childrenImmunizationListCount,
ImmunizationDueTypeFragmentDirections.actionImmunizationDueTypeFragmentToChildImmunizationListFragment()
),
- ).apply {
+ ).apply {
forEachIndexed { index, icon ->
icon.colorPrimary = index % 2 == 0
}
@@ -374,6 +742,30 @@ class IconDataset @Inject constructor(
recordsRepo.tbSuspectedListCount,
CdFragmentDirections.actionCdFragmentToTBSuspectedListFragment()
+ ), Icon(
+ icon = R.drawable.ic__death,
+ title = resources.getString(R.string.icon_title_ncd_tb_confirmed),
+ recordsRepo.tbConfirmedListCount,
+ CdFragmentDirections.actionCdFragmentToTBConfirmedListFragment()
+ )
+ ).apply {
+ forEachIndexed { index, icon ->
+ icon.colorPrimary = index % 2 == 0
+ }
+ }
+
+ fun getMalariaDataset(resources: Resources) = listOf(
+ Icon(
+ R.drawable.malaria_list,
+ resources.getString(R.string.icon_title_maleria),
+ recordsRepo.tbScreeningListCount,
+ MalariaIconsFragmentDirections.actionMalariaIconsFragmentToAllHouseHoldDiseaseControlFragment(resources.getString(Disease.MALARIA.getTitleRes()))
+ ), Icon(
+ R.drawable.confirmed,
+ resources.getString(R.string.icon_title_malaria_confirmed),
+ recordsRepo.malariaConfirmedCasesListCount,
+ MalariaIconsFragmentDirections.actionMalariaIconsFragmentToConfirmedMalariaLIstFragment()
+
)
).apply {
forEachIndexed { index, icon ->
@@ -381,4 +773,4 @@ class IconDataset @Inject constructor(
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/ImmunizationDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/ImmunizationDataset.kt
index 8fd36623e..3c030d4a2 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/ImmunizationDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/ImmunizationDataset.kt
@@ -1,6 +1,8 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.model.BenRegCache
@@ -13,7 +15,8 @@ class ImmunizationDataset(context: Context, language: Languages) : Dataset(conte
private var vaccineId: Int = 0
- private val name = FormElement(
+
+ /*private val name = FormElement(
id = 100,
inputType = InputType.TEXT_VIEW,
title = resources.getString(R.string.name_ben),
@@ -32,7 +35,7 @@ class ImmunizationDataset(context: Context, language: Languages) : Dataset(conte
inputType = InputType.TEXT_VIEW,
title = resources.getString(R.string.date_of_birth),
required = false
- )
+ )*/
// private val dateOfPrevVaccination = FormElement(
// id = 103,
@@ -69,7 +72,7 @@ class ImmunizationDataset(context: Context, language: Languages) : Dataset(conte
inputType = InputType.DATE_PICKER,
title = resources.getString(R.string.date_of_vaccination),
max = System.currentTimeMillis(),
- required = false
+ required = true
)
private val vaccinatedPlace = FormElement(
id = 109,
@@ -88,36 +91,77 @@ class ImmunizationDataset(context: Context, language: Languages) : Dataset(conte
required = false
)
+ private val doseName = FormElement(
+ id = 113,
+ inputType = InputType.TEXT_VIEW,
+ title = context.getString(R.string.dose_name),
+ required = false
+ )
+
+ private val vaccinationDueDate = FormElement(
+ id = 114,
+ inputType = InputType.TEXT_VIEW,
+ title = context.getString(R.string.vaccination_due_date),
+ required = false
+ )
+
+ val mcpCard1 = FormElement(
+ id = 111,
+ inputType = InputType.FILE_UPLOAD,
+ required = false,
+ title = context.getString(R.string.mcp_card_1)
+ )
+ val mcpCard2 = FormElement(
+ id = 112,
+ inputType = InputType.FILE_UPLOAD,
+ required = false,
+ title = context.getString(R.string.mcp_card_2)
+ )
+
+
suspend fun setFirstPage(ben: BenRegCache, vaccine: Vaccine, imm: ImmunizationCache?) {
- val list = listOf(
- name,
- motherName,
- dateOfBirth,
+ val list = mutableListOf(
+// name,
+// motherName,
+// dateOfBirth,
+// vaccineName,
+// doseNumber,
+// expectedDate,
vaccineName,
- doseNumber,
- expectedDate,
+ vaccinationDueDate,
dateOfVaccination,
vaccinatedPlace,
- vaccinatedBy
+ vaccinatedBy,
+ mcpCard1,
+ mcpCard2
)
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(mcpCard1)
+ list.remove(mcpCard2)
+ }
vaccineId = vaccine.vaccineId
- name.value = ben.firstName ?: "Baby of ${ben.motherName}"
- motherName.value = ben.motherName
- dateOfBirth.value = getDateFromLong(ben.dob)
+// name.value = ben.firstName ?: "Baby of ${ben.motherName}"
+// motherName.value = ben.motherName
+// dateOfBirth.value = getDateFromLong(ben.dob)
+// doseName.value = vaccine.immunizationService.name
vaccineName.value = vaccine.vaccineName.dropLastWhile { it.isDigit() }
doseNumber.value = vaccine.vaccineName.takeLastWhile { it.isDigit() }
+ vaccinationDueDate.value = getDateFromLong(ben.dob + vaccine.maxAllowedAgeInMillis)
expectedDate.value =
- getDateFromLong(ben.dob + vaccine.minAllowedAgeInMillis + vaccine.overdueDurationSinceMinInMillis)
+ getDateFromLong(ben.dob + vaccine.maxAllowedAgeInMillis)
dateOfVaccination.value = getDateFromLong(System.currentTimeMillis())
dateOfVaccination.min = ben.dob + vaccine.minAllowedAgeInMillis
if (System.currentTimeMillis() > ben.dob + vaccine.maxAllowedAgeInMillis) {
dateOfVaccination.max = ben.dob + vaccine.maxAllowedAgeInMillis
}
+
imm?.let { saved ->
dateOfVaccination.value = saved.date?.let { getDateFromLong(it) }
vaccinatedPlace.value = getLocalValueInArray(vaccinatedPlace.arrayId, saved.place)
vaccinatedBy.value = getLocalValueInArray(vaccinatedBy.arrayId, saved.byWho)
+ mcpCard1.value = imm.mcpCardSummary1
+ mcpCard2.value = imm.mcpCardSummary2
}
setUpPage(list)
}
@@ -128,15 +172,34 @@ class ImmunizationDataset(context: Context, language: Languages) : Dataset(conte
(cacheModel as ImmunizationCache).let {
it.date = dateOfVaccination.value?.let { getLongFromDate(it) }
// it.placeId= vaccinatedPlace.getPosition()
- it.vaccineId = vaccineId
+ // it.vaccineId = vaccineId
it.place =
vaccinatedPlace.getEnglishStringFromPosition(vaccinatedPlace.getPosition()) ?: ""
// it.byWhoId= vaccinatedBy.getPosition()
it.byWho = vaccinatedBy.getEnglishStringFromPosition(vaccinatedBy.getPosition()) ?: ""
-
+ it.mcpCardSummary1 = mcpCard1.value?.takeIf { it.isNotEmpty() }
+ it.mcpCardSummary2 = mcpCard2.value?.takeIf { it.isNotEmpty() }
}
}
+
+ fun getIndexMCPCard1() = getIndexById(mcpCard1.id)
+ fun getIndexMCPCard2() = getIndexById(mcpCard2.id)
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ mcpCard1.id -> {
+ mcpCard1.value = dpUri.toString()
+ mcpCard1.errorText = null
+ }
+
+ mcpCard2.id -> {
+ mcpCard2.value = dpUri.toString()
+ mcpCard2.errorText = null
+ }
+ }
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/InfantRegistrationDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/InfantRegistrationDataset.kt
index f762e0366..d3c14b1e5 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/InfantRegistrationDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/InfantRegistrationDataset.kt
@@ -1,6 +1,8 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.helpers.getWeeksOfPregnancy
@@ -11,7 +13,6 @@ import org.piramalswasthya.sakhi.model.Gender
import org.piramalswasthya.sakhi.model.InfantRegCache
import org.piramalswasthya.sakhi.model.InputType
import org.piramalswasthya.sakhi.model.PregnantWomanRegistrationCache
-import java.util.concurrent.TimeUnit
class InfantRegistrationDataset(
context: Context, currentLanguage: Languages
@@ -20,7 +21,7 @@ class InfantRegistrationDataset(
private var babyName = FormElement(
id = 1,
inputType = InputType.TEXT_VIEW,
- title = "Name of Baby",
+ title = resources.getString(R.string.ir_baby_name),
required = false,
hasDependants = false
)
@@ -28,8 +29,9 @@ class InfantRegistrationDataset(
private var infantTerm = FormElement(
id = 2,
inputType = InputType.TEXT_VIEW,
- title = "Infant Term",
- entries = arrayOf("Full Term", "Pre Term"),
+ title = resources.getString(R.string.ir_infant_term),
+ arrayId = R.array.ir_infant_term,
+ entries = resources.getStringArray(R.array.ir_infant_term),
required = false,
hasDependants = false
)
@@ -37,8 +39,9 @@ class InfantRegistrationDataset(
private var corticosteroidGiven = FormElement(
id = 3,
inputType = InputType.RADIO,
- title = "Was Corticosteroid Inj. given?",
- entries = arrayOf("Yes", "No", "Don't Know"),
+ title = resources.getString(R.string.ir_corticosteroid_given),
+ arrayId = R.array.ir_confirmation_array3,
+ entries = resources.getStringArray(R.array.ir_confirmation_array3),
required = false,
hasDependants = false
)
@@ -46,7 +49,7 @@ class InfantRegistrationDataset(
private var gender = FormElement(
id = 4,
inputType = InputType.RADIO,
- title = "Sex of Infant",
+ title = resources.getString(R.string.ir_gender),
entries = resources.getStringArray(R.array.ecr_gender_array),
required = true,
hasDependants = true,
@@ -55,8 +58,8 @@ class InfantRegistrationDataset(
private var babyCriedAtBirth = FormElement(
id = 5,
inputType = InputType.RADIO,
- title = "Baby Cried Immediately at Birth",
- entries = arrayOf("Yes", "No"),
+ title = resources.getString(R.string.ir_baby_cried_at_birth),
+ entries = resources.getStringArray(R.array.ir_confirmation_array1),
required = false,
hasDependants = true
)
@@ -64,8 +67,8 @@ class InfantRegistrationDataset(
private var resuscitation = FormElement(
id = 6,
inputType = InputType.RADIO,
- title = "If No, Resuscitation Done",
- entries = arrayOf("Yes", "No"),
+ title = resources.getString(R.string.ir_resuscitation),
+ entries = resources.getStringArray(R.array.ir_confirmation_array1),
required = true,
hasDependants = false
)
@@ -73,8 +76,9 @@ class InfantRegistrationDataset(
private var referred = FormElement(
id = 7,
inputType = InputType.RADIO,
- title = "Referred to higher facility for further management",
- entries = arrayOf("Yes", "No", "NA"),
+ title = resources.getString(R.string.ir_referred),
+ arrayId = R.array.ir_confirmation_array2,
+ entries = resources.getStringArray(R.array.ir_confirmation_array2),
required = false,
hasDependants = false
)
@@ -82,28 +86,27 @@ class InfantRegistrationDataset(
private var hadBirthDefect = FormElement(
id = 8,
inputType = InputType.RADIO,
- title = "Any birth defect seen in at birth?",
- entries = arrayOf("Yes", "No", "NA"),
+ title = resources.getString(R.string.ir_had_birth_defect),
+ arrayId = R.array.ir_confirmation_array2,
+ entries = resources.getStringArray(R.array.ir_confirmation_array2),
required = false,
hasDependants = true
)
private var birthDefect = FormElement(
- id = 9, inputType = InputType.DROPDOWN, title = "Defect seen at birth", entries = arrayOf(
- "Cleft Lip / Cleft Palate",
- "Club Foot",
- "Down's Syndrome",
- "Hydrocephalus",
- "Imperforate Anus",
- "Neural Tube Defect (Spinal Bifida)",
- "Other"
- ), required = false, hasDependants = true
+ id = 9,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.ir_birth_defect),
+ arrayId = R.array.ir_birth_defect_array,
+ entries = resources.getStringArray(R.array.ir_birth_defect_array),
+ required = false,
+ hasDependants = true
)
private var otherDefect = FormElement(
id = 10,
inputType = InputType.EDIT_TEXT,
- title = "Other defect seen at Birth",
+ title = resources.getString(R.string.ir_other_defect),
required = false,
hasDependants = false,
)
@@ -111,63 +114,103 @@ class InfantRegistrationDataset(
private var weight = FormElement(
id = 11,
inputType = InputType.EDIT_TEXT,
- title = "Weight at Birth(kg)",
- required = false,
+ title = resources.getString(R.string.str_weight_at_birth_gram),
+ required = true,
hasDependants = false,
- minDecimal = 0.5,
- maxDecimal = 7.0,
- etInputType = android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL,
+ etMaxLength = 4,
+ min = 500,
+ max = 6000,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
)
private var breastFeedingStarted = FormElement(
id = 12,
inputType = InputType.RADIO,
- title = "Breast feeding started within one hour of birth",
- entries = arrayOf("Yes", "No"),
- required = false,
+ title = resources.getString(R.string.ir_breast_feeding_started),
+ entries = resources.getStringArray(R.array.ir_confirmation_array1),
+ required = true,
hasDependants = false,
)
-
- private val opv0Dose = FormElement(
+ private var isSncu = FormElement(
id = 13,
- inputType = InputType.DATE_PICKER,
- title = "OPV0 Dose",
- arrayId = -1,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.is_baby_discharge_from_sncu),
+ arrayId = R.array.do_is_jsy_beneficiary_array,
+ entries = resources.getStringArray(R.array.do_is_jsy_beneficiary_array),
required = false,
- max = System.currentTimeMillis(),
hasDependants = true
)
- private val bcgDose = FormElement(
- id = 14,
- inputType = InputType.DATE_PICKER,
- title = "BCG Dose",
- arrayId = -1,
- required = false,
- max = System.currentTimeMillis(),
- hasDependants = true
+
+ private val deliveryDischargeSummary1 = FormElement(
+ id = 58,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_1),
+ required = false
+
)
- private val hepBDose = FormElement(
- id = 15,
- inputType = InputType.DATE_PICKER,
- title = "HEP B-0 Dose",
- arrayId = -1,
- required = false,
- max = System.currentTimeMillis(),
- hasDependants = true
+ private val deliveryDischargeSummary2 = FormElement(
+ id =59,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_2),
+ required = false
)
- private val vitkDose = FormElement(
- id = 16,
- inputType = InputType.DATE_PICKER,
- title = "VITK Dose",
- arrayId = -1,
- required = false,
- max = System.currentTimeMillis(),
- hasDependants = true
+ private val deliveryDischargeSummary3 = FormElement(
+ id =60,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_3),
+ required = false
+ )
+
+ private val deliveryDischargeSummary4 = FormElement(
+ id =61,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_4),
+ required = false
)
+// private val opv0Dose = FormElement(
+// id = 13,
+// inputType = InputType.DATE_PICKER,
+// title = "OPV0 Dose",
+// arrayId = -1,
+// required = false,
+// max = System.currentTimeMillis(),
+// hasDependants = true
+// )
+
+// private val bcgDose = FormElement(
+// id = 14,
+// inputType = InputType.DATE_PICKER,
+// title = "BCG Dose",
+// arrayId = -1,
+// required = false,
+// max = System.currentTimeMillis(),
+// hasDependants = true
+// )
+
+// private val hepBDose = FormElement(
+// id = 15,
+// inputType = InputType.DATE_PICKER,
+// title = "HEP B-0 Dose",
+// arrayId = -1,
+// required = false,
+// max = System.currentTimeMillis(),
+// hasDependants = true
+// )
+
+// private val vitkDose = FormElement(
+// id = 16,
+// inputType = InputType.DATE_PICKER,
+// title = "VITK Dose",
+// arrayId = -1,
+// required = false,
+// max = System.currentTimeMillis(),
+// hasDependants = true
+// )
+
suspend fun setUpPage(
ben: BenRegCache?,
@@ -183,10 +226,10 @@ class InfantRegistrationDataset(
hadBirthDefect,
// birthDefect,
// otherDefect,
- weight, breastFeedingStarted, opv0Dose, bcgDose, hepBDose, vitkDose
+ weight, breastFeedingStarted,isSncu //opv0Dose, bcgDose, hepBDose, vitkDose
)
if (deliveryOutcomeCache != null) {
- opv0Dose.min = deliveryOutcomeCache.dateOfDelivery
+ /* opv0Dose.min = deliveryOutcomeCache.dateOfDelivery
bcgDose.min = deliveryOutcomeCache.dateOfDelivery
hepBDose.min = deliveryOutcomeCache.dateOfDelivery
vitkDose.min = deliveryOutcomeCache.dateOfDelivery
@@ -205,7 +248,7 @@ class InfantRegistrationDataset(
vitkDose.max = it + TimeUnit.DAYS.toMillis(1)
}
}
- }
+ }*/
}
if (pwrCache != null && deliveryOutcomeCache != null) {
val weeksOfPregnancy = deliveryOutcomeCache.dateOfDelivery?.let {
@@ -240,27 +283,45 @@ class InfantRegistrationDataset(
otherDefect,
weight,
breastFeedingStarted,
- opv0Dose,
+ isSncu
+ /* opv0Dose,
bcgDose,
hepBDose,
- vitkDose
+ vitkDose*/
)
babyName.value = saved.babyName
- infantTerm.value = saved.infantTerm
- corticosteroidGiven.value = saved.corticosteroidGiven
+ infantTerm.value = getLocalValueInArray(R.array.ir_infant_term, saved.infantTerm)
+ corticosteroidGiven.value = getLocalValueInArray(R.array.ir_confirmation_array3, saved.corticosteroidGiven)
gender.value = saved.gender?.let { gender.entries?.get(it.ordinal) }
- babyCriedAtBirth.value = if (saved.babyCriedAtBirth == true) "Yes" else "No"
- resuscitation.value = if (saved.resuscitation == true) "Yes" else "No"
- referred.value = saved.referred
- hadBirthDefect.value = saved.hadBirthDefect
- birthDefect.value = saved.birthDefect
+ babyCriedAtBirth.value = if (saved.babyCriedAtBirth == true) babyCriedAtBirth.entries!![0] else babyCriedAtBirth.entries!![1]
+ resuscitation.value = if (saved.resuscitation == true) resuscitation.entries!![0] else resuscitation.entries!![1]
+ referred.value = getLocalValueInArray(R.array.ir_confirmation_array2, saved.referred)
+ hadBirthDefect.value = getLocalValueInArray(R.array.ir_confirmation_array2, saved.hadBirthDefect)
+ birthDefect.value = getLocalValueInArray(R.array.ir_birth_defect_array, saved.birthDefect)
otherDefect.value = saved.otherDefect
weight.value = saved.weight.toString()
- breastFeedingStarted.value = if (saved.breastFeedingStarted == true) "Yes" else "No"
- opv0Dose.value = saved.opv0Dose?.let { getDateFromLong(it) }
- bcgDose.value = saved.bcgDose?.let { getDateFromLong(it) }
- hepBDose.value = saved.hepBDose?.let { getDateFromLong(it) }
- vitkDose.value = saved.vitkDose?.let { getDateFromLong(it) }
+ breastFeedingStarted.value = if (saved.breastFeedingStarted == true) breastFeedingStarted.entries!![0] else breastFeedingStarted.entries!![1]
+ isSncu.value = getLocalValueInArray(R.array.do_is_jsy_beneficiary_array, saved.isSNCU)
+ if (saved.isSNCU=="Yes")
+ {
+ deliveryDischargeSummary1.value = saved.deliveryDischargeSummary1
+ deliveryDischargeSummary2.value = saved.deliveryDischargeSummary2
+ deliveryDischargeSummary3.value = saved.deliveryDischargeSummary3
+ deliveryDischargeSummary4.value = saved.deliveryDischargeSummary4
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.add(list.indexOf(isSncu) + 1, deliveryDischargeSummary1)
+ list.add(list.indexOf(deliveryDischargeSummary1) + 1, deliveryDischargeSummary2)
+ list.add(list.indexOf(deliveryDischargeSummary2) + 1, deliveryDischargeSummary3)
+ list.add(list.indexOf(deliveryDischargeSummary3) + 1, deliveryDischargeSummary4)
+ }
+
+
+ }
+
+// opv0Dose.value = saved.opv0Dose?.let { getDateFromLong(it) }
+// bcgDose.value = saved.bcgDose?.let { getDateFromLong(it) }
+// hepBDose.value = saved.hepBDose?.let { getDateFromLong(it) }
+// vitkDose.value = saved.vitkDose?.let { getDateFromLong(it) }
}
setUpPage(list)
@@ -287,6 +348,25 @@ class InfantRegistrationDataset(
)
}
+ isSncu.id -> {
+ val isYes = isSncu.value == isSncu.entries!![0]
+ if(isYes){
+ triggerDependants(
+ source = isSncu,
+ addItems = listOf(deliveryDischargeSummary1,deliveryDischargeSummary2,deliveryDischargeSummary3,deliveryDischargeSummary4),
+ removeItems = emptyList()
+ )
+ }
+ else{
+ triggerDependants(
+ source = isSncu,
+ addItems = emptyList(),
+ removeItems =listOf(deliveryDischargeSummary1,deliveryDischargeSummary2,deliveryDischargeSummary3,deliveryDischargeSummary4),
+ )
+ }
+
+ }
+
birthDefect.id -> {
triggerDependants(
source = birthDefect,
@@ -301,9 +381,7 @@ class InfantRegistrationDataset(
}
weight.id -> {
- validateDoubleUpto1DecimalPlaces(weight)
- if (weight.errorText == null) validateDoubleMinMax(weight)
- -1
+ validateWeightOnEditText(weight)
}
@@ -314,23 +392,60 @@ class InfantRegistrationDataset(
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as InfantRegCache).let { form ->
form.babyName = babyName.value
- form.infantTerm = infantTerm.value
- form.corticosteroidGiven = corticosteroidGiven.value
+ form.infantTerm = getEnglishValueInArray(R.array.ir_infant_term, infantTerm.value)
+ form.corticosteroidGiven = getEnglishValueInArray(R.array.ir_confirmation_array3, corticosteroidGiven.value)
form.gender = gender.value?.let {
Gender.values()[gender.getPosition() - 1]
}
- form.babyCriedAtBirth = babyCriedAtBirth.value == "Yes"
- form.resuscitation = resuscitation.value == "Yes"
- form.referred = referred.value
- form.hadBirthDefect = hadBirthDefect.value
- form.birthDefect = birthDefect.value
+ form.babyCriedAtBirth = babyCriedAtBirth.value == babyCriedAtBirth.entries!![0]
+ form.resuscitation = resuscitation.value == resuscitation.entries!![0]
+ form.referred = getEnglishValueInArray(R.array.ir_confirmation_array2, referred.value)
+
+ form.isSNCU = getEnglishValueInArray(R.array.do_is_jsy_beneficiary_array, isSncu.value) ?: "No"
+ form.deliveryDischargeSummary1 = deliveryDischargeSummary1.value?.takeIf { it.isNotEmpty() }
+ form.deliveryDischargeSummary2 = deliveryDischargeSummary2.value?.takeIf { it.isNotEmpty() }
+ form.deliveryDischargeSummary3 = deliveryDischargeSummary3.value?.takeIf { it.isNotEmpty() }
+ form.deliveryDischargeSummary4 = deliveryDischargeSummary4.value?.takeIf { it.isNotEmpty() }
+
+
+ form.hadBirthDefect = getEnglishValueInArray(R.array.ir_confirmation_array2, hadBirthDefect.value)
+ form.birthDefect = getEnglishValueInArray(R.array.ir_birth_defect_array, birthDefect.value)
form.otherDefect = otherDefect.value
form.weight = weight.value?.toDouble()
- form.breastFeedingStarted = breastFeedingStarted.value == "Yes"
- form.opv0Dose = getLongFromDate(opv0Dose.value)
+ form.breastFeedingStarted = breastFeedingStarted.value == breastFeedingStarted.entries!![0]
+ /* form.opv0Dose = getLongFromDate(opv0Dose.value)
form.bcgDose = getLongFromDate(bcgDose.value)
form.hepBDose = getLongFromDate(hepBDose.value)
- form.vitkDose = getLongFromDate(vitkDose.value)
+ form.vitkDose = getLongFromDate(vitkDose.value)*/
+ }
+ }
+
+
+ fun getIndexDeliveryDischargeSummary1 () = getIndexById(deliveryDischargeSummary1.id)
+ fun getIndexDeliveryDischargeSummary2 () = getIndexById(deliveryDischargeSummary2.id)
+ fun getIndexDeliveryDischargeSummary3 () = getIndexById(deliveryDischargeSummary3.id)
+ fun getIndexDeliveryDischargeSummary4 () = getIndexById(deliveryDischargeSummary4.id)
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ 58 -> {
+ deliveryDischargeSummary1.value = dpUri.toString()
+ deliveryDischargeSummary1.errorText = null
+ }
+ 59 -> {
+ deliveryDischargeSummary2.value = dpUri.toString()
+ deliveryDischargeSummary2.errorText = null
+ }
+ 60 -> {
+ deliveryDischargeSummary3.value = dpUri.toString()
+ deliveryDischargeSummary3.errorText = null
+ }
+ 61 -> {
+ deliveryDischargeSummary4.value = dpUri.toString()
+ deliveryDischargeSummary4.errorText = null
+ }
+
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/KalaAzarFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/KalaAzarFormDataset.kt
new file mode 100644
index 000000000..5e3b2380e
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/KalaAzarFormDataset.kt
@@ -0,0 +1,414 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.KalaAzarScreeningCache
+
+class KalaAzarFormDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.visit_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = false
+
+ )
+ private val beneficiaryStatus = FormElement(
+ id = 2,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.beneficiary_status),
+ arrayId = R.array.benificary_case_status_kalaazar,
+ entries = resources.getStringArray(R.array.benificary_case_status_kalaazar),
+ required = true,
+ hasDependants = true
+
+ )
+ private val dateOfDeath = FormElement(
+ id = 3,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.death_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+ private val placeOfDeath = FormElement(
+ id = 4,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_Death),
+ arrayId = R.array.death_place,
+ entries = resources.getStringArray(R.array.death_place),
+ required = true,
+ hasDependants = true
+
+ )
+
+ private var otherPlaceOfDeath = FormElement(
+ id = 5,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_place),
+ required = true,
+ hasDependants = false
+ )
+
+ private val reasonOfDeath = FormElement(
+ id = 6,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.reason_of_Death),
+ arrayId = R.array.reason_death,
+ entries = resources.getStringArray(R.array.reason_death),
+ required = true,
+ hasDependants = true
+
+ )
+ private var otherReasonOfDeath = FormElement(
+ id = 7,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_reason),
+ required = true,
+ hasDependants = false
+ )
+
+
+ private val caseStatus = FormElement(
+ id = 8,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.case_status),
+ arrayId = R.array.dc_case_status,
+ entries = resources.getStringArray(R.array.dc_case_status),
+ required = false,
+ hasDependants = true
+
+ )
+ private var rapidDiagnostic = FormElement(
+ id = 9,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.rapid_diagnostic_kala),
+ arrayId = R.array.positive_negative,
+ entries = resources.getStringArray(R.array.positive_negative),
+ required = false,
+ hasDependants = true
+ )
+
+ private val dateOfTest = FormElement(
+ id = 10,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.test_up_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ hasDependants = true
+
+ )
+ private var followUpPoint = FormElement(
+ id = 11,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.follow_up),
+ arrayId = R.array.follow_up_array,
+ entries = resources.getStringArray(R.array.follow_up_array),
+ required = false,
+ hasDependants = true
+ )
+
+ private var referredTo = FormElement(
+ id = 12,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.refer_to),
+ arrayId = R.array.dc_refer,
+ entries = resources.getStringArray(R.array.dc_refer),
+ required = false,
+ hasDependants = true
+ )
+ private var other = FormElement(
+ id = 13,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other),
+ required = true,
+ hasDependants = false
+ )
+
+
+
+
+
+
+ suspend fun setUpPage(ben: BenRegCache?, saved: KalaAzarScreeningCache?) {
+ val list = mutableListOf(
+ dateOfCase,
+ beneficiaryStatus,
+ )
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ beneficiaryStatus.value = resources.getStringArray(R.array.benificary_case_status_kalaazar)[0]
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[0]
+ } else {
+
+ dateOfCase.value = getDateFromLong(saved.visitDate)
+
+ rapidDiagnostic.value = getLocalValueInArray(R.array.positive_negative, saved.rapidDiagnosticTest)
+ ?: resources.getStringArray(R.array.positive_negative)[2]
+
+ val caseStatusArray = resources.getStringArray(R.array.dc_case_status)
+ if (saved.kalaAzarCaseStatus == "Suspected") {
+ caseStatus.entries = caseStatusArray
+ .filter { it == caseStatusArray[1] || it == caseStatusArray[2] }
+ .toTypedArray()
+ } else if (saved.kalaAzarCaseStatus == "Confirmed") {
+ caseStatus.entries = caseStatusArray
+ .filter { it == caseStatusArray[3] }
+ .toTypedArray()
+ } else {
+ caseStatus.entries = caseStatusArray
+ }
+ if (saved.kalaAzarCaseStatus != null) {
+ caseStatus.value =
+ getLocalValueInArray(R.array.dc_case_status, saved.kalaAzarCaseStatus)
+ }
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ referredTo.value = saved.referToName
+ list.add(list.indexOf(referredTo) + 1, other)
+ } else {
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ }
+ beneficiaryStatus.value =
+ getLocalValueInArray(beneficiaryStatus.arrayId, saved.beneficiaryStatus)
+ other.value = saved.otherReferredFacility
+ if (beneficiaryStatus.value == beneficiaryStatus.entries!![beneficiaryStatus.entries!!.size - 2]) {
+ list.add(list.indexOf(beneficiaryStatus) + 1, dateOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 2, placeOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 3, reasonOfDeath)
+ dateOfDeath.value =
+ getDateFromLong(saved.dateOfDeath)
+ placeOfDeath.value =
+ getLocalValueInArray(placeOfDeath.arrayId, saved.placeOfDeath)
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ otherPlaceOfDeath.value = saved.otherPlaceOfDeath
+ }
+
+ reasonOfDeath.value =
+ getLocalValueInArray(reasonOfDeath.arrayId, saved.reasonForDeath)
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ list.add(list.indexOf(reasonOfDeath) + 1, otherReasonOfDeath)
+ otherReasonOfDeath.value = saved.otherReasonForDeath
+ }
+ } else {
+ list.add(list.indexOf(beneficiaryStatus) + 1, caseStatus)
+ list.add(list.indexOf(beneficiaryStatus) + 2, rapidDiagnostic)
+ list.add(list.indexOf(beneficiaryStatus) + 3, followUpPoint)
+ list.add(list.indexOf(beneficiaryStatus) + 4, referredTo)
+ if (rapidDiagnostic.value != resources.getStringArray(R.array.positive_negative)[2]) {
+ list.add(list.indexOf(rapidDiagnostic) + 1, dateOfTest)
+ dateOfTest.value = getDateFromLong(saved.dateOfRdt)
+ }
+
+
+
+ }
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ referredTo.value = saved.referToName
+ list.add(list.indexOf(referredTo) + 1, other)
+ } else {
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ }
+
+ other.value = saved.otherReferredFacility
+ }
+
+
+ setUpPage(list)
+
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ beneficiaryStatus.id -> {
+ if (beneficiaryStatus.value == beneficiaryStatus.entries!![beneficiaryStatus.entries!!.size - 2]
+ ) {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(dateOfDeath, placeOfDeath, reasonOfDeath),
+ removeItems = listOf(
+ caseStatus, rapidDiagnostic,followUpPoint, referredTo,
+ )
+ )
+ } else {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(
+ caseStatus, rapidDiagnostic, referredTo
+ ),
+ removeItems = listOf(dateOfDeath, placeOfDeath, reasonOfDeath,otherPlaceOfDeath,otherReasonOfDeath)
+ )
+ }
+ 0
+ }
+
+ other.id -> {
+ validateEmptyOnEditText(other)
+ }
+
+ referredTo.id -> {
+ if (referredTo.value == referredTo.entries!!.last()) {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(other),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(),
+ removeItems = listOf(other)
+ )
+ }
+ 0
+ }
+
+ placeOfDeath.id -> {
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(otherPlaceOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherPlaceOfDeath)
+ )
+ }
+ 0
+ }
+
+ otherPlaceOfDeath.id -> {
+ validateEmptyOnEditText(otherPlaceOfDeath)
+ }
+
+ rapidDiagnostic.id -> {
+ if (rapidDiagnostic.value == resources.getStringArray(R.array.positive_negative)[2]) {
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(),
+ removeItems = listOf(dateOfTest)
+ )
+ caseStatus.value =
+ getLocalValueInArray(
+ caseStatus.arrayId,
+ resources.getStringArray(R.array.dc_case_status)[0]
+ )
+ } else if (rapidDiagnostic.value == resources.getStringArray(R.array.positive_negative)[1]) {
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(dateOfTest),
+ removeItems = listOf()
+ )
+ caseStatus.value =
+ getLocalValueInArray(
+ caseStatus.arrayId,
+ resources.getStringArray(R.array.dc_case_status)[1]
+ )
+ } else {
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(dateOfTest),
+ removeItems = listOf()
+ )
+ caseStatus.value =
+ getLocalValueInArray(
+ caseStatus.arrayId,
+ resources.getStringArray(R.array.dc_case_status)[0]
+ )
+ }
+ 0
+ }
+
+
+ reasonOfDeath.id -> {
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(otherReasonOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherReasonOfDeath)
+ )
+ }
+ 0
+ }
+ otherReasonOfDeath.id -> {
+ validateEmptyOnEditText(otherReasonOfDeath)
+ }
+
+ else -> {
+ 0
+ }
+ }
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as KalaAzarScreeningCache).let { form ->
+ form.visitDate = getLongFromDate(dateOfCase.value)
+ form.referToName = getEnglishValueInArray(R.array.dc_refer, referredTo.value)
+ form.referredTo = referredTo.getPosition()
+ form.beneficiaryStatus = getEnglishValueInArray(R.array.benificary_case_status_kalaazar, beneficiaryStatus.value)
+ form.beneficiaryStatusId = beneficiaryStatus.getPosition()
+ form.reasonForDeath = getEnglishValueInArray(R.array.reason_death, reasonOfDeath.value)
+ form.kalaAzarCaseStatus = getEnglishValueInArray(R.array.dc_case_status, caseStatus.value)
+ form.otherPlaceOfDeath = otherPlaceOfDeath.value
+ form.otherReasonForDeath = otherReasonOfDeath.value
+ form.dateOfDeath = getLongFromDate(dateOfDeath.value)
+ form.dateOfRdt = getLongFromDate(dateOfTest.value)
+ form.placeOfDeath = getEnglishValueInArray(R.array.death_place, placeOfDeath.value)
+ form.otherReferredFacility = other.value
+ form.rapidDiagnosticTest = getEnglishValueInArray(R.array.positive_negative, rapidDiagnostic.value)
+ form.diseaseTypeID = 2
+ form.createdDate = getLongFromDate(dateOfCase.value)
+ form.followUpPoint = followUpPoint.value?.toIntOrNull() ?: 0
+
+ }
+ }
+
+
+
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosyConfirmedDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosyConfirmedDataset.kt
new file mode 100644
index 000000000..eea646909
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosyConfirmedDataset.kt
@@ -0,0 +1,694 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.widget.Toast
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.LeprosyFollowUpCache
+import org.piramalswasthya.sakhi.model.LeprosyScreeningCache
+import java.util.Calendar
+
+class LeprosyConfirmedDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private var homeVisitDateLong: Long = System.currentTimeMillis()
+ private var treatmentStartDateLong: Long = 0L
+ private var lastFollowUpDateLong: Long = 0L
+ private var isNewFollowUp: Boolean = false
+ private var nextFollowUpMonthStart: Long = 0L
+ private var nextFollowUpMonthEnd: Long = 0L
+ private var context = context
+
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.home_visit_date),
+ arrayId = -1,
+ required = false,
+ max = System.currentTimeMillis(),
+ hasDependants = true,
+ isEnabled = false
+ )
+
+ private val leprosyStatus = FormElement(
+ id = 8,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.str_leprosy_status),
+ arrayId = R.array.leprosy_status,
+ entries = resources.getStringArray(R.array.leprosy_status),
+ required = false,
+ hasDependants = true,
+ isEnabled = false
+ )
+
+ private var referredTo = FormElement(
+ id = 9,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.refer_to),
+ arrayId = R.array.dc_refer,
+ entries = resources.getStringArray(R.array.dc_refer),
+ required = false,
+ hasDependants = true,
+ isEnabled = false
+ )
+ private var other = FormElement(
+ id = 10,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other),
+ required = false,
+ hasDependants = false
+ )
+
+ private val followUpdate = FormElement(
+ id = 12,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.follow_up_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ hasDependants = true
+ )
+
+ private val remarks = FormElement(
+ id = 13,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.pnc_remarks),
+ required = false,
+ isEnabled = false
+ )
+
+ private val leprosySymptoms = FormElement(
+ id = 14,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.any_leprosy_symptoms_present),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = false,
+ isEnabled = false
+ )
+
+ private val visitLabel = FormElement(
+ id = 15,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.visits),
+ required = false,
+ isEnabled = false
+ )
+
+ private val typeOfLeprosy = FormElement(
+ id = 16,
+ inputType = InputType.RADIO,
+ isEnabled = false,
+ required = false,
+ title = resources.getString(R.string.type_of_leprocy),
+ arrayId = R.array.type_of_leprocy,
+ entries = resources.getStringArray(R.array.type_of_leprocy),
+ hasDependants = true
+ )
+
+ private val treatmentStartDate = FormElement(
+ id = 17,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.treatment_start_date),
+ required = true,
+ isEnabled = true,
+ hasDependants = true,
+ max = System.currentTimeMillis(),
+ )
+
+ private val mdt_blister_pack_recived = FormElement(
+ id = 18,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.mdt_blister_pack_received),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ isEnabled = true,
+ )
+
+ private val treatmentStatus = FormElement(
+ id = 19,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.treatment_status),
+ arrayId = R.array.leprosy_treatment_status_before_time,
+ entries = resources.getStringArray(R.array.leprosy_treatment_status_before_time),
+ required = true,
+ isEnabled = true,
+ )
+
+ private val treatmentEndDate = FormElement(
+ id = 20,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.actual_treatment_completion_date),
+ required = true,
+ isEnabled = true,
+ max = System.currentTimeMillis(),
+ )
+
+ private val treatmentEndDateEstimation = FormElement(
+ id = 21,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.expected_treatment_completion_date),
+ required = false,
+ isEnabled = false,
+ hasDependants = true,
+ max = System.currentTimeMillis(),
+ )
+
+
+ suspend fun setUpPage(
+ ben: BenRegCache?,
+ saved: LeprosyScreeningCache?,
+ followUp: LeprosyFollowUpCache?
+ ) {
+ val list = mutableListOf(
+ dateOfCase,
+ leprosySymptoms,
+ visitLabel,
+ leprosyStatus,
+ referredTo,
+ typeOfLeprosy,
+ treatmentStartDate,
+ treatmentEndDateEstimation,
+ followUpdate,
+ mdt_blister_pack_recived,
+
+ )
+
+ homeVisitDateLong = saved?.homeVisitDate ?: System.currentTimeMillis()
+ treatmentStartDateLong =
+ saved?.treatmentStartDate?.takeIf { it > 0L } ?: followUp?.treatmentStartDate ?: 0L
+ lastFollowUpDateLong = followUp?.followUpDate ?: 0L
+ // isNewFollowUp = followUp == null
+
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[0]
+ visitLabel.value = resources.getString(R.string.visit_number_label, saved?.currentVisitNumber ?: 1)
+ leprosySymptoms.value = resources.getStringArray(R.array.yes_no)[1]
+
+ updateDateConstraints()
+ checkFollowUpDateAvailability()
+ calculateAndSetExpectedCompletionDate()
+
+ } else {
+ dateOfCase.value = getDateFromLong(saved.homeVisitDate)
+ leprosySymptoms.value =
+ getLocalValueInArray(leprosySymptoms.arrayId, saved.leprosySymptoms)
+ typeOfLeprosy.value = getLocalValueInArray(typeOfLeprosy.arrayId, saved.typeOfLeprosy)
+ treatmentStartDate.value = getDateFromLong(treatmentStartDateLong)
+ val symptomsPosition = saved.leprosySymptomsPosition ?: 1
+ leprosySymptoms.value =
+ resources.getStringArray(R.array.yes_no).getOrNull(symptomsPosition)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ val visit_value = saved.visitLabel
+ val visitNum = visit_value?.substringAfterLast("-")?.toIntOrNull() ?: 1
+ visitLabel.value = resources.getString(R.string.visit_number_label, visitNum)
+ leprosyStatus.value = getLocalValueInArray(leprosyStatus.arrayId, saved.leprosyStatus)
+
+ if (leprosyStatus.value == leprosyStatus.entries!!.last()) {
+ leprosyStatus.value = saved.leprosyStatus
+ list.add(list.indexOf(leprosyStatus) + 1, other)
+ } else {
+ leprosyStatus.value =
+ getLocalValueInArray(leprosyStatus.arrayId, saved.leprosyStatus)
+ }
+
+ remarks.value = saved.remarks
+ referredTo.value = getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ referredTo.value = saved.referToName
+ list.add(list.indexOf(referredTo) + 1, other)
+ } else {
+ referredTo.value = getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ }
+ treatmentStartDate.value = getDateFromLong(treatmentStartDateLong)
+
+ other.value = saved.otherReferredTo
+
+ updateDateConstraints()
+ checkFollowUpDateAvailability()
+ calculateAndSetExpectedCompletionDate()
+
+
+ }
+
+ if (followUp == null) {
+ visitLabel.value = resources.getString(R.string.visit_number_label, saved?.currentVisitNumber ?: 1)
+ // followUpdate.value = getDateFromLong(System.currentTimeMillis())
+ isNewFollowUp = true
+ } else {
+ isNewFollowUp = false
+ visitLabel.value = resources.getString(R.string.visit_number_label, saved?.currentVisitNumber ?: 1)
+ // followUpdate.value = getDateFromLong(followUp.followUpDate)
+ mdt_blister_pack_recived.value = getLocalValueInArray(
+ mdt_blister_pack_recived.arrayId,
+ followUp.mdtBlisterPackReceived
+ )
+ treatmentStatus.value = getLocalValueInArray(
+ treatmentStatus.arrayId,
+ followUp.treatmentStatus
+ )
+
+ if (followUp.treatmentCompleteDate > 0) {
+ treatmentEndDate.value = getDateFromLong(followUp.treatmentCompleteDate)
+ list.add(list.indexOf(treatmentStatus) + 1, treatmentEndDate)
+ }
+
+ remarks.value = followUp.remarks
+
+ updateDateConstraints()
+ checkFollowUpDateAvailability()
+ calculateAndSetExpectedCompletionDate()
+ }
+
+ setUpPage(list)
+ }
+
+ suspend fun setUpPage(ben: BenRegCache?, followUp: LeprosyFollowUpCache?) {
+ val list = mutableListOf(
+ dateOfCase,
+ leprosySymptoms,
+ visitLabel,
+ leprosyStatus,
+ referredTo,
+ typeOfLeprosy,
+ treatmentStartDate,
+ followUpdate,
+ mdt_blister_pack_recived,
+ treatmentStatus,
+ )
+
+ dateOfCase.isEnabled = false
+ leprosyStatus.isEnabled = false
+ visitLabel.isEnabled = false
+ leprosySymptoms.isEnabled = false
+ referredTo.isEnabled = false
+ typeOfLeprosy.isEnabled = false
+ treatmentStartDate.isEnabled = false
+ followUpdate.isEnabled = false
+ mdt_blister_pack_recived.isEnabled = false
+ treatmentStatus.isEnabled = false
+
+ homeVisitDateLong = followUp?.homeVisitDate ?: System.currentTimeMillis()
+ treatmentStartDateLong = followUp?.treatmentStartDate ?: 0L
+ lastFollowUpDateLong = followUp?.followUpDate ?: 0L
+
+ treatmentStatus.arrayId = R.array.leprosy_treatment_status
+ treatmentStatus.entries = resources.getStringArray(R.array.leprosy_treatment_status)
+ if (followUp == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[0]
+ visitLabel.value = resources.getString(R.string.visit_number_label, 1)
+ leprosySymptoms.value = resources.getStringArray(R.array.yes_no)[1]
+ isNewFollowUp = true
+ updateDateConstraints()
+ } else {
+ isNewFollowUp = false
+ dateOfCase.value = getDateFromLong(followUp.homeVisitDate)
+ leprosySymptoms.value =
+ getLocalValueInArray(leprosySymptoms.arrayId, followUp.leprosySymptoms)
+ typeOfLeprosy.value =
+ getLocalValueInArray(typeOfLeprosy.arrayId, followUp.typeOfLeprosy)
+ treatmentStartDate.value = getDateFromLong(followUp.treatmentStartDate)
+ val symptomsPosition = followUp.leprosySymptomsPosition ?: 1
+ leprosySymptoms.value =
+ resources.getStringArray(R.array.yes_no).getOrNull(symptomsPosition)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ val visit_value = followUp.visitLabel
+ val visitNum = visit_value?.substringAfterLast("-")?.toIntOrNull() ?: 1
+ visitLabel.value = resources.getString(R.string.visit_number_label, visitNum)
+ leprosyStatus.value =
+ getLocalValueInArray(leprosyStatus.arrayId, followUp.leprosyStatus)
+
+ if (leprosyStatus.value == leprosyStatus.entries!!.last()) {
+ leprosyStatus.value = followUp.leprosyStatus
+ list.add(list.indexOf(leprosyStatus) + 1, other)
+ } else {
+ leprosyStatus.value =
+ getLocalValueInArray(leprosyStatus.arrayId, followUp.leprosyStatus)
+ }
+
+ remarks.value = followUp.remarks
+ referredTo.value = getLocalValueInArray(referredTo.arrayId, followUp.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ referredTo.value = followUp.referToName
+ list.add(list.indexOf(referredTo) + 1, other)
+ } else {
+ referredTo.value = getLocalValueInArray(referredTo.arrayId, followUp.referToName)
+ }
+ treatmentStartDate.value = getDateFromLong(followUp.treatmentStartDate)
+ followUpdate.value = getDateFromLong(followUp.followUpDate)
+ mdt_blister_pack_recived.value = getLocalValueInArray(
+ mdt_blister_pack_recived.arrayId,
+ followUp.mdtBlisterPackReceived
+ )
+
+ treatmentStatus.value = getLocalValueInArray(
+ treatmentStatus.arrayId,
+ followUp.treatmentStatus
+ )
+
+ if (followUp.treatmentCompleteDate > 0) {
+ treatmentEndDate.value = getDateFromLong(followUp.treatmentCompleteDate)
+ list.add(list.indexOf(treatmentStatus) + 1, treatmentEndDate)
+ }
+
+ updateDateConstraints()
+ }
+
+ setUpPage(list)
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ when (formId) {
+ treatmentStatus.id -> {
+
+ if (treatmentStatus.value == treatmentStatus.entries!!.last()) {
+ triggerDependants(
+ source = treatmentStatus,
+ addItems = listOf(treatmentEndDate),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = treatmentStatus,
+ addItems = listOf(),
+ removeItems = listOf(treatmentEndDate)
+ )
+ }
+ }
+
+ treatmentStartDate.id -> {
+ treatmentStartDateLong = getLongFromDate(treatmentStartDate.value)
+ calculateAndSetExpectedCompletionDate()
+ followUpdate.min = treatmentStartDateLong
+ followUpdate.isEnabled = true
+
+ }
+
+ followUpdate.id -> {
+ // lastFollowUpDateLong = getLongFromDate(followUpdate.value)
+ updateTreatmentStatusDropdown()
+ triggerDependants(
+ source = followUpdate,
+ addItems = listOf(treatmentStatus),
+ removeItems = listOf()
+ )
+
+
+ }
+
+ }
+ return 0
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as LeprosyFollowUpCache).let { followUp ->
+ followUp.followUpDate = getLongFromDate(followUpdate.value)
+ followUp.mdtBlisterPackReceived = getEnglishValueInArray(R.array.yes_no, mdt_blister_pack_recived.value)
+ followUp.treatmentStatus = getEnglishValueInArray(treatmentStatus.arrayId, treatmentStatus.value)
+ followUp.treatmentStartDate = getLongFromDate(treatmentStartDate.value)
+
+ if (treatmentStatus.value == treatmentStatus.entries?.last()) {
+ followUp.treatmentCompleteDate = getLongFromDate(treatmentEndDate.value)
+ } else {
+ followUp.treatmentCompleteDate = 0
+ }
+
+ followUp.remarks = remarks.value
+ }
+ }
+
+
+ private fun calculateAndSetExpectedCompletionDate() {
+ if (treatmentStartDateLong == 0L) {
+ treatmentEndDateEstimation.value = ""
+ return
+ }
+
+ val typeOfLeprosyValue = typeOfLeprosy.value
+ if (typeOfLeprosyValue.isNullOrBlank()) {
+ treatmentEndDateEstimation.value = ""
+ return
+ }
+
+ val leprosyTypes = resources.getStringArray(R.array.type_of_leprocy)
+ val index = leprosyTypes.indexOf(typeOfLeprosyValue)
+
+ val monthsToAdd = when (index) {
+ 0 -> 12
+ 1 -> 6
+ else -> {
+ treatmentEndDateEstimation.value = ""
+ return
+ }
+ }
+
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = treatmentStartDateLong
+ calendar.add(Calendar.MONTH, monthsToAdd)
+
+ treatmentEndDateEstimation.value = getDateFromLong(calendar.timeInMillis)
+ }
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(followUpdate.id)
+ }
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+ private fun getFirstDayOfNextMonth(date: Long): Long {
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = date
+ calendar.set(Calendar.DAY_OF_MONTH, 1)
+ calendar.add(Calendar.MONTH, 1)
+ calendar.set(Calendar.HOUR_OF_DAY, 0)
+ calendar.set(Calendar.MINUTE, 0)
+ calendar.set(Calendar.SECOND, 0)
+ calendar.set(Calendar.MILLISECOND, 0)
+ return calendar.timeInMillis
+ }
+
+ private fun getLastDayOfNextMonth(date: Long): Long {
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = date
+ calendar.set(Calendar.DAY_OF_MONTH, 1)
+ calendar.add(Calendar.MONTH, 2)
+ calendar.add(Calendar.DAY_OF_MONTH, -1)
+ calendar.set(Calendar.HOUR_OF_DAY, 23)
+ calendar.set(Calendar.MINUTE, 59)
+ calendar.set(Calendar.SECOND, 59)
+ calendar.set(Calendar.MILLISECOND, 999)
+ return calendar.timeInMillis
+ }
+
+ private fun isSameMonth(date1: Long, date2: Long): Boolean {
+ val cal1 = Calendar.getInstance()
+ val cal2 = Calendar.getInstance()
+ cal1.timeInMillis = date1
+ cal2.timeInMillis = date2
+ return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
+ cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
+ }
+
+ private fun isSameOrAfterMonth(date1: Long, date2: Long): Boolean {
+ val cal1 = Calendar.getInstance()
+ val cal2 = Calendar.getInstance()
+
+ cal1.timeInMillis = date1
+ cal2.timeInMillis = date2
+
+ val year1 = cal1.get(Calendar.YEAR)
+ val year2 = cal2.get(Calendar.YEAR)
+
+ val month1 = cal1.get(Calendar.MONTH)
+ val month2 = cal2.get(Calendar.MONTH)
+
+ return when {
+ year1 > year2 -> true
+ year1 == year2 && month1 >= month2 -> true
+ else -> false
+ }
+ }
+
+ private fun getFirstDayOfCurrentMonth(): Long {
+ val calendar = Calendar.getInstance()
+ calendar.set(Calendar.DAY_OF_MONTH, 1)
+ calendar.set(Calendar.HOUR_OF_DAY, 0)
+ calendar.set(Calendar.MINUTE, 0)
+ calendar.set(Calendar.SECOND, 0)
+ calendar.set(Calendar.MILLISECOND, 0)
+ return calendar.timeInMillis
+ }
+
+ private fun updateTreatmentStatusDropdown() {
+ val followUpDateLong = getLongFromDate(followUpdate.value)
+ val expectedEndDateLong = getLongFromDate(treatmentEndDateEstimation.value)
+
+ if (followUpDateLong > 0 && expectedEndDateLong > 0 &&
+ isSameOrAfterMonth(followUpDateLong, expectedEndDateLong)
+ ) {
+ treatmentStatus.arrayId = R.array.leprosy_treatment_status
+ treatmentStatus.entries =
+ resources.getStringArray(R.array.leprosy_treatment_status)
+ } else {
+ treatmentStatus.arrayId = R.array.leprosy_treatment_status_before_time
+ treatmentStatus.entries =
+ resources.getStringArray(R.array.leprosy_treatment_status_before_time)
+ }
+
+ if (!treatmentStatus.entries!!.contains(treatmentStatus.value)) {
+ treatmentStatus.value = ""
+ }
+ }
+
+
+ private fun checkFollowUpDateAvailability() {
+ val currentTime = System.currentTimeMillis()
+ if (treatmentStartDateLong == 0L) {
+ followUpdate.isEnabled = false
+ return
+ }
+ if (lastFollowUpDateLong == 0L) {
+ followUpdate.isEnabled = true
+ return
+ }
+
+ nextFollowUpMonthStart = getFirstDayOfNextMonth(lastFollowUpDateLong)
+ nextFollowUpMonthEnd = getLastDayOfNextMonth(lastFollowUpDateLong)
+
+ if (currentTime < nextFollowUpMonthStart) {
+ followUpdate.isEnabled = false
+ Toast.makeText(
+ context,
+ "Next follow-up will be available from ${getDateFromLong(nextFollowUpMonthStart)}",
+ Toast.LENGTH_LONG
+ ).show()
+ } else if (currentTime >= nextFollowUpMonthStart && currentTime <= nextFollowUpMonthEnd) {
+ followUpdate.isEnabled = true
+ // followUpdate.errorMessage = null
+ } else {
+ followUpdate.isEnabled = true
+ }
+ }
+
+ fun validateFollowUpDate(selectedDate: Long): String? {
+ if (lastFollowUpDateLong == 0L) {
+ if (selectedDate < homeVisitDateLong) {
+ return "Follow-up date cannot be before home visit date"
+ }
+ if (selectedDate > System.currentTimeMillis()) {
+ return "Follow-up date cannot be in the future"
+ }
+ return null
+ }
+
+ val nextMonthStart = getFirstDayOfNextMonth(lastFollowUpDateLong)
+ val currentTime = System.currentTimeMillis()
+
+ /* if (selectedDate < nextMonthStart) {
+ return "Next follow-up must be in the next month. Please select a date from ${getDateFromLong(nextMonthStart)}"
+ }*/
+
+ if (selectedDate > currentTime) {
+ return "Follow-up date cannot be in the future"
+ }
+
+ /* if (!isSameOrAfterMonth(selectedDate, nextMonthStart)) {
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = nextMonthStart
+ val monthName = getMonthName(cal.get(Calendar.MONTH))
+ return "Follow-up must be in $monthName. Please select a date between ${getDateFromLong(nextMonthStart)} and ${getDateFromLong(getLastDayOfNextMonth(lastFollowUpDateLong))}"
+ }*/
+
+ return null
+ }
+
+ private fun getMonthName(month: Int): String {
+ val monthNames = arrayOf(
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+ )
+ return monthNames.getOrElse(month) { "Unknown" }
+ }
+
+
+ fun validateForm(): String? {
+ if (followUpdate.value!!.isBlank()) {
+ return "Follow-up date is required"
+ }
+
+ val selectedDate = getLongFromDate(followUpdate.value)
+ val dateValidation = validateFollowUpDate(selectedDate)
+ if (dateValidation != null) {
+ return dateValidation
+ }
+
+ if (treatmentStatus.value!!.isBlank()) {
+ return "Treatment status is required"
+ }
+
+ if (treatmentStatus.value == treatmentStatus.entries?.last() && treatmentEndDate.value!!.isBlank()) {
+ return "Treatment end date is required when treatment status is completed"
+ }
+
+ return null
+ }
+
+
+ private fun updateDateConstraints() {
+ treatmentStartDate.min = homeVisitDateLong
+ if (treatmentStartDateLong > 0) {
+ treatmentStartDate.isEnabled = false
+ treatmentStartDate.required = false
+
+ } else {
+ followUpdate.isEnabled = false
+ return
+ }
+
+ if (lastFollowUpDateLong > 0) {
+ val nextMonthStart = getFirstDayOfNextMonth(lastFollowUpDateLong)
+ followUpdate.min = nextMonthStart
+ followUpdate.max = System.currentTimeMillis()
+ } else {
+ followUpdate.min = treatmentStartDateLong
+ followUpdate.max = System.currentTimeMillis()
+ }
+
+ val followUpDateLong = getLongFromDate(followUpdate.value)
+ treatmentEndDate.min = if (followUpDateLong > 0) followUpDateLong else followUpdate.min
+ }
+
+
+ fun getNextFollowUpAvailabilityMessage(): String? {
+ if (lastFollowUpDateLong == 0L) {
+ return null
+ }
+
+ val nextMonthStart = getFirstDayOfNextMonth(lastFollowUpDateLong)
+ val currentTime = System.currentTimeMillis()
+
+ if (currentTime < nextMonthStart) {
+ return "Next follow-up will be available from ${getDateFromLong(nextMonthStart)}"
+ }
+
+ return null
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosyFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosyFormDataset.kt
new file mode 100644
index 000000000..861bd5f3c
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosyFormDataset.kt
@@ -0,0 +1,721 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.room.SyncState
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.LeprosyScreeningCache
+import java.util.Calendar
+
+class LeprosyFormDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private fun getOneYearBeforeCurrentDate(): Long {
+ val calendar = Calendar.getInstance()
+ calendar.add(Calendar.YEAR, -1)
+ calendar.set(Calendar.HOUR_OF_DAY, 0)
+ calendar.set(Calendar.MINUTE, 0)
+ calendar.set(Calendar.SECOND, 0)
+ calendar.set(Calendar.MILLISECOND, 0)
+ return calendar.timeInMillis
+ }
+
+ private val title = FormElement(
+ id = 28,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.leprosy_title),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.home_visit_date_screening),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = getOneYearBeforeCurrentDate(),
+ hasDependants = true
+
+ )
+ private val beneficiaryStatus = FormElement(
+ id = 2,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.beneficiary_status),
+ arrayId = R.array.benificary_case_status_leprosy,
+ entries = resources.getStringArray(R.array.benificary_case_status_leprosy),
+ required = true,
+ hasDependants = true
+
+ )
+ private val dateOfDeath = FormElement(
+ id = 3,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.death_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+ private val placeOfDeath = FormElement(
+ id = 4,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_Death),
+ arrayId = R.array.death_place,
+ entries = resources.getStringArray(R.array.death_place),
+ required = true,
+ hasDependants = true
+
+ )
+
+ private var otherPlaceOfDeath = FormElement(
+ id = 5,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_place),
+ required = true,
+ hasDependants = false
+ )
+
+ private val reasonOfDeath = FormElement(
+ id = 6,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.reason_of_Death),
+ arrayId = R.array.reason_death,
+ entries = resources.getStringArray(R.array.reason_death),
+ required = true,
+ hasDependants = true
+
+ )
+ private var otherReasonOfDeath = FormElement(
+ id = 7,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_reason),
+ required = true,
+ hasDependants = false
+ )
+ private val leprosyStatus = FormElement(
+ id = 8,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.str_leprosy_status),
+ arrayId = R.array.leprosy_status,
+ entries = resources.getStringArray(R.array.leprosy_status),
+ required = false,
+ isEnabled = false,
+ hasDependants = true
+
+ )
+
+ private var referredTo = FormElement(
+ id = 9,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.refer_to),
+ arrayId = R.array.dc_refer,
+ entries = resources.getStringArray(R.array.dc_refer),
+ required = false,
+ hasDependants = true
+ )
+ private var other = FormElement(
+ id = 10,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other),
+ required = true,
+ hasDependants = false
+ )
+ private var typeOfLeprosy = FormElement(
+ id = 11,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.type_of_leprocy),
+ arrayId = R.array.type_of_leprocy,
+ entries = resources.getStringArray(R.array.type_of_leprocy),
+ required = false,
+ hasDependants = true
+ )
+
+ private val followUpdate = FormElement(
+ id = 12,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.follow_up_date),
+ arrayId = -1,
+ required = false,
+ max = System.currentTimeMillis(),
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ hasDependants = true
+
+ )
+ private val remarks = FormElement(
+ id = 13,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.pnc_remarks),
+ required = false,
+
+ )
+
+ private val recurrentUlceration = FormElement(
+ id = 16,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_recurrent_ulceration),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+
+ private val cbacRecurrentTingling = FormElement(
+ id = 17,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_recurrent_tingling),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacAnyHyperPigmented = FormElement(
+ id = 18,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_Any_hyper_pigmented),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+
+ private val cbacAnyThickendSkin = FormElement(
+ id = 19,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_any_thickend_skin),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacAnyNodulesSkin = FormElement(
+ id = 20,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_any_nodules_skin),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacRecurrentNumbness = FormElement(
+ id = 21,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_Recurrent_numbness),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacClawingOfFingers = FormElement(
+ id = 22,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_Clawing_of_fingers),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacTinglingOrNumbness = FormElement(
+ id = 23,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_Tingling_or_Numbness),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacInabilityCloseEyelid = FormElement(
+ id = 24,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_Inability_close_eyelid),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacDiffHoldingObjects = FormElement(
+ id = 25,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_diff_holding_objects),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+ private val cbacWeeknessInFeet = FormElement(
+ id = 26,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.cbac_Weekness_in_feet),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+
+ private val leprosySymptoms = FormElement(
+ id = 14,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.any_leprosy_symptoms_present),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = true
+ )
+
+ private val visitLabel = FormElement(
+ id = 15,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.visit_leprosy),
+ required = true,
+ isEnabled = false
+ )
+
+ suspend fun setUpPage(ben: BenRegCache?, saved: LeprosyScreeningCache?) {
+ val list = mutableListOf(
+ dateOfCase,
+ // beneficiaryStatus,
+ title,
+ recurrentUlceration,
+ cbacRecurrentTingling,
+ cbacAnyHyperPigmented,
+ cbacAnyThickendSkin,
+ cbacAnyNodulesSkin,
+ cbacRecurrentNumbness,
+ cbacClawingOfFingers,
+ cbacTinglingOrNumbness,
+ cbacInabilityCloseEyelid,
+ cbacDiffHoldingObjects,
+ cbacWeeknessInFeet,
+ leprosySymptoms,
+ visitLabel,
+ leprosyStatus,
+
+
+ )
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[0]
+ visitLabel.value = resources.getString(R.string.visit_number_label, 1)
+ leprosySymptoms.value = resources.getStringArray(R.array.yes_no)[1]
+ } else {
+ dateOfCase.value = getDateFromLong(saved.homeVisitDate)
+ val symptomsPosition = saved.leprosySymptomsPosition ?: 1
+ leprosySymptoms.value = resources.getStringArray(R.array.yes_no).getOrNull(symptomsPosition)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ visitLabel.value = resources.getString(R.string.visit_number_label, saved?.currentVisitNumber ?: 1)
+ leprosyStatus.value =
+ getLocalValueInArray(leprosyStatus.arrayId, saved.leprosyStatus)
+
+ if (leprosyStatus.value == leprosyStatus.entries!!.last()) {
+ leprosyStatus.value = saved.leprosyStatus
+ list.add(list.indexOf(leprosyStatus) + 1, other)
+ } else {
+ leprosyStatus.value =
+ getLocalValueInArray(leprosyStatus.arrayId, saved.leprosyStatus)
+ }
+ list.add(list.indexOf(leprosyStatus) + 1, referredTo)
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ referredTo.value = saved.referToName
+ list.add(list.indexOf(referredTo) + 1, other)
+ } else {
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ }
+ val recurrentUlcerationId = saved.recurrentUlcerationId ?: 1
+ val recurrentTinglingId = saved.recurrentTinglingId ?: 1
+ val hypopigmentedPatchId = saved.hypopigmentedPatchId ?: 1
+ val thickenedSkinId = saved.thickenedSkinId ?: 1
+ val skinNodulesId = saved.skinNodulesId ?: 1
+ val recurrentNumbnessId = saved.recurrentNumbnessId ?: 1
+ val clawingFingersId = saved.clawingFingersId ?: 1
+ val tinglingNumbnessExtremitiesId = saved.tinglingNumbnessExtremitiesId ?: 1
+ val inabilityCloseEyelidId = saved.inabilityCloseEyelidId ?: 1
+ val difficultyHoldingObjectsId = saved.difficultyHoldingObjectsId ?: 1
+ val weaknessFeetId = saved.weaknessFeetId ?: 1
+ recurrentUlceration.value = resources.getStringArray(R.array.yes_no).getOrNull(recurrentUlcerationId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacRecurrentTingling.value = resources.getStringArray(R.array.yes_no).getOrNull(recurrentTinglingId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacAnyHyperPigmented.value = resources.getStringArray(R.array.yes_no).getOrNull(hypopigmentedPatchId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacAnyThickendSkin.value = resources.getStringArray(R.array.yes_no).getOrNull(thickenedSkinId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacAnyNodulesSkin.value = resources.getStringArray(R.array.yes_no).getOrNull(skinNodulesId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacRecurrentNumbness.value = resources.getStringArray(R.array.yes_no).getOrNull(recurrentNumbnessId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacClawingOfFingers.value = resources.getStringArray(R.array.yes_no).getOrNull(clawingFingersId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacTinglingOrNumbness.value = resources.getStringArray(R.array.yes_no).getOrNull(tinglingNumbnessExtremitiesId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacInabilityCloseEyelid.value = resources.getStringArray(R.array.yes_no).getOrNull(inabilityCloseEyelidId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacDiffHoldingObjects.value = resources.getStringArray(R.array.yes_no).getOrNull(difficultyHoldingObjectsId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ cbacWeeknessInFeet.value = resources.getStringArray(R.array.yes_no).getOrNull(weaknessFeetId)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ /*if
+ (beneficiaryStatus.value == beneficiaryStatus.entries!![3]) {
+ list.add(list.indexOf(beneficiaryStatus) + 1, dateOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 2, placeOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 3, reasonOfDeath)
+ dateOfDeath.value =
+ getDateFromLong(saved.dateOfDeath)
+ placeOfDeath.value =
+ getLocalValueInArray(placeOfDeath.arrayId, saved.placeOfDeath)
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ otherPlaceOfDeath.value = saved.otherPlaceOfDeath
+ }
+
+ reasonOfDeath.value =
+ getLocalValueInArray(reasonOfDeath.arrayId, saved.reasonForDeath)
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ list.add(list.indexOf(reasonOfDeath) + 1, otherReasonOfDeath)
+ otherReasonOfDeath.value = saved.otherReasonForDeath
+ }
+ } else {
+ list.add(list.indexOf(beneficiaryStatus) + 1, leprosyStatus)
+ list.add(list.indexOf(beneficiaryStatus) + 2, typeOfLeprosy)
+ list.add(list.indexOf(beneficiaryStatus) + 3, followUpdate)
+ list.add(list.indexOf(beneficiaryStatus) + 4, remarks)
+ remarks.value = saved.remarks
+ leprosyStatus.value = getLocalValueInArray(leprosyStatus.arrayId, saved.leprosyStatus)
+ if (leprosyStatus.value == leprosyStatus.entries!![leprosyStatus.entries!!.size-3]) {
+ list.add(list.indexOf(leprosyStatus) + 1, referredTo)
+
+ }
+ typeOfLeprosy.value = getLocalValueInArray(typeOfLeprosy.arrayId, saved.typeOfLeprosy)
+
+ }
+
+
+ other.value = saved.otherReferredTo*/
+
+ }
+
+
+
+ setUpPage(list)
+
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+
+ return when (formId) {
+
+ recurrentUlceration.id,
+ cbacRecurrentTingling.id,
+ cbacAnyHyperPigmented.id,
+ cbacAnyThickendSkin.id,
+ cbacAnyNodulesSkin.id,
+ cbacRecurrentNumbness.id,
+ cbacClawingOfFingers.id,
+ cbacTinglingOrNumbness.id,
+ cbacInabilityCloseEyelid.id,
+ cbacDiffHoldingObjects.id,
+ cbacWeeknessInFeet.id -> {
+
+ updateLeprosySymptomsFromChecklist()
+ 0
+ }
+
+ leprosySymptoms.id -> {
+ if (leprosySymptoms.value == resources.getStringArray(R.array.yes_no)[0]) {
+
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[3]
+ visitLabel.value = resources.getString(R.string.visit_number_label, 1)
+
+ triggerDependants(
+ source = leprosySymptoms,
+ addItems = listOf(visitLabel,leprosyStatus,referredTo),
+ removeItems = listOf()
+ )
+
+ } else {
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[0]
+ triggerDependants(
+ source = leprosySymptoms,
+ addItems = listOf(),
+ removeItems = listOf(referredTo)
+ )
+ }
+ 0
+ }
+ beneficiaryStatus.id -> {
+ if (beneficiaryStatus.value == beneficiaryStatus.entries!![3]!!) {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(dateOfDeath,placeOfDeath,reasonOfDeath),
+ removeItems = listOf(leprosyStatus,referredTo,typeOfLeprosy,followUpdate,
+ remarks)
+ )
+ } else {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(leprosyStatus,typeOfLeprosy,followUpdate,
+ remarks),
+ removeItems = listOf(dateOfDeath,placeOfDeath,reasonOfDeath,otherPlaceOfDeath,otherReasonOfDeath)
+ )
+ }
+ 0
+ }
+
+
+ leprosyStatus.id -> {
+ if (leprosyStatus.value == leprosyStatus.entries!![leprosyStatus.entries!!.size-3]) {
+ triggerDependants(
+ source = leprosyStatus,
+ addItems = listOf(referredTo),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = leprosyStatus,
+ addItems = listOf(),
+ removeItems = listOf(referredTo)
+ )
+ }
+ 0
+ }
+
+ referredTo.id -> {
+ if (referredTo.value == referredTo.entries!!.last()) {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(other),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(),
+ removeItems = listOf(other)
+ )
+ }
+ 0
+ }
+
+
+
+ placeOfDeath.id -> {
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(otherPlaceOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherPlaceOfDeath)
+ )
+ }
+ 0
+ }
+ reasonOfDeath.id -> {
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(otherReasonOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherReasonOfDeath)
+ )
+ }
+ 0
+ }
+
+ other.id -> {
+ validateEmptyOnEditText(other)
+ }
+
+ otherReasonOfDeath.id -> {
+ validateEmptyOnEditText(otherReasonOfDeath)
+ }
+ otherPlaceOfDeath.id -> {
+ validateEmptyOnEditText(otherPlaceOfDeath)
+
+ }
+
+ else -> {
+ 0
+ }
+ }
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as LeprosyScreeningCache).let { form ->
+ form.homeVisitDate = getLongFromDate(dateOfCase.value)
+ form.referToName = getEnglishValueInArray(R.array.dc_refer, referredTo.value)
+ form.referredTo = referredTo.getPosition()
+ form.beneficiaryStatus = getEnglishValueInArray(R.array.benificary_case_status_leprosy, beneficiaryStatus.value)
+ form.beneficiaryStatusId = beneficiaryStatus.getPosition()
+ form.reasonForDeath = getEnglishValueInArray(R.array.reason_death, reasonOfDeath.value)
+ form.otherPlaceOfDeath = otherPlaceOfDeath.value
+ form.otherReasonForDeath = otherReasonOfDeath.value
+ form.dateOfDeath = getLongFromDate(dateOfDeath.value)
+ form.placeOfDeath = getEnglishValueInArray(R.array.death_place, placeOfDeath.value)
+ form.otherReferredTo = other.value
+ form.remarks = remarks.value
+ form.leprosyStatus = getEnglishValueInArray(R.array.leprosy_status, leprosyStatus.value) ?: "Screening"
+ form.typeOfLeprosy = getEnglishValueInArray(R.array.type_of_leprocy, typeOfLeprosy.value)
+ form.diseaseTypeID = 5
+ form.leprosySymptoms = getEnglishValueInArray(R.array.yes_no, leprosySymptoms.value)
+ form.visitLabel = englishResources.getString(R.string.visit_number_label, form.currentVisitNumber)
+ form.syncState = SyncState.UNSYNCED
+ form.leprosySymptomsPosition = when (leprosySymptoms.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.recurrentUlcerationId = when (recurrentUlceration.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.recurrentTinglingId = when (cbacRecurrentTingling.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.hypopigmentedPatchId = when (cbacAnyHyperPigmented.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.thickenedSkinId = when (cbacAnyThickendSkin.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.skinNodulesId = when (cbacAnyNodulesSkin.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.recurrentNumbnessId = when (cbacRecurrentNumbness .value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.clawingFingersId = when (cbacClawingOfFingers.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.tinglingNumbnessExtremitiesId = when (cbacTinglingOrNumbness .value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.inabilityCloseEyelidId = when (cbacInabilityCloseEyelid.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.difficultyHoldingObjectsId = when (cbacDiffHoldingObjects.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.weaknessFeetId = when (cbacWeeknessInFeet.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.recurrentUlceration = getEnglishValueInArray(R.array.yes_no, recurrentUlceration.value)
+ form.recurrentTingling = getEnglishValueInArray(R.array.yes_no, cbacRecurrentTingling.value)
+ form.hypopigmentedPatch = getEnglishValueInArray(R.array.yes_no, cbacAnyHyperPigmented.value)
+ form.thickenedSkin = getEnglishValueInArray(R.array.yes_no, cbacAnyThickendSkin.value)
+ form.skinNodules = getEnglishValueInArray(R.array.yes_no, cbacAnyNodulesSkin.value)
+ form.recurrentNumbness = getEnglishValueInArray(R.array.yes_no, cbacRecurrentNumbness.value)
+ form.clawingFingers = getEnglishValueInArray(R.array.yes_no, cbacClawingOfFingers.value)
+ form.tinglingNumbnessExtremities = getEnglishValueInArray(R.array.yes_no, cbacTinglingOrNumbness.value)
+ form.inabilityCloseEyelid = getEnglishValueInArray(R.array.yes_no, cbacInabilityCloseEyelid.value)
+ form.difficultyHoldingObjects = getEnglishValueInArray(R.array.yes_no, cbacDiffHoldingObjects.value)
+ form.weaknessFeet = getEnglishValueInArray(R.array.yes_no, cbacWeeknessInFeet.value)
+
+
+ }
+ }
+
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+//
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+
+ private fun updateLeprosySymptomsFromChecklist()
+ {
+ val yesValue = resources.getStringArray(R.array.yes_no)[0]
+
+ val anyYes = listOf(
+ recurrentUlceration.value,
+ cbacRecurrentTingling.value,
+ cbacAnyHyperPigmented.value,
+ cbacAnyThickendSkin.value,
+ cbacAnyNodulesSkin.value,
+ cbacRecurrentNumbness.value,
+ cbacClawingOfFingers.value,
+ cbacTinglingOrNumbness.value,
+ cbacInabilityCloseEyelid.value,
+ cbacDiffHoldingObjects.value,
+ cbacWeeknessInFeet.value
+ ).any { it == yesValue }
+
+ leprosySymptoms.value =
+ if (anyYes)
+ resources.getStringArray(R.array.yes_no)[0]
+
+ else resources.getStringArray(R.array.yes_no)[1]
+
+ if (anyYes){
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[3]
+ visitLabel.value = resources.getString(R.string.visit_number_label, 1)
+
+ triggerDependants(
+ source = leprosySymptoms,
+ addItems = listOf(visitLabel,leprosyStatus,referredTo),
+ removeItems = listOf()
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosySuspectedDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosySuspectedDataset.kt
new file mode 100644
index 000000000..ef5e91ef1
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/LeprosySuspectedDataset.kt
@@ -0,0 +1,278 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.room.SyncState
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.LeprosyScreeningCache
+
+class LeprosySuspectedDataset (
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private var homeVisitDateLong: Long = System.currentTimeMillis()
+ private var treatmentStartDateLong: Long = 0L
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.home_visit_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ hasDependants = true,
+ isEnabled = false
+
+ )
+
+ private val leprosyStatus = FormElement(
+ id = 8,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.str_leprosy_status),
+ arrayId = R.array.leprosy_status,
+ entries = resources.getStringArray(R.array.leprosy_status),
+ required = false,
+ hasDependants = true,
+ isEnabled = false
+
+ )
+
+ private var referredTo = FormElement(
+ id = 9,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.refer_to),
+ arrayId = R.array.dc_refer,
+ entries = resources.getStringArray(R.array.dc_refer),
+ required = false,
+ hasDependants = true,
+ isEnabled = false
+ )
+ private var other = FormElement(
+ id = 10,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other),
+ required = true,
+ hasDependants = false
+ )
+ /* private var typeOfLeprosy = FormElement(
+ id = 11,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.type_of_leprocy),
+ arrayId = R.array.type_of_leprocy,
+ entries = resources.getStringArray(R.array.type_of_leprocy),
+ required = false,
+ hasDependants = true
+ )*/
+
+ private val followUpdate = FormElement(
+ id = 12,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.follow_up_date),
+ arrayId = -1,
+ required = false,
+ max = System.currentTimeMillis(),
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ hasDependants = true
+
+ )
+ private val remarks = FormElement(
+ id = 13,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.pnc_remarks),
+ required = false,
+ isEnabled = false
+ )
+
+ private val leprosySymptoms = FormElement(
+ id = 14,
+ inputType = InputType.RADIO,
+ arrayId = R.array.yes_no,
+ title = resources.getString(R.string.any_leprosy_symptoms_present),
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true,
+ required = true,
+ isEnabled = false
+ )
+
+ private val visitLabel = FormElement(
+ id = 15,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.visits),
+ required = true,
+ isEnabled = false
+ )
+
+ private val typeOfLeprosy = FormElement(
+ id = 16,
+ inputType = InputType.RADIO,
+ isEnabled = true,
+ required = true,
+ title = resources.getString(R.string.type_of_leprocy),
+ arrayId = R.array.type_of_leprocy,
+ entries = resources.getStringArray(R.array.type_of_leprocy),
+ hasDependants = true
+ )
+
+ private val treatmentStartDate = FormElement(
+ id = 17,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.treatment_start_date),
+ isEnabled = true,
+ required = false,
+ max = System.currentTimeMillis()
+
+ )
+
+ private val leprosyConfirmed = FormElement(
+ id = 18,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.has_leprosy_been_confirmed),
+ required = true,
+ isEnabled = true,
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ hasDependants = true)
+
+
+ suspend fun setUpPage(ben: BenRegCache?, saved: LeprosyScreeningCache?) {
+ val list = mutableListOf(
+ dateOfCase,
+ leprosySymptoms,
+ visitLabel,
+ leprosyStatus,
+ referredTo,
+ leprosyConfirmed,
+ //typeOfLeprosy,
+
+
+
+ )
+ homeVisitDateLong = saved?.homeVisitDate ?: System.currentTimeMillis()
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[0]
+ visitLabel.value = resources.getString(R.string.visit_number_label, 1)
+ leprosySymptoms.value = resources.getStringArray(R.array.yes_no)[1]
+
+ updateDateConstraints()
+
+ } else {
+ dateOfCase.value = getDateFromLong(saved.homeVisitDate)
+ val symptomsPosition = saved.leprosySymptomsPosition ?: 1
+ leprosySymptoms.value = resources.getStringArray(R.array.yes_no).getOrNull(symptomsPosition)
+ ?: resources.getStringArray(R.array.yes_no)[1]
+ visitLabel.value = resources.getString(R.string.visit_number_label, saved?.currentVisitNumber ?: 1)
+
+ leprosyStatus.value =
+ getLocalValueInArray(leprosyStatus.arrayId, saved.leprosyStatus)
+
+ if (leprosyStatus.value == leprosyStatus.entries!!.last()) {
+ leprosyStatus.value = saved.leprosyStatus
+ list.add(list.indexOf(leprosyStatus) + 1, other)
+ } else {
+ leprosyStatus.value =
+ getLocalValueInArray(leprosyStatus.arrayId, saved.leprosyStatus)
+ }
+ remarks.value = saved.remarks
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!!.last()) {
+ referredTo.value = saved.referToName
+ list.add(list.indexOf(referredTo) + 1, other)
+ } else {
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ }
+
+ other.value = saved.otherReferredTo
+
+
+ updateDateConstraints()
+
+ }
+
+
+
+ setUpPage(list)
+
+ }
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ when (formId) {
+
+ leprosyConfirmed.id ->{
+ if (leprosyConfirmed.value == resources.getStringArray(R.array.yes_no)[0]) {
+ triggerDependants(source = leprosyConfirmed, addItems =listOf(typeOfLeprosy),removeItems = listOf())
+ }
+ else{
+ triggerDependants(source = leprosyConfirmed, addItems = listOf(),removeItems =listOf(typeOfLeprosy))
+
+ }
+
+ }
+
+ typeOfLeprosy.id -> {
+ leprosyStatus.value = resources.getStringArray(R.array.leprosy_status)[4]
+
+ treatmentStartDate.value = getDateFromLong(System.currentTimeMillis())
+
+ triggerDependants(
+ source = typeOfLeprosy,
+ addItems = listOf(treatmentStartDate),
+ removeItems = listOf(treatmentStartDate)
+ )
+
+
+ }
+
+
+ }
+ return 0
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as LeprosyScreeningCache).let { form ->
+ form.homeVisitDate = getLongFromDate(dateOfCase.value)
+ form.referToName = getEnglishValueInArray(R.array.dc_refer, referredTo.value)
+ form.referredTo = referredTo.getPosition()
+ form.otherReferredTo = other.value
+ form.remarks = remarks.value
+ form.typeOfLeprosy = getEnglishValueInArray(R.array.type_of_leprocy, typeOfLeprosy.value)
+ form.diseaseTypeID = 5
+ form.leprosyStatus = getEnglishValueInArray(R.array.leprosy_status, leprosyStatus.value) ?: "Screening"
+ form.visitLabel = visitLabel.value
+ form.leprosySymptomsPosition = when (leprosySymptoms.value) {
+ resources.getStringArray(R.array.yes_no)[0] -> 0
+ resources.getStringArray(R.array.yes_no)[1] -> 1
+ else -> 1
+ }
+ form.isConfirmed = !typeOfLeprosy.value.isNullOrEmpty()
+ form.treatmentStartDate = getLongFromDate(treatmentStartDate.value)
+ form.syncState = SyncState.UNSYNCED
+
+ }
+ }
+
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+//
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+
+ private fun updateDateConstraints() {
+ treatmentStartDate.min = homeVisitDateLong
+
+
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/MDSRFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MDSRFormDataset.kt
index 36329a972..04abc75de 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/MDSRFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MDSRFormDataset.kt
@@ -1,8 +1,11 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
import android.widget.LinearLayout
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.FormElement
@@ -10,14 +13,23 @@ import org.piramalswasthya.sakhi.model.InputType
import org.piramalswasthya.sakhi.model.MDSRCache
class MDSRFormDataset(
- context: Context, currentLanguage: Languages
+ context: Context,
+ currentLanguage: Languages,
+ val preferences: PreferenceDao,
+ val pregnancyDeath: Boolean = false,
+ val abortionDeath: Boolean = false,
+ val deliveryDeath: Boolean = false,
+ val pncDeath: Boolean = false,
+ val pncDeathCause: Boolean = false,
+ val ancDeathCause: Boolean = false
+
) : Dataset(context, currentLanguage) {
private val dateOfDeath = FormElement(
id = 1,
- inputType = InputType.DATE_PICKER,
- title = "Date of death ",
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.date_of_death),
min = 0L,
max = System.currentTimeMillis(),
required = true
@@ -25,35 +37,36 @@ class MDSRFormDataset(
private val address = FormElement(
id = 2,
inputType = InputType.TEXT_VIEW,
- title = "Address",
+ title = resources.getString(R.string.address),
required = false
)
private val husbandName = FormElement(
id = 3,
inputType = InputType.TEXT_VIEW,
etMaxLength = 50,
- title = "Husband’s Name",
+ title = resources.getString(R.string.mdsr_husband_name),
required = false
)
private val causeOfDeath = FormElement(
id = 4,
inputType = InputType.RADIO,
- title = "Cause of death",
+ title = resources.getString(R.string.mdsr_cause),
required = true,
- orientation = LinearLayout.VERTICAL,
+ isEnabled = false,
hasDependants = true,
- entries = arrayOf("Maternal", "Non-maternal")
+ arrayId = R.array.mdsr_cause_of_death_type,
+ entries = resources.getStringArray(R.array.mdsr_cause_of_death_type)
)
private val reasonOfDeath = FormElement(
id = 5,
inputType = InputType.EDIT_TEXT,
- title = "Specify Reason",
+ title = resources.getString(R.string.mdsr_reason_death),
required = true
)
private val investigationDate = FormElement(
id = 6,
inputType = InputType.DATE_PICKER,
- title = "Date of field investigation",
+ title = resources.getString(R.string.mdsr_field_investigation),
min = 0L,
max = System.currentTimeMillis(),
required = false
@@ -61,15 +74,15 @@ class MDSRFormDataset(
private val actionTaken = FormElement(
id = 7,
inputType = InputType.RADIO,
- title = "Action Take",
+ title = resources.getString(R.string.mdsr_action),
required = false,
orientation = LinearLayout.VERTICAL,
- entries = arrayOf("Yes", "No")
+ entries = resources.getStringArray(R.array.yes_no)
)
private val blockMOSign = FormElement(
id = 8,
inputType = InputType.EDIT_TEXT,
- title = "Signature of MO I/C of the block",
+ title = resources.getString(R.string.mdsr_signature),
required = false
)
private val dateIc = FormElement(
@@ -77,10 +90,177 @@ class MDSRFormDataset(
inputType = InputType.DATE_PICKER,
min = 0L,
max = System.currentTimeMillis(),
- title = "Date",
+ title = resources.getString(R.string.mdsr_ic_date),
+ required = false
+ )
+ private val duringPregnancy = FormElement(
+ id = 4,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.a_during_pregnancy),
+ required = false,
+ isEnabled = false,
+ entries = resources.getStringArray(R.array.yes_no)
+ )
+
+ private val duringDelivery = FormElement(
+ id = 4,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.b_during_delivery),
+ required = false,
+ isEnabled = false,
+ entries = resources.getStringArray(R.array.yes_no)
+ )
+ private val duringDelivery42Days = FormElement(
+ id = 4,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.c_within_42_days_after_delivery),
+ required = false,
+ isEnabled = false,
+ entries = resources.getStringArray(R.array.yes_no)
+ )
+ private val duringAbortion6Weeks = FormElement(
+ id = 4,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.d_during_abortion_or_within_6_weeks_after_abortion),
+ required = false,
+ isEnabled = false,
+ entries = resources.getStringArray(R.array.yes_no)
+ )
+
+ private val nameOfReportingPerson = FormElement(
+ id = 18,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.name_of_reporting_person),
+ required = false
+ )
+
+ private val designation = FormElement(
+ id = 18,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.designation),
+ required = false
+ )
+
+ private val veryficationByANM = FormElement(
+ id = 18,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.verification_by_anm_of_the_respective_sub_center_that_death_of_women_occurred_during_pregnancy_or_within_42_days_of_delivery_abortion),
+ required = false
+ )
+ private val nameOdANM = FormElement(
+ id = 18,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.name_of_anm),
+ required = false
+ )
+ private val nameOfSubCenter = FormElement(
+ id = 18,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.name_of_the_sub_center),
required = false
)
+ private val mdsrFileUpload1 = FormElement(
+ id = 21,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.mdsr_form_from_anm_1),
+ required = false,
+ )
+ private val mdsrFileUpload2 = FormElement(
+ id = 22,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.mdsr_form_from_anm_2),
+ required = false,
+ )
+ private val mdsrDeathFileUpload = FormElement(
+ id = 23,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.death_certificate),
+ required = false,
+ )
+
+ //................changes BRD................................
+ private val state = FormElement(
+ id = 24,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.state),
+ required = false
+ )
+ private val district = FormElement(
+ id = 25,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.district),
+ required = false
+ )
+ private val block = FormElement(
+ id = 26,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.block),
+ required = false
+ )
+ private val village = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.village_town_city),
+ required = false
+ )
+
+ private val fatherName = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.father_name),
+ required = false
+ )
+ private val ageOfWomen = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.age_of_woman),
+ required = false
+ )
+
+ private val rchID = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.rch_id),
+ required = false
+ )
+
+
+ private val mobileNo = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.mobile_number),
+ required = false
+ )
+
+ private val timeOfDeath = FormElement(
+ id = 16,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.time_of_death),
+ required = false
+ )
+ private val placeOfDate = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.place_of_death),
+ required = false
+ )
+
+ private val whenDidDeathOccur = FormElement(
+ id = 27,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.when_did_death_occur),
+ required = false
+ )
+ private val nameOfDeceased = FormElement(
+ id = 27,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.name_of_the_deceased_woman),
+ required = false
+ )
+
+
+//.............................................................
suspend fun setUpPage(
ben: BenRegCache,
@@ -88,26 +268,90 @@ class MDSRFormDataset(
saved: MDSRCache?
) {
val list = mutableListOf(
- dateOfDeath,
- this.address,
+ state,
+ district,
+ block,
+ village,
+ nameOfDeceased,
husbandName,
+ fatherName,
+ ageOfWomen,
+ rchID,
+ mobileNo,
+ dateOfDeath,
+ timeOfDeath,
+ placeOfDate,
+ whenDidDeathOccur,
+ duringPregnancy,
+ duringDelivery,
+ duringDelivery42Days,
+ duringAbortion6Weeks,
causeOfDeath,
- investigationDate,
- actionTaken,
- blockMOSign,
- dateIc
+ nameOfReportingPerson,
+ designation,
+ veryficationByANM,
+ nameOdANM,
+ nameOfSubCenter,
+ dateIc,
+ mdsrFileUpload1,
+ mdsrFileUpload2,
+ mdsrDeathFileUpload,
+// this.address,
+// investigationDate,
+// actionTaken,
+// blockMOSign,
+
)
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(mdsrFileUpload1)
+ list.remove(mdsrFileUpload2)
+ list.remove(mdsrDeathFileUpload)
+ }
+
this.address.value = address
husbandName.value = ben.genDetails?.spouseName
+ val user = preferences.getLoggedInUser()
+ nameOfReportingPerson.value = user?.userName ?: ""
+ designation.value="Asha"
+ state.value = user?.state?.name ?: ""
+ district.value = user?.district?.name ?: ""
+ block.value = user?.block?.name ?: ""
+// nameOfSubCenter.value = user?.subs?.name ?: ""
+ village.value = user!!.villages[0].name
+ placeOfDate.value = ben.placeOfDeath
+ rchID.value = ben.rchId
+ ageOfWomen.value = ben.age.toString()
+ fatherName.value=ben.fatherName
+ dateOfDeath.value=ben.dateOfDeath
+ timeOfDeath.value=ben.timeOfDeath
+ nameOfDeceased.value = "${ben.firstName} ${ben.lastName}"
+ duringPregnancy.value = if (pregnancyDeath) duringPregnancy.entries!![0] else duringPregnancy.entries!![1]
+ duringDelivery.value = if (deliveryDeath) duringDelivery.entries!![0] else duringDelivery.entries!![1]
+ duringDelivery42Days.value = if (pncDeath) duringDelivery42Days.entries!![0] else duringDelivery42Days.entries!![1]
+ duringAbortion6Weeks.value = if (abortionDeath) duringAbortion6Weeks.entries!![0] else duringAbortion6Weeks.entries!![1]
+
+ val causeOfDeathValue = if (pregnancyDeath || abortionDeath || deliveryDeath || pncDeath) {
+ if(pncDeathCause || ancDeathCause)
+ causeOfDeath.entries!![1]
+ else
+ causeOfDeath.entries!![0]
+ } else {
+ causeOfDeath.entries!![1]
+ }
+ causeOfDeath.value = causeOfDeathValue
saved?.let { mdsr ->
dateOfDeath.value = mdsr.dateOfDeath?.let { getDateFromLong(it) }
this.address.value = mdsr.address
husbandName.value = mdsr.husbandName
- causeOfDeath.value = mdsr.causeOfDeath
+ causeOfDeath.value = getLocalValueInArray(R.array.mdsr_cause_of_death_type, mdsr.causeOfDeath)
reasonOfDeath.value = mdsr.reasonOfDeath
+ mdsrFileUpload1.value=mdsr.mdsr1File
+ mdsrFileUpload2.value=mdsr.mdsr2File
+ mdsrDeathFileUpload.value=mdsr.mdsrDeathCertFile
investigationDate.value = mdsr.investigationDate?.let { getDateFromLong(it) }
actionTaken.value = mdsr.actionTaken?.let {
- if (it) resources.getString(R.string.yes) else resources.getString(R.string.no)
+ if (it) actionTaken.entries!![0] else actionTaken.entries!![1]
}
blockMOSign.value = mdsr.blockMOSign
dateIc.value = mdsr.dateIc?.let { getDateFromLong(it) }
@@ -130,16 +374,48 @@ class MDSRFormDataset(
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as MDSRCache).let { mdsrCache ->
- mdsrCache.dateOfDeath = getLongFromDate(dateOfDeath.value!!)
+ mdsrCache.dateOfDeath = dateOfDeath.value?.let { getLongFromDate(it) }
mdsrCache.address = address.value
mdsrCache.husbandName = husbandName.value
- mdsrCache.causeOfDeath = causeOfDeath.value
+ mdsrCache.mdsr1File = mdsrFileUpload1.value
+ mdsrCache.mdsr2File = mdsrFileUpload2.value
+ mdsrCache.mdsrDeathCertFile = mdsrDeathFileUpload.value
+ mdsrCache.causeOfDeath = getEnglishValueInArray(R.array.mdsr_cause_of_death_type, causeOfDeath.value)
mdsrCache.reasonOfDeath = reasonOfDeath.value
- mdsrCache.actionTaken = actionTaken.value?.let { actionTaken.value == "Yes" }
+ mdsrCache.actionTaken = actionTaken.value?.let { actionTaken.value == actionTaken.entries!![0] }
mdsrCache.investigationDate = investigationDate.value?.let { getLongFromDate(it) }
mdsrCache.blockMOSign = blockMOSign.value
mdsrCache.dateIc = dateIc.value?.let { getLongFromDate(it) }
mdsrCache.createdDate = System.currentTimeMillis()
}
}
+
+
+
+ fun getIndexOfMDSR1() = getIndexById(mdsrFileUpload1.id)
+ fun getIndexOfMDSR2() = getIndexById(mdsrFileUpload2.id)
+ fun getIndexOfIsDeathCertificate() = getIndexById(mdsrDeathFileUpload.id)
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+
+ when (lastImageFormId) {
+ 21 -> {
+ mdsrFileUpload1.value = dpUri.toString()
+ mdsrFileUpload1.errorText = null
+ }
+
+ 22 -> {
+ mdsrFileUpload2.value = dpUri.toString()
+ mdsrFileUpload2.errorText = null
+ }
+
+ 23 -> {
+ mdsrDeathFileUpload.value = dpUri.toString()
+ mdsrDeathFileUpload.errorText = null
+ }
+
+ }
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/MaaMeetingDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MaaMeetingDataset.kt
new file mode 100644
index 000000000..305c4338d
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MaaMeetingDataset.kt
@@ -0,0 +1,205 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import java.util.Calendar
+
+class MaaMeetingDataset(
+ context: Context,
+ currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ val meetingDate = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.maa_meeting_date),
+ required = true,
+ max = System.currentTimeMillis(),
+ ).apply {
+ val cal = Calendar.getInstance()
+ cal.add(Calendar.MONTH, -2)
+ min = cal.timeInMillis
+ }
+
+
+ val meetingPlace = FormElement(
+ id = 2,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_maa_meeting),
+ required = true,
+ entries = resources.getStringArray(R.array.maa_meeting_place_array)
+ )
+
+ val villageName = FormElement(
+ id = 9,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.village_name),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ val noOfPW = FormElement(
+ id = 17,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_pregnant_woman_attended),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+
+ val noOfLM = FormElement(
+ id = 16,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_lactating_mothers_attended),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+
+ val duringBreastfeeding = FormElement(
+ id = 15,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.during_breastfeeding_counseling_check_list),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.maa_breastfeeding),
+ required = false,
+ )
+
+
+ val participants = FormElement(
+ id = 3,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.total_no_b_attended),
+ required = true,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER,
+ etMaxLength = 3,
+ min = 0,
+ max = 999
+ )
+
+ val upload1 = FormElement(
+ id = 10,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.meeting_photos_mom, 1),
+ required = false
+ )
+ val upload2 = upload1.copy(id = 11, title = resources.getString(R.string.meeting_photos_mom, 2))
+ val upload3 = upload1.copy(id = 12, title = resources.getString(R.string.meeting_photos_mom, 3))
+ val upload4 = upload1.copy(id = 13, title = resources.getString(R.string.meeting_photos_mom, 4))
+ val upload5 = upload1.copy(id = 14, title = resources.getString(R.string.meeting_photos_mom, 5))
+
+ suspend fun setUpPage(recordExists: Boolean) {
+ val list = mutableListOf(
+ meetingDate,
+ meetingPlace,
+ )
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.add(villageName)
+ list.add(participants)
+ list.add(noOfPW)
+ list.add(noOfLM)
+ list.add(duringBreastfeeding)
+ }
+ else{
+ list.add(participants)
+ }
+
+ val uploadList = listOf(upload1, upload2, upload3, upload4, upload5)
+
+ if (recordExists) {
+ val filledUploads = uploadList.filter { !it.value.isNullOrEmpty() }
+ if (filledUploads.isEmpty()) {
+ list.addAll(uploadList)
+ } else {
+ list.addAll(filledUploads)
+ }
+ } else {
+ list.addAll(uploadList)
+ }
+
+ setUpPage(list)
+ }
+
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ duringBreastfeeding.id -> {
+
+ val allItems = resources.getStringArray(R.array.maa_breastfeeding)
+ val totalCount = allItems.size
+
+ val selectedIndexes = duringBreastfeeding.value
+ ?.split("|")
+ ?.mapNotNull { it.toIntOrNull() }
+ ?.toMutableSet()
+ ?: mutableSetOf()
+
+ if (index == 0) {
+
+ if (selectedIndexes.contains(0)) {
+ selectedIndexes.clear()
+ selectedIndexes.addAll(0 until totalCount)
+ } else {
+ selectedIndexes.clear()
+ }
+
+ duringBreastfeeding.value =
+ if (selectedIndexes.isEmpty()) null
+ else selectedIndexes.sorted().joinToString("|")
+
+ return -1
+ }
+ val normalIndexes = (1 until totalCount)
+
+ if (selectedIndexes.contains(0) &&
+ normalIndexes.any { !selectedIndexes.contains(it) }
+ ) {
+ selectedIndexes.remove(0)
+ }
+
+ if (normalIndexes.all { selectedIndexes.contains(it) }) {
+ selectedIndexes.add(0)
+ }
+
+ duringBreastfeeding.value =
+ if (selectedIndexes.isEmpty()) null
+ else selectedIndexes.sorted().joinToString("|")
+
+ -1
+ }
+
+
+
+
+ participants.id -> {
+ validateAllDigitOnEditText(participants)
+ validateIntMinMax(participants)
+ }
+ else -> -1
+ }
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+
+ }
+
+
+}
+
+
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/MalariaConfirmCasesDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MalariaConfirmCasesDataset.kt
new file mode 100644
index 000000000..7efe72801
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MalariaConfirmCasesDataset.kt
@@ -0,0 +1,226 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.util.Log
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.MalariaConfirmedCasesCache
+import org.piramalswasthya.sakhi.model.MalariaScreeningCache
+
+class MalariaConfirmCasesDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.start_t_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+
+ private var treatmentGiven = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.treatment_given),
+ arrayId = R.array.pf_pv,
+ entries = resources.getStringArray(R.array.pf_pv),
+ required = false,
+ isEnabled = false,
+ hasDependants = true
+ )
+
+
+ private var dayWiseTrackingPf = FormElement(
+ id = 22,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.day_wise_tracking_pf),
+ arrayId = R.array.daysPf,
+ entries = resources.getStringArray(R.array.daysPf),
+ required = false,
+ hasDependants = true
+ )
+
+ private var dayWiseTrackingPV = FormElement(
+ id = 23,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.day_wise_tracking_pv),
+ arrayId = R.array.daysPv,
+ entries = resources.getStringArray(R.array.daysPv),
+ required = false,
+ hasDependants = true
+ )
+
+ private val dateOfCompletion = FormElement(
+ id = 2,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date_of_completion),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis(),
+ max = Long.MAX_VALUE,
+ hasDependants = true
+
+ )
+
+ private val referalDate = FormElement(
+ id = 3,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date_of_referal),
+ arrayId = -1,
+ required = false,
+ min = System.currentTimeMillis() ,
+ max = System.currentTimeMillis() + (3L * 30 * 24 * 60 * 60 * 1000),
+ hasDependants = true
+
+ )
+
+
+ suspend fun setUpPage(ben: BenRegCache?, slideTestName:String, saved: MalariaConfirmedCasesCache?) {
+ val list = mutableListOf(
+ dateOfCase,
+ treatmentGiven,
+ dateOfCompletion,
+ referalDate
+ )
+
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ dayWiseTrackingPf.value = resources.getStringArray(R.array.daysPf)[0]
+ dayWiseTrackingPV.value = resources.getStringArray(R.array.daysPv)[0]
+
+ treatmentGiven.value = getLocalValueInArray(R.array.pf_pv, slideTestName)
+ if(treatmentGiven.value == resources.getStringArray(R.array.pf_pv)[0]){
+ list.add(list.indexOf(treatmentGiven) + 1 ,dayWiseTrackingPf)
+ } else {
+ list.add(list.indexOf(treatmentGiven) + 1 ,dayWiseTrackingPV)
+
+ }
+ updateCompletionDateLimits(setDefault = true)
+ } else {
+ dateOfCase.value = getDateFromLong(saved.dateOfDiagnosis)
+ dateOfCompletion.value = getDateFromLong(saved.treatmentCompletionDate)
+ referalDate.value = getDateFromLong(saved.referralDate)
+ treatmentGiven.value = getLocalValueInArray(R.array.pf_pv, saved.treatmentGiven)
+
+ if(treatmentGiven.value == resources.getStringArray(R.array.pf_pv)[0]){
+ list.add(list.indexOf(treatmentGiven) + 1 ,dayWiseTrackingPf)
+ dayWiseTrackingPf.value = getLocalValueInArray(R.array.daysPf,saved.day)
+ } else {
+ list.add(list.indexOf(treatmentGiven) + 1 ,dayWiseTrackingPV)
+ dayWiseTrackingPV.value = getLocalValueInArray(R.array.daysPv,saved.day)
+
+ }
+ updateCompletionDateLimits()
+
+ }
+
+ setUpPage(list)
+
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+
+ return when (formId) {
+
+ dateOfCase.id -> {
+ updateCompletionDateLimits(setDefault = true)
+ 0
+ }
+
+
+ treatmentGiven.id -> {
+ updateCompletionDateLimits(setDefault = true)
+ if(treatmentGiven.value == resources.getStringArray(R.array.pf_pv)[0]){
+ triggerDependants(
+ source = treatmentGiven,
+ addItems = listOf(dayWiseTrackingPf),
+ removeItems = listOf(dayWiseTrackingPV)
+ )
+
+ } else if(treatmentGiven.value == resources.getStringArray(R.array.pf_pv)[1]){
+ triggerDependants(
+ source = treatmentGiven,
+ addItems = listOf(dayWiseTrackingPV),
+ removeItems = listOf(dayWiseTrackingPf)
+ )
+
+ }
+ 0
+ }
+
+
+ else -> {
+ 0
+ }
+ }
+
+
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as MalariaConfirmedCasesCache).let { form ->
+ form.dateOfDiagnosis = getLongFromDate(dateOfCase.value)
+ form.treatmentStartDate = getLongFromDate(dateOfCase.value)
+ form.treatmentGiven = getEnglishValueInArray(R.array.pf_pv, treatmentGiven.value)
+ if(treatmentGiven.value == resources.getStringArray(R.array.pf_pv)[0]){
+ form.day = getEnglishValueInArray(R.array.daysPv, dayWiseTrackingPf.value)
+
+ } else {
+ form.day = getEnglishValueInArray(R.array.daysPv, dayWiseTrackingPV.value)
+
+ }
+ form.treatmentCompletionDate= getLongFromDate(dateOfCompletion.value)
+ form.referralDate= getLongFromDate(referalDate.value)
+
+ }
+ }
+
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+
+
+ private fun updateCompletionDateLimits(setDefault: Boolean = false) {
+ val startDate = getLongFromDate(dateOfCase.value) ?: return
+ val treatment = treatmentGiven.value ?: return
+
+
+
+ val days = when (treatment) {
+ resources.getStringArray(R.array.pf_pv)[0] -> 3
+ resources.getStringArray(R.array.pf_pv)[1] -> 4
+ else -> 0
+ }
+
+ if (days > 0) {
+ val maxDate = startDate + (days * 24 * 60 * 60 * 1000L)
+ dateOfCompletion.min = startDate
+ dateOfCompletion.max = maxDate
+
+ if (setDefault) {
+ dateOfCompletion.value = getDateFromLong(maxDate)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/MalariaFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MalariaFormDataset.kt
new file mode 100644
index 000000000..8b8acb247
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/MalariaFormDataset.kt
@@ -0,0 +1,961 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.MalariaScreeningCache
+import org.piramalswasthya.sakhi.model.TBScreeningCache
+import timber.log.Timber
+import java.util.Calendar
+
+class MalariaFormDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+
+
+ private val dateOfCase = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.case_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+ private val beneficiaryStatus = FormElement(
+ id = 2,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.beneficiary_status),
+ arrayId = R.array.benificary_case_status,
+ entries = resources.getStringArray(R.array.benificary_case_status),
+ required = true,
+ hasDependants = true
+
+ )
+ private val dateOfDeath = FormElement(
+ id = 3,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.death_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+ private val placeOfDeath = FormElement(
+ id = 4,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_Death),
+ arrayId = R.array.death_place,
+ entries = resources.getStringArray(R.array.death_place),
+ required = true,
+ hasDependants = true
+
+ )
+
+ private var otherPlaceOfDeath = FormElement(
+ id = 5,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_place),
+ required = true,
+ hasDependants = false
+ )
+
+ private val reasonOfDeath = FormElement(
+ id = 6,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.reason_of_Death),
+ arrayId = R.array.reason_death,
+ entries = resources.getStringArray(R.array.reason_death),
+ required = true,
+ hasDependants = true
+
+ )
+ private var otherReasonOfDeath = FormElement(
+ id = 28,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other_reason),
+ required = true,
+ hasDependants = false
+ )
+
+ private var headline = FormElement(
+ id = 27,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.sympt),
+ required = false,
+ headingLine = false,
+ hasDependants = false
+ )
+
+ private var isFever = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.cbac_feverwks),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ private var isFluLikeIllness = FormElement(
+ id = 8,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.flu_like_illness),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ private var isShakingchills = FormElement(
+ id = 9,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.shakingchills),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ private var isHeadache = FormElement(
+ id = 10,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.headache),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ private var isMuscleaches = FormElement(
+ id = 11,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.muscleaches),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ private var isTiredness = FormElement(
+ id = 12,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tiredness),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+ private var isNausea = FormElement(
+ id = 13,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.nausea),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+ private var isVomiting = FormElement(
+ id = 14,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.vomiting),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ private var isDiarrhea = FormElement(
+ id = 15,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.diarrhea),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ ).apply {
+ value = resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ private val caseStatus = FormElement(
+ id = 16,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.case_status),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.dc_case_status),
+ required = false,
+ isEnabled = false,
+ hasDependants = true
+
+ )
+
+ private val testType = FormElement(
+ id = 28,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.m_test_type),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.test_type),
+ required = false,
+ isEnabled = true,
+ hasDependants = true
+
+ )
+ private var rapidDiagnostic = FormElement(
+ id = 17,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.rapid_diagnostic),
+ arrayId = R.array.positive_negative,
+ entries = resources.getStringArray(R.array.positive_negative),
+ required = false,
+ hasDependants = true
+ )
+
+ private val dateOfTest = FormElement(
+ id = 18,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.test_up_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+ private var slideTestOptions = FormElement(
+ id = 27,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.slide_test),
+ arrayId = R.array.pf_pv,
+ entries = resources.getStringArray(R.array.pf_pv),
+ required = false,
+ hasDependants = true
+ )
+
+ private var slideTestPf = FormElement(
+ id = 19,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.slide_test_pf),
+ arrayId = R.array.positive_negative,
+ entries = resources.getStringArray(R.array.positive_negative),
+ required = false,
+ hasDependants = true
+ )
+
+ private var slideTestPv = FormElement(
+ id = 20,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.slide_test_pv),
+ arrayId = R.array.positive_negative,
+ entries = resources.getStringArray(R.array.positive_negative),
+ required = false,
+ hasDependants = true
+ )
+
+ private val dateOfSlidetest = FormElement(
+ id = 21,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.test_up_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ hasDependants = true
+
+ )
+
+ private var referredTo = FormElement(
+ id = 22,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.refer_to),
+ arrayId = R.array.dc_refer_malaria,
+ entries = resources.getStringArray(R.array.dc_refer_malaria),
+ required = false,
+ hasDependants = true
+ )
+ private var other = FormElement(
+ id = 23,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.other),
+ required = true,
+ hasDependants = false
+ )
+ private val followUpdate = FormElement(
+ id = 24,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.follow_up_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ hasDependants = true
+
+ )
+
+
+ private val remarks = FormElement(
+ id = 25,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.pnc_remarks),
+ required = false,
+
+ )
+ private val dateOfVisitBySupervisor = FormElement(
+ id = 26,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.supervisor_visit_date),
+ arrayId = -1,
+ required = false,
+ max = System.currentTimeMillis(),
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ hasDependants = true
+
+ )
+
+ var visitId = 0L
+
+ suspend fun setUpPage(ben: BenRegCache?, saved: MalariaScreeningCache?) {
+ val list = mutableListOf(
+ dateOfCase,
+ beneficiaryStatus,
+ headline,
+ isFever,
+ isFluLikeIllness,
+ isShakingchills,
+ isHeadache,
+ isMuscleaches,
+ isTiredness,
+ isNausea,
+ isVomiting,
+ isDiarrhea,
+ caseStatus
+ )
+ if (saved == null) {
+ dateOfCase.value = getDateFromLong(System.currentTimeMillis())
+ beneficiaryStatus.value = resources.getStringArray(R.array.benificary_case_status)[0]
+ visitId = 0
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[0]
+ } else {
+ dateOfCase.value = getDateFromLong(saved.caseDate)
+ followUpdate.value = getDateFromLong(saved.followUpDate)
+ visitId = saved.visitId
+ val entries = resources.getStringArray(R.array.test_type)
+ val index = saved.malariaTestType ?: 0
+ if (index != 0) {
+ testType.value = entries[index-1]
+ }
+ remarks.value = saved.remarks
+ if (saved.caseStatus == "Suspected") {
+ caseStatus.entries = resources.getStringArray(R.array.dc_case_status)
+ .filter { it == "Confirmed" || it == "Not Confirmed" }
+ .toTypedArray()
+ } else {
+ caseStatus.entries = resources.getStringArray(R.array.dc_case_status)
+ }
+ saved.caseStatus
+ isFever.value =
+ if (saved.feverMoreThanTwoWeeks == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isFluLikeIllness.value =
+ if (saved.fluLikeIllness == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isShakingchills.value =
+ if (saved.shakingChills == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isHeadache.value =
+ if (saved.headache == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isMuscleaches.value =
+ if (saved.muscleAches == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isTiredness.value =
+ if (saved.tiredness == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isNausea.value =
+ if (saved.nausea == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isVomiting.value =
+ if (saved.vomiting == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ isDiarrhea.value =
+ if (saved.diarrhea == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ if (saved.caseStatus != null) {
+ caseStatus.value =
+ getLocalValueInArray(R.array.dc_case_status, saved.caseStatus)
+ }
+
+ rapidDiagnostic.value = getLocalValueInArray(R.array.positive_negative, saved.rapidDiagnosticTest)
+ ?: resources.getStringArray(R.array.positive_negative)[2]
+
+ slideTestPv.value = getLocalValueInArray(R.array.positive_negative, saved.slideTestPv)
+ ?: resources.getStringArray(R.array.positive_negative)[2]
+
+ slideTestPf.value = getLocalValueInArray(R.array.positive_negative, saved.slideTestPf)
+ ?: resources.getStringArray(R.array.positive_negative)[2]
+
+
+ if (saved.malariaSlideTestType != 0) {
+ slideTestOptions.value = resources.getStringArray(R.array.pf_pv)[saved.malariaSlideTestType!!-1]
+
+ }
+ beneficiaryStatus.value =
+ getLocalValueInArray(beneficiaryStatus.arrayId, saved.beneficiaryStatus)
+
+
+ if (beneficiaryStatus.value == beneficiaryStatus.entries!!.last()) {
+ list.add(list.indexOf(beneficiaryStatus) + 1, dateOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 2, placeOfDeath)
+ list.add(list.indexOf(beneficiaryStatus) + 3, reasonOfDeath)
+ list.remove(isFever)
+ list.remove(isDiarrhea)
+ list.remove(isFluLikeIllness)
+ list.remove(isShakingchills)
+ list.remove(isHeadache)
+ list.remove(isMuscleaches)
+ list.remove(isTiredness)
+ list.remove(isNausea)
+ list.remove(isVomiting)
+ list.remove(headline)
+ list.remove(caseStatus)
+
+
+ dateOfDeath.value =
+ getDateFromLong(saved.dateOfDeath)
+ placeOfDeath.value =
+ getLocalValueInArray(placeOfDeath.arrayId, saved.placeOfDeath)
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ otherPlaceOfDeath.value = saved.otherPlaceOfDeath
+ }
+
+ reasonOfDeath.value =
+ getLocalValueInArray(reasonOfDeath.arrayId, saved.reasonForDeath)
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ list.add(list.indexOf(reasonOfDeath) + 1, otherReasonOfDeath)
+ otherReasonOfDeath.value = saved.otherReasonForDeath
+ }
+ } else {
+ /* list.add(list.indexOf(beneficiaryStatus) + 1, headline)
+ list.add(list.indexOf(beneficiaryStatus) + 2, isFever)
+ list.add(list.indexOf(beneficiaryStatus) + 3, isFluLikeIllness)
+ list.add(list.indexOf(beneficiaryStatus) + 4, isShakingchills)
+ list.add(list.indexOf(beneficiaryStatus) + 5, isHeadache)
+ list.add(list.indexOf(beneficiaryStatus) + 6, isMuscleaches)
+ list.add(list.indexOf(beneficiaryStatus) + 7, isTiredness)
+ list.add(list.indexOf(beneficiaryStatus) + 8, isNausea)
+ list.add(list.indexOf(beneficiaryStatus) + 9, isVomiting)
+ list.add(list.indexOf(beneficiaryStatus) + 10, isDiarrhea)
+ list.add(list.indexOf(beneficiaryStatus) + 11, caseStatus)*/
+ /* list.add(list.indexOf(beneficiaryStatus) + 12, rapidDiagnostic)
+ list.add(list.indexOf(beneficiaryStatus) + 13, referredTo)
+ list.add(list.indexOf(beneficiaryStatus) + 14, remarks)
+ list.add(list.indexOf(beneficiaryStatus) + 15, dateOfVisitBySupervisor)*/
+
+
+ if (caseStatus.value == resources.getStringArray(R.array.dc_case_status)[0] || caseStatus.value == resources.getStringArray(R.array.dc_case_status)[1] || caseStatus.value == resources.getStringArray(R.array.dc_case_status)[2]) {
+ list.add(list.indexOf(caseStatus) + 1, testType)
+ if (testType.value == resources.getStringArray(R.array.test_type)[0]) {
+ list.add(list.indexOf(testType) + 1, rapidDiagnostic)
+ if (rapidDiagnostic.value != resources.getStringArray(R.array.positive_negative)[2]) {
+ list.add(list.indexOf(rapidDiagnostic) + 1, dateOfTest)
+ dateOfTest.value = getDateFromLong(saved.dateOfRdt)
+
+ }
+
+
+ } else if (testType.value == resources.getStringArray(R.array.test_type)[1]) {
+ list.add(list.indexOf(testType) + 1, slideTestOptions)
+ if (slideTestOptions.value == resources.getStringArray(R.array.pf_pv)[0]) {
+ list.add(list.indexOf(slideTestOptions) + 1, slideTestPf)
+ } else {
+ list.add(list.indexOf(slideTestOptions) + 1, slideTestPv)
+ }
+ if (slideTestPv.value != resources.getStringArray(R.array.positive_negative)[2]) {
+ list.add(list.indexOf(slideTestPv) + 1, dateOfSlidetest)
+ dateOfSlidetest.value = getDateFromLong(saved.dateOfSlideTest)
+ }
+
+ if (slideTestPf.value != resources.getStringArray(R.array.positive_negative)[2]) {
+ list.add(list.indexOf(slideTestPf) + 1, dateOfSlidetest)
+ dateOfSlidetest.value = getDateFromLong(saved.dateOfSlideTest)
+ }
+
+ } else {
+ list.add(list.indexOf(testType) + 1, rapidDiagnostic)
+ if (rapidDiagnostic.value != resources.getStringArray(R.array.positive_negative)[2]) {
+ list.add(list.indexOf(rapidDiagnostic) + 1, dateOfTest)
+ dateOfTest.value = getDateFromLong(saved.dateOfRdt)
+ list.add(list.indexOf(rapidDiagnostic) + 2, slideTestOptions)
+
+ }
+
+ if (slideTestOptions.value == resources.getStringArray(R.array.pf_pv)[0]) {
+ list.add(list.indexOf(slideTestOptions) + 1, slideTestPf)
+ } else {
+ list.add(list.indexOf(slideTestOptions) + 1, slideTestPv)
+ }
+ if (slideTestPv.value != resources.getStringArray(R.array.positive_negative)[2]) {
+ list.add(list.indexOf(slideTestPv) + 1, dateOfSlidetest)
+ dateOfSlidetest.value = getDateFromLong(saved.dateOfSlideTest)
+ }
+
+ if (slideTestPf.value != resources.getStringArray(R.array.positive_negative)[2]) {
+ list.add(list.indexOf(slideTestPf) + 1, dateOfSlidetest)
+ dateOfSlidetest.value = getDateFromLong(saved.dateOfSlideTest)
+ }
+ }
+
+ } else if (caseStatus.value == resources.getStringArray(R.array.dc_case_status)[1]) {
+ list.add(list.indexOf(caseStatus) + 1, testType)
+ }
+
+
+
+
+
+
+
+ }
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ if (referredTo.value == referredTo.entries!![referredTo.entries!!.size - 2]) {
+ referredTo.value = saved.referToName
+ list.add(list.indexOf(referredTo) + 1, other)
+ } else {
+ referredTo.value =
+ getLocalValueInArray(referredTo.arrayId, saved.referToName)
+ }
+
+ other.value = saved.otherReferredFacility
+ followUpdate.value = getDateFromLong(saved.followUpDate)
+
+ }
+
+ setUpPage(list)
+
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+
+ return when (formId) {
+
+ isFever.id,
+ isFluLikeIllness.id,
+ isShakingchills.id,
+ isHeadache.id,
+ isMuscleaches.id,
+ isTiredness.id,
+ isNausea.id,
+ isVomiting.id,
+ isDiarrhea.id -> {
+
+ val yesValue = resources.getStringArray(R.array.yes_no)[0]
+ val suspectedValue = resources.getStringArray(R.array.dc_case_status)[0]
+ val notConfirmedValue = resources.getStringArray(R.array.dc_case_status)[2]
+
+ val symptoms = listOf(
+ isFluLikeIllness.value,
+ isShakingchills.value,
+ isHeadache.value,
+ isMuscleaches.value,
+ isTiredness.value,
+ isNausea.value,
+ isVomiting.value,
+ isDiarrhea.value
+ )
+
+ val nonFeverYesCount = symptoms.count { it == yesValue }
+
+ caseStatus.value = when {
+ isFever.value == yesValue -> suspectedValue
+ nonFeverYesCount >= 2 -> suspectedValue
+ else -> notConfirmedValue
+ }
+
+ if(caseStatus.value == suspectedValue){
+ triggerDependants(
+ source = caseStatus,
+ addItems = listOf(testType),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = caseStatus,
+ addItems = listOf(),
+ removeItems = listOf(testType)
+ )
+ }
+ }
+
+ caseStatus.id -> {
+ if(caseStatus.value == resources.getStringArray(R.array.dc_case_status)[0]){
+ triggerDependants(
+ source = caseStatus,
+ addItems = listOf(testType),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = caseStatus,
+ addItems = listOf(),
+ removeItems = listOf(testType)
+ )
+ }
+ 0
+ }
+
+
+ testType.id -> {
+ if(testType.value == resources.getStringArray(R.array.test_type)[0]){
+ triggerDependants(
+ source = testType,
+ addItems = listOf(rapidDiagnostic),
+ removeItems = listOf(slideTestOptions,slideTestPf,slideTestPv,dateOfTest,dateOfSlidetest)
+ )
+ } else if(testType.value == resources.getStringArray(R.array.test_type)[1]){
+ triggerDependants(
+ source = testType,
+ addItems = listOf(slideTestOptions),
+ removeItems = listOf(rapidDiagnostic,slideTestPf,slideTestPv,dateOfTest,dateOfSlidetest)
+ )
+ } else {
+ triggerDependants(
+ source = testType,
+ addItems = listOf(rapidDiagnostic,slideTestOptions),
+ removeItems = listOf(slideTestPf,slideTestPv,dateOfTest,dateOfSlidetest)
+ )
+ }
+ 0
+ }
+
+ beneficiaryStatus.id -> {
+ if (beneficiaryStatus.value == beneficiaryStatus.entries!!.last()) {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(dateOfDeath,placeOfDeath,reasonOfDeath),
+ removeItems = listOf(headline,isFever,isFluLikeIllness,isShakingchills,isHeadache,
+ isMuscleaches,isTiredness,isNausea,isVomiting,isDiarrhea,
+ caseStatus,rapidDiagnostic,slideTestPf,slideTestPv,referredTo,
+ remarks,dateOfVisitBySupervisor)
+ )
+ } else {
+ triggerDependants(
+ source = beneficiaryStatus,
+ addItems = listOf(headline,isFever,isFluLikeIllness,isShakingchills,isHeadache,
+ isMuscleaches,isTiredness,isNausea,isVomiting,isDiarrhea,
+ caseStatus),
+ removeItems = listOf(dateOfDeath,placeOfDeath,reasonOfDeath)
+ )
+ }
+ 0
+ }
+
+ referredTo.id -> {
+ if (referredTo.value == referredTo.entries!![referredTo.entries!!.size - 2]) {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(other),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = referredTo,
+ addItems = listOf(),
+ removeItems = listOf(other)
+ )
+ }
+ 0
+ }
+
+ other.id -> {
+ validateEmptyOnEditText(other)
+ }
+
+ placeOfDeath.id -> {
+ if (placeOfDeath.value == placeOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(otherPlaceOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = placeOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherPlaceOfDeath)
+ )
+ }
+ 0
+ }
+ otherPlaceOfDeath.id -> {
+ validateEmptyOnEditText(otherPlaceOfDeath)
+
+ }
+
+ rapidDiagnostic.id -> {
+ if (rapidDiagnostic.value == resources.getStringArray(R.array.positive_negative)[2]) {
+
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(),
+ removeItems = listOf(dateOfTest,slideTestOptions,slideTestPf,slideTestPv,dateOfSlidetest)
+ )
+ } else if (rapidDiagnostic.value == resources.getStringArray(R.array.positive_negative)[1]) {
+ if (testType.value == resources.getStringArray(R.array.test_type)[2]) {
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(dateOfTest,slideTestOptions),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(dateOfTest),
+ removeItems = listOf(slideTestOptions,slideTestPf,slideTestPv)
+ )
+ }
+
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[2]
+
+
+// caseStatus.value = getLocalValueInArray(caseStatus.arrayId, resources.getStringArray(R.array.dc_case_status)[1])
+ } else {
+ if (testType.value == resources.getStringArray(R.array.test_type)[2]) {
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(dateOfTest,slideTestOptions),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(dateOfTest),
+ removeItems = listOf(slideTestOptions,slideTestPf,slideTestPv)
+ )
+ }
+ /* triggerDependants(
+ source = rapidDiagnostic,
+ addItems = listOf(dateOfTest),
+ removeItems = listOf()
+ )*/
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[1]
+
+
+ }
+ 0
+ }
+
+ slideTestOptions.id -> {
+ slideTestOptions.isEnabled = true
+ if (slideTestOptions.value == resources.getStringArray(R.array.pf_pv)[0]) {
+ triggerDependants(
+ source = slideTestOptions,
+ addItems = listOf(slideTestPf),
+ removeItems = listOf(slideTestPv)
+ )
+ } else if (slideTestOptions.value == resources.getStringArray(R.array.pf_pv)[1]) {
+
+ triggerDependants(
+ source = slideTestOptions,
+ addItems = listOf(slideTestPv),
+ removeItems = listOf(slideTestPf)
+ )
+ }
+ 0
+ }
+
+ slideTestPv.id -> {
+ slideTestPv.isEnabled = true
+ if (slideTestPv.value == resources.getStringArray(R.array.positive_negative)[0]) {
+ triggerDependants(
+ source = slideTestPv,
+ addItems = listOf(dateOfSlidetest),
+ removeItems = listOf()
+ )
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[1]
+
+
+
+ } else if (slideTestPv.value == resources.getStringArray(R.array.positive_negative)[1]) {
+
+ triggerDependants(
+ source = slideTestPv,
+ addItems = listOf(dateOfSlidetest),
+ removeItems = listOf()
+ )
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[2]
+
+
+
+ } else {
+ triggerDependants(
+ source = slideTestPv,
+ addItems = listOf(),
+ removeItems = listOf(dateOfSlidetest)
+ )
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[2]
+
+
+
+ }
+ 0
+ }
+
+ slideTestPf.id -> {
+ slideTestPf.isEnabled = true
+ if (slideTestPf.value == resources.getStringArray(R.array.positive_negative)[0]) {
+ triggerDependants(
+ source = slideTestPf,
+ addItems = listOf(dateOfSlidetest),
+ removeItems = listOf()
+ )
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[1]
+
+
+
+ } else if (slideTestPf.value == resources.getStringArray(R.array.positive_negative)[1]) {
+
+ triggerDependants(
+ source = slideTestPf,
+ addItems = listOf(dateOfSlidetest),
+ removeItems = listOf()
+ )
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[2]
+
+
+
+ } else {
+ triggerDependants(
+ source = slideTestPf,
+ addItems = listOf(),
+ removeItems = listOf(dateOfSlidetest)
+ )
+
+ caseStatus.value = resources.getStringArray(R.array.dc_case_status)[2]
+
+
+
+ }
+ 0
+ }
+
+ reasonOfDeath.id -> {
+ if (reasonOfDeath.value == reasonOfDeath.entries!!.last()) {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(otherReasonOfDeath),
+ removeItems = listOf()
+ )
+ } else {
+ triggerDependants(
+ source = reasonOfDeath,
+ addItems = listOf(),
+ removeItems = listOf(otherReasonOfDeath)
+ )
+ }
+ 0
+ }
+ otherReasonOfDeath.id -> {
+ validateEmptyOnEditText(otherReasonOfDeath)
+ }
+
+ else -> {
+ 0
+ }
+ }
+
+
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as MalariaScreeningCache).let { form ->
+ form.caseDate = getLongFromDate(dateOfCase.value)
+ form.feverMoreThanTwoWeeks =
+ isFever.value == resources.getStringArray(R.array.yes_no)[0]
+ form.fluLikeIllness = isFluLikeIllness.value == resources.getStringArray(R.array.yes_no)[0]
+ form.shakingChills = isShakingchills.value == resources.getStringArray(R.array.yes_no)[0]
+ form.headache = isHeadache.value == resources.getStringArray(R.array.yes_no)[0]
+ form.muscleAches = isMuscleaches.value == resources.getStringArray(R.array.yes_no)[0]
+ form.tiredness = isTiredness.value == resources.getStringArray(R.array.yes_no)[0]
+ form.nausea =
+ isNausea.value == resources.getStringArray(R.array.yes_no)[0]
+ form.vomiting =
+ isVomiting.value == resources.getStringArray(R.array.yes_no)[0]
+ form.diarrhea =
+ isDiarrhea.value == resources.getStringArray(R.array.yes_no)[0]
+ form.caseStatus = getEnglishValueInArray(R.array.dc_case_status, caseStatus.value)
+ form.referToName = getEnglishValueInArray(R.array.dc_refer_malaria, referredTo.value)
+ form.referredTo = referredTo.getPosition()
+ form.beneficiaryStatus = getEnglishValueInArray(R.array.benificary_case_status, beneficiaryStatus.value)
+ form.beneficiaryStatusId = beneficiaryStatus.getPosition()
+ form.reasonForDeath = getEnglishValueInArray(R.array.reason_death, reasonOfDeath.value)
+ form.otherPlaceOfDeath = otherPlaceOfDeath.value
+ form.otherReasonForDeath = otherReasonOfDeath.value
+ form.dateOfDeath = getLongFromDate(dateOfDeath.value)
+ form.dateOfRdt = getLongFromDate(dateOfTest.value)
+ form.dateOfSlideTest = getLongFromDate(dateOfSlidetest.value)
+ form.placeOfDeath = getEnglishValueInArray(R.array.death_place, placeOfDeath.value)
+ form.otherReferredFacility = other.value
+ form.rapidDiagnosticTest = getEnglishValueInArray(R.array.positive_negative, rapidDiagnostic.value)
+ form.slideTestPv = getEnglishValueInArray(R.array.positive_negative, slideTestPv.value)
+ form.slideTestPf = getEnglishValueInArray(R.array.positive_negative, slideTestPf.value)
+ form.slideTestName = getEnglishValueInArray(R.array.pf_pv, slideTestOptions.value)
+ form.remarks = remarks.value
+ form.dateOfVisitBySupervisor = getLongFromDate(dateOfVisitBySupervisor.value)
+ form.diseaseTypeID = 1
+ form.followUpDate = getLongFromDate(followUpdate.value)
+ form.visitId = 1
+ form.malariaTestType = testType.getPosition()
+ form.malariaSlideTestType = slideTestOptions.getPosition()
+
+ }
+ }
+
+
+ fun updateBen(benRegCache: BenRegCache) {
+ benRegCache.genDetails?.let {
+ it.reproductiveStatus =
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
+ it.reproductiveStatusId = 2
+ }
+ if (benRegCache.processed != "N") benRegCache.processed = "U"
+ }
+
+
+ fun getIndexOfDate(): Int {
+ return getIndexById(dateOfCase.id)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/NewChildBenRegDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/NewChildBenRegDataset.kt
new file mode 100644
index 000000000..1ec09b1f2
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/NewChildBenRegDataset.kt
@@ -0,0 +1,1508 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.text.InputType
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Konstants
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
+import org.piramalswasthya.sakhi.model.AgeUnit
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.EligibleCoupleRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.Gender
+import org.piramalswasthya.sakhi.model.Gender.FEMALE
+import org.piramalswasthya.sakhi.model.Gender.MALE
+import org.piramalswasthya.sakhi.model.Gender.TRANSGENDER
+import org.piramalswasthya.sakhi.model.HouseholdCache
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.HEADLINE
+import org.piramalswasthya.sakhi.model.InputType.RADIO
+import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
+import org.piramalswasthya.sakhi.ui.home_activity.all_ben.new_ben_registration.ben_form.NewBenRegViewModel.Companion.isOtpVerified
+import org.piramalswasthya.sakhi.utils.HelperUtil.getDiffYears
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+
+
+class NewChildBenRegDataset(context: Context, language: Languages) : Dataset(context, language) {
+
+
+ companion object {
+ private fun getCurrentDateString(): String {
+ val calendar = Calendar.getInstance()
+ val mdFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ return mdFormat.format(calendar.time)
+ }
+
+ private fun getLongFromDate(dateString: String): Long {
+ val f = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val date = f.parse(dateString)
+ return date?.time ?: throw IllegalStateException("Invalid date for dateReg")
+ }
+
+ private fun getMinLmpMillis(): Long {
+ val cal = Calendar.getInstance()
+ cal.add(Calendar.DAY_OF_YEAR, -1 * 400) //before it is 280
+ return cal.timeInMillis
+ }
+
+ private fun getMinDobMillis(): Long {
+ val cal = Calendar.getInstance()
+ cal.add(Calendar.YEAR, -15)
+ cal.add(Calendar.DAY_OF_MONTH, +1)
+ return cal.timeInMillis
+ }
+
+ private fun getMaxDobMillis(): Long {
+ return System.currentTimeMillis()
+ }
+
+ fun getMinimumSecondChildDob(firstChildDobStr: String?): String {
+
+ val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val firstChildDob = dateFormat.parse(firstChildDobStr)
+
+ val calendar = Calendar.getInstance()
+ calendar.time = firstChildDob!!
+
+ return dateFormat.format(calendar.time)
+ }
+ }
+
+ private var isExistingRecord = false
+ private var selectedBen: BenRegCache? = null
+ private val rchId = 0L
+ private val dateOfReg = FormElement(
+ id = 0,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_date_of_reg),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = 0L,
+ hasDependants = true,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_anc_date,
+ showDrawable = true
+ )
+
+ private val elderChildrenCount = FormElement(
+ id = 1,
+ inputType = org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW,
+ title = resources.getString(R.string.no_of_elderly_children),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+
+ )
+
+
+ private val ageRestrictionLabel = FormElement(
+ id = 69,
+ inputType = org.piramalswasthya.sakhi.model.InputType.CHECKBOXES,
+ title = resources.getString(R.string.ecrdset_reg_children_15_below),
+ arrayId = -1,
+ required = false,
+ headingLine = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 1,
+ max = 9,
+ min = 0,
+ )
+
+ val noOfChildren = FormElement(
+ id = 12,
+ inputType = org.piramalswasthya.sakhi.model.InputType.NUMBER_PICKER,
+ title = resources.getString(R.string.ecrdset_no_live_child),
+ required = false,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 1,
+ max = 9,
+ min = 0,
+
+ )
+
+
+ private val numMale = FormElement(
+ id = 14,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_male),
+ arrayId = -1,
+ required = false,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 1,
+ max = 9,
+ min = 0,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_male,
+ showDrawable = true
+ )
+
+ private val numFemale = FormElement(
+ id = 15,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_female),
+ arrayId = -1,
+ required = false,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 1,
+ max = 9,
+ min = 0,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_female,
+ showDrawable = true
+
+ )
+
+ private val ageAtMarriage = FormElement(
+ id = 5,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_cur_ag_of_wo_marr),
+ arrayId = -1,
+ required = false,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForGenBen.toLong(),
+ min = Konstants.minAgeForGenBen.toLong(),
+ isEnabled = false,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_age_of_women_at_marriage,
+ showDrawable = true
+ )
+
+ private val firstChildDetails = FormElement(
+ id = 16,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dls_1_child),
+ arrayId = -1,
+ required = false,
+
+ )
+
+ private val firstChildName = FormElement(
+ id = 111,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ private val dob1 = FormElement(
+ id = 17,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_1_child_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_anc_date,
+ showDrawable = true
+ )
+
+ private val age1 = FormElement(
+ id = 18,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_1_child_age_in_yrs),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_no_of_live_child,
+ showDrawable = true
+ )
+
+ private val gender1 = FormElement(
+ id = 19,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_1_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val marriageFirstChildGap = FormElement(
+ id = 20,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_1_child_marr),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ backgroundDrawable=R.drawable.ic_bg_circular,
+ iconDrawableRes=R.drawable.ic_gap_bet_marriage_child,
+ showDrawable = true
+ )
+
+ private val secondChildDetails = FormElement(
+ id = 21,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dts_2_child),
+ arrayId = -1,
+ required = false
+ )
+ private val secondChildName = FormElement(
+ id = 112,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val dob2 = FormElement(
+ id = 22,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_2_child_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age2 = FormElement(
+ id = 23,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_2_child_age_yrs),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender2 = FormElement(
+ id = 24,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_2_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val firstAndSecondChildGap = FormElement(
+ id = 25,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_1_child_2_child),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ private val thirdChildDetails = FormElement(
+ id = 26,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dts_3_child),
+ arrayId = -1,
+ required = false
+ )
+
+ private val thirdChildName = FormElement(
+ id = 113,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val dob3 = FormElement(
+ id = 27,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_3_child_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age3 = FormElement(
+ id = 28,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_3_child_age_yrs),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender3 = FormElement(
+ id = 29,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_3_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val secondAndThirdChildGap = FormElement(
+ id = 30,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_bet_2_3_child_sex),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ private val fourthChildDetails = FormElement(
+ id = 31,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dts_4_child),
+ arrayId = -1,
+ required = false
+ )
+
+ private val forthChildName = FormElement(
+ id = 114,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val dob4 = FormElement(
+ id = 32,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_4_child_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age4 = FormElement(
+ id = 33,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_4_child_age_yrs),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender4 = FormElement(
+ id = 34,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_4_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val thirdAndFourthChildGap = FormElement(
+ id = 35,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_bet_3_4_child),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ private val fifthChildDetails = FormElement(
+ id = 36,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dts_5_child),
+ arrayId = -1,
+ required = false
+ )
+
+ private val fifthChildName = FormElement(
+ id = 115,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val dob5 = FormElement(
+ id = 37,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_5_child_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age5 = FormElement(
+ id = 38,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_5_child_age_yrs),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender5 = FormElement(
+ id = 39,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_5_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val fourthAndFifthChildGap = FormElement(
+ id = 40,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_4_5_child),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ private val sixthChildDetails = FormElement(
+ id = 41,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dts_6_child),
+ arrayId = -1,
+ required = false
+ )
+
+ private val sixthChildName = FormElement(
+ id = 116,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val dob6 = FormElement(
+ id = 42,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_dts_6_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age6 = FormElement(
+ id = 43,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_6_child_age),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender6 = FormElement(
+ id = 44,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_6_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val fifthAndSixthChildGap = FormElement(
+ id = 45,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_5_6_child),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ private val seventhChildDetails = FormElement(
+ id = 46,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_7_dts_child),
+ arrayId = -1,
+ required = false
+ )
+
+ private val seventhChildName = FormElement(
+ id = 117,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ private val dob7 = FormElement(
+ id = 47,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_7_child_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age7 = FormElement(
+ id = 48,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_7_child_age_yrs),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender7 = FormElement(
+ id = 49,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_7_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val sixthAndSeventhChildGap = FormElement(
+ id = 50,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_6_7_child),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ private val eighthChildDetails = FormElement(
+ id = 51,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dts_8_child),
+ arrayId = -1,
+ required = false
+ )
+
+ private val eightChildName = FormElement(
+ id = 118,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val dob8 = FormElement(
+ id = 52,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_8_child_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age8 = FormElement(
+ id = 53,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_8_child_age),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender8 = FormElement(
+ id = 54,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_8_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val seventhAndEighthChildGap = FormElement(
+ id = 55,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_7_8_child),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ private val ninthChildDetails = FormElement(
+ id = 56,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.ecrdset_dts_9_child),
+ arrayId = -1,
+ required = false
+ )
+
+ private val ninthChildName = FormElement(
+ id = 119,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.nbr_child_first_name),
+ arrayId = -1,
+ required = true,
+ allCaps = true,
+ hasSpeechToText = true,
+ etInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+ private val dob9 = FormElement(
+ id = 57,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.ecrdset_9_bth),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ max = getMaxDobMillis(),
+ min = getMinDobMillis(),
+ )
+
+ private val age9 = FormElement(
+ id = 58,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_9_age_yrs),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = Konstants.maxAgeForAdolescent.toLong(),
+ min = 0,
+ )
+
+ private val gender9 = FormElement(
+ id = 59,
+ inputType = RADIO,
+ title = resources.getString(R.string.ecrdset_9_child_sex),
+ arrayId = -1,
+ entries = resources.getStringArray(R.array.ecr_gender_array),
+ required = true,
+ hasDependants = true,
+ )
+
+ private var maleChild = 0
+
+ private var femaleChild = 0
+
+ private var dateOfBirth = 0L
+
+ private var lastDeliveryDate = 0L
+ private var timeAtMarriage: Long = 0L
+ private val eighthAndNinthChildGap = FormElement(
+ id = 60,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.ecrdset_gap_8_9_child),
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 2,
+ max = 99,
+ min = 0,
+ )
+
+ suspend fun setUpPage(
+ ben: EligibleCoupleRegCache?,
+ household: HouseholdCache,
+ hoF: BenRegCache?,
+ benGender: Gender,
+ relationToHeadId: Int,
+ hoFSpouse: List = emptyList(),
+ selectedben: BenRegCache?,
+ isAddspouse: Int,
+ childList: List,
+ elderChildCount: Int
+
+ ) {
+ val list = mutableListOf(
+ dateOfReg,
+ elderChildrenCount,
+ ageRestrictionLabel,
+ noOfChildren,
+
+
+
+ )
+
+ isExistingRecord = ben != null
+
+ selectedBen = selectedben
+ selectedben?.let {
+ dateOfReg.min = it.regDate
+ selectedben.genDetails?.ageAtMarriage?.let { it1 ->
+ ageAtMarriage.value = it1.toString()
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = selectedben.dob
+ cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + it1)
+ timeAtMarriage = cal.timeInMillis
+ }
+ }
+
+
+
+ /* if (ecCache.dateOfReg == 0L) {
+ ecCache.dateOfReg = System.currentTimeMillis()
+ }*/
+
+ dateOfReg.value = getDateFromLong(System.currentTimeMillis())
+
+ noOfChildren.value = childList.size.toString()
+
+ elderChildrenCount.value = elderChildCount.coerceAtMost(5).toString()
+
+
+ var insertIndex = list.indexOf(noOfChildren) + 1
+
+ childList.forEachIndexed { index, child ->
+
+ val bundle = children[index]
+
+ bundle.name.value = child.firstName
+ bundle.dob.value = getDateFromLong(child.dob)
+ bundle.age.value = child.age?.toString()
+
+ bundle.gender.value = getLocalValueInArray(
+ R.array.ecr_gender_array,
+ child.gender?.name
+ ?.lowercase()
+ ?.replaceFirstChar { it.uppercase() }
+ )
+
+ if (index == 0) {
+ setSiblingAgeDiff(timeAtMarriage, child.dob, bundle.gap)
+ } else {
+ setSiblingAgeDiff(
+ childList[index - 1].dob,
+ child.dob,
+ bundle.gap
+ )
+ }
+
+ val childViews = listOf(
+ bundle.name,
+ bundle.dob,
+ bundle.age,
+ bundle.gender,
+ bundle.gap
+ )
+
+ list.addAll(insertIndex, childViews)
+
+ insertIndex += childViews.size
+ }
+
+ setUpPage(list)
+
+ }
+
+
+ private suspend fun updateTimeLessThan18() {
+ val dobStrings = listOf(
+ dob1.value, dob2.value, dob3.value, dob4.value, dob5.value,
+ dob6.value, dob7.value, dob8.value, dob9.value
+ ).filter { !it.isNullOrBlank() }
+
+ if (dobStrings.isNotEmpty()) {
+ val dobLongs = dobStrings.map { getLongFromDate(it!!) }
+ lastDeliveryDate = dobLongs.maxOrNull()!!
+ }
+
+ }
+
+ private fun setSiblingAgeDiff(old: Long, new: Long, target: FormElement) {
+ val calOld = Calendar.getInstance().setToStartOfTheDay().apply {
+ timeInMillis = old
+ }
+ val calNew = Calendar.getInstance().setToStartOfTheDay().apply {
+ timeInMillis = new
+ }
+ val diff = getDiffYears(calOld, calNew)
+ target.value = "${diff.toString()} years"
+ }
+
+ private fun getRelationStringFromId(familyHeadRelationId: Int): String {
+ return if (familyHeadRelationId == 9)
+ "Son"
+ else
+ "Daughter"
+ }
+
+ private fun getFamilyHeadRelationFromMother(childGender: Gender): Int {
+ return if (childGender == Gender.MALE)
+ 9
+ else
+ 10
+ }
+ fun mapChild(
+ cacheModel: BenRegCache,
+ childIndex: Int
+ ): BenRegCache {
+
+ val ben = cacheModel.copy()
+ val childGender = getChildGender(childIndex)
+ if (childGender == null) {
+ throw IllegalStateException("Gender must be selected for child $childIndex")
+ }
+ val familyHeadRelationId =
+ getFamilyHeadRelationFromMother(childGender)
+ val familyHeadRelation = getRelationStringFromId(familyHeadRelationId)
+ when(childIndex) {
+
+ 1 -> {
+ ben.firstName = firstChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob1.value!!)
+ ben.age = age1.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender1.value) {
+ gender1.entries!![0] -> 1
+ gender1.entries!![1] -> 2
+ gender1.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+ 2 -> {
+ ben.firstName = secondChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob2.value!!)
+ ben.age = age2.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender2.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+
+ 3 -> {
+ ben.firstName = thirdChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob3.value!!)
+ ben.age = age3.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender3.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+
+ 4 -> {
+ ben.firstName = forthChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob4.value!!)
+ ben.age = age4.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender4.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+ 5 -> {
+ ben.firstName = fifthChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob5.value!!)
+ ben.age = age5.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender5.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+ 6 -> {
+ ben.firstName = sixthChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob6.value!!)
+ ben.age = age6.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender6.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+ 7 -> {
+ ben.firstName = seventhChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob7.value!!)
+ ben.age = age7.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender7.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+ 8 -> {
+ ben.firstName = eightChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob8.value!!)
+ ben.age = age8.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender8.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+ 9 -> {
+ ben.firstName = ninthChildName.value
+ ben.lastName = selectedBen?.lastName
+ ben.dob = Dataset.getLongFromDate(dob9.value!!)
+ ben.age = age9.value!!.toInt()
+ ben.ageUnitId = 3
+ ben.ageUnit = AgeUnit.YEARS
+ ben.isAdult = ben.ageUnit == AgeUnit.YEARS && ben.age >= 15
+ ben.isKid = !ben.isAdult
+ ben.genderId = when (gender9.value) {
+ gender2.entries!![0] -> 1
+ gender2.entries!![1] -> 2
+ gender2.entries!![2] -> 3
+ else -> 0
+ }
+ ben.gender = when (ben.genderId) {
+ 1 -> MALE
+ 2 -> FEMALE
+ 3 -> TRANSGENDER
+ else -> null
+ }
+ ben.familyHeadRelation = familyHeadRelation
+ ben.familyHeadRelationPosition = familyHeadRelationId
+ }
+ }
+
+ ben.householdId = selectedBen?.householdId!!
+ ben.regDate = Dataset.Companion.getLongFromDate(dateOfReg.value!!)
+ ben.fatherName = "${selectedBen?.genDetails?.spouseName}"
+ ben.motherName = "${selectedBen?.firstName}"
+ ben.isDeath = false
+ ben.isDeathValue = "false"
+ ben.dateOfDeath = null
+ ben.timeOfDeath = null
+ ben.reasonOfDeath = null
+ ben.doYouHavechildren = false
+ ben.placeOfDeath = null
+ ben.mobileNoOfRelationId = 5
+ ben.otherPlaceOfDeath = null
+ ben.contactNumber = selectedBen!!.contactNumber
+ ben.mobileNoOfRelationId = 5
+ ben.isDraft = false
+ ben.isConsent = isOtpVerified
+ ben.isSpouseAdded = false
+ ben.isChildrenAdded = false
+ ben.isMarried = false
+ ben.doYouHavechildren = false
+ ben.community = selectedBen!!.community
+ ben.communityId = selectedBen!!.communityId
+
+ return ben
+ }
+
+ private fun mapGender(genderField: FormElement): Gender? {
+ return when (genderField.value) {
+ genderField.entries?.getOrNull(0) -> MALE
+ genderField.entries?.getOrNull(1) -> FEMALE
+ genderField.entries?.getOrNull(2) -> TRANSGENDER
+ else -> null
+ }
+ }
+
+ private fun getChildGender(childIndex: Int): Gender? {
+ return when (childIndex) {
+ 1 -> mapGender(gender1)
+ 2 -> mapGender(gender2)
+ 3 -> mapGender(gender3)
+ 4 -> mapGender(gender4)
+ 5 -> mapGender(gender5)
+ 6 -> mapGender(gender6)
+ 7 -> mapGender(gender7)
+ 8 -> mapGender(gender8)
+ 9 -> mapGender(gender9)
+ else -> null
+ }
+ }
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as EligibleCoupleRegCache).let { ecr ->
+ ecr.dateOfReg =
+ getLongFromDate(dateOfReg.value!!)
+
+ ecr.noOfChildren = noOfChildren.value?.takeIf { it.isNotBlank() }?.toInt() ?: 0
+ ecr.noOfMaleChildren = numMale.value?.takeIf { it.isNotBlank() }?.toInt() ?: 0
+ ecr.noOfFemaleChildren = numFemale.value?.takeIf { it.isNotBlank() }?.toInt() ?: 0
+ ecr.dob1 = getLongFromDate(dob1.value)
+ ecr.age1 = age1.value?.toInt()
+ ecr.gender1 = when (gender1.value) {
+ gender1.entries!![0] -> Gender.MALE
+ gender1.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.marriageFirstChildGap =marriageFirstChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ if ((noOfChildren.value?.toIntOrNull() ?: 0) > 1){
+ ecr.dob2 = getLongFromDate(dob2.value)
+ ecr.age2 = age2.value?.toInt()
+ ecr.gender2 = when (gender2.value) {
+ gender2.entries!![0] -> Gender.MALE
+ gender2.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.firstAndSecondChildGap =firstAndSecondChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ if (noOfChildren.value?.toInt()!! > 2) {
+ ecr.dob3 = getLongFromDate(dob3.value)
+ ecr.age3 = age3.value?.toInt()
+ ecr.gender3 = when (gender3.value) {
+ gender3.entries!![0] -> Gender.MALE
+ gender3.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.secondAndThirdChildGap =secondAndThirdChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ if (noOfChildren.value?.toInt()!! > 3) {
+ ecr.dob4 = getLongFromDate(dob4.value)
+ ecr.age4 = age4.value?.toInt()
+ ecr.gender4 = when (gender4.value) {
+ gender4.entries!![0] -> Gender.MALE
+ gender4.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.thirdAndFourthChildGap =thirdAndFourthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ if (noOfChildren.value?.toInt()!! > 4) {
+ ecr.dob5 = getLongFromDate(dob5.value)
+ ecr.age5 = age5.value?.toInt()
+ ecr.gender5 = when (gender5.value) {
+ gender5.entries!![0] -> Gender.MALE
+ gender5.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.fourthAndFifthChildGap =fourthAndFifthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ if (noOfChildren.value?.toInt()!! > 5) {
+ ecr.dob6 = getLongFromDate(dob6.value)
+ ecr.age6 = age6.value?.toInt()
+ ecr.gender6 = when (gender6.value) {
+ gender6.entries!![0] -> Gender.MALE
+ gender6.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.fifthANdSixthChildGap =fifthAndSixthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ if (noOfChildren.value?.toInt()!! > 6) {
+ ecr.dob7 = getLongFromDate(dob7.value)
+ ecr.age7 = age7.value?.toInt()
+ ecr.gender7 = when (gender7.value) {
+ gender7.entries!![0] -> Gender.MALE
+ gender7.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.sixthAndSeventhChildGap =sixthAndSeventhChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ if (noOfChildren.value?.toInt()!! > 7) {
+ ecr.dob8 = getLongFromDate(dob8.value)
+ ecr.age8 = age8.value?.toInt()
+ ecr.gender8 = when (gender8.value) {
+ gender8.entries!![0] -> Gender.MALE
+ gender8.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.seventhAndEighthChildGap = seventhAndEighthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ if (noOfChildren.value?.toInt()!! > 8) {
+ ecr.dob9 = getLongFromDate(dob9.value)
+ ecr.age9 = age9.value?.toInt()
+ ecr.gender9 = when (gender9.value) {
+ gender9.entries!![0] -> Gender.MALE
+ gender9.entries!![1] -> Gender.FEMALE
+ else -> null
+ }
+ ecr.eighthAndNinthChildGap = eighthAndNinthChildGap.value?.filter { it.isDigit() }?.toIntOrNull() ?: 0
+ }
+ }
+ }
+
+
+ private val children = listOf(
+ ChildBundle(firstChildDetails, firstChildName, dob1, age1, gender1, marriageFirstChildGap),
+ ChildBundle(secondChildDetails, secondChildName, dob2, age2, gender2, firstAndSecondChildGap),
+ ChildBundle(thirdChildDetails, thirdChildName, dob3, age3, gender3, secondAndThirdChildGap),
+ ChildBundle(fourthChildDetails, forthChildName, dob4, age4, gender4, thirdAndFourthChildGap),
+ ChildBundle(fifthChildDetails, fifthChildName, dob5, age5, gender5, fourthAndFifthChildGap),
+ ChildBundle(sixthChildDetails, sixthChildName, dob6, age6, gender6, fifthAndSixthChildGap),
+ ChildBundle(seventhChildDetails, seventhChildName, dob7, age7, gender7, sixthAndSeventhChildGap),
+ ChildBundle(eighthChildDetails, eightChildName, dob8, age8, gender8, seventhAndEighthChildGap),
+ ChildBundle(ninthChildDetails, ninthChildName, dob9, age9, gender9, eighthAndNinthChildGap)
+ )
+
+ private val childNameFields = listOf(
+ firstChildName,
+ secondChildName,
+ thirdChildName,
+ forthChildName,
+ fifthChildName,
+ sixthChildName,
+ seventhChildName,
+ eightChildName,
+ ninthChildName
+ )
+
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ childNameFields.firstOrNull { it.id == formId }?.let { childName ->
+ validateEmptyOnEditText(childName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(childName)
+ }
+
+
+ children.forEachIndexed { idx, child ->
+ if (formId == child.dob.id) {
+ val prevDobValue = if (idx == 0) {
+ null
+ } else children[idx - 1].dob.value
+
+ prevDobValue?.let { isValidChildGap(child.dob, it) }
+
+ val currentDobStr = child.dob.value
+ if ((idx == 0 && currentDobStr != null && timeAtMarriage != 0L) ||
+ (idx != 0 && children[idx - 1].dob.value != null && currentDobStr != null)
+ ) {
+ val currDobLong = getLongFromDate(currentDobStr)
+ assignValuesToAgeFromDob(currDobLong, child.age)
+ validateIntMinMax(child.age)
+
+ val months = getMonthsFromDob(currDobLong)
+ val existingName = child.name.value
+ if (months <= 3) {
+ val motherName = selectedBen?.firstName ?: ""
+ child.name.value = "Baby of $motherName"
+ child.name.required = false
+ } else {
+ child.name.required = true
+ if (existingName.isNullOrBlank()) {
+ child.name.value = ""
+ }
+ }
+
+
+ val prevLong = when {
+ idx == 0 -> timeAtMarriage
+ else -> getLongFromDate(children[idx - 1].dob.value!!)
+ }
+ setSiblingAgeDiff(prevLong, currDobLong, child.gap)
+
+ children.getOrNull(idx + 1)?.let { nextChild ->
+ nextChild.dob.min = getLongFromDate(getMinimumSecondChildDob(currentDobStr))
+ }
+
+ updateTimeLessThan18()
+ }
+ return -1
+ }
+ }
+
+ if (formId == noOfChildren.id) {
+ noOfChildren.min = noOfChildren.value.takeIf { !it.isNullOrEmpty() }?.toLong()
+ validateIntMinMax(noOfChildren)
+
+ if (isExistingRecord) {
+
+ val newCount = noOfChildren.value?.toIntOrNull() ?: 0
+
+ val oldCount = children.count { child ->
+ child.dob.value != null ||
+ child.gender.value != null ||
+ child.age.value != null
+ }
+
+ if (newCount > oldCount) {
+ for (i in oldCount until newCount) {
+ if (i == 0) {
+ if (timeAtMarriage != 0L) {
+ children[i].dob.min = timeAtMarriage
+ }
+ } else {
+ val prevDob = children[i - 1].dob.value
+ if (!prevDob.isNullOrEmpty()) {
+ children[i].dob.min =
+ getLongFromDate(getMinimumSecondChildDob(prevDob))
+ }
+ }
+ }
+
+ val addItems = children.subList(oldCount, newCount)
+ .flatMap { it.toFormList() }
+
+ infantTriggerDependants(
+ source = noOfChildren,
+ addItems = addItems,
+ removeItems = emptyList()
+ )
+ }
+ } else {
+ val count = noOfChildren.value?.toIntOrNull() ?: 0
+ val addItems = children.take(count).flatMap { it.toFormList() }
+ val removeItems = children.drop(count).flatMap { it.toFormList() }
+ triggerDependants( source = noOfChildren, addItems = addItems, removeItems = removeItems )
+ children.drop(count).forEach { it.clearValues() }
+
+ }
+
+
+
+
+
+ return 1
+ }
+
+ val genderIds = children.map { it.gender.id }
+ if (genderIds.contains(formId)) {
+ var male = 0
+ var female = 0
+ val genderArray = resources.getStringArray(R.array.ecr_gender_array)
+
+ children.forEach { child ->
+ val g = child.gender.value
+ if (g == genderArray[0]) male += 1
+ else if (g == genderArray[1]) female += 1
+ }
+
+ numFemale.value = female.toString()
+ numMale.value = male.toString()
+ return -1
+ }
+
+ return -1
+ }
+
+ fun getMonthsFromDob(dob: Long): Int {
+ val now = Calendar.getInstance()
+ val birth = Calendar.getInstance().apply { timeInMillis = dob }
+
+ val years = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR)
+ val months = now.get(Calendar.MONTH) - birth.get(Calendar.MONTH)
+ return years * 12 + months
+ }
+ fun getIndexOfChildren() = getIndexById(noOfChildren.id)
+
+ fun getIndexOfMaleChildren() = getIndexById(numMale.id)
+ fun getIndexOfFeMaleChildren() = getIndexById(numFemale.id)
+ fun getIndexOfAge1() = getIndexById(age1.id)
+ fun getIndexOfGap1() = getIndexById(marriageFirstChildGap.id)
+ fun getIndexOfAge2() = getIndexById(age2.id)
+ fun getIndexOfGap2() = getIndexById(firstAndSecondChildGap.id)
+ fun getIndexOfAge3() = getIndexById(age3.id)
+ fun getIndexOfGap3() = getIndexById(secondAndThirdChildGap.id)
+ fun getIndexOfAge4() = getIndexById(age4.id)
+ fun getIndexOfGap4() = getIndexById(thirdAndFourthChildGap.id)
+ fun getIndexOfAge5() = getIndexById(age5.id)
+ fun getIndexOfGap5() = getIndexById(fourthAndFifthChildGap.id)
+
+ fun getIndexOfAge6() = getIndexById(age6.id)
+ fun getIndexOfGap6() = getIndexById(fifthAndSixthChildGap.id)
+
+ fun getIndexOfAge7() = getIndexById(age7.id)
+ fun getIndexOfGap7() = getIndexById(sixthAndSeventhChildGap.id)
+
+ fun getIndexOfAge8() = getIndexById(age8.id)
+ fun getIndexOfGap8() = getIndexById(seventhAndEighthChildGap.id)
+
+ fun getIndexOfAge9() = getIndexById(age9.id)
+ fun getIndexOfGap9() = getIndexById(eighthAndNinthChildGap.id)
+
+
+}
+
+
+data class ChildBundle(
+ val details: FormElement,
+ val name: FormElement,
+ val dob: FormElement,
+ val age: FormElement,
+ val gender: FormElement,
+ val gap: FormElement
+) {
+ fun isEmpty(): Boolean {
+ return dob.value.isNullOrEmpty() &&
+ age.value.isNullOrEmpty() &&
+ gender.value.isNullOrEmpty() &&
+ name.value.isNullOrEmpty()
+ }
+ fun toFormList() = listOf(details, name, dob, age, gender, gap)
+ fun clearValues() {
+ name.value = null
+ dob.value = null
+ age.value = null
+ gender.value = null
+ gap.value = null
+ }
+}
+
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PHCReviewDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PHCReviewDataset.kt
new file mode 100644
index 000000000..36b4a549e
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PHCReviewDataset.kt
@@ -0,0 +1,278 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import android.util.Log
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Konstants
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.IMAGE_VIEW
+import org.piramalswasthya.sakhi.model.PHCReviewMeetingCache
+import org.piramalswasthya.sakhi.model.VHNCCache
+import org.piramalswasthya.sakhi.utils.HelperUtil.parseSelections
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+class PHCReviewDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ companion object {
+ private fun getCurrentDateString(): String {
+ val calendar = Calendar.getInstance()
+ val mdFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ return mdFormat.format(calendar.time)
+ }
+
+ }
+
+
+ private val phcReviewDate = FormElement(
+ id = 3,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.phc_review_meeting_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (60L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ )
+
+ private val place = FormElement(
+ id = 4,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_meeting),
+ entries = resources.getStringArray(R.array.place_of_vhsnc),
+ arrayId = R.array.place_of_vhsnc,
+ required = true,
+ allCaps = true,
+ )
+
+ private var villageName = FormElement(
+ id = 5,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.village_name),
+ required = false,
+ hasDependants = false
+ )
+
+ private val noOfParticipantsAttended = FormElement(
+ id = 6,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.total_no_of_participants_attended),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ value = "0",
+ etMaxLength = 3,
+ max = 999,
+ min = 0
+ )
+
+ private val mitanin = FormElement(
+ id = 8,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.participants_attended),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.mitanin_array),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+
+ private val mT = FormElement(
+ id = 9,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.mt),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.activity_checklist),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+
+ private val pic1 = FormElement(
+ id = 1,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false,
+ )
+ private val pic2 = FormElement(
+ id = 2,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false,
+ )
+
+ suspend fun setUpPage(phc: PHCReviewMeetingCache?) {
+ if (pic1.value.isNullOrBlank()) {
+ pic1.value = "default"
+ }
+
+ if (pic2.value.isNullOrBlank()) {
+ pic2.value = "default"
+ }
+ val list = mutableListOf(
+ phcReviewDate,
+ place,
+ villageName,
+ noOfParticipantsAttended,
+ )
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.addAll(
+ listOf(
+ mitanin,
+ mT,
+
+
+ )
+ )
+ }
+
+ list.addAll(
+ listOf(
+ pic1,
+ pic2
+ )
+ )
+ phcReviewDate.value = getCurrentDateString()
+ phc?.let {
+ phcReviewDate.value = it.phcReviewDate
+ pic1.value = it.image1
+ pic2.value = it.image2
+ place.value = getLocalValueInArray(R.array.place_of_vhsnc, it.place)
+ villageName.value = it.villageName
+ noOfParticipantsAttended.value = it.noOfBeneficiariesAttended.toString()
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ val parsedMitaninHistoryList = parseSelections(it.mitaninHistory, mitanin.entries!!)
+ mitanin.value = if (parsedMitaninHistoryList.isNotEmpty()) {
+ parsedMitaninHistoryList.joinToString("|")
+ } else {
+ it.mitaninHistory ?: ""
+ }
+
+ val parsedMitaninCheckListList = parseSelections(it.mitaninActivityCheckList, mT.entries!!)
+ mT.value = if (parsedMitaninCheckListList.isNotEmpty()) {
+ parsedMitaninCheckListList.joinToString("|")
+ } else {
+ it.mitaninActivityCheckList ?: ""
+ }
+ }
+
+ }
+ setUpPage(list)
+ }
+
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+
+ return when (formId) {
+
+ mT.id -> {
+
+ val allItems = resources.getStringArray(R.array.activity_checklist)
+ val itemCount = allItems.size
+
+ val selectedIndexes = mT.value
+ ?.split("|")
+ ?.mapNotNull { it.toIntOrNull() }
+ ?.toMutableSet()
+ ?: mutableSetOf()
+
+ if (index == 0) {
+
+ if (selectedIndexes.contains(0)) {
+ selectedIndexes.clear()
+ selectedIndexes.addAll(0 until itemCount)
+ } else {
+ selectedIndexes.clear()
+ }
+
+ mT.value =
+ if (selectedIndexes.isEmpty()) null
+ else selectedIndexes.sorted().joinToString("|")
+
+ return -1
+ }
+ val normalIndexes = (1 until itemCount)
+
+ if (selectedIndexes.contains(0) &&
+ normalIndexes.any { !selectedIndexes.contains(it) }
+ ) {
+ selectedIndexes.remove(0)
+ }
+
+ if (normalIndexes.all { selectedIndexes.contains(it) }) {
+ selectedIndexes.add(0)
+ }
+
+ mT.value =
+ if (selectedIndexes.isEmpty()) null
+ else selectedIndexes.sorted().joinToString("|")
+
+
+ -1
+ }
+ place.id -> {
+ validateEmptyOnEditText(place)
+ validateAllAlphabetsSpecialAndNumericOnEditText(place)
+ -1
+ }
+ villageName.id -> {
+ validateEmptyOnEditText(villageName)
+ validateAllAlphabetsSpecialAndNumericOnEditText(villageName)
+ -1
+ }
+
+ noOfParticipantsAttended.id -> {
+ validateEmptyOnEditText(noOfParticipantsAttended)
+ -1
+ }
+
+ else -> {
+ -1
+ }
+ }
+ }
+
+ private fun toCsv(rawValue: String?, entries: Array): String {
+ return parseSelections(rawValue, entries).joinToString("|")
+ }
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as PHCReviewMeetingCache).let { form ->
+
+ form.phcReviewDate = phcReviewDate.value!!
+ form.place = getEnglishValueInArray(R.array.place_of_vhsnc, place.value)
+ form.placeId = place.getPosition()
+ form.noOfBeneficiariesAttended = noOfParticipantsAttended.value?.toIntOrNull() ?: 0
+ form.image1 = pic1.value
+ form.image2 = pic2.value
+ form.villageName = villageName.value
+ form.mitaninHistory = toCsv(mitanin.value,mitanin.entries!!)
+ form.mitaninActivityCheckList = toCsv(mT.value,mT.entries!!)
+
+ }
+
+ }
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ pic1.id -> {
+ pic1.value = dpUri.toString()
+ pic1.errorText = null
+ }
+ pic2.id -> {
+ pic2.value = dpUri.toString()
+ pic2.errorText = null
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PMSMAFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PMSMAFormDataset.kt
index 294409a96..53eff5be5 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PMSMAFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PMSMAFormDataset.kt
@@ -1,511 +1,660 @@
-package org.piramalswasthya.sakhi.configuration
-
-import android.content.Context
-import android.text.InputType
-import org.piramalswasthya.sakhi.R
-import org.piramalswasthya.sakhi.helpers.Languages
-import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
-import org.piramalswasthya.sakhi.model.BenRegCache
-import org.piramalswasthya.sakhi.model.FormElement
-import org.piramalswasthya.sakhi.model.HouseholdCache
-import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
-import org.piramalswasthya.sakhi.model.InputType.HEADLINE
-import org.piramalswasthya.sakhi.model.InputType.RADIO
-import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
-import org.piramalswasthya.sakhi.model.PMSMACache
-import org.piramalswasthya.sakhi.model.PregnantWomanAncCache
-import org.piramalswasthya.sakhi.model.PregnantWomanRegistrationCache
-import java.text.SimpleDateFormat
-import java.util.Calendar
-import java.util.Locale
-import java.util.concurrent.TimeUnit
-
-class PMSMAFormDataset(
- context: Context, currentLanguage: Languages
-) : Dataset(context, currentLanguage) {
-
- companion object {
- private fun getLongFromDate(dateString: String): Long {
- val f = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
- val date = f.parse(dateString)
- return date?.time ?: throw IllegalStateException("Invalid date for dateReg")
- }
- }
-
- private val mctsNumberOrRchNumber = FormElement(
- id = 1,
- inputType = TEXT_VIEW,
- title = resources.getString(R.string.pmsma_mcts_rch_number),
- required = false
- )
- private val haveMCPCard = FormElement(
- id = 2,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_have_mcp_card),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- hasDependants = true,
- required = false
- )
- val givenMCPCard = FormElement(
- id = 3,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_given_mcp_card),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
-
- private val husbandName = FormElement(
- id = 4,
- inputType = TEXT_VIEW,
- title = resources.getString(R.string.pmsma_husband_name),
- required = false
- )
- private val address = FormElement(
- id = 5,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_address),
- required = false
- )
- private val mobileNumber = FormElement(
- id = 6,
- inputType = TEXT_VIEW,
- title = resources.getString(R.string.pmsma_mobile_number),
- required = false
- )
- private val numANC = FormElement(
- id = 7,
- inputType = EDIT_TEXT,
- etMaxLength = 2,
- title = resources.getString(R.string.pmsma_num_anc),
- etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
- required = false
- )
- private val motherStatus = FormElement(
- id = 8,
- inputType = HEADLINE,
- title = resources.getString(R.string.pmsma_mother_status),
- required = false
- )
- private val weight = FormElement(
- id = 9,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_weight),
- min = 30,
- max = 200,
- etMaxLength = 3,
- etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
- required = false
- )
- private val bp = FormElement(
- id = 10,
- inputType = EDIT_TEXT,
- title = "BP of PW – Systolic/ Diastolic (mm Hg) ",
-// etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
- etMaxLength = 7,
- required = false,
- )
- private val abdominalCheckUp = FormElement(
- id = 12,
- inputType = TEXT_VIEW,
- title = resources.getString(R.string.pmsma_abdominal_check_up),
- required = false
- )
- private val fetalStatus = FormElement(
- id = 13,
- inputType = HEADLINE,
- title = resources.getString(R.string.pmsma_fetal_status),
- required = false
- )
- private val fetalHRPM = FormElement(
- id = 14,
- inputType = EDIT_TEXT,
- etMaxLength = 3,
- title = resources.getString(R.string.pmsma_fetal_hrpm),
- etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
- required = false
- )
- private val twinPregnancy = FormElement(
- id = 15,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_twin_pregnancy),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val investigations = FormElement(
- id = 16,
- inputType = HEADLINE,
- title = resources.getString(R.string.pmsma_investigation),
- required = false
- )
- private val urineAlbumin = FormElement(
- id = 17,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_urine_albumin),
- required = false
- )
- private val haemoglobinAndBloodGroup = FormElement(
- id = 18,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_haemoglobin_and_blood_group),
- required = false
- )
- private val hiv = FormElement(
- id = 19,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_hiv),
- required = false
- )
- private val vdrl = FormElement(
- id = 20,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_vdrl),
- required = false
- )
- private val hbsc = FormElement(
- id = 21,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_hbsc),
- required = false
- )
- private val malaria = FormElement(
- id = 22,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_malaria),
- required = false
- )
- private val hivTestDuringANC = FormElement(
- id = 23,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_hiv_test_during_anc),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val swollenCondtion = FormElement(
- id = 24,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_swollen_condition),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val bloodSugarTest = FormElement(
- id = 25,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_blood_sugar_test),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val ultraSound = FormElement(
- id = 26,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_ultrasound),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val interventionDetails = FormElement(
- id = 27,
- inputType = HEADLINE,
- title = resources.getString(R.string.pmsma_intervention_details),
- required = false
- )
- private val ironFolicAcid = FormElement(
- id = 28,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_iron_folic_acid),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val calciumSupplementation = FormElement(
- id = 29,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_calcium_supplementation),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val tetanusToxoid = FormElement(
- id = 30,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_tetanus_toxoid),
- entries = resources.getStringArray(R.array.pmsma_tetanus_toxoid_array),
- required = false
- )
- private val lmp = FormElement(
- id = 31,
- inputType = HEADLINE,
- title = resources.getString(R.string.pmsma_lmp),
- required = false
- )
- private val lastMenstrualPeriod = FormElement(
- id = 32,
- inputType = TEXT_VIEW,
- title = resources.getString(R.string.pmsma_last_mestrual_period),
- min = 0L,
- max = System.currentTimeMillis(),
- required = false
- )
- private val expectedDateOfDelivery = FormElement(
- id = 33,
- inputType = TEXT_VIEW,
- title = resources.getString(R.string.pmsma_expected_delivery_date),
- required = false
- )
- private val highRiskFactors = FormElement(
- id = 34,
- inputType = HEADLINE,
- title = resources.getString(R.string.pmsma_high_risk_factors),
- required = false
- )
- private val highriskSymbols = FormElement(
- id = 35,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_high_risk_symbols),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- hasDependants = true,
- required = false
- )
- private val highRiskReason = FormElement(
- id = 36,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_high_risk_reason),
- required = false
- )
- private val highRiskPregnant = FormElement(
- id = 37,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_high_risk_pregnant),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val highRiskPregnancyReferred = FormElement(
- id = 38,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_high_risk_pregnancy_referred),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val advice = FormElement(
- id = 39,
- inputType = HEADLINE,
- title = resources.getString(R.string.pmsma_advice),
- required = false
- )
- private val birthPrepAndNutritionAndFamilyPlanning = FormElement(
- id = 40,
- inputType = RADIO,
- title = resources.getString(R.string.pmsma_birth_complications_and_planning),
- entries = resources.getStringArray(R.array.pmsma_confirmation_array),
- required = false
- )
- private val medicalOfficerSign = FormElement(
- id = 41,
- inputType = EDIT_TEXT,
- title = resources.getString(R.string.pmsma_medical_officer_sign),
- required = false
- )
-
- suspend fun setUpFirstPage(
- household: HouseholdCache,
- ben: BenRegCache,
- pwr: PregnantWomanRegistrationCache,
- lastAnc: PregnantWomanAncCache?,
- pmsma: PMSMACache?
- ) {
- mctsNumberOrRchNumber.value = pwr.rchId?.toString()
- address.value = getAddress(household)
- mobileNumber.value = ben.contactNumber.toString()
- husbandName.value = ben.genDetails?.spouseName
- mctsNumberOrRchNumber.value = ben.rchId
- lastAnc?.let {
- "${(it.ancDate - pwr.lmpDate) / 7} Weeks"
- }
- lastMenstrualPeriod.value = getDateFromLong(pwr.lmpDate)
- expectedDateOfDelivery.value = getDateFromLong(getEddFromLmp(pwr.lmpDate))
- abdominalCheckUp.value = "${
- (TimeUnit.MILLISECONDS.toDays(
- Calendar.getInstance().setToStartOfTheDay().timeInMillis - pwr.lmpDate
- ) / 7)
- } Weeks"
- pmsma?.let { setExistingValues(it) }
- val list = firstPage
- setUpPage(list)
- }
-
-
- private val firstPage by lazy {
- listOf(
- mctsNumberOrRchNumber,
- haveMCPCard,
- husbandName,
- address,
- mobileNumber,
- numANC,
- motherStatus,
- weight,
- bp,
- abdominalCheckUp,
- fetalStatus,
- fetalHRPM,
- twinPregnancy,
- investigations,
- urineAlbumin,
- haemoglobinAndBloodGroup,
- hiv,
- vdrl,
- hbsc,
- malaria,
- hivTestDuringANC,
- swollenCondtion,
- bloodSugarTest,
- ultraSound,
- interventionDetails,
- ironFolicAcid,
- calciumSupplementation,
- tetanusToxoid,
- lmp,
- lastMenstrualPeriod,
- expectedDateOfDelivery,
- highRiskFactors,
- highriskSymbols,
- highRiskPregnant,
- highRiskPregnancyReferred,
- advice,
- birthPrepAndNutritionAndFamilyPlanning,
- medicalOfficerSign,
-
- )
- }
-
-
- override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
- (cacheModel as PMSMACache).let { pmsmaCache ->
- pmsmaCache.mctsNumberOrRchNumber = mctsNumberOrRchNumber.value
- pmsmaCache.haveMCPCard = haveMCPCard.value == "Yes"
- pmsmaCache.husbandName = husbandName.value
- pmsmaCache.address = address.value
- pmsmaCache.mobileNumber = mobileNumber.value?.toLong() ?: 0L
- pmsmaCache.numANC = numANC.value?.toInt() ?: 0
- pmsmaCache.weight = weight.value?.toInt() ?: 0
- pmsmaCache.systolicBloodPressure =
- bp.value?.takeIf { it.isNotEmpty() }?.substringBefore("/")
- pmsmaCache.bloodPressure = bp.value?.takeIf { it.isNotEmpty() }?.substringAfter("/")
- pmsmaCache.abdominalCheckUp = abdominalCheckUp.value
- pmsmaCache.fetalHRPM = fetalHRPM.value?.toInt() ?: 0
- pmsmaCache.twinPregnancy = twinPregnancy.value == "Yes"
- pmsmaCache.urineAlbumin = urineAlbumin.value
- pmsmaCache.haemoglobinAndBloodGroup = haemoglobinAndBloodGroup.value
- pmsmaCache.hiv = hiv.value
- pmsmaCache.vdrl = vdrl.value
- pmsmaCache.hbsc = hbsc.value
- pmsmaCache.malaria = malaria.value
- pmsmaCache.hivTestDuringANC = hivTestDuringANC.value == "Yes"
- pmsmaCache.swollenCondtion = swollenCondtion.value == "Yes"
- pmsmaCache.bloodSugarTest = bloodSugarTest.value == "Yes"
- pmsmaCache.ultraSound = ultraSound.value == "Yes"
- pmsmaCache.ironFolicAcid = ironFolicAcid.value == "Yes"
- pmsmaCache.calciumSupplementation = calciumSupplementation.value == "Yes"
- pmsmaCache.tetanusToxoid = tetanusToxoid.value
- pmsmaCache.lastMenstrualPeriod =
- lastMenstrualPeriod.value?.let { getLongFromDate(it) } ?: 0L
- pmsmaCache.expectedDateOfDelivery = getLongFromDate(expectedDateOfDelivery.value!!)
- pmsmaCache.highriskSymbols = highriskSymbols.value == "Yes"
- pmsmaCache.highRiskReason = highRiskReason.value
- pmsmaCache.highRiskPregnant = highRiskPregnant.value == "Yes"
- pmsmaCache.highRiskPregnancyReferred = highRiskPregnancyReferred.value == "Yes"
- pmsmaCache.birthPrepAndNutritionAndFamilyPlanning =
- birthPrepAndNutritionAndFamilyPlanning.value == "Yes"
- pmsmaCache.medicalOfficerSign = medicalOfficerSign.value
+ package org.piramalswasthya.sakhi.configuration
+
+ import android.app.AlertDialog
+ import android.content.Context
+ import android.text.InputType
+ import android.util.Log
+ import org.piramalswasthya.sakhi.R
+ import org.piramalswasthya.sakhi.helpers.Konstants.english
+ import org.piramalswasthya.sakhi.helpers.Languages
+ import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
+ import org.piramalswasthya.sakhi.model.BenRegCache
+ import org.piramalswasthya.sakhi.model.FormElement
+ import org.piramalswasthya.sakhi.model.HouseholdCache
+ import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+ import org.piramalswasthya.sakhi.model.InputType.HEADLINE
+ import org.piramalswasthya.sakhi.model.InputType.RADIO
+ import org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW
+ import org.piramalswasthya.sakhi.model.PMSMACache
+ import org.piramalswasthya.sakhi.model.PregnantWomanAncCache
+ import org.piramalswasthya.sakhi.model.PregnantWomanRegistrationCache
+ import org.piramalswasthya.sakhi.ui.home_activity.maternal_health.pmsma.PmsmaViewModel
+ import java.text.SimpleDateFormat
+ import java.util.Calendar
+ import java.util.Date
+ import java.util.Locale
+ import java.util.concurrent.TimeUnit
+
+ class PMSMAFormDataset(
+ context: Context, currentLanguage: Languages,
+ private val viewModel: PmsmaViewModel
+ ) : Dataset(context, currentLanguage) {
+
+ companion object {
+ private fun getLongFromDate(dateString: String): Long {
+ val f = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ val date = f.parse(dateString)
+ return date?.time ?: throw IllegalStateException("Invalid date for dateReg")
+ }
}
- }
-
- fun setExistingValues(pmsma: PMSMACache) {
- mctsNumberOrRchNumber.value = pmsma.mctsNumberOrRchNumber
- haveMCPCard.value = if (pmsma.haveMCPCard == true) "Yes" else "No"
- husbandName.value = pmsma.husbandName
- address.value = pmsma.address?.let { if (it.length > 100) it.substring(0, 100) else it }
- mobileNumber.value = pmsma.mobileNumber.toString()
- numANC.value = pmsma.numANC.toString()
- weight.value = pmsma.weight.toString()
- bp.value =
- if (pmsma.systolicBloodPressure == null || pmsma.bloodPressure == null) null else "${pmsma.systolicBloodPressure}/${pmsma.bloodPressure}"
- abdominalCheckUp.value = pmsma.abdominalCheckUp
- fetalHRPM.value = pmsma.fetalHRPM.toString()
- twinPregnancy.value = if (pmsma.twinPregnancy == true) "Yes" else "No"
- urineAlbumin.value = pmsma.urineAlbumin
- haemoglobinAndBloodGroup.value = pmsma.haemoglobinAndBloodGroup
- hiv.value = pmsma.hiv
- vdrl.value = pmsma.vdrl
- hbsc.value = pmsma.hbsc
- malaria.value = pmsma.malaria
- hivTestDuringANC.value = if (pmsma.hivTestDuringANC == true) "Yes" else "No"
- swollenCondtion.value = if (pmsma.swollenCondtion == true) "Yes" else "No"
- bloodSugarTest.value = if (pmsma.bloodSugarTest == true) "Yes" else "No"
- ultraSound.value = if (pmsma.ultraSound == true) "Yes" else "No"
- ironFolicAcid.value = if (pmsma.ironFolicAcid == true) "Yes" else "No"
- calciumSupplementation.value =
- if (pmsma.calciumSupplementation == true) "Yes" else "No"
- tetanusToxoid.value = pmsma.tetanusToxoid
- lastMenstrualPeriod.value = pmsma.lastMenstrualPeriod.let { getDateFromLong(it) }
- expectedDateOfDelivery.value = pmsma.expectedDateOfDelivery.let { getDateFromLong(it) }
- highriskSymbols.value = if (pmsma.highriskSymbols == true) "Yes" else "No"
- highRiskReason.value = pmsma.highRiskReason
- highRiskPregnant.value = if (pmsma.highRiskPregnant == true) "Yes" else "No"
- highRiskPregnancyReferred.value =
- if (pmsma.highRiskPregnancyReferred == true) "Yes" else "No"
- birthPrepAndNutritionAndFamilyPlanning.value =
- if (pmsma.birthPrepAndNutritionAndFamilyPlanning == true) "Yes" else "No"
- medicalOfficerSign.value = pmsma.medicalOfficerSign
- }
-
-
- override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
- return when (formId) {
- haveMCPCard.id -> {
- triggerDependants(
- source = haveMCPCard,
- passedIndex = index,
- triggerIndex = 1,
- target = givenMCPCard
- )
+ private val pmsmaVisitDate = FormElement(
+ id = 43,
+ inputType = org.piramalswasthya.sakhi.model.InputType.DATE_PICKER,
+ title = resources.getString(R.string.pmsma_visit_date),
+ required = true,
+ hasDependants = true,
+ showDrawable = true
+ )
+
+ private val pmsmaVisit = FormElement(
+ id = 44,
+ inputType = org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_visit),
+ required = true,
+ showDrawable = true,
+ )
+ private val detailsOfPW = FormElement(
+ id = 46,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.details_of_pregnant_women),
+ required = false
+ )
+
+ private val highRiskReason = FormElement(
+ id = 45,
+ inputType = org.piramalswasthya.sakhi.model.InputType.DROPDOWN,
+ title = resources.getString(R.string.if_yes_select_high_risk_condition),
+ arrayId = R.array.select_high_risk_condition,
+ entries = resources.getStringArray(R.array.select_high_risk_condition),
+ required = true,
+ showDrawable = true,
+ )
+ private val anyOtherHighRiskCondition = FormElement(
+ id = 43,
+ etMaxLength = 50,
+ inputType = EDIT_TEXT,
+ title = context.getString(R.string.any_other_high_risk_conditions),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val mctsNumberOrRchNumber = FormElement(
+ id = 1,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_mcts_rch_number),
+ required = false
+ )
+ private val haveMCPCard = FormElement(
+ id = 2,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_have_mcp_card),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ hasDependants = true,
+ required = false
+ )
+ val givenMCPCard = FormElement(
+ id = 3,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_given_mcp_card),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+
+ private val husbandName = FormElement(
+ id = 4,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_husband_name),
+ required = false
+ )
+ private val address = FormElement(
+ id = 5,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.pmsma_address),
+ required = false
+ )
+ private val mobileNumber = FormElement(
+ id = 6,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_mobile_number),
+ required = false
+ )
+ private val numANC = FormElement(
+ id = 7,
+ inputType = TEXT_VIEW,
+ etMaxLength = 2,
+ title = resources.getString(R.string.pmsma_num_anc),
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ required = false
+ )
+ private val motherStatus = FormElement(
+ id = 8,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.pmsma_mother_status),
+ required = false
+ )
+ private val weight = FormElement(
+ id = 9,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.pmsma_weight),
+ min = 30,
+ max = 200,
+ etMaxLength = 3,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ required = false
+ )
+ private val bp = FormElement(
+ id = 10,
+ inputType = EDIT_TEXT,
+ title = "BP of PW – Systolic/ Diastolic (mm Hg) ",
+ // etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 7,
+ required = false,
+ )
+ private val abdominalCheckUp = FormElement(
+ id = 12,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_abdominal_check_up),
+ required = false
+ )
+ private val fetalStatus = FormElement(
+ id = 13,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.pmsma_fetal_status),
+ required = false
+ )
+ private val fetalHRPM = FormElement(
+ id = 14,
+ inputType = EDIT_TEXT,
+ etMaxLength = 3,
+ title = resources.getString(R.string.pmsma_fetal_hrpm),
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ required = false
+ )
+ private val twinPregnancy = FormElement(
+ id = 15,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_twin_pregnancy),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val investigations = FormElement(
+ id = 16,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.pmsma_investigation),
+ required = false
+ )
+ private val urineAlbumin = FormElement(
+ id = 17,
+ inputType = RADIO,
+ arrayId = R.array.pmsma_confirmation_array,
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ title = resources.getString(R.string.pmsma_urine_albumin),
+ required = false
+ )
+ private val haemoglobinAndBloodGroup = FormElement(
+ id = 18,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.pmsma_haemoglobin_and_blood_group),
+ required = false
+ )
+ private val hiv = FormElement(
+ id = 19,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_hiv),
+ required = false
+ )
+ private val vdrl = FormElement(
+ id = 20,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_vdrl),
+ required = false
+ )
+ private val hbsc = FormElement(
+ id = 21,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_hbsc),
+ required = false
+ )
+ private val malaria = FormElement(
+ id = 22,
+ inputType = RADIO,
+ arrayId = R.array.pmsma_malaria_array,
+ entries = resources.getStringArray(R.array.pmsma_malaria_array),
+ title = resources.getString(R.string.pmsma_malaria),
+ required = false
+ )
+ private val hivTestDuringANC = FormElement(
+ id = 23,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_hiv_test_during_anc),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val swollenCondtion = FormElement(
+ id = 24,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_swollen_condition),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val bloodSugarTest = FormElement(
+ id = 25,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_blood_sugar_test),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val ultraSound = FormElement(
+ id = 26,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_ultrasound),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val interventionDetails = FormElement(
+ id = 27,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.pmsma_intervention_details),
+ required = false
+ )
+ private val ironFolicAcid = FormElement(
+ id = 28,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_iron_folic_acid),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val calciumSupplementation = FormElement(
+ id = 29,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_calcium_supplementation),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val tetanusToxoid = FormElement(
+ id = 30,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_tetanus_toxoid),
+ arrayId = R.array.pmsma_tetanus_toxoid_array,
+ entries = resources.getStringArray(R.array.pmsma_tetanus_toxoid_array),
+ required = false
+ )
+ private val lmp = FormElement(
+ id = 31,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.pmsma_lmp),
+ required = false
+ )
+ private val lastMenstrualPeriod = FormElement(
+ id = 32,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_last_mestrual_period),
+ min = 0L,
+ max = System.currentTimeMillis(),
+ required = false
+ )
+ private val expectedDateOfDelivery = FormElement(
+ id = 33,
+ inputType = TEXT_VIEW,
+ title = resources.getString(R.string.pmsma_expected_delivery_date),
+ required = false
+ )
+ private val highRiskFactors = FormElement(
+ id = 34,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.pmsma_high_risk_factors),
+ required = false
+ )
+ private val highriskSymbols = FormElement(
+ id = 35,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_high_risk_symbols),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ hasDependants = true,
+ required = false
+ )
+ // private val highRiskReason = FormElement(
+ // id = 36,
+ // inputType = EDIT_TEXT,
+ // title = resources.getString(R.string.pmsma_high_risk_reason),
+ // required = false
+ // )
+ private val highRiskPregnant = FormElement(
+ id = 37,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_high_risk_pregnant),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val highRiskPregnancyReferred = FormElement(
+ id = 38,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_high_risk_pregnancy_referred),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val advice = FormElement(
+ id = 39,
+ inputType = HEADLINE,
+ title = resources.getString(R.string.pmsma_advice),
+ required = false
+ )
+ private val birthPrepAndNutritionAndFamilyPlanning = FormElement(
+ id = 40,
+ inputType = RADIO,
+ title = resources.getString(R.string.pmsma_birth_complications_and_planning),
+ entries = resources.getStringArray(R.array.pmsma_confirmation_array),
+ required = false
+ )
+ private val medicalOfficerSign = FormElement(
+ id = 41,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.pmsma_medical_officer_sign),
+ required = false
+ )
+
+
+ suspend fun setUpFirstPage(
+ household: HouseholdCache,
+ ben: BenRegCache,
+ pwr: PregnantWomanRegistrationCache,
+ lastAnc: PregnantWomanAncCache?,
+ pmsma: PMSMACache?,
+ visitNumber:Int,
+ countOfANC:Int,
+ lastPmsmaVisit:PMSMACache?
+ ) {
+ val minDate = lastPmsmaVisit?.visitDate?.let { lastVisit ->
+ lastVisit + TimeUnit.DAYS.toMillis(7)
+ } ?: pwr.lmpDate.toStartOfDay()
+
+ val maxFromLMP = (pwr.lmpDate + TimeUnit.DAYS.toMillis(42 * 7)).toStartOfDay()
+ val today = Calendar.getInstance().apply {
+ set(Calendar.HOUR_OF_DAY, 0)
+ set(Calendar.MINUTE, 0)
+ set(Calendar.SECOND, 0)
+ set(Calendar.MILLISECOND, 0)
+ }.timeInMillis
+ val finalMaxDate = minOf(today, maxFromLMP)
+ val clampedMinDate = if (minDate > finalMaxDate) finalMaxDate else minDate
+ pmsmaVisitDate.min = minDate
+ pmsmaVisitDate.max = today
+
+ hiv.value=pwr.hivTestResult
+ vdrl.value=pwr.vdrlRprTestResult
+ hbsc.value=pwr.hbsAgTestResult
+ malaria.value = resources.getStringArray(R.array.pmsma_malaria_array)[0]
+ numANC.value=countOfANC.toString()
+// hivTestDuringANC.value=pwr.hivTestResult
+
+ pmsmaVisit.value=visitNumber.toString()
+ mctsNumberOrRchNumber.value = pwr.rchId?.toString()
+ address.value = getAddress(household)
+ mobileNumber.value = ben.contactNumber.toString()
+ husbandName.value = ben.genDetails?.spouseName
+ mctsNumberOrRchNumber.value = ben.rchId
+ lastAnc?.let {
+ "${(it.ancDate - pwr.lmpDate) / 7} Weeks"
}
+ lastMenstrualPeriod.value = getDateFromLong(pwr.lmpDate)
+ expectedDateOfDelivery.value = getDateFromLong(getEddFromLmp(pwr.lmpDate))
+ abdominalCheckUp.value = "${
+ (TimeUnit.MILLISECONDS.toDays(
+ Calendar.getInstance().setToStartOfTheDay() - pwr.lmpDate
+ ) / 7)
+ } Weeks"
+
+ pmsma?.let { data ->
+
+ val updatedList = firstPage.toMutableList().apply {
+ if (data.highriskSymbols == true) {
+ indexOf(highriskSymbols).takeIf { it != -1 }?.let { idx ->
+ add(idx + 1, highRiskReason)
+ }
+ }
+ if (data.highRiskReason == highRiskReason.entries?.lastOrNull()) {
+ indexOf(highRiskReason).takeIf { it != -1 }?.let { idx ->
+ add(idx + 1, anyOtherHighRiskCondition)
+ }
+ }
+ }
+ setUpPage(updatedList)
+ setExistingValues(data)
+
+ } ?: run {
+ setUpPage(firstPage)
+ }
+
+ }
+
+
+ private val firstPage by lazy {
+ listOf(
+ pmsmaVisitDate,
+ pmsmaVisit,
+ detailsOfPW,
+ mctsNumberOrRchNumber,
+ haveMCPCard,
+ husbandName,
+ address,
+ mobileNumber,
+ numANC,
+ motherStatus,
+ weight,
+ bp,
+ abdominalCheckUp,
+ fetalStatus,
+ fetalHRPM,
+ twinPregnancy,
+ investigations,
+ urineAlbumin,
+ haemoglobinAndBloodGroup,
+ hiv,
+ vdrl,
+ hbsc,
+ malaria,
+ hivTestDuringANC,
+ swollenCondtion,
+ bloodSugarTest,
+ ultraSound,
+ interventionDetails,
+ ironFolicAcid,
+ calciumSupplementation,
+ tetanusToxoid,
+ lmp,
+ lastMenstrualPeriod,
+ expectedDateOfDelivery,
+ highRiskFactors,
+ highriskSymbols,
+ highRiskPregnant,
+ highRiskPregnancyReferred,
+ advice,
+ birthPrepAndNutritionAndFamilyPlanning,
+ medicalOfficerSign,
- highriskSymbols.id -> {
- triggerDependants(
- source = highriskSymbols,
- passedIndex = index,
- triggerIndex = 0,
- target = highRiskReason
)
+ }
+
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as PMSMACache).let { pmsmaCache ->
+ pmsmaCache.mctsNumberOrRchNumber = mctsNumberOrRchNumber.value
+ pmsmaCache.haveMCPCard = haveMCPCard.value == haveMCPCard.entries!![0]
+ pmsmaCache.husbandName = husbandName.value
+ pmsmaCache.visitDate= getLongFromDate(pmsmaVisitDate.value)
+ pmsmaCache.visitNumber = pmsmaVisit.value!!.toInt()
+ pmsmaCache.anyOtherHighRiskCondition=anyOtherHighRiskCondition.value
+ pmsmaCache.address = address.value
+ pmsmaCache.mobileNumber = mobileNumber.value?.toLong() ?: 0L
+ pmsmaCache.numANC = numANC.value?.toInt() ?: 0
+ pmsmaCache.weight = weight.value?.toInt() ?: 0
+ pmsmaCache.systolicBloodPressure =
+ bp.value?.takeIf { it.isNotEmpty() }?.substringBefore("/")
+ pmsmaCache.bloodPressure = bp.value?.takeIf { it.isNotEmpty() }?.substringAfter("/")
+ pmsmaCache.abdominalCheckUp = abdominalCheckUp.value
+ pmsmaCache.fetalHRPM = fetalHRPM.value?.toInt() ?: 0
+ pmsmaCache.twinPregnancy = twinPregnancy.value == twinPregnancy.entries!![0]
+ pmsmaCache.urineAlbumin = getEnglishValueInArray(R.array.pmsma_confirmation_array, urineAlbumin.value)
+ pmsmaCache.haemoglobinAndBloodGroup = haemoglobinAndBloodGroup.value
+ pmsmaCache.hiv = hiv.value
+ pmsmaCache.vdrl = vdrl.value
+ pmsmaCache.hbsc = hbsc.value
+ pmsmaCache.malaria = getEnglishValueInArray(R.array.pmsma_malaria_array, malaria.value)
+ pmsmaCache.hivTestDuringANC = hivTestDuringANC.value == hivTestDuringANC.entries!![0]
+ pmsmaCache.swollenCondtion = swollenCondtion.value == swollenCondtion.entries!![0]
+ pmsmaCache.bloodSugarTest = bloodSugarTest.value == bloodSugarTest.entries!![0]
+ pmsmaCache.ultraSound = ultraSound.value == ultraSound.entries!![0]
+ pmsmaCache.ironFolicAcid = ironFolicAcid.value == ironFolicAcid.entries!![0]
+ pmsmaCache.calciumSupplementation = calciumSupplementation.value == calciumSupplementation.entries!![0]
+ pmsmaCache.tetanusToxoid = getEnglishValueInArray(R.array.pmsma_tetanus_toxoid_array, tetanusToxoid.value)
+ pmsmaCache.lastMenstrualPeriod =
+ lastMenstrualPeriod.value?.let { getLongFromDate(it) } ?: 0L
+ pmsmaCache.expectedDateOfDelivery = getLongFromDate(expectedDateOfDelivery.value!!)
+ pmsmaCache.highriskSymbols = highriskSymbols.value == highriskSymbols.entries!![0]
+ pmsmaCache.highRiskReason = getEnglishValueInArray(R.array.select_high_risk_condition, highRiskReason.value)
+ pmsmaCache.highRiskPregnant = highRiskPregnant.value == highRiskPregnant.entries!![0]
+ pmsmaCache.highRiskPregnancyReferred = highRiskPregnancyReferred.value == highRiskPregnancyReferred.entries!![0]
+ pmsmaCache.birthPrepAndNutritionAndFamilyPlanning =
+ birthPrepAndNutritionAndFamilyPlanning.value == birthPrepAndNutritionAndFamilyPlanning.entries!![0]
+ pmsmaCache.medicalOfficerSign = medicalOfficerSign.value
}
- mobileNumber.id -> validateMobileNumberOnEditText(mobileNumber)
- husbandName.id -> validateAllCapsOrSpaceOnEditText(husbandName)
- bp.id -> validateForBp(bp)
- weight.id -> validateIntMinMax(weight)
+ }
+
+ fun setExistingValues(pmsma: PMSMACache) {
+ mctsNumberOrRchNumber.value = pmsma.mctsNumberOrRchNumber
+ haveMCPCard.value = if (pmsma.haveMCPCard == true) haveMCPCard.entries!![0] else haveMCPCard.entries!![1]
+ husbandName.value = pmsma.husbandName
+ pmsmaVisitDate.value = getDateFromLong(pmsma.visitDate!!)
+ pmsmaVisit.value = pmsma.visitNumber.toString()
+ anyOtherHighRiskCondition.value = pmsma.anyOtherHighRiskCondition
+ address.value = pmsma.address?.let { if (it.length > 100) it.substring(0, 100) else it }
+ mobileNumber.value = pmsma.mobileNumber.toString()
+ numANC.value = pmsma.numANC.toString()
+ weight.value = pmsma.weight.toString()
+ bp.value =
+ if (pmsma.systolicBloodPressure == null || pmsma.bloodPressure == null) null else "${pmsma.systolicBloodPressure}/${pmsma.bloodPressure}"
+ abdominalCheckUp.value = pmsma.abdominalCheckUp
+ fetalHRPM.value = pmsma.fetalHRPM.toString()
+ twinPregnancy.value = if (pmsma.twinPregnancy == true) twinPregnancy.entries!![0] else twinPregnancy.entries!![1]
+ urineAlbumin.value = getLocalValueInArray(R.array.pmsma_confirmation_array, pmsma.urineAlbumin)
+ haemoglobinAndBloodGroup.value = pmsma.haemoglobinAndBloodGroup
+ hiv.value = pmsma.hiv
+ vdrl.value = pmsma.vdrl
+ hbsc.value = pmsma.hbsc
+ malaria.value = getLocalValueInArray(R.array.pmsma_malaria_array, pmsma.malaria)
+ hivTestDuringANC.value = if (pmsma.hivTestDuringANC == true) hivTestDuringANC.entries!![0] else hivTestDuringANC.entries!![1]
+ swollenCondtion.value = if (pmsma.swollenCondtion == true) swollenCondtion.entries!![0] else swollenCondtion.entries!![1]
+ bloodSugarTest.value = if (pmsma.bloodSugarTest == true) bloodSugarTest.entries!![0] else bloodSugarTest.entries!![1]
+ ultraSound.value = if (pmsma.ultraSound == true) ultraSound.entries!![0] else ultraSound.entries!![1]
+ ironFolicAcid.value = if (pmsma.ironFolicAcid == true) ironFolicAcid.entries!![0] else ironFolicAcid.entries!![1]
+ calciumSupplementation.value =
+ if (pmsma.calciumSupplementation == true) calciumSupplementation.entries!![0] else calciumSupplementation.entries!![1]
+ tetanusToxoid.value = getLocalValueInArray(R.array.pmsma_tetanus_toxoid_array, pmsma.tetanusToxoid)
+ lastMenstrualPeriod.value = pmsma.lastMenstrualPeriod.let { getDateFromLong(it) }
+ expectedDateOfDelivery.value = pmsma.expectedDateOfDelivery.let { getDateFromLong(it) }
+ highriskSymbols.value = if (pmsma.highriskSymbols == true) highriskSymbols.entries!![0] else highriskSymbols.entries!![1]
+ highRiskReason.value = getLocalValueInArray(R.array.select_high_risk_condition, pmsma.highRiskReason)
+ highRiskPregnant.value = if (pmsma.highRiskPregnant == true) highRiskPregnant.entries!![0] else highRiskPregnant.entries!![1]
+ highRiskPregnancyReferred.value =
+ if (pmsma.highRiskPregnancyReferred == true) highRiskPregnancyReferred.entries!![0] else highRiskPregnancyReferred.entries!![1]
+ birthPrepAndNutritionAndFamilyPlanning.value =
+ if (pmsma.birthPrepAndNutritionAndFamilyPlanning == true) birthPrepAndNutritionAndFamilyPlanning.entries!![0] else birthPrepAndNutritionAndFamilyPlanning.entries!![1]
+ medicalOfficerSign.value = pmsma.medicalOfficerSign
+ }
+
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ haveMCPCard.id -> {
+ triggerDependants(
+ source = haveMCPCard,
+ passedIndex = index,
+ triggerIndex = 1,
+ target = givenMCPCard
+ )
+ }
+ highriskSymbols.id -> {
+ if(highriskSymbols.value == highriskSymbols.entries!![0])
+ {
+ viewModel.onHighRiskSelected(true)
- else -> -1
+ }
+ triggerDependants(
+ source = highriskSymbols,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = highRiskReason,
+ targetSideEffect = listOf(anyOtherHighRiskCondition)
+ )
+
+ }
+
+ highRiskReason.id -> {
+ val index = highRiskReason.entries?.indexOf(highRiskReason.value).takeIf { it!! >= 0 }
+ ?: return -1
+ val triggerIndex = 7
+ return triggerDependants(
+ source = highRiskReason,
+ passedIndex = index,
+ triggerIndex = triggerIndex,
+ target = anyOtherHighRiskCondition
+ )
+ }
+
+ mobileNumber.id -> validateMobileNumberOnEditText(mobileNumber)
+ husbandName.id -> {
+ if (currentLanguage.toString() == english) {
+ // validateAllCapsOrSpaceOnEditText(husbandName)
+ validateAllCapsOrSpaceOnEditTextWithHindiEnabled(husbandName)
+ } else -1
+ }
+
+ bp.id -> validateForBp(bp)
+ weight.id -> validateIntMinMax(weight)
+
+
+ else -> -1
+ }
}
- }
- private fun getAddress(household: HouseholdCache): String {
- val houseNo = household.family?.houseNo
- val wardNo = household.family?.wardNo
- val name = household.family?.wardName
- val mohalla = household.family?.mohallaName
- val district = household.locationRecord.district.name
- val city = household.locationRecord.village.name
- val state = household.locationRecord.state.name
+ private fun getAddress(household: HouseholdCache): String {
+ val houseNo = household.family?.houseNo
+ val wardNo = household.family?.wardNo
+ val name = household.family?.wardName
+ val mohalla = household.family?.mohallaName
+ val district = household.locationRecord.district.name
+ val city = household.locationRecord.village.name
+ val state = household.locationRecord.state.name
- var address = "$houseNo, $wardNo, $name, $mohalla, $city, $district, $state"
- address = address.replace(", ,", ",")
- address = address.replace(",,", ",")
- address = address.replace(" ,", "")
- address = address.replace("null, ", "")
- address = address.replace(", null", "")
+ var address = "$houseNo, $wardNo, $name, $mohalla, $city, $district, $state"
+ address = address.replace(", ,", ",")
+ address = address.replace(",,", ",")
+ address = address.replace(" ,", "")
+ address = address.replace("null, ", "")
+ address = address.replace(", null", "")
- return address
- }
+ return address
+ }
+ fun Long.toStartOfDay(): Long {
+ val cal = Calendar.getInstance()
+ cal.timeInMillis = this
+ cal.set(Calendar.HOUR_OF_DAY, 0)
+ cal.set(Calendar.MINUTE, 0)
+ cal.set(Calendar.SECOND, 0)
+ cal.set(Calendar.MILLISECOND, 0)
+ return cal.timeInMillis
+ }
+ fun Calendar.setToStartOfTheDay(): Long {
+ this.set(Calendar.HOUR_OF_DAY, 0)
+ this.set(Calendar.MINUTE, 0)
+ this.set(Calendar.SECOND, 0)
+ this.set(Calendar.MILLISECOND, 0)
+ return this.timeInMillis
+ }
-}
\ No newline at end of file
+ }
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PncFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PncFormDataset.kt
index 1b05c2304..a0a80ec5f 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PncFormDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PncFormDataset.kt
@@ -1,47 +1,78 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.configuration.dynamicDataSet.FormField
import org.piramalswasthya.sakhi.helpers.Languages
import org.piramalswasthya.sakhi.helpers.setToStartOfTheDay
import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.DeliveryOutcomeCache
import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
import org.piramalswasthya.sakhi.model.PNCVisitCache
import org.piramalswasthya.sakhi.model.getDateStrFromLong
+import org.piramalswasthya.sakhi.ui.home_activity.maternal_health.pnc.form.PncFormViewModel
+import timber.log.Timber
import java.util.Calendar
import java.util.concurrent.TimeUnit
class PncFormDataset(
- context: Context, currentLanguage: Languages
+ context: Context, currentLanguage: Languages, private val viewModel: PncFormViewModel? = null
) : Dataset(context, currentLanguage) {
private var visit: Int = 0
private var dateOfDelivery: Long = 0L
- private val pncPeriod = FormElement(
+ companion object{
+ fun getMinDeliveryDate(): Long {
+ val cal = Calendar.getInstance()
+ cal.add(Calendar.YEAR, -1)
+ return cal.timeInMillis
+ }
+ }
+
+
+ private val deliveryDate = FormElement(
id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date_of_delivery),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = getMinDeliveryDate(),
+ isEnabled = true
+ )
+
+ private val pncDays = listOf(1, 3, 7, 14, 21, 28, 42)
+ private val pncDayLabels = resources.getStringArray(R.array.pnc_period_array)
+ private val pncDayLabelMap: Map = pncDays.zip(pncDayLabels).toMap()
+ private val pncLabelDayMap: Map = pncDayLabels.zip(pncDays).toMap()
+
+ private val pncPeriod = FormElement(
+ id = 2,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.pnc_period),
-// entries = resources.getStringArray(R.array.pnc_period_array),
arrayId = -1,
required = true,
hasDependants = false
)
private val visitDate = FormElement(
- id = 2,
- inputType = InputType.TEXT_VIEW,
+ id = 3,
+ inputType = InputType.DATE_PICKER,
title = resources.getString(R.string.pnc_visit_date),
arrayId = -1,
required = true,
hasDependants = false
)
+
private val ifaTabsGiven = FormElement(
- id = 3,
- inputType = InputType.EDIT_TEXT,
+ id = 4,
+ inputType = InputType.NUMBER_PICKER,
title = resources.getString(R.string.pnc_ifa_tabs_given),
required = false,
hasDependants = false,
@@ -49,10 +80,11 @@ class PncFormDataset(
etMaxLength = 3,
max = 400,
min = 0,
+ value = "0"
)
private val anyContraceptionMethod = FormElement(
- id = 4,
+ id = 5,
inputType = InputType.RADIO,
title = resources.getString(R.string.pnc_any_contraception_method),
entries = resources.getStringArray(R.array.pnc_confirmation_array),
@@ -61,16 +93,25 @@ class PncFormDataset(
)
private val contraceptionMethod = FormElement(
- id = 5,
+ id = 6,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.pnc_contraception_method),
- entries = resources.getStringArray(R.array.pnc_contraception_method_array),
+ entries = resources.getStringArray(R.array.pnc_contraception_method_array).let { entries ->
+ val englishEntries = englishResources.getStringArray(R.array.pnc_contraception_method_array)
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ val miniLapIndex = englishEntries.indexOfFirst { it.equals("MiniLap", ignoreCase = true) }
+ entries.filterIndexed { index, _ -> index != miniLapIndex }.toTypedArray()
+ } else {
+ val femSterIndex = englishEntries.indexOfFirst { it.equals("FEMALE STERILIZATION", ignoreCase = true) }
+ entries.filterIndexed { index, _ -> index != femSterIndex }.toTypedArray()
+ }
+ },
required = false,
hasDependants = true
)
private val otherPpcMethod = FormElement(
- id = 6,
+ id = 7,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.pnc_other_ppc_method),
required = true,
@@ -78,16 +119,16 @@ class PncFormDataset(
)
private val motherDangerSign = FormElement(
- id = 7,
+ id = 8,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.pnc_mother_danger_sign),
entries = resources.getStringArray(R.array.pnc_mother_danger_sign_array),
- required = false,
+ required = true,
hasDependants = true
)
private val otherDangerSign = FormElement(
- id = 8,
+ id = 9,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.pnc_other_danger_sign),
required = true,
@@ -95,7 +136,7 @@ class PncFormDataset(
)
private val referralFacility = FormElement(
- id = 9,
+ id = 10,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.pnc_referral_facility),
entries = resources.getStringArray(R.array.pnc_referral_facility_array),
@@ -104,7 +145,7 @@ class PncFormDataset(
)
private val motherDeath = FormElement(
- id = 10,
+ id = 11,
inputType = InputType.RADIO,
title = resources.getString(R.string.pnc_mother_death),
entries = resources.getStringArray(R.array.pnc_confirmation_array),
@@ -113,7 +154,7 @@ class PncFormDataset(
)
private val deathDate = FormElement(
- id = 11,
+ id = 12,
inputType = InputType.DATE_PICKER,
title = resources.getString(R.string.pnc_death_date),
arrayId = -1,
@@ -123,7 +164,7 @@ class PncFormDataset(
)
private val causeOfDeath = FormElement(
- id = 12,
+ id = 13,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.pnc_death_cause),
entries = resources.getStringArray(R.array.pnc_death_cause_array),
@@ -132,7 +173,7 @@ class PncFormDataset(
)
private val otherDeathCause = FormElement(
- id = 13,
+ id = 14,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.pnc_other_death_cause),
required = true,
@@ -140,51 +181,138 @@ class PncFormDataset(
)
private val placeOfDeath = FormElement(
- id = 14,
+ id = 15,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.pnc_death_place),
- entries = resources.getStringArray(R.array.pnc_death_place_array),
+ entries = resources.getStringArray(R.array.death_place_array),
required = true,
hasDependants = false,
)
private val remarks = FormElement(
- id = 15,
+ id = 16,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.pnc_remarks),
required = false,
hasDependants = false
)
+ private val otherPlaceOfDeath = FormElement(
+ id = 55,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.other_place_of_death),
+ required = true,
+ hasDependants = true,
+ )
+
+ private val dateOfSterilisation = FormElement(
+ id = 56,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date_of_sterilisation),
+ arrayId = -1,
+ max = System.currentTimeMillis(),
+ min = getMinDeliveryDate(),
+ required = true,
+ hasDependants = false
+
+ )
+ private val anySignOfDanger = FormElement(
+ id = 57,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.any_danger_signs) +
+ resources.getString(R.string.any_high_risk_identified),
+ entries = resources.getStringArray(R.array.pnc_confirmation_array),
+ required = false,
+ hasDependants = true
+ )
+
+ private val deliveryDischargeSummary1 = FormElement(
+ id = 58,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_1),
+ required = false
+
+ )
- suspend fun setUpPage(
+ private val deliveryDischargeSummary2 = FormElement(
+ id =59,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_2),
+ required = false
+ )
+
+ private val deliveryDischargeSummary3 = FormElement(
+ id =60,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_3),
+ required = false
+ )
+
+ private val deliveryDischargeSummary4 = FormElement(
+ id =61,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.delivery_discharge_summary_4),
+ required = false
+ )
+
+
+ private val sterilisation : Array by lazy {
+ resources.getStringArray(R.array.sterilization_methods_array)
+ }
+
+ suspend fun
+ setUpPage(
visitNumber: Int,
ben: BenRegCache,
- deliveryOutcomeCache: DeliveryOutcomeCache,
+ deliveryOutcomeCache: DeliveryOutcomeCache?=null,
previousPnc: PNCVisitCache?,
- saved: PNCVisitCache?
+ saved: PNCVisitCache?,
+ hasPreviousPermanentSterilization: Boolean = false
) {
val list = mutableListOf(
+ deliveryDate,
pncPeriod,
visitDate,
+ motherDeath,
ifaTabsGiven,
anyContraceptionMethod,
- motherDangerSign,
+ anySignOfDanger,
referralFacility,
- motherDeath,
- remarks
+ remarks,
+ deliveryDischargeSummary1,
+ deliveryDischargeSummary2,
+ deliveryDischargeSummary3,
+ deliveryDischargeSummary4,
+
+
)
- dateOfDelivery = deliveryOutcomeCache.dateOfDelivery!!
- deathDate.min = dateOfDelivery
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(deliveryDischargeSummary1)
+ list.remove(deliveryDischargeSummary2)
+ list.remove(deliveryDischargeSummary3)
+ list.remove(deliveryDischargeSummary4)
+ }
+
+ dateOfDelivery = deliveryOutcomeCache?.dateOfDelivery?:0L
+ if (dateOfDelivery!=0L){
+ deathDate.min = dateOfDelivery
+ deliveryDate.isEnabled = false
+ }
+
deathDate.max = System.currentTimeMillis()
+ anySignOfDanger.value = anySignOfDanger.entries!!.last()
motherDeath.value = motherDeath.entries!!.last()
val daysSinceDeliveryMillis = Calendar.getInstance()
- .setToStartOfTheDay().timeInMillis - deliveryOutcomeCache.dateOfDelivery!!.let {
+ .setToStartOfTheDay().timeInMillis - deliveryOutcomeCache?.dateOfDelivery.let {
val cal = Calendar.getInstance()
- cal.timeInMillis = it
+ if (it != null) {
+ cal.timeInMillis = it
+ }
cal.setToStartOfTheDay()
cal.timeInMillis
}
val daysSinceDelivery = TimeUnit.MILLISECONDS.toDays(daysSinceDeliveryMillis)
+ deliveryDate.value = getDateFromLong(dateOfDelivery)
pncPeriod.entries =
listOf(
1,
@@ -196,10 +324,46 @@ class PncFormDataset(
42
).filter { if (daysSinceDelivery == 0L) it <= 1 else it <= daysSinceDelivery }
.filter { it > (previousPnc?.pncPeriod ?: 0) }
- .map { "Day $it" }.toTypedArray()
+ .map { pncDayLabelMap[it] ?: "Day $it" }.toTypedArray()
+
+ if (hasPreviousPermanentSterilization) {
+
+ anyContraceptionMethod.isEnabled = false
+ contraceptionMethod.isEnabled = false
+ dateOfSterilisation.isEnabled = false
+ otherPpcMethod.isEnabled = false
+
+
+ val lastSterilizationVisit =
+ viewModel?.getLastPermanentSterilizationVisit(ben.beneficiaryId, visitNumber)
+ lastSterilizationVisit?.let { sterilizationVisit ->
+
+ anyContraceptionMethod.value = if (sterilizationVisit.anyContraceptionMethod == true)
+ anyContraceptionMethod.entries!!.first() else anyContraceptionMethod.entries!!.last()
+
+ contraceptionMethod.value = sterilizationVisit.contraceptionMethod
+ dateOfSterilisation.value = getDateFromLong(sterilizationVisit.sterilisationDate!!)
+ otherPpcMethod.value = sterilizationVisit.otherPpcMethod
+
+ if (sterilizationVisit.anyContraceptionMethod == true) {
+ list.add(list.indexOf(anyContraceptionMethod) + 1, contraceptionMethod)
+
+ if (sterilizationVisit.contraceptionMethod in sterilisation) {
+ list.add(list.indexOf(contraceptionMethod) + 1, dateOfSterilisation)
+ }
+
+ if (sterilizationVisit.contraceptionMethod == contraceptionMethod.entries!!.last()) {
+ list.add(list.indexOf(contraceptionMethod) + 1, otherPpcMethod)
+ }
+ }
+
+
+ }}
+
+
saved?.let {
- pncPeriod.value = "Day ${it.pncPeriod}"
+ pncPeriod.value = pncDayLabelMap[it.pncPeriod] ?: "Day ${it.pncPeriod}"
visitDate.value = getDateFromLong(it.pncDate)
ifaTabsGiven.value = it.ifaTabsGiven?.toString()
anyContraceptionMethod.value = it.anyContraceptionMethod?.let {
@@ -211,24 +375,45 @@ class PncFormDataset(
if (it.anyContraceptionMethod == true) {
list.add(list.indexOf(anyContraceptionMethod) + 1, contraceptionMethod)
}
- contraceptionMethod.value = it.contraceptionMethod
- if (it.contraceptionMethod == contraceptionMethod.entries!!.last()) {
+ contraceptionMethod.value = getLocalValueInArray(R.array.pnc_contraception_method_array, it.contraceptionMethod)
+ it.sterilisationDate.let { it2 ->
+ dateOfSterilisation.value = getDateFromLong(it2 ?: 0L)
+ }
+ if (contraceptionMethod.value == contraceptionMethod.entries!!.last()) {
list.add(list.indexOf(contraceptionMethod) + 1, otherPpcMethod)
+
+ }
+ if(contraceptionMethod.value in sterilisation )
+ {
+ list.add(list.indexOf(contraceptionMethod) + 1, dateOfSterilisation)
+
}
+
otherPpcMethod.value = it.otherPpcMethod
- motherDangerSign.value = it.motherDangerSign
- if (it.motherDangerSign == motherDangerSign.entries!!.last()) {
+ anySignOfDanger.value = getLocalValueInArray(R.array.pnc_confirmation_array, it.anyDangerSign)
+ anySignOfDanger.value?.let { dangerSignValue ->
+ val isDangerSignYes = dangerSignValue == anySignOfDanger.entries!!.first()
+ referralFacility.required = isDangerSignYes
+ }
+ motherDangerSign.value = getLocalValueInArray(R.array.pnc_mother_danger_sign_array, it.motherDangerSign)
+ if (motherDangerSign.value == motherDangerSign.entries!!.last()) {
list.add(list.indexOf(motherDangerSign) + 1, otherDangerSign)
}
otherDangerSign.value = it.otherDangerSign
- referralFacility.value = it.referralFacility
+ referralFacility.value = getLocalValueInArray(R.array.pnc_referral_facility_array, it.referralFacility)
motherDeath.value =
if (it.motherDeath) motherDeath.entries!!.first() else motherDeath.entries!!.last()
if (it.motherDeath) {
deathDate.value = getDateStrFromLong(it.deathDate)
- causeOfDeath.value = it.causeOfDeath
+ causeOfDeath.value = getLocalValueInArray(R.array.pnc_death_cause_array, it.causeOfDeath)
otherDeathCause.value = it.otherDeathCause
- placeOfDeath.value = it.placeOfDeath
+ placeOfDeath.value = getLocalValueInArray(R.array.death_place_array, it.placeOfDeath)
+ otherPlaceOfDeath.value = it.otherPlaceOfDeath
+ placeOfDeath.entries?.indexOf(placeOfDeath.value)?.takeIf { it >= 0 }?.let { index ->
+ if (index == 8) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ }
+ }
list.addAll(
list.indexOf(motherDeath) + 1,
listOf(deathDate, causeOfDeath, placeOfDeath)
@@ -237,6 +422,11 @@ class PncFormDataset(
list.add(list.indexOf(causeOfDeath) + 1, otherDeathCause)
}
remarks.value = it.remarks
+ deliveryDischargeSummary1.value = it.deliveryDischargeSummary1
+ deliveryDischargeSummary2.value = it.deliveryDischargeSummary2
+ deliveryDischargeSummary3.value = it.deliveryDischargeSummary3
+ deliveryDischargeSummary4.value = it.deliveryDischargeSummary4
+
}
// pncPeriod.entries = pncPeriod.entries!!.
@@ -287,10 +477,15 @@ class PncFormDataset(
override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
return when (formId) {
pncPeriod.id -> {
- visitDate.inputType = InputType.DATE_PICKER
+ dateOfDelivery = getLongFromDate(deliveryDate.value)
+
visitDate.value = null
+ visitDate.inputType = InputType.DATE_PICKER
+
+
+
val today = Calendar.getInstance().setToStartOfTheDay().timeInMillis
- when (val visitNumber = pncPeriod.value!!.substring(4).toInt()) {
+ when (val visitNumber = pncLabelDayMap[pncPeriod.value] ?: pncPeriod.value!!.replace("Day ", "").toInt()) {
1 -> {
visitDate.min = minOf(today, dateOfDelivery)
visitDate.max = minOf(
@@ -397,21 +592,120 @@ class PncFormDataset(
return -1
}
+ placeOfDeath.id -> {
+ val index = placeOfDeath.entries?.indexOf(placeOfDeath.value).takeIf { it!! >= 0 } ?: return -1
+ val triggerIndex = 8
+ return triggerDependants(
+ source = placeOfDeath,
+ passedIndex = index,
+ triggerIndex = triggerIndex,
+ target = otherPlaceOfDeath
+ )
+ }
+
ifaTabsGiven.id -> validateIntMinMax(ifaTabsGiven)
+
anyContraceptionMethod.id -> triggerDependants(
source = anyContraceptionMethod,
passedIndex = index,
triggerIndex = 0,
target = contraceptionMethod,
- targetSideEffect = listOf(otherPpcMethod)
+ targetSideEffect = listOf(
+ otherPpcMethod,
+ dateOfSterilisation
+ )
)
- contraceptionMethod.id -> triggerDependants(
- source = contraceptionMethod,
- passedIndex = index,
- triggerIndex = contraceptionMethod.entries!!.lastIndex,
- target = otherPpcMethod,
- )
+
+ contraceptionMethod.id -> {
+ val selected = contraceptionMethod.entries?.getOrNull(index)?.trim() ?: ""
+ Timber.d("Selected contraception: '$selected' (index=$index)")
+
+ val requiresIncentiveAlert = selected.isNotEmpty() &&
+ !selected.equals("CONDOM", ignoreCase = true) &&
+ !selected.equals(contraceptionMethod.entries!!.last().trim(), ignoreCase = true)
+
+ if (requiresIncentiveAlert) {
+ if (!BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ viewModel?.triggerIncentiveAlert()
+ }
+ }
+
+ val anyOtherValue = contraceptionMethod.entries!!.last().trim()
+ val result1 = if (selected.equals(anyOtherValue, ignoreCase = true)) {
+ Timber.d("Will add OtherPPCMethod")
+ triggerDependants(
+ source = contraceptionMethod,
+ passedIndex = index,
+ triggerIndex = contraceptionMethod.entries!!.lastIndex,
+ target = otherPpcMethod
+ )
+ } else {
+
+ triggerDependants(
+ source = contraceptionMethod,
+ passedIndex = -1, // Force removal
+ triggerIndex = contraceptionMethod.entries!!.lastIndex,
+ target = otherPpcMethod
+ )
+ }
+
+
+ val isSterilisation = sterilisation.any { it.equals(selected, ignoreCase = true) }
+ Timber.d("isSterilisation = $isSterilisation")
+ val result2 = if (isSterilisation) {
+ dateOfSterilisation.min = dateOfDelivery
+ dateOfSterilisation.max = System.currentTimeMillis()
+ Timber.d("Will add DateOfSterilisation")
+ triggerDependants(
+ source = contraceptionMethod,
+ passedIndex = index,
+ triggerIndex = index,
+ target = dateOfSterilisation
+ )
+ } else {
+ dateOfSterilisation.value = null
+
+ triggerDependants(
+ source = contraceptionMethod,
+ passedIndex = -1,
+ triggerIndex = index,
+ target = dateOfSterilisation
+ )
+ }
+
+ if (result1 != -1) result1 else result2
+ }
+
+ anySignOfDanger.id -> {
+ val result = triggerDependants(
+ source = anySignOfDanger,
+ passedIndex = index,
+ triggerIndex = 0,
+ target = motherDangerSign,
+ targetSideEffect = listOf(otherDangerSign)
+ )
+
+ val oldRequiredState = referralFacility.required
+
+ if (index == 0) {
+ referralFacility.required = true
+
+ /* if (referralFacility.value.isNullOrEmpty()) {
+ referralFacility.errorText = "This field is required"
+ }*/
+ } else {
+ referralFacility.required = false
+ referralFacility.errorText = null
+ }
+ val referralFacilityIndex = getIndexById(referralFacility.id)
+ return if (oldRequiredState != referralFacility.required && referralFacilityIndex != -1) {
+ referralFacilityIndex
+ } else {
+ result
+ }}
+
+
motherDangerSign.id ->
triggerDependants(
@@ -421,7 +715,8 @@ class PncFormDataset(
target = otherDangerSign
)
- motherDeath.id -> {
+ /* motherDeath.id -> {
+
triggerDependants(
source = motherDeath,
passedIndex = index,
@@ -429,8 +724,51 @@ class PncFormDataset(
target = listOf(deathDate, causeOfDeath, placeOfDeath),
targetSideEffect = listOf(otherDeathCause)
)
+
+ }*/
+
+ motherDeath.id -> {
+ if (index == 0) {
+ triggerDependants(
+ source = motherDeath,
+ removeItems = listOf(
+ ifaTabsGiven,
+ anyContraceptionMethod,
+ anySignOfDanger,
+ referralFacility,
+ remarks
+
+ ),
+ addItems = listOf(
+ deathDate,
+ causeOfDeath,
+ placeOfDeath,
+ otherDeathCause
+ )
+ )
+ } else {
+ triggerDependants(
+ source = motherDeath,
+ removeItems = listOf(
+ deathDate,
+ causeOfDeath,
+ placeOfDeath,
+ otherDeathCause
+ ),
+ addItems = listOf(
+ ifaTabsGiven,
+ anyContraceptionMethod,
+ anySignOfDanger,
+ referralFacility,
+ remarks
+
+ )
+ )
+ }
}
+
+
causeOfDeath.id -> {
triggerDependants(
source = causeOfDeath,
@@ -455,25 +793,68 @@ class PncFormDataset(
// return -1
// }
+
+
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as PNCVisitCache).let { form ->
- form.pncPeriod = pncPeriod.value!!.substring(4).toInt()
+ form.pncPeriod = pncLabelDayMap[pncPeriod.value] ?: pncPeriod.value!!.replace("Day ", "").toInt()
form.pncDate = getLongFromDate(visitDate.value!!)
+ form.otherPlaceOfDeath=otherPlaceOfDeath.value
+ form.dateOfDelivery = getLongFromDate(deliveryDate.value)
form.ifaTabsGiven = ifaTabsGiven.value?.takeIf { it.isNotEmpty() }?.toInt()
form.anyContraceptionMethod =
anyContraceptionMethod.value?.let { it == anyContraceptionMethod.entries!!.first() }
- form.contraceptionMethod = contraceptionMethod.value?.takeIf { it.isNotEmpty() }
+ form.contraceptionMethod = getEnglishValueInArray(R.array.pnc_contraception_method_array, contraceptionMethod.value)?.takeIf { it.isNotEmpty() }
form.otherPpcMethod = otherPpcMethod.value?.takeIf { it.isNotEmpty() }
- form.motherDangerSign = motherDangerSign.value?.takeIf { it.isNotEmpty() }
+ form.motherDangerSign = getEnglishValueInArray(R.array.pnc_mother_danger_sign_array, motherDangerSign.value)?.takeIf { it.isNotEmpty() }
form.otherDangerSign = otherDangerSign.value?.takeIf { it.isNotEmpty() }
- form.referralFacility = referralFacility.value?.takeIf { it.isNotEmpty() }
+ form.referralFacility = getEnglishValueInArray(R.array.pnc_referral_facility_array, referralFacility.value)?.takeIf { it.isNotEmpty() }
form.motherDeath =
motherDeath.value?.let { it == motherDeath.entries!!.first() } ?: false
form.deathDate = deathDate.value?.let { getLongFromDate(it) }
- form.causeOfDeath = causeOfDeath.value?.takeIf { it.isNotEmpty() }
+ form.causeOfDeath = getEnglishValueInArray(R.array.pnc_death_cause_array, causeOfDeath.value)?.takeIf { it.isNotEmpty() }
form.otherDeathCause = otherDeathCause.value?.takeIf { it.isNotEmpty() }
- form.placeOfDeath = placeOfDeath.value?.takeIf { it.isNotEmpty() }
+ form.placeOfDeath = getEnglishValueInArray(R.array.death_place_array, placeOfDeath.value)?.takeIf { it.isNotEmpty() }
form.remarks = remarks.value?.takeIf { it.isNotEmpty() }
+ form.deliveryDischargeSummary1 = deliveryDischargeSummary1.value?.takeIf { it.isNotEmpty() }
+ form.deliveryDischargeSummary2 = deliveryDischargeSummary2.value?.takeIf { it.isNotEmpty() }
+ form.deliveryDischargeSummary3 = deliveryDischargeSummary3.value?.takeIf { it.isNotEmpty() }
+ form.deliveryDischargeSummary4 = deliveryDischargeSummary4.value?.takeIf { it.isNotEmpty() }
+
+
+ }
+ }
+
+ fun getIndexDeliveryDischargeSummary1 () = getIndexById(deliveryDischargeSummary1.id)
+ fun getIndexDeliveryDischargeSummary2 () = getIndexById(deliveryDischargeSummary2.id)
+ fun getIndexDeliveryDischargeSummary3 () = getIndexById(deliveryDischargeSummary3.id)
+ fun getIndexDeliveryDischargeSummary4 () = getIndexById(deliveryDischargeSummary4.id)
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ 58 -> {
+ deliveryDischargeSummary1.value = dpUri.toString()
+ deliveryDischargeSummary1.errorText = null
+ }
+ 59 -> {
+ deliveryDischargeSummary2.value = dpUri.toString()
+ deliveryDischargeSummary2.errorText = null
+ }
+ 60 -> {
+ deliveryDischargeSummary3.value = dpUri.toString()
+ deliveryDischargeSummary3.errorText = null
+ }
+ 61 -> {
+ deliveryDischargeSummary4.value = dpUri.toString()
+ deliveryDischargeSummary4.errorText = null
+ }
+
}
}
+
+
+
+
+
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanAncAbortionDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanAncAbortionDataset.kt
new file mode 100644
index 000000000..fbee50012
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanAncAbortionDataset.kt
@@ -0,0 +1,331 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import android.util.Log
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.helpers.getWeeksOfPregnancy
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.PregnantWomanAncCache
+import java.util.concurrent.TimeUnit
+
+class PregnantWomanAncAbortionDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private var lastAncVisitDate: Long = 0L
+ private lateinit var regis: PregnantWomanAncCache
+
+ private val visitDate = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.visit_date),
+ required = true,
+ max = System.currentTimeMillis(),
+ hasDependants = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_anc_date,
+ showDrawable = true
+ )
+
+ private val weekOfPregnancy = FormElement(
+ id = 2,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.weeks_of_pregnancy),
+ required = false,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
+ )
+
+ private val abortionDate = FormElement(
+ id = 3,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.abortion_date),
+ required = false,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
+ )
+
+ private val abortionType = FormElement(
+ id = 4,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.abortion_type),
+ required = false,
+ )
+
+ private val abortionFacility = FormElement(
+ id = 5,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.facility_place_of_abortion),
+ required = false,
+ )
+
+ private val serialNoAsPerAdmission = FormElement(
+ id = 6,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.serial_no_as_per_admission_evacuation_register),
+ arrayId = -1,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_SIGNED,
+ etMaxLength = 10,
+ required = false,
+ )
+
+ private val methodOfTermination = FormElement(
+ id = 7,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.method_of_termination),
+ arrayId = R.array.anc_method_of_termination,
+ entries = resources.getStringArray(R.array.anc_method_of_termination),
+ required = false,
+ hasDependants = true,
+ )
+
+ private val terminationDoneBy = FormElement(
+ id = 8,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.termination_done_by),
+ arrayId = R.array.anc_termination_done_by,
+ entries = resources.getStringArray(R.array.anc_termination_done_by),
+ required = false,
+ )
+
+ private val isPlanig = FormElement(
+ id = 25,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.what_family_planning_method_has_been_chosen_after_the_abortion),
+ required = false,
+ hasDependants = false
+ )
+ private val isPaiucd = FormElement(
+ id = 9,
+ inputType = InputType.RADIO,
+ title = " ",
+ arrayId = R.array.abortion_isplaning_array,
+ entries = resources.getStringArray(R.array.abortion_isplaning_array),
+ required = false,
+ orientation = 1,
+ hasDependants = true
+ )
+
+ private val isYesOrNo = FormElement(
+ id = 23,
+ inputType = InputType.RADIO,
+ title = " ",
+ arrayId = R.array.anc_confirmation_array,
+ entries = resources.getStringArray(R.array.anc_confirmation_array),
+ required = true,
+ orientation = 1,
+ hasDependants = true
+ )
+ private val dateOfSterilization = FormElement(
+ id = 24,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date_of_sterilisation),
+ required = true,
+ max = System.currentTimeMillis(),
+ hasDependants = true,
+ )
+
+ private val remarks = FormElement(
+ id = 10,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.remarks),
+ arrayId = -1,
+ etMaxLength = 100,
+ required = false,
+ )
+
+ private val abortionDischargeSummaryImg1 = FormElement(
+ id = 21,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.abortion_discharge_summary_1),
+ required = false,
+ )
+
+ private val abortionDischargeSummaryImg2 = FormElement(
+ id = 22,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.abortion_discharge_summary_2),
+ required = false,
+ )
+
+ private var toggleBp = false
+
+ fun resetBpToggle() {
+ toggleBp = false
+ }
+
+ fun triggerBpToggle() = toggleBp
+
+ suspend fun setUpPage(
+ ben: BenRegCache?,
+ lastAnc: PregnantWomanAncCache?,
+ saved: PregnantWomanAncCache?
+ ) {
+ this.regis = lastAnc!!
+
+ val list = mutableListOf(
+ visitDate,
+ weekOfPregnancy,
+ abortionDate,
+ abortionType,
+ abortionFacility,
+ serialNoAsPerAdmission,
+ methodOfTermination,
+ terminationDoneBy,
+ isPlanig,
+ isPaiucd,
+ remarks,
+ abortionDischargeSummaryImg1,
+ abortionDischargeSummaryImg2,
+ )
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(abortionDischargeSummaryImg1)
+ list.remove(abortionDischargeSummaryImg2)
+ }
+
+
+ val now = System.currentTimeMillis()
+ val oneYearMillis = TimeUnit.DAYS.toMillis(365)
+
+ abortionDate.min = regis.lmpDate?.plus(
+ TimeUnit.DAYS.toMillis(5 * 7 + 1)
+ ) ?: (now - oneYearMillis)
+
+ abortionDate.max = regis.lmpDate?.let { lmp ->
+ minOf(
+ now,
+ lmp + TimeUnit.DAYS.toMillis(21 * 7)
+ )
+ } ?: now
+
+ if (saved == null) {
+ visitDate.min = regis.abortionDate
+ dateOfSterilization.min = regis.abortionDate
+ val woP = getWeeksOfPregnancy(regis.ancDate, regis.lmpDate)
+ weekOfPregnancy.value = woP.toString()
+ abortionType.value = getLocalValueInArray(R.array.anc_abortion_type_array, regis.abortionType)
+ abortionFacility.value = getLocalValueInArray(R.array.abortion_place_array, regis.abortionFacility)
+ abortionDate.value = regis.abortionDate?.let { getDateFromLong(it) }
+ } else {
+ isPaiucd.value = when (saved.isPaiucdId) {
+ 1 -> isPaiucd.entries?.getOrNull(0)
+ 2 -> isPaiucd.entries?.getOrNull(1)
+ else -> null
+ }
+ if (saved.isPaiucdId != 0) {
+ list.add(list.indexOf(isPaiucd) + 1, isYesOrNo)
+ isYesOrNo.value = getLocalValueInArray(R.array.anc_confirmation_array, if (saved.isYesOrNo == true) "Yes" else "No")
+
+ if (saved.isPaiucdId == 2 && saved.isYesOrNo == true) {
+ list.add(list.indexOf(isYesOrNo) + 1, dateOfSterilization)
+ dateOfSterilization.value = saved.dateSterilisation?.let { getDateFromLong(it) }
+ }
+ }
+
+
+
+ dateOfSterilization.min=saved.abortionDate
+ visitDate.min = saved.abortionDate
+ visitDate.value = saved.visitDate?.let { getDateFromLong(it) }
+
+ val woP = getWeeksOfPregnancy(saved.ancDate, regis.lmpDate)
+ weekOfPregnancy.value = woP.toString()
+ abortionType.value = getLocalValueInArray(R.array.anc_abortion_type_array, saved.abortionType)
+ abortionFacility.value = getLocalValueInArray(R.array.abortion_place_array, saved.abortionFacility)
+ abortionDate.value = saved.abortionDate?.let { getDateFromLong(it) }
+ serialNoAsPerAdmission.value = saved.serialNo
+ methodOfTermination.value = getLocalValueInArray(R.array.anc_method_of_termination, saved.methodOfTermination)
+ terminationDoneBy.value = getLocalValueInArray(R.array.anc_termination_done_by, saved.terminationDoneBy)
+ remarks.value = saved.remarks
+ abortionDischargeSummaryImg1.value = saved.abortionImg1
+ abortionDischargeSummaryImg2.value = saved.abortionImg2
+ }
+
+ setUpPage(list)
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+
+ return when (formId) {
+ isPaiucd.id -> {
+ isYesOrNo.value=null
+ triggerDependants(
+ source = isPaiucd,
+ addItems = listOf(isYesOrNo),
+ removeItems = listOf(dateOfSterilization),
+ )
+ }
+
+
+ isYesOrNo.id -> {
+ val isPaiucdSecondOption = (isPaiucd.entries?.indexOf(isPaiucd.value ?: "") ?: -1) == 1
+ val isYes = isYesOrNo.entries?.indexOf(isYesOrNo.value ?: "") == 0
+ if (isYes && isPaiucdSecondOption) {
+ triggerDependants(
+ source = isYesOrNo,
+ addItems = listOf(dateOfSterilization),
+ removeItems = emptyList()
+ )
+ } else {
+ triggerDependants(
+ source = isYesOrNo,
+ addItems = emptyList(),
+ removeItems = listOf(dateOfSterilization)
+ )
+ }
+ }
+
+ else -> -1
+ }
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as PregnantWomanAncCache).let { cache ->
+ cache.visitDate = visitDate.value?.let { getLongFromDate(it) }
+ cache.lmpDate = regis.lmpDate
+ cache.abortionType = abortionType.value
+ cache.abortionTypeId = abortionType.getPosition()
+ cache.abortionFacility = abortionFacility.value
+ cache.abortionFacilityId = abortionFacility.getPosition()
+ cache.abortionDate = abortionDate.value?.let { getLongFromDate(it) }
+ cache.serialNo = serialNoAsPerAdmission.value
+ cache.methodOfTermination = methodOfTermination.getEnglishStringFromPosition(methodOfTermination.getPosition())
+ cache.methodOfTerminationId = methodOfTermination.getPosition().takeIf { it > 0 }?.minus(1)
+ cache.terminationDoneBy = terminationDoneBy.getEnglishStringFromPosition(terminationDoneBy.getPosition())
+ cache.terminationDoneById = terminationDoneBy.getPosition().takeIf { it > 0 }?.minus(1)
+ cache.isPaiucd = isPaiucd.getEnglishStringFromPosition(isPaiucd.getPosition())
+ cache.isPaiucdId = isPaiucd.getPosition()
+ cache.isYesOrNo = isYesOrNo.entries?.indexOf(isYesOrNo.value ?: "") == 0
+ cache.remarks = remarks.value
+ cache.dateSterilisation = dateOfSterilization.value?.let { getLongFromDate(it) }
+ cache.abortionImg1 = abortionDischargeSummaryImg1.value
+ cache.abortionImg2 = abortionDischargeSummaryImg2.value
+ }
+ }
+
+ fun getWeeksOfPregnancy(): Int = getIndexById(weekOfPregnancy.id)
+ fun getIndexOfAbortionDischarge1() = getIndexById(abortionDischargeSummaryImg1.id)
+ fun getIndexOfAbortionDischarge2() = getIndexById(abortionDischargeSummaryImg2.id)
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ 21 -> {
+ abortionDischargeSummaryImg1.value = dpUri.toString()
+ abortionDischargeSummaryImg1.errorText = null
+ }
+
+ 22 -> {
+ abortionDischargeSummaryImg2.value = dpUri.toString()
+ abortionDischargeSummaryImg2.errorText = null
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanAncVisitDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanAncVisitDataset.kt
index 08288c3a5..b93cde591 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanAncVisitDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanAncVisitDataset.kt
@@ -1,6 +1,9 @@
package org.piramalswasthya.sakhi.configuration
import android.content.Context
+import android.net.Uri
+import android.util.Log
+import org.piramalswasthya.sakhi.BuildConfig
import org.piramalswasthya.sakhi.R
import org.piramalswasthya.sakhi.database.room.SyncState
import org.piramalswasthya.sakhi.helpers.Konstants
@@ -9,6 +12,8 @@ import org.piramalswasthya.sakhi.helpers.getWeeksOfPregnancy
import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.FormElement
import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
import org.piramalswasthya.sakhi.model.PregnantWomanAncCache
import org.piramalswasthya.sakhi.model.PregnantWomanRegistrationCache
import java.util.concurrent.TimeUnit
@@ -25,76 +30,124 @@ class PregnantWomanAncVisitDataset(
private val ancDate = FormElement(
id = 1,
inputType = InputType.DATE_PICKER,
- title = "ANC Date",
+ title = resources.getString(R.string.anc_date),
required = true,
hasDependants = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_anc_date,
+ showDrawable = true
)
+ private val placeOfAnc = FormElement(
+ id = 45,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_anc),
+ arrayId = R.array.place_of_anc_array,
+ entries = resources.getStringArray(R.array.place_of_anc_array),
+ required = true,
+ hasDependants = true,
+ )
+
private val weekOfPregnancy = FormElement(
id = 2,
inputType = InputType.TEXT_VIEW,
- title = "Weeks of Pregnancy",
+ title = resources.getString(R.string.weeks_of_pregnancy),
required = false,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val ancVisit = FormElement(
id = 3,
inputType = InputType.DROPDOWN,
- title = "ANC Period",
+ title = resources.getString(R.string.anc_period),
required = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val isAborted = FormElement(
id = 4,
inputType = InputType.RADIO,
- title = "Abortion If Any",
+ title = resources.getString(R.string.abortion_if_any),
arrayId = R.array.anc_confirmation_array1,
entries = resources.getStringArray(R.array.anc_confirmation_array1),
required = false,
- hasDependants = true
+ hasDependants = true,
)
private val abortionType = FormElement(
id = 5,
- inputType = InputType.RADIO,
- title = "Abortion Type",
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.abortion_type),
arrayId = R.array.anc_abortion_type_array,
entries = resources.getStringArray(R.array.anc_abortion_type_array),
required = true,
- hasDependants = true
+ hasDependants = true,
+ )
+
+
+
+ private val placeOfDeath = FormElement(
+ id = 42,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.place_of_death),
+ arrayId = R.array.death_place_array,
+ entries = resources.getStringArray(R.array.death_place_array),
+ required = true,
+ )
+ private val otherPlaceOfDeath = FormElement(
+ id = 43,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.other_place_of_death),
+ required = true,
+ hasDependants = true,
)
+
+
private val abortionFacility = FormElement(
id = 6,
- inputType = InputType.RADIO,
- title = "Facility",
- arrayId = R.array.anc_abortion_facility_array,
- entries = resources.getStringArray(R.array.anc_abortion_facility_array),
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.facility_place_of_abortion),
+ arrayId = R.array.abortion_place_array,
+ entries = resources.getStringArray(R.array.abortion_place_array),
required = true,
- hasDependants = true
+ hasDependants = true,
)
private val abortionDate = FormElement(
id = 7,
inputType = InputType.DATE_PICKER,
- title = "Abortion Date",
+ title = resources.getString(R.string.abortion_date),
required = true,
max = System.currentTimeMillis(),
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val weight = FormElement(
id = 8,
inputType = InputType.EDIT_TEXT,
- title = "Weight of PW (Kg) at time Registration",
+ title = resources.getString(R.string.weight_of_pw_kg),
arrayId = -1,
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 3,
required = false,
min = 30,
- max = 200
+ max = 200,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_pw_weight,
)
private val bp = FormElement(
id = 9,
inputType = InputType.EDIT_TEXT,
- title = "BP of PW – Systolic/ Diastolic (mm Hg) ",
+ title = resources.getString(R.string.bp_of_pw),
// etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 7,
- required = false,
+ required = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_blood_pressure,
)
// private val bpDiastolic = FormElement(
// id = 10,
@@ -130,122 +183,162 @@ class PregnantWomanAncVisitDataset(
private val pulseRate = FormElement(
id = 11,
inputType = InputType.EDIT_TEXT,
- etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ title = resources.getString(R.string.pulse_rate_bpm),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL,
etMaxLength = 3,
- title = "Pulse Rate",
+ minDecimal = 40.0,
+ maxDecimal = 200.0,
required = false,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_pulse_rate,
)
+
private val hb = FormElement(
id = 12,
inputType = InputType.EDIT_TEXT,
- title = "HB (gm/dl)",
+ title = resources.getString(R.string.hb_gm_dl),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL,
etMaxLength = 4,
minDecimal = 2.0,
maxDecimal = 15.0,
- required = false,
+ required = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_blood_test,
)
private val fundalHeight = FormElement(
id = 13,
inputType = InputType.EDIT_TEXT,
- title = "Fundal Height / Size of the Uterus weeks",
+ title = resources.getString(R.string.fundal_height_uterus),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
+ min = 1,
+ max = 99,
required = false,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_fundal_height,
)
private val urineAlbumin = FormElement(
id = 14,
inputType = InputType.RADIO,
- title = "Urine Albumin",
+ title = resources.getString(R.string.urine_albumin),
arrayId = R.array.anc_urine_albumin_array,
entries = resources.getStringArray(R.array.anc_urine_albumin_array),
required = false,
+ showDrawable = true
)
private val randomBloodSugarTest = FormElement(
id = 15,
inputType = InputType.RADIO,
- title = "Random Blood Sugar Test",
+ title = resources.getString(R.string.random_blood_sugar_test),
arrayId = R.array.anc_random_blood_sugar_test_array,
entries = resources.getStringArray(R.array.anc_random_blood_sugar_test_array),
required = false,
+ showDrawable = true
)
private val dateOfTTOrTd1 = FormElement(
id = 16,
inputType = InputType.DATE_PICKER,
- title = "Date of Td TT (1st Dose)",
+ title = resources.getString(R.string.date_td_tt_1st_dose),
required = false,
hasDependants = true,
max = System.currentTimeMillis(),
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val dateOfTTOrTd2 = FormElement(
id = 17,
inputType = InputType.DATE_PICKER,
- title = "Date of Td TT (2nd Dose)",
+ title = resources.getString(R.string.date_td_tt_2nd_dose),
required = false,
max = System.currentTimeMillis(),
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val dateOfTTOrTdBooster = FormElement(
id = 18,
inputType = InputType.DATE_PICKER,
- title = "Date of Td TT (Boooster Dose)",
+ title = resources.getString(R.string.date_td_tt_booster_dose),
required = false,
hasDependants = true,
max = System.currentTimeMillis(),
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val numFolicAcidTabGiven = FormElement(
id = 19,
inputType = InputType.EDIT_TEXT,
- title = "No. of Folic Acid Tabs given",
+ title = resources.getString(R.string.no_of_folic_acid_tabs),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 2,
required = false,
min = 0,
- max = 60
+ max = 60,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_tablets,
)
private val numIfaAcidTabGiven = FormElement(
id = 20,
inputType = InputType.EDIT_TEXT,
- title = "No. of IFA Tabs given",
+ title = resources.getString(R.string.no_of_ifa_tabs),
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
etMaxLength = 3,
required = false,
min = 0,
- max = 400
+ max = 400,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_tablets,
)
private val anyHighRisk = FormElement(
id = 21,
inputType = InputType.RADIO,
- title = "Any High Risk conditions",
+ title = resources.getString(R.string.any_high_risk_conditions),
arrayId = R.array.anc_confirmation_array1,
entries = resources.getStringArray(R.array.anc_confirmation_array1),
required = false,
hasDependants = true
)
private val highRiskCondition = FormElement(
- id = 22, inputType = InputType.DROPDOWN, title = "High Risk Conditions",
+ id = 22, inputType = InputType.DROPDOWN, title = resources.getString(R.string.high_risk_conditions),
arrayId = R.array.anc_high_risk_array,
entries = resources.getStringArray(R.array.anc_high_risk_array),
- required = false, hasDependants = true
+ required = false, hasDependants = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val otherHighRiskCondition = FormElement(
id = 23,
inputType = InputType.EDIT_TEXT,
- title = "Any other High Risk conditions",
+ title = resources.getString(R.string.any_other_high_risk_conditions),
required = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val highRiskReferralFacility = FormElement(
id = 24,
inputType = InputType.DROPDOWN,
- title = "Referral Facility",
+ title = resources.getString(R.string.referral_facility),
arrayId = R.array.anc_referral_facility_array,
entries = resources.getStringArray(R.array.anc_referral_facility_array),
required = false,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_referral,
)
private val hrpConfirm = FormElement(
- id = 25, inputType = InputType.RADIO, title = "Is HRP Confirmed?",
+ id = 25, inputType = InputType.RADIO, title = resources.getString(R.string.is_hrp_confirmed),
arrayId = R.array.anc_confirmation_array1,
entries = resources.getStringArray(R.array.anc_confirmation_array1),
required = false, hasDependants = true
@@ -253,13 +346,17 @@ class PregnantWomanAncVisitDataset(
private val hrpConfirmedBy = FormElement(
id = 26,
inputType = InputType.DROPDOWN,
- title = "Who had identified as HRP?",
+ title = resources.getString(R.string.who_identified_hrp),
arrayId = R.array.anc_confirmed_by_array,
entries = resources.getStringArray(R.array.anc_confirmed_by_array),
required = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val maternalDeath = FormElement(
- id = 27, inputType = InputType.RADIO, title = "Maternal Death",
+ id = 27, inputType = InputType.RADIO,
+ title = resources.getString(R.string.maternal_death),
arrayId = R.array.anc_confirmation_array1,
entries = resources.getStringArray(R.array.anc_confirmation_array1),
required = false, hasDependants = true
@@ -267,35 +364,65 @@ class PregnantWomanAncVisitDataset(
private val maternalDeathProbableCause = FormElement(
id = 28,
inputType = InputType.DROPDOWN,
- title = "Probable Cause of Death",
+ title = resources.getString(R.string.probable_cause_of_death),
arrayId = R.array.anc_death_cause_array,
entries = resources.getStringArray(R.array.anc_death_cause_array),
required = true,
- hasDependants = true
+ hasDependants = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val otherMaternalDeathProbableCause = FormElement(
id = 29,
inputType = InputType.EDIT_TEXT,
- title = "Other Death Cause",
+ title = resources.getString(R.string.other_death_cause),
required = true,
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val maternalDateOfDeath = FormElement(
id = 30,
inputType = InputType.DATE_PICKER,
- title = "Death Date",
+ title = resources.getString(R.string.death_date),
required = true,
max = System.currentTimeMillis(),
+ showDrawable = true,
+ backgroundDrawable = R.drawable.ic_bg_circular,
+ iconDrawableRes = R.drawable.ic_bmi,
)
private val deliveryDone = FormElement(
id = 31,
inputType = InputType.RADIO,
- title = "Has the pregnant woman delivered?",
+ title = resources.getString(R.string.has_pw_delivered),
arrayId = R.array.anc_confirmation_array,
entries = resources.getStringArray(R.array.anc_confirmation_array),
required = false,
)
+ private val headLine = FormElement(
+ id = 34,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.mcp_cards),
+ headingLine = false,
+ required = false,
+ )
+ private val fileUploadFront = FormElement(
+ id = 31,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.front_side),
+ required = false,
+ )
+
+ private val fileUploadBack = FormElement(
+ id = 32,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.back_side),
+ required = false,
+ )
+
private var toggleBp = false
fun resetBpToggle() {
@@ -304,27 +431,31 @@ class PregnantWomanAncVisitDataset(
fun triggerBpToggle() = toggleBp
-
+ fun getIndexOfMCPCardFrontPath() = getIndexById(fileUploadFront.id)
+ fun getIndexOfMCPCardBackPath() = getIndexById(fileUploadBack.id)
suspend fun setUpPage(
visitNumber: Int,
ben: BenRegCache?,
regis: PregnantWomanRegistrationCache,
lastAnc: PregnantWomanAncCache?,
- saved: PregnantWomanAncCache?
+ isFromPmsma: Boolean,
+ saved: PregnantWomanAncCache?,
) {
this.regis = regis
val list = mutableListOf(
ancDate,
+ placeOfAnc,
weekOfPregnancy,
ancVisit,
- isAborted,
+// isAborted,
+ maternalDeath,
weight,
bp,
- pulseRate,
+// pulseRate,
hb,
- fundalHeight,
- urineAlbumin,
- randomBloodSugarTest,
+// fundalHeight,
+// urineAlbumin,
+// randomBloodSugarTest,
dateOfTTOrTd1,
dateOfTTOrTd2,
dateOfTTOrTdBooster,
@@ -333,9 +464,33 @@ class PregnantWomanAncVisitDataset(
anyHighRisk,
highRiskReferralFacility,
hrpConfirm,
- maternalDeath
+ headLine,
+ fileUploadFront,
+ fileUploadBack,
+
+ )
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.remove(fileUploadFront)
+ list.remove(fileUploadBack)
+ list.remove(headLine)
+ }
+ if (BuildConfig.FLAVOR.contains("xushrukha", ignoreCase = true)) {
+ bp.required=true
+ hb.required=true
+ }
+ else{
+ bp.required=false
+ hb.required=false
+ }
+
+ if (isFromPmsma) {
+ placeOfAnc.value = placeOfAnc.entries?.get(3)
+ placeOfAnc.inputType = InputType.TEXT_VIEW
+ placeOfAnc.required = true
+ placeOfAnc.isEnabled=false
+ }
- )
abortionDate.min = regis.lmpDate + TimeUnit.DAYS.toMillis(5 * 7 + 1)
dateOfTTOrTd1.min = abortionDate.min
dateOfTTOrTdBooster.min = abortionDate.min
@@ -344,29 +499,37 @@ class PregnantWomanAncVisitDataset(
dateOfTTOrTd1.max = abortionDate.max
dateOfTTOrTd2.max = abortionDate.max
dateOfTTOrTdBooster.max = abortionDate.max
-
if (lastAnc == null)
list.remove(dateOfTTOrTd2)
setUpTdX()
ben?.let {
ancDate.min =
- regis.lmpDate + TimeUnit.DAYS.toMillis(7 * Konstants.minAnc1Week.toLong() + 1)
- ancVisit.entries = arrayOf("1", "2", "3", "4")
+ regis.lmpDate + TimeUnit.DAYS.toMillis(7 * Konstants.minAnc1Week.toLong())
+ ancVisit.entries = arrayOf("1", "2", "3", "4", "5", "6", "7", "8","9")
lastAnc?.let { last ->
ancDate.min = last.ancDate + TimeUnit.DAYS.toMillis(4 * 7)
- ancVisit.entries = arrayOf(2, 3, 4).filter {
+ ancVisit.entries = arrayOf(2, 3, 4, 5, 6, 7, 8,9).filter {
it > last.visitNumber
}.map { it.toString() }.toTypedArray()
lastAncVisitDate = last.ancDate
}
+// ancDate.max =
+// minOf(getEddFromLmp(regis.lmpDate), System.currentTimeMillis())
+
+ /*This change is done to test working as per Madhava*/
ancDate.max =
- minOf(getEddFromLmp(regis.lmpDate), System.currentTimeMillis())
- ancDate.value = getDateFromLong(ancDate.max!!)
+ minOf(getANCMaxFromLmp(regis.lmpDate), System.currentTimeMillis())
+
+// ancDate.value = getDateFromLong(ancDate.max!!)
maternalDateOfDeath.min =
maxOf(regis.lmpDate, lastAncVisitDate) + TimeUnit.DAYS.toMillis(1)
maternalDateOfDeath.max =
minOf(getEddFromLmp(regis.lmpDate), System.currentTimeMillis())
+
+ isAborted.value = resources.getStringArray(R.array.yes_no)[1]
+ maternalDeath.value = resources.getStringArray(R.array.yes_no)[1]
+
}
// ancDate.value = getDateFromLong(System.currentTimeMillis())
@@ -375,7 +538,8 @@ class PregnantWomanAncVisitDataset(
val long = getLongFromDate(it)
val weeks = getWeeksOfPregnancy(long, regis.lmpDate)
if (weeks >= Konstants.minWeekToShowDelivered) {
- list.add(deliveryDone)
+ list.add(list.indexOf(maternalDeath) + 1,deliveryDone)
+
}
if (weeks <= 12) {
list.remove(fundalHeight)
@@ -390,7 +554,7 @@ class PregnantWomanAncVisitDataset(
ancVisit.value = visitNumber.toString()
saved?.let { savedAnc ->
-
+ placeOfAnc.value = getLocalValueInArray(placeOfAnc.arrayId, savedAnc.placeOfAnc)
val woP = getWeeksOfPregnancy(savedAnc.ancDate, regis.lmpDate)
if (woP <= 12) {
list.remove(fundalHeight)
@@ -399,10 +563,12 @@ class PregnantWomanAncVisitDataset(
list.remove(numFolicAcidTabGiven)
}
if (woP >= Konstants.minWeekToShowDelivered) {
- if (!list.contains(deliveryDone)) list.add(deliveryDone)
+ if (!list.contains(deliveryDone)) list.add(list.indexOf(maternalDeath) + 1,deliveryDone)
}
ancDate.value = getDateFromLong(savedAnc.ancDate)
weekOfPregnancy.value = woP.toString()
+ fileUploadFront.value = savedAnc.frontFilePath
+ fileUploadBack.value = savedAnc.backFilePath
isAborted.value =
if (savedAnc.isAborted) isAborted.entries!!.last() else isAborted.entries!!.first()
if (savedAnc.isAborted) {
@@ -455,8 +621,7 @@ class PregnantWomanAncVisitDataset(
list.add(list.indexOf(hrpConfirm) + 1, hrpConfirmedBy)
}
savedAnc.maternalDeath?.let {
- maternalDeath.value =
- if (it) maternalDeath.entries!!.last() else maternalDeath.entries!!.first()
+ maternalDeath.value = if (it) maternalDeath.entries!!.last() else maternalDeath.entries!!.first()
if (it) {
maternalDeathProbableCause.value =
getLocalValueInArray(
@@ -469,6 +634,11 @@ class PregnantWomanAncVisitDataset(
list.indexOf(maternalDeath) + 1,
listOf(maternalDeathProbableCause, maternalDateOfDeath)
)
+ placeOfDeath.entries?.indexOf(savedAnc.placeOfDeath)?.takeIf { it >= 0 }?.let { index ->
+ if (index == 8) {
+ list.add(list.indexOf(placeOfDeath) + 1, otherPlaceOfDeath)
+ }
+ }
otherMaternalDeathProbableCause.value =
savedAnc.otherMaternalDeathProbableCause
if (maternalDeathProbableCause.value == maternalDeathProbableCause.entries!!.last()) list.add(
@@ -526,6 +696,21 @@ class PregnantWomanAncVisitDataset(
removeItems = listOf(deliveryDone),
)
}
+
+ if (weeks > 24) {
+ triggerDependants(
+ source = ancVisit,
+ removeItems = listOf(isAborted,abortionDate,abortionType,abortionFacility),
+ addItems = emptyList()
+ )
+ } else {
+ triggerDependants(
+ source = ancVisit,
+ addItems = listOf(isAborted),
+ removeItems = emptyList()
+ )
+ }
+
weekOfPregnancy.value = weeks.toString()
val calcVisitNumber = when (weeks) {
in Konstants.minAnc1Week..Konstants.maxAnc1Week -> 1
@@ -534,16 +719,19 @@ class PregnantWomanAncVisitDataset(
in Konstants.minAnc4Week..Konstants.maxAnc4Week -> 4
else -> 0
}
- if (ancVisit.entries?.contains(calcVisitNumber.toString()) == true) {
+ if (isAborted.value == isAborted.entries!!.first() &&
+ maternalDeath.value == maternalDeath.entries!!.first()
+ ) {
ancVisit.value = calcVisitNumber.toString()
- val listChanged2 = if (weeks <= 12)
+
+ val listChanged2 = if (weeks <= 12) {
triggerDependants(
source = ancVisit,
addItems = listOf(numFolicAcidTabGiven),
removeItems = listOf(fundalHeight, numIfaAcidTabGiven),
position = getIndexById(dateOfTTOrTdBooster.id) + 1
)
- else {
+ } else {
triggerDependants(
source = ancVisit,
removeItems = listOf(numFolicAcidTabGiven),
@@ -556,14 +744,15 @@ class PregnantWomanAncVisitDataset(
addItems = listOf(numIfaAcidTabGiven),
position = getIndexById(dateOfTTOrTdBooster.id) + 1
)
-
}
+
return if (listChanged >= 0 || listChanged2 >= 0)
1
else
-1
}
return listChanged
+
}
-1
}
@@ -593,20 +782,64 @@ class PregnantWomanAncVisitDataset(
}
}
- isAborted.id -> triggerDependants(
- source = isAborted,
- passedIndex = index,
- triggerIndex = 1,
- target = listOf(abortionType, abortionDate),
- targetSideEffect = listOf(abortionFacility)
- )
+ isAborted.id -> {
+ val commonAddItems = listOf(
+ weight,
+ bp,
+// pulseRate,
+ hb,
+// fundalHeight,
+// urineAlbumin,
+// randomBloodSugarTest,
+ dateOfTTOrTd1,
+ dateOfTTOrTd2,
+ dateOfTTOrTdBooster,
+ numFolicAcidTabGiven,
+ numIfaAcidTabGiven,
+ anyHighRisk,
+ highRiskReferralFacility,
+ hrpConfirm
+ )
+
+ val isAbortedYes = isAborted.value == isAborted.entries!!.last()
+ val isMaternalDeathYes = maternalDeath.value == maternalDeath.entries!!.last()
+ val abortionFields = listOf(abortionType, abortionFacility, abortionDate)
+
+ if (isAbortedYes) {
+ triggerDependants(
+ source = maternalDeath,
+ addItems = abortionFields,
+ removeItems = commonAddItems + deliveryDone,
+ position = getIndexById(isAborted.id).coerceAtLeast(0) + 1 // safe
+ )
+ } else if (isMaternalDeathYes) {
+ triggerDependants(
+ source = maternalDeath,
+ addItems = emptyList(),
+ removeItems = abortionFields + commonAddItems + deliveryDone,
+ position = -1
+ )
+ } else {
+ val week = weekOfPregnancy.value?.toIntOrNull()
+
+ val addItems = if (week != null && week >= Konstants.minWeekToShowDelivered) {
+ listOf(deliveryDone) + commonAddItems
+ } else {
+ commonAddItems
+ }
+
+ val removeItems = abortionFields +
+ if (week == null || week < Konstants.minWeekToShowDelivered) listOf(deliveryDone) else emptyList()
+
+ triggerDependants(
+ source = maternalDeath,
+ addItems = addItems,
+ removeItems = removeItems,
+ position = -1
+ )
+ }
+ }
- abortionType.id -> triggerDependants(
- source = abortionType,
- passedIndex = index,
- triggerIndex = 0,
- target = abortionFacility,
- )
dateOfTTOrTd1.id -> {
if (dateOfTTOrTd1.value == null)
@@ -630,6 +863,10 @@ class PregnantWomanAncVisitDataset(
weight.id -> validateIntMinMax(weight)
+ fundalHeight.id -> validateIntMinMax(fundalHeight)
+
+ pulseRate.id -> validateIntMinMax(pulseRate)
+
hb.id -> {
validateDoubleUpto1DecimalPlaces(hb)
if (hb.errorText == null) validateDoubleMinMax(hb)
@@ -679,13 +916,81 @@ class PregnantWomanAncVisitDataset(
target = hrpConfirmedBy,
)
- maternalDeath.id -> triggerDependants(
- source = maternalDeath,
- passedIndex = index,
- triggerIndex = 1,
- target = listOf(maternalDeathProbableCause, maternalDateOfDeath),
- targetSideEffect = listOf(otherMaternalDeathProbableCause)
- )
+ placeOfDeath.id -> {
+ val index = placeOfDeath.entries?.indexOf(placeOfDeath.value).takeIf { it!! >= 0 }
+ ?: return -1
+ val triggerIndex = 8
+ return triggerDependants(
+ source = placeOfDeath,
+ passedIndex = index,
+ triggerIndex = triggerIndex,
+ target = otherPlaceOfDeath
+ )
+ }
+
+ maternalDeath.id -> {
+ val commonAddItems = listOf(
+ weight,
+ bp,
+// pulseRate,
+ hb,
+// fundalHeight,
+// urineAlbumin,
+// randomBloodSugarTest,
+ dateOfTTOrTd1,
+ dateOfTTOrTd2,
+ dateOfTTOrTdBooster,
+ numFolicAcidTabGiven,
+ numIfaAcidTabGiven,
+ anyHighRisk,
+ highRiskReferralFacility,
+ hrpConfirm
+ )
+
+ val maternalDeathFields = listOf(
+ maternalDeathProbableCause,
+ maternalDateOfDeath,
+ placeOfDeath
+ )
+
+ val week = weekOfPregnancy.value?.toIntOrNull()
+
+ val isMaternalDeathYes = maternalDeath.value == maternalDeath.entries!!.last()
+ val isAbortedYes = isAborted.value == isAborted.entries!!.last()
+
+ if (isMaternalDeathYes) {
+ triggerDependants(
+ source = maternalDeath,
+ addItems = maternalDeathFields,
+ removeItems = commonAddItems + deliveryDone,
+ position = getIndexById(maternalDeath.id).coerceAtLeast(0) + 1
+ )
+ } else if (isAbortedYes) {
+ triggerDependants(
+ source = maternalDeath,
+ addItems = emptyList(),
+ removeItems = maternalDeathFields + commonAddItems + deliveryDone,
+ position = -1
+ )
+ } else {
+ val addItems = if (week != null && week >= Konstants.minWeekToShowDelivered) {
+ listOf(deliveryDone) + commonAddItems // deliveryDone first
+ } else {
+ commonAddItems
+ }
+
+ val removeItems = maternalDeathFields +
+ if (week == null || week < Konstants.minWeekToShowDelivered) listOf(deliveryDone) else emptyList()
+
+ triggerDependants(
+ source = maternalDeath,
+ addItems = addItems,
+ removeItems = removeItems,
+ position = -1
+ )
+ }
+ }
+
maternalDeathProbableCause.id -> triggerDependants(
source = maternalDeathProbableCause,
@@ -711,12 +1016,21 @@ class PregnantWomanAncVisitDataset(
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as PregnantWomanAncCache).let { cache ->
+ cache.placeOfDeath = getEnglishValueInArray(placeOfDeath.arrayId, placeOfDeath.value)
+ cache.placeOfDeathId = placeOfDeath.entries?.indexOf(placeOfDeath.value ?: "")
+ ?.takeIf { it != -1 }
+
+ cache.placeOfAnc = getEnglishValueInArray(placeOfAnc.arrayId, placeOfAnc.value)
+ cache.placeOfAncId = placeOfAnc.entries?.indexOf(placeOfAnc.value ?: "")
+ ?.takeIf { it != -1 }
+ cache.otherPlaceOfDeath = otherPlaceOfDeath.value
+ cache.lmpDate = regis.lmpDate
cache.visitNumber = ancVisit.value!!.toInt()
cache.ancDate = getLongFromDate(ancDate.value)
cache.isAborted = isAborted.value == isAborted.entries!!.last()
- cache.abortionType = abortionType.value
+ cache.abortionType = getEnglishValueInArray(abortionType.arrayId, abortionType.value)
cache.abortionTypeId = abortionType.getPosition()
- cache.abortionFacility = abortionFacility.value
+ cache.abortionFacility = getEnglishValueInArray(abortionFacility.arrayId, abortionFacility.value)
cache.abortionFacilityId = abortionFacility.getPosition()
cache.abortionDate = abortionDate.value?.let { getLongFromDate(it) }
cache.weight = weight.value?.toInt()
@@ -725,9 +1039,9 @@ class PregnantWomanAncVisitDataset(
cache.pulseRate = pulseRate.value?.takeIf { it.isNotEmpty() }
cache.hb = hb.value?.toDouble()
cache.fundalHeight = fundalHeight.value?.toInt()
- cache.urineAlbumin = urineAlbumin.value
+ cache.urineAlbumin = getEnglishValueInArray(urineAlbumin.arrayId, urineAlbumin.value)
cache.urineAlbuminId = urineAlbumin.getPosition()
- cache.randomBloodSugarTest = randomBloodSugarTest.value
+ cache.randomBloodSugarTest = getEnglishValueInArray(randomBloodSugarTest.arrayId, randomBloodSugarTest.value)
cache.randomBloodSugarTestId = randomBloodSugarTest.getPosition()
updateRegistrationForTdX()
cache.numFolicAcidTabGiven = numFolicAcidTabGiven.value?.toInt() ?: 0
@@ -735,22 +1049,24 @@ class PregnantWomanAncVisitDataset(
anyHighRisk.value?.let {
cache.anyHighRisk = it == anyHighRisk.entries!!.last()
}
- cache.highRisk = highRiskCondition.value
+ cache.highRisk = getEnglishValueInArray(highRiskCondition.arrayId, highRiskCondition.value)
cache.highRiskId = highRiskCondition.getPosition()
cache.otherHighRisk = otherHighRiskCondition.value
- cache.referralFacility = highRiskReferralFacility.value
+ cache.referralFacility = getEnglishValueInArray(highRiskReferralFacility.arrayId, highRiskReferralFacility.value)
cache.referralFacilityId = highRiskReferralFacility.getPosition()
cache.hrpConfirmed = hrpConfirm.value?.let { it == hrpConfirm.entries!!.last() }
- cache.hrpConfirmedBy = hrpConfirmedBy.value
+ cache.hrpConfirmedBy = getEnglishValueInArray(hrpConfirmedBy.arrayId, hrpConfirmedBy.value)
cache.hrpConfirmedById = hrpConfirmedBy.getPosition()
cache.maternalDeath = maternalDeath.value == maternalDeath.entries!!.last()
- cache.maternalDeathProbableCause = maternalDeathProbableCause.value
+ cache.maternalDeathProbableCause = getEnglishValueInArray(maternalDeathProbableCause.arrayId, maternalDeathProbableCause.value)
cache.maternalDeathProbableCauseId = maternalDeathProbableCause.getPosition()
cache.otherMaternalDeathProbableCause = otherMaternalDeathProbableCause.value
cache.deathDate = maternalDateOfDeath.value?.let { getLongFromDate(it) }
deliveryDone.value?.let {
cache.pregnantWomanDelivered = it == deliveryDone.entries!!.first()
}
+ cache.frontFilePath = fileUploadFront.value.toString()
+ cache.backFilePath = fileUploadBack.value.toString()
}
}
@@ -784,7 +1100,7 @@ class PregnantWomanAncVisitDataset(
fun updateBenRecordToDelivered(it: BenRegCache) {
it.genDetails?.apply {
reproductiveStatus =
- englishResources.getStringArray(R.array.nbr_reproductive_status_array)[2]
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[2]
reproductiveStatusId = 3
}
if (it.processed != "N") it.processed = "U"
@@ -794,10 +1110,24 @@ class PregnantWomanAncVisitDataset(
fun updateBenRecordToEligibleCouple(it: BenRegCache) {
it.genDetails?.apply {
reproductiveStatus =
- englishResources.getStringArray(R.array.nbr_reproductive_status_array)[0]
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[0]
reproductiveStatusId = 1
}
if (it.processed != "N") it.processed = "U"
it.syncState = SyncState.UNSYNCED
}
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ if (lastImageFormId == 31) {
+ fileUploadFront.value = dpUri.toString()
+ fileUploadFront.errorText = null
+
+ } else {
+ fileUploadBack.value = dpUri.toString()
+ fileUploadBack.errorText = null
+
+ }
+
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanRegistrationDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanRegistrationDataset.kt
index 23e9f4486..3a072a122 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanRegistrationDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/PregnantWomanRegistrationDataset.kt
@@ -14,6 +14,7 @@ import org.piramalswasthya.sakhi.model.HRPPregnantAssessCache
import org.piramalswasthya.sakhi.model.InputType
import org.piramalswasthya.sakhi.model.PregnantWomanRegistrationCache
import org.piramalswasthya.sakhi.utils.HelperUtil.getDiffYears
+import org.piramalswasthya.sakhi.utils.Log
import java.util.Calendar
import java.util.concurrent.TimeUnit
@@ -22,11 +23,16 @@ class PregnantWomanRegistrationDataset(
) : Dataset(context, currentLanguage) {
companion object {
- private fun getMinLmpMillis(): Long {
+ var registrationDate:Long = 0
+ fun getMinLmpMillis(): Long {
val cal = Calendar.getInstance()
- cal.add(Calendar.DAY_OF_YEAR, -1 * 280)
+ cal.add(Calendar.DAY_OF_YEAR, -1 * 400) //before it is 280
return cal.timeInMillis
}
+ private fun pwRegisterBeforeoneYear(): Long {
+ return registrationDate-TimeUnit.DAYS.toMillis(365)
+
+ }
}
private val dateOfReg = FormElement(
@@ -35,6 +41,9 @@ class PregnantWomanRegistrationDataset(
title = resources.getString(R.string.nbr_dor),
arrayId = -1,
required = true,
+ min = Calendar.getInstance().apply {
+ add(Calendar.YEAR, -1)
+ }.timeInMillis,
max = System.currentTimeMillis(),
hasDependants = true
@@ -49,7 +58,7 @@ class PregnantWomanRegistrationDataset(
isMobileNumber = true,
etMaxLength = 12
)
- private val mcpCardNumber = FormElement(
+/* private val mcpCardNumber = FormElement(
id = 3,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.pwrdst_mcp_card_no),
@@ -57,7 +66,7 @@ class PregnantWomanRegistrationDataset(
etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
isMobileNumber = true,
etMaxLength = 12
- )
+ )*/
private val name = FormElement(
id = 4,
inputType = InputType.TEXT_VIEW,
@@ -99,7 +108,8 @@ class PregnantWomanRegistrationDataset(
required = true,
max = System.currentTimeMillis(),
min = getMinLmpMillis(),
- hasDependants = true
+ hasDependants = true,
+ isEnabled = false,
)
private val weekOfPregnancy = FormElement(
id = 8,
@@ -144,7 +154,8 @@ class PregnantWomanRegistrationDataset(
min = 50,
max = 200
)
- private val vdrlrprTestResult = FormElement(
+
+ /* private val vdrlrprTestResult = FormElement(
id = 13,
inputType = InputType.DROPDOWN,
title = resources.getString(R.string.pwrdst_vdrl_rpr_tst_rlts),
@@ -160,6 +171,7 @@ class PregnantWomanRegistrationDataset(
title = resources.getString(R.string.pwrdst_vdrl_tst_done),
arrayId = -1,
required = false,
+ min= pwRegisterBeforeoneYear(),
max = System.currentTimeMillis(),
)
private val hivTestResult = FormElement(
@@ -198,7 +210,7 @@ class PregnantWomanRegistrationDataset(
required = false,
max = System.currentTimeMillis(),
)
-
+*/
private val pastIllness = FormElement(
id = 19,
inputType = InputType.CHECKBOXES,
@@ -206,7 +218,7 @@ class PregnantWomanRegistrationDataset(
arrayId = R.array.maternal_health_past_illness,
entries = resources.getStringArray(R.array.maternal_health_past_illness),
required = true,
- value = resources.getStringArray(R.array.maternal_health_past_illness).first(),
+ value = "0",
hasDependants = true
)
@@ -403,7 +415,7 @@ class PregnantWomanRegistrationDataset(
val list = mutableListOf(
dateOfReg,
rchId,
- mcpCardNumber,
+ // mcpCardNumber,
name,
husbandName,
age,
@@ -413,11 +425,11 @@ class PregnantWomanRegistrationDataset(
bloodGroup,
weight,
height,
- vdrlrprTestResult,
+// vdrlrprTestResult,
// dateOfVdrlTestDone,
- hivTestResult,
+// hivTestResult,
// dateOfhivTestDone,
- hbsAgTestResult,
+// hbsAgTestResult,
// dateOfhbsAgTestDone,
pastIllness,
isFirstPregnancy,
@@ -435,20 +447,22 @@ class PregnantWomanRegistrationDataset(
multiplePregnancy,
isHrpCase
)
- dateOfReg.value = getDateFromLong(System.currentTimeMillis())
+
+ // dateOfReg.value = getDateFromLong(System.currentTimeMillis())
dateOfReg.value?.let {
val long = getLongFromDate(it)
- dateOfhivTestDone.min = long
- dateOfVdrlTestDone.min = long
- dateOfhbsAgTestDone.min = long
+// dateOfhivTestDone.min = long - TimeUnit.DAYS.toMillis(365)
+// dateOfVdrlTestDone.min = long - TimeUnit.DAYS.toMillis(365)
+// dateOfhbsAgTestDone.min = long - TimeUnit.DAYS.toMillis(365)
}
+
ben?.let {
- dateOfReg.min = it.regDate.also {
- dateOfVdrlTestDone.min = it
- dateOfhivTestDone.min = it
+ /* dateOfReg.min = it.regDate.also {
+ dateOfVdrlTestDone.min = it - TimeUnit.DAYS.toMillis(365)
+ dateOfhivTestDone.min = it - TimeUnit.DAYS.toMillis(365)
hbsAgTestResult.min = it
- }
+ }*/
rchId.value = ben.rchId
name.value = "${ben.firstName} ${if (ben.lastName == null) "" else ben.lastName}"
husbandName.value = ben.genDetails?.spouseName
@@ -468,9 +482,9 @@ class PregnantWomanRegistrationDataset(
)[1]
}
- lastTrackTimestamp?.let {
+ /* lastTrackTimestamp?.let {
dateOfReg.min = it
- }
+ }*/
// fetching high risk assess cache details and assigning them
assess?.let {
noOfDeliveries.value = getLocalValueInArray(R.array.yes_no, it.noOfDeliveries)
@@ -494,7 +508,7 @@ class PregnantWomanRegistrationDataset(
multiplePregnancy.value = getLocalValueInArray(R.array.yes_no, it.multiplePregnancy)
// if there is valid lmp date auto populating edd and weeks of pregnancy
- lmp.value = getDateFromLong(it.lmpDate)
+// lmp.value = getDateFromLong(it.lmpDate)
if (it.lmpDate > 0) {
val weekOfPreg =
@@ -502,20 +516,20 @@ class PregnantWomanRegistrationDataset(
saved?.dateOfRegistration ?: Calendar.getInstance().timeInMillis,
it.lmpDate
)
- weekOfPregnancy.value =
- weekOfPreg.toString()
+ /* weekOfPregnancy.value =
+ weekOfPreg.toString()*/
// if (weekOfPreg > 26)
- lmp.inputType = InputType.TEXT_VIEW
- edd.value = getDateFromLong(getEddFromLmp(it.lmpDate))
- ben?.regDate?.let { it1 ->
- if (lastTrackTimestamp != null) {
- dateOfReg.min = maxOf(it.lmpDate, it1, lastTrackTimestamp)
- } else {
- dateOfReg.min = maxOf(it.lmpDate, it1)
- }
- }
- dateOfReg.max = minOf(it.edd, System.currentTimeMillis())
-
+// lmp.inputType = InputType.TEXT_VIEW
+// edd.value = getDateFromLong(getEddFromLmp(it.lmpDate))
+ /* ben?.regDate?.let { it1 ->
+ if (lastTrackTimestamp != null) {
+ dateOfReg.min = maxOf(it.lmpDate, it1, lastTrackTimestamp)
+ } else {
+ dateOfReg.min = maxOf(it.lmpDate, it1)
+ }
+ }
+ dateOfReg.max = minOf(it.edd, System.currentTimeMillis())
+ */
}
childInfoLabel.showHighRisk = (
@@ -545,22 +559,25 @@ class PregnantWomanRegistrationDataset(
dateOfReg.apply {
value = getDateFromLong(it.dateOfRegistration)
inputType = InputType.TEXT_VIEW
+
}
+
it.dateOfRegistration.let {
lmp.max = it
- lmp.min = it - TimeUnit.DAYS.toMillis(280)
- dateOfVdrlTestDone.min = it
- dateOfhivTestDone.min = it
- dateOfhbsAgTestDone.min = it
+ lmp.min = it - TimeUnit.DAYS.toMillis(400)
+ /* dateOfVdrlTestDone.min = it - TimeUnit.DAYS.toMillis(365)
+ dateOfhivTestDone.min = it - TimeUnit.DAYS.toMillis(365)
+ dateOfhbsAgTestDone.min = it - TimeUnit.DAYS.toMillis(365)
+*/
}
val eddFromLmp = getEddFromLmp(it.lmpDate)
minOf(System.currentTimeMillis(), eddFromLmp).let { maxDate ->
- dateOfVdrlTestDone.max = maxDate
+ /* dateOfVdrlTestDone.max = maxDate
dateOfhivTestDone.max = maxDate
- dateOfhbsAgTestDone.max = maxDate
+ dateOfhbsAgTestDone.max = maxDate*/
}
- mcpCardNumber.value = it.mcpCardNumber.toString()
+ // mcpCardNumber.value = it.mcpCardNumber.toString()
lmp.value = getDateFromLong(it.lmpDate)
if (it.lmpDate > 0) {
lmp.isEnabled = false
@@ -574,7 +591,7 @@ class PregnantWomanRegistrationDataset(
bloodGroup.value = getLocalValueInArray(bloodGroup.arrayId, saved.bloodGroup)
weight.value = it.weight?.toString()
height.value = it.height?.toString()
- vdrlrprTestResult.value =
+ /* vdrlrprTestResult.value =
getLocalValueInArray(vdrlrprTestResult.arrayId, saved.vdrlRprTestResult)
it.vdrlRprTestResult?.let { it1 ->
if (it1 == vdrlrprTestResult.entries?.get(0) || it1 == vdrlrprTestResult.entries?.get(
@@ -601,10 +618,12 @@ class PregnantWomanRegistrationDataset(
}
hivTestResult.value = getLocalValueInArray(hivTestResult.arrayId, saved.hivTestResult)
hbsAgTestResult.value =
- getLocalValueInArray(hbsAgTestResult.arrayId, saved.hbsAgTestResult)
- pastIllness.value = getLocalValueInArray(pastIllness.arrayId, saved.pastIllness)
+ getLocalValueInArray(hbsAgTestResult.arrayId, saved.hbsAgTestResult)*/
+ pastIllness.value = getCheckboxIndexesFromValues(pastIllness.arrayId, saved.pastIllness) ?: "0"
otherPastIllness.value = it.otherPastIllness
- if (pastIllness.value == pastIllness.entries!!.last())
+ val otherIndex = pastIllness.entries!!.size - 1
+ val selectedIndexes = pastIllness.value?.split("|")?.mapNotNull { it.trim().toIntOrNull() } ?: emptyList()
+ if (selectedIndexes.contains(otherIndex))
list.add(list.indexOf(pastIllness) + 1, otherPastIllness)
isFirstPregnancy.value = isFirstPregnancy.getStringFromPosition(if (it.is1st) 1 else 2)
if (isFirstPregnancy.value == isFirstPregnancy.entries!!.last()) {
@@ -635,11 +654,11 @@ class PregnantWomanRegistrationDataset(
} ?: run {
assess?.let {
// if there is no lmp date from pwr saved form or hrp assessment form then disabling these fields
- if (it.lmpDate <= 0L) {
+ /* if (it.lmpDate <= 0L) {
vdrlrprTestResult.inputType = InputType.TEXT_VIEW
hivTestResult.inputType = InputType.TEXT_VIEW
hbsAgTestResult.inputType = InputType.TEXT_VIEW
- }
+ }*/
}
}
@@ -672,32 +691,50 @@ class PregnantWomanRegistrationDataset(
// list.add(assignedAsHrpBy)
// }
// }
+
+
+ noOfDeliveries.isEnabled=false
+ timeLessThan18m.isEnabled=false
setUpPage(list)
}
fun getIndexOfEdd() = getIndexById(edd.id)
+ fun getIndexOfLmp() = getIndexById(lmp.id)
fun getIndexOfWeeksPregnancy() = getIndexById(weekOfPregnancy.id)
fun getIndexOfPastIllness() = getIndexById(pastIllness.id)
- fun getIndexOfVdrlTestResult() = getIndexById(vdrlrprTestResult.id)
+// fun getIndexOfVdrlTestResult() = getIndexById(vdrlrprTestResult.id)
override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
return when (formId) {
rchId.id -> validateRchIdOnEditText(rchId)
- mcpCardNumber.id -> validateMcpOnEditText(mcpCardNumber)
+ // mcpCardNumber.id -> validateMcpOnEditText(mcpCardNumber)
dateOfReg.id -> {
- dateOfReg.value?.let {
- val dateOfRegLong = getLongFromDate(it)
+ val dateStr = dateOfReg.value
+
+ if (dateOfReg.value != null) {
+ Log.e("DATKHJH","Coming")
+ triggerDependants(
+ source = age,
+ passedIndex = index,
+ triggerIndex = index,
+ target = listOf(lmp)
+ )
+ val dateOfRegLong = getLongFromDate(dateStr)
+
+ lmp.isEnabled = true
lmp.max = dateOfRegLong
lmp.min = getMinFromMaxForLmp(lmp.max!!)
- dateOfVdrlTestDone.min = dateOfRegLong
- dateOfhivTestDone.min = dateOfRegLong
- dateOfhbsAgTestDone.min = dateOfRegLong
+
updateAgeCheck(dateOfBirth, dateOfRegLong)
+
+
+
return handleListOnValueChanged(isHrpCase.id, 0)
}
+
-1
}
@@ -712,7 +749,7 @@ class PregnantWomanRegistrationDataset(
weekOfPregnancy.value = bracket.toString()
}
}
- vdrlrprTestResult.let {
+ /* vdrlrprTestResult.let {
if (it.inputType != InputType.DROPDOWN) it.inputType = InputType.DROPDOWN
}
hivTestResult.let {
@@ -720,18 +757,18 @@ class PregnantWomanRegistrationDataset(
}
hbsAgTestResult.let {
if (it.inputType != InputType.DROPDOWN) it.inputType = InputType.DROPDOWN
- }
+ }*/
edd.value = eddLong?.let { getDateFromLong(it) }
regLong?.let {
- dateOfhivTestDone.min = it
- dateOfVdrlTestDone.min = it
- dateOfhbsAgTestDone.min = it
+ /* dateOfhivTestDone.min = it - TimeUnit.DAYS.toMillis(365)
+ dateOfVdrlTestDone.min = it - TimeUnit.DAYS.toMillis(365)
+ dateOfhbsAgTestDone.min = it - TimeUnit.DAYS.toMillis(365)*/
}
eddLong?.let {
val max = minOf(it, System.currentTimeMillis())
- dateOfVdrlTestDone.max = max
+ /* dateOfVdrlTestDone.max = max
dateOfhivTestDone.max = max
- dateOfhbsAgTestDone.max = max
+ dateOfhbsAgTestDone.max = max*/
}
-1
}
@@ -754,7 +791,7 @@ class PregnantWomanRegistrationDataset(
-1
}
- vdrlrprTestResult.id -> {
+ /* vdrlrprTestResult.id -> {
triggerDependantsReverse(
source = vdrlrprTestResult,
passedIndex = index,
@@ -779,29 +816,44 @@ class PregnantWomanRegistrationDataset(
triggerIndex = 2,
target = listOf(dateOfhbsAgTestDone)
)
- }
+ }*/
pastIllness.id -> {
val entries = pastIllness.entries!!
- pastIllness.value?.takeIf { it.isNotEmpty() }?.let {
- if (index == 0) pastIllness.value = pastIllness.entries!!.first()
- else pastIllness.value = it.replace(entries.first(), "")
- } ?: run {
- pastIllness.value = pastIllness.entries!!.first()
+ val noneIndex = 0
+ val otherIndex = entries.size - 1
+ val selectedIndexes = pastIllness.value
+ ?.split("|")
+ ?.mapNotNull { it.trim().toIntOrNull() }
+ ?.toMutableSet()
+ ?: mutableSetOf()
+
+ if (index == noneIndex) {
+ // "None" selected: clear all others, keep only None
+ pastIllness.value = "0"
+ } else {
+ // Other option selected: remove None
+ selectedIndexes.remove(noneIndex)
+ pastIllness.value =
+ if (selectedIndexes.isEmpty()) "0"
+ else selectedIndexes.sorted().joinToString("|")
}
- if (pastIllness.value?.contains(entries.last()) == true) {
+
+ if (selectedIndexes.contains(otherIndex)) {
triggerDependants(
source = pastIllness,
passedIndex = index,
triggerIndex = index,
target = otherPastIllness
)
- } else triggerDependants(
- source = pastIllness,
- passedIndex = index,
- triggerIndex = -230,
- target = otherPastIllness
- )
+ } else {
+ triggerDependants(
+ source = pastIllness,
+ passedIndex = index,
+ triggerIndex = -230,
+ target = otherPastIllness
+ )
+ }
}
otherPastIllness.id -> {
@@ -929,7 +981,7 @@ class PregnantWomanRegistrationDataset(
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as PregnantWomanRegistrationCache).let { form ->
form.dateOfRegistration = getLongFromDate(dateOfReg.value)
- form.mcpCardNumber = mcpCardNumber.value?.takeIf { it.isNotEmpty() }?.toLong() ?: 0
+ // form.mcpCardNumber = mcpCardNumber.value?.takeIf { it.isNotEmpty() }?.toLong() ?: 0
form.rchId = rchId.value?.takeIf { it.isNotEmpty() }?.toLong() ?: 0
form.lmpDate = getLongFromDate(lmp.value)
form.bloodGroup =
@@ -937,7 +989,7 @@ class PregnantWomanRegistrationDataset(
form.bloodGroupId = bloodGroup.getPosition()
form.weight = weight.value?.toInt()
form.height = height.value?.toInt()
- form.vdrlRprTestResult =
+ /* form.vdrlRprTestResult =
getEnglishValueInArray(R.array.maternal_health_test_result, vdrlrprTestResult.value)
form.vdrlRprTestResultId = vdrlrprTestResult.getPosition()
form.dateOfVdrlRprTest =
@@ -951,9 +1003,9 @@ class PregnantWomanRegistrationDataset(
getEnglishValueInArray(R.array.maternal_health_test_result_2, hbsAgTestResult.value)
form.hbsAgTestResultId = hbsAgTestResult.getPosition()
form.dateOfHbsAgTest =
- dateOfhbsAgTestDone.value?.let { getLongFromDate(dateOfhbsAgTestDone.value) }
+ dateOfhbsAgTestDone.value?.let { getLongFromDate(dateOfhbsAgTestDone.value) }*/
form.pastIllness =
- getEnglishValueInArray(R.array.maternal_health_past_illness, pastIllness.value)
+ getEnglishCheckboxValues(R.array.maternal_health_past_illness, pastIllness.value)
form.otherPastIllness = otherPastIllness.value
form.is1st = isFirstPregnancy.value == isFirstPregnancy.entries!!.first()
form.numPrevPregnancy = totalNumberOfPreviousPregnancy.value?.toInt()
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/SaasBahuSamelanDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/SaasBahuSamelanDataset.kt
new file mode 100644
index 000000000..6837ccb90
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/SaasBahuSamelanDataset.kt
@@ -0,0 +1,139 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.SaasBahuSammelanCache
+import java.util.Calendar
+import org.piramalswasthya.sakhi.utils.HelperUtil.getDateStringFromLong
+
+
+class SaasBahuSamelanDataset(context: Context, language: Languages) : Dataset(context, language) {
+
+ private fun getTwoMonthsBackDate(): Long {
+ val cal = Calendar.getInstance()
+ cal.add(Calendar.MONTH, -2)
+ return cal.timeInMillis
+ }
+
+ private val dateD = FormElement(
+ id = 1,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.saas_date),
+ required = true,
+ min = getTwoMonthsBackDate(),
+ max = System.currentTimeMillis()
+ )
+
+ private val place = FormElement(
+ id = 2,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place),
+ entries = resources.getStringArray(R.array.place_array),
+ arrayId = R.array.place_array,
+ required = false,
+ hasDependants = false
+ )
+ private val noOfParticipante = FormElement(
+ id = 3,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.no_participent),
+ arrayId = -1,
+ required = true,
+ hasDependants = true,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 3,
+ max = 999,
+ min = 0,
+ )
+
+ val upload1 = FormElement(
+ id = 10,
+ inputType = InputType.FILE_UPLOAD,
+ title = "Sammelan Photos / MoM (1)",
+ required = false,
+ )
+ val upload2 = upload1.copy(id = 11, title = "Sammelan Photos / MoM (2)")
+ val upload3 = upload1.copy(id = 12, title = "Sammelan Photos / MoM (3)")
+ val upload4 = upload1.copy(id = 13, title = "Sammelan Photos / MoM (4)")
+ val upload5 = upload1.copy(id = 14, title = "Sammelan Photos / MoM (5)")
+
+
+ suspend fun setUpPage(
+ saasBahu: SaasBahuSammelanCache?,
+ recordExists: Boolean
+
+ ) {
+ val list = mutableListOf(
+ dateD,
+ place,
+ noOfParticipante,
+ )
+
+ val uploadList = listOf(upload1, upload2, upload3, upload4, upload5)
+
+ if (recordExists) {
+
+ dateD.value = getDateStringFromLong(saasBahu?.date)
+ place.value = getLocalValueInArray(R.array.place_array, saasBahu?.place)
+ noOfParticipante.value = saasBahu?.participants?.toString()
+ val imgs = saasBahu?.sammelanImages ?: emptyList()
+ upload1.value = imgs.getOrNull(0)
+ upload2.value = imgs.getOrNull(1)
+ upload3.value = imgs.getOrNull(2)
+ upload4.value = imgs.getOrNull(3)
+ upload5.value = imgs.getOrNull(4)
+ val filledUploads = uploadList.filter { !it.value.isNullOrEmpty() }
+
+ if (filledUploads.isEmpty()) {
+ list.addAll(uploadList)
+ } else {
+ list.addAll(filledUploads)
+ }
+
+
+ } else {
+ list.addAll(uploadList)
+ }
+
+ setUpPage(list)
+
+ }
+
+ override suspend fun handleListOnValueChanged(
+ formId: Int,
+ index: Int
+ ): Int {
+ return when (formId) {
+ noOfParticipante.id -> {
+ validateAllDigitOnEditText(noOfParticipante)
+ }
+
+ else -> -1
+ }
+
+ }
+
+ override fun mapValues(
+ cacheModel: FormDataModel,
+ pageNumber: Int
+ ) {
+
+ }
+
+ fun mapSaasBahuValues(
+ cacheModel: SaasBahuSammelanCache,
+ ) {
+ cacheModel.place = getEnglishValueInArray(R.array.place_array, place.value)
+ cacheModel.sammelanImages = listOfNotNull(upload1.value, upload2.value, upload3.value, upload4.value, upload5.value)
+ cacheModel.participants = noOfParticipante.value?.toInt()
+
+ cacheModel.date = getLongFromDate(dateD.value.toString())
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/SuspectedTBDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/SuspectedTBDataset.kt
index 112087eba..9adaaa1af 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/SuspectedTBDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/SuspectedTBDataset.kt
@@ -22,9 +22,64 @@ class SuspectedTBDataset(
hasDependants = true
)
+ private val visitLabel = FormElement(
+ id = 2,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.visits),
+ arrayId = -1,
+ required = false,
+ hasDependants = false
+ )
+
+ private val typeOfTBCase = FormElement(
+ id = 3,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.type_of_tb_case),
+ arrayId = R.array.type_of_tb_case,
+ entries = resources.getStringArray(R.array.type_of_tb_case),
+ required = true,
+ hasDependants = true
+ )
+
+ private val reasonForSuspicion = FormElement(
+ id = 4,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.reason_for_suspicion),
+ arrayId = R.array.reason_for_suspicion,
+ entries = resources.getStringArray(R.array.reason_for_suspicion),
+ required = true,
+ hasDependants = true
+ )
+
+ private val hasSymptoms = FormElement(
+ id = 5,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.has_symptoms),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true,
+ hasDependants = true
+ )
+ private val isChestXRayDone = FormElement(
+ id = 6,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.is_chest_xray_done),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true
+ )
+
+ private val chestXRayResult = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.chest_xray_result),
+ arrayId = R.array.chest_xray_result,
+ entries = resources.getStringArray(R.array.chest_xray_result),
+ required = false,
+ hasDependants = false
+ )
private val isSputumCollected = FormElement(
- id = 2,
+ id = 8,
inputType = InputType.RADIO,
title = resources.getString(R.string.is_sputum_sample_collected),
entries = resources.getStringArray(R.array.yes_no),
@@ -32,43 +87,67 @@ class SuspectedTBDataset(
hasDependants = true
)
- private var sputumSubmittedAt = FormElement(
- id = 3,
- inputType = InputType.RADIO,
+
+ private val sputumSubmittedAt = FormElement(
+ id = 9,
+ inputType = InputType.DROPDOWN,
title = resources.getString(R.string.sputum_sample_submitted_at),
- entries = resources.getStringArray(R.array.tb_submitted_yet),
+ arrayId = R.array.tb_sputum_sample_submitted_at,
+ entries = resources.getStringArray(R.array.tb_sputum_sample_submitted_at),
required = false,
hasDependants = false
)
- private var nikshayId = FormElement(
- id = 4,
+
+ private val nikshayId = FormElement(
+ id = 10,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.nikshay_id),
required = false,
hasDependants = false
)
- private var sputumTestResult = FormElement(
- id = 5,
+ private val sputumTestResult = FormElement(
+ id = 11,
inputType = InputType.RADIO,
title = resources.getString(R.string.sputum_test_result),
+ arrayId = R.array.tb_test_result,
entries = resources.getStringArray(R.array.tb_test_result),
required = false,
hasDependants = false
)
- private var referred = FormElement(
- id = 6,
+
+
+ private val referralFacility = FormElement(
+ id = 12,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.referral_facility),
+ arrayId = R.array.referral_facility,
+ entries = resources.getStringArray(R.array.referral_facility),
+ required = true,
+ hasDependants = false
+ )
+
+ private val isTBConfirmed = FormElement(
+ id = 13,
inputType = InputType.RADIO,
- title = resources.getString(R.string.referred_to_facility),
+ title = resources.getString(R.string.is_tb_confirmed),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true,
+ hasDependants = true
+ )
+ private val isDRTBConfirmed = FormElement(
+ id = 14,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.is_drtb_confirmed),
entries = resources.getStringArray(R.array.yes_no),
required = true,
hasDependants = false
)
private var followUps = FormElement(
- id = 7,
+ id = 15,
inputType = InputType.EDIT_TEXT,
title = resources.getString(R.string.facility_referral_follow_ups),
entries = resources.getStringArray(R.array.yes_no),
@@ -77,61 +156,100 @@ class SuspectedTBDataset(
)
suspend fun setUpPage(ben: BenRegCache?, saved: TBSuspectedCache?) {
- var list = mutableListOf(
- dateOfVisit,
- isSputumCollected,
-// sputumSubmittedAt,
-// nikshayId,
-// sputumTestResult,
- referred,
- followUps
- )
+ visitLabel.value = resources.getString(R.string.visit_format, 1)
+ var list = mutableListOf()
+
if (saved == null) {
dateOfVisit.value = getDateFromLong(System.currentTimeMillis())
- } else {
+ typeOfTBCase.value = null
+ hasSymptoms.value = resources.getStringArray(R.array.yes_no)[0]
+
+ list.addAll(listOf(
+ dateOfVisit,
+ visitLabel,
+ typeOfTBCase,
+
+ ))
+
+ if (hasSymptoms.value == resources.getStringArray(R.array.yes_no)[0]) {
+ isSputumCollected.value = resources.getStringArray(R.array.yes_no)[1]
+ list.add(isSputumCollected)
+ } else {
+ isChestXRayDone.value = resources.getStringArray(R.array.yes_no)[1]
+ list.add(isChestXRayDone)
+ }
+
+ list.addAll(listOf(
+ referralFacility,
+ ))
+ }
+ else {
+ dateOfVisit.value = getDateFromLong(saved.visitDate)
+ visitLabel.value = resources.getString(R.string.visit_format, 1)
+ typeOfTBCase.value = getLocalValueInArray(R.array.type_of_tb_case, saved.typeOfTBCase)
+ hasSymptoms.value = saved.hasSymptoms?.let {
+ if (it) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(R.array.yes_no)[1]
+ }
+ isSputumCollected.value = saved.isSputumCollected?.let {
+ if (it) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(R.array.yes_no)[1]
+ }
+
+ list.addAll(listOf(
+ dateOfVisit,
+ visitLabel,
+ typeOfTBCase
+ ))
+
+ if (typeOfTBCase.value in listOf(
+ resources.getStringArray(R.array.type_of_tb_case)[1],
+ resources.getStringArray(R.array.type_of_tb_case)[2]
+ )) {
+ reasonForSuspicion.value = getLocalValueInArray(R.array.reason_for_suspicion, saved.reasonForSuspicion)
+ list.add(reasonForSuspicion)
+ }
+
+ //list.add(hasSymptoms)
+ list.add(isSputumCollected)
+
if (saved.isSputumCollected == true) {
- list = mutableListOf(
- dateOfVisit,
- isSputumCollected,
+ sputumSubmittedAt.value = getLocalValueInArray(R.array.tb_sputum_sample_submitted_at, saved.sputumSubmittedAt)
+ nikshayId.value = saved.nikshayId
+ sputumTestResult.value = getLocalValueInArray(R.array.tb_test_result, saved.sputumTestResult)
+
+ list.addAll(listOf(
sputumSubmittedAt,
nikshayId,
- sputumTestResult,
- referred,
- followUps
- )
- dateOfVisit.value = getDateFromLong(saved.visitDate)
- isSputumCollected.value =
- if (saved.isSputumCollected == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
- R.array.yes_no
- )[1]
- sputumSubmittedAt.value =
- if (saved.sputumSubmittedAt == null) null else resources.getStringArray(R.array.tb_submitted_yet)[englishResources.getStringArray(
- R.array.tb_submitted_yet
- ).indexOf(saved.sputumSubmittedAt)]
- nikshayId.value = saved.nikshayId
- sputumTestResult.value =
- if (saved.sputumTestResult == null) null else resources.getStringArray(R.array.tb_test_result)[englishResources.getStringArray(
- R.array.tb_test_result
- ).indexOf(saved.sputumTestResult)]
- referred.value =
- if (saved.referred == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
- R.array.yes_no
- )[1]
- followUps.value = saved.followUps
- } else {
- dateOfVisit.value = getDateFromLong(saved.visitDate)
- isSputumCollected.value =
- if (saved.isSputumCollected == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
- R.array.yes_no
- )[1]
- referred.value =
- if (saved.referred == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
- R.array.yes_no
- )[1]
- followUps.value = saved.followUps
+ sputumTestResult
+ ))
+ }
+
+
+ referralFacility.value = getLocalValueInArray(R.array.referral_facility, saved.referralFacility)
+
+ if (typeOfTBCase.value == typeOfTBCase.entries!![0]) {
+ isTBConfirmed.value = saved.isTBConfirmed?.let {
+ if (it) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(R.array.yes_no)[1]
+ }
+ list.add(isTBConfirmed)
+ } else if (typeOfTBCase.value in listOf(
+ typeOfTBCase.entries!![1],
+ typeOfTBCase.entries!![2]
+ )) {
+ isDRTBConfirmed.value = saved.isDRTBConfirmed?.let {
+ if (it) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(R.array.yes_no)[1]
+ }
+ list.add(isDRTBConfirmed)
}
+
+ list.addAll(listOf(
+ referralFacility,
+
+ ))
}
+
+
+
ben?.let {
dateOfVisit.min = it.regDate
@@ -142,6 +260,76 @@ class SuspectedTBDataset(
override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
return when (formId) {
+/*
+ typeOfTBCase.id ->{
+ if (typeOfTBCase.value != resources.getStringArray(R.array.type_of_tb_case)[0])
+ {
+ triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(reasonForSuspicion),
+ removeItems = listOf(),
+ )
+ triggerDependants(source = referralFacility,
+ addItems = listOf(isTBConfirmed), removeItems = listOf(), position = -2)
+ }
+ else
+ {
+ triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(),
+ removeItems = listOf(reasonForSuspicion),
+ )
+ triggerDependants(source = referralFacility,
+ addItems = listOf(), removeItems = listOf(isTBConfirmed), position = 12)
+ }
+ }*/
+ typeOfTBCase.id -> {
+ val currentValue = typeOfTBCase.value
+
+ if (currentValue == typeOfTBCase.entries!![0]) {
+ triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(),
+ removeItems = listOf(reasonForSuspicion, isDRTBConfirmed),
+ )
+
+ return triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(isTBConfirmed),
+ removeItems = listOf(),
+ position = -2
+ )
+ } else if (currentValue == typeOfTBCase.entries!![1] || currentValue == typeOfTBCase.entries!![2]) {
+ val result1 = triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(reasonForSuspicion),
+ removeItems = listOf(),
+ )
+
+ triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(isDRTBConfirmed),
+ removeItems = listOf(),
+ position = -2
+ )
+
+ triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(),
+ removeItems = listOf(isTBConfirmed),
+ )
+
+ return result1
+ } else {
+ triggerDependants(
+ source = typeOfTBCase,
+ addItems = listOf(),
+ removeItems = listOf(reasonForSuspicion, isTBConfirmed, isDRTBConfirmed),
+ )
+ return -1
+ }
+ }
+
isSputumCollected.id -> {
triggerDependants(
source = isSputumCollected,
@@ -163,6 +351,8 @@ class SuspectedTBDataset(
)
}
+
+
else -> -1
}
}
@@ -170,19 +360,33 @@ class SuspectedTBDataset(
override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
(cacheModel as TBSuspectedCache).let { form ->
form.visitDate = getLongFromDate(dateOfVisit.value)
- form.isSputumCollected =
- isSputumCollected.value == resources.getStringArray(R.array.yes_no)[0]
- form.sputumSubmittedAt =
- if (sputumSubmittedAt.value == null) null else englishResources.getStringArray(R.array.tb_submitted_yet)[sputumSubmittedAt.entries!!.indexOf(
- sputumSubmittedAt.value
- )]
+ form.visitLabel = visitLabel.value
+ form.typeOfTBCase = getEnglishValueInArray(R.array.type_of_tb_case, typeOfTBCase.value)
+ form.reasonForSuspicion = getEnglishValueInArray(R.array.reason_for_suspicion, reasonForSuspicion.value)
+ form.isChestXRayDone = isChestXRayDone.value?.let {
+ it == isChestXRayDone.entries!![0]
+ }
+ form.chestXRayResult = getEnglishValueInArray(R.array.chest_xray_result, chestXRayResult.value)
+
+ form.isSputumCollected = isSputumCollected.value?.let {
+ it == isSputumCollected.entries!![0]
+ }
+ form.sputumSubmittedAt = getEnglishValueInArray(R.array.tb_sputum_sample_submitted_at, sputumSubmittedAt.value)
form.nikshayId = nikshayId.value
- form.sputumTestResult =
- if (sputumTestResult.value == null) null else englishResources.getStringArray(R.array.tb_test_result)[sputumTestResult.entries!!.indexOf(
- sputumTestResult.value
- )]
- form.referred = referred.value == resources.getStringArray(R.array.yes_no)[0]
- form.followUps = followUps.value
+ form.sputumTestResult = getEnglishValueInArray(R.array.tb_test_result, sputumTestResult.value)
+
+ form.referralFacility = getEnglishValueInArray(R.array.referral_facility, referralFacility.value)
+ form.isTBConfirmed = isTBConfirmed.value?.let {
+ it == isTBConfirmed.entries!![0]
+ }
+ form.isDRTBConfirmed = isDRTBConfirmed.value?.let {
+ it == isDRTBConfirmed.entries!![0]
+ }
+
+
+ if (form.isTBConfirmed == true || form.isDRTBConfirmed == true) {
+ form.isConfirmed = true
+ }
}
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/TBConfirmedDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/TBConfirmedDataset.kt
new file mode 100644
index 000000000..20668637b
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/TBConfirmedDataset.kt
@@ -0,0 +1,652 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.util.Range
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.TBConfirmedTreatmentCache
+import org.piramalswasthya.sakhi.model.TBSuspectedCache
+import java.util.Calendar
+import java.util.Locale
+import kotlinx.coroutines.flow.first
+
+class TBConfirmedDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ private fun getOneYearBeforeCurrentDate(): Long {
+ val calendar = Calendar.getInstance()
+ calendar.add(Calendar.YEAR, -1)
+ calendar.set(Calendar.HOUR_OF_DAY, 0)
+ calendar.set(Calendar.MINUTE, 0)
+ calendar.set(Calendar.SECOND, 0)
+ calendar.set(Calendar.MILLISECOND, 0)
+ return calendar.timeInMillis
+ }
+
+ private var treatmentStartDateLong: Long = 0L
+ private var lastFollowUpDateLong: Long = 0L
+ private var nextFollowUpMonthStart: Long = 0L
+ private var nextFollowUpMonthEnd: Long = 0L
+
+ private val regimenType = FormElement(
+ id = 1,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.regimen_type),
+ arrayId = R.array.tb_regimen_types,
+ entries = resources.getStringArray(R.array.tb_regimen_types),
+ required = true,
+ hasDependants = true,
+ isEnabled = true
+ )
+
+ private val treatmentStartDate = FormElement(
+ id = 2,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.treatment_start_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ hasDependants = true,
+ isEnabled = true
+
+ )
+
+ private val expectedTreatmentCompletionDate = FormElement(
+ id = 3,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.expected_treatment_completion_date),
+ arrayId = -1,
+ required = false,
+ hasDependants = true,
+ isEnabled = true,
+
+ )
+
+ private val followUpDate = FormElement(
+ id = 4,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.follow_up_date),
+ arrayId = -1,
+ required = true,
+ max = System.currentTimeMillis(),
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ hasDependants = true,
+ isEnabled = false
+
+ )
+
+ private val monthlyFollowUpDone = FormElement(
+ id = 5,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.monthly_follow_up_done),
+ arrayId = -1,
+ required = false,
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+ private val adherenceToMedicines = FormElement(
+ id = 6,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.adherence_to_medicines),
+ arrayId = R.array.adherence_options,
+ entries = resources.getStringArray(R.array.adherence_options),
+ required = true,
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+ private val anyDiscomfort = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.any_discomfort),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = true,
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+ private val treatmentCompleted = FormElement(
+ id = 8,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.treatment_completed),
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true,
+ isEnabled = true
+
+ )
+
+ private val actualTreatmentCompletionDate = FormElement(
+ id = 9,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.actual_treatment_completion_date),
+ arrayId = -1,
+ max = System.currentTimeMillis(),
+ required = false,
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+ private val treatmentOutcome = FormElement(
+ id = 10,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.treatment_outcome),
+ arrayId = R.array.tb_treatment_outcomes,
+ entries = resources.getStringArray(R.array.tb_treatment_outcomes),
+ required = false,
+ hasDependants = true,
+ isEnabled = true
+
+ )
+
+ private val dateOfDeath = FormElement(
+ id = 11,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.date_of_death),
+ arrayId = -1,
+ required = false,
+ max = System.currentTimeMillis(),
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+ private val placeOfDeath = FormElement(
+ id = 12,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_death),
+ arrayId = R.array.place_of_death,
+ entries = resources.getStringArray(R.array.place_of_death),
+ required = false,
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+ private val reasonForDeath = FormElement(
+ id = 13,
+ inputType = InputType.TEXT_VIEW,
+ title = resources.getString(R.string.reason_for_death),
+ required = false,
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+ private val reasonForNotCompleting = FormElement(
+ id = 14,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.reason_for_not_completing),
+ required = false,
+ hasDependants = false,
+ isEnabled = true
+
+ )
+
+
+
+ private var lastFollowUpDate: Long? = null
+ private var followUpCount = 0
+ private var treatmentStartDateValue: Long? = null
+ private var regimenTypeValue: String? = null
+ private var isNewRecord = true
+
+ suspend fun setUpPage(
+ ben: BenRegCache?,
+ saved: TBConfirmedTreatmentCache?,
+ suspectedTb: TBSuspectedCache?
+ ) {
+ val baseList = mutableListOf()
+
+ if (saved == null) {
+ isNewRecord = true
+ treatmentStartDate.value = getDateFromLong(System.currentTimeMillis())
+ reasonForDeath.value = resources.getString(R.string.tuberculosis)
+
+ baseList.addAll(listOf(
+ regimenType,
+ treatmentStartDate,
+ expectedTreatmentCompletionDate,
+ followUpDate,
+ monthlyFollowUpDone,
+ adherenceToMedicines,
+ anyDiscomfort,
+ // treatmentCompleted,
+
+ ))
+
+ treatmentStartDate.max = System.currentTimeMillis()
+ treatmentStartDate.min = suspectedTb?.visitDate
+ ?.takeIf { it > 0 }
+ ?: getOneYearBeforeCurrentDate()
+
+ // Enable follow-up date since treatment start date is pre-filled
+ val todayStart = Calendar.getInstance().apply {
+ set(Calendar.HOUR_OF_DAY, 0)
+ set(Calendar.MINUTE, 0)
+ set(Calendar.SECOND, 0)
+ set(Calendar.MILLISECOND, 0)
+ }.timeInMillis
+ treatmentStartDateValue = todayStart
+ treatmentStartDateLong = todayStart
+ followUpDate.min = todayStart
+ followUpDate.isEnabled = true
+
+
+ } else
+ {
+ isNewRecord = false
+ regimenType.value = getLocalValueInArray(R.array.tb_regimen_types, saved.regimenType)
+ followUpDate.isEnabled =true
+ treatmentStartDateLong = saved?.treatmentStartDate ?: 0L
+ lastFollowUpDateLong = saved?.followUpDate ?: 0L
+
+ if (!saved.regimenType.isNullOrBlank()) {
+ regimenType.isEnabled = false
+ }
+
+ saved.treatmentStartDate
+ ?.takeIf { it > 0 }
+ ?.let {
+ treatmentStartDate.value = getDateFromLong(it)
+ treatmentStartDate.isEnabled = false
+ updateFollowUpDateConstraints()
+ }
+ expectedTreatmentCompletionDate.value = saved.expectedTreatmentCompletionDate?.let {
+ getDateFromLong(it)
+ }
+ followUpDate.value = saved.followUpDate?.let { getDateFromLong(it) }
+ monthlyFollowUpDone.value = saved.monthlyFollowUpDone
+ adherenceToMedicines.value = getLocalValueInArray(R.array.adherence_options, saved.adherenceToMedicines)
+ anyDiscomfort.value = saved.anyDiscomfort?.let {
+ if (it) resources.getStringArray(R.array.yes_no)[0]
+ else resources.getStringArray(R.array.yes_no)[1]
+ }
+ treatmentCompleted.value = saved.treatmentCompleted?.let {
+ if (it) resources.getStringArray(R.array.yes_no)[0]
+ else resources.getStringArray(R.array.yes_no)[1]
+ }
+ actualTreatmentCompletionDate.value = saved.actualTreatmentCompletionDate?.let {
+ getDateFromLong(it)
+ }
+ treatmentOutcome.value = getLocalValueInArray(R.array.tb_treatment_outcomes, saved.treatmentOutcome)
+ dateOfDeath.value = saved.dateOfDeath?.let { getDateFromLong(it) }
+ placeOfDeath.value = getLocalValueInArray(R.array.place_of_death, saved.placeOfDeath)
+ reasonForDeath.value = saved.reasonForDeath
+ reasonForNotCompleting.value = saved.reasonForNotCompleting
+
+ treatmentStartDateValue = saved.treatmentStartDate
+ regimenTypeValue = saved.regimenType
+ lastFollowUpDate = saved.followUpDate
+ baseList.addAll(listOf(
+ regimenType,
+ treatmentStartDate,
+ expectedTreatmentCompletionDate
+ ))
+
+ if (saved.followUpDate != null) {
+ baseList.addAll(listOf(
+ followUpDate,
+ monthlyFollowUpDone,
+ adherenceToMedicines,
+ anyDiscomfort
+ ))
+ } else {
+ baseList.add(followUpDate)
+ }
+
+ if (saved.treatmentCompleted != null) {
+ baseList.add(treatmentCompleted)
+
+ if (saved.treatmentCompleted == true) {
+ baseList.add(actualTreatmentCompletionDate)
+
+ if (saved.treatmentOutcome != null) {
+ baseList.add(treatmentOutcome)
+
+ if (treatmentOutcome.value == treatmentOutcome.entries!![3]) {
+ baseList.addAll(listOf(
+ dateOfDeath,
+ placeOfDeath,
+ reasonForDeath
+ ))
+ }
+ }
+ } else {
+ baseList.add(reasonForNotCompleting)
+ }
+ }
+
+ treatmentOutcome.value?.let { outcome ->
+ if (outcome == treatmentOutcome.entries!![0] || outcome == treatmentOutcome.entries!!.last()) {
+ baseList.forEach { it.isEnabled = false }
+ }
+ }
+
+ }
+
+ /* ben?.let {
+ treatmentStartDate.min = suspectedTb?.visitDate ?: it.regDate
+ }*/
+
+ setUpPage(baseList)
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ when (formId)
+ {
+ regimenType.id -> {
+ regimenTypeValue = regimenType.value
+ calculateExpectedCompletionDate()
+ checkAndEnableTreatmentCompletion()
+
+ }
+
+ treatmentStartDate.id -> {
+ val dateLong = getLongFromDate(treatmentStartDate.value)
+ treatmentStartDateValue = dateLong
+ followUpDate.min = dateLong
+ followUpDate.isEnabled = true
+ calculateExpectedCompletionDate()
+
+ }
+
+ followUpDate.id -> {
+ val dateLong = getLongFromDate(followUpDate.value)
+ lastFollowUpDate = dateLong
+ updateMonthlyFollowUpCount()
+ val error = validateFollowUpDate(dateLong)
+
+ followUpDate.errorText = error
+ checkAndEnableTreatmentCompletion()
+
+
+
+ }
+
+ treatmentCompleted.id -> {
+ val yesNoArray = resources.getStringArray(R.array.yes_no)
+
+ return if (index == 0) {
+
+ triggerDependants(
+ source = treatmentCompleted,
+ removeItems = listOf(reasonForNotCompleting),
+ addItems = listOf(actualTreatmentCompletionDate, treatmentOutcome),
+ position = -2
+ )
+ } else {
+ triggerDependants(
+ source = treatmentCompleted,
+ removeItems = listOf(actualTreatmentCompletionDate, treatmentOutcome,
+ dateOfDeath, placeOfDeath, reasonForDeath),
+ addItems = listOf(reasonForNotCompleting),
+ position = -2
+ )
+ }
+ }
+
+ treatmentOutcome.id -> {
+ val treatmentOutcomes = resources.getStringArray(R.array.tb_treatment_outcomes)
+
+ return if (treatmentOutcome.value == treatmentOutcomes[3]) {
+ triggerDependants(
+ source = treatmentOutcome,
+ removeItems = listOf(),
+ addItems = listOf(dateOfDeath, placeOfDeath, reasonForDeath),
+ position = -2
+ )
+ } else {
+ triggerDependants(
+ source = treatmentOutcome,
+ removeItems = listOf(dateOfDeath, placeOfDeath, reasonForDeath),
+ addItems = listOf(),
+ position = -2
+ )
+ }
+ }
+
+
+ }
+ return 0
+ }
+
+ private fun getFirstDayOfNextMonth(date: Long): Long {
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = date
+ calendar.set(Calendar.DAY_OF_MONTH, 1)
+ calendar.add(Calendar.MONTH, 1)
+ calendar.set(Calendar.HOUR_OF_DAY, 0)
+ calendar.set(Calendar.MINUTE, 0)
+ calendar.set(Calendar.SECOND, 0)
+ calendar.set(Calendar.MILLISECOND, 0)
+ return calendar.timeInMillis
+ }
+
+ private fun getLastDayOfNextMonth(date: Long): Long {
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = date
+ calendar.set(Calendar.DAY_OF_MONTH, 1)
+ calendar.add(Calendar.MONTH, 2)
+ calendar.add(Calendar.DAY_OF_MONTH, -1)
+ calendar.set(Calendar.HOUR_OF_DAY, 23)
+ calendar.set(Calendar.MINUTE, 59)
+ calendar.set(Calendar.SECOND, 59)
+ calendar.set(Calendar.MILLISECOND, 999)
+ return calendar.timeInMillis
+ }
+
+ private fun isSameMonth(date1: Long, date2: Long): Boolean {
+ val cal1 = Calendar.getInstance()
+ val cal2 = Calendar.getInstance()
+ cal1.timeInMillis = date1
+ cal2.timeInMillis = date2
+ return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
+ cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
+ }
+
+
+
+ private fun updateFollowUpDateConstraints() {
+ if (treatmentStartDateLong == 0L) {
+ followUpDate.isEnabled = false
+ return
+ }
+
+ followUpDate.max = System.currentTimeMillis()
+
+ if (lastFollowUpDateLong == 0L) {
+ followUpDate.min = treatmentStartDateLong
+ followUpDate.isEnabled = true
+ } else {
+ nextFollowUpMonthStart = getFirstDayOfNextMonth(lastFollowUpDateLong)
+ nextFollowUpMonthEnd = getLastDayOfNextMonth(lastFollowUpDateLong)
+
+ followUpDate.min = nextFollowUpMonthStart
+ followUpDate.isEnabled = System.currentTimeMillis() >= nextFollowUpMonthStart
+ }
+ }
+
+ fun validateAllFields(): Boolean {
+
+ val followUpDateValid = validateCurrentFollowUpDate()
+ if (regimenType.required && (regimenType.value == null || regimenType.value.isNullOrEmpty())) {
+ regimenType.errorText = "Regimen type is required"
+ return false
+ }
+ if (treatmentStartDate.required && (treatmentStartDate.value == null || treatmentStartDate.value.isNullOrEmpty())) {
+ treatmentStartDate.errorText = "Treatment start date is required"
+ return false
+ }
+
+ return followUpDateValid
+ }
+ fun validateCurrentFollowUpDate(): Boolean {
+ val dateString = followUpDate.value
+ if (dateString == null || dateString.isEmpty()) {
+ followUpDate.errorText = "Follow-up date is required"
+ return false
+ }
+
+ val dateLong = getLongFromDate(dateString)
+ val error = validateFollowUpDate(dateLong)
+ followUpDate.errorText = error
+ return error == null
+ }
+
+ private fun validateFollowUpDate(selectedDate: Long): String? {
+
+ if (selectedDate > System.currentTimeMillis()) {
+ return "Follow-up date cannot be in the future"
+ }
+
+ if (selectedDate < treatmentStartDateLong) {
+ return "Follow-up date cannot be before treatment start date"
+ }
+
+ if (lastFollowUpDateLong > 0) {
+ if (selectedDate <= lastFollowUpDateLong) {
+ return "Follow-up date must be after last follow-up date"
+ }
+
+ if (isSameMonth(selectedDate, lastFollowUpDateLong)) {
+ return "Only one follow-up is allowed per month"
+ }
+ }
+
+ return null
+ }
+
+
+ private fun calculateExpectedCompletionDate() {
+ if (regimenTypeValue == null || treatmentStartDateValue == null) return
+
+ val calendar = Calendar.getInstance().apply {
+ timeInMillis = treatmentStartDateValue!!
+ }
+
+ when (regimenTypeValue) {
+ resources.getStringArray(R.array.tb_regimen_types)[0],
+ resources.getStringArray(R.array.tb_regimen_types)[3],
+ resources.getStringArray(R.array.tb_regimen_types)[4]
+ -> {
+ calendar.add(Calendar.MONTH, 6)
+ expectedTreatmentCompletionDate.value = getDateFromLong(calendar.timeInMillis)
+ }
+ resources.getStringArray(R.array.tb_regimen_types)[1] -> {
+ val minDate = Calendar.getInstance().apply {
+ timeInMillis = treatmentStartDateValue!!
+ add(Calendar.MONTH, 9)
+ }.timeInMillis
+ val maxDate = Calendar.getInstance().apply {
+ timeInMillis = treatmentStartDateValue!!
+ add(Calendar.MONTH, 12)
+ }.timeInMillis
+ expectedTreatmentCompletionDate.value = "${getDateFromLong(minDate)} to ${getDateFromLong(maxDate)}"
+ }
+ resources.getStringArray(R.array.tb_regimen_types)[2] -> { // Longer Regimen (18–24 Months)
+ val minDate = Calendar.getInstance().apply {
+ timeInMillis = treatmentStartDateValue!!
+ add(Calendar.MONTH, 18)
+ }.timeInMillis
+ val maxDate = Calendar.getInstance().apply {
+ timeInMillis = treatmentStartDateValue!!
+ add(Calendar.MONTH, 24)
+ }.timeInMillis
+ expectedTreatmentCompletionDate.value = "${getDateFromLong(minDate)} to ${getDateFromLong(maxDate)}"
+ }
+ }
+ }
+
+ private fun checkAndEnableTreatmentCompletion() {
+ if (regimenTypeValue == null || followUpCount == 0) return
+
+ val requiredFollowUps = when (regimenTypeValue) {
+ resources.getStringArray(R.array.tb_regimen_types)[0],
+ resources.getStringArray(R.array.tb_regimen_types)[3],
+ resources.getStringArray(R.array.tb_regimen_types)[4]
+ -> 5
+ resources.getStringArray(R.array.tb_regimen_types)[1] -> 9
+ resources.getStringArray(R.array.tb_regimen_types)[2] -> 18
+ else -> 0
+ }
+
+ if (followUpCount >= requiredFollowUps) {
+ treatmentCompleted.isEnabled = true
+ triggerDependants(source = followUpDate, addItems = listOf(treatmentCompleted),removeItems = listOf(), position = -2)
+ } else {
+ treatmentCompleted.isEnabled = false
+ treatmentCompleted.value = null
+
+ triggerDependants(
+ source = treatmentCompleted,
+ removeItems = listOf(actualTreatmentCompletionDate, treatmentOutcome,
+ reasonForNotCompleting, dateOfDeath, placeOfDeath, reasonForDeath),
+ addItems = listOf(),
+ position = -2
+ )
+ }
+ }
+
+ private fun updateMonthlyFollowUpCount() {
+ if (lastFollowUpDate == null || treatmentStartDateValue == null)
+ { monthlyFollowUpDone.value = resources.getString(R.string.month_format, followUpCount)
+ return}
+
+
+ val calendarStart = Calendar.getInstance().apply {
+ timeInMillis = treatmentStartDateValue!!
+ }
+ val calendarFollowUp = Calendar.getInstance().apply {
+ timeInMillis = lastFollowUpDate!!
+ }
+
+ val yearDiff = calendarFollowUp.get(Calendar.YEAR) - calendarStart.get(Calendar.YEAR)
+ val monthDiff = calendarFollowUp.get(Calendar.MONTH) - calendarStart.get(Calendar.MONTH)
+
+ followUpCount = (yearDiff * 12) + monthDiff + 1
+
+ monthlyFollowUpDone.value = resources.getString(R.string.month_format, followUpCount)
+
+ checkAndEnableTreatmentCompletion()
+ }
+
+ private fun validateMonthlyFollowUp(newDate: Long): Boolean {
+ val newCalendar = Calendar.getInstance().apply { timeInMillis = newDate }
+ val newMonth = newCalendar.get(Calendar.MONTH)
+ val newYear = newCalendar.get(Calendar.YEAR)
+
+
+ return true
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as TBConfirmedTreatmentCache).let { form ->
+ form.regimenType = getEnglishValueInArray(R.array.tb_regimen_types, regimenType.value)
+ form.treatmentStartDate = getLongFromDate(treatmentStartDate.value)
+ form.expectedTreatmentCompletionDate = getLongFromDate(expectedTreatmentCompletionDate.value)
+ form.followUpDate = getLongFromDate(followUpDate.value)
+ form.monthlyFollowUpDone = monthlyFollowUpDone.value
+ form.adherenceToMedicines = getEnglishValueInArray(R.array.adherence_options, adherenceToMedicines.value)
+ form.anyDiscomfort = anyDiscomfort.value == anyDiscomfort.entries!![0]
+ form.treatmentCompleted = treatmentCompleted.value?.let {
+ it == treatmentCompleted.entries!![0]
+ }
+ form.actualTreatmentCompletionDate = getLongFromDate(actualTreatmentCompletionDate.value)
+ form.treatmentOutcome = getEnglishValueInArray(R.array.tb_treatment_outcomes, treatmentOutcome.value)
+ form.dateOfDeath = getLongFromDate(dateOfDeath.value)
+ form.placeOfDeath = getEnglishValueInArray(R.array.place_of_death, placeOfDeath.value)
+ form.reasonForDeath = reasonForDeath.value ?: resources.getString(R.string.tuberculosis)
+ form.reasonForNotCompleting = reasonForNotCompleting.value
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/TBScreeningDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/TBScreeningDataset.kt
index 300c4b33b..a373a2f92 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/configuration/TBScreeningDataset.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/TBScreeningDataset.kt
@@ -12,6 +12,19 @@ class TBScreeningDataset(
context: Context, currentLanguage: Languages
) : Dataset(context, currentLanguage) {
+ private val symptomaticLabel = FormElement(
+ id = 14,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.symptomatic_tb_screening),
+ required = false
+ )
+
+ private val checkSymptomsLabel = FormElement(
+ id = 14,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.check_if_the_person_has_any_of_these_symptoms),
+ required = false
+ )
private val dateOfVisit = FormElement(
id = 1,
inputType = InputType.DATE_PICKER,
@@ -97,8 +110,98 @@ class TBScreeningDataset(
hasDependants = false
)
+ private var riseOfFever = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_rise_of_fever),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+
+
+ private var lossOfAppetite = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_loss_of_appetite),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+ private val aSymptomaticLabel = FormElement(
+ id = 14,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.tb_asymptomatic_symptoms),
+ required = false
+ )
+ private val checkSymptomsLabel1 = FormElement(
+ id = 14,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.check_if_the_person_has_any_of_these_symptoms),
+ required = false
+ )
+ private var age = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_age_more_than_60),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+ private var diabetic = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_diabetic),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+ private var tobaccoUser = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_tobacco_user),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+ private var bmi = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_bmi_less_than_18_5),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+ private var contactWithTBPatient = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_contact_with_patient_on_treatment),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+ private var historyOfTBInLastFiveYrs = FormElement(
+ id = 7,
+ inputType = InputType.RADIO,
+ title = resources.getString(R.string.tb_history_last_5_years),
+ entries = resources.getStringArray(R.array.yes_no),
+ doubleStar = true,
+ required = true,
+ hasDependants = false
+ )
+
+
suspend fun setUpPage(ben: BenRegCache?, saved: TBScreeningCache?) {
val list = mutableListOf(
+ symptomaticLabel,
+ checkSymptomsLabel,
dateOfVisit,
isCoughing,
bloodInSputum,
@@ -107,7 +210,17 @@ class TBScreeningDataset(
nightSweats,
historyOfTB,
currentlyTakingDrugs,
- familyHistoryTB
+ familyHistoryTB,
+ riseOfFever,
+ lossOfAppetite,
+ aSymptomaticLabel,
+ checkSymptomsLabel1,
+ age,
+ diabetic,
+ tobaccoUser,
+ bmi,
+ contactWithTBPatient,
+ historyOfTBInLastFiveYrs
)
if (saved == null) {
dateOfVisit.value = getDateFromLong(System.currentTimeMillis())
@@ -145,6 +258,41 @@ class TBScreeningDataset(
if (saved.familySufferingFromTB == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
R.array.yes_no
)[1]
+
+ riseOfFever.value =
+ if (saved.riseOfFever == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+
+ lossOfAppetite.value =
+ if (saved.lossOfAppetite == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ age.value =
+ if (saved.age == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ diabetic.value =
+ if (saved.diabetic == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ tobaccoUser.value =
+ if (saved.tobaccoUser == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ bmi.value =
+ if (saved.bmi == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+ contactWithTBPatient.value =
+ if (saved.contactWithTBPatient == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
+
+ historyOfTBInLastFiveYrs.value =
+ if (saved.historyOfTBInLastFiveYrs == true) resources.getStringArray(R.array.yes_no)[0] else resources.getStringArray(
+ R.array.yes_no
+ )[1]
}
@@ -175,6 +323,33 @@ class TBScreeningDataset(
currentlyTakingDrugs.value == resources.getStringArray(R.array.yes_no)[0]
form.familySufferingFromTB =
familyHistoryTB.value == resources.getStringArray(R.array.yes_no)[0]
+ form.riseOfFever = riseOfFever.value == resources.getStringArray(R.array.yes_no)[0]
+ form.lossOfAppetite =
+ lossOfAppetite.value == resources.getStringArray(R.array.yes_no)[0]
+ form.age =
+ age.value == resources.getStringArray(R.array.yes_no)[0]
+ form.diabetic =
+ diabetic.value == resources.getStringArray(R.array.yes_no)[0]
+ form.tobaccoUser =
+ tobaccoUser.value == resources.getStringArray(R.array.yes_no)[0]
+ form.bmi =
+ bmi.value == resources.getStringArray(R.array.yes_no)[0]
+ form.contactWithTBPatient =
+ contactWithTBPatient.value == resources.getStringArray(R.array.yes_no)[0]
+ form.historyOfTBInLastFiveYrs =
+ historyOfTBInLastFiveYrs.value == resources.getStringArray(R.array.yes_no)[0]
+ form.sympotomatic = isSymptomatic()
+ form.asymptomatic = isAsymptomatic()
+
+ if (isSymptomatic()=="Yes" && isAsymptomatic() =="No"){
+ form.recommandateTest = "Sputum Test"
+ }else if(isSymptomatic() == "No"&& isAsymptomatic() =="Yes"){
+ form.recommandateTest = "Chest X-Ray"
+ }else if(isSymptomatic() == "Yes"&& isAsymptomatic() =="Yes"){
+ form.recommandateTest = "Both"
+ }else{
+ form.recommandateTest = "None"
+ }
}
}
@@ -182,19 +357,73 @@ class TBScreeningDataset(
fun updateBen(benRegCache: BenRegCache) {
benRegCache.genDetails?.let {
it.reproductiveStatus =
- englishResources.getStringArray(R.array.nbr_reproductive_status_array)[1]
+ englishResources.getStringArray(R.array.nbr_reproductive_status_array2)[1]
it.reproductiveStatusId = 2
}
if (benRegCache.processed != "N") benRegCache.processed = "U"
}
+ fun referHwcFacility():String?{
+ return if (isCoughing.value == resources.getStringArray(R.array.yes_no)[0] ||
+ bloodInSputum.value == resources.getStringArray(R.array.yes_no)[0] ||
+ isFever.value == resources.getStringArray(R.array.yes_no)[0] ||
+ nightSweats.value == resources.getStringArray(R.array.yes_no)[0] ||
+ lossOfWeight.value == resources.getStringArray(R.array.yes_no)[0] ||
+ historyOfTB.value == resources.getStringArray(R.array.yes_no)[0]||
+
+ riseOfFever.value == resources.getStringArray(R.array.yes_no)[0] ||
+ lossOfAppetite.value == resources.getStringArray(R.array.yes_no)[0] ||
+ age.value == resources.getStringArray(R.array.yes_no)[0] ||
+ diabetic.value == resources.getStringArray(R.array.yes_no)[0] ||
+ tobaccoUser.value == resources.getStringArray(R.array.yes_no)[0] ||
+ bmi.value == resources.getStringArray(R.array.yes_no)[0] ||
+ contactWithTBPatient.value == resources.getStringArray(R.array.yes_no)[0] ||
+ historyOfTBInLastFiveYrs.value == resources.getStringArray(R.array.yes_no)[0]
+ )
+ resources.getString(R.string.refer_to_hwc_facility_alert) else null
+
+ }
+
+ fun isSymptomatic():String{
+ return if (isCoughing.value == resources.getStringArray(R.array.yes_no)[0] ||
+ bloodInSputum.value == resources.getStringArray(R.array.yes_no)[0] ||
+ isFever.value == resources.getStringArray(R.array.yes_no)[0] ||
+ nightSweats.value == resources.getStringArray(R.array.yes_no)[0] ||
+ lossOfWeight.value == resources.getStringArray(R.array.yes_no)[0] ||
+ historyOfTB.value == resources.getStringArray(R.array.yes_no)[0]||
+ riseOfFever.value == resources.getStringArray(R.array.yes_no)[0] ||
+ lossOfAppetite.value == resources.getStringArray(R.array.yes_no)[0]
+ )
+ "Yes" else "No"
+ }
+ fun isAsymptomatic():String{
+ return if (
+ age.value == resources.getStringArray(R.array.yes_no)[0] ||
+ diabetic.value == resources.getStringArray(R.array.yes_no)[0] ||
+ tobaccoUser.value == resources.getStringArray(R.array.yes_no)[0] ||
+ bmi.value == resources.getStringArray(R.array.yes_no)[0] ||
+ contactWithTBPatient.value == resources.getStringArray(R.array.yes_no)[0] ||
+ historyOfTBInLastFiveYrs.value == resources.getStringArray(R.array.yes_no)[0]
+ )
+ "Yes" else "No"
+ }
+
fun isTbSuspected(): String? {
return if (isCoughing.value == resources.getStringArray(R.array.yes_no)[0] ||
bloodInSputum.value == resources.getStringArray(R.array.yes_no)[0] ||
isFever.value == resources.getStringArray(R.array.yes_no)[0] ||
nightSweats.value == resources.getStringArray(R.array.yes_no)[0] ||
lossOfWeight.value == resources.getStringArray(R.array.yes_no)[0] ||
- historyOfTB.value == resources.getStringArray(R.array.yes_no)[0]
+ historyOfTB.value == resources.getStringArray(R.array.yes_no)[0]||
+
+ riseOfFever.value == resources.getStringArray(R.array.yes_no)[0] ||
+ lossOfAppetite.value == resources.getStringArray(R.array.yes_no)[0] ||
+ age.value == resources.getStringArray(R.array.yes_no)[0] ||
+ diabetic.value == resources.getStringArray(R.array.yes_no)[0] ||
+ tobaccoUser.value == resources.getStringArray(R.array.yes_no)[0] ||
+ bmi.value == resources.getStringArray(R.array.yes_no)[0] ||
+ contactWithTBPatient.value == resources.getStringArray(R.array.yes_no)[0] ||
+ historyOfTBInLastFiveYrs.value == resources.getStringArray(R.array.yes_no)[0]
)
resources.getString(R.string.tb_suspected_alert) else null
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/UWINDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/UWINDataset.kt
new file mode 100644
index 000000000..2c8423d07
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/UWINDataset.kt
@@ -0,0 +1,154 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.UwinCache
+import java.util.Calendar
+
+class UWINDataset(context: Context, language: Languages) : Dataset(context, language) {
+
+
+ companion object {
+
+ private fun getMinDate(monthsBack: Int = 2): Long {
+ return Calendar.getInstance().apply {
+ add(Calendar.MONTH, -monthsBack)
+ }.timeInMillis
+ }
+ }
+
+ private val uWinSessionDate = FormElement(
+ id = 117,
+ inputType = InputType.DATE_PICKER,
+ title = resources.getString(R.string.u_win_session_date),
+ max = System.currentTimeMillis(),
+ min = getMinDate(2),
+ required = true,
+ isEnabled = true
+ )
+
+ private val place = FormElement(
+ id = 118,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place),
+ arrayId = R.array.place_of_delivery_options,
+ entries = resources.getStringArray(R.array.place_of_delivery_options),
+ required = true,
+ )
+
+ private val participant = FormElement(
+ id = 119,
+ inputType = InputType.EDIT_TEXT,
+ title = resources.getString(R.string.no_of_participants_attended),
+ required = true,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 3,
+ isEnabled = true
+ )
+
+ private val uploadSummary1 = FormElement(
+ id = 120,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.file_upload_n, 1),
+ required = false
+ )
+
+ private val uploadSummary2 = FormElement(
+ id = 121,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.file_upload_n, 2),
+ required = false
+ )
+
+ suspend fun setFirstPage(saved: Boolean, cache: UwinCache?) {
+ val list = listOf(
+ uWinSessionDate,
+ place,
+ participant,
+ uploadSummary1,
+ uploadSummary2
+ )
+
+ if (saved && cache != null) {
+ uWinSessionDate.value = getDateFromLong(cache.sessionDate)
+ place.value = getLocalValueInArray(R.array.place_of_delivery_options, cache.place)
+ participant.value = cache.participantsCount.toString()
+ uploadSummary1.value = cache.uploadedFiles1
+ uploadSummary2.value = cache.uploadedFiles2
+
+
+ uWinSessionDate.isEnabled = false
+ place.isEnabled = false
+ participant.isEnabled = false
+ } else {
+
+ uWinSessionDate.value = null
+ place.value = null
+ participant.value = null
+ uploadSummary1.value = null
+ uploadSummary2.value = null
+
+
+ uWinSessionDate.isEnabled = true
+ place.isEnabled = true
+ participant.isEnabled = true
+ }
+
+ setUpPage(list)
+ }
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ when (formId) {
+ uWinSessionDate.id -> {
+ uWinSessionDate.errorText = ((if (uWinSessionDate.value.isNullOrEmpty())
+ emitAlertErrorMessage(R.string.form_input_empty_error)
+ else null) as String?)
+ }
+
+
+ participant.id -> {
+ participant.errorText = (if (participant.value.isNullOrEmpty())
+ emitAlertErrorMessage(R.string.form_input_empty_error)
+ else null) as String?
+ }
+
+
+ }
+
+
+ return -1
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as UwinCache).let {
+ it.sessionDate = uWinSessionDate.value?.let { getLongFromDate(it) }!!
+ it.place = place.getEnglishStringFromPosition(place.getPosition())
+ it.participantsCount = participant.value!!.toInt()
+ it.uploadedFiles1 = uploadSummary1.value?.takeIf { it.isNotEmpty() }
+ it.uploadedFiles2 = uploadSummary2.value?.takeIf { it.isNotEmpty() }
+ }
+ }
+
+ fun getUwinFileIndex1() = getIndexById(uploadSummary1.id)
+ fun getUwinFileIndex2() = getIndexById(uploadSummary2.id)
+
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ 120 -> {
+ uploadSummary1.value = dpUri.toString()
+ uploadSummary1.errorText = null
+ }
+
+ 121 -> {
+ uploadSummary2.value = dpUri.toString()
+ uploadSummary2.errorText = null
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/VHNCDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/VHNCDataset.kt
new file mode 100644
index 000000000..2e6cdf53f
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/VHNCDataset.kt
@@ -0,0 +1,310 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import android.util.Log
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Konstants
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.BenRegCache
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.IMAGE_VIEW
+import org.piramalswasthya.sakhi.model.InputType.RADIO
+import org.piramalswasthya.sakhi.model.VHNCCache
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+class VHNCDataset(
+ context: Context, currentLanguage: Languages,
+) : Dataset(context, currentLanguage) {
+
+ companion object {
+ private fun getCurrentDateString(): String {
+ val calendar = Calendar.getInstance()
+ val mdFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ return mdFormat.format(calendar.time)
+ }
+ private fun getTwoMonthsBackMillis(): Long {
+ return Calendar.getInstance().apply {
+ add(Calendar.MONTH, -2)
+ }.timeInMillis
+ }
+ }
+
+
+ private val vhncDate = FormElement(
+ id = 2,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.vhsnc_meeting_date),
+ arrayId = -1,
+ required = true,
+ min = getTwoMonthsBackMillis(),
+ max = System.currentTimeMillis()
+ )
+ private val place = FormElement(
+ id = 3,
+ inputType = InputType.DROPDOWN,
+ title = context.getString(R.string.place_of_vhsnc_meeting),
+ entries = resources.getStringArray(R.array.place_of_vhsnc),
+ arrayId = R.array.place_of_vhsnc,
+ required = true,
+ )
+
+ private val villageName = FormElement(
+ id = 9,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.village_name),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
+ )
+
+ private val noOfBeneficiariesAttended = FormElement(
+ id = 4,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.no_b_attended),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+
+ private val noOfANM = FormElement(
+ id = 11,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_anm_mpw_attended),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+ private val noOfAWW = FormElement(
+ id = 12,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_aww_attended),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+ private val noOfPW = FormElement(
+ id = 13,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_pregnant_woman),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+ private val noOfLM = FormElement(
+ id = 14,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_lactating_mothers),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+ private val noOfCommentte = FormElement(
+ id = 15,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.number_of_committee_members_present),
+ arrayId = -1,
+ value = "0",
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 1
+ )
+
+ private val followupPrevius = FormElement(
+ id = 16,
+ inputType = RADIO,
+ title = resources.getString(R.string.follow_up_the_previous_meeting_minutes),
+ arrayId = R.array.yes_no,
+ entries = resources.getStringArray(R.array.yes_no),
+ required = false,
+ hasDependants = true,
+ )
+ private val pic1 = FormElement(
+ id = 1,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false,
+ )
+ private val pic2 = FormElement(
+ id = 2,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false,
+ )
+
+ suspend fun setUpPage( vhnd: VHNCCache?) {
+
+
+ if (pic1.value.isNullOrBlank()) {
+ pic1.value = "default"
+ }
+
+ if (pic2.value.isNullOrBlank()) {
+ pic2.value = "default"
+ }
+ val list = mutableListOf(
+ vhncDate,
+ place,
+ )
+
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.add(villageName)
+ list.add(noOfBeneficiariesAttended)
+ list.add(noOfANM)
+ list.add(noOfAWW)
+ list.add(noOfPW)
+ list.add(noOfLM)
+ list.add(noOfCommentte)
+ list.add(followupPrevius)
+ list.add(pic1)
+ list.add(pic2)
+
+ noOfBeneficiariesAttended.title=
+ resources.getString(R.string.number_of_mitanins_participated_in_vhsnc_meeting)
+
+ }
+ else{
+ list.add(noOfBeneficiariesAttended)
+ list.add(pic1)
+ list.add(pic2)
+ noOfBeneficiariesAttended.title= resources.getString(R.string.number_of_asha_participated_in_vhsnc_meeting)
+
+ }
+ vhncDate.value = getCurrentDateString()
+ vhnd?.let {
+ vhncDate.value = it.vhncDate
+ pic1.value = it.image1
+ pic2.value = it.image2
+ place.value = getLocalValueInArray(R.array.place_of_vhsnc, it.place)
+ villageName.value = it.villageName?.takeIf { v -> v.isNotEmpty() && v != "null" } ?: ""
+ noOfBeneficiariesAttended.value = (it.noOfBeneficiariesAttended ?: 0).toString()
+ noOfANM.value = (it.anm ?: 0).toString()
+ noOfAWW.value = (it.aww ?: 0).toString()
+ noOfPW.value = (it.noOfPragnentWoment ?: 0).toString()
+ noOfLM.value = (it.noOfLactingMother ?: 0).toString()
+ noOfCommentte.value = (it.noOfCommittee ?: 0).toString()
+ followupPrevius.value = it.followupPrevius?.let { value ->
+ val options = resources.getStringArray(R.array.yes_no)
+ if (value) options[0] else options[1]
+ }
+ }
+ setUpPage(list)
+ }
+
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ place.id -> {
+ validateEmptyOnEditText(place)
+ validateAllAlphabetsSpecialAndNumericOnEditText(place)
+ -1
+ }
+
+ noOfBeneficiariesAttended.id -> {
+ validateEmptyOnEditText(noOfBeneficiariesAttended)
+ -1
+ }
+
+ else -> {
+ -1
+ }
+ }
+ }
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as VHNCCache).let { form ->
+
+ form.vhncDate = vhncDate.value!!
+ form.place = getEnglishValueInArray(R.array.place_of_vhsnc, place.value)
+ form.noOfBeneficiariesAttended = noOfBeneficiariesAttended.value!!.toInt()
+ form.image1 = pic1.value?.takeIf { it.isNotEmpty() }
+ form.image2 = pic2.value?.takeIf { it.isNotEmpty() }
+ form.villageName = villageName.value
+ form.anm = noOfANM.value?.trim()?.toIntOrNull() ?: 0
+ form.aww = noOfAWW.value?.trim()?.toIntOrNull() ?: 0
+ form.noOfPragnentWoment = noOfPW.value?.trim()?.toIntOrNull() ?: 0
+ form.noOfLactingMother = noOfLM.value?.trim()?.toIntOrNull() ?: 0
+ form.noOfCommittee = noOfCommentte.value?.trim()?.toIntOrNull() ?: 0
+ form.followupPrevius= followupPrevius.value?.let { value ->
+ val options = resources.getStringArray(R.array.yes_no)
+ when (value.trim()) {
+ options[0] -> true
+ options[1] -> false
+ else -> null
+ }
+ }
+
+ }
+
+ }
+
+ fun getFileIndex1() = getIndexById(pic1.id)
+ fun getFileIndex2() = getIndexById(pic2.id)
+
+
+// fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+// when (lastImageFormId) {
+// 1 -> {
+// pic1.value = dpUri.toString()
+// pic1.errorText = null
+// }
+//
+// 2-> {
+// pic2.value = dpUri.toString()
+// pic2.errorText = null
+// }
+// }
+// }
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ pic1.id -> {
+ pic1.value = dpUri.toString()
+ pic1.errorText = null
+ }
+ pic2.id -> {
+ pic2.value = dpUri.toString()
+ pic2.errorText = null
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/VHNDDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/VHNDDataset.kt
new file mode 100644
index 000000000..801931c05
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/VHNDDataset.kt
@@ -0,0 +1,361 @@
+package org.piramalswasthya.sakhi.configuration
+
+import android.content.Context
+import android.net.Uri
+import org.piramalswasthya.sakhi.BuildConfig
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.EDIT_TEXT
+import org.piramalswasthya.sakhi.model.InputType.IMAGE_VIEW
+import org.piramalswasthya.sakhi.model.VHNDCache
+import org.piramalswasthya.sakhi.utils.HelperUtil.parseSelections
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+class VHNDDataset(
+ context: Context, currentLanguage: Languages
+) : Dataset(context, currentLanguage) {
+
+ companion object {
+ private fun getCurrentDateString(): String {
+ val calendar = Calendar.getInstance()
+ val mdFormat = SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH)
+ return mdFormat.format(calendar.time)
+ }
+
+ }
+
+
+ private val vhndDate = FormElement(
+ id = 2,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.vhnd_date),
+ arrayId = -1,
+ required = true,
+ min = System.currentTimeMillis() - (60L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis()
+ )
+ private val place = FormElement(
+ id = 3,
+ inputType = InputType.DROPDOWN,
+ title = resources.getString(R.string.place_of_vhnd),
+ entries = resources.getStringArray(R.array.place_of_vhsnc),
+ arrayId = R.array.place_of_vhsnc,
+ required = true,
+ allCaps = true,
+ )
+
+ private val noOfBeneficiariesAttended = FormElement(
+ id = 4,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.total_no_b_attended),
+ arrayId = -1,
+ required = true,
+ value = "0",
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 0
+ )
+
+ private val noOfPWAttended = FormElement(
+ id = 5,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.total_no_pw_attended),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 0
+ )
+ private val noOflactingMotherAttended = FormElement(
+ id = 6,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.total_no_lacting_mother_attended),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 3,
+ max = 999,
+ min = 0
+ )
+ private val noOfchildrenAttended = FormElement(
+ id = 7,
+ inputType = EDIT_TEXT,
+ title = resources.getString(R.string.total_no_children_attended),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ etMaxLength = 3,
+ max = 999,
+ min = 0
+ )
+ private val heading = FormElement(
+ id = 14,
+ inputType = InputType.HEADLINE,
+ title = resources.getString(R.string.health_nutrition),
+ arrayId = -1,
+ required = false,
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ isMobileNumber = true,
+ etMaxLength = 3,
+ max = 999,
+ min = 0
+ )
+
+ private val knowOfBalanceDiet = FormElement(
+ id = 8,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.know_balance_diet),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.diet_plane),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+ private val careDuringPregnancy = FormElement(
+ id = 9,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.care_d_pregnancy),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.care_pregnancy),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+ private val importBreastFeeding = FormElement(
+ id = 10,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.imp_brestfeeding_title),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.import_brestfeeding),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+ private val complementFeeding = FormElement(
+ id = 11,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.com_feeding_title),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.complementary_feeding),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+ private val hygieneSenitation = FormElement(
+ id = 12,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.hygiene_title),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.hygiene_senetigation),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+ private val fPlanning = FormElement(
+ id = 13,
+ inputType = InputType.CHECKBOXES,
+ title = resources.getString(R.string.family_planning_title),
+ arrayId = -1,
+ required = false,
+ entries = resources.getStringArray(R.array.family_planning_health),
+ etInputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+
+ private val pic1 = FormElement(
+ id = 1,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false,
+ )
+ private val pic2 = FormElement(
+ id = 2,
+ inputType = InputType.FILE_UPLOAD,
+ title = resources.getString(R.string.upload_image),
+ arrayId = -1,
+ required = false,
+ )
+
+ suspend fun setUpPage(vhnd: VHNDCache?) {
+
+
+ if (pic1.value.isNullOrBlank()) {
+ pic1.value = "default"
+ }
+
+ if (pic2.value.isNullOrBlank()) {
+ pic2.value = "default"
+ }
+
+ val list = mutableListOf(
+ vhndDate,
+ place,
+ noOfBeneficiariesAttended
+ )
+
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ list.addAll(
+ listOf(
+ noOfPWAttended,
+ noOflactingMotherAttended,
+ noOfchildrenAttended,
+ heading,
+ knowOfBalanceDiet,
+ careDuringPregnancy,
+ importBreastFeeding,
+ complementFeeding,
+ hygieneSenitation,
+ fPlanning
+
+ )
+ )
+ }
+
+ list.addAll(
+ listOf(
+ pic1,
+ pic2
+ )
+ )
+
+
+ vhndDate.value = getCurrentDateString()
+ vhnd?.let {
+ vhndDate.value = it.vhndDate
+ pic1.value = it.image1
+ pic2.value = it.image2
+ place.value = getLocalValueInArray(R.array.place_of_vhsnc, it.place)
+ noOfBeneficiariesAttended.value = (it.noOfBeneficiariesAttended ?: 0).toString()
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ noOfPWAttended.value = it.pregnantWomenAnc?.takeIf { v -> v.isNotEmpty() && v != "null" } ?: "0"
+ noOflactingMotherAttended.value = it.lactatingMothersPnc?.takeIf { v -> v.isNotEmpty() && v != "null" } ?: "0"
+ noOfchildrenAttended.value = it.childrenImmunization?.takeIf { v -> v.isNotEmpty() && v != "null" } ?: "0"
+ val parsedKBDList = parseSelections(it.knowledgeBalancedDiet, knowOfBalanceDiet.entries!!)
+ knowOfBalanceDiet.value = if (parsedKBDList.isNotEmpty()) {
+ parsedKBDList.joinToString("|")
+ } else {
+ it.knowledgeBalancedDiet ?: ""
+ }
+ val parsedCDPList = parseSelections(it.careDuringPregnancy, careDuringPregnancy.entries!!)
+ careDuringPregnancy.value = if (parsedCDPList.isNotEmpty()) {
+ parsedCDPList.joinToString("|")
+ } else {
+ it.careDuringPregnancy ?: ""
+ }
+ val parsedBrestFeedingList = parseSelections(it.importanceBreastfeeding, importBreastFeeding.entries!!)
+ importBreastFeeding.value = if (parsedBrestFeedingList.isNotEmpty()) {
+ parsedBrestFeedingList.joinToString("|")
+ } else {
+ it.importanceBreastfeeding ?: ""
+ }
+
+ val parsedComplementaryFeedingList = parseSelections(it.complementaryFeeding, complementFeeding.entries!!)
+ complementFeeding.value = if (parsedComplementaryFeedingList.isNotEmpty()) {
+ parsedComplementaryFeedingList.joinToString("|")
+ } else {
+ it.complementaryFeeding ?: ""
+ }
+
+ val parsedHygieneSanitiList = parseSelections(it.hygieneSanitation, hygieneSenitation.entries!!)
+ hygieneSenitation.value = if (parsedHygieneSanitiList.isNotEmpty()) {
+ parsedHygieneSanitiList.joinToString("|")
+ } else {
+ it.hygieneSanitation ?: ""
+ }
+
+ val parsedFamilyPlanList = parseSelections(it.familyPlanningHealthcare, fPlanning.entries!!)
+ fPlanning.value = if (parsedFamilyPlanList.isNotEmpty()) {
+ parsedFamilyPlanList.joinToString("|")
+ } else {
+ it.familyPlanningHealthcare ?: ""
+ }
+
+ }
+
+ }
+ setUpPage(list)
+ }
+
+
+ override suspend fun handleListOnValueChanged(formId: Int, index: Int): Int {
+ return when (formId) {
+ place.id -> {
+ validateEmptyOnEditText(place)
+ validateAllAlphabetsSpecialAndNumericOnEditText(place)
+ -1
+ }
+
+ noOfBeneficiariesAttended.id -> {
+ validateEmptyOnEditText(noOfBeneficiariesAttended)
+ -1
+ }
+ noOfPWAttended.id -> {
+ validateEmptyOnEditText(noOfPWAttended)
+ -1
+ }
+ noOflactingMotherAttended.id -> {
+ validateEmptyOnEditText(noOflactingMotherAttended)
+ -1
+ }
+ noOfchildrenAttended.id -> {
+ validateEmptyOnEditText(noOfchildrenAttended)
+ -1
+ }
+
+
+ else -> {
+ -1
+ }
+ }
+ }
+
+
+
+ override fun mapValues(cacheModel: FormDataModel, pageNumber: Int) {
+ (cacheModel as VHNDCache).let { form ->
+
+ form.vhndDate = vhndDate.value!!
+ form.place = getEnglishValueInArray(R.array.place_of_vhsnc, place.value)
+ form.vhndPlaceId = place.getPosition()
+ form.noOfBeneficiariesAttended = noOfBeneficiariesAttended.value!!.toInt()
+ if (BuildConfig.FLAVOR.contains("mitanin", ignoreCase = true)) {
+ form.pregnantWomenAnc = noOfPWAttended.value?.takeUnless { it.isBlank() } ?: "0"
+ form.lactatingMothersPnc = noOflactingMotherAttended.value?.takeUnless { it.isBlank() } ?: "0"
+ form.childrenImmunization = noOfchildrenAttended.value?.takeUnless { it.isBlank() } ?: "0"
+ form.knowledgeBalancedDiet = toCsv(knowOfBalanceDiet.value,knowOfBalanceDiet.entries!!)
+ form.careDuringPregnancy = toCsv(careDuringPregnancy.value,careDuringPregnancy.entries!!)
+ form.importanceBreastfeeding = toCsv(importBreastFeeding.value,importBreastFeeding.entries!!)
+ form.complementaryFeeding = toCsv(complementFeeding.value,complementFeeding.entries!!)
+ form.hygieneSanitation = toCsv(hygieneSenitation.value,hygieneSenitation.entries!!)
+ form.familyPlanningHealthcare = toCsv(fPlanning.value,fPlanning.entries!!)
+
+ }
+ form.image1 = pic1.value
+ form.image2 = pic2.value
+
+ }
+
+ }
+
+ fun setImageUriToFormElement(lastImageFormId: Int, dpUri: Uri) {
+ when (lastImageFormId) {
+ pic1.id -> {
+ pic1.value = dpUri.toString()
+ pic1.errorText = null
+ }
+
+ pic2.id -> {
+ pic2.value = dpUri.toString()
+ pic2.errorText = null
+ }
+ }
+
+ }
+ private fun toCsv(rawValue: String?, entries: Array): String {
+ return parseSelections(rawValue, entries).joinToString("|")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/dynamicDataSet/FormField.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/dynamicDataSet/FormField.kt
new file mode 100644
index 000000000..65447d403
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/dynamicDataSet/FormField.kt
@@ -0,0 +1,44 @@
+package org.piramalswasthya.sakhi.configuration.dynamicDataSet
+
+import org.piramalswasthya.sakhi.model.dynamicEntity.OptionItem
+
+data class FormField(
+ val fieldId: String,
+ val label: String,
+ val type: String,
+ var defaultValue: String? = null,
+ val isRequired: Boolean,
+ val options: List? = null,
+ var value: Any? = null,
+ var visible: Boolean = true,
+ val conditional: ConditionalLogic? = null,
+ var errorMessage: String? = null,
+ val placeholder: String? = null,
+ val validation: FieldValidation? = null,
+ var isEditable: Boolean = true
+)
+
+data class ConditionalLogic(
+ val dependsOn: String,
+ val expectedValue: String
+)
+
+data class FieldValidation(
+ val min: Float? = null,
+ val max: Float? = null,
+ var minDate: String? = null,
+ val maxDate: String? = null,
+
+ val maxLength: Int? = null,
+ val regex: String? = null,
+ val errorMessage: String? = null,
+
+ val decimalPlaces: Int? = null,
+
+ val maxSizeMB: Int? = null,
+
+ val afterField: String? = null,
+ val beforeField: String? = null
+)
+
+
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/configuration/dynamicDataSet/ReferalFormDataset.kt b/app/src/main/java/org/piramalswasthya/sakhi/configuration/dynamicDataSet/ReferalFormDataset.kt
new file mode 100644
index 000000000..0173c6c2a
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/configuration/dynamicDataSet/ReferalFormDataset.kt
@@ -0,0 +1,112 @@
+package org.piramalswasthya.sakhi.configuration.dynamicDataSet
+import android.content.Context
+import android.text.InputType
+import org.piramalswasthya.sakhi.R
+import org.piramalswasthya.sakhi.configuration.Dataset
+import org.piramalswasthya.sakhi.configuration.FormDataModel
+import org.piramalswasthya.sakhi.database.shared_preferences.PreferenceDao
+import org.piramalswasthya.sakhi.helpers.Languages
+import org.piramalswasthya.sakhi.model.FormElement
+import org.piramalswasthya.sakhi.model.InputType.DATE_PICKER
+import org.piramalswasthya.sakhi.model.InputType.DROPDOWN
+import org.piramalswasthya.sakhi.model.ReferalCache
+
+class ReferalFormDataset(context: Context, language: Languages,var preferenceDao: PreferenceDao) : Dataset(context, language) {
+
+ private val healthCenter = FormElement(
+ id = 1,
+ inputType = DROPDOWN,
+ title = resources.getString(R.string.higher_healthcare_center),
+ arrayId = R.array.referal_health_center_array,
+ entries = resources.getStringArray(R.array.referal_health_center_array),
+ required = true,
+ hasDependants = true
+ )
+ private val reasonForReferal = FormElement(
+ id = 2,
+ inputType = org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW,
+ title = resources.getString(R.string.referral_reason),
+ arrayId = -1,
+ required = false,
+
+ )
+
+ private val additionalService = FormElement(
+ id = 3,
+ inputType = org.piramalswasthya.sakhi.model.InputType.TEXT_VIEW,
+ title = resources.getString(R.string.additional_services),
+ value = "FLW",
+ arrayId = -1,
+ required = true,
+ etInputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL,
+ )
+
+ private val referDate = FormElement(
+ id = 4,
+ inputType = DATE_PICKER,
+ title = resources.getString(R.string.refer_date),
+ arrayId = -1,
+ required = true,
+ isEnabled = false,
+ min = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000),
+ max = System.currentTimeMillis(),
+ )
+
+ var referralTypes = ""
+ suspend fun setUpPage(referral : String , referralType : String) {
+ val list = mutableListOf(
+ healthCenter,
+ reasonForReferal,
+ referDate
+ )
+ referralTypes = referralType
+ referDate.value = getDateFromLong(System.currentTimeMillis())
+ reasonForReferal.value = referral
+ setUpPage(list)
+ }
+
+ override suspend fun handleListOnValueChanged(
+ formId: Int,
+ index: Int
+ ): Int {
+ return when (formId) {
+ reasonForReferal.id -> {
+ validateEmptyOnEditText(reasonForReferal)
+ }
+ healthCenter.id -> {
+ validateEmptyOnEditText(healthCenter)
+ }
+
+ else -> {
+ -1
+ }
+ }
+
+
+
+ }
+
+ override fun mapValues(
+ cacheModel: FormDataModel,
+ pageNumber: Int
+ ) {
+ (cacheModel as ReferalCache).let { form ->
+ form.revisitDate = getLongFromDate(referDate.value)
+ form.referralReason = reasonForReferal.value
+ form.refrredToAdditionalServiceList = listOf("FLW")
+ form.referredToInstituteID = healthCenter.getPosition()
+ form.referredToInstituteName = healthCenter.getEnglishStringFromPosition(healthCenter.getPosition())
+ form.createdBy = preferenceDao.getLoggedInUser()?.userName
+ form.vanID = preferenceDao.getLoggedInUser()?.vanId
+ form.providerServiceMapID = preferenceDao.getLoggedInUser()?.serviceMapId
+ form.parkingPlaceID = preferenceDao.getLoggedInUser()?.serviceMapId
+ form.type = referralTypes
+
+
+
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/crypt/CryptoUtil.kt b/app/src/main/java/org/piramalswasthya/sakhi/crypt/CryptoUtil.kt
index 9ea31d40d..aa7c04e36 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/crypt/CryptoUtil.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/crypt/CryptoUtil.kt
@@ -1,6 +1,7 @@
package org.piramalswasthya.sakhi.crypt
import android.util.Base64
+import org.piramalswasthya.sakhi.utils.KeyUtils
import java.util.Random
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
@@ -13,7 +14,7 @@ class CryptoUtil {
private val keySize = 256
private val ivSize = 128
private val iterationCount = 1989
- private val passPhrase = "Piramal12Piramal"
+ private val passPhrase = KeyUtils.encryptedPassKey()
private fun generateKey(
salt: String,
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/converters/StringListConverter.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/converters/StringListConverter.kt
new file mode 100644
index 000000000..b650c8d0f
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/converters/StringListConverter.kt
@@ -0,0 +1,19 @@
+package org.piramalswasthya.sakhi.database.converters
+
+import androidx.room.TypeConverter
+
+class StringListConverter {
+ @TypeConverter
+ fun fromList(list: List?): String? {
+ if (list == null) return null
+ return list.joinToString(separator = "|||")
+ }
+
+ @TypeConverter
+ fun toList(value: String?): List? {
+ if (value.isNullOrBlank()) return null
+ return value.split("|||")
+ }
+}
+
+
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/converters/SyncStateConverter.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/converters/SyncStateConverter.kt
index 1525fc0be..7e05104c4 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/database/converters/SyncStateConverter.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/converters/SyncStateConverter.kt
@@ -14,4 +14,14 @@ object SyncStateConverter {
fun fromInt(value: Int): SyncState {
return SyncState.values()[value]
}
+
+ @TypeConverter
+ fun toSyncState(value: String?): SyncState? {
+ return value?.let { enumValueOf(it) }
+ }
+
+ @TypeConverter
+ fun fromSyncState(state: SyncState?): String? {
+ return state?.name
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/room/InAppDb.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/room/InAppDb.kt
index d093ebf3a..06fbf67c6 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/database/room/InAppDb.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/room/InAppDb.kt
@@ -1,13 +1,21 @@
package org.piramalswasthya.sakhi.database.room
import android.content.Context
+import android.util.Log
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+import net.zetetic.database.sqlcipher.SQLiteDatabase
+import net.zetetic.database.sqlcipher.SupportOpenHelperFactory
import org.piramalswasthya.sakhi.database.converters.LocationEntityListConverter
+import org.piramalswasthya.sakhi.database.converters.StringListConverter
import org.piramalswasthya.sakhi.database.converters.SyncStateConverter
+import org.piramalswasthya.sakhi.database.room.dao.ABHAGenratedDao
+import org.piramalswasthya.sakhi.database.room.dao.AdolescentHealthDao
+import org.piramalswasthya.sakhi.database.room.dao.AesDao
import org.piramalswasthya.sakhi.database.room.dao.BenDao
import org.piramalswasthya.sakhi.database.room.dao.BeneficiaryIdsAvailDao
import org.piramalswasthya.sakhi.database.room.dao.CbacDao
@@ -15,7 +23,9 @@ import org.piramalswasthya.sakhi.database.room.dao.CdrDao
import org.piramalswasthya.sakhi.database.room.dao.ChildRegistrationDao
import org.piramalswasthya.sakhi.database.room.dao.DeliveryOutcomeDao
import org.piramalswasthya.sakhi.database.room.dao.EcrDao
+import org.piramalswasthya.sakhi.database.room.dao.FilariaDao
import org.piramalswasthya.sakhi.database.room.dao.FpotDao
+import org.piramalswasthya.sakhi.database.room.dao.GeneralOpdDao
import org.piramalswasthya.sakhi.database.room.dao.HbncDao
import org.piramalswasthya.sakhi.database.room.dao.HbycDao
import org.piramalswasthya.sakhi.database.room.dao.HouseholdDao
@@ -23,22 +33,53 @@ import org.piramalswasthya.sakhi.database.room.dao.HrpDao
import org.piramalswasthya.sakhi.database.room.dao.ImmunizationDao
import org.piramalswasthya.sakhi.database.room.dao.IncentiveDao
import org.piramalswasthya.sakhi.database.room.dao.InfantRegDao
+import org.piramalswasthya.sakhi.database.room.dao.KalaAzarDao
+import org.piramalswasthya.sakhi.database.room.dao.LeprosyDao
+import org.piramalswasthya.sakhi.database.room.dao.MaaMeetingDao
+import org.piramalswasthya.sakhi.database.room.dao.MalariaDao
import org.piramalswasthya.sakhi.database.room.dao.MaternalHealthDao
import org.piramalswasthya.sakhi.database.room.dao.MdsrDao
+import org.piramalswasthya.sakhi.database.room.dao.MosquitoNetFormResponseDao
import org.piramalswasthya.sakhi.database.room.dao.PmjayDao
import org.piramalswasthya.sakhi.database.room.dao.PmsmaDao
import org.piramalswasthya.sakhi.database.room.dao.PncDao
+import org.piramalswasthya.sakhi.database.room.dao.ProfileDao
+import org.piramalswasthya.sakhi.database.room.dao.SaasBahuSammelanDao
import org.piramalswasthya.sakhi.database.room.dao.SyncDao
import org.piramalswasthya.sakhi.database.room.dao.TBDao
+import org.piramalswasthya.sakhi.database.room.dao.UwinDao
+import org.piramalswasthya.sakhi.database.room.dao.VLFDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.BenIfaFormResponseJsonDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.CUFYFormResponseDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.CUFYFormResponseJsonDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.EyeSurgeryFormResponseJsonDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.FilariaMDAFormResponseJsonDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.FormResponseDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.FormResponseJsonDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.FormResponseJsonDaoHBYC
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.FormSchemaDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.InfantDao
+import org.piramalswasthya.sakhi.model.ABHAModel
+import org.piramalswasthya.sakhi.helpers.DatabaseKeyManager
+import org.piramalswasthya.sakhi.helpers.RoomDbEncryptionHelper
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.FilariaMdaCampaignJsonDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.NCDReferalFormResponseJsonDao
+import org.piramalswasthya.sakhi.database.room.dao.dynamicSchemaDao.FormResponseANCJsonDao
+import org.piramalswasthya.sakhi.model.AHDCache
+import org.piramalswasthya.sakhi.model.AESScreeningCache
+import org.piramalswasthya.sakhi.model.AdolescentHealthCache
import org.piramalswasthya.sakhi.model.BenBasicCache
import org.piramalswasthya.sakhi.model.BenRegCache
import org.piramalswasthya.sakhi.model.CDRCache
import org.piramalswasthya.sakhi.model.CbacCache
import org.piramalswasthya.sakhi.model.ChildRegCache
import org.piramalswasthya.sakhi.model.DeliveryOutcomeCache
+import org.piramalswasthya.sakhi.model.DewormingCache
import org.piramalswasthya.sakhi.model.EligibleCoupleRegCache
import org.piramalswasthya.sakhi.model.EligibleCoupleTrackingCache
import org.piramalswasthya.sakhi.model.FPOTCache
+import org.piramalswasthya.sakhi.model.FilariaScreeningCache
+import org.piramalswasthya.sakhi.model.GeneralOPEDBeneficiary
import org.piramalswasthya.sakhi.model.HBNCCache
import org.piramalswasthya.sakhi.model.HBYCCache
import org.piramalswasthya.sakhi.model.HRPMicroBirthPlanCache
@@ -47,19 +88,48 @@ import org.piramalswasthya.sakhi.model.HRPNonPregnantTrackCache
import org.piramalswasthya.sakhi.model.HRPPregnantAssessCache
import org.piramalswasthya.sakhi.model.HRPPregnantTrackCache
import org.piramalswasthya.sakhi.model.HouseholdCache
+import org.piramalswasthya.sakhi.model.IRSRoundScreening
import org.piramalswasthya.sakhi.model.ImmunizationCache
import org.piramalswasthya.sakhi.model.IncentiveActivityCache
import org.piramalswasthya.sakhi.model.IncentiveRecordCache
import org.piramalswasthya.sakhi.model.InfantRegCache
+import org.piramalswasthya.sakhi.model.KalaAzarScreeningCache
+import org.piramalswasthya.sakhi.model.LeprosyFollowUpCache
+import org.piramalswasthya.sakhi.model.LeprosyScreeningCache
import org.piramalswasthya.sakhi.model.MDSRCache
+import org.piramalswasthya.sakhi.model.MalariaConfirmedCasesCache
+import org.piramalswasthya.sakhi.model.MalariaScreeningCache
+import org.piramalswasthya.sakhi.model.PHCReviewMeetingCache
import org.piramalswasthya.sakhi.model.PMJAYCache
import org.piramalswasthya.sakhi.model.PMSMACache
import org.piramalswasthya.sakhi.model.PNCVisitCache
import org.piramalswasthya.sakhi.model.PregnantWomanAncCache
import org.piramalswasthya.sakhi.model.PregnantWomanRegistrationCache
+import org.piramalswasthya.sakhi.model.ProfileActivityCache
+import org.piramalswasthya.sakhi.model.ReferalCache
+import org.piramalswasthya.sakhi.model.SaasBahuSammelanCache
import org.piramalswasthya.sakhi.model.TBScreeningCache
import org.piramalswasthya.sakhi.model.TBSuspectedCache
+import org.piramalswasthya.sakhi.model.UwinCache
+import org.piramalswasthya.sakhi.model.MaaMeetingEntity
+import org.piramalswasthya.sakhi.model.TBConfirmedTreatmentCache
import org.piramalswasthya.sakhi.model.Vaccine
+import org.piramalswasthya.sakhi.model.PulsePolioCampaignCache
+import org.piramalswasthya.sakhi.model.ORSCampaignCache
+import org.piramalswasthya.sakhi.model.VHNCCache
+import org.piramalswasthya.sakhi.model.dynamicEntity.CUFYFormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.FilariaMDA.FilariaMDAFormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.FormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.FormSchemaEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.InfantEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.hbyc.FormResponseJsonEntityHBYC
+import org.piramalswasthya.sakhi.model.VHNDCache
+import org.piramalswasthya.sakhi.model.dynamicEntity.NCDReferalFormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.anc.ANCFormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.ben_ifa.BenIfaFormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.eye_surgery.EyeSurgeryFormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.filariaaMdaCampaign.FilariaMDACampaignFormResponseJsonEntity
+import org.piramalswasthya.sakhi.model.dynamicEntity.mosquitonetEntity.MosquitoNetFormResponseJsonEntity
@Database(
entities = [
@@ -94,18 +164,60 @@ import org.piramalswasthya.sakhi.model.Vaccine
//INCENTIVES
IncentiveActivityCache::class,
IncentiveRecordCache::class,
+ VHNDCache::class,
+ VHNCCache::class,
+ PHCReviewMeetingCache::class,
+ AHDCache::class,
+ DewormingCache::class,
+ PulsePolioCampaignCache::class,
+ ORSCampaignCache::class,
+ MalariaScreeningCache::class,
+ AESScreeningCache::class,
+ KalaAzarScreeningCache::class,
+ FilariaScreeningCache::class,
+ LeprosyScreeningCache::class,
+ LeprosyFollowUpCache::class,
+ MalariaConfirmedCasesCache::class,
+ IRSRoundScreening::class,
+ ProfileActivityCache::class,
+ AdolescentHealthCache::class,
+ ABHAModel::class,
+ //Dynamic Data
+ InfantEntity::class,
+ FormSchemaEntity::class,
+ SaasBahuSammelanCache::class,
+ MaaMeetingEntity::class,
+ FormResponseJsonEntity::class,
+ FormResponseJsonEntityHBYC::class,
+ CUFYFormResponseJsonEntity::class,
+ NCDReferalFormResponseJsonEntity::class,
+ GeneralOPEDBeneficiary::class,
+ ReferalCache::class,
+ UwinCache::class,
+ EyeSurgeryFormResponseJsonEntity::class,
+ BenIfaFormResponseJsonEntity::class,
+ MosquitoNetFormResponseJsonEntity::class,
+ FilariaMDAFormResponseJsonEntity::class,
+ ANCFormResponseJsonEntity::class,
+ FilariaMDACampaignFormResponseJsonEntity::class,
+ TBConfirmedTreatmentCache::class
],
views = [BenBasicCache::class],
- version = 14, exportSchema = false
+ version = 57, exportSchema = false
)
-@TypeConverters(LocationEntityListConverter::class, SyncStateConverter::class)
+@TypeConverters(
+ LocationEntityListConverter::class,
+ SyncStateConverter::class,
+ StringListConverter::class
+)
abstract class InAppDb : RoomDatabase() {
abstract val benIdGenDao: BeneficiaryIdsAvailDao
abstract val householdDao: HouseholdDao
abstract val benDao: BenDao
+ abstract val adolescentHealthDao: AdolescentHealthDao
abstract val cbacDao: CbacDao
abstract val cdrDao: CdrDao
abstract val mdsrDao: MdsrDao
@@ -124,6 +236,36 @@ abstract class InAppDb : RoomDatabase() {
abstract val infantRegDao: InfantRegDao
abstract val childRegistrationDao: ChildRegistrationDao
abstract val incentiveDao: IncentiveDao
+ abstract val vlfDao: VLFDao
+ abstract val malariaDao: MalariaDao
+ abstract val aesDao: AesDao
+ abstract val kalaAzarDao: KalaAzarDao
+ abstract val leprosyDao: LeprosyDao
+ abstract val filariaDao: FilariaDao
+ abstract val profileDao: ProfileDao
+ abstract val abhaGenratedDao: ABHAGenratedDao
+ abstract val saasBahuSammelanDao: SaasBahuSammelanDao
+ abstract val generalOpdDao: GeneralOpdDao
+ abstract val maaMeetingDao: MaaMeetingDao
+ abstract val uwinDao: UwinDao
+
+ abstract val referalDao: NcdReferalDao
+
+ abstract fun infantDao(): InfantDao
+ abstract fun formSchemaDao(): FormSchemaDao
+ abstract fun formResponseDao(): FormResponseDao
+ abstract fun CUFYFormResponseDao(): CUFYFormResponseDao
+ abstract fun CUFYFormResponseJsonDao(): CUFYFormResponseJsonDao
+ abstract fun NCDReferalFormResponseJsonDao(): NCDReferalFormResponseJsonDao
+ abstract fun formResponseJsonDao(): FormResponseJsonDao
+ abstract fun formResponseJsonDaoHBYC(): FormResponseJsonDaoHBYC
+
+ abstract fun formResponseJsonDaoANC() : FormResponseANCJsonDao
+ abstract fun formResponseJsonDaoEyeSurgery(): EyeSurgeryFormResponseJsonDao
+ abstract fun formResponseJsonDaoBenIfa(): BenIfaFormResponseJsonDao
+ abstract fun formResponseMosquitoNetJsonDao(): MosquitoNetFormResponseDao
+ abstract fun formResponseFilariaMDAJsonDao(): FilariaMDAFormResponseJsonDao
+ abstract fun formResponseFilariaMDACampaignJsonDao(): FilariaMdaCampaignJsonDao
abstract val syncDao: SyncDao
@@ -131,10 +273,2658 @@ abstract class InAppDb : RoomDatabase() {
@Volatile
private var INSTANCE: InAppDb? = null
+ fun tableExists(db: SupportSQLiteDatabase, tableName: String): Boolean {
+ val cursor = db.query(
+ "SELECT name FROM sqlite_master WHERE type='table' AND name=?",
+ arrayOf(tableName)
+ )
+ val exists = cursor.count > 0
+ cursor.close()
+ return exists
+ }
+
+ fun columnExists(
+ db: SupportSQLiteDatabase,
+ tableName: String,
+ columnName: String
+ ): Boolean {
+ val cursor = db.query("PRAGMA table_info($tableName)")
+ while (cursor.moveToNext()) {
+ if (cursor.getString(cursor.getColumnIndexOrThrow("name")) == columnName) {
+ cursor.close()
+ return true
+ }
+ }
+ cursor.close()
+ return false
+ }
+
+
fun getInstance(appContext: Context): InAppDb {
- val MIGRATION_1_2 = Migration(1, 2, migrate = {
-// it.execSQL("select count(*) from beneficiary")
+ val MIGRATION_1_2 = Migration(18, 19, migrate = {
+ it.execSQL("alter table BEN_BASIC_CACHE add column isConsent BOOL")
+ it.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN newColumn TEXT DEFAULT 'undefined'")
+ it.execSQL(
+ "ALTER TABLE BENEFICIARY ADD COLUMN kid_isConsent INTEGER DEFAULT 0"
+ )
+
+ })
+
+ val MIGRATION_56_57 = object : Migration(56, 57) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ val householdLocColumns = listOf(
+ "loc_country_id INTEGER NOT NULL DEFAULT 0",
+ "loc_country_name TEXT NOT NULL DEFAULT ''",
+ "loc_country_nameHindi TEXT",
+ "loc_country_nameAssamese TEXT",
+ "loc_state_id INTEGER NOT NULL DEFAULT 0",
+ "loc_state_name TEXT NOT NULL DEFAULT ''",
+ "loc_state_nameHindi TEXT",
+ "loc_state_nameAssamese TEXT",
+ "loc_district_id INTEGER NOT NULL DEFAULT 0",
+ "loc_district_name TEXT NOT NULL DEFAULT ''",
+ "loc_district_nameHindi TEXT",
+ "loc_district_nameAssamese TEXT",
+ "loc_block_id INTEGER NOT NULL DEFAULT 0",
+ "loc_block_name TEXT NOT NULL DEFAULT ''",
+ "loc_block_nameHindi TEXT",
+ "loc_block_nameAssamese TEXT",
+ "loc_village_id INTEGER NOT NULL DEFAULT 0",
+ "loc_village_name TEXT NOT NULL DEFAULT ''",
+ "loc_village_nameHindi TEXT",
+ "loc_village_nameAssamese TEXT"
+ )
+ for (column in householdLocColumns) {
+ val columnName = column.split(" ")[0]
+ if (!columnExists(database, "HOUSEHOLD", columnName)) {
+ database.execSQL("ALTER TABLE HOUSEHOLD ADD COLUMN $column")
+ }
+ }
+ if (!columnExists(database, "HOUSEHOLD", "isDeactivate")) {
+ database.execSQL("ALTER TABLE HOUSEHOLD ADD COLUMN isDeactivate INTEGER NOT NULL DEFAULT 0")
+ }
+
+ if (!columnExists(database, "BENEFICIARY", "isSpouseAdded")) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isSpouseAdded INTEGER NOT NULL DEFAULT 0")
+ }
+ if (!columnExists(database, "BENEFICIARY", "isChildrenAdded")) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isChildrenAdded INTEGER NOT NULL DEFAULT 0")
+ }
+ if (!columnExists(database, "BENEFICIARY", "isMarried")) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isMarried INTEGER NOT NULL DEFAULT 0")
+ }
+ if (!columnExists(database, "BENEFICIARY", "noOfChildren")) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN noOfChildren INTEGER NOT NULL DEFAULT 0")
+ }
+ if (!columnExists(database, "BENEFICIARY", "noOfAliveChildren")) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN noOfAliveChildren INTEGER NOT NULL DEFAULT 0")
+ }
+ if (!columnExists(database, "BENEFICIARY", "doYouHavechildren")) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN doYouHavechildren INTEGER NOT NULL DEFAULT 0")
+ }
+ if (!columnExists(database, "BENEFICIARY", "isDeactivate")) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isDeactivate INTEGER NOT NULL DEFAULT 0")
+ }
+
+ // Update isMarried based on existing gen_maritalStatusId data.
+ database.execSQL("""
+ UPDATE BENEFICIARY
+ SET isMarried = CASE
+ WHEN gen_maritalStatusId = 2 THEN 1
+ ELSE 0
+ END
+ WHERE isMarried = 0
+ """.trimIndent())
+
+ // ========================================================
+ // 2b. PREGNANCY_ANC: add placeOfAnc columns
+ // (added to MIGRATION_45_46 after release-2.7,
+ // so users upgrading from v46 never got them)
+ // ========================================================
+ if (!columnExists(database, "PREGNANCY_ANC", "placeOfAnc")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN placeOfAnc TEXT")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "placeOfAncId")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN placeOfAncId INTEGER")
+ }
+
+ // ========================================================
+ // 3. CREATE new tables
+ // ========================================================
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `PulsePolioCampaign` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `formDataJson` TEXT,
+ `syncState` INTEGER NOT NULL DEFAULT 0
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `ORSCampaign` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `formDataJson` TEXT,
+ `syncState` INTEGER NOT NULL DEFAULT 0
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `TB_CONFIRMED_TREATMENT` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `benId` INTEGER NOT NULL,
+ `regimenType` TEXT,
+ `treatmentStartDate` INTEGER NOT NULL,
+ `expectedTreatmentCompletionDate` INTEGER,
+ `followUpDate` INTEGER,
+ `monthlyFollowUpDone` TEXT,
+ `adherenceToMedicines` TEXT,
+ `anyDiscomfort` INTEGER,
+ `treatmentCompleted` INTEGER,
+ `actualTreatmentCompletionDate` INTEGER,
+ `treatmentOutcome` TEXT,
+ `dateOfDeath` INTEGER,
+ `placeOfDeath` TEXT,
+ `reasonForDeath` TEXT NOT NULL DEFAULT 'Tuberculosis',
+ `reasonForNotCompleting` TEXT,
+ `syncState` INTEGER NOT NULL DEFAULT 0,
+ `createdAt` INTEGER NOT NULL,
+ `updatedAt` INTEGER NOT NULL,
+ FOREIGN KEY(`benId`) REFERENCES `BENEFICIARY`(`beneficiaryId`) ON UPDATE CASCADE ON DELETE CASCADE
+ )
+ """.trimIndent()
+ )
+ database.execSQL("CREATE INDEX IF NOT EXISTS `ind_tb_confirmed` ON `TB_CONFIRMED_TREATMENT` (`benId`)")
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `ALL_VISIT_HISTORY_ANC` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `benId` INTEGER NOT NULL,
+ `visitDay` TEXT NOT NULL,
+ `visitDate` TEXT NOT NULL,
+ `formId` TEXT NOT NULL,
+ `version` INTEGER NOT NULL,
+ `formDataJson` TEXT NOT NULL,
+ `isSynced` INTEGER NOT NULL DEFAULT 0,
+ `createdAt` INTEGER NOT NULL,
+ `syncedAt` INTEGER
+ )
+ """.trimIndent()
+ )
+ database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_ALL_VISIT_HISTORY_ANC_benId_visitDay_visitDate_formId` ON `ALL_VISIT_HISTORY_ANC` (`benId`, `visitDay`, `visitDate`, `formId`)")
+
+ // ========================================================
+ // 4. TB_SCREENING: add 11 new columns
+ // ========================================================
+ val tbScreeningColumns = listOf(
+ "riseOfFever INTEGER",
+ "lossOfAppetite INTEGER",
+ "age INTEGER",
+ "diabetic INTEGER",
+ "tobaccoUser INTEGER",
+ "bmi INTEGER",
+ "contactWithTBPatient INTEGER",
+ "historyOfTBInLastFiveYrs INTEGER",
+ "sympotomatic TEXT",
+ "asymptomatic TEXT",
+ "recommandateTest TEXT"
+ )
+ for (column in tbScreeningColumns) {
+ val columnName = column.split(" ")[0]
+ if (!columnExists(database, "TB_SCREENING", columnName)) {
+ database.execSQL("ALTER TABLE TB_SCREENING ADD COLUMN $column")
+ }
+ }
+
+ // ========================================================
+ // 5. VHNC: recreate table to fix wrong-name columns
+ // MIGRATION_48_49 added noOfPregnantWomen,
+ // noOfLactatingMother, followupPrevious (wrong names).
+ // Entity expects noOfPragnentWoment, noOfLactingMother,
+ // followupPrevius. Room requires exact column match,
+ // so extra columns cause failure. Recreate the table.
+ // ========================================================
+ if (tableExists(database, "VHNC")) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `VHNC_new` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `vhncDate` TEXT NOT NULL,
+ `place` TEXT,
+ `noOfBeneficiariesAttended` INTEGER,
+ `image1` TEXT,
+ `image2` TEXT,
+ `villageName` TEXT,
+ `anm` INTEGER,
+ `aww` INTEGER,
+ `noOfPragnentWoment` INTEGER DEFAULT 0,
+ `noOfLactingMother` INTEGER DEFAULT 0,
+ `noOfCommittee` INTEGER DEFAULT 0,
+ `followupPrevius` INTEGER,
+ `syncState` INTEGER NOT NULL DEFAULT 0
+ )
+ """.trimIndent()
+ )
+ // Copy data, preferring correctly-named columns if they exist,
+ // falling back to wrong-named columns from MIGRATION_48_49
+ val hasCorrectPragnent = columnExists(database, "VHNC", "noOfPragnentWoment")
+ val hasWrongPregnant = columnExists(database, "VHNC", "noOfPregnantWomen")
+ val hasCorrectLacting = columnExists(database, "VHNC", "noOfLactingMother")
+ val hasWrongLactating = columnExists(database, "VHNC", "noOfLactatingMother")
+ val hasCorrectFollowup = columnExists(database, "VHNC", "followupPrevius")
+ val hasWrongFollowup = columnExists(database, "VHNC", "followupPrevious")
+
+ val pragnentSrc = when {
+ hasCorrectPragnent -> "`noOfPragnentWoment`"
+ hasWrongPregnant -> "`noOfPregnantWomen`"
+ else -> "0"
+ }
+ val lactingSrc = when {
+ hasCorrectLacting -> "`noOfLactingMother`"
+ hasWrongLactating -> "`noOfLactatingMother`"
+ else -> "0"
+ }
+ val followupSrc = when {
+ hasCorrectFollowup -> "`followupPrevius`"
+ hasWrongFollowup -> "`followupPrevious`"
+ else -> "NULL"
+ }
+
+ database.execSQL(
+ """
+ INSERT INTO `VHNC_new`
+ (`id`, `vhncDate`, `place`, `noOfBeneficiariesAttended`,
+ `image1`, `image2`, `villageName`, `anm`, `aww`,
+ `noOfPragnentWoment`, `noOfLactingMother`, `noOfCommittee`,
+ `followupPrevius`, `syncState`)
+ SELECT `id`, `vhncDate`, `place`, `noOfBeneficiariesAttended`,
+ `image1`, `image2`,
+ ${if (columnExists(database, "VHNC", "villageName")) "`villageName`" else "NULL"},
+ ${if (columnExists(database, "VHNC", "anm")) "`anm`" else "NULL"},
+ ${if (columnExists(database, "VHNC", "aww")) "`aww`" else "NULL"},
+ $pragnentSrc,
+ $lactingSrc,
+ ${if (columnExists(database, "VHNC", "noOfCommittee")) "`noOfCommittee`" else "0"},
+ $followupSrc,
+ `syncState`
+ FROM `VHNC`
+ """.trimIndent()
+ )
+ database.execSQL("DROP TABLE `VHNC`")
+ database.execSQL("ALTER TABLE `VHNC_new` RENAME TO `VHNC`")
+ } else {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `VHNC` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `vhncDate` TEXT NOT NULL,
+ `place` TEXT,
+ `noOfBeneficiariesAttended` INTEGER,
+ `image1` TEXT,
+ `image2` TEXT,
+ `villageName` TEXT,
+ `anm` INTEGER,
+ `aww` INTEGER,
+ `noOfPragnentWoment` INTEGER DEFAULT 0,
+ `noOfLactingMother` INTEGER DEFAULT 0,
+ `noOfCommittee` INTEGER DEFAULT 0,
+ `followupPrevius` INTEGER,
+ `syncState` INTEGER NOT NULL DEFAULT 0
+ )
+ """.trimIndent()
+ )
+ }
+
+ // ========================================================
+ // 6. NCD_REFER: fix unique index (benId) -> (benId, referralReason)
+ // ========================================================
+ database.execSQL("DROP INDEX IF EXISTS `ind_refcache`")
+ database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `ind_refcache` ON `NCD_REFER` (`benId`, `referralReason`)")
+
+ // ========================================================
+ // 7. ncd_referal_all_visit: fix index names + uniqueness
+ // (MIGRATION_49_50 used wrong names and missed UNIQUE)
+ // ========================================================
+ if (tableExists(database, "ncd_referal_all_visit")) {
+ database.execSQL("DROP INDEX IF EXISTS `index_ncd_visit_ben_hh`")
+ database.execSQL("DROP INDEX IF EXISTS `index_ncd_visit_followup`")
+ database.execSQL("DROP INDEX IF EXISTS `index_ncd_referal_all_visit_benId_hhId`")
+ database.execSQL("DROP INDEX IF EXISTS `index_ncd_referal_all_visit_benId_hhId_visitNo_followUpNo`")
+ database.execSQL("CREATE INDEX IF NOT EXISTS `index_ncd_referal_all_visit_benId_hhId` ON `ncd_referal_all_visit` (`benId`, `hhId`)")
+ database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_ncd_referal_all_visit_benId_hhId_visitNo_followUpNo` ON `ncd_referal_all_visit` (`benId`, `hhId`, `visitNo`, `followUpNo`)")
+ }
+
+ // ========================================================
+ // 8. MAA_MEETING: add 4 missing columns
+ // (MIGRATION_51_52 used CREATE TABLE IF NOT EXISTS which
+ // is a no-op since the table already existed from v29)
+ // ========================================================
+ if (tableExists(database, "MAA_MEETING")) {
+ if (!columnExists(database, "MAA_MEETING", "villageName")) {
+ database.execSQL("ALTER TABLE MAA_MEETING ADD COLUMN villageName TEXT")
+ }
+ if (!columnExists(database, "MAA_MEETING", "mitaninActivityCheckList")) {
+ database.execSQL("ALTER TABLE MAA_MEETING ADD COLUMN mitaninActivityCheckList TEXT")
+ }
+ if (!columnExists(database, "MAA_MEETING", "noOfPragnentWomen")) {
+ database.execSQL("ALTER TABLE MAA_MEETING ADD COLUMN noOfPragnentWomen TEXT")
+ }
+ if (!columnExists(database, "MAA_MEETING", "noOfLactingMother")) {
+ database.execSQL("ALTER TABLE MAA_MEETING ADD COLUMN noOfLactingMother TEXT")
+ }
+ }
+
+ // ========================================================
+ // 9. FILARIA_MDA_CAMPAIGN_HISTORY: fix column types
+ // (MIGRATION_52_53 used syncState TEXT instead of INTEGER,
+ // and isSynced nullable instead of NOT NULL)
+ // ========================================================
+ if (tableExists(database, "FILARIA_MDA_CAMPAIGN_HISTORY")) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `FILARIA_MDA_CAMPAIGN_HISTORY_new` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `visitDate` TEXT NOT NULL,
+ `visitYear` TEXT NOT NULL,
+ `formId` TEXT NOT NULL,
+ `version` INTEGER NOT NULL,
+ `formDataJson` TEXT NOT NULL,
+ `isSynced` INTEGER NOT NULL DEFAULT 0,
+ `syncState` INTEGER NOT NULL DEFAULT 0,
+ `createdAt` INTEGER NOT NULL,
+ `syncedAt` TEXT
+ )
+ """.trimIndent()
+ )
+ database.execSQL(
+ """
+ INSERT OR IGNORE INTO `FILARIA_MDA_CAMPAIGN_HISTORY_new`
+ (`id`, `visitDate`, `visitYear`, `formId`, `version`, `formDataJson`,
+ `isSynced`, `syncState`, `createdAt`, `syncedAt`)
+ SELECT `id`, `visitDate`, `visitYear`, `formId`, `version`, `formDataJson`,
+ COALESCE(`isSynced`, 0),
+ CASE WHEN typeof(`syncState`) = 'text' THEN
+ CASE WHEN `syncState` = 'SYNCED' THEN 2
+ WHEN `syncState` = 'SYNCING' THEN 1
+ ELSE 0 END
+ ELSE COALESCE(`syncState`, 0) END,
+ `createdAt`, `syncedAt`
+ FROM `FILARIA_MDA_CAMPAIGN_HISTORY`
+ """.trimIndent()
+ )
+ database.execSQL("DROP TABLE `FILARIA_MDA_CAMPAIGN_HISTORY`")
+ database.execSQL("ALTER TABLE `FILARIA_MDA_CAMPAIGN_HISTORY_new` RENAME TO `FILARIA_MDA_CAMPAIGN_HISTORY`")
+ } else {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `FILARIA_MDA_CAMPAIGN_HISTORY` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `visitDate` TEXT NOT NULL,
+ `visitYear` TEXT NOT NULL,
+ `formId` TEXT NOT NULL,
+ `version` INTEGER NOT NULL,
+ `formDataJson` TEXT NOT NULL,
+ `isSynced` INTEGER NOT NULL DEFAULT 0,
+ `syncState` INTEGER NOT NULL DEFAULT 0,
+ `createdAt` INTEGER NOT NULL,
+ `syncedAt` TEXT
+ )
+ """.trimIndent()
+ )
+ }
+ database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_FILARIA_MDA_CAMPAIGN_HISTORY_formId_visitYear` ON `FILARIA_MDA_CAMPAIGN_HISTORY` (`formId`, `visitYear`)")
+ database.execSQL("CREATE INDEX IF NOT EXISTS `index_FILARIA_MDA_CAMPAIGN_HISTORY_visitDate` ON `FILARIA_MDA_CAMPAIGN_HISTORY` (`visitDate`)")
+
+ // ========================================================
+ // 10. BEN_BASIC_CACHE: drop and recreate view
+ // (MIGRATION_45_46 reverted 6 columns from 44_45,
+ // and isDeactivate was never added to the view)
+ // ========================================================
+ database.execSQL("DROP VIEW IF EXISTS `BEN_BASIC_CACHE`")
+ database.execSQL(
+ """CREATE VIEW `BEN_BASIC_CACHE` AS SELECT b.beneficiaryId as benId,b.isMarried,b.noOfAliveChildren, b.noOfChildren, b.doYouHavechildren ,b.isConsent as isConsent, b.motherName as motherName, b.householdId as hhId, b.regDate, b.firstName as benName, b.lastName as benSurname, b.gender, b.dob as dob,b.isDeactivate, b.isDeath,b.isDeathValue,b.dateOfDeath,b.timeOfDeath,b.reasonOfDeath,b.reasonOfDeathId,b.placeOfDeath,b.placeOfDeathId,b.otherPlaceOfDeath,b.isSpouseAdded,b.isChildrenAdded, b.familyHeadRelationPosition as relToHeadId, b.contactNumber as mobileNo, b.fatherName,h.fam_familyHeadName as familyHeadName, b.gen_spouseName as spouseName, b.rchId, b.gen_lastMenstrualPeriod as lastMenstrualPeriod, b.isHrpStatus as hrpStatus, b.syncState, b.gen_reproductiveStatusId as reproductiveStatusId, b.isKid, b.immunizationStatus, b.loc_village_id as villageId, b.abha_healthIdNumber as abhaId, b.isNewAbha, IFNULL(cbac.benId IS NOT NULL, 0) as cbacFilled, cbac.syncState as cbacSyncState, IFNULL(cdr.benId IS NOT NULL, 0) as cdrFilled, cdr.syncState as cdrSyncState, IFNULL(mdsr.benId IS NOT NULL, 0) as mdsrFilled, mdsr.syncState as mdsrSyncState, IFNULL(pmsma.benId IS NOT NULL, 0) as pmsmaFilled, pmsma.syncState as pmsmaSyncState, IFNULL(hbnc.benId IS NOT NULL, 0) as hbncFilled, IFNULL(hbyc.benId IS NOT NULL, 0) as hbycFilled, IFNULL(pwr.benId IS NOT NULL, 0) as pwrFilled, pwr.syncState as pwrSyncState, IFNULL(pwa.pregnantWomanDelivered, 0) as isDelivered, IFNULL(pwa.hrpConfirmed, 0) as pwHrp, IFNULL(ecr.benId IS NOT NULL, 0) as ecrFilled, IFNULL(ect.benId IS NOT NULL, 0) as ectFilled, IFNULL((pwa.maternalDeath OR do.complication = 'DEATH' OR pnc.motherDeath), 0) as isMdsr, IFNULL(tbsn.benId IS NOT NULL, 0) as tbsnFilled, tbsn.syncState as tbsnSyncState, IFNULL(tbsp.benId IS NOT NULL, 0) as tbspFilled, tbsp.syncState as tbspSyncState, IFNULL(ir.motherBenId IS NOT NULL, 0) as irFilled, ir.syncState as irSyncState, IFNULL(cr.motherBenId IS NOT NULL, 0) as crFilled, cr.syncState as crSyncState, IFNULL(do.benId IS NOT NULL, 0) as doFilled, do.syncState as doSyncState, IFNULL((hrppa.benId IS NOT NULL AND hrppa.noOfDeliveries IS NOT NULL AND hrppa.timeLessThan18m IS NOT NULL AND hrppa.heightShort IS NOT NULL AND hrppa.age IS NOT NULL AND hrppa.rhNegative IS NOT NULL AND hrppa.homeDelivery IS NOT NULL AND hrppa.badObstetric IS NOT NULL AND hrppa.multiplePregnancy IS NOT NULL), 0) as hrppaFilled, hrppa.syncState as hrppaSyncState, IFNULL((hrpnpa.benId IS NOT NULL AND hrpnpa.noOfDeliveries IS NOT NULL AND hrpnpa.timeLessThan18m IS NOT NULL AND hrpnpa.heightShort IS NOT NULL AND hrpnpa.age IS NOT NULL AND hrpnpa.misCarriage IS NOT NULL AND hrpnpa.homeDelivery IS NOT NULL AND hrpnpa.medicalIssues IS NOT NULL AND hrpnpa.pastCSection IS NOT NULL), 0) as hrpnpaFilled, hrpnpa.syncState as hrpnpaSyncState, IFNULL(hrpmbp.benId IS NOT NULL, 0) as hrpmbpFilled, hrpmbp.syncState as hrpmbpSyncState, IFNULL(hrpt.benId IS NOT NULL, 0) as hrptFilled, IFNULL(((count(distinct hrpt.id) > 3) OR (((JulianDay('now')) - JulianDay(date(max(hrpt.visitDate)/1000,'unixepoch','localtime'))) < 1)), 0) as hrptrackingDone, hrpt.syncState as hrptSyncState, IFNULL(hrnpt.benId IS NOT NULL, 0) as hrnptFilled, IFNULL(((JulianDay('now') - JulianDay(date(max(hrnpt.visitDate)/1000,'unixepoch','localtime'))) < 1), 0) as hrnptrackingDone, hrnpt.syncState as hrnptSyncState FROM BENEFICIARY b JOIN HOUSEHOLD h ON b.householdId = h.householdId LEFT OUTER JOIN CBAC cbac ON b.beneficiaryId = cbac.benId LEFT OUTER JOIN CDR cdr ON b.beneficiaryId = cdr.benId LEFT OUTER JOIN MDSR mdsr ON b.beneficiaryId = mdsr.benId LEFT OUTER JOIN PMSMA pmsma ON b.beneficiaryId = pmsma.benId LEFT OUTER JOIN HBNC hbnc ON b.beneficiaryId = hbnc.benId LEFT OUTER JOIN HBYC hbyc ON b.beneficiaryId = hbyc.benId LEFT OUTER JOIN PREGNANCY_REGISTER pwr ON b.beneficiaryId = pwr.benId LEFT OUTER JOIN PREGNANCY_ANC pwa ON b.beneficiaryId = pwa.benId LEFT OUTER JOIN pnc_visit pnc ON b.beneficiaryId = pnc.benId LEFT OUTER JOIN ELIGIBLE_COUPLE_REG ecr ON b.beneficiaryId = ecr.benId LEFT OUTER JOIN ELIGIBLE_COUPLE_TRACKING ect ON (b.beneficiaryId = ect.benId AND CAST((strftime('%s','now') - ect.visitDate/1000)/60/60/24 AS INTEGER) < 30) LEFT OUTER JOIN TB_SCREENING tbsn ON b.beneficiaryId = tbsn.benId LEFT OUTER JOIN TB_SUSPECTED tbsp ON b.beneficiaryId = tbsp.benId LEFT OUTER JOIN MALARIA_SCREENING masp on b.beneficiaryId = masp.benId LEFT OUTER JOIN MALARIA_CONFIRMED macp on b.beneficiaryId = macp.benId LEFT OUTER JOIN HRP_PREGNANT_ASSESS hrppa ON b.beneficiaryId = hrppa.benId LEFT OUTER JOIN HRP_NON_PREGNANT_ASSESS hrpnpa ON b.beneficiaryId = hrpnpa.benId LEFT OUTER JOIN HRP_MICRO_BIRTH_PLAN hrpmbp ON b.beneficiaryId = hrpmbp.benId LEFT OUTER JOIN HRP_NON_PREGNANT_TRACK hrnpt ON b.beneficiaryId = hrnpt.benId LEFT OUTER JOIN HRP_PREGNANT_TRACK hrpt ON b.beneficiaryId = hrpt.benId LEFT OUTER JOIN DELIVERY_OUTCOME do ON b.beneficiaryId = do.benId LEFT OUTER JOIN INFANT_REG ir ON b.beneficiaryId = ir.motherBenId LEFT OUTER JOIN CHILD_REG cr ON b.beneficiaryId = cr.motherBenId WHERE b.isDraft = 0 GROUP BY b.beneficiaryId ORDER BY b.updatedDate DESC"""
+ )
+ }
+ }
+
+ val MIGRATION_55_56 = object : Migration(55, 56) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ if (!columnExists(database, "INCENTIVE_RECORD", "isEligible")) {
+ database.execSQL(
+ """
+ ALTER TABLE INCENTIVE_RECORD
+ ADD COLUMN isEligible INTEGER NOT NULL DEFAULT 0
+ """.trimIndent()
+ )
+ }
+ }
+ }
+
+
+ val MIGRATION_54_55 = object : Migration(54, 55) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ ALTER TABLE ELIGIBLE_COUPLE_TRACKING
+ ADD COLUMN dateOfSterilisation INTEGER NOT NULL DEFAULT 0
+ """.trimIndent()
+ )
+ }
+ }
+ val MIGRATION_53_54 = object : Migration(53, 54) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN visitLabel TEXT")
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN typeOfTBCase TEXT")
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN reasonForSuspicion TEXT")
+
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN hasSymptoms INTEGER NOT NULL DEFAULT 0")
+
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN isChestXRayDone INTEGER")
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN chestXRayResult TEXT")
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN referralFacility TEXT")
+
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN isTBConfirmed INTEGER")
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN isDRTBConfirmed INTEGER")
+
+ database.execSQL("ALTER TABLE TB_SUSPECTED ADD COLUMN isConfirmed INTEGER NOT NULL DEFAULT 0")
+ }
+ }
+
+ val MIGRATION_52_53 = object : Migration(52, 53) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS index_DewormingMeeting_dewormingDate
+ ON DewormingMeeting(dewormingDate)
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS FILARIA_MDA_CAMPAIGN_HISTORY (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ visitDate TEXT NOT NULL,
+ visitYear TEXT NOT NULL,
+ formId TEXT NOT NULL,
+ version INTEGER NOT NULL,
+ formDataJson TEXT NOT NULL,
+ isSynced INTEGER,
+ createdAt INTEGER NOT NULL,
+ syncedAt TEXT,
+ syncState TEXT NOT NULL DEFAULT 'UNSYNCED'
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS
+ index_FILARIA_MDA_CAMPAIGN_HISTORY_formId_visitYear
+ ON FILARIA_MDA_CAMPAIGN_HISTORY(formId, visitYear)
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS
+ index_FILARIA_MDA_CAMPAIGN_HISTORY_visitDate
+ ON FILARIA_MDA_CAMPAIGN_HISTORY(visitDate)
+ """.trimIndent()
+ )
+ }
+
+
+ }
+
+
+
+ val MIGRATION_51_52 = object : Migration(51, 52) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS MAA_MEETING (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ meetingDate TEXT,
+ place TEXT,
+ villageName TEXT,
+ mitaninActivityCheckList TEXT,
+ noOfPragnentWomen TEXT,
+ noOfLactingMother TEXT,
+ participants INTEGER,
+ ashaId INTEGER,
+ meetingImages TEXT,
+ createdAt INTEGER NOT NULL DEFAULT 0,
+ updatedAt INTEGER NOT NULL DEFAULT 0,
+ syncState TEXT NOT NULL DEFAULT 'UNSYNCED'
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ "CREATE UNIQUE INDEX IF NOT EXISTS index_MAA_MEETING_id ON MAA_MEETING(id)"
+ )
+ }
+ }
+
+
+ val MIGRATION_50_51 = Migration(50, 51, migrate = {
+ it.execSQL("alter table PHCReviewMeeting add column villageName TEXT")
+ it.execSQL("alter table PHCReviewMeeting add column mitaninHistory TEXT")
+ it.execSQL("alter table PHCReviewMeeting add column mitaninActivityCheckList TEXT")
+ it.execSQL("alter table PHCReviewMeeting add column placeId INTEGER DEFAULT 0")
+ it.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS index_PHCReviewMeeting_id
+ ON PHCReviewMeeting(id)
+ """.trimIndent()
+ )
+
+ })
+
+
+
+ val MIGRATION_49_50 = object : Migration(49, 50) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN vhndPlaceId INTEGER DEFAULT 0"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN pregnantWomenAnc TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN lactatingMothersPnc TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN childrenImmunization TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN knowledgeBalancedDiet TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN careDuringPregnancy TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN importanceBreastfeeding TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN complementaryFeeding TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN hygieneSanitation TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN familyPlanningHealthcare TEXT"
+ )
+
+ database.execSQL(
+ "ALTER TABLE VHND ADD COLUMN selectAllEducation INTEGER DEFAULT 0"
+ )
+
+ // ncd_refer
+
+ database.execSQL("DROP TABLE IF EXISTS ncd_referal_all_visit")
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `ncd_referal_all_visit` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `benId` INTEGER NOT NULL,
+ `hhId` INTEGER NOT NULL,
+ `visitNo` INTEGER NOT NULL,
+ `followUpNo` INTEGER NOT NULL,
+ `treatmentStartDate` TEXT NOT NULL,
+ `followUpDate` TEXT,
+ `diagnosisCodes` TEXT,
+ `formId` TEXT NOT NULL,
+ `version` INTEGER NOT NULL,
+ `formDataJson` TEXT NOT NULL,
+ `isSynced` INTEGER NOT NULL DEFAULT 0,
+ `createdAt` INTEGER NOT NULL,
+ `updatedAt` INTEGER NOT NULL,
+ `syncedAt` INTEGER
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS `index_ncd_visit_ben_hh`
+ ON `ncd_referal_all_visit` (`benId`, `hhId`)
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS `index_ncd_visit_followup`
+ ON `ncd_referal_all_visit` (`benId`, `hhId`, `visitNo`, `followUpNo`)
+ """.trimIndent()
+ )
+ }
+ }
+
+
+ val MIGRATION_48_49 = object : Migration(48, 49) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+
+ val columns = listOf(
+ "villageName TEXT",
+ "anm INTEGER DEFAULT 0",
+ "aww INTEGER DEFAULT 0",
+ "noOfPregnantWomen INTEGER DEFAULT 0",
+ "noOfLactatingMother INTEGER DEFAULT 0",
+ "noOfCommittee INTEGER DEFAULT 0",
+ "followupPrevious INTEGER"
+ )
+
+ columns.forEach { columnDef ->
+ db.execSQL("ALTER TABLE VHNC ADD COLUMN $columnDef")
+ }
+ }
+ }
+
+
+
+ val MIGRATION_47_48 = Migration(47, 48) {
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN recurrentUlcerationId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN recurrentTinglingId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN hypopigmentedPatchId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN thickenedSkinId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN skinNodulesId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN skinPatchDiscolorationId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN recurrentNumbnessId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN clawingFingersId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN tinglingNumbnessExtremitiesId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN inabilityCloseEyelidId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN difficultyHoldingObjectsId INTEGER DEFAULT 1")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN weaknessFeetId INTEGER DEFAULT 1")
+
+ // ===== Symptom String fields =====
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN recurrentUlceration TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN recurrentTingling TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN hypopigmentedPatch TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN thickenedSkin TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN skinNodules TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN skinPatchDiscoloration TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN recurrentNumbness TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN clawingFingers TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN tinglingNumbnessExtremities TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN inabilityCloseEyelid TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN difficultyHoldingObjects TEXT")
+ it.execSQL("ALTER TABLE LEPROSY_SCREENING ADD COLUMN weaknessFeet TEXT")
+
+ }
+ val MIGRATION_46_47 = Migration(46, 47) {
+ it.execSQL(
+ """ALTER TABLE NCD_REFER
+ ADD COLUMN type TEXT
+ """.trimIndent()
+ )
+
+ }
+
+ val MIGRATION_45_46 = Migration(45, 46) {
+ it.execSQL("DROP VIEW IF EXISTS `BEN_BASIC_CACHE`")
+ it.execSQL(
+ """
+ CREATE VIEW `BEN_BASIC_CACHE` AS SELECT b.beneficiaryId as benId, b.isConsent as isConsent, b.motherName as motherName, b.householdId as hhId, b.regDate, b.firstName as benName, b.lastName as benSurname, b.gender, b.dob as dob, b.isDeath,b.isDeathValue,b.dateOfDeath,b.timeOfDeath,b.reasonOfDeath,b.reasonOfDeathId,b.placeOfDeath,b.placeOfDeathId,b.otherPlaceOfDeath, b.familyHeadRelationPosition as relToHeadId, b.contactNumber as mobileNo, b.fatherName, h.fam_familyHeadName as familyHeadName, b.gen_spouseName as spouseName, b.rchId, b.gen_lastMenstrualPeriod as lastMenstrualPeriod, b.isHrpStatus as hrpStatus, b.syncState, b.gen_reproductiveStatusId as reproductiveStatusId, b.isKid, b.immunizationStatus, b.loc_village_id as villageId, b.abha_healthIdNumber as abhaId, b.isNewAbha, IFNULL(cbac.benId IS NOT NULL, 0) as cbacFilled, cbac.syncState as cbacSyncState, IFNULL(cdr.benId IS NOT NULL, 0) as cdrFilled, cdr.syncState as cdrSyncState, IFNULL(mdsr.benId IS NOT NULL, 0) as mdsrFilled, mdsr.syncState as mdsrSyncState, IFNULL(pmsma.benId IS NOT NULL, 0) as pmsmaFilled, pmsma.syncState as pmsmaSyncState, IFNULL(hbnc.benId IS NOT NULL, 0) as hbncFilled, IFNULL(hbyc.benId IS NOT NULL, 0) as hbycFilled, IFNULL(pwr.benId IS NOT NULL, 0) as pwrFilled, pwr.syncState as pwrSyncState, IFNULL(pwa.pregnantWomanDelivered, 0) as isDelivered, IFNULL(pwa.hrpConfirmed, 0) as pwHrp, IFNULL(ecr.benId IS NOT NULL, 0) as ecrFilled, IFNULL(ect.benId IS NOT NULL, 0) as ectFilled, IFNULL((pwa.maternalDeath OR do.complication = 'DEATH' OR pnc.motherDeath), 0) as isMdsr, IFNULL(tbsn.benId IS NOT NULL, 0) as tbsnFilled, tbsn.syncState as tbsnSyncState, IFNULL(tbsp.benId IS NOT NULL, 0) as tbspFilled, tbsp.syncState as tbspSyncState, IFNULL(ir.motherBenId IS NOT NULL, 0) as irFilled, ir.syncState as irSyncState, IFNULL(cr.motherBenId IS NOT NULL, 0) as crFilled, cr.syncState as crSyncState, IFNULL(do.benId IS NOT NULL, 0) as doFilled, do.syncState as doSyncState, IFNULL((hrppa.benId IS NOT NULL AND hrppa.noOfDeliveries IS NOT NULL AND hrppa.timeLessThan18m IS NOT NULL AND hrppa.heightShort IS NOT NULL AND hrppa.age IS NOT NULL AND hrppa.rhNegative IS NOT NULL AND hrppa.homeDelivery IS NOT NULL AND hrppa.badObstetric IS NOT NULL AND hrppa.multiplePregnancy IS NOT NULL), 0) as hrppaFilled, hrppa.syncState as hrppaSyncState, IFNULL((hrpnpa.benId IS NOT NULL AND hrpnpa.noOfDeliveries IS NOT NULL AND hrpnpa.timeLessThan18m IS NOT NULL AND hrpnpa.heightShort IS NOT NULL AND hrpnpa.age IS NOT NULL AND hrpnpa.misCarriage IS NOT NULL AND hrpnpa.homeDelivery IS NOT NULL AND hrpnpa.medicalIssues IS NOT NULL AND hrpnpa.pastCSection IS NOT NULL), 0) as hrpnpaFilled, hrpnpa.syncState as hrpnpaSyncState, IFNULL(hrpmbp.benId IS NOT NULL, 0) as hrpmbpFilled, hrpmbp.syncState as hrpmbpSyncState, IFNULL(hrpt.benId IS NOT NULL, 0) as hrptFilled, IFNULL(((count(distinct hrpt.id) > 3) OR (((JulianDay('now')) - JulianDay(date(max(hrpt.visitDate)/1000,'unixepoch','localtime'))) < 1)), 0) as hrptrackingDone, hrpt.syncState as hrptSyncState, IFNULL(hrnpt.benId IS NOT NULL, 0) as hrnptFilled, IFNULL(((JulianDay('now') - JulianDay(date(max(hrnpt.visitDate)/1000,'unixepoch','localtime'))) < 1), 0) as hrnptrackingDone, hrnpt.syncState as hrnptSyncState FROM BENEFICIARY b JOIN HOUSEHOLD h ON b.householdId = h.householdId LEFT OUTER JOIN CBAC cbac ON b.beneficiaryId = cbac.benId LEFT OUTER JOIN CDR cdr ON b.beneficiaryId = cdr.benId LEFT OUTER JOIN MDSR mdsr ON b.beneficiaryId = mdsr.benId LEFT OUTER JOIN PMSMA pmsma ON b.beneficiaryId = pmsma.benId LEFT OUTER JOIN HBNC hbnc ON b.beneficiaryId = hbnc.benId LEFT OUTER JOIN HBYC hbyc ON b.beneficiaryId = hbyc.benId LEFT OUTER JOIN PREGNANCY_REGISTER pwr ON b.beneficiaryId = pwr.benId LEFT OUTER JOIN PREGNANCY_ANC pwa ON b.beneficiaryId = pwa.benId LEFT OUTER JOIN pnc_visit pnc ON b.beneficiaryId = pnc.benId LEFT OUTER JOIN ELIGIBLE_COUPLE_REG ecr ON b.beneficiaryId = ecr.benId LEFT OUTER JOIN ELIGIBLE_COUPLE_TRACKING ect ON (b.beneficiaryId = ect.benId AND CAST((strftime('%s','now') - ect.visitDate/1000)/60/60/24 AS INTEGER) < 30) LEFT OUTER JOIN TB_SCREENING tbsn ON b.beneficiaryId = tbsn.benId LEFT OUTER JOIN TB_SUSPECTED tbsp ON b.beneficiaryId = tbsp.benId LEFT OUTER JOIN MALARIA_SCREENING masp on b.beneficiaryId = masp.benId LEFT OUTER JOIN MALARIA_CONFIRMED macp on b.beneficiaryId = macp.benId LEFT OUTER JOIN HRP_PREGNANT_ASSESS hrppa ON b.beneficiaryId = hrppa.benId LEFT OUTER JOIN HRP_NON_PREGNANT_ASSESS hrpnpa ON b.beneficiaryId = hrpnpa.benId LEFT OUTER JOIN HRP_MICRO_BIRTH_PLAN hrpmbp ON b.beneficiaryId = hrpmbp.benId LEFT OUTER JOIN HRP_NON_PREGNANT_TRACK hrnpt ON b.beneficiaryId = hrnpt.benId LEFT OUTER JOIN HRP_PREGNANT_TRACK hrpt ON b.beneficiaryId = hrpt.benId LEFT OUTER JOIN DELIVERY_OUTCOME do ON b.beneficiaryId = do.benId LEFT OUTER JOIN INFANT_REG ir ON b.beneficiaryId = ir.motherBenId LEFT OUTER JOIN CHILD_REG cr ON b.beneficiaryId = cr.motherBenId WHERE b.isDraft = 0 GROUP BY b.beneficiaryId ORDER BY b.updatedDate DESC
+ """.trimIndent()
+ )
+
+ if (tableExists(it, "PREGNANCY_ANC")) {
+ if (!columnExists(it, "PREGNANCY_ANC", "placeOfAnc")) {
+ it.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN placeOfAnc TEXT")
+ }
+ if (!columnExists(it, "PREGNANCY_ANC", "placeOfAncId")) {
+ it.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN placeOfAncId INTEGER")
+ }
+ }
+ }
+
+ val MIGRATION_44_45 = object : Migration(44, 45) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isSpouseAdded INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isChildrenAdded INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isMarried INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN noOfChildren INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN noOfAliveChildren INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN doYouHavechildren INTEGER NOT NULL DEFAULT 0")
+
+ database.execSQL("DROP VIEW IF EXISTS BEN_BASIC_CACHE")
+ database.execSQL(
+ "CREATE VIEW `BEN_BASIC_CACHE` AS " +
+ "SELECT b.beneficiaryId as benId,b.isMarried, b.noOfAliveChildren, b.noOfChildren, b.doYouHavechildren, b.isConsent as isConsent, b.motherName as motherName, b.householdId as hhId, b.regDate, b.firstName as benName, b.lastName as benSurname, b.gender, b.dob as dob, b.isDeath,b.isDeathValue,b.dateOfDeath,b.timeOfDeath,b.reasonOfDeath,b.reasonOfDeathId,b.placeOfDeath,b.placeOfDeathId,b.otherPlaceOfDeath,b.isSpouseAdded,b.isChildrenAdded, b.familyHeadRelationPosition as relToHeadId" +
+ ", b.contactNumber as mobileNo, b.fatherName, h.fam_familyHeadName as familyHeadName, b.gen_spouseName as spouseName, b.rchId, b.gen_lastMenstrualPeriod as lastMenstrualPeriod" +
+ ", b.isHrpStatus as hrpStatus, b.syncState, b.gen_reproductiveStatusId as reproductiveStatusId, b.isKid, b.immunizationStatus" +
+ ", b.loc_village_id as villageId, b.abha_healthIdNumber as abhaId" +
+ ", b.isNewAbha" + // FIX: Using only one, correct source for isNewAbha.
+ ", IFNULL(cbac.benId IS NOT NULL, 0) as cbacFilled, cbac.syncState as cbacSyncState" +
+ ", IFNULL(cdr.benId IS NOT NULL, 0) as cdrFilled, cdr.syncState as cdrSyncState" +
+ ", IFNULL(mdsr.benId IS NOT NULL, 0) as mdsrFilled, mdsr.syncState as mdsrSyncState" +
+ ", IFNULL(pmsma.benId IS NOT NULL, 0) as pmsmaFilled, pmsma.syncState as pmsmaSyncState" +
+ ", IFNULL(hbnc.benId IS NOT NULL, 0) as hbncFilled" +
+ ", IFNULL(hbyc.benId IS NOT NULL, 0) as hbycFilled" +
+ ", IFNULL(pwr.benId IS NOT NULL, 0) as pwrFilled, pwr.syncState as pwrSyncState" +
+ ", IFNULL(pwa.pregnantWomanDelivered, 0) as isDelivered, IFNULL(pwa.hrpConfirmed, 0) as pwHrp" +
+ ", IFNULL(ecr.benId IS NOT NULL, 0) as ecrFilled" +
+ ", IFNULL(ect.benId IS NOT NULL, 0) as ectFilled" + // FIX: Removed duplicate ectFilled and used a safe version.
+ ", IFNULL((pwa.maternalDeath OR do.complication = 'DEATH' OR pnc.motherDeath), 0) as isMdsr" +
+ ", IFNULL(tbsn.benId IS NOT NULL, 0) as tbsnFilled, tbsn.syncState as tbsnSyncState" +
+ ", IFNULL(tbsp.benId IS NOT NULL, 0) as tbspFilled, tbsp.syncState as tbspSyncState" +
+ ", IFNULL(ir.motherBenId IS NOT NULL, 0) as irFilled, ir.syncState as irSyncState" +
+ ", IFNULL(cr.motherBenId IS NOT NULL, 0) as crFilled, cr.syncState as crSyncState" +
+ ", IFNULL(do.benId IS NOT NULL, 0) as doFilled, do.syncState as doSyncState" +
+ ", IFNULL((hrppa.benId IS NOT NULL AND hrppa.noOfDeliveries IS NOT NULL AND hrppa.timeLessThan18m IS NOT NULL AND hrppa.heightShort IS NOT NULL AND hrppa.age IS NOT NULL AND hrppa.rhNegative IS NOT NULL AND hrppa.homeDelivery IS NOT NULL AND hrppa.badObstetric IS NOT NULL AND hrppa.multiplePregnancy IS NOT NULL), 0) as hrppaFilled, hrppa.syncState as hrppaSyncState" +
+ ", IFNULL((hrpnpa.benId IS NOT NULL AND hrpnpa.noOfDeliveries IS NOT NULL AND hrpnpa.timeLessThan18m IS NOT NULL AND hrpnpa.heightShort IS NOT NULL AND hrpnpa.age IS NOT NULL AND hrpnpa.misCarriage IS NOT NULL AND hrpnpa.homeDelivery IS NOT NULL AND hrpnpa.medicalIssues IS NOT NULL AND hrpnpa.pastCSection IS NOT NULL), 0) as hrpnpaFilled, hrpnpa.syncState as hrpnpaSyncState" +
+ ", IFNULL(hrpmbp.benId IS NOT NULL, 0) as hrpmbpFilled, hrpmbp.syncState as hrpmbpSyncState" +
+ ", IFNULL(hrpt.benId IS NOT NULL, 0) as hrptFilled, IFNULL(((count(distinct hrpt.id) > 3) OR (((JulianDay('now')) - JulianDay(date(max(hrpt.visitDate)/1000,'unixepoch','localtime'))) < 1)), 0) as hrptrackingDone, hrpt.syncState as hrptSyncState" +
+ ", IFNULL(hrnpt.benId IS NOT NULL, 0) as hrnptFilled, IFNULL(((JulianDay('now') - JulianDay(date(max(hrnpt.visitDate)/1000,'unixepoch','localtime'))) < 1), 0) as hrnptrackingDone, hrnpt.syncState as hrnptSyncState " +
+ "FROM BENEFICIARY b " +
+ "JOIN HOUSEHOLD h ON b.householdId = h.householdId " +
+ "LEFT OUTER JOIN CBAC cbac ON b.beneficiaryId = cbac.benId " +
+ "LEFT OUTER JOIN CDR cdr ON b.beneficiaryId = cdr.benId " +
+ "LEFT OUTER JOIN MDSR mdsr ON b.beneficiaryId = mdsr.benId " +
+ "LEFT OUTER JOIN PMSMA pmsma ON b.beneficiaryId = pmsma.benId " +
+ "LEFT OUTER JOIN HBNC hbnc ON b.beneficiaryId = hbnc.benId " +
+ "LEFT OUTER JOIN HBYC hbyc ON b.beneficiaryId = hbyc.benId " +
+ "LEFT OUTER JOIN PREGNANCY_REGISTER pwr ON b.beneficiaryId = pwr.benId " +
+ "LEFT OUTER JOIN PREGNANCY_ANC pwa ON b.beneficiaryId = pwa.benId " +
+ "LEFT OUTER JOIN pnc_visit pnc ON b.beneficiaryId = pnc.benId " +
+ "LEFT OUTER JOIN ELIGIBLE_COUPLE_REG ecr ON b.beneficiaryId = ecr.benId " +
+ "LEFT OUTER JOIN ELIGIBLE_COUPLE_TRACKING ect ON (b.beneficiaryId = ect.benId AND CAST((strftime('%s','now') - ect.visitDate/1000)/60/60/24 AS INTEGER) < 30) " +
+ "LEFT OUTER JOIN TB_SCREENING tbsn ON b.beneficiaryId = tbsn.benId " +
+ "LEFT OUTER JOIN TB_SUSPECTED tbsp ON b.beneficiaryId = tbsp.benId " +
+ "LEFT OUTER JOIN MALARIA_SCREENING masp on b.beneficiaryId = masp.benId " +
+ "LEFT OUTER JOIN MALARIA_CONFIRMED macp on b.beneficiaryId = macp.benId " +
+ "LEFT OUTER JOIN HRP_PREGNANT_ASSESS hrppa ON b.beneficiaryId = hrppa.benId " +
+ "LEFT OUTER JOIN HRP_NON_PREGNANT_ASSESS hrpnpa ON b.beneficiaryId = hrpnpa.benId " +
+ "LEFT OUTER JOIN HRP_MICRO_BIRTH_PLAN hrpmbp ON b.beneficiaryId = hrpmbp.benId " +
+ "LEFT OUTER JOIN HRP_NON_PREGNANT_TRACK hrnpt ON b.beneficiaryId = hrnpt.benId " +
+ "LEFT OUTER JOIN HRP_PREGNANT_TRACK hrpt ON b.beneficiaryId = hrpt.benId " +
+ "LEFT OUTER JOIN DELIVERY_OUTCOME do ON b.beneficiaryId = do.benId " +
+ "LEFT OUTER JOIN INFANT_REG ir ON b.beneficiaryId = ir.motherBenId " +
+ "LEFT OUTER JOIN CHILD_REG cr ON b.beneficiaryId = cr.motherBenId " +
+ "WHERE b.isDraft = 0 GROUP BY b.beneficiaryId ORDER BY b.updatedDate DESC"
+ )
+
+ database.execSQL("""
+ UPDATE BENEFICIARY
+ SET isMarried = CASE
+ WHEN gen_maritalStatusId = 2 THEN 1
+ ELSE 0
+ END
+ """.trimIndent())
+
+ fun migrateTable(
+ tableName: String,
+ criticalColumns: List,
+ createTableColumns: String
+ ) {
+ val cursor = database.query(
+ "SELECT name FROM sqlite_master WHERE type='table' AND name='$tableName'"
+ )
+ val tableExists = cursor.moveToFirst()
+ cursor.close()
+
+ if (tableExists) {
+ val columnsCursor = database.query("PRAGMA table_info($tableName)")
+ val existingColumns = mutableSetOf()
+ while (columnsCursor.moveToNext()) {
+ existingColumns.add(
+ columnsCursor.getString(
+ columnsCursor.getColumnIndexOrThrow(
+ "name"
+ )
+ )
+ )
+ }
+ columnsCursor.close()
+
+ if (!existingColumns.contains("image2")) {
+ database.execSQL("ALTER TABLE $tableName ADD COLUMN image2 TEXT")
+ }
+ if (!existingColumns.contains("syncState")) {
+ database.execSQL("ALTER TABLE $tableName ADD COLUMN syncState INTEGER NOT NULL DEFAULT 0")
+ }
+
+ val missingCritical =
+ criticalColumns.filter { !existingColumns.contains(it) }
+
+ if (missingCritical.isNotEmpty()) {
+ database.execSQL("CREATE TABLE IF NOT EXISTS ${tableName}_temp ($createTableColumns)")
+
+ val copyColumns = existingColumns.intersect(criticalColumns.toSet())
+ if (copyColumns.isNotEmpty()) {
+ database.execSQL(
+ """
+ INSERT INTO ${tableName}_temp (${copyColumns.joinToString(",")})
+ SELECT ${copyColumns.joinToString(",")} FROM $tableName
+ """.trimIndent()
+ )
+ }
+
+ database.execSQL("DROP TABLE $tableName")
+ database.execSQL("ALTER TABLE ${tableName}_temp RENAME TO $tableName")
+ }
+
+ } else {
+ database.execSQL("CREATE TABLE IF NOT EXISTS $tableName ($createTableColumns)")
+ }
+ }
+
+
+ migrateTable(
+ tableName = "PHCReviewMeeting",
+ criticalColumns = listOf(
+ "id",
+ "phcReviewDate",
+ "place",
+ "noOfBeneficiariesAttended",
+ "image1"
+ ),
+ createTableColumns = """
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ phcReviewDate TEXT NOT NULL,
+ place TEXT,
+ noOfBeneficiariesAttended INTEGER,
+ image1 TEXT,
+ image2 TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0
+ """.trimIndent()
+ )
+
+ migrateTable(
+ tableName = "VHND",
+ criticalColumns = listOf(
+ "id",
+ "vhndDate",
+ "place",
+ "noOfBeneficiariesAttended",
+ "image1"
+ ),
+ createTableColumns = """
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ vhndDate TEXT NOT NULL,
+ place TEXT,
+ noOfBeneficiariesAttended INTEGER,
+ image1 TEXT,
+ image2 TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0
+ """.trimIndent()
+ )
+
+ migrateTable(
+ tableName = "VHNC",
+ criticalColumns = listOf(
+ "id",
+ "vhncDate",
+ "place",
+ "noOfBeneficiariesAttended",
+ "image1"
+ ),
+ createTableColumns = """
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ vhncDate TEXT NOT NULL,
+ place TEXT,
+ noOfBeneficiariesAttended INTEGER,
+ image1 TEXT,
+ image2 TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0
+ """.trimIndent()
+ )
+
+ migrateTable(
+ tableName = "AHDMeeting",
+ criticalColumns = listOf(
+ "id",
+ "mobilizedForAHD",
+ "ahdPlace",
+ "ahdDate",
+ "image1"
+ ),
+ createTableColumns = """
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ mobilizedForAHD TEXT,
+ ahdPlace TEXT,
+ ahdDate TEXT,
+ image1 TEXT,
+ image2 TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0
+ """.trimIndent()
+ )
+
+ migrateTable(
+ tableName = "DewormingMeeting",
+ criticalColumns = listOf(
+ "id",
+ "dewormingDone",
+ "dewormingDate",
+ "dewormingLocation",
+ "ageGroup",
+ "image1"
+ ),
+ createTableColumns = """
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ dewormingDone TEXT,
+ dewormingDate TEXT,
+ dewormingLocation TEXT,
+ ageGroup INTEGER,
+ image1 TEXT,
+ image2 TEXT,
+ regDate TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0
+ """.trimIndent()
+ )
+
+ migrateTable(
+ tableName = "NCD_REFER",
+ criticalColumns = listOf(
+ "id",
+ "benId",
+ "referredToInstituteID",
+ "refrredToAdditionalServiceList",
+ "referredToInstituteName",
+ "referralReason",
+ "revisitDate",
+ "vanID",
+ "parkingPlaceID",
+ "beneficiaryRegID",
+ "benVisitID",
+ "visitCode",
+ "providerServiceMapID",
+ "createdBy",
+ "isSpecialist",
+ "syncState"
+ ),
+ createTableColumns = """
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ benId INTEGER NOT NULL,
+ referredToInstituteID INTEGER DEFAULT 0,
+ refrredToAdditionalServiceList TEXT DEFAULT 'undefined',
+ referredToInstituteName TEXT DEFAULT 'undefined',
+ referralReason TEXT DEFAULT 'undefined',
+ revisitDate INTEGER NOT NULL DEFAULT ${System.currentTimeMillis()},
+ vanID INTEGER DEFAULT 0,
+ parkingPlaceID INTEGER DEFAULT 0,
+ beneficiaryRegID INTEGER DEFAULT 0,
+ benVisitID INTEGER DEFAULT 0,
+ visitCode INTEGER DEFAULT 0,
+ providerServiceMapID INTEGER DEFAULT 0,
+ createdBy TEXT DEFAULT '',
+ isSpecialist INTEGER DEFAULT 0,
+ syncState INTEGER NOT NULL DEFAULT 0,
+ FOREIGN KEY(benId)
+ REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS ind_refcache
+ ON NCD_REFER (benId)
+ """
+ )
+
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS MALARIA_SCREENING (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+
+ benId INTEGER NOT NULL,
+ visitId INTEGER NOT NULL,
+ houseHoldDetailsId INTEGER NOT NULL,
+
+ caseDate INTEGER NOT NULL,
+ screeningDate INTEGER NOT NULL,
+ dateOfDeath INTEGER NOT NULL,
+ dateOfRdt INTEGER NOT NULL,
+ dateOfSlideTest INTEGER NOT NULL,
+ dateOfVisitBySupervisor INTEGER NOT NULL,
+ followUpDate INTEGER NOT NULL,
+
+ beneficiaryStatus TEXT,
+ beneficiaryStatusId INTEGER NOT NULL,
+
+ placeOfDeath TEXT,
+ otherPlaceOfDeath TEXT,
+ reasonForDeath TEXT,
+ otherReasonForDeath TEXT,
+
+ rapidDiagnosticTest TEXT,
+ slideTestPf TEXT,
+ slideTestPv TEXT,
+ slideTestName TEXT,
+
+ caseStatus TEXT,
+ referredTo INTEGER,
+ referToName TEXT,
+ otherReferredFacility TEXT,
+ remarks TEXT,
+
+ diseaseTypeID INTEGER,
+ malariaTestType INTEGER,
+ malariaSlideTestType INTEGER,
+
+ feverMoreThanTwoWeeks INTEGER,
+ fluLikeIllness INTEGER,
+ shakingChills INTEGER,
+ headache INTEGER,
+ muscleAches INTEGER,
+ tiredness INTEGER,
+ nausea INTEGER,
+ vomiting INTEGER,
+ diarrhea INTEGER,
+
+ createdBy TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0,
+
+ FOREIGN KEY(benId)
+ REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS ind_malariasn
+ ON MALARIA_SCREENING (benId, visitId)
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS AES_SCREENING (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+
+ benId INTEGER NOT NULL,
+ houseHoldDetailsId INTEGER NOT NULL,
+
+ visitDate INTEGER NOT NULL,
+ createdDate INTEGER NOT NULL,
+ dateOfDeath INTEGER NOT NULL,
+
+ beneficiaryStatus TEXT,
+ beneficiaryStatusId INTEGER NOT NULL,
+
+ placeOfDeath TEXT,
+ otherPlaceOfDeath TEXT,
+ reasonForDeath TEXT,
+ otherReasonForDeath TEXT,
+
+ aesJeCaseStatus TEXT,
+
+ referredTo INTEGER,
+ referToName TEXT,
+ otherReferredFacility TEXT,
+
+ diseaseTypeID INTEGER,
+ followUpPoint INTEGER,
+
+ createdBy TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0,
+
+ FOREIGN KEY(benId)
+ REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS ind_aessn
+ ON AES_SCREENING (benId)
+"""
+ )
+
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS KALAZAR_SCREENING (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+
+ benId INTEGER NOT NULL,
+ houseHoldDetailsId INTEGER NOT NULL,
+
+ visitDate INTEGER NOT NULL,
+ createdDate INTEGER NOT NULL,
+ dateOfDeath INTEGER NOT NULL,
+ dateOfRdt INTEGER NOT NULL,
+
+ beneficiaryStatus TEXT,
+ beneficiaryStatusId INTEGER NOT NULL,
+
+ placeOfDeath TEXT,
+ otherPlaceOfDeath TEXT,
+ reasonForDeath TEXT,
+ otherReasonForDeath TEXT,
+
+ rapidDiagnosticTest TEXT,
+ kalaAzarCaseStatus TEXT,
+
+ referredTo INTEGER,
+ referToName TEXT,
+ otherReferredFacility TEXT,
+
+ diseaseTypeID INTEGER,
+ followUpPoint INTEGER,
+
+ createdBy TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0,
+
+ FOREIGN KEY(benId)
+ REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS ind_kalazarsn
+ ON KALAZAR_SCREENING (benId)
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS FILARIA_SCREENING (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+
+ benId INTEGER NOT NULL,
+ houseHoldDetailsId INTEGER NOT NULL,
+
+ mdaHomeVisitDate INTEGER NOT NULL,
+ createdDate INTEGER NOT NULL,
+
+ sufferingFromFilariasis INTEGER,
+ doseStatus TEXT,
+ affectedBodyPart TEXT,
+ otherDoseStatusDetails TEXT,
+ filariasisCaseCount TEXT,
+
+ medicineSideEffect TEXT,
+ otherSideEffectDetails TEXT,
+
+ diseaseTypeID INTEGER,
+ createdBy TEXT,
+
+ syncState INTEGER NOT NULL DEFAULT 0,
+
+ FOREIGN KEY(benId)
+ REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS ind_filariasn
+ ON FILARIA_SCREENING (benId)
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS MALARIA_CONFIRMED (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+
+ diseaseId INTEGER NOT NULL,
+ benId INTEGER NOT NULL,
+ houseHoldDetailsId INTEGER NOT NULL,
+
+ dateOfDiagnosis INTEGER NOT NULL,
+ treatmentStartDate INTEGER NOT NULL,
+ treatmentCompletionDate INTEGER NOT NULL,
+
+ treatmentGiven TEXT,
+ referralDate INTEGER NOT NULL,
+ day TEXT,
+
+ syncState INTEGER NOT NULL DEFAULT 0,
+
+ FOREIGN KEY(benId)
+ REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS ind_malariacs
+ ON MALARIA_CONFIRMED (benId)
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS IRS_ROUND (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ date INTEGER NOT NULL,
+ rounds INTEGER NOT NULL,
+ householdId INTEGER NOT NULL
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS ind_irs_round
+ ON IRS_ROUND (householdId)
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS Adolescent_Health_Form_Data (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ userID INTEGER,
+ benId INTEGER,
+
+ visitDate INTEGER NOT NULL,
+ healthStatus TEXT,
+ ifaTabletDistributed INTEGER,
+ quantityOfIfaTablets INTEGER,
+ menstrualHygieneAwarenessGiven INTEGER,
+ sanitaryNapkinDistributed INTEGER,
+ noOfPacketsDistributed INTEGER,
+ place TEXT,
+ distributionDate INTEGER NOT NULL,
+ referredToHealthFacility TEXT,
+ counselingProvided INTEGER,
+ counselingType TEXT,
+ followUpDate INTEGER NOT NULL,
+
+ referralStatus TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0,
+
+ FOREIGN KEY(benId)
+ REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS ind_adolescentsn
+ ON Adolescent_Health_Form_Data (benId)
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS infant (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+
+ rchId TEXT NOT NULL,
+ name TEXT NOT NULL,
+ motherName TEXT NOT NULL,
+ fatherName TEXT,
+ dob TEXT NOT NULL,
+ gender TEXT NOT NULL,
+ phoneNumber TEXT NOT NULL,
+ sncuDischarged INTEGER NOT NULL DEFAULT 0
+ )
+"""
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS SAAS_BAHU_ACTIVITY (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+
+ ashaId INTEGER NOT NULL,
+ place TEXT,
+ participants INTEGER,
+ date INTEGER,
+
+ sammelanImages TEXT,
+ syncState INTEGER NOT NULL DEFAULT 0
+ )
+"""
+ )
+ }
+ }
+
+
+ val MIGRATION_43_44 = object : Migration(43, 44) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS LEPROSY_SCREENING (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ benId INTEGER NOT NULL,
+ houseHoldDetailsId INTEGER NOT NULL,
+ visitNumber INTEGER,
+ isConfirmed INTEGER NOT NULL,
+ homeVisitDate INTEGER NOT NULL,
+ leprosyState TEXT,
+ leprosyStatusDate INTEGER NOT NULL,
+ lerosyStatusPosition INTEGER,
+ beneficiaryStatus TEXT,
+ beneficiaryStatusId INTEGER,
+ dateOfDeath INTEGER NOT NULL,
+ placeOfDeath TEXT,
+ otherPlaceOfDeath TEXT,
+ reasonForDeath TEXT,
+ otherReasonForDeath TEXT,
+ treatmentStatus TEXT,
+ mdtBlisterPackRecived TEXT,
+ leprosySymptoms TEXT,
+ typeOfLeprosy TEXT,
+ leprosySymptomsPosition INTEGER,
+ visitLabel TEXT,
+ leprosyStatus TEXT,
+ referredTo INTEGER,
+ referToName TEXT,
+ otherReferredTo TEXT,
+ treatmentEndDate INTEGER NOT NULL,
+ treatmentStartDate INTEGER NOT NULL,
+ currentVisitNumber INTEGER NOT NULL,
+ totalFollowUpMonthsRequired INTEGER NOT NULL,
+ diseaseTypeID INTEGER,
+ remarks TEXT,
+ syncState INTEGER NOT NULL,
+ createdBy TEXT NOT NULL,
+ createdDate INTEGER NOT NULL,
+ modifiedBy TEXT NOT NULL,
+ lastModDate INTEGER NOT NULL,
+ FOREIGN KEY(benId) REFERENCES BENEFICIARY(beneficiaryId) ON UPDATE CASCADE ON DELETE CASCADE
+ )
+ """
+ )
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS ind_leprosysn ON LEPROSY_SCREENING (benId)
+ """
+ )
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS LEPROSY_FOLLOW_UP (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ benId INTEGER NOT NULL,
+ visitNumber INTEGER NOT NULL,
+ followUpDate INTEGER NOT NULL,
+ treatmentStatus TEXT,
+ mdtBlisterPackReceived TEXT,
+ treatmentCompleteDate INTEGER NOT NULL,
+ remarks TEXT,
+ homeVisitDate INTEGER NOT NULL,
+ leprosySymptoms TEXT,
+ typeOfLeprosy TEXT,
+ leprosySymptomsPosition INTEGER,
+ visitLabel TEXT,
+ leprosyStatus TEXT,
+ referredTo INTEGER,
+ referToName TEXT,
+ treatmentEndDate INTEGER NOT NULL,
+ mdtBlisterPackRecived TEXT,
+ treatmentStartDate INTEGER NOT NULL,
+ syncState INTEGER NOT NULL,
+ createdBy TEXT NOT NULL,
+ createdDate INTEGER NOT NULL,
+ modifiedBy TEXT NOT NULL,
+ lastModDate INTEGER NOT NULL
+ )
+ """
+ )
+
+ database.execSQL("CREATE INDEX IF NOT EXISTS ind_leprosy_followup_ben ON LEPROSY_FOLLOW_UP (benId)")
+ database.execSQL("CREATE INDEX IF NOT EXISTS ind_leprosy_followup_visit ON LEPROSY_FOLLOW_UP (benId, visitNumber)")
+
+
+ }
+ }
+
+
+ val MIGRATION_42_43 = object : Migration(42, 43) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+
+ if (!tableExists(db, "LEPROSY_SCREENING")) {
+ return
+ }
+
+ val columns = listOf(
+ "leprosySymptoms" to "TEXT",
+ "visitLabel" to "TEXT",
+ "visitNumber" to "INTEGER",
+ "leprosySymptomsPosition" to "INTEGER DEFAULT 1",
+ "isConfirmed" to "INTEGER NOT NULL DEFAULT 0",
+ "treatmentStartDate" to "INTEGER NOT NULL DEFAULT 0",
+ "treatmentEndDate" to "INTEGER NOT NULL DEFAULT 0",
+ "mdtBlisterPackRecived" to "TEXT",
+ "treatmentStatus" to "TEXT",
+ "leprosyState" to "TEXT"
+ )
+
+ for ((column, type) in columns) {
+ if (!columnExists(db, "LEPROSY_SCREENING", column)) {
+ db.execSQL(
+ "ALTER TABLE LEPROSY_SCREENING ADD COLUMN $column $type"
+ )
+ }
+ }
+ }
+ }
+
+
+ val MIGRATION_41_42 = object : Migration(41, 42) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE form_schema ADD COLUMN language TEXT NOT NULL DEFAULT 'en'")
+ if (tableExists(database, "HRP_MICRO_BIRTH_PLAN")) {
+
+ if (!columnExists(database, "HRP_MICRO_BIRTH_PLAN", "processed")) {
+ database.execSQL(
+ "ALTER TABLE HRP_MICRO_BIRTH_PLAN ADD COLUMN processed TEXT"
+ )
+ }
+ }
+ }
+ }
+
+ val MIGRATION_40_41 = object : Migration(40, 41) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+
+ if (tableExists(db, "PREGNANCY_ANC")) {
+
+ if (!columnExists(db, "PREGNANCY_ANC", "isYesOrNo")) {
+ db.execSQL(
+ "ALTER TABLE PREGNANCY_ANC ADD COLUMN isYesOrNo INTEGER "
+ )
+ }
+
+ if (!columnExists(db, "PREGNANCY_ANC", "dateSterilisation")) {
+ db.execSQL(
+ "ALTER TABLE PREGNANCY_ANC ADD COLUMN dateSterilisation INTEGER"
+ )
+ }
+
+ if (columnExists(db, "PREGNANCY_ANC", "isPaiucdId")) {
+ db.execSQL(
+ """
+ UPDATE PREGNANCY_ANC
+ SET isPaiucdId = CASE
+ WHEN isPaiucdId = 1 THEN 1
+ ELSE 0
+ END
+ """.trimIndent()
+ )
+ }
+
+ db.execSQL(
+ "ALTER TABLE PREGNANCY_ANC ADD COLUMN isPaiucd TEXT"
+ )
+
+ db.execSQL(
+ "ALTER TABLE PREGNANCY_ANC ADD COLUMN remarks TEXT"
+ )
+ db.execSQL(
+ "ALTER TABLE PREGNANCY_ANC ADD COLUMN isPaiucdId INTEGER"
+ )
+ db.execSQL(
+ "ALTER TABLE PREGNANCY_ANC ADD COLUMN serialNo TEXT "
+ )
+ db.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN abortionImg1 TEXT")
+ db.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN abortionImg2 TEXT")
+
+
+ }
+
+ }
+ }
+
+
+ val MIGRATION_39_40 = object : Migration(39, 40) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `ALL_BEN_IFA_VISIT_HISTORY` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `benId` INTEGER NOT NULL,
+ `hhId` INTEGER NOT NULL,
+ `visitDate` TEXT NOT NULL,
+ `formId` TEXT NOT NULL,
+ `version` INTEGER NOT NULL,
+ `formDataJson` TEXT NOT NULL,
+ `isSynced` INTEGER NOT NULL,
+ `createdAt` INTEGER NOT NULL,
+ `syncedAt` INTEGER
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS
+ `index_ALL_BEN_IFA_VISIT_HISTORY_benId_hhId_visitDate_formId`
+ ON `ALL_BEN_IFA_VISIT_HISTORY` (`benId`, `hhId`, `visitDate`, `formId`)
+ """.trimIndent()
+ )
+ }
+ }
+
+
+ val MIGRATION_38_39 = object : Migration(38, 39) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS FILARIA_MDA_VISIT_HISTORY (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ hhId INTEGER NOT NULL,
+ visitDate TEXT NOT NULL,
+ visitMonth TEXT NOT NULL,
+ formId TEXT NOT NULL,
+ version INTEGER NOT NULL,
+ formDataJson TEXT NOT NULL,
+ isSynced INTEGER NOT NULL DEFAULT 0,
+ createdAt INTEGER NOT NULL DEFAULT (strftime('%s','now')),
+ syncedAt TEXT
+ )
+ """.trimIndent()
+ )
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS index_FILARIA_MDA_VISIT_HISTORY_hhId_formId_visitMonth
+ ON FILARIA_MDA_VISIT_HISTORY (hhId, formId, visitMonth)
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS index_FILARIA_MDA_VISIT_HISTORY_hhId_visitDate
+ ON FILARIA_MDA_VISIT_HISTORY (hhId, visitDate)
+ """.trimIndent()
+ )
+ }
+ }
+
+
+ val MIGRATION_37_38 = object : Migration(37, 38) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE INFANT_REG ADD COLUMN isSNCU TEXT")
+ database.execSQL("ALTER TABLE INFANT_REG ADD COLUMN deliveryDischargeSummary1 TEXT")
+ database.execSQL("ALTER TABLE INFANT_REG ADD COLUMN deliveryDischargeSummary2 TEXT")
+ database.execSQL("ALTER TABLE INFANT_REG ADD COLUMN deliveryDischargeSummary3 TEXT")
+ database.execSQL("ALTER TABLE INFANT_REG ADD COLUMN deliveryDischargeSummary4 TEXT")
+ }
+ }
+
+ val MIGRATION_36_37 = object : Migration(36, 37) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS mosquito_net_visit (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ hhId INTEGER NOT NULL,
+ visitDate TEXT NOT NULL,
+ formId TEXT NOT NULL,
+ version INTEGER NOT NULL,
+ formDataJson TEXT NOT NULL,
+ isSynced INTEGER NOT NULL DEFAULT 0,
+ syncedAt TEXT
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS index_mosquito_net_visit_unique
+ ON mosquito_net_visit (hhId, visitDate, formId)
+ """.trimIndent()
+ )
+ }
+ }
+
+ val MIGRATION_35_36 = object : Migration(35, 36) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+
+
+ if (tableExists(db, "ALL_EYE_SURGERY_VISIT_HISTORY")) {
+
+ db.execSQL("ALTER TABLE ALL_EYE_SURGERY_VISIT_HISTORY RENAME TO temp_eye_history")
+
+ db.execSQL(
+ """
+ CREATE TABLE ALL_EYE_SURGERY_VISIT_HISTORY (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ benId INTEGER NOT NULL,
+ hhId INTEGER NOT NULL,
+ visitDate TEXT NOT NULL,
+ formId TEXT NOT NULL,
+ version INTEGER NOT NULL,
+ formDataJson TEXT NOT NULL,
+ isSynced INTEGER NOT NULL DEFAULT 0,
+ createdAt INTEGER NOT NULL,
+ syncedAt TEXT,
+ visitMonth TEXT NOT NULL DEFAULT ''
+ )
+ """.trimIndent()
+ )
+
+ db.execSQL(
+ """
+ INSERT INTO ALL_EYE_SURGERY_VISIT_HISTORY (
+ id, benId, hhId, visitDate, formId, version, formDataJson, isSynced, createdAt, syncedAt, visitMonth
+ )
+ SELECT id, benId, hhId, visitDate, formId, version, formDataJson, isSynced, createdAt, syncedAt, visitMonth
+ FROM temp_eye_history
+ """.trimIndent()
+ )
+
+ db.execSQL("DROP TABLE temp_eye_history")
+
+ db.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS index_ALL_EYE_SURGERY_VISIT_HISTORY_benId_formId_visitMonth
+ ON ALL_EYE_SURGERY_VISIT_HISTORY(benId, formId, visitMonth)
+ """.trimIndent()
+ )
+
+ db.execSQL(
+ """
+ CREATE INDEX IF NOT EXISTS index_ALL_EYE_SURGERY_VISIT_HISTORY_benId_visitDate
+ ON ALL_EYE_SURGERY_VISIT_HISTORY(benId, visitDate)
+ """.trimIndent()
+ )
+ }
+
+ if (tableExists(db, "MALARIA_SCREENING")) {
+
+ db.execSQL("DROP INDEX IF EXISTS ind_malariasn")
+
+ if (!columnExists(db, "MALARIA_SCREENING", "visitId")) {
+ db.execSQL(
+ "ALTER TABLE MALARIA_SCREENING ADD COLUMN visitId INTEGER NOT NULL DEFAULT 1"
+ )
+ }
+
+ db.execSQL(
+ "CREATE UNIQUE INDEX IF NOT EXISTS ind_malariasn ON MALARIA_SCREENING(benId, visitId)"
+ )
+ }
+ }
+ }
+
+
+ val MIGRATION_34_35 = object : Migration(34, 35) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ """
+ CREATE TABLE ALL_EYE_SURGERY_VISIT_HISTORY (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ benId INTEGER NOT NULL,
+ hhId INTEGER NOT NULL,
+ visitDate TEXT NOT NULL,
+ formId TEXT NOT NULL,
+ version INTEGER NOT NULL,
+ formDataJson TEXT NOT NULL,
+ isSynced INTEGER NOT NULL DEFAULT 0,
+ createdAt INTEGER NOT NULL,
+ syncedAt TEXT,
+ visitMonth TEXT NOT NULL DEFAULT ''
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS
+ index_ALL_EYE_SURGERY_VISIT_HISTORY_benId_hhId_visitDate_formId
+ ON ALL_EYE_SURGERY_VISIT_HISTORY (benId, hhId, visitDate, formId)
+ """.trimIndent()
+ )
+
+ if (tableExists(database, "MALARIA_SCREENING")) {
+
+ if (!columnExists(database, "MALARIA_SCREENING", "visitId")) {
+ database.execSQL(
+ "ALTER TABLE MALARIA_SCREENING ADD COLUMN visitId INTEGER NOT NULL DEFAULT 1"
+ )
+ }
+
+ if (!columnExists(database, "MALARIA_SCREENING", "malariaTestType")) {
+ database.execSQL(
+ "ALTER TABLE MALARIA_SCREENING ADD COLUMN malariaTestType INTEGER DEFAULT 0"
+ )
+ }
+
+ if (!columnExists(database, "MALARIA_SCREENING", "malariaSlideTestType")) {
+ database.execSQL(
+ "ALTER TABLE MALARIA_SCREENING ADD COLUMN malariaSlideTestType INTEGER DEFAULT 0"
+ )
+ }
+
+ database.execSQL(
+ "CREATE UNIQUE INDEX IF NOT EXISTS ind_malariasn ON MALARIA_SCREENING(benId, visitId)"
+ )
+ }
+ }
+ }
+
+
+ val MIGRATION_33_34 = object : Migration(33, 34) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS form_schema (
+ formId TEXT NOT NULL PRIMARY KEY,
+ formName TEXT NOT NULL,
+ version INTEGER NOT NULL DEFAULT 1,
+ schemaJson TEXT NOT NULL
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS all_visit_history (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ benId INTEGER NOT NULL,
+ hhId INTEGER NOT NULL,
+ visitDay TEXT NOT NULL,
+ visitDate TEXT NOT NULL,
+ formId TEXT NOT NULL,
+ version INTEGER NOT NULL,
+ formDataJson TEXT NOT NULL,
+ isSynced INTEGER NOT NULL DEFAULT 0,
+ createdAt INTEGER NOT NULL,
+ syncedAt INTEGER
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS index_all_visit_history_unique
+ ON all_visit_history (benId, hhId, visitDay, visitDate, formId)
+ """.trimIndent()
+ )
+ }
+ }
+
+
+ val MIGRATION_32_33 = object : Migration(32, 33) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS ALL_VISIT_HISTORY_HBYC (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ benId INTEGER NOT NULL,
+ hhId INTEGER NOT NULL,
+ visitDay TEXT NOT NULL,
+ visitDate TEXT NOT NULL,
+ formId TEXT NOT NULL,
+ version INTEGER NOT NULL,
+ formDataJson TEXT NOT NULL,
+ isSynced INTEGER NOT NULL DEFAULT 0,
+ createdAt INTEGER NOT NULL,
+ syncedAt INTEGER
+ )
+ """.trimIndent()
+ )
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS index_all_visit_history_hbyc_unique
+ ON ALL_VISIT_HISTORY_HBYC (benId, hhId, visitDay, visitDate, formId)
+ """.trimIndent()
+ )
+ }
+ }
+
+ val MIGRATION_31_32 = object : Migration(31, 32) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `children_under_five_all_visit` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `benId` INTEGER NOT NULL,
+ `hhId` INTEGER NOT NULL,
+ `visitDate` TEXT NOT NULL,
+ `formId` TEXT NOT NULL,
+ `version` INTEGER NOT NULL,
+ `formDataJson` TEXT NOT NULL,
+ `isSynced` INTEGER NOT NULL DEFAULT 0,
+ `createdAt` INTEGER NOT NULL,
+ `updatedAt` INTEGER NOT NULL,
+ `syncedAt` INTEGER
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL(
+ """
+ CREATE UNIQUE INDEX IF NOT EXISTS `index_children_under_five_all_visit_benId_hhId_visitDate_formId`
+ ON `children_under_five_all_visit` (`benId`, `hhId`, `visitDate`, `formId`)
+ """.trimIndent()
+ )
+ }
+ }
+
+
+ val MIGRATION_30_31 = object : Migration(30, 31) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE CBAC ADD COLUMN isReffered INTEGER DEFAULT 0")
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS form_schema (
+ formId TEXT NOT NULL PRIMARY KEY,
+ formName TEXT NOT NULL,
+ version INTEGER NOT NULL DEFAULT 1,
+ schemaJson TEXT NOT NULL
+ )
+ """.trimIndent()
+ )
+ database.execSQL("ALTER TABLE IMMUNIZATION ADD COLUMN mcpCardSummary1 TEXT")
+ database.execSQL("ALTER TABLE IMMUNIZATION ADD COLUMN mcpCardSummary2 TEXT")
+ database.execSQL("DROP TABLE IF EXISTS `UWIN_SESSION`")
+ database.execSQL(
+ """CREATE TABLE IF NOT EXISTS `UWIN_SESSION` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `sessionDate` INTEGER NOT NULL,
+ `place` TEXT,
+ `participantsCount` INTEGER NOT NULL,
+ `uploadedFiles1` TEXT,
+ `uploadedFiles2` TEXT,
+ `processed` TEXT,
+ `createdBy` TEXT NOT NULL,
+ `createdDate` INTEGER NOT NULL,
+ `updatedBy` TEXT NOT NULL,
+ `updatedDate` INTEGER NOT NULL,
+ `syncState` INTEGER NOT NULL
+ )
+ """.trimIndent()
+ )
+ }
+ }
+
+
+ val MIGRATION_29_30 = object : Migration(29, 30) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE eligible_couple_tracking ADD COLUMN dischargeSummary1 TEXT")
+ database.execSQL("ALTER TABLE eligible_couple_tracking ADD COLUMN dischargeSummary2 TEXT")
+ database.execSQL(
+ "CREATE TABLE IF NOT EXISTS `MAA_MEETING` (" +
+ "`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
+ "`meetingDate` TEXT, `place` TEXT, `participants` INTEGER, `ashaId` INTEGER, " +
+ "`meetingImages` TEXT, " +
+ "`createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, `syncState` INTEGER NOT NULL)"
+ )
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_REG ADD COLUMN isKitHandedOver INTEGER ")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_REG ADD COLUMN kitHandedOverDate INTEGER")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_REG ADD COLUMN kitPhoto1 TEXT")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_REG ADD COLUMN kitPhoto2 TEXT")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_REG ADD COLUMN lmpDate INTEGER NOT NULL DEFAULT 0 ")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_REG ADD COLUMN lmp_date INTEGER NOT NULL DEFAULT 0")
+
+ }
+ }
+
+
+// val MIGRATION_22_23 = object : Migration(22, 23) {
+// override fun migrate(database: SupportSQLiteDatabase) {
+// database.execSQL("ALTER TABLE GENERAL_OPD_ACTIVITY ADD COLUMN village TEXT")
+// }
+// }
+
+
+ val MIGRATION_28_29 = object : Migration(28, 29) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE PMSMA ADD COLUMN visitDate INTEGER")
+ database.execSQL("ALTER TABLE PMSMA ADD COLUMN visitNumber INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE PMSMA ADD COLUMN anyOtherHighRiskCondition TEXT")
+ }
+ }
+
+ val MIGRATION_27_28 = object : Migration(27, 28) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ val cursor = database.query("PRAGMA table_info(PNC_VISIT)")
+ val existingColumns = mutableSetOf()
+ while (cursor.moveToNext()) {
+ existingColumns.add(cursor.getString(1))
+ }
+ cursor.close()
+
+ if (!existingColumns.contains("deliveryDischargeSummary1")) {
+ database.execSQL("ALTER TABLE PNC_VISIT ADD COLUMN deliveryDischargeSummary1 TEXT")
+ }
+ if (!existingColumns.contains("deliveryDischargeSummary2")) {
+ database.execSQL("ALTER TABLE PNC_VISIT ADD COLUMN deliveryDischargeSummary2 TEXT")
+ }
+ if (!existingColumns.contains("deliveryDischargeSummary3")) {
+ database.execSQL("ALTER TABLE PNC_VISIT ADD COLUMN deliveryDischargeSummary3 TEXT")
+ }
+ if (!existingColumns.contains("deliveryDischargeSummary4")) {
+ database.execSQL("ALTER TABLE PNC_VISIT ADD COLUMN deliveryDischargeSummary4 TEXT")
+ }
+ if (!existingColumns.contains("sterilisationDate")) {
+ database.execSQL("ALTER TABLE PNC_VISIT ADD COLUMN sterilisationDate INTEGER ")
+ }
+ if (!existingColumns.contains("anyDangerSign")) {
+ database.execSQL("ALTER TABLE PNC_VISIT ADD COLUMN anyDangerSign TEXT ")
+ }
+ }
+
+ }
+
+ val MIGRATION_26_27 = object : Migration(26, 27) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE INCENTIVE_ACTIVITY ADD COLUMN groupName TEXT NOT NULL DEFAULT 'undefined'")
+
+ }
+ }
+
+
+ val MIGRATION_25_26 = object : Migration(25, 26) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ if (tableExists(database, "PREGNANCY_ANC")) {
+ if (!columnExists(database, "PREGNANCY_ANC", "lmpDate")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN lmpDate INTEGER")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "visitDate")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN visitDate INTEGER")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "weekOfPregnancy")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN weekOfPregnancy INTEGER")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "placeOfDeath")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN placeOfDeath TEXT")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "placeOfDeathId")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN placeOfDeathId INTEGER")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "otherPlaceOfDeath")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN otherPlaceOfDeath TEXT")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "methodOfTermination")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN methodOfTermination TEXT")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "methodOfTerminationId")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN methodOfTerminationId INTEGER")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "terminationDoneBy")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN terminationDoneBy TEXT")
+ }
+ if (!columnExists(database, "PREGNANCY_ANC", "terminationDoneById")) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN terminationDoneById INTEGER")
+ }
+ }
+ }
+ }
+
+// val MIGRATION_20_21 = object : Migration(20, 21) {
+// override fun migrate(database: SupportSQLiteDatabase) {
+// database.execSQL("""
+// CREATE TABLE IF NOT EXISTS `GENERAL_OPD_ACTIVITY` (
+// `benFlowID` INTEGER,
+// `beneficiaryRegID` INTEGER,
+// `benVisitID` INTEGER,
+// `visitCode` INTEGER,
+// `benVisitNo` INTEGER,
+// `nurseFlag` INTEGER,
+// `doctorFlag` INTEGER,
+// `pharmacist_flag` INTEGER,
+// `lab_technician_flag` INTEGER,
+// `radiologist_flag` INTEGER,
+// `oncologist_flag` INTEGER,
+// `specialist_flag` INTEGER,
+// `agentId` TEXT,
+// `visitDate` TEXT,
+// `modified_by` TEXT,
+// `modified_date` TEXT,
+// `benName` TEXT,
+// `deleted` INTEGER,
+// `firstName` TEXT,
+// `lastName` TEXT,
+// `age` TEXT,
+// `ben_age_val` INTEGER,
+// `genderID` INTEGER,
+// `genderName` TEXT,
+// `preferredPhoneNum` TEXT,
+// `fatherName` TEXT,
+// `spouseName` TEXT,
+// `districtName` TEXT,
+// `servicePointName` TEXT,
+// `registrationDate` TEXT,
+// `benVisitDate` TEXT,
+// `consultationDate` TEXT,
+// `consultantID` INTEGER,
+// `consultantName` TEXT,
+// `visitSession` TEXT,
+// `servicePointID` INTEGER,
+// `districtID` INTEGER,
+// `villageID` INTEGER,
+// `vanID` INTEGER,
+// `beneficiaryId` INTEGER NOT NULL,
+// `dob` TEXT,
+// `tc_SpecialistLabFlag` INTEGER,
+// `visitReason` TEXT,
+// `visitCategory` TEXT,
+// PRIMARY KEY(`beneficiaryId`)
+// )
+// """)
+// }
+// }
+
+// val MIGRATION_19_20 = object : Migration(19, 20) {
+// override fun migrate(database: SupportSQLiteDatabase) {
+// database.execSQL("ALTER TABLE MALARIA_SCREENING ADD COLUMN slideTestName TEXT")
+// }
+// }
+
+ val MIGRATION_24_25 = object : Migration(24, 25) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_TRACKING ADD COLUMN dateOfAntraInjection TEXT")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_TRACKING ADD COLUMN dueDateOfAntraInjection TEXT")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_TRACKING ADD COLUMN mpaFile TEXT")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_TRACKING ADD COLUMN antraDose TEXT")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_TRACKING ADD COLUMN lmp_date INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE ELIGIBLE_COUPLE_TRACKING ADD COLUMN lmpDate INTEGER NOT NULL DEFAULT 0")
+
+
+ }
+ }
+
+ val MIGRATION_23_24 = object : Migration(23, 24) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE MDSR ADD COLUMN mdsr1File TEXT")
+ database.execSQL("ALTER TABLE MDSR ADD COLUMN mdsr2File TEXT")
+ database.execSQL("ALTER TABLE MDSR ADD COLUMN mdsrDeathCertFile TEXT")
+ }
+ }
+ val MIGRATION_22_23 = object : Migration(22, 23) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ "ALTER TABLE PNC_VISIT ADD COLUMN otherPlaceOfDeath TEXT"
+ )
+ database.execSQL("ALTER TABLE GENERAL_OPD_ACTIVITY ADD COLUMN village TEXT")
+ }
+ }
+
+
+// val MIGRATION_21_22 = object : Migration(21, 22) {
+// override fun migrate(database: SupportSQLiteDatabase) {
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN isDeath INTEGER")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN isDeathValue TEXT")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN dateOfDeath TEXT")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN placeOfDeath TEXT")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN placeOfDeathId INTEGER DEFAULT 0")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN otherPlaceOfDeath TEXT")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN mcp1File TEXT")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN mcp2File TEXT")
+// database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN jsyFile TEXT")
+// }
+// }
+
+
+ val MIGRATION_20_21 = object : Migration(20, 21) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE CDR ADD COLUMN cdr1File TEXT")
+ database.execSQL("ALTER TABLE CDR ADD COLUMN cdr2File TEXT")
+ database.execSQL("ALTER TABLE CDR ADD COLUMN cdrDeathCertFile TEXT")
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `GENERAL_OPD_ACTIVITY` (
+ `benFlowID` INTEGER,
+ `beneficiaryRegID` INTEGER,
+ `benVisitID` INTEGER,
+ `visitCode` INTEGER,
+ `benVisitNo` INTEGER,
+ `nurseFlag` INTEGER,
+ `doctorFlag` INTEGER,
+ `pharmacist_flag` INTEGER,
+ `lab_technician_flag` INTEGER,
+ `radiologist_flag` INTEGER,
+ `oncologist_flag` INTEGER,
+ `specialist_flag` INTEGER,
+ `agentId` TEXT,
+ `visitDate` TEXT,
+ `modified_by` TEXT,
+ `modified_date` TEXT,
+ `benName` TEXT,
+ `deleted` INTEGER,
+ `firstName` TEXT,
+ `lastName` TEXT,
+ `age` TEXT,
+ `ben_age_val` INTEGER,
+ `genderID` INTEGER,
+ `genderName` TEXT,
+ `preferredPhoneNum` TEXT,
+ `fatherName` TEXT,
+ `spouseName` TEXT,
+ `districtName` TEXT,
+ `servicePointName` TEXT,
+ `registrationDate` TEXT,
+ `benVisitDate` TEXT,
+ `consultationDate` TEXT,
+ `consultantID` INTEGER,
+ `consultantName` TEXT,
+ `visitSession` TEXT,
+ `servicePointID` INTEGER,
+ `districtID` INTEGER,
+ `villageID` INTEGER,
+ `vanID` INTEGER,
+ `beneficiaryId` INTEGER NOT NULL,
+ `dob` TEXT,
+ `tc_SpecialistLabFlag` INTEGER,
+ `visitReason` TEXT,
+ `visitCategory` TEXT,
+ PRIMARY KEY(`beneficiaryId`)
+ )
+ """
+ )
+ }
+ }
+ val MIGRATION_19_20 = object : Migration(19, 20) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ db.execSQL("DROP VIEW IF EXISTS BEN_BASIC_CACHE")
+ db.execSQL(
+ "CREATE VIEW `BEN_BASIC_CACHE` AS " +
+ "SELECT b.beneficiaryId as benId, b.motherName as motherName, b.householdId as hhId, b.regDate, b.firstName as benName, b.lastName as benSurname, b.gender, b.dob as dob, b.familyHeadRelationPosition as relToHeadId" +
+ ", b.contactNumber as mobileNo, b.fatherName, h.fam_familyHeadName as familyHeadName, b.gen_spouseName as spouseName, b.rchId, b.gen_lastMenstrualPeriod as lastMenstrualPeriod" +
+ ", b.isHrpStatus as hrpStatus, b.syncState, b.gen_reproductiveStatusId as reproductiveStatusId, b.isKid, b.immunizationStatus" +
+ ", b.loc_village_id as villageId, b.abha_healthIdNumber as abhaId" +
+ ", b.isNewAbha" +
+ ", IFNULL(cbac.benId IS NOT NULL, 0) as cbacFilled, cbac.syncState as cbacSyncState" +
+ ", IFNULL(cdr.benId IS NOT NULL, 0) as cdrFilled, cdr.syncState as cdrSyncState" +
+ ", IFNULL(mdsr.benId IS NOT NULL, 0) as mdsrFilled, mdsr.syncState as mdsrSyncState" +
+ ", IFNULL(pmsma.benId IS NOT NULL, 0) as pmsmaFilled, pmsma.syncState as pmsmaSyncState" +
+ ", IFNULL(hbnc.benId IS NOT NULL, 0) as hbncFilled" +
+ ", IFNULL(hbyc.benId IS NOT NULL, 0) as hbycFilled" +
+ ", IFNULL(pwr.benId IS NOT NULL, 0) as pwrFilled, pwr.syncState as pwrSyncState" +
+ ", IFNULL(pwa.pregnantWomanDelivered, 0) as isDelivered, IFNULL(pwa.hrpConfirmed, 0) as pwHrp" +
+ ", IFNULL(ecr.benId IS NOT NULL, 0) as ecrFilled" +
+ ", IFNULL(ect.benId IS NOT NULL, 0) as ectFilled" +
+ ", IFNULL((pwa.maternalDeath OR do.complication = 'DEATH' OR pnc.motherDeath), 0) as isMdsr" +
+ ", IFNULL(tbsn.benId IS NOT NULL, 0) as tbsnFilled, tbsn.syncState as tbsnSyncState" +
+ ", IFNULL(tbsp.benId IS NOT NULL, 0) as tbspFilled, tbsp.syncState as tbspSyncState" +
+ ", IFNULL(ir.motherBenId IS NOT NULL, 0) as irFilled, ir.syncState as irSyncState" +
+ ", IFNULL(cr.motherBenId IS NOT NULL, 0) as crFilled, cr.syncState as crSyncState" +
+ ", IFNULL(do.benId IS NOT NULL, 0) as doFilled, do.syncState as doSyncState" +
+ ", IFNULL((hrppa.benId IS NOT NULL AND hrppa.noOfDeliveries IS NOT NULL AND hrppa.timeLessThan18m IS NOT NULL AND hrppa.heightShort IS NOT NULL AND hrppa.age IS NOT NULL AND hrppa.rhNegative IS NOT NULL AND hrppa.homeDelivery IS NOT NULL AND hrppa.badObstetric IS NOT NULL AND hrppa.multiplePregnancy IS NOT NULL), 0) as hrppaFilled, hrppa.syncState as hrppaSyncState" +
+ ", IFNULL((hrpnpa.benId IS NOT NULL AND hrpnpa.noOfDeliveries IS NOT NULL AND hrpnpa.timeLessThan18m IS NOT NULL AND hrpnpa.heightShort IS NOT NULL AND hrpnpa.age IS NOT NULL AND hrpnpa.misCarriage IS NOT NULL AND hrpnpa.homeDelivery IS NOT NULL AND hrpnpa.medicalIssues IS NOT NULL AND hrpnpa.pastCSection IS NOT NULL), 0) as hrpnpaFilled, hrpnpa.syncState as hrpnpaSyncState" +
+ ", IFNULL(hrpmbp.benId IS NOT NULL, 0) as hrpmbpFilled, hrpmbp.syncState as hrpmbpSyncState" +
+ ", IFNULL(hrpt.benId IS NOT NULL, 0) as hrptFilled, IFNULL(((count(distinct hrpt.id) > 3) OR (((JulianDay('now')) - JulianDay(date(max(hrpt.visitDate)/1000,'unixepoch','localtime'))) < 1)), 0) as hrptrackingDone, hrpt.syncState as hrptSyncState" +
+ ", IFNULL(hrnpt.benId IS NOT NULL, 0) as hrnptFilled, IFNULL(((JulianDay('now') - JulianDay(date(max(hrnpt.visitDate)/1000,'unixepoch','localtime'))) < 1), 0) as hrnptrackingDone, hrnpt.syncState as hrnptSyncState " +
+ "FROM BENEFICIARY b " +
+ "JOIN HOUSEHOLD h ON b.householdId = h.householdId " +
+ "LEFT OUTER JOIN CBAC cbac ON b.beneficiaryId = cbac.benId " +
+ "LEFT OUTER JOIN CDR cdr ON b.beneficiaryId = cdr.benId " +
+ "LEFT OUTER JOIN MDSR mdsr ON b.beneficiaryId = mdsr.benId " +
+ "LEFT OUTER JOIN PMSMA pmsma ON b.beneficiaryId = pmsma.benId " +
+ "LEFT OUTER JOIN HBNC hbnc ON b.beneficiaryId = hbnc.benId " +
+ "LEFT OUTER JOIN HBYC hbyc ON b.beneficiaryId = hbyc.benId " +
+ "LEFT OUTER JOIN PREGNANCY_REGISTER pwr ON b.beneficiaryId = pwr.benId " +
+ "LEFT OUTER JOIN PREGNANCY_ANC pwa ON b.beneficiaryId = pwa.benId " +
+ "LEFT OUTER JOIN pnc_visit pnc ON b.beneficiaryId = pnc.benId " +
+ "LEFT OUTER JOIN ELIGIBLE_COUPLE_REG ecr ON b.beneficiaryId = ecr.benId " +
+ "LEFT OUTER JOIN ELIGIBLE_COUPLE_TRACKING ect ON (b.beneficiaryId = ect.benId AND CAST((strftime('%s','now') - ect.visitDate/1000)/60/60/24 AS INTEGER) < 30) " +
+ "LEFT OUTER JOIN TB_SCREENING tbsn ON b.beneficiaryId = tbsn.benId " +
+ "LEFT OUTER JOIN TB_SUSPECTED tbsp ON b.beneficiaryId = tbsp.benId " +
+ "LEFT OUTER JOIN HRP_PREGNANT_ASSESS hrppa ON b.beneficiaryId = hrppa.benId " +
+ "LEFT OUTER JOIN HRP_NON_PREGNANT_ASSESS hrpnpa ON b.beneficiaryId = hrpnpa.benId " +
+ "LEFT OUTER JOIN HRP_MICRO_BIRTH_PLAN hrpmbp ON b.beneficiaryId = hrpmbp.benId " +
+ "LEFT OUTER JOIN HRP_NON_PREGNANT_TRACK hrnpt ON b.beneficiaryId = hrnpt.benId " +
+ "LEFT OUTER JOIN HRP_PREGNANT_TRACK hrpt ON b.beneficiaryId = hrpt.benId " +
+ "LEFT OUTER JOIN DELIVERY_OUTCOME do ON b.beneficiaryId = do.benId " +
+ "LEFT OUTER JOIN INFANT_REG ir ON b.beneficiaryId = ir.motherBenId " +
+ "LEFT OUTER JOIN CHILD_REG cr ON b.beneficiaryId = cr.motherBenId " +
+ "WHERE b.isDraft = 0 GROUP BY b.beneficiaryId ORDER BY b.updatedDate DESC"
+ )
+
+ if (tableExists(db, "MALARIA_SCREENING")
+ && !columnExists(db, "MALARIA_SCREENING", "slideTestName")
+ ) {
+ db.execSQL(
+ "ALTER TABLE MALARIA_SCREENING ADD COLUMN slideTestName TEXT"
+ )
+ }
+ }
+ }
+// val MIGRATION_18_19 = object : Migration(18, 19) {
+// override fun migrate(database: SupportSQLiteDatabase) {
+// val columns = listOf(
+// "isDeath INTEGER",
+// "isDeathValue TEXT",
+// "dateOfDeath TEXT",
+// "timeOfDeath TEXT",
+// "reasonOfDeath TEXT",
+// "reasonOfDeathId INTEGER",
+// "placeOfDeath TEXT",
+// "placeOfDeathId INTEGER",
+// "otherPlaceOfDeath TEXT"
+// )
+//
+// for (column in columns) {
+// database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN $column")
+// }
+//
+//
+//
+// // 🔹 Columns for PREGNANCY_ANC table
+// val pregnancyAncColumns = listOf(
+// "serialNo TEXT",
+// "methodOfTermination TEXT",
+// "methodOfTerminationId INTEGER DEFAULT 0 NOT NULL",
+// "terminationDoneBy TEXT",
+// "terminationDoneById INTEGER DEFAULT 0 NOT NULL",
+// "isPaiucdId INTEGER DEFAULT 0 NOT NULL",
+// "isPaiucd TEXT",
+// "remarks TEXT",
+// "abortionImg1 TEXT",
+// "abortionImg2 TEXT",
+// "placeOfDeath TEXT",
+// "placeOfDeathId INTEGER DEFAULT 0 NOT NULL",
+// "otherPlaceOfDeath TEXT"
+// )
+//
+// for (column in pregnancyAncColumns) {
+// database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN $column")
+// }
+//
+// }
+// }
+
+ val MIGRATION_17_18 = object : Migration(17, 18) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `ABHA_GENERATED_NEW` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `beneficiaryID` INTEGER NOT NULL,
+ `beneficiaryRegID` INTEGER NOT NULL,
+ `benName` TEXT NOT NULL,
+ `createdBy` TEXT NOT NULL,
+ `message` TEXT NOT NULL,
+ `txnId` TEXT NOT NULL,
+ `benSurname` TEXT,
+ `healthId` TEXT NOT NULL,
+ `healthIdNumber` TEXT NOT NULL,
+ `abhaProfileJson` TEXT NOT NULL,
+ `isNewAbha` INTEGER NOT NULL,
+ `providerServiceMapId` INTEGER NOT NULL,
+ `syncState` INTEGER NOT NULL,
+ FOREIGN KEY(`beneficiaryID`) REFERENCES `BENEFICIARY`(`beneficiaryId`) ON UPDATE CASCADE ON DELETE CASCADE
+ )
+ """.trimIndent()
+ )
+ try {
+ database.execSQL(
+ """
+ INSERT INTO ABHA_GENERATED_NEW (
+ id,
+ beneficiaryID,
+ beneficiaryRegID,
+ benName,
+ createdBy,
+ message,
+ txnId,
+ benSurname,
+ healthId,
+ healthIdNumber,
+ abhaProfileJson,
+ isNewAbha,
+ providerServiceMapId,
+ syncState
+ )
+ SELECT
+ id,
+ benId AS beneficiaryID,
+ hhId AS beneficiaryRegID,
+ benName,
+ '' AS createdBy,
+ '' AS message,
+ '' AS txnId,
+ benSurname,
+ healthId,
+ healthIdNumber,
+ '' AS abhaProfileJson,
+ isNewAbha,
+ 0,
+ 0
+ FROM ABHA_GENERATED
+ """.trimIndent()
+ )
+ } catch (e: Exception) {
+ Log.w(
+ "RoomMigration",
+ "Skipping data copy: ABHA_GENERATED table not found",
+ e
+ )
+ }
+
+ try {
+ database.execSQL("DROP TABLE IF EXISTS ABHA_GENERATED")
+ } catch (_: Exception) {
+ }
+ database.execSQL("ALTER TABLE ABHA_GENERATED_NEW RENAME TO ABHA_GENERATED")
+ database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_ABHA_GENERATED_beneficiaryID` ON `ABHA_GENERATED` (`beneficiaryID`)")
+ }
+ }
+
+ val MIGRATION_16_18 = object : Migration(16, 18) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS `ABHA_GENERATED_NEW` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ `beneficiaryID` INTEGER NOT NULL,
+ `beneficiaryRegID` INTEGER NOT NULL,
+ `benName` TEXT NOT NULL,
+ `createdBy` TEXT NOT NULL,
+ `message` TEXT NOT NULL,
+ `txnId` TEXT NOT NULL,
+ `benSurname` TEXT,
+ `healthId` TEXT NOT NULL,
+ `healthIdNumber` TEXT NOT NULL,
+ `abhaProfileJson` TEXT NOT NULL,
+ `isNewAbha` INTEGER NOT NULL,
+ `providerServiceMapId` INTEGER NOT NULL,
+ `syncState` INTEGER NOT NULL,
+ FOREIGN KEY(`beneficiaryID`) REFERENCES `BENEFICIARY`(`beneficiaryId`) ON UPDATE CASCADE ON DELETE CASCADE
+ )
+ """.trimIndent()
+ )
+ try {
+ database.execSQL(
+ """
+ INSERT INTO ABHA_GENERATED_NEW (
+ id,
+ beneficiaryID,
+ beneficiaryRegID,
+ benName,
+ createdBy,
+ message,
+ txnId,
+ benSurname,
+ healthId,
+ healthIdNumber,
+ abhaProfileJson,
+ isNewAbha,
+ providerServiceMapId,
+ syncState
+ )
+ SELECT
+ id,
+ benId AS beneficiaryID,
+ hhId AS beneficiaryRegID,
+ benName,
+ '' AS createdBy,
+ '' AS message,
+ '' AS txnId,
+ benSurname,
+ healthId,
+ healthIdNumber,
+ '' AS abhaProfileJson,
+ isNewAbha,
+ 0,
+ 0
+ FROM ABHA_GENERATED
+ """.trimIndent()
+ )
+ } catch (e: Exception) {
+ Log.w(
+ "RoomMigration",
+ "Skipping data copy: ABHA_GENERATED table not found",
+ e
+ )
+ }
+
+ try {
+ database.execSQL("DROP TABLE IF EXISTS ABHA_GENERATED")
+ } catch (_: Exception) {
+ }
+
+ database.execSQL("ALTER TABLE ABHA_GENERATED_NEW RENAME TO ABHA_GENERATED")
+
+ database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_ABHA_GENERATED_beneficiaryID` ON `ABHA_GENERATED` (`beneficiaryID`)")
+ }
+ }
+
+ val MIGRATION_21_22 = object : Migration(21, 22) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS PREGNANCY_ANC_NEW (
+ id INTEGER NOT NULL PRIMARY KEY,
+ benId INTEGER NOT NULL,
+ visitNumber INTEGER NOT NULL,
+ isActive INTEGER NOT NULL,
+ ancDate INTEGER NOT NULL,
+ isAborted INTEGER NOT NULL,
+ abortionType TEXT,
+ abortionTypeId INTEGER NOT NULL,
+ abortionFacility TEXT,
+ abortionFacilityId INTEGER NOT NULL,
+ abortionDate INTEGER,
+ weight INTEGER,
+ bpSystolic INTEGER,
+ bpDiastolic INTEGER,
+ pulseRate TEXT,
+ hb REAL,
+ fundalHeight INTEGER,
+ urineAlbumin TEXT,
+ urineAlbuminId INTEGER NOT NULL,
+ randomBloodSugarTest TEXT,
+ randomBloodSugarTestId INTEGER NOT NULL,
+ numFolicAcidTabGiven INTEGER NOT NULL,
+ numIfaAcidTabGiven INTEGER NOT NULL,
+ anyHighRisk INTEGER,
+ highRisk TEXT,
+ highRiskId INTEGER NOT NULL,
+ otherHighRisk TEXT,
+ referralFacility TEXT,
+ referralFacilityId INTEGER NOT NULL,
+ hrpConfirmed INTEGER,
+ hrpConfirmedBy TEXT,
+ hrpConfirmedById INTEGER NOT NULL,
+ maternalDeath INTEGER,
+ maternalDeathProbableCause TEXT,
+ maternalDeathProbableCauseId INTEGER NOT NULL,
+ otherMaternalDeathProbableCause TEXT,
+ deathDate INTEGER,
+ pregnantWomanDelivered INTEGER,
+ processed TEXT,
+ createdBy TEXT NOT NULL,
+ createdDate INTEGER NOT NULL,
+ updatedBy TEXT NOT NULL,
+ updatedDate INTEGER NOT NULL,
+ syncState INTEGER NOT NULL,
+ frontFilePath TEXT,
+ backFilePath TEXT,
+ FOREIGN KEY(benId) REFERENCES BENEFICIARY(beneficiaryId)
+ ON UPDATE CASCADE ON DELETE CASCADE
+ )
+ """.trimIndent()
+ )
+
+ database.execSQL("DROP VIEW IF EXISTS BEN_BASIC_CACHE")
+ if (tableExists(database, "PREGNANCY_ANC")) {
+ database.execSQL(
+ """
+ INSERT INTO PREGNANCY_ANC_NEW (
+ id, benId, visitNumber, isActive, ancDate, isAborted,
+ abortionType, abortionTypeId, abortionFacility, abortionFacilityId, abortionDate,
+ weight, bpSystolic, bpDiastolic, pulseRate, hb, fundalHeight,
+ urineAlbumin, urineAlbuminId, randomBloodSugarTest, randomBloodSugarTestId,
+ numFolicAcidTabGiven, numIfaAcidTabGiven, anyHighRisk, highRisk, highRiskId,
+ otherHighRisk, referralFacility, referralFacilityId,
+ hrpConfirmed, hrpConfirmedBy, hrpConfirmedById,
+ maternalDeath, maternalDeathProbableCause, maternalDeathProbableCauseId,
+ otherMaternalDeathProbableCause, deathDate, pregnantWomanDelivered,
+ processed, createdBy, createdDate, updatedBy, updatedDate, syncState,
+ frontFilePath, backFilePath
+ )
+ SELECT
+ id, benId, visitNumber, isActive, ancDate, isAborted,
+ abortionType, abortionTypeId, abortionFacility, abortionFacilityId, abortionDate,
+ weight, bpSystolic, bpDiastolic, pulseRate, hb, fundalHeight,
+ urineAlbumin, urineAlbuminId, randomBloodSugarTest, randomBloodSugarTestId,
+ numFolicAcidTabGiven, numIfaAcidTabGiven, anyHighRisk, highRisk, highRiskId,
+ otherHighRisk, referralFacility, referralFacilityId,
+ hrpConfirmed, hrpConfirmedBy, hrpConfirmedById,
+ maternalDeath, maternalDeathProbableCause, maternalDeathProbableCauseId,
+ otherMaternalDeathProbableCause, deathDate, pregnantWomanDelivered,
+ processed, createdBy, createdDate, updatedBy, updatedDate, syncState,
+ NULL AS frontFilePath,
+ NULL AS backFilePath
+ FROM PREGNANCY_ANC
+ """.trimIndent()
+ )
+ database.execSQL("DROP TABLE PREGNANCY_ANC")
+ }
+ database.execSQL("ALTER TABLE PREGNANCY_ANC_NEW RENAME TO PREGNANCY_ANC")
+
+ database.execSQL("CREATE INDEX IF NOT EXISTS ind_mha ON PREGNANCY_ANC(benId)")
+
+ if (tableExists(database, "DELIVERY_OUTCOME")) {
+ if (!columnExists(database, "DELIVERY_OUTCOME", "isDeath")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN isDeath INTEGER DEFAULT 0")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "isDeathValue")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN isDeathValue TEXT")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "dateOfDeath")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN dateOfDeath TEXT")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "placeOfDeath")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN placeOfDeath TEXT")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "placeOfDeathId")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN placeOfDeathId INTEGER DEFAULT 0")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "otherPlaceOfDeath")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN otherPlaceOfDeath TEXT")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "mcp1File")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN mcp1File TEXT")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "mcp2File")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN mcp2File TEXT")
+ }
+ if (!columnExists(database, "DELIVERY_OUTCOME", "jsyFile")) {
+ database.execSQL("ALTER TABLE DELIVERY_OUTCOME ADD COLUMN jsyFile TEXT")
+ }
+ }
+ }
+ }
+
+
+ val MIGRATION_15_16 = object : Migration(15, 16) {
+ override fun migrate(db: SupportSQLiteDatabase) {
+ db.execSQL("DROP VIEW IF EXISTS BEN_BASIC_CACHE")
+
+ db.execSQL(
+ "CREATE VIEW `BEN_BASIC_CACHE` AS " +
+ "SELECT b.beneficiaryId as benId, b.householdId as hhId, b.regDate, b.firstName as benName, b.lastName as benSurname, b.gender, b.dob as dob, b.familyHeadRelationPosition as relToHeadId" +
+ ", b.contactNumber as mobileNo, b.fatherName, h.fam_familyHeadName as familyHeadName, b.gen_spouseName as spouseName, b.rchId, b.gen_lastMenstrualPeriod as lastMenstrualPeriod" +
+ ", b.isHrpStatus as hrpStatus, b.syncState, b.gen_reproductiveStatusId as reproductiveStatusId, b.isKid, b.immunizationStatus" +
+ ", b.loc_village_id as villageId, b.abha_healthIdNumber as abhaId" +
+ ", b.isNewAbha" +
+ ", IFNULL(cbac.benId IS NOT NULL, 0) as cbacFilled, cbac.syncState as cbacSyncState" +
+ ", IFNULL(cdr.benId IS NOT NULL, 0) as cdrFilled, cdr.syncState as cdrSyncState" +
+ ", IFNULL(mdsr.benId IS NOT NULL, 0) as mdsrFilled, mdsr.syncState as mdsrSyncState" +
+ ", IFNULL(pmsma.benId IS NOT NULL, 0) as pmsmaFilled, pmsma.syncState as pmsmaSyncState" +
+ ", IFNULL(hbnc.benId IS NOT NULL, 0) as hbncFilled" +
+ ", IFNULL(hbyc.benId IS NOT NULL, 0) as hbycFilled" +
+ ", IFNULL(pwr.benId IS NOT NULL, 0) as pwrFilled, pwr.syncState as pwrSyncState" +
+ ", IFNULL(pwa.pregnantWomanDelivered, 0) as isDelivered, IFNULL(pwa.hrpConfirmed, 0) as pwHrp" +
+ ", IFNULL(ecr.benId IS NOT NULL, 0) as ecrFilled" +
+ ", IFNULL(ect.benId IS NOT NULL, 0) as ectFilled" +
+ ", IFNULL((pwa.maternalDeath OR do.complication = 'DEATH' OR pnc.motherDeath), 0) as isMdsr" +
+ ", IFNULL(tbsn.benId IS NOT NULL, 0) as tbsnFilled, tbsn.syncState as tbsnSyncState" +
+ ", IFNULL(tbsp.benId IS NOT NULL, 0) as tbspFilled, tbsp.syncState as tbspSyncState" +
+ ", IFNULL(ir.motherBenId IS NOT NULL, 0) as irFilled, ir.syncState as irSyncState" +
+ ", IFNULL(cr.motherBenId IS NOT NULL, 0) as crFilled, cr.syncState as crSyncState" +
+ ", IFNULL(do.benId IS NOT NULL, 0) as doFilled, do.syncState as doSyncState" +
+ ", IFNULL((hrppa.benId IS NOT NULL AND hrppa.noOfDeliveries IS NOT NULL AND hrppa.timeLessThan18m IS NOT NULL AND hrppa.heightShort IS NOT NULL AND hrppa.age IS NOT NULL AND hrppa.rhNegative IS NOT NULL AND hrppa.homeDelivery IS NOT NULL AND hrppa.badObstetric IS NOT NULL AND hrppa.multiplePregnancy IS NOT NULL), 0) as hrppaFilled, hrppa.syncState as hrppaSyncState" +
+ ", IFNULL((hrpnpa.benId IS NOT NULL AND hrpnpa.noOfDeliveries IS NOT NULL AND hrpnpa.timeLessThan18m IS NOT NULL AND hrpnpa.heightShort IS NOT NULL AND hrpnpa.age IS NOT NULL AND hrpnpa.misCarriage IS NOT NULL AND hrpnpa.homeDelivery IS NOT NULL AND hrpnpa.medicalIssues IS NOT NULL AND hrpnpa.pastCSection IS NOT NULL), 0) as hrpnpaFilled, hrpnpa.syncState as hrpnpaSyncState" +
+ ", IFNULL(hrpmbp.benId IS NOT NULL, 0) as hrpmbpFilled, hrpmbp.syncState as hrpmbpSyncState" +
+ ", IFNULL(hrpt.benId IS NOT NULL, 0) as hrptFilled, IFNULL(((count(distinct hrpt.id) > 3) OR (((JulianDay('now')) - JulianDay(date(max(hrpt.visitDate)/1000,'unixepoch','localtime'))) < 1)), 0) as hrptrackingDone, hrpt.syncState as hrptSyncState" +
+ ", IFNULL(hrnpt.benId IS NOT NULL, 0) as hrnptFilled, IFNULL(((JulianDay('now') - JulianDay(date(max(hrnpt.visitDate)/1000,'unixepoch','localtime'))) < 1), 0) as hrnptrackingDone, hrnpt.syncState as hrnptSyncState " +
+ "FROM BENEFICIARY b " +
+ "JOIN HOUSEHOLD h ON b.householdId = h.householdId " +
+ "LEFT OUTER JOIN CBAC cbac ON b.beneficiaryId = cbac.benId " +
+ "LEFT OUTER JOIN CDR cdr ON b.beneficiaryId = cdr.benId " +
+ "LEFT OUTER JOIN MDSR mdsr ON b.beneficiaryId = mdsr.benId " +
+ "LEFT OUTER JOIN PMSMA pmsma ON b.beneficiaryId = pmsma.benId " +
+ "LEFT OUTER JOIN HBNC hbnc ON b.beneficiaryId = hbnc.benId " +
+ "LEFT OUTER JOIN HBYC hbyc ON b.beneficiaryId = hbyc.benId " +
+ "LEFT OUTER JOIN PREGNANCY_REGISTER pwr ON b.beneficiaryId = pwr.benId " +
+ "LEFT OUTER JOIN PREGNANCY_ANC pwa ON b.beneficiaryId = pwa.benId " +
+ "LEFT OUTER JOIN pnc_visit pnc ON b.beneficiaryId = pnc.benId " +
+ "LEFT OUTER JOIN ELIGIBLE_COUPLE_REG ecr ON b.beneficiaryId = ecr.benId " +
+ "LEFT OUTER JOIN ELIGIBLE_COUPLE_TRACKING ect ON (b.beneficiaryId = ect.benId AND CAST((strftime('%s','now') - ect.visitDate/1000)/60/60/24 AS INTEGER) < 30) " +
+ "LEFT OUTER JOIN TB_SCREENING tbsn ON b.beneficiaryId = tbsn.benId " +
+ "LEFT OUTER JOIN TB_SUSPECTED tbsp ON b.beneficiaryId = tbsp.benId " +
+ "LEFT OUTER JOIN HRP_PREGNANT_ASSESS hrppa ON b.beneficiaryId = hrppa.benId " +
+ "LEFT OUTER JOIN HRP_NON_PREGNANT_ASSESS hrpnpa ON b.beneficiaryId = hrpnpa.benId " +
+ "LEFT OUTER JOIN HRP_MICRO_BIRTH_PLAN hrpmbp ON b.beneficiaryId = hrpmbp.benId " +
+ "LEFT OUTER JOIN HRP_NON_PREGNANT_TRACK hrnpt ON b.beneficiaryId = hrnpt.benId " +
+ "LEFT OUTER JOIN HRP_PREGNANT_TRACK hrpt ON b.beneficiaryId = hrpt.benId " +
+ "LEFT OUTER JOIN DELIVERY_OUTCOME do ON b.beneficiaryId = do.benId " +
+ "LEFT OUTER JOIN INFANT_REG ir ON b.beneficiaryId = ir.motherBenId " +
+ "LEFT OUTER JOIN CHILD_REG cr ON b.beneficiaryId = cr.motherBenId " +
+ "WHERE b.isDraft = 0 GROUP BY b.beneficiaryId ORDER BY b.updatedDate DESC"
+ )
+ }
+ }
+
+ val MIGRATION_14_15 = Migration(14, 15, migrate = {
+ it.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN isNewAbha INTEGER NOT NULL DEFAULT 0")
+ it.execSQL("DROP VIEW IF EXISTS BEN_BASIC_CACHE")
+ // it.execSQL("CREATE VIEW BEN_BASIC_CACHE AS " +
+ // "SELECT benId,hhId,regDate,benName,benSurname,gender,dob,relToHeadId,mobileNo,fatherName,familyHeadName,spouseName,rchId,hrpStatus,syncState,reproductiveStatusId, lastMenstrualPeriod,isKid,immunizationStatus,villageId,abhaId,isNewAbha,cbacFilled,cbacSyncState,cdrFilled,cdrSyncState,mdsrFilled,mdsrSyncState,pmsmaSyncState,pmsmaFilled,hbncFilled,hbycFilled,pwrFilled,pwrSyncState,doSyncState,irSyncState,crSyncState,ecrFilled,ectFilled,tbsnFilled,tbsnSyncState,tbspFilled,tbspSyncState,hrppaFilled,hrpnpaFilled,hrpmbpFilled,hrptFilled,hrptrackingDone,hrnptrackingDone,hrnptFilled,hrppaSyncState,hrpnpaSyncState,hrpmbpSyncState,hrptSyncState,hrnptSyncState,isDelivered,pwHrp,irFilled,isMdsr,crFilled,doFilled FROM BENEFICIARY");
+ it.execSQL(
+ "CREATE VIEW BEN_BASIC_CACHE AS " +
+ "SELECT b.beneficiaryId as benId, b.householdId as hhId, b.regDate, " +
+ "b.firstName as benName, b.lastName as benSurname, b.gender, b.dob as dob, " +
+ "b.familyHeadRelationPosition as relToHeadId, b.contactNumber as mobileNo, " +
+ "b.fatherName, h.fam_familyHeadName as familyHeadName, b.gen_spouseName as spouseName, " +
+ "b.rchId, b.gen_lastMenstrualPeriod as lastMenstrualPeriod, b.isHrpStatus as hrpStatus, " +
+ "b.syncState, b.gen_reproductiveStatusId as reproductiveStatusId, b.isKid, b.immunizationStatus, " +
+ "b.loc_village_id as villageId, b.abha_healthIdNumber as abhaId, " +
+ "b.isNewAbha, " + // Added the new column here
+ "cbac.benId is not null as cbacFilled, cbac.syncState as cbacSyncState " +
+ "FROM BENEFICIARY b " +
+ "JOIN HOUSEHOLD h ON b.householdId = h.householdId " +
+ "LEFT OUTER JOIN CBAC cbac on b.beneficiaryId = cbac.benId " +
+ "WHERE b.isDraft = 0 GROUP BY b.beneficiaryId ORDER BY b.updatedDate DESC"
+ )
+
})
val MIGRATION_13_14 = Migration(13, 14, migrate = {
@@ -161,19 +2951,273 @@ abstract class InAppDb : RoomDatabase() {
it.execSQL("alter table HRP_PREGNANT_TRACK add column fastingOgtt INTEGER")
it.execSQL("alter table HRP_PREGNANT_TRACK add column after2hrsOgtt INTEGER")
})
-// _db.execSQL("CREATE TABLE IF NOT EXISTS `HRP_PREGNANT_TRACK` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `benId` INTEGER NOT NULL, `visitDate` INTEGER, `rdPmsa` TEXT, `rdDengue` TEXT, `rdFilaria` TEXT, `severeAnemia` TEXT, `hemoglobinTest` TEXT, `ifaGiven` TEXT, `ifaQuantity` INTEGER, `pregInducedHypertension` TEXT, `systolic` INTEGER, `diastolic` INTEGER, `gestDiabetesMellitus` TEXT, `bloodGlucoseTest` TEXT, `fbg` INTEGER, `rbg` INTEGER, `ppbg` INTEGER, `fastingOgtt` INTEGER, `after2hrsOgtt` INTEGER, `hypothyrodism` TEXT, `polyhydromnios` TEXT, `oligohydromnios` TEXT, `antepartumHem` TEXT, `malPresentation` TEXT, `hivsyph` TEXT, `visit` TEXT, `syncState` INTEGER NOT NULL, FOREIGN KEY(`benId`) REFERENCES `BENEFICIARY`(`beneficiaryId`) ON UPDATE CASCADE ON DELETE CASCADE )");
+
+ val MIGRATION_18_19 = object : Migration(18, 19) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+
+ database.execSQL(
+ """
+ CREATE TABLE IF NOT EXISTS PROFILE_ACTIVITY_new (
+ id INTEGER PRIMARY KEY NOT NULL,
+ name TEXT,
+ profileImage TEXT NOT NULL,
+ village TEXT NOT NULL,
+ employeeId INTEGER NOT NULL,
+ dob TEXT NOT NULL,
+ age INTEGER NOT NULL,
+ mobileNumber TEXT NOT NULL,
+ alternateMobileNumber TEXT NOT NULL,
+ fatherOrSpouseName TEXT NOT NULL,
+ dateOfJoining TEXT NOT NULL,
+ bankAccount TEXT NOT NULL,
+ ifsc TEXT NOT NULL,
+ populationCovered INTEGER NOT NULL,
+ choName TEXT NOT NULL,
+ choMobile TEXT NOT NULL,
+ awwName TEXT NOT NULL,
+ awwMobile TEXT NOT NULL,
+ anm1Name TEXT NOT NULL,
+ anm1Mobile TEXT NOT NULL,
+ anm2Name TEXT NOT NULL,
+ anm2Mobile TEXT NOT NULL,
+ abhaNumber TEXT NOT NULL,
+ ashaHouseholdRegistration TEXT NOT NULL,
+ ashaFamilyMember TEXT NOT NULL,
+ providerServiceMapID TEXT NOT NULL,
+ isFatherOrSpouse INTEGER NOT NULL DEFAULT 0,
+ supervisorName TEXT NOT NULL,
+ supervisorMobile TEXT NOT NULL
+ )
+ """
+ )
+
+ if (tableExists(database, "PROFILE_ACTIVITY")) {
+ database.execSQL(
+ """
+ INSERT INTO PROFILE_ACTIVITY_new (
+ id, name, profileImage, village, employeeId, dob, age,
+ mobileNumber, alternateMobileNumber, fatherOrSpouseName,
+ dateOfJoining, bankAccount, ifsc, populationCovered,
+ choName, choMobile, awwName, awwMobile,
+ anm1Name, anm1Mobile, anm2Name, anm2Mobile,
+ abhaNumber, ashaHouseholdRegistration,
+ ashaFamilyMember, providerServiceMapID,
+ isFatherOrSpouse, supervisorName, supervisorMobile
+ )
+ SELECT
+ id, name, profileImage, village, employeeId, dob, age,
+ mobileNumber, alternateMobileNumber, fatherOrSpouseName,
+ dateOfJoining, bankAccount, ifsc, populationCovered,
+ choName, choMobile, awwName, awwMobile,
+ anm1Name, anm1Mobile, anm2Name, anm2Mobile,
+ abhaNumber, ashaHouseholdRegistration,
+ ashaFamilyMember, providerServiceMapID,
+ isFatherOrSpouse, supervisorName, supervisorMobile
+ FROM PROFILE_ACTIVITY
+ """
+ )
+ }
+
+ database.execSQL("DROP TABLE IF EXISTS PROFILE_ACTIVITY")
+ database.execSQL("ALTER TABLE PROFILE_ACTIVITY_new RENAME TO PROFILE_ACTIVITY")
+
+
+ if (tableExists(database, "BENEFICIARY")) {
+ val beneficiaryColumns = listOf(
+ "isDeath INTEGER NOT NULL DEFAULT 'undefined'",
+ "isDeathValue TEXT",
+ "dateOfDeath TEXT",
+ "timeOfDeath TEXT",
+ "reasonOfDeath TEXT",
+ "reasonOfDeathId INTEGER NOT NULL DEFAULT 0",
+ "placeOfDeath TEXT",
+ "placeOfDeathId INTEGER NOT NULL DEFAULT 'undefined'",
+ "otherPlaceOfDeath TEXT",
+ "isConsent INTEGER NOT NULL DEFAULT 0",
+ "kid_isConsent INTEGER ",
+ "suspectedTb TEXT DEFAULT 'undefined'",
+ "kid_childName TEXT DEFAULT 'undefined'",
+ "loc_country_nameHindi TEXT DEFAULT 'undefined'",
+ "kid_birthOPV INTEGER DEFAULT 'undefined'",
+ "kid_opvDate TEXT DEFAULT 'undefined'",
+ "kid_conductedDelivery TEXT DEFAULT 'undefined'",
+ "kid_conductedDeliveryOther TEXT DEFAULT 'undefined'",
+ "kid_conductedDeliveryId INTEGER DEFAULT 'undefined'",
+ "suspectedHrp TEXT DEFAULT 'undefined'",
+ "familyHeadRelation TEXT DEFAULT 'undefined'",
+ "kid_opvGivenDueDate TEXT DEFAULT 'undefined'",
+ "kid_childMotherName TEXT DEFAULT 'undefined'",
+ "community TEXT DEFAULT 'undefined'",
+ "kid_birthPlace TEXT DEFAULT 'undefined'",
+ "loc_village_nameHindi TEXT DEFAULT 'undefined'",
+ "religionOthers TEXT DEFAULT 'undefined'",
+ "kid_typeOfSchool TEXT DEFAULT 'undefined'",
+ "hrpLastVisitDate TEXT DEFAULT 'undefined'",
+ "kid_typeOfSchoolId INTEGER DEFAULT 'undefined'",
+ "kid_complicationsId INTEGER DEFAULT 'undefined'",
+ "kid_motherPosition INTEGER DEFAULT 'undefined'",
+ "kid_feedingStarted TEXT DEFAULT 'undefined'",
+ "hrpIdentificationDate TEXT DEFAULT 'undefined'",
+ "kid_gestationalAge TEXT DEFAULT 'undefined'",
+ "loc_state_nameHindi TEXT DEFAULT 'undefined'",
+ "suspectedNcdDiseases TEXT DEFAULT 'undefined'",
+ "kid_bcdBatchNo TEXT DEFAULT 'undefined'",
+ "abha_isNewAbha INTEGER DEFAULT 'undefined'",
+ "kid_bcgDate TEXT DEFAULT 'undefined'",
+ "kid_bcgGivenDueDate TEXT DEFAULT 'undefined'",
+ "kid_hptBatchNo TEXT DEFAULT 'undefined'",
+ "loc_state_nameAssamese TEXT DEFAULT 'undefined'",
+ "gen_maritalStatus TEXT DEFAULT 'undefined'",
+ "loc_block_id INTEGER DEFAULT 'undefined'",
+ "syncState INTEGER DEFAULT 'undefined'",
+ "kid_birthPlaceId INTEGER DEFAULT 'undefined'",
+ "kid_birthDosageId INTEGER DEFAULT 'undefined'",
+ "abha_healthIdNumber TEXT DEFAULT 'undefined'",
+ "loc_country_name TEXT DEFAULT 'undefined'",
+ "kid_birthDefectsId INTEGER DEFAULT 'undefined'",
+ "kid_vitaminKGivenDueDate TEXT DEFAULT 'undefined'",
+ "createdDate INTEGER DEFAULT 'undefined'",
+ "kid_birthCertificateFileBackView TEXT DEFAULT 'undefined'",
+ "kid_birthCertificateFileFrontView TEXT DEFAULT 'undefined'",
+ "kid_hptGivenDueDate TEXT DEFAULT 'undefined'",
+ "kid_motherBenId INTEGER DEFAULT 'undefined'",
+ "kid_childRegisteredSchoolId INTEGER DEFAULT 'undefined'",
+ "kid_birthHepB INTEGER DEFAULT 'undefined'",
+ "kid_birthBCG INTEGER DEFAULT 'undefined'",
+ "kid_birthCertificateNumber TEXT DEFAULT 'undefined'",
+ "kid_birthDosage TEXT DEFAULT 'undefined'",
+ "kid_gestationalAgeId INTEGER DEFAULT 'undefined'",
+ "kid_facilityId INTEGER DEFAULT 'undefined'",
+ "kid_opvBatchNo TEXT DEFAULT 'undefined'",
+ "confirmedHrp TEXT DEFAULT 'undefined'",
+ "confirmedTb TEXT DEFAULT 'undefined'",
+ "kid_corticosteroidGivenMother TEXT DEFAULT 'undefined'",
+ "kid_birthDefects TEXT DEFAULT 'undefined'",
+ "kid_deliveryTypeOther TEXT DEFAULT 'undefined'",
+ "kid_deliveryTypeId INTEGER DEFAULT 'undefined'",
+ "kid_term TEXT DEFAULT 'undefined'",
+ "kid_facilityName TEXT DEFAULT 'undefined'",
+ "kid_hptDate TEXT DEFAULT 'undefined'",
+ "kid_vitaminKBatchNo TEXT DEFAULT 'undefined'",
+ "confirmedNcdDiseases TEXT DEFAULT 'undefined'",
+ "processed TEXT DEFAULT 'undefined'",
+ "kid_childRegisteredAWC TEXT DEFAULT 'undefined'",
+ "kid_facilityOther TEXT DEFAULT 'undefined'",
+ "kid_deliveryType TEXT DEFAULT 'undefined'",
+ "kid_heightAtBirth REAL DEFAULT 'undefined'",
+ "kid_weightAtBirth REAL DEFAULT 'undefined'",
+ "kid_placeName TEXT DEFAULT 'undefined'",
+ "tempMobileNoOfRelationId INTEGER NOT NULL DEFAULT 'undefined'"
+ )
+
+ for (column in beneficiaryColumns) {
+ val columnName = column.split(" ")[0]
+ if (!columnExists(database, "BENEFICIARY", columnName)) {
+ database.execSQL("ALTER TABLE BENEFICIARY ADD COLUMN $column")
+ }
+ }
+ }
+
+ if (tableExists(database, "PREGNANCY_ANC")) {
+ val pregnancyAncColumns = listOf(
+ "serialNo TEXT",
+ "methodOfTermination TEXT",
+ "methodOfTerminationId INTEGER NOT NULL DEFAULT 0",
+ "terminationDoneBy TEXT",
+ "terminationDoneById INTEGER NOT NULL DEFAULT 0",
+ "isPaiucdId INTEGER NOT NULL DEFAULT 0",
+ "isPaiucd TEXT",
+ "remarks TEXT",
+ "abortionImg1 TEXT",
+ "abortionImg2 TEXT",
+ "placeOfDeath TEXT",
+ "placeOfDeathId INTEGER NOT NULL DEFAULT 0",
+ "otherPlaceOfDeath TEXT"
+ )
+
+ for (column in pregnancyAncColumns) {
+ val columnName = column.split(" ")[0]
+ if (!columnExists(database, "PREGNANCY_ANC", columnName)) {
+ database.execSQL("ALTER TABLE PREGNANCY_ANC ADD COLUMN $column")
+ }
+ }
+ }
+ }
+ }
+
+
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
- instance = Room.databaseBuilder(
+ val isDebug = appContext.applicationInfo.flags and android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE != 0
+
+ val builder = Room.databaseBuilder(
appContext,
InAppDb::class.java,
"Sakhi-2.0-In-app-database"
)
- .addMigrations(
- MIGRATION_13_14
+
+ if (!isDebug) {
+ val passphrase = DatabaseKeyManager.getDatabasePassphrase(appContext)
+
+ RoomDbEncryptionHelper.encryptIfNeeded(
+ context = appContext,
+ dbName = "Sakhi-2.0-In-app-database",
+ passphrase = passphrase
)
- .build()
+
+ val factory = SupportOpenHelperFactory(String(passphrase).toByteArray(Charsets.UTF_8))
+ builder.openHelperFactory(factory)
+ }
+
+ instance = builder.addMigrations(
+ MIGRATION_13_14,
+ MIGRATION_14_15,
+ MIGRATION_15_16,
+ MIGRATION_16_18,
+ MIGRATION_17_18,
+ MIGRATION_18_19,
+ MIGRATION_19_20,
+ MIGRATION_20_21,
+ MIGRATION_21_22,
+ MIGRATION_22_23,
+ MIGRATION_23_24,
+ MIGRATION_24_25,
+ MIGRATION_25_26,
+ MIGRATION_26_27,
+ MIGRATION_27_28,
+ MIGRATION_28_29,
+ MIGRATION_29_30,
+ MIGRATION_30_31,
+ MIGRATION_31_32,
+ MIGRATION_32_33,
+ MIGRATION_33_34,
+ MIGRATION_34_35,
+ MIGRATION_35_36,
+ MIGRATION_36_37,
+ MIGRATION_37_38,
+ MIGRATION_38_39,
+ MIGRATION_39_40,
+ MIGRATION_40_41,
+ MIGRATION_41_42,
+ MIGRATION_42_43,
+ MIGRATION_43_44,
+ MIGRATION_44_45,
+ MIGRATION_45_46,
+ MIGRATION_46_47,
+ MIGRATION_47_48,
+ MIGRATION_48_49,
+ MIGRATION_49_50,
+ MIGRATION_50_51,
+ MIGRATION_51_52,
+ MIGRATION_52_53,
+ MIGRATION_53_54,
+ MIGRATION_54_55,
+ MIGRATION_55_56,
+ MIGRATION_56_57
+
+
+ ).build()
INSTANCE = instance
}
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/room/NcdReferalDao.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/room/NcdReferalDao.kt
new file mode 100644
index 000000000..ef47b0748
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/room/NcdReferalDao.kt
@@ -0,0 +1,25 @@
+package org.piramalswasthya.sakhi.database.room
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Update
+import org.piramalswasthya.sakhi.model.ReferalCache
+@Dao
+interface NcdReferalDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun upsert(vararg referalCache: ReferalCache)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertAll(referalCache: List)
+ @Update
+ suspend fun update(vararg referalCache: ReferalCache)
+
+ @Query("SELECT * FROM NCD_REFER WHERE benId = :benId LIMIT 1")
+ suspend fun getReferalFromBenId(benId: Long): ReferalCache?
+
+ @Query("SELECT * FROM NCD_REFER WHERE syncState = 0")
+ suspend fun getAllUnprocessedReferals(): List
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/ABHAGenratedDao.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/ABHAGenratedDao.kt
new file mode 100644
index 000000000..499a0e11c
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/ABHAGenratedDao.kt
@@ -0,0 +1,28 @@
+package org.piramalswasthya.sakhi.database.room.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Transaction
+import androidx.room.Update
+import org.piramalswasthya.sakhi.model.ABHAModel
+import org.piramalswasthya.sakhi.model.BenWithABHAGeneratedCache
+
+@Dao
+interface ABHAGenratedDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun saveABHA(abhaModel: ABHAModel)
+ @Update
+ suspend fun updateAbha(abhaModel: ABHAModel)
+
+ @Query("DELETE FROM ABHA_GENERATED WHERE beneficiaryID = :benId")
+ suspend fun deleteAbhaByBenId(benId: Long)
+
+ @Query("SELECT * FROM ABHA_GENERATED")
+ fun getAllAbha(): List
+
+ @Transaction
+ @Query("SELECT * FROM BEN_BASIC_CACHE WHERE benId = :benId")
+ suspend fun getBenWithAbha(benId: Long): BenWithABHAGeneratedCache?
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/AdolescentHealthDao.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/AdolescentHealthDao.kt
new file mode 100644
index 000000000..ef490e19e
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/AdolescentHealthDao.kt
@@ -0,0 +1,26 @@
+package org.piramalswasthya.sakhi.database.room.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import org.piramalswasthya.sakhi.database.room.SyncState
+import org.piramalswasthya.sakhi.model.AdolescentHealthCache
+
+@Dao
+interface AdolescentHealthDao {
+ @Query("SELECT * FROM ADOLESCENT_HEALTH_FORM_DATA WHERE benId =:benId limit 1")
+ suspend fun getAdolescentHealth(benId: Long): AdolescentHealthCache?
+
+ @Query("SELECT * FROM Adolescent_Health_Form_Data WHERE benId =:benId and (visitDate = :visitDate or visitDate = :visitDateGMT) limit 1")
+ suspend fun getAdolescentHealth(benId: Long, visitDate: Long, visitDateGMT: Long): AdolescentHealthCache?
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun saveAdolescentHealth(tbScreeningCache: AdolescentHealthCache)
+
+ @Query("SELECT * FROM Adolescent_Health_Form_Data WHERE syncState = :syncState")
+ suspend fun getAdolescentHealth(syncState: SyncState): List
+
+ @Query("UPDATE Adolescent_Health_Form_Data SET syncState = 0 WHERE syncState = 1")
+ suspend fun resetSyncingToUnsynced()
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/AesDao.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/AesDao.kt
new file mode 100644
index 000000000..d42f607d6
--- /dev/null
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/AesDao.kt
@@ -0,0 +1,26 @@
+package org.piramalswasthya.sakhi.database.room.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import org.piramalswasthya.sakhi.database.room.SyncState
+import org.piramalswasthya.sakhi.model.AESScreeningCache
+import org.piramalswasthya.sakhi.model.MalariaScreeningCache
+
+@Dao
+interface AesDao {
+ @Query("SELECT * FROM AES_SCREENING WHERE benId =:benId limit 1")
+ suspend fun getAESScreening(benId: Long): AESScreeningCache?
+
+ @Query("SELECT * FROM AES_SCREENING WHERE benId =:benId and (visitDate = :visitDate or visitDate = :visitDateGMT) limit 1")
+ suspend fun getAESScreening(benId: Long, visitDate: Long, visitDateGMT: Long): AESScreeningCache?
+
+ @Query("SELECT * FROM AES_SCREENING WHERE syncState = :syncState")
+ suspend fun getAESScreening(syncState: SyncState): List
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun saveAESScreening(malariaScreeningCache: AESScreeningCache)
+
+ @Query("UPDATE AES_SCREENING SET syncState = 0 WHERE syncState = 1")
+ suspend fun resetSyncingToUnsynced()
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/BenDao.kt b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/BenDao.kt
index 5f27cdafa..221b25ee7 100644
--- a/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/BenDao.kt
+++ b/app/src/main/java/org/piramalswasthya/sakhi/database/room/dao/BenDao.kt
@@ -1,6 +1,7 @@
package org.piramalswasthya.sakhi.database.room.dao
import androidx.lifecycle.LiveData
+import androidx.paging.PagingSource
import androidx.room.*
import kotlinx.coroutines.flow.Flow
import org.piramalswasthya.sakhi.database.room.SyncState
@@ -16,37 +17,496 @@ interface BenDao {
@Update
suspend fun updateBen(ben: BenRegCache)
+ @Query("UPDATE BENEFICIARY SET syncState = :unsynced ,processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId")
+ suspend fun updateBenToSync(
+ householdId: Long,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query("UPDATE BENEFICIARY SET isSpouseAdded = 1 , syncState = :unsynced ,processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND familyHeadRelationPosition = 19")
+ suspend fun updateHofSpouseAdded(
+ householdId: Long,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET isChildrenAdded = 1 , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND beneficiaryId = :benId"
+ )
+ suspend fun updateBeneficiaryChildrenAdded(
+ householdId: Long,
+ benId: Long,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET fatherName = :benName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND fatherName = :parentName AND (familyHeadRelationPosition = 9 OR familyHeadRelationPosition = 10)"
+ )
+ suspend fun updateFatherInChildren(
+ benName: String,
+ householdId: Long,
+ parentName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET motherName = :benName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND motherName = :parentName AND (familyHeadRelationPosition = 9 OR familyHeadRelationPosition = 10)"
+ )
+ suspend fun updateMotherInChildren(
+ benName: String,
+ householdId: Long,
+ parentName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET gen_spouseName = :benName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE gen_maritalStatusId = 2 AND householdId = :householdId AND gen_spouseName = :spouseName AND (familyHeadRelationPosition = 5 OR familyHeadRelationPosition = 6)"
+ )
+ suspend fun updateSpouseOfHoF(
+ benName: String,
+ householdId: Long,
+ spouseName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET gen_marriageDate = :marriageDate , gen_ageAtMarriage = :ageAtMarriage, syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND gen_spouseName = :spouseName"
+ )
+ suspend fun updateMarriageAgeOfWife(
+ marriageDate: Long,
+ ageAtMarriage: Int,
+ householdId: Long,
+ spouseName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET gen_marriageDate = :marriageDate , gen_ageAtMarriage = :ageAtMarriage, syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND gen_spouseName = :spouseName"
+ )
+ suspend fun updateMarriageAgeOfHusband(
+ marriageDate: Long,
+ ageAtMarriage: Int,
+ householdId: Long,
+ spouseName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET gen_spouseName = :benName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE gen_maritalStatusId = 2 AND householdId = :householdId AND gen_spouseName = :spouseName"
+ )
+ suspend fun updateSpouse(
+ benName: String,
+ householdId: Long,
+ spouseName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET fatherName = :benName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND fatherName = :parentName"
+ )
+ suspend fun updateFather(
+ benName: String,
+ householdId: Long,
+ parentName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET motherName = :benName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND motherName = :parentName"
+ )
+ suspend fun updateMother(
+ benName: String,
+ householdId: Long,
+ parentName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET firstName = :babyName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND motherName = :parentName AND age < 1"
+ )
+ suspend fun updateBabyName(
+ babyName: String,
+ householdId: Long,
+ parentName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET lastName = :lastName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE gen_maritalStatusId = 2 AND householdId = :householdId AND gen_spouseName = :spouseName"
+ )
+ suspend fun updateSpouseLastName(
+ lastName: String,
+ householdId: Long,
+ spouseName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query(
+ "UPDATE BENEFICIARY " +
+ "SET lastName = :lastName , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND fatherName = :parentName"
+ )
+ suspend fun updateChildrenLastName(
+ lastName: String,
+ householdId: Long,
+ parentName: String,
+ unsynced: SyncState,
+ proccess: String,
+ updateStatus: Int
+ )
+
+ @Query("UPDATE BENEFICIARY SET isSpouseAdded = 1 , syncState = :unsynced , processed = :proccess , serverUpdatedStatus =:updateStatus WHERE householdId = :householdId AND beneficiaryId = :benId")
+ suspend fun updateBeneficiarySpouseAdded(householdId: Long,benId: Long, unsynced: SyncState, proccess: String,
+ updateStatus: Int)
+
@Query("SELECT * FROM BENEFICIARY WHERE isDraft = 1 and householdId =:hhId LIMIT 1")
suspend fun getDraftBenKidForHousehold(hhId: Long): BenRegCache?
- @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage")
+ @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage AND isDeactivate = 0")
fun getAllBen(selectedVillage: Int): Flow>
- @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage and gender = :gender")
+ @Query("""
+ SELECT * FROM BEN_BASIC_CACHE
+ WHERE villageId = :selectedVillage
+ AND isDeactivate = 0
+ AND (:source = 0
+ OR (:source = 1 AND abhaId IS NOT NULL)
+ OR (:source = 2 AND rchId IS NOT NULL AND rchId != '')
+ OR (:source = 3 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) >= 30 AND isDeath = 0)
+ OR (:source = 4 AND gender = 'Female' AND isDeath = 0
+ AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) BETWEEN 20 AND 49
+ AND (reproductiveStatusId = 1 OR reproductiveStatusId = 2))
+ )
+ AND (:filterType = 0
+ OR (:filterType = 1 AND abhaId IS NOT NULL)
+ OR (:filterType = 2 AND abhaId IS NULL)
+ OR (:filterType = 3 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) >= 30 AND isDeath = 0)
+ OR (:filterType = 4 AND gender = 'Female' AND isDeath = 0
+ AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) BETWEEN 20 AND 49
+ AND (reproductiveStatusId = 1 OR reproductiveStatusId = 2))
+ )
+ AND (:query = '' OR
+ benName LIKE '%' || :query || '%'
+ OR benSurname LIKE '%' || :query || '%'
+ OR CAST(mobileNo AS TEXT) LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR REPLACE(IFNULL(abhaId, ''), '-', '') LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR IFNULL(familyHeadName, '') LIKE '%' || :query || '%'
+ OR IFNULL(spouseName, '') LIKE '%' || :query || '%'
+ OR IFNULL(fatherName, '') LIKE '%' || :query || '%'
+ OR CAST(benId AS TEXT) LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR CAST(hhId AS TEXT) LIKE '%' || :query || '%'
+ OR IFNULL(rchId, '') LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ )
+ """)
+ fun searchBen(selectedVillage: Int, source: Int, filterType: Int, query: String): Flow>
+
+ @Query("""
+ SELECT * FROM BEN_BASIC_CACHE
+ WHERE villageId = :selectedVillage
+ AND isDeactivate = 0
+ AND (:source = 0
+ OR (:source = 1 AND abhaId IS NOT NULL)
+ OR (:source = 2 AND rchId IS NOT NULL AND rchId != '')
+ OR (:source = 3 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) >= 30 AND isDeath = 0)
+ OR (:source = 4 AND gender = 'Female' AND isDeath = 0
+ AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) BETWEEN 20 AND 49
+ AND (reproductiveStatusId = 1 OR reproductiveStatusId = 2))
+ )
+ AND (:filterType = 0
+ OR (:filterType = 1 AND abhaId IS NOT NULL)
+ OR (:filterType = 2 AND abhaId IS NULL)
+ OR (:filterType = 3 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) >= 30 AND isDeath = 0)
+ OR (:filterType = 4 AND gender = 'Female' AND isDeath = 0
+ AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) BETWEEN 20 AND 49
+ AND (reproductiveStatusId = 1 OR reproductiveStatusId = 2))
+ )
+ AND (:query = '' OR
+ benName LIKE '%' || :query || '%'
+ OR benSurname LIKE '%' || :query || '%'
+ OR CAST(mobileNo AS TEXT) LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR REPLACE(IFNULL(abhaId, ''), '-', '') LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR IFNULL(familyHeadName, '') LIKE '%' || :query || '%'
+ OR IFNULL(spouseName, '') LIKE '%' || :query || '%'
+ OR IFNULL(fatherName, '') LIKE '%' || :query || '%'
+ OR CAST(benId AS TEXT) LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR CAST(hhId AS TEXT) LIKE '%' || :query || '%'
+ OR IFNULL(rchId, '') LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ )
+ ORDER BY CASE
+ WHEN isDeath = 0 THEN 0
+ WHEN isDeath = 1 THEN 1
+ ELSE 2
+ END
+ """)
+ fun searchBenPaged(selectedVillage: Int, source: Int, filterType: Int, query: String): PagingSource
+
+ @Query("""
+ SELECT * FROM BEN_BASIC_CACHE
+ WHERE villageId = :selectedVillage
+ AND isDeactivate = 0
+ AND (:source = 0
+ OR (:source = 1 AND abhaId IS NOT NULL)
+ OR (:source = 2 AND rchId IS NOT NULL AND rchId != '')
+ OR (:source = 3 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) >= 30 AND isDeath = 0)
+ OR (:source = 4 AND gender = 'Female' AND isDeath = 0
+ AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) BETWEEN 20 AND 49
+ AND (reproductiveStatusId = 1 OR reproductiveStatusId = 2))
+ )
+ AND (:filterType = 0
+ OR (:filterType = 1 AND abhaId IS NOT NULL)
+ OR (:filterType = 2 AND abhaId IS NULL)
+ OR (:filterType = 3 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) >= 30 AND isDeath = 0)
+ OR (:filterType = 4 AND gender = 'Female' AND isDeath = 0
+ AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) BETWEEN 20 AND 49
+ AND (reproductiveStatusId = 1 OR reproductiveStatusId = 2))
+ )
+ AND (:query = '' OR
+ benName LIKE '%' || :query || '%'
+ OR benSurname LIKE '%' || :query || '%'
+ OR CAST(mobileNo AS TEXT) LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR REPLACE(IFNULL(abhaId, ''), '-', '') LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR IFNULL(familyHeadName, '') LIKE '%' || :query || '%'
+ OR IFNULL(spouseName, '') LIKE '%' || :query || '%'
+ OR IFNULL(fatherName, '') LIKE '%' || :query || '%'
+ OR CAST(benId AS TEXT) LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ OR CAST(hhId AS TEXT) LIKE '%' || :query || '%'
+ OR IFNULL(rchId, '') LIKE '%' || REPLACE(:query, ' ', '') || '%'
+ )
+ ORDER BY CASE
+ WHEN isDeath = 0 AND isDeactivate = 0 THEN 0
+ WHEN isDeath = 1 AND isDeactivate = 0 THEN 1
+ WHEN isDeactivate = 1 THEN 2
+ ELSE 4
+ END ASC
+ """)
+ suspend fun searchBenOnce(selectedVillage: Int, source: Int, filterType: Int, query: String): List
+
+ @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage AND abhaId IS NOT NULL AND isDeactivate = 0")
+ fun getAllBenWithAbha(selectedVillage: Int): Flow>
+
+ @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage AND abhaId IS NULL and isDeactivate=0")
+ fun getAllBenWithoutAbha(selectedVillage: Int): Flow>
+
+ @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage AND rchId IS NOT NULL AND rchId != '' AND isDeactivate = 0")
+ fun getAllBenWithRch(selectedVillage: Int): Flow>
+
+ @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage AND isDeactivate = 0 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) >= 30 AND isDeath = 0")
+ fun getAllBenAboveThirty(selectedVillage: Int): Flow>
+
+ @Query("SELECT * FROM BEN_BASIC_CACHE WHERE villageId = :selectedVillage AND isDeactivate=0 AND gender = 'Female' AND isDeath = 0 AND CAST((strftime('%s','now') - dob/1000)/60/60/24/365 AS INTEGER) BETWEEN 20 AND 49 AND (reproductiveStatusId = 1 OR reproductiveStatusId = 2)")
+ fun getAllBenWARA(selectedVillage: Int): Flow>
+
+ @Query("SELECT * FROM BEN_BASIC_CACHE where villageId = :selectedVillage and gender = :gender and isDeactivate=0")
fun getAllBenGender(selectedVillage: Int, gender: String): Flow