Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
e03662c
Adapt data importer for GGW
brianbrix Feb 13, 2026
e482b9b
Add xml patch for Menu item
brianbrix Feb 13, 2026
4127921
Add indicator configuration for import
brianbrix Feb 13, 2026
3fba4c6
Add program if missing and attach to activity; including percentages
brianbrix Feb 14, 2026
d2a3bcb
Use constants for common strings
brianbrix Feb 15, 2026
d308833
Activity status getOrCreate
brianbrix Feb 15, 2026
2e82e7c
Use indicator Location column
brianbrix Feb 16, 2026
d4bcfa5
Use indicator Location column
brianbrix Feb 16, 2026
bf722b0
Use indicator Location column
brianbrix Feb 16, 2026
b2acdf4
Correct location ID
brianbrix Feb 16, 2026
f7eeee4
Usse Project Location field instead of Location
brianbrix Feb 16, 2026
babda87
Enable edit of column pair config
brianbrix Feb 16, 2026
661fded
Enable edit of column pair config
brianbrix Feb 16, 2026
88d9c3d
Enable edit of column pair config
brianbrix Feb 16, 2026
068afbe
Enable edit of column pair config
brianbrix Feb 16, 2026
ae0a3a0
Change session acquisition
brianbrix Feb 16, 2026
b664050
Change session acquisition
brianbrix Feb 16, 2026
8c12511
Change session acquisition
brianbrix Feb 16, 2026
b2f4652
Multiple locations
brianbrix Feb 16, 2026
e242a02
Append indicators
brianbrix Feb 16, 2026
16bf3ab
Append indicators
brianbrix Feb 16, 2026
feafa26
Append indicators
brianbrix Feb 16, 2026
df952cb
Append indicators
brianbrix Feb 16, 2026
7dd0811
Merge fundings
brianbrix Feb 16, 2026
89b253d
Merge fundings
brianbrix Feb 16, 2026
0ee99f3
Merge fundings
brianbrix Feb 16, 2026
e9ecb60
Add location to indicator actual value
brianbrix Feb 16, 2026
236c55c
Add location to indicator actual value
brianbrix Feb 16, 2026
363c276
Remove documents
brianbrix Feb 16, 2026
79a7c31
Try resolve thread issue
brianbrix Feb 17, 2026
977c8bf
Try resolve thread issue
brianbrix Feb 17, 2026
c4c30fb
Try resolve thread issue
brianbrix Feb 17, 2026
93652d0
Try resolve thread issue
brianbrix Feb 17, 2026
ec07560
Try resolve thread issue
brianbrix Feb 17, 2026
94e4f61
Try resolve thread issue
brianbrix Feb 17, 2026
9510657
Try resolve thread issue
brianbrix Feb 17, 2026
400b956
Try resolve thread issue
brianbrix Feb 17, 2026
842ac1c
Check for existing actual value before adding
brianbrix Feb 17, 2026
1818f77
Check for existing actual value before adding
brianbrix Feb 17, 2026
e18f6f2
Try resolve thread issue
brianbrix Feb 17, 2026
e529e52
Try resolve thread issue
brianbrix Feb 17, 2026
be5c0b7
Try resolve thread issue
brianbrix Feb 17, 2026
6a9c180
Try resolve thread issue
brianbrix Feb 17, 2026
1060ed6
Increase currency project column
brianbrix Feb 17, 2026
957aec0
Increase currency project column
brianbrix Feb 17, 2026
328c973
Try resolve threadcontext issue
brianbrix Feb 17, 2026
a50c0a3
Try resolve threadcontext issue
brianbrix Feb 17, 2026
2796c5f
Try resolve threadcontext issue
brianbrix Feb 17, 2026
833652e
record trnsaction date as now for missing
brianbrix Feb 17, 2026
af1c658
record trnsaction date as now for missing
brianbrix Feb 17, 2026
e238888
record trnsaction date as now for missing
brianbrix Feb 17, 2026
d00e6f0
Try resolve threadcontext issue
brianbrix Feb 17, 2026
d869c25
Try resolve threadcontext issue
brianbrix Feb 17, 2026
91692cb
Try resolve threadcontext issue
brianbrix Feb 17, 2026
1c572fe
Avoid duplicate transactions
brianbrix Feb 18, 2026
d617bac
Avoid duplicate transactions
brianbrix Feb 18, 2026
f0de89f
Add importer guide
brianbrix Feb 19, 2026
ed8a84e
Add importer guide
brianbrix Feb 19, 2026
90b492a
Add importer guide
brianbrix Feb 19, 2026
eef24ce
Update the importer to optinally skip existing activities
brianbrix Mar 5, 2026
73d2311
Update the importer to optinally skip existing activities
brianbrix Mar 5, 2026
7dcc101
Update the importer to optinally skip existing activities
brianbrix Mar 5, 2026
31c70b5
Resolve deployment issues
brianbrix Mar 5, 2026
3e608e1
Resolve deployment issues
brianbrix Mar 5, 2026
bdb528f
Resolve deployment issues
brianbrix Mar 6, 2026
ad5da27
Resolve deployment issues
brianbrix Mar 6, 2026
b10e987
Resolve deployment issues
brianbrix Mar 6, 2026
0ca6a11
Update the importer to accomodate multiple values
brianbrix Mar 6, 2026
5fe36d6
Update the importer to accomodate multiple values
brianbrix Mar 6, 2026
172399f
Update the importer to accomodate multiple values
brianbrix Mar 6, 2026
00851ff
Update the importer to accomodate multiple values
brianbrix Mar 6, 2026
8265482
Update the importer to accomodate multiple values
brianbrix Mar 6, 2026
cfe3e24
Update the importer to accomodate multiple values
brianbrix Mar 6, 2026
0c8d763
Update the importer to accomodate multiple values
brianbrix Mar 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,12 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 60 # Add timeout to prevent hanging jobs
steps:
- name: Setup SSH agent for Docker build
- name: Setup SSH agent with build and deploy keys
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.DOCKER_BUILD_SSH_KEY || '' }}

- name: Add deployment SSH key to agent
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
ssh-private-key: |
${{ secrets.DOCKER_BUILD_SSH_KEY }}
${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}

- name: Configure git to use SSH for submodules
run: |
Expand Down Expand Up @@ -520,6 +517,13 @@ jobs:
echo "IMAGE=$IMAGE_BY_TAG" >> $GITHUB_ENV
fi

- name: Debug SSH agent
if: steps.check_image.outputs.SKIP_BUILD == 'false'
run: |
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK"
ssh-add -l || echo "No keys in agent"
ssh -o StrictHostKeyChecking=no -T git@github.com 2>&1 || true

- name: Build Docker image
if: steps.check_image.outputs.SKIP_BUILD == 'false'
env:
Expand All @@ -533,7 +537,7 @@ jobs:
# Build SSH args - only add if SSH_AUTH_SOCK is available (from ssh-agent)
SSH_ARGS=""
if [ -n "$SSH_AUTH_SOCK" ]; then
SSH_ARGS="--ssh default"
SSH_ARGS="--ssh default=$SSH_AUTH_SOCK"
fi

# Collect cache sources for better layer reuse
Expand Down
6 changes: 5 additions & 1 deletion amp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ COPY --from=compile-amp-filter /tmp/amp/TEMPLATE/ampTemplate/node_modules/amp-fi
COPY --from=compile-amp-settings /tmp/amp/TEMPLATE/ampTemplate/node_modules/amp-settings ../ampTemplate/node_modules/amp-settings
# Copy package files for dependency installation
COPY TEMPLATE/reampv2/package*.json ./
COPY TEMPLATE/reampv2/packages/ampoffline/package.json ./packages/ampoffline/package.json
COPY TEMPLATE/reampv2/packages/container/package.json ./packages/container/package.json
COPY TEMPLATE/reampv2/packages/reampv2-app/package.json ./packages/reampv2-app/package.json
COPY TEMPLATE/reampv2/packages/user-manager/package.json ./packages/user-manager/package.json
RUN --mount=type=cache,target=/root/.npm \
--mount=type=ssh \
npm-install-with-retry.sh
Expand Down Expand Up @@ -252,4 +256,4 @@ LABEL "branch"=$AMP_BRANCH
ENV AMP_REGISTRY_PRIVATE_KEY $AMP_REGISTRY_PRIVATE_KEY

RUN rm -fr /usr/local/tomcat/webapps/ROOT
COPY --from=compile-mvn /tmp/amp/exploded /usr/local/tomcat/webapps/ROOT/
COPY --from=compile-mvn /tmp/amp/exploded /usr/local/tomcat/webapps/ROOT/
3 changes: 1 addition & 2 deletions amp/src/main/java/org/dgfoundation/amp/ar/ArConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,7 @@ public final class ArConstants {
// public final static String EXECUTING_AGENCY_PERCENTAGE="Eexecuting Agency Percentage";


//burkina
// public final static String PROGRAM_PERCENTAGE="Program Percentage";
public final static String PROGRAM_PERCENTAGE="Program Percentage";



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public static JsonApiResponse<ActivitySummary> importActivity(Map<String, Object
.getResult();
}


private static Long getFMTemplateId(Map<String, Object> newJson) {
if (AmpClientModeHolder.isOfflineClient()) {
Workspace team = TeamUtil.getWorkspace(Long.parseLong(newJson.get("team").toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ public class SectorSchemeDTO {
private final SectorDTO[] children;

public SectorSchemeDTO(AmpSectorScheme scheme, SectorDTO[] children) {
this.ampSecSchemeId = scheme.getAmpSecSchemeId();
this.secSchemeCode = scheme.getSecSchemeCode();
this.secSchemeName = scheme.getSecSchemeName();
this.showInRMFilters = scheme.getShowInRMFilters();
this.used = scheme.isUsed();
this.children = children;
this.ampSecSchemeId = scheme != null ? scheme.getAmpSecSchemeId() : null;
this.secSchemeCode = scheme != null ? scheme.getSecSchemeCode() : null;
this.secSchemeName = scheme != null ? scheme.getSecSchemeName() : null;
this.showInRMFilters = Boolean.TRUE.equals(scheme != null ? scheme.getShowInRMFilters() : null);
this.used = scheme != null && scheme.isUsed();
this.children = children != null ? children : new SectorDTO[0];
}

public Long getAmpSecSchemeId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,88 @@ public MEIndicatorDTO getMEIndicatorById(final Long indicatorId) {
throw new ApiRuntimeException(BAD_REQUEST,
ApiError.toError("Indicator with id " + indicatorId + " not found"));
}
public MEIndicatorDTO getMeIndicatorByNameAndProgramName(String name, String programName) {
Session session = PersistenceManager.getSession();
AmpIndicator indicator;
if (programName==null){
indicator = (AmpIndicator) session.createCriteria(AmpIndicator.class)
.add(Restrictions.eq("name", name))
.setMaxResults(1)
.uniqueResult();
}
else {
indicator = (AmpIndicator) session.createCriteria(AmpIndicator.class)
.add(Restrictions.eq("name", name))
.createAlias("program", "p")
.add(Restrictions.eq("p.name", programName))
.setMaxResults(1)
.uniqueResult();
}



if (indicator != null) {
return new MEIndicatorDTO(indicator);
}

throw new ApiRuntimeException(BAD_REQUEST,
ApiError.toError("Indicator with name " + name + " and program name " + programName + " not found"));
}

/**
* Returns the indicator by name and optional program name, or null if not found.
* Use this when you need to look up an indicator without throwing (e.g. data import).
* Tries exact name match first; if not found, looks for an indicator whose name contains
* the given name (e.g. DB "1.2.1 - Number of ... - 1.2.1" matches file "Number of ...").
*/
public MEIndicatorDTO getMeIndicatorByNameAndProgramNameOptional(String name, String programName) {
if (name == null || name.trim().isEmpty()) {
return null;
}
String trimmedName = name.trim();
String trimmedProgram = programName != null && !programName.trim().isEmpty() ? programName.trim() : null;
try {
return getMeIndicatorByNameAndProgramName(trimmedName, trimmedProgram);
} catch (ApiRuntimeException e) {
logger.info("getMeIndicatorByNameAndProgramNameOptional: exact match not found, trying substring match for name='" + trimmedName + "' programName='" + trimmedProgram + "'");

// exact match not found, try substring match (e.g. DB "1.2.1 - X - 1.2.1" vs file "X")
}
return getMeIndicatorByNameSubstringOptional(trimmedName, trimmedProgram);
}

/**
* Finds an indicator whose stored name contains the given name (e.g. "1.2.1 - X - 1.2.1" contains "X").
* Returns null if none or multiple matches (when program not specified), or the match when program is specified.
*/
private MEIndicatorDTO getMeIndicatorByNameSubstringOptional(String name, String programName) {
Session session = PersistenceManager.getSession();
String escaped = escapeForLike(name);
String pattern = "%" + escaped + "%";
String hql = "from " + AmpIndicator.class.getName() + " i where i.name like :name escape '\\'";
if (programName != null) {
hql += " and i.program is not null and i.program.name = :programName";
}
org.hibernate.query.Query<?> query = session.createQuery(hql);
query.setParameter("name", pattern);
if (programName != null) {
query.setParameter("programName", programName);
}
@SuppressWarnings("unchecked")
List<AmpIndicator> list = (List<AmpIndicator>) query.list();
if (list == null || list.isEmpty()) {
return null;
}
if (list.size() > 1 && programName == null) {
logger.warn("getMeIndicatorByNameSubstringOptional: multiple indicators contain name substring '" + name + "', returning first");
}
return new MEIndicatorDTO(list.get(0));
}

private static String escapeForLike(String s) {
if (s == null) return null;
return s.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_");
}

public MEIndicatorDTO createMEIndicator(final MEIndicatorDTO indicatorRequest) {
Session session = PersistenceManager.getSession();
Expand Down Expand Up @@ -167,6 +249,12 @@ private void validateYear(MEIndicatorDTO value) {
}

private void validateYearRange(String startYear, String endYear, AmpIndicatorGlobalValue value, String error){
if (value == null) {
return;
}
if (startYear == null || endYear == null) {
return;
}
String startInString = "01/01/" + startYear;
DateTime dateTime = DateTime.parse(startInString, formatter);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -881,4 +881,4 @@ public static <R> R doInTransaction(Function<Session, R> fn) {
PersistenceManager.closeSession(session);
}
}
}
}
Loading