Prediction.php 2.86 KB
<?php

namespace FootyRoom\Core\Predictor;

use FootyRoom\Core\CoreException;
use FootyRoom\Core\EventGenerator;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document(collection="predictor.predictions")
 */
class Prediction
{
    use EventGenerator;

    /**
     * @ODM\Id
     *
     * @var string
     */
    protected $id;

    /**
     * @ODM\Field(type="int")
     *
     * @var int|string
     */
    protected $userId;

    /**
     * @ODM\Field(type="int")
     *
     * @var int
     */
    protected $matchId;

    /**
     * @ODM\Field(type="int")
     *
     * @var string
     */
    protected $homeScore;

    /**
     * @ODM\Field(type="int")
     *
     * @var string
     */
    protected $awayScore;

    /**
     * @ODM\Field(type="int")
     *
     * @var int
     */
    protected $stake;

    /**
     * @ODM\Field(type="bool")
     * 
     * @var boolean
     */
    protected $settled;

    public function __construct(int $userId, int $matchId, int $homeScore, int $awayScore, int $stake = 0)
    {
        $this->userId = $userId;
        $this->matchId = $matchId;
        $this->setScore($homeScore, $awayScore);
        $this->stake = 0;
        $this->settled = false;

        $this->bet($stake);

        $this->raise(new PredictionCreated($this));
    }

    public function getUserId(): int
    {
        return $this->userId;
    }

    public function getMatchId(): int
    {
        return $this->matchId;
    }

    public function getStake(): int
    {
        return $this->stake;
    }

    public function getHomeScore(): int
    {
        return $this->homeScore;
    }

    public function getAwayScore(): int
    {
        return $this->awayScore;
    }

    public function getSettled(): bool
    {
        return $this->settled;
    }

    public function bet(int $stake)
    {
        if ($stake < 0) {
            throw new CoreException('You can\'t make a negative bet.');
        }

        if ($this->stake > $stake) {
            throw new CoreException('You can\'t lower your bet.');
        }

        $raise = $stake - $this->stake;

        $this->stake = $stake;

        if ($raise > 0) {
            $this->raise(new PredictionStakeRaised($this, $raise));
        }
    }

    public function change(int $homeScore, int $awayScore)
    {
        if ($this->stake > 0) {
            if ($this->homeScore !== $homeScore || $this->awayScore !== $awayScore) {
                throw new CoreException('You can\'t change your prediction once you\'ve placed a bet.');
            }
        }

        $this->setScore($homeScore, $awayScore);
    }

    protected function setScore(int $homeScore, int $awayScore)
    {
        if ($homeScore > 20 || $awayScore > 20) {
            throw new CoreException('Please check your prediction, it\'s outrageous!');
        }

        $this->homeScore = $homeScore;
        $this->awayScore = $awayScore;
    }
}