use of org.activityinfo.legacy.shared.command.UpdateMonthlyReports in project activityinfo by bedatadriven.
the class UpdateMonthlyReportsAsync method executeUpdates.
private Promise<VoidResult> executeUpdates(SqlTransaction tx, UpdateMonthlyReports command, Map<Month, Integer> periodMap) {
KeyGenerator generator = new KeyGenerator();
List<Promise<Void>> pendingUpdates = new ArrayList<>();
for (UpdateMonthlyReports.Change change : command.getChanges()) {
Integer periodId = periodMap.get(change.getMonth());
if (periodId == null) {
periodId = generator.generateInt();
periodMap.put(change.getMonth(), periodId);
pendingUpdates.add(insertPeriod(tx, command.getSiteId(), periodId, change.getMonth()));
}
pendingUpdates.add(deleteValue(tx, periodId, change.getIndicatorId()));
if (change.getValue() != null) {
pendingUpdates.add(insertValue(tx, periodId, change.getIndicatorId(), change.getValue()));
}
}
return Promise.waitAll(pendingUpdates).then(Functions.<VoidResult>constant(null));
}
use of org.activityinfo.legacy.shared.command.UpdateMonthlyReports in project activityinfo by bedatadriven.
the class MonthlyReportsPanel method save.
public Promise<Void> save() {
ArrayList<UpdateMonthlyReports.Change> changes = new ArrayList<>();
for (Record record : store.getModifiedRecords()) {
IndicatorRowDTO report = (IndicatorRowDTO) record.getModel();
for (String property : record.getChanges().keySet()) {
UpdateMonthlyReports.Change change = new UpdateMonthlyReports.Change();
change.setIndicatorId(report.getIndicatorId());
change.setMonth(IndicatorRowDTO.monthForProperty(property));
change.setValue(report.get(property));
changes.add(change);
}
}
final Promise<Void> promise = new Promise<>();
service.execute(new UpdateMonthlyReports(currentSiteId, changes), new MaskingAsyncMonitor(this, I18N.CONSTANTS.saving()), new AsyncCallback<VoidResult>() {
@Override
public void onFailure(Throwable caught) {
promise.onFailure(caught);
}
@Override
public void onSuccess(VoidResult result) {
store.commitChanges();
promise.onSuccess(null);
}
});
return promise;
}
use of org.activityinfo.legacy.shared.command.UpdateMonthlyReports in project activityinfo by bedatadriven.
the class UpdateMonthlyReportsHandler method execute.
@Override
public CommandResult execute(UpdateMonthlyReports cmd, User user) throws CommandException {
// Phantom Row issue occurs when attempting to update Monthly ReportingPeriods concurrently.
// To prevent this, we introduce a locking mechanism to prevent simultaneous insertions into table which result
// in duplicate reporting periods on the given site.
// Once we have acquired a lock, we can then safely execute the command
acquireLock(cmd.getSiteId());
try {
Site site = em.find(Site.class, cmd.getSiteId());
if (site == null) {
throw new CommandException(cmd, "site " + cmd.getSiteId() + " not found for user " + user.getEmail());
}
if (!permissionOracle.isEditAllowed(site, user)) {
throw new IllegalAccessCommandException("Not authorized to modify sites");
}
Map<Month, ReportingPeriod> periods = Maps.newHashMap();
Map<String, Object> siteHistoryChangeMap = createChangeMap();
for (ReportingPeriod period : site.getReportingPeriods()) {
periods.put(HandlerUtil.monthFromRange(period.getDate1(), period.getDate2()), period);
}
for (UpdateMonthlyReports.Change change : cmd.getChanges()) {
if (!periods.containsKey(change.getMonth())) {
ReportingPeriod period = new ReportingPeriod(site);
period.setId(keyGenerator.generateInt());
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, change.getMonth().getYear());
calendar.set(Calendar.MONTH, change.getMonth().getMonth() - 1);
calendar.set(Calendar.DATE, 1);
period.setDate1(calendar.getTime());
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
period.setDate2(calendar.getTime());
em.persist(period);
periods.put(change.getMonth(), period);
}
}
for (UpdateMonthlyReports.Change change : cmd.getChanges()) {
updateIndicatorValue(em, periods.get(change.getMonth()), change.getIndicatorId(), change.getValue(), false);
siteHistoryChangeMap.put(getPropertyName(change.getIndicatorId(), change.getMonth()), change.getValue());
}
// update the timestamp on the site entity so changes get picked up
// by the synchro mechanism
site.setVersion(site.getActivity().incrementSiteVersion());
siteHistoryProcessor.persistHistory(site, user, ChangeType.UPDATE, siteHistoryChangeMap);
} finally {
releaseLock(cmd.getSiteId());
}
return new VoidResult();
}
use of org.activityinfo.legacy.shared.command.UpdateMonthlyReports in project activityinfo by bedatadriven.
the class MonthlyReportsTest method testUpdate.
@Test
public void testUpdate() throws Exception {
ArrayList<UpdateMonthlyReports.Change> changes = new ArrayList<UpdateMonthlyReports.Change>();
changes.add(new UpdateMonthlyReports.Change(6, new Month(2009, 1), 45.0));
changes.add(new UpdateMonthlyReports.Change(6, new Month(2009, 3), 22.0));
execute(new UpdateMonthlyReports(6, changes));
// verify that that changes have been made
GetMonthlyReports cmd = new GetMonthlyReports(6);
cmd.setStartMonth(new Month(2009, 1));
cmd.setEndMonth(new Month(2009, 3));
MonthlyReportResult result = execute(cmd);
Assert.assertEquals(1, result.getData().size());
Assert.assertEquals(45, result.getData().get(0).getValue(2009, 1).intValue());
Assert.assertEquals(70, result.getData().get(0).getValue(2009, 2).intValue());
Assert.assertEquals(22, result.getData().get(0).getValue(2009, 3).intValue());
}
use of org.activityinfo.legacy.shared.command.UpdateMonthlyReports in project activityinfo by bedatadriven.
the class MonthlyReportsTest method unauthorized.
@Test(expected = CommandException.class)
public void unauthorized() {
// marlene: viewall, but not editall
setUser(4);
ArrayList<UpdateMonthlyReports.Change> changes = new ArrayList<UpdateMonthlyReports.Change>();
changes.add(new UpdateMonthlyReports.Change(6, new Month(2009, 1), 45.0));
changes.add(new UpdateMonthlyReports.Change(6, new Month(2009, 3), 22.0));
execute(new UpdateMonthlyReports(6, changes));
}
Aggregations