diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetHistoryDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetHistoryDAO.java index d5beef5c11..723b23563c 100644 --- a/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetHistoryDAO.java +++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetHistoryDAO.java @@ -51,14 +51,23 @@ public TextFlowTargetHistoryDAO(Session session) { * HTextFlowTarget union HTextFlowTargetHistory tables * in a project-version, within given date range group by state and locale. * - * @param versionId - * @param personId - * @param from - * @param to - * @return list of [wordCount][contentState][localeId] + * HTextFlowTargetHistory: + * gets latest of all records translated from user in given version, + * locale and dateRange and its target is not translated by same person. + * + * HTextFlowTarget: + * gets all records translated from user in given version, locale and + * dateRange. + * + * @param versionId HProjectIteration identifier + * @param personId HPerson identifier + * @param from start of date range + * @param to end of date range + * + * @return list of Object[wordCount][contentState][localeId] */ @NativeQuery - public List getUserTranslationHistoryInVersion( + public List getUserContributionStatisticInVersion( Long versionId, Long personId, Date from, Date to) { StringBuilder queryString = new StringBuilder(); @@ -72,8 +81,12 @@ public List getUserTranslationHistoryInVersion( .append("JOIN HTextFlow tf ON tf.id = tft.tf_id ") .append("JOIN HDocument doc ON doc.id = tf.document_Id ") .append("where doc.project_iteration_id =:versionId ") + .append("and h.state <> 0 ") .append("and h.translated_by_id =:personId ") .append("and h.lastChanged between :from and :to ") + .append("and tft.translated_by_id <> h.translated_by_id ") + .append("and h.lastChanged = ") + .append("(select max(lastChanged) from HTextFlowTargetHistory where h.target_id = target_id) ") .append("union all ") .append("select tft.state, tft.id, tft.translated_by_id, tf.wordCount, locale.localeId ") .append("from HTextFlowTarget tft ") @@ -81,8 +94,10 @@ public List getUserTranslationHistoryInVersion( .append("JOIN HTextFlow tf ON tf.id = tft.tf_id ") .append("JOIN HDocument doc ON doc.id = tf.document_Id ") .append("where doc.project_iteration_id =:versionId ") + .append("and tft.state <> 0 ") .append("and tft.translated_by_id =:personId ") - .append("and tft.lastChanged between :from and :to) as target_history_union ") + .append("and tft.lastChanged between :from and :to ") + .append(") as target_history_union ") .append("group by state, id, localeId, wordCount) as target_history_group ") .append("group by state, localeId"); @@ -92,7 +107,7 @@ public List getUserTranslationHistoryInVersion( query.setParameter("personId", personId); query.setTimestamp("from", from); query.setTimestamp("to", to); - query.setComment("textFlowTargetHistoryDAO.getUserTranslationHistoryInVersion"); + query.setComment("textFlowTargetHistoryDAO.getUserContributionStatisticInVersion"); return query.list(); } diff --git a/zanata-war/src/main/java/org/zanata/service/impl/StatisticsServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/StatisticsServiceImpl.java index 5ff66041e1..dd77c87435 100644 --- a/zanata-war/src/main/java/org/zanata/service/impl/StatisticsServiceImpl.java +++ b/zanata-war/src/main/java/org/zanata/service/impl/StatisticsServiceImpl.java @@ -27,7 +27,6 @@ import java.util.Map; import javax.ws.rs.Path; -import javax.ws.rs.core.Response; import lombok.extern.slf4j.Slf4j; @@ -36,7 +35,6 @@ import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; -import org.zanata.common.BaseTranslationCount; import org.zanata.common.ContentState; import org.zanata.common.EntityStatus; import org.zanata.common.LocaleId; @@ -57,6 +55,7 @@ import org.zanata.rest.dto.stats.ContainerTranslationStatistics; import org.zanata.rest.dto.stats.TranslationStatistics; import org.zanata.rest.dto.stats.TranslationStatistics.StatUnit; +import org.zanata.rest.dto.stats.contribution.BaseContributionStatistic; import org.zanata.rest.dto.stats.contribution.ContributionStatistics; import org.zanata.rest.dto.stats.contribution.LocaleStatistics; import org.zanata.rest.service.StatisticsResource; @@ -351,7 +350,7 @@ public ContributionStatistics getContributionStatistics(String projectSlug, LocaleStatistics localeStatistics = new LocaleStatistics(); List data = - textFlowTargetHistoryDAO.getUserTranslationHistoryInVersion( + textFlowTargetHistoryDAO.getUserContributionStatisticInVersion( version.getId(), person.getId(), fromDate, toDate); for (Object[] entry : data) { @@ -359,11 +358,11 @@ public ContributionStatistics getContributionStatistics(String projectSlug, ContentState state = ContentState.values()[(int) entry[1]]; LocaleId localeId = new LocaleId(entry[2].toString()); - BaseTranslationCount stats; + BaseContributionStatistic stats; if (localeStatistics.containsKey(localeId)) { stats = localeStatistics.get(localeId); } else { - stats = new BaseTranslationCount(0,0,0,0,0); + stats = new BaseContributionStatistic(0,0,0,0); } stats.set(state, count); localeStatistics.put(localeId, stats); diff --git a/zanata-war/src/test/java/org/zanata/service/impl/StatisticsServiceImplTest.java b/zanata-war/src/test/java/org/zanata/service/impl/StatisticsServiceImplTest.java index 4485ebab9f..0beee881b8 100644 --- a/zanata-war/src/test/java/org/zanata/service/impl/StatisticsServiceImplTest.java +++ b/zanata-war/src/test/java/org/zanata/service/impl/StatisticsServiceImplTest.java @@ -37,10 +37,8 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.zanata.ZanataDbunitJpaTest; -import org.zanata.common.BaseTranslationCount; import org.zanata.common.ContentState; import org.zanata.common.LocaleId; -import org.zanata.common.TransUnitCount; import org.zanata.dao.PersonDAO; import org.zanata.dao.TextFlowTargetDAO; import org.zanata.exception.InvalidDateParamException; @@ -49,6 +47,7 @@ import org.zanata.rest.NoSuchEntityException; import org.zanata.rest.dto.stats.ContainerTranslationStatistics; import org.zanata.rest.dto.stats.TranslationStatistics; +import org.zanata.rest.dto.stats.contribution.BaseContributionStatistic; import org.zanata.rest.dto.stats.contribution.ContributionStatistics; import org.zanata.rest.dto.stats.contribution.LocaleStatistics; import org.zanata.rest.service.StatisticsResource; @@ -332,7 +331,7 @@ public void getContribStatsSingleTarget() { "sample-project", "1.0", username, todayDate + ".." + todayDate); - BaseTranslationCount stats = + BaseContributionStatistic stats = initialStats.get(username).get(target.getLocaleId()); // Should have no stats for user on today @@ -340,7 +339,7 @@ public void getContribStatsSingleTarget() { // needReview -> approved ContributionStatistics expectedStats = new ContributionStatistics(); - expectedStats.put(username, buildStats(target.getLocaleId(), 0, 0, 0, + expectedStats.put(username, buildStats(target.getLocaleId(), 0, 0, wordCount, 0)); target = executeStateChangeTest(target, "test1", ContentState.Approved, demoPerson, expectedStats); @@ -354,17 +353,10 @@ public void getContribStatsSingleTarget() { demoPerson, expectedStats); // approved -> needReview - expectedStats.put(username, buildStats(target.getLocaleId(), 0, - wordCount, 0, wordCount, 0)); + expectedStats.put(username, buildStats(target.getLocaleId(), wordCount, + 0, 0, 0)); target = executeStateChangeTest(target, "test4", ContentState.NeedReview, demoPerson, expectedStats); - - // needReview -> new - expectedStats.put(username, buildStats(target.getLocaleId(), wordCount, - wordCount, 0, wordCount, 0)); - target = executeStateChangeTest(target, "", ContentState.New, - demoPerson, expectedStats); - } @Test @@ -388,25 +380,25 @@ public void getContribStatsSameLocaleMultiTargets() { ContentState newState = ContentState.Approved; ContributionStatistics expectedStats = new ContributionStatistics(); - expectedStats.put(username, buildStats(localeId, 0, 0, 0, + expectedStats.put(username, buildStats(localeId, 0, 0, wordCount1, 0)); target1 = executeStateChangeTest(target1, "test1", newState, demoPerson, expectedStats); - expectedStats.put(username, buildStats(localeId, 0, 0, 0, + expectedStats.put(username, buildStats(localeId, 0, 0, wordCount1 + wordCount2, 0)); target2 = executeStateChangeTest(target2, "test1", newState, demoPerson, expectedStats); // approved -> needReview newState = ContentState.NeedReview; - expectedStats.put(username, buildStats(localeId, 0, wordCount1, 0, - wordCount1 + wordCount2, 0)); + expectedStats.put(username, buildStats(localeId, wordCount1, 0, + wordCount1, 0)); target1 = executeStateChangeTest(target1, "test2", newState, demoPerson, expectedStats); - expectedStats.put(username, buildStats(localeId, 0, - wordCount1 + wordCount2, 0, wordCount1 + wordCount2, 0)); + expectedStats.put(username, buildStats(localeId, wordCount1 + wordCount2, + 0, 0, 0)); target2 = executeStateChangeTest(target2, "test2", newState, demoPerson, expectedStats); } @@ -430,37 +422,75 @@ public void getContributionStatisticsMultiLocale() { ContentState newState = ContentState.Approved; ContributionStatistics expectedStats = new ContributionStatistics(); - expectedStats.put(username, buildStats(target1.getLocaleId(), 0, 0, 0, + expectedStats.put(username, buildStats(target1.getLocaleId(), 0, 0, wordCount1, 0)); target1 = executeStateChangeTest(target1, "test1", newState, demoPerson, expectedStats); expectedStats.get(username).putAll(buildStats(target2.getLocaleId(), 0, - 0, 0, wordCount2, 0)); + 0, wordCount2, 0)); target2 = executeStateChangeTest(target2, "test1", newState, demoPerson, expectedStats); // approved -> needReview newState = ContentState.NeedReview; - BaseTranslationCount localeStat = expectedStats.get(username) + BaseContributionStatistic localeStat = expectedStats.get(username) .get(target1.getLocaleId()); localeStat.set(newState, localeStat.get(newState) + wordCount1); + localeStat.set(ContentState.Approved, 0); target1 = executeStateChangeTest(target1, "test2", newState, demoPerson, expectedStats); localeStat = expectedStats.get(username).get(target2.getLocaleId()); localeStat.set(newState, localeStat.get(newState) + wordCount2); + localeStat.set(ContentState.Approved, 0); target2 = executeStateChangeTest(target2, "test2", newState, demoPerson, expectedStats); } - private LocaleStatistics buildStats(LocaleId localeId, int untranslated, - int needReview, int translated, int approved, int rejected) { + @Test + public void getContribStatsDiffUser() { + PersonDAO personDAO = seam.autowire(PersonDAO.class); + + String username1 = "demo"; + String username2 = "admin"; + HPerson person1 = personDAO.findByUsername(username1); + HPerson person2 = personDAO.findByUsername(username2); + + HTextFlowTarget target = textFlowTargetDAO.findById(1L); + + int wordCount = target.getTextFlow().getWordCount().intValue(); + + ContentState newState = ContentState.Approved; + + ContributionStatistics expectedStats = new ContributionStatistics(); + expectedStats.put(username1, buildStats(target.getLocaleId(), 0, 0, + wordCount, 0)); + target = executeStateChangeTest(target, "test1", + newState, person1, expectedStats); + + ContributionStatistics expectedStats2 = new ContributionStatistics(); + expectedStats2.put(username2, buildStats(target.getLocaleId(), 0, 0, + wordCount, 0)); + target = executeStateChangeTest(target, "test2", + newState, person2, expectedStats2); + + //Test person1 statistic has not changed + String todayDate = formatter.format(today); + ContributionStatistics newStats = + statisticsService.getContributionStatistics( + "sample-project", "1.0", person1.getAccount() + .getUsername(), todayDate + ".." + todayDate); + assertThat(newStats).isEqualTo(expectedStats); + } + + private LocaleStatistics buildStats(LocaleId localeId, int needReview, + int translated, int approved, int rejected) { LocaleStatistics localeStatistics = new LocaleStatistics(); - localeStatistics.put(localeId, new TransUnitCount(approved, needReview, - untranslated, translated, rejected)); + localeStatistics.put(localeId, new BaseContributionStatistic(approved, + needReview, translated, rejected)); return localeStatistics; }