Commit f2c51c09 authored by Antonio.Suerte's avatar Antonio.Suerte

Monthly Charge and Suspension Enhancement

parent abcdb482
<?php
require_once "../lib/config.php";
class MonthlyCharge extends System {
/**
*
* @var integer
*/
private $forTest;
/**
*
* @var integer
*/
private $userAccount;
/**
*
* @var string
*/
private $ipAddress;
/**
*
* @var string
*/
private $contentType;
/**
*
* @var string
*/
private $requestMethod;
/**
*
* コンストラクタ
*
*/
public function __construct(){
parent::__construct();
header("Content-type: text/plain");
$this -> setParameter();
$this -> validation();
}
/**
*
* パラメータの設定
*
*/
private function setParameter(){
$this -> forTest = $this -> getDataPost("test");
$this -> userAccount = $this -> getDataPost("userAccount");
$this -> ipAddress = $this -> getColumnData($_SERVER, "REMOTE_ADDR");
$this -> contentType = $this -> getColumnData($_SERVER, "CONTENT_TYPE");
$this -> requestMethod = $this -> getColumnData($_SERVER, "REQUEST_METHOD");
}
/**
*
* 確認の機能
*
*/
private function validation(){
$validation = [];
$chargeAPIConf = $this -> getSettingConfiguration("charge_api_conf");
$ipAddresses = explode(",", $chargeAPIConf -> ip_address);
if(strtoupper($this -> requestMethod) != "POST")
$validation[] = "Invalid Request Method: {$this -> requestMethod}";
if(!in_array($this -> ipAddress, $ipAddresses))
$validation[] = "Invalid IP Address: {$this -> ipAddress}";
if($this -> contentType != "application/x-www-form-urlencoded")
$validation[] = "Invalid Content-type: {$this -> contentType}";
if(!$this -> isLoopData($this -> getAccountCommon($this -> userAccount)))
$validation[] = "Account doesn't exist: {$this -> userAccount}";
if($this -> isLoopData($validation)){
header("HTTP/1.1 403 Forbidden due to validation results");
die(json_encode($validation));
}
}
/**
*
* @param integer $account
* @param string $currency
* @param double $amount
*/
private function executeWithdraw($account, $currency, $amount){
if ($this -> forTest) {
$simulatedAmount = $this -> intToCurrency($amount, $currency);
echo "Simulation: Charged For {$currency} {$simulatedAmount}\n";
} else
$this -> monthlyWithdraw($account, $currency, $amount);
}
/**
*
* @param integer $account
* @param string $currency
* @param double $amount
*/
private function monthlyWithdraw($account, $currency, $amount) {
$this -> registFeeCommon($account,
$currency,
$this -> intToCurrency($amount, $currency),
'Monthly Maintenance',
VAL_INT_2);
}
/**
*
* 毎月の保守料の活用
*
*/
private function charge(){
// 維持費を取得する
$fee = $this -> getFeeCommon(VAR_MONTHLY, NO_COUNT, USD, $this -> userAccount);
// USD手数料
$feeInt = $this -> currencyToInt($this -> getColumnData($fee, USD . VAL_INT_1), USD);
// 手数料が無い人は、飛ばす
if($feeInt == NO_COUNT)
return;
// ユーザの残高を取得する
$balances = $this -> getBalanceListCommon($this -> userAccount);
if($this -> isLoopData($balances)) {
// まずは、USD優先
if(isset($balances[USD])) {
// USD口座で賄えた場合
if($feeInt <= $balances[USD]) {
// 出金処理
$this -> executeWithdraw($this -> userAccount, USD, $feeInt);
return;
} else {
// 出金処理
$this -> executeWithdraw($this -> userAccount, USD, $balances[USD]);
$feeInt -= $balances[USD];
}
unset($balances[USD]);
}
$zeroDecimalCurrencies = $this -> getZeroDecimalCurrenciesCommon();
// Loop until maintenance costs are gone
foreach($balances as $currency => $balance) {
// Money exchange
$exchange = $this -> getExchangeCommon($balance, $currency, USD, true, false);
if(in_array($currency, $zeroDecimalCurrencies))
$remaining = floor($this -> getColumnData($exchange, PARAM_AMOUNT)*100);
else
$remaining = floor($this -> getColumnData($exchange, PARAM_AMOUNT));
// 相殺できてるか
if($feeInt <= $remaining) {
$exchange = $this -> getExchangeCommon($feeInt, USD, $currency,true, true);
if(in_array($currency, $zeroDecimalCurrencies))
$feeval = floor($this -> getColumnData($exchange, PARAM_AMOUNT)/100);
else
$feeval = floor($this -> getColumnData($exchange, PARAM_AMOUNT));
// 出金処理
$this -> executeWithdraw($this -> userAccount, $currency, $feeval);
break;
} else {
// 出金処理
$this -> executeWithdraw($this -> userAccount, $currency, $balance);
$feeInt -= $remaining;
}
// 手数料が無くなったら終了
if($feeInt <= NO_COUNT)
break;
}
}
}
/**
*
* 主な機能
*
*/
public function listen(){
$this -> charge();
}
}
$charge = new MonthlyCharge();
$charge -> listen();
\ No newline at end of file
<?php
require_once "../lib/config.php";
/**
*
* @author i-Wallet
*
*/
class SuspendAndDeduct extends System {
/**
*
* @var integer
*/
private $forTest;
/**
*
* @var string
*/
private $payload;
/**
*
* @var string
*/
private $contentType;
/**
*
* @var string
*/
private $requestMethod;
/**
*
* @var string
*/
private $ipAddress;
/**
*
* @var array
*/
private $reportObject = [];
/**
*
* コンストラクタ
*
*/
public function __construct(){
parent::__construct();
header("Content-type: text/plain");
$this -> setParameter();
$this -> validation();
}
/**
*
* パラメータの設定
*
*/
private function setParameter(){
$this -> payload = file_get_contents("php://input");
$this -> ipAddress = $this -> getColumnData($_SERVER, "REMOTE_ADDR");
$this -> contentType = $this -> getColumnData($_SERVER, "CONTENT_TYPE");
$this -> requestMethod = $this -> getColumnData($_SERVER, "REQUEST_METHOD");
}
/**
*
* データを確認
*
*/
private function validation(){
$validation = [];
$chargeAPIConf = $this -> getSettingConfiguration("charge_api_conf");
$ipAddresses = explode(",", $chargeAPIConf -> ip_address);
if(!$this -> checkJSONString($this -> payload)){
$validation[] = "Invalid JSON String format found on the request data";
}
if(strtoupper($this -> requestMethod) != "POST"){
$validation[] = "Invalid Request Method: {$this -> requestMethod}";
}
if(!in_array($this -> ipAddress, $ipAddresses)){
$validation[] = "Invalid IP Address: {$this -> ipAddress}";
}
if($this -> contentType != "application/json"){
$validation[] = "Invalid Content-type: {$this -> contentType}";
}
if($this -> isLoopData($validation)){
header("HTTP/1.1 403 Forbidden due to validation results");
die(json_encode($validation));
}
$this -> payload = json_decode($this -> payload, true);
$this -> forTest = $this -> payload["test"];
}
/**
*
* @param unknown $later
* @param unknown $earlier
* @param unknown $period
* @return boolean
*/
private function isWithinPeriod($later, $earlier, $period){
$dateDiff = $this -> computeDateDiff($later, $earlier);
//if dateDiff is <= $period days
return $dateDiff <= $period;
}
/**
*
* @param unknown $subtrahend
* @param unknown $subtractor
* @return number
*/
private function computeDateDiff($subtrahend, $subtractor){
$dateDiff = strtotime($subtrahend) - strtotime($subtractor);
//divide to get the number of days
$dateDiff = floor($dateDiff / 86400);
return $dateDiff;
}
private function appendSuspendedReport($userAccount, $suspensionStatus){
if(!isset($this -> reportObject["suspended"]))
$this -> reportObject["suspended"] = [];
$userAccount["suspensionStatus"] = $suspensionStatus;
$userAccount["dateOfSuspension"] = date("Y/m/d");
$this -> reportObject["suspended"][] = $userAccount;
}
private function appendDeductionReport($userAccount, $transactionNumber, $currency, $dormancyFee){
if(!isset($this -> reportObject["deducted"]))
$this -> reportObject["deducted"] = [];
$userAccount["transactionNumber"] = $transactionNumber;
$userAccount["dormancyFee"] = $dormancyFee;
$userAccount["currency"] = $currency;
$userAccount["dateOfDeduction"] = date("Y/m/d");
$this -> reportObject["deducted"][] = $userAccount;
}
private function suspendAccount($userAccount, $status){
//suspend account
if($this -> forTest){
$this -> rawSQL("INSERT INTO t_job_test_suspended_account (user_account, status, suspension_date) ".
"VALUES ('{$userAccount[PARAM_USER_ACCOUNT]}', '{$status}', CONVERT_TZ(NOW(),@@session.time_zone,'+09:00'))");
}else{
$this -> accessModify('UPDATE_USER_STATUS_INACTIVE',
[$this -> getColumnData($userAccount, PARAM_USER_ACCOUNT), $status],
false);
}
}
private function executeWithdraw($userAccount, $currency, $amount){
$transactionNumber = NO_STRING;
if($this -> forTest){
$transactionNumber = $this -> createUId();
$this -> rawSQL("INSERT INTO t_job_test_transactions (transaction_number, user_account, amount, currency, note, status, create_time) ".
"VALUES ('{$transactionNumber}', '{$userAccount[PARAM_USER_ACCOUNT]}', '{$amount}', '{$currency}', 'Dormancy Test', 2, CONVERT_TZ(NOW(),@@session.time_zone,'+09:00'))");
}else{
$transactionNumber = $this -> registInactiveFeeCommon($userAccount[PARAM_USER_ACCOUNT],
$currency,
$this -> intToCurrency($amount, $currency),
VAR_TRANSACTION_DOMANT_FEE,
'Inactive Account Maintenance Fee',
VAL_INT_2
);
}
return $transactionNumber;
}
private function deductInactiveFee($userAccount, $currency, $amount){
//return string for deduction details
$returnString = NO_STRING;
$transactionNumber = $this -> executeWithdraw($userAccount, $currency, $amount);
$amount = $this -> intToCurrency($amount, $currency);
//if JPY or PHP or IDR, remove decimal
if(in_array($currency, $this -> getZeroDecimalCurrenciesCommon())){
$amount = floor($amount);
}
$returnString = "• {$currency} {$amount} ({$transactionNumber}) \n";
return $returnString;
}
private function processAccountBalance($userAccount){
//temporary string holder
$tempString = NO_STRING;
//get all balances
$balances = array();
$balances = $this -> getBalanceListCommon($userAccount[PARAM_USER_ACCOUNT]);
//fee
$fee = 20;
$feeInt = $this -> currencyToInt($fee, USD);
//check if there is a balance in USD
if(isset($balances['USD'])){
//check if USD is enough
if(($balances['USD'] - $feeInt) >= 0){
//deduct
$tempString = $this -> deductInactiveFee($userAccount, 'USD', $feeInt);
//parse $deductionDetails to get the transaction number
$transactionNumber = $this -> getTransactionNumber($tempString);
$currency = USD;
$this -> appendDeductionReport($userAccount, $transactionNumber, $currency, $this -> intToCurrency($feeInt, $currency));
return;
}
}
//define converted (to USD) currency array
$convertedCurrencyBalances = array();
//convert other currencies
foreach ($balances as $key => $value) {
if($key != 'USD'){
$exchange = $this -> getExchangeCommon($value, $key, 'USD', true, false);
$zeroDecimalCurrencies = $this -> getZeroDecimalCurrenciesCommon();
if(in_array($key, $zeroDecimalCurrencies)){
$convertedCurrencyBalances[$key] = floor($this -> getColumnData($exchange, PARAM_ORIGINAL_AMOUNT) * 100);
} else {
$convertedCurrencyBalances[$key] = floor($this -> getColumnData($exchange, PARAM_ORIGINAL_AMOUNT));
}
} else
$convertedCurrencyBalances[$key] = $value;
}
//check if all the converted amount is >= $feeInt
if(array_sum($convertedCurrencyBalances) >= $feeInt){
//check if there is USD currency in the balance
if(isset($convertedCurrencyBalances['USD'])){
//check first if there is remaining USD
if($convertedCurrencyBalances['USD'] > 0){
//deduct from remaining USD
$feeInt -= $balances['USD'];
$tempString = $this -> deductInactiveFee($userAccount, 'USD', $balances['USD']);
//parse $deductionDetails to get the transaction number
$transactionNumber = $this -> getTransactionNumber($tempString);
$currency = USD;
$this -> appendDeductionReport($userAccount, $transactionNumber, $currency,
$this -> intToCurrency($balances[$currency], $currency));
}
//unset USD
unset($convertedCurrencyBalances['USD']);
}
//sort $convertedCurrencyBalances in desc order
arsort($convertedCurrencyBalances);
//after sorting deduct
foreach($convertedCurrencyBalances as $key => $value){
//check if there is still remaining fee
if($feeInt > 0){
if(($value - $feeInt) >= 0){
//convert fee currency
$exchange = $this -> getExchangeCommon($feeInt, 'USD', $key, true, false);
$zeroDecimalCurrencies = $this -> getZeroDecimalCurrenciesCommon();
if(in_array($key,$zeroDecimalCurrencies)){
$deductAmount = floor($this -> getColumnData($exchange, PARAM_ORIGINAL_AMOUNT) / 100);
} else {
$deductAmount = floor($this -> getColumnData($exchange, PARAM_ORIGINAL_AMOUNT));
}
//deduct
$tempString = $this -> deductInactiveFee($userAccount, $key, $deductAmount);
//parse $deductionDetails to get the transaction number
$transactionNumber = $this -> getTransactionNumber($tempString);
$this ->appendDeductionReport($userAccount, $transactionNumber, $key, $this -> intToCurrency($deductAmount, $key));
break;
} else{
//get remaining fee
$feeInt -= $value;
//deduct
$tempString = $this -> deductInactiveFee($userAccount, $key, $balances[$key]);
$transactionNumber = $this -> getTransactionNumber($tempString);
//put report data
$this ->appendDeductionReport($userAccount, $transactionNumber, $key, $this -> intToCurrency($deductAmount, $key));
}
} else
break;
}
} else{
//suspend
$suspensionStatus = ($userAccount['status'] == VAL_INT_3) ? VAL_INT_7 : VAL_INT_6;
$this -> suspendAccount($userAccount, $suspensionStatus);
//put report data
$this -> appendSuspendedReport($userAccount, $suspensionStatus);
}
}
/**
*
* @param unknown $transactionList
* @param unknown $userAccount
* @return boolean
*/
private function isTransactionWithinPeriod($transactionList, $userAccount){
//check if there is last lift date
if($userAccount['last_lift_date'] != null){
$hasTransactionWithin180 = false;
$hasTransactionAfterLift = false;
//if there is last lift date, check if it not is between now and now-180
if(!$this -> isWithinPeriod(date("Y-m-d H:i:s"), $userAccount['last_lift_date'], 180)){
//check for any transactions within now and now - 180
foreach($transactionList as $transaction){
if($this -> isWithinPeriod(date("Y-m-d H:i:s"), $transaction['transaction_time'], 180)){
$hasTransactionWithin180 = true;
break;
}
}
//check for any transactions within 180 days after last lift date
foreach($transactionList as $transaction){
if($this -> isWithinPeriod($transaction['transaction_time'], $userAccount['last_lift_date'], 180)){
$hasTransactionAfterLift = true;
break;
}
}
//check if both has passed
if($hasTransactionWithin180 && $hasTransactionAfterLift)
return true;
} else
return true;
} else{
//check for any transactions within now and now - 180
foreach($transactionList as $transaction){
if($this -> isWithinPeriod(date("Y-m-d H:i:s"), $transaction['transaction_time'], 180))
return true;
}
}
return false;
}
private function getTransactionNumber($string){
$transactionNumber = NO_STRING;
if(strlen($string) > 0) {
$arrayContainer = explode("(", $string);
$arrayContainer = explode(")", $arrayContainer[1]);
$transactionNumber = $arrayContainer[0];
}
return $transactionNumber;
}
/**
*
* @param array $userAccounts
*/
private function applySuspendAndDeduction(Array $userAccounts){
foreach($userAccounts as $userAccount){
$transactionList = $this -> accessSelect("LIST_USER_TRANSACTION_FOR_SUSPENSION_CHECKING",
[$this -> getColumnData($userAccount, PARAM_USER_ACCOUNT), NO_STRING]);
$dataCount = count($transactionList);
if($dataCount < VAL_INT_1){
$lastLiftDate = $userAccount["last_lift_date"];
if($lastLiftDate != null && !$this -> isWithinPeriod(date("Y-m-d H:i:s"), $lastLiftDate, 180)){
//suspend
$suspensionStatus = ($userAccount['status'] == VAL_INT_3) ? VAL_INT_7 : VAL_INT_6;
$this -> suspendAccount($userAccount, $suspensionStatus);
$this -> appendSuspendedReport($userAccount, $suspensionStatus);
}else{
//suspend
$suspensionStatus = ($userAccount['status'] == VAL_INT_3) ? VAL_INT_7 : VAL_INT_6;
$this -> suspendAccount($userAccount, $suspensionStatus);
$this -> appendSuspendedReport($userAccount, $suspensionStatus);
}
}else{
//check if there is a valid transaction
$hasTransaction = $this -> isTransactionWithinPeriod($transactionList, $userAccount);
//if there is no transaction
if(!$hasTransaction)
//deduct or suspend
$this -> processAccountBalance($userAccount);
}
}
}
/**
*
* 主な機能
*
*/
public function listen(){
if(is_array($this -> payload)){
$start = microtime(true);
$this -> applySuspendAndDeduction($this -> payload["accounts"]);
$this -> reportObject["elapsed_time"] = sprintf("%.5f", microtime(true) - $start);
$this -> reportObject["test_only"] = $this -> forTest;
echo json_encode($this -> reportObject);
}
}
}
$suspendAndDeduct = new SuspendAndDeduct();
$suspendAndDeduct -> listen();
\ No newline at end of file
...@@ -211,8 +211,11 @@ class DBAccess extends Cnnector { ...@@ -211,8 +211,11 @@ class DBAccess extends Cnnector {
throw new Exception($this -> getMessage(ERROR, 'E_SQL_EXE_ERROR', array($sqlString)), -1); throw new Exception($this -> getMessage(ERROR, 'E_SQL_EXE_ERROR', array($sqlString)), -1);
} }
$rtnArr = $this -> setResultForArray($result); if(!is_bool($result)){
$this -> afterProc($result); $rtnArr = $this -> setResultForArray($result);
$this -> afterProc($result);
}else
$rtnArr = [];
return $rtnArr; return $rtnArr;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment