Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 128 |
|
0.00% |
0 / 15 |
CRAP | |
0.00% |
0 / 1 |
| RewardController | |
0.00% |
0 / 128 |
|
0.00% |
0 / 15 |
1560 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| getAllRewards | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| getAllPromotions | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| getRewardsFromAPI | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
12 | |||
| getRewardsFromCache | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getPointsAndRewardsByPhone | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
30 | |||
| redeemRewardByPhone | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
30 | |||
| addMember | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
| getRewardsUIDsForFiveStarsAPI | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| getRedeemedRewards | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
| insertRedemption | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
6 | |||
| removeDuplicateRedemptions | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
30 | |||
| getPromotionsByPhone | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
| getPromotionsFromCache | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getPromotionsFromAPI | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php /** @noinspection PhpObjectFieldsAreOnlyWrittenInspection */ |
| 2 | |
| 3 | namespace BuyerKiosk\FiveStars\Controllers; |
| 4 | |
| 5 | |
| 6 | use BuyerKiosk\FiveStars\API; |
| 7 | use BuyerKiosk\FiveStars\Points; |
| 8 | use BuyerKiosk\FiveStars\Reward; |
| 9 | class RewardController extends BaseController { |
| 10 | private $predis; |
| 11 | private $key; |
| 12 | |
| 13 | public function __construct($app, \Store $store) { |
| 14 | parent::__construct($app, $store); |
| 15 | $this->predis = new \Predis\Client($_ENV['REDIS_URL']); |
| 16 | $this->key = $store->getTypeNum()."_rewards"; |
| 17 | $this->promotionKey = $store->getTypeNum()."_promotions"; |
| 18 | } |
| 19 | //Check the Redis cache for our rewards array first before making an API call to the FS API for the rewards. |
| 20 | public function getAllRewards() { |
| 21 | if($this->predis->exists($this->key)) { |
| 22 | return $this->getRewardsFromCache(); |
| 23 | } |
| 24 | return $this->getRewardsFromAPI(); |
| 25 | } |
| 26 | public function getAllPromotions() { |
| 27 | if($this->predis->exists($this->promotionKey)) { |
| 28 | return $this->getPromotionsFromCache(); |
| 29 | } |
| 30 | return $this->getPromotionsFromAPI(); |
| 31 | } |
| 32 | |
| 33 | //Fetch rewards from the FS API and return the array. Also add the array to Redis cache set to expire after 2 hours |
| 34 | public function getRewardsFromAPI() { |
| 35 | $endpoint = $this->endpointBase."/rewards"; |
| 36 | $API = new API($this->store->getDev()); |
| 37 | $result = $API->api_call($endpoint); |
| 38 | $rewardArray = []; |
| 39 | if(isset($result['items'])) { |
| 40 | foreach($result['items'] as $item) { |
| 41 | $reward = new Reward($item['uid'], $item['point_cost'], $item['perk']); |
| 42 | $rewardArray[] = $reward; |
| 43 | } |
| 44 | } |
| 45 | $this->predis->set($this->key, json_encode($rewardArray)); |
| 46 | $this->predis->expire($this->key, 60*60*2); |
| 47 | return $rewardArray; |
| 48 | } |
| 49 | //Load rewards array from Redis cache. (Check to make sure key exists before calling this function). |
| 50 | public function getRewardsFromCache() { |
| 51 | return json_decode($this->predis->get($this->key)); |
| 52 | } |
| 53 | //Call the FS API to get the points the customer has (look up by phone number). Also include the rewards this customer can redeem. |
| 54 | public function getPointsAndRewardsByPhone($phone) { |
| 55 | $rewardsArray = $this->getAllRewards(); |
| 56 | $API = new API($this->store->getDev()); |
| 57 | $phoneHash = $API->phone_hash($phone); |
| 58 | $endpoint = $this->endpointBase."/memberships/by-phone/".$phoneHash; |
| 59 | $start_time = microtime(TRUE); |
| 60 | $result = $API->api_call($endpoint); |
| 61 | $end_time = microtime(TRUE); |
| 62 | $executionTime = $end_time - $start_time; |
| 63 | if($executionTime > 1) { |
| 64 | $this->log->LogDebug("Slow API Call"); |
| 65 | $this->log->LogDebug("Time: ".$executionTime); |
| 66 | $this->log->LogDebug("Endpoint: ".$endpoint); |
| 67 | $this->log->LogDebug("Phone: ".$phone); |
| 68 | $this->log->LogDebug("/////////////"); |
| 69 | } |
| 70 | $customer = []; |
| 71 | if(isset($result['account'])) { |
| 72 | $customer['points'] = $result['points']; |
| 73 | $customer['name'] = $result['account']['name']; |
| 74 | $customer['phone'] = $result['account']['phone']; |
| 75 | $customer['subscription_status'] = $result['subscription_status']; |
| 76 | } |
| 77 | $availableRewardsArray = []; |
| 78 | foreach($rewardsArray as $reward) { |
| 79 | if($reward->pointCost <= $customer['points']) { |
| 80 | $reward->type = 0; |
| 81 | $availableRewardsArray[] = $reward; |
| 82 | } |
| 83 | } |
| 84 | //$availableRewardsArray = $this->getPromotionsByPhone($phone, $availableRewardsArray); |
| 85 | return array("customer" => $customer, "rewards" => $availableRewardsArray); |
| 86 | } |
| 87 | |
| 88 | public function redeemRewardByPhone($phone, $rewards) { |
| 89 | $API = new API($this->store->getDev()); |
| 90 | $endpoint = $this->endpointBase."/sales"; |
| 91 | $this->log->LogDebug("Rewards Variable: ". json_encode($rewards)); |
| 92 | //RedeemedArray is an array of coupon UID's specifically for sending to the FiveStars API |
| 93 | $redeemedArray = $this->getRewardsUIDsForFiveStarsAPI($rewards); |
| 94 | //This array will be used to enter data for the redemtion in the fiveStarsPoints table. |
| 95 | $redeemedDataArray = $this->getRedeemedRewards($rewards); |
| 96 | $duplicateUIDArray = []; |
| 97 | //Post redemptions to the fiveStarsData table. If a slug collision occurs then add that UID to the duplicateUIDArray for removal |
| 98 | foreach($redeemedDataArray as $redeemedData) { |
| 99 | if(!$this->insertRedemption($redeemedData->pointCost, $phone)) { |
| 100 | $duplicateUIDArray[] = $redeemedData->uid; |
| 101 | } |
| 102 | } |
| 103 | //If we found any duplicated redemptions then we need to remove them from the array before we send it to the FiveStars API |
| 104 | $redeemedArray = $this->removeDuplicateRedemptions($redeemedArray, $duplicateUIDArray); |
| 105 | $this->log->LogDebug("Rewards After Remove Duplicates: ". json_encode($redeemedArray)); |
| 106 | //Post to the FiveStars API and return any errors |
| 107 | $this->log->LogDebug(json_encode($redeemedArray)); |
| 108 | $data = array("phone" => (String)$phone, "points" => array(array("amount"=>0)), "rewards" => $redeemedArray); |
| 109 | $this->log->LogDebug("RewardArray: ".json_encode($data)); |
| 110 | if(count($redeemedArray) > 0) { |
| 111 | $result = $API->api_call($endpoint, $data); |
| 112 | } else { |
| 113 | return array("errorCode"=> 3, "errorMessage" => "No redemptions that weren't duplicates"); |
| 114 | } |
| 115 | if($result == "Not enough points") { |
| 116 | return array("errorCode"=> 1, "errorMessage" => "Not Enough Points"); |
| 117 | } |
| 118 | $this->log->LogDebug(json_encode($result)); |
| 119 | return array("errorCode"=> 0, "errorMessage" => ""); |
| 120 | } |
| 121 | |
| 122 | public function addMember($phone) |
| 123 | { |
| 124 | $API = new API($this->store->getDev()); |
| 125 | $endpoint = $this->endpointBase . "/memberships"; |
| 126 | $data = array("phone" => (string)$phone); |
| 127 | $this->log->LogDebug(json_encode($data)); |
| 128 | $result = $API->api_call($endpoint, $data); |
| 129 | return true; |
| 130 | } |
| 131 | |
| 132 | public function getRewardsUIDsForFiveStarsAPI($rewards) { |
| 133 | foreach($rewards as $uid) { |
| 134 | $redeemedArray[] = array("uid" => $uid['uid']); |
| 135 | } |
| 136 | return $redeemedArray; |
| 137 | } |
| 138 | |
| 139 | public function getRedeemedRewards($rewards) { |
| 140 | //Get the store rewards from cache or from the API. This will contain all rewards that the store offers. |
| 141 | $storeRewardsArray = $this->getAllRewards(); |
| 142 | $redeemedDataArray = []; |
| 143 | foreach($rewards as $reward) { |
| 144 | foreach($storeRewardsArray as $storeReward) { |
| 145 | if($reward['uid'] == $storeReward->uid) { |
| 146 | $redeemedDataArray[] = $storeReward; |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | return $redeemedDataArray; |
| 151 | } |
| 152 | public function insertRedemption($pointsRedeemed, $phone) { |
| 153 | try { |
| 154 | $points = new Points($this->store, $this->storeDB); |
| 155 | $points->totalBuys = 0; |
| 156 | $points->totalSales = 0; |
| 157 | $points->totalTax = 0; |
| 158 | $points->phone = $phone; |
| 159 | $today = new \DateTime("now", new \DateTimeZone($this->store->getTimeZone())); |
| 160 | $points->date = $today->format("Y-m-d"); |
| 161 | $points->pointsRedeemed = $pointsRedeemed; |
| 162 | return $points->insert(); |
| 163 | } catch (\PDOException $e) { |
| 164 | $this->log->LogError($e->getMessage()); |
| 165 | } |
| 166 | } |
| 167 | public function removeDuplicateRedemptions($redeemedArray, $duplicateUIDArray) { |
| 168 | if(count($duplicateUIDArray) > 0) { |
| 169 | foreach($duplicateUIDArray as $duplicateUID) { |
| 170 | foreach($redeemedArray as $key => $redeemedUID) { |
| 171 | $this->log->LogDebug("Key: ". $key." Value: ".json_encode($redeemedUID)); |
| 172 | if($duplicateUID == $redeemedUID['uid']) { |
| 173 | unset($redeemedArray[$key]); |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | } |
| 178 | return $redeemedArray; |
| 179 | } |
| 180 | public function getPromotionsByPhone($phone, $rewardsArray) { |
| 181 | $API = new API($this->store->getDev()); |
| 182 | $phoneHash = $API->phone_hash($phone); |
| 183 | $endpoint = $this->endpointBase."/memberships/by-phone/".$phoneHash."/promotions"; |
| 184 | $result = $API->api_call($endpoint); |
| 185 | if(isset($result['promotions'])) { |
| 186 | foreach($result['promotions'] as $promotion) { |
| 187 | $promotion['type'] = 1; |
| 188 | $rewardsArray[] = $promotion; |
| 189 | } |
| 190 | } |
| 191 | return $rewardsArray; |
| 192 | } |
| 193 | public function getPromotionsFromCache() { |
| 194 | return json_decode($this->predis->get($this->promotionKey)); |
| 195 | } |
| 196 | public function getPromotionsFromAPI() { |
| 197 | $API = new API($this->store->getDev()); |
| 198 | $endpoint = $this->endpointBase."/perks"; |
| 199 | $result = $API->api_call($endpoint); |
| 200 | $promotionsArray = []; |
| 201 | foreach($result['items'] as $item) { |
| 202 | $tempPromotion = []; |
| 203 | $tempPromotion['uid'] = $item['uid']; |
| 204 | $tempPromotion['name'] = $item['name']; |
| 205 | $tempPromotion['shortname'] = $item['shortname']; |
| 206 | $tempPromotion['expiration_date'] = $item['expiration_date']; |
| 207 | $tempPromotion['start_date'] = $item['start_date']; |
| 208 | $promotionsArray[$item['uid']] = $tempPromotion; |
| 209 | } |
| 210 | $this->predis->set($this->promotionKey, json_encode($promotionsArray)); |
| 211 | $this->predis->expire($this->promotionKey, 60*60*24); |
| 212 | return $promotionsArray; |
| 213 | } |
| 214 | } |