public void addActivityAchievement(long userId, long groupId, SocialAchievement achievement)
      throws PortalException, SystemException {

    SocialActivityAchievement activityAchievement =
        socialActivityAchievementPersistence.fetchByG_U_N(groupId, userId, achievement.getName());

    if (activityAchievement != null) {
      return;
    }

    User user = userPersistence.findByPrimaryKey(userId);

    long activityAchievementId = counterLocalService.increment();

    activityAchievement = socialActivityAchievementPersistence.create(activityAchievementId);

    activityAchievement.setGroupId(groupId);
    activityAchievement.setCompanyId(user.getCompanyId());
    activityAchievement.setUserId(userId);
    activityAchievement.setCreateDate(System.currentTimeMillis());

    int count = socialActivityAchievementPersistence.countByG_N(groupId, achievement.getName());

    if (count == 0) {
      activityAchievement.setFirstInGroup(true);
    }

    activityAchievement.setName(achievement.getName());

    socialActivityAchievementPersistence.update(activityAchievement, false);

    socialActivityCounterLocalService.incrementUserAchievementCounter(userId, groupId);
  }
  /**
   * Adds or increments activity counters related to an activity. This method is called
   * asynchronously from the social activity service when the user performs an activity defined in
   * </code>liferay-social.xml</code>.
   *
   * <p>This method first calls the activity processor class, if there is one defined for the
   * activity, checks for limits and increments all the counters that belong to the activity.
   * Afterwards, it processes the activity with respect to achievement classes, if any. Lastly it
   * increments the built-in <code>user.activities</code> and <code>asset.activities</code>
   * counters.
   *
   * @param activity the social activity
   * @throws PortalException if an expected group or expected previous activity counters could not
   *     be found
   */
  @Override
  public void addActivityCounters(SocialActivity activity) throws PortalException {

    if (!socialActivitySettingLocalService.isEnabled(
        activity.getGroupId(), activity.getClassNameId())) {

      return;
    }

    if (!socialActivitySettingLocalService.isEnabled(
        activity.getGroupId(), activity.getClassNameId(), activity.getClassPK())) {

      return;
    }

    if ((activity.getType() == SocialActivityConstants.TYPE_MOVE_ATTACHMENT_TO_TRASH)
        || (activity.getType() == SocialActivityConstants.TYPE_MOVE_TO_TRASH)) {

      disableActivityCounters(activity.getClassNameId(), activity.getClassPK());

      return;
    }

    if ((activity.getType() == SocialActivityConstants.TYPE_RESTORE_ATTACHMENT_FROM_TRASH)
        || (activity.getType() == SocialActivityConstants.TYPE_RESTORE_FROM_TRASH)) {

      enableActivityCounters(activity.getClassNameId(), activity.getClassPK());

      return;
    }

    User user = userPersistence.findByPrimaryKey(activity.getUserId());

    SocialActivityDefinition activityDefinition =
        socialActivitySettingLocalService.getActivityDefinition(
            activity.getGroupId(), activity.getClassName(), activity.getType());

    if ((activityDefinition == null) || !activityDefinition.isCountersEnabled()) {

      return;
    }

    SocialActivityProcessor activityProcessor = activityDefinition.getActivityProcessor();

    if (activityProcessor != null) {
      activityProcessor.processActivity(activity);
    }

    AssetEntry assetEntry = activity.getAssetEntry();

    User assetEntryUser = userPersistence.findByPrimaryKey(assetEntry.getUserId());

    List<SocialActivityCounter> activityCounters = new ArrayList<>();

    for (SocialActivityCounterDefinition activityCounterDefinition :
        activityDefinition.getActivityCounterDefinitions()) {

      if (isAddActivityCounter(user, assetEntryUser, assetEntry, activityCounterDefinition)) {

        SocialActivityCounter activityCounter =
            addActivityCounter(activity.getGroupId(), user, activity, activityCounterDefinition);

        activityCounters.add(activityCounter);
      }
    }

    SocialActivityCounter assetActivitiesCounter = null;

    if (!assetEntryUser.isDefaultUser() && assetEntryUser.isActive() && assetEntry.isVisible()) {

      assetActivitiesCounter = addAssetActivitiesCounter(activity);
    }

    SocialActivityCounter userActivitiesCounter = null;

    if (!user.isDefaultUser() && user.isActive()) {
      userActivitiesCounter = addUserActivitiesCounter(activity);
    }

    for (SocialActivityCounter activityCounter : activityCounters) {
      SocialActivityCounterDefinition activityCounterDefinition =
          activityDefinition.getActivityCounterDefinition(activityCounter.getName());

      if (checkActivityLimit(user, activity, activityCounterDefinition)) {
        incrementActivityCounter(activityCounter, activityCounterDefinition);
      }
    }

    if (assetActivitiesCounter != null) {
      incrementActivityCounter(assetActivitiesCounter, _assetActivitiesActivityCounterDefinition);
    }

    if (userActivitiesCounter != null) {
      incrementActivityCounter(userActivitiesCounter, _userActivitiesActivityCounterDefinition);
    }

    for (SocialAchievement achievement : activityDefinition.getAchievements()) {

      achievement.processActivity(activity);
    }
  }