<commit_before>package com.ext.portlet.service.impl;

import java.util.Collection;
import java.util.List;

import org.xcolab.points.DistributionStrategy;
import org.xcolab.points.PointsTarget;
import org.xcolab.points.ReceiverLimitationStrategy;

import com.ext.portlet.model.Contest;
import com.ext.portlet.model.ContestPhase;
import com.ext.portlet.model.PointDistributionTarget;
import com.ext.portlet.model.PointType;
import com.ext.portlet.model.Points;
import com.ext.portlet.model.Proposal;
import com.ext.portlet.service.base.PointsLocalServiceBaseImpl;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;

/**
 * The implementation of the points local service.
 *
 * <p>
 * All custom service methods should be put in this class. Whenever methods are added, rerun ServiceBuilder to copy their definitions into the {@link com.ext.portlet.service.PointsLocalService} interface.
 *
 * <p>
 * This is a local service. Methods of this service will not have security checks based on the propagated JAAS credentials because this service can only be accessed from within the same VM.
 * </p>
 *
 * @author <NAME>
 * @see com.ext.portlet.service.base.PointsLocalServiceBaseImpl
 * @see com.ext.portlet.service.PointsLocalServiceUtil
 */
public class PointsLocalServiceImpl extends PointsLocalServiceBaseImpl {
	
	private final static Log _log = LogFactoryUtil.getLog(PointsLocalServiceImpl.class);
	
	/**
	 * Returns number of materialized points for given user.
	 * 
	 * @param userId
	 * @return
	 * @throws SystemException
	 */
	public int getUserMaterializedPoints(long userId) throws SystemException {
		int count = 0;
		for (Points points: pointsPersistence.findByUserId(userId)) {
			count += points.getMaterializedPoints();
		}
		return count;
	}
	
	/**
	 * Returns number of points for hypothetical user. 
	 * 
	 * @param userId
	 * @return
	 * @throws SystemException
	 */
	public long getUserHypotheticalPoints(long userId) throws SystemException {
		int count = 0;
		for (Points points: pointsPersistence.findByUserId(userId)) {
			count += points.getHypotheticalPoints();
		}
		return count;
	}
	
	/**
	 * Distribute points for given contest
	 * 
	 * @param contestPK
	 * @throws SystemException 
	 * @throws PortalException 
	 */
	public void distributePoints(long contestPK) throws PortalException, SystemException {
		Contest contest = contestLocalService.getContest(contestPK);
		ContestPhase latestPhase = contestLocalService.getActiveOrLastPhase(contest);
		
		// clean up old data
		pointsPersistence.removeByOriginatingContestPK(contestPK);
		
		for (Points points: pointsPersistence.findByOriginatingContestPK(contestPK)) {
			deletePoints(points);
		}
		
		PointType pointType = pointTypeLocalService.getPointType(contest.getDefaultParentPointType());

        boolean calculatePointsForAllProposals = true;

		if (contestLocalService.hasContestEnded(contest)) {
            calculatePointsForAllProposals = false;
			// check if distribution targets have been defined manually
			Collection<PointDistributionTarget> distributionTargets = pointDistributionTargetPersistence.findByContestId(contestPK);
			if (distributionTargets.isEmpty()) {
				// distribution targets haven't been defined - distribute points to the winner
				Proposal proposal = contestLocalService.getWinnerProposal(contestPK);
                if (proposal != null) {
                    distributePointsToProposal(proposal, contest, 0, pointType, 0, contest.getPoints());
                } else {
                    //no winner is selected: calculate points for each proposal
                    calculatePointsForAllProposals = true;
                }
			}
			else {
				for (PointDistributionTarget pdt: distributionTargets) {
					Proposal proposal = proposalLocalService.getProposal(pdt.getProposalId());
					if (! proposal.isVisible()) {
						continue;
					}
					PointType pointTypeToUse = pointType;
					if (pdt.getPointTypeOverride() > 0) {
						pointTypeToUse = pointTypeLocalService.getPointType(pdt.getPointTypeOverride());
					}

					distributePointsToProposal(proposal, contest, 0, pointTypeToUse, 0, pdt.getNumberOfPoints());
				}
			}
			
		}
		if (calculatePointsForAllProposals) {
			// apply points to all of the proposals
			for (Proposal proposal: proposalLocalService.getProposalsInContest(contestPK)) {
				distributePointsToProposal(proposal, contest, 0, pointType, 0, contest.getPoints());
				
			}
		}
	}
	
	private void distributePointsToProposal(Proposal proposal, 
			Contest originatingContest, 
			long pointsSourceId, 
			PointType pointType, 
			double materializedPoints,
			double hypotheticalPoints) throws SystemException, PortalException {
        String logString = proposal.getProposalId() + ". originatingContest: " + originatingContest.getContestPK() +
                " pointsSourceId: " + pointsSourceId + " pointType: " + pointType + " materializedPoints: " + materializedPoints +
                " hypotheticalPoints: " + hypotheticalPoints;
        if (hypotheticalPoints < 1 && materializedPoints < 1) {
            _log.info("Points left to be distributed are less than 1 for proposal: " + logString);
            return;
        }
		
		_log.info("Distributing points to proposal: " + logString);
		
		DistributionStrategy distributionStrategy = DistributionStrategy.valueOf(pointType.getDistributionStrategy());
		ReceiverLimitationStrategy receiverLimitationStrategy = ReceiverLimitationStrategy.valueOf(pointType.getReceiverLimitationStrategy());
		
		if (distributionStrategy == DistributionStrategy.DEFINED_BY_CHILDREN_PERCENTAGES) {
			for (PointType subPointType: pointTypePersistence.findByParentPointTypeId(pointType.getId())) {
				distributePointsToProposal(proposal, 
						originatingContest, 
						pointsSourceId, 
						subPointType, 
						materializedPoints * subPointType.getPercentageOfParent(), 
						hypotheticalPoints * subPointType.getPercentageOfParent());
			}
			return;
		}
		
		List<PointsTarget> targets = receiverLimitationStrategy.getTargets(proposal, pointType, distributionStrategy);
		
		for (PointsTarget target: targets) {
			Points points = createPoints(counterLocalService.increment(Points.class.getName()));

			points.setOriginatingContestPK(originatingContest.getContestPK());
			points.setPointsSourceId(pointsSourceId);
			points.setProposalId(proposal.getProposalId());

            //round points up to the next integer
            double roundedHypotheticalPoints = Math.ceil(hypotheticalPoints * target.getPercentage());
            double roundedMaterializedPoints = Math.ceil(materializedPoints * target.getPercentage());
			points.setHypotheticalPoints(roundedHypotheticalPoints);
			points.setMaterializedPoints(roundedMaterializedPoints);

			if (target.isUser()) {
				_log.info("Adding points to a user: " + target.getUserId() + ", hypotheticalPoints: " + points.getHypotheticalPoints() + 
						", materializedPoints: " + points.getMaterializedPoints());
				points.setUserId(target.getUserId());
			}
			
			addPoints(points);
			if (target.isProposal()) {
				_log.info("Passing points to a proposal: " + target.getProposalId() + ", hypotheticalPoints: " + points.getHypotheticalPoints() + 
						", materializedPoints: " + points.getMaterializedPoints());
				Proposal subProposal = proposalLocalService.getProposal(target.getProposalId());
				Contest subProposalContest = proposalLocalService.getLatestProposalContest(target.getProposalId());
				PointType subProposalPointType = pointType;
				if (subProposalContest.getDefaultParentPointType() > 0) {
					subProposalPointType = pointTypeLocalService.getPointType(subProposalContest.getDefaultParentPointType());
				}
				
				distributePointsToProposal(subProposal, originatingContest, points.getId(), 
						subProposalPointType, points.getMaterializedPoints(), points.getHypotheticalPoints());
			}
			<commit_msg>Points backend: only distribute points to subproposals if it's contest has a pointtype<commit_after>package com.ext.portlet.service.impl;

import java.util.Collection;
import java.util.List;

import org.xcolab.points.DistributionStrategy;
import org.xcolab.points.PointsTarget;
import org.xcolab.points.ReceiverLimitationStrategy;

import com.ext.portlet.model.Contest;
import com.ext.portlet.model.ContestPhase;
import com.ext.portlet.model.PointDistributionTarget;
import com.ext.portlet.model.PointType;
import com.ext.portlet.model.Points;
import com.ext.portlet.model.Proposal;
import com.ext.portlet.service.base.PointsLocalServiceBaseImpl;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;

/**
 * The implementation of the points local service.
 *
 * <p>
 * All custom service methods should be put in this class. Whenever methods are added, rerun ServiceBuilder to copy their definitions into the {@link com.ext.portlet.service.PointsLocalService} interface.
 *
 * <p>
 * This is a local service. Methods of this service will not have security checks based on the propagated JAAS credentials because this service can only be accessed from within the same VM.
 * </p>
 *
 * @author <NAME>
 * @see com.ext.portlet.service.base.PointsLocalServiceBaseImpl
 * @see com.ext.portlet.service.PointsLocalServiceUtil
 */
public class PointsLocalServiceImpl extends PointsLocalServiceBaseImpl {
	
	private final static Log _log = LogFactoryUtil.getLog(PointsLocalServiceImpl.class);
	
	/**
	 * Returns number of materialized points for given user.
	 * 
	 * @param userId
	 * @return
	 * @throws SystemException
	 */
	public int getUserMaterializedPoints(long userId) throws SystemException {
		int count = 0;
		for (Points points: pointsPersistence.findByUserId(userId)) {
			count += points.getMaterializedPoints();
		}
		return count;
	}
	
	/**
	 * Returns number of points for hypothetical user. 
	 * 
	 * @param userId
	 * @return
	 * @throws SystemException
	 */
	public long getUserHypotheticalPoints(long userId) throws SystemException {
		int count = 0;
		for (Points points: pointsPersistence.findByUserId(userId)) {
			count += points.getHypotheticalPoints();
		}
		return count;
	}
	
	/**
	 * Distribute points for given contest
	 * 
	 * @param contestPK
	 * @throws SystemException 
	 * @throws PortalException 
	 */
	public void distributePoints(long contestPK) throws PortalException, SystemException {
		Contest contest = contestLocalService.getContest(contestPK);
		ContestPhase latestPhase = contestLocalService.getActiveOrLastPhase(contest);
		
		// clean up old data
		pointsPersistence.removeByOriginatingContestPK(contestPK);
		
		for (Points points: pointsPersistence.findByOriginatingContestPK(contestPK)) {
			deletePoints(points);
		}
		
		PointType pointType = pointTypeLocalService.getPointType(contest.getDefaultParentPointType());

        boolean calculatePointsForAllProposals = true;

		if (contestLocalService.hasContestEnded(contest)) {
            calculatePointsForAllProposals = false;
			// check if distribution targets have been defined manually
			Collection<PointDistributionTarget> distributionTargets = pointDistributionTargetPersistence.findByContestId(contestPK);
			if (distributionTargets.isEmpty()) {
				// distribution targets haven't been defined - distribute points to the winner
				Proposal proposal = contestLocalService.getWinnerProposal(contestPK);
                if (proposal != null) {
                    distributePointsToProposal(proposal, contest, 0, pointType, 0, contest.getPoints());
                } else {
                    //no winner is selected: calculate points for each proposal
                    calculatePointsForAllProposals = true;
                }
			}
			else {
				for (PointDistributionTarget pdt: distributionTargets) {
					Proposal proposal = proposalLocalService.getProposal(pdt.getProposalId());
					if (! proposal.isVisible()) {
						continue;
					}
					PointType pointTypeToUse = pointType;
					if (pdt.getPointTypeOverride() > 0) {
						pointTypeToUse = pointTypeLocalService.getPointType(pdt.getPointTypeOverride());
					}

					distributePointsToProposal(proposal, contest, 0, pointTypeToUse, 0, pdt.getNumberOfPoints());
				}
			}
			
		}
		if (calculatePointsForAllProposals) {
			// apply points to all of the proposals
			for (Proposal proposal: proposalLocalService.getProposalsInContest(contestPK)) {
				distributePointsToProposal(proposal, contest, 0, pointType, 0, contest.getPoints());
				
			}
		}
	}
	
	private void distributePointsToProposal(Proposal proposal, 
			Contest originatingContest, 
			long pointsSourceId, 
			PointType pointType, 
			double materializedPoints,
			double hypotheticalPoints) throws SystemException, PortalException {
        String logString = proposal.getProposalId() + ". originatingContest: " + originatingContest.getContestPK() +
                " pointsSourceId: " + pointsSourceId + " pointType: " + pointType + " materializedPoints: " + materializedPoints +
                " hypotheticalPoints: " + hypotheticalPoints;
        if (hypotheticalPoints < 1 && materializedPoints < 1) {
            _log.info("Points left to be distributed are less than 1 for proposal: " + logString);
            return;
        }
		
		_log.info("Distributing points to proposal: " + logString);
		
		DistributionStrategy distributionStrategy = DistributionStrategy.valueOf(pointType.getDistributionStrategy());
		ReceiverLimitationStrategy receiverLimitationStrategy = ReceiverLimitationStrategy.valueOf(pointType.getReceiverLimitationStrategy());
		
		if (distributionStrategy == DistributionStrategy.DEFINED_BY_CHILDREN_PERCENTAGES) {
			for (PointType subPointType: pointTypePersistence.findByParentPointTypeId(pointType.getId())) {
				distributePointsToProposal(proposal, 
						originatingContest, 
						pointsSourceId, 
						subPointType, 
						materializedPoints * subPointType.getPercentageOfParent(), 
						hypotheticalPoints * subPointType.getPercentageOfParent());
			}
			return;
		}
		
		List<PointsTarget> targets = receiverLimitationStrategy.getTargets(proposal, pointType, distributionStrategy);
		
		for (PointsTarget target: targets) {
			Points points = createPoints(counterLocalService.increment(Points.class.getName()));

			points.setOriginatingContestPK(originatingContest.getContestPK());
			points.setPointsSourceId(pointsSourceId);
			points.setProposalId(proposal.getProposalId());

            //round points up to the next integer
            double roundedHypotheticalPoints = Math.ceil(hypotheticalPoints * target.getPercentage());
            double roundedMaterializedPoints = Math.ceil(materializedPoints * target.getPercentage());
			points.setHypotheticalPoints(roundedHypotheticalPoints);
			points.setMaterializedPoints(roundedMaterializedPoints);

			if (target.isUser()) {
				_log.info("Adding points to a user: " + target.getUserId() + ", hypotheticalPoints: " + points.getHypotheticalPoints() + 
						", materializedPoints: " + points.getMaterializedPoints());
				points.setUserId(target.getUserId());
			}
			
			addPoints(points);
			if (target.isProposal()) {
				_log.info("Passing points to a proposal: " + target.getProposalId() + ", hypotheticalPoints: " + points.getHypotheticalPoints() + 
						", materializedPoints: " + points.getMaterializedPoints());
				Proposal subProposal = proposalLocalService.getProposal(target.getProposalId());
				Contest subProposalContest = proposalLocalService.getLatestProposalContest(target.getProposalId());
                //only distribute points if the subproposal's contest has a default point type defined.
				if (subProposalContest.getDefaultParentPointType() > 0) {
                    PointType subProposalPointType = pointTypeLocalService.getPointType(subProposalContest.getDefaultParentPointType());
                    distributePointsToProposal(subProposal, originatingContest, points.getId(),
                            subProposalPointType, points.getMaterializedPoints(), points.getHypotheticalPoints());
				}
				

			}
			
{'fraction_non_alphanumeric': 0.08951375245579568, 'fraction_numerical': 0.0015962671905697446, 'mean_word_length': 4.229213483146068, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4746517', 'n_tokens_mistral': 5076, 'n_tokens_neox': 4372, 'n_words': 953}