Example #1
0
 public function acceptBid($bid_id, $budget_id = 0, $is_mechanic = true)
 {
     $this->conditionalLoadByBidId($bid_id);
     /*if ($this->hasAcceptedBids()) {
           throw new Exception('Can not accept an already accepted bid.');
       }*/
     $user_id = isset($_SESSION['userid']) ? (int) $_SESSION['userid'] : 0;
     $is_runner = isset($_SESSION['is_runner']) ? (int) $_SESSION['is_runner'] : 0;
     // If a bid is being accepted, and the runner for the workitem does not exist (incase a bid went from suggested straight
     // to working) or is different than current user, then we should set the person accepting the bid as the runner;
     if ($this->getRunnerId() != $user_id) {
         $this->setRunnerId($user_id);
     }
     $res = mysql_query('SELECT * FROM `' . BIDS . '` WHERE `id`=' . $bid_id);
     $bid_info = mysql_fetch_assoc($res);
     $workitem_info = $this->getWorkItem($bid_info['worklist_id']);
     // Get bidder information
     $bidder = new User();
     if (!$bidder->findUserById($bid_info['bidder_id'])) {
         // If bidder doesn't exist, return false. Don't want to throw an
         // exception because it would kill multiple bid acceptances
         return false;
     }
     $bid_info['nickname'] = $bidder->getNickname();
     $project = new Project($this->getProjectId());
     // Get the repo for this project
     $repository = $this->getRepository();
     $job_id = $this->getId();
     /* Verify whether the user already has this repo forked on his account
      *If not create the fork
      *Check for existing unix account in dev.  If new, make call to create account
      */
     $GitHubUser = new User($bid_info['bidder_id']);
     $url = TOWER_API_URL;
     $fields = array('action' => 'create_unixaccount', 'nickname' => $bidder->getNickname());
     $result = CURLHandler::Post($url, $fields);
     if (!$GitHubUser->verifyForkExists($project)) {
         $forkStatus = $GitHubUser->createForkForUser($project);
         $bidderEmail = $bidder->getUsername();
         $emailTemplate = 'forked-repo';
         $data = array('project_name' => $forkStatus['data']['full_name'], 'nickname' => $bidder->getNickname(), 'users_fork' => $forkStatus['data']['git_url'], 'master_repo' => str_replace('https://', 'git://', $project->getRepository()));
         $senderEmail = 'Worklist <*****@*****.**>';
         Utils::sendTemplateEmail($bidderEmail, $emailTemplate, $data, $senderEmail);
         sleep(10);
     }
     // Create a branch for the user
     if (!$forkStatus['error']) {
         $branchStatus = $GitHubUser->createBranchForUser($job_id, $project);
         $bidderEmail = $bidder->getUsername();
         $emailTemplate = 'branch-created';
         $data = array('branch_name' => $job_id, 'nickname' => $bidder->getNickname(), 'users_fork' => $forkStatus['data']['git_url'], 'master_repo' => str_replace('https://', 'git://', $project->getRepository()));
         $bid_info = array_merge($data, $bid_info);
     }
     if (!$branchStatus['error']) {
         $bid_info['sandbox'] = $branchStatus['branch_url'];
     }
     $bid_info['bid_done'] = strtotime('+' . $bid_info['bid_done_in'], time());
     // Adding transaction wrapper around steps
     if (mysql_query('BEGIN')) {
         $is_runner_or_assignee = $is_runner || $this->getAssigned_id() == $user_id;
         // changing mechanic of the job
         $sql = "UPDATE `" . WORKLIST . "` SET " . ($is_mechanic ? "`mechanic_id` =  '" . $bid_info['bidder_id'] . "', " : '') . ($is_runner_or_assignee && $user_id > 0 && $workitem_info['runner_id'] != $user_id ? "`runner_id` =  '" . $user_id . "', " : '') . " `status` = 'In Progress',`status_changed`=NOW(),`sandbox` = '" . $bid_info['sandbox'] . "',`budget_id` = " . $budget_id . " WHERE `" . WORKLIST . "`.`id` = " . $bid_info['worklist_id'];
         if (!($myresult = mysql_query($sql))) {
             error_log("AcceptBid:UpdateMechanic failed: " . mysql_error());
             mysql_query("ROLLBACK");
             return false;
         }
         // marking bid as "accepted"
         if (!($result = mysql_query("UPDATE `" . BIDS . "` SET `accepted` =  1, `bid_done` = FROM_UNIXTIME('" . $bid_info['bid_done'] . "') WHERE `id` = " . $bid_id))) {
             error_log("AcceptBid:MarkBid failed: " . mysql_error());
             mysql_query("ROLLBACK");
             return false;
         }
         // adding bid amount to list of fees
         if (!($result = mysql_query("INSERT INTO `" . FEES . "` (`id`, `worklist_id`, `amount`, `user_id`, `desc`, `bid_notes`, `date`, `bid_id`) VALUES (NULL, " . $bid_info['worklist_id'] . ", '" . $bid_info['bid_amount'] . "', '" . $bid_info['bidder_id'] . "', 'Accepted Bid', '" . mysql_real_escape_string($bid_info['notes']) . "', NOW(), '{$bid_id}')"))) {
             error_log("AcceptBid:Insert Fee failed: " . mysql_error());
             mysql_query("ROLLBACK");
             return false;
         }
         $creator_fee = 0;
         $creator_fee_desc = 'Creator';
         $creator_fee_added = false;
         $runner_fee = 0;
         $runner_fee_desc = 'Designer';
         $runner_fee_added = false;
         $accepted_bid_amount = $bid_info['bid_amount'];
         $fee_category = '';
         $is_expense = '';
         $is_rewarder = '';
         $fees = $this->getFees($this->getId());
         foreach ($fees as $fee) {
             // find the accepted bid amount
             if ($fee['desc'] == 'Accepted Bid') {
                 $accepted_bid_amount = $fee['amount'];
             }
             if (preg_match($reviewer_fee_desc, $fee['desc'])) {
                 $reviewer_fee_added = true;
             }
             if ($fee['desc'] == $creator_fee_desc) {
                 $creator_fee_added = true;
             }
             if ($fee['desc'] == $runner_fee_desc) {
                 $runner_fee_added = true;
             }
         }
         // get project creator role settings, if not available, no fee is added
         // and will need to be added manually if applicable
         $project = new Project();
         $project_roles = $project->getRoles($this->getProjectId(), "role_title = 'Creator'");
         if (count($project_roles) != 0 && !$creator_fee_added) {
             // fees are not automatically created for internal users
             if (!$this->getCreator()->isInternal()) {
                 $creator_role = $project_roles[0];
                 if ($creator_role['percentage'] !== null && $creator_role['min_amount'] !== null) {
                     $creator_fee = $creator_role['percentage'] / 100 * $accepted_bid_amount;
                     if ((double) $creator_fee < $creator_role['min_amount']) {
                         $creator_fee = $creator_role['min_amount'];
                     }
                     // add the fee
                     /**
                      * @TODO - We call addfees and then deduct from budget
                      * seems we should add the deduction process to the Fee::add
                      * function
                      *
                      */
                     Fee::add($this->getId(), $creator_fee, $fee_category, $creator_fee_desc, $this->getCreatorId(), $is_expense, $is_rewarder);
                     // and reduce the runners budget
                     $myRunner = new User();
                     $myRunner->findUserById($this->getRunnerId());
                     $myRunner->updateBudget(-$creator_fee, $this->getBudget_id());
                 }
             }
         }
         $project_roles = $project->getRoles($this->getProjectId(), "role_title = 'Runner'");
         if (count($project_roles) != 0 && !$runner_fee_added) {
             error_log("[FEES] we have a role for runner");
             $runner_role = $project_roles[0];
             // fees are not automatically created for internal users
             if (!$this->getRunner()->isInternal()) {
                 if ($runner_role['percentage'] !== null && $runner_role['min_amount'] !== null) {
                     $runner_fee = $runner_role['percentage'] / 100 * $accepted_bid_amount;
                     if ((double) $runner_fee < $runner_role['min_amount']) {
                         $runner_fee = $runner_role['min_amount'];
                     }
                     // add the fee
                     Fee::add($this->getId(), $runner_fee, $fee_category, $runner_fee_desc, $this->getRunnerId(), $is_expense, $is_rewarder);
                     // and reduce the runners budget
                     $myRunner = new User();
                     $myRunner->findUserById($this->getRunnerId());
                     $myRunner->updateBudget(-$runner_fee, $this->getBudget_id());
                 }
             }
         }
         // add an entry to the status log
         $status_sql = "\n                INSERT INTO " . STATUS_LOG . " (worklist_id, status, user_id, change_date)\n                VALUES({$bid_info['worklist_id']}, 'Working', {$_SESSION['userid']}, NOW())";
         if (!($result = mysql_query($status_sql))) {
             error_log("AcceptedBid:Insert status log failed: " . mysql_error());
             mysql_query("ROLLBACK");
             return false;
         }
         // When we get this far, commit and return bid_info
         if (mysql_query('COMMIT')) {
             $bid_info['summary'] = $workitem_info['summary'];
             $this->setMechanicId($bid_info['bidder_id']);
             return $bid_info;
         } else {
             return false;
         }
     } else {
         return false;
     }
 }