486 lines
18 KiB
PHP
486 lines
18 KiB
PHP
<?php
|
|
|
|
ini_set('display_errors', 'Off');
|
|
ini_set('error_reporting', E_ALL);
|
|
|
|
class ProductsController extends AppController
|
|
{
|
|
|
|
var $uses = array('Expense', 'GroupExpense', 'Participant', 'DemoExpense', 'AccessInfo', 'User', 'Product', 'Wallet');
|
|
public $components = array(
|
|
'RequestHandler',
|
|
'MobileDetect'
|
|
);
|
|
private $app_version = "1"; // 1= old expense date, 2= new expense date
|
|
|
|
|
|
public function initialize()
|
|
{
|
|
|
|
$this->app_version = "1"; // 1= old app; 2=new app; date related
|
|
$this->setDefaultTimeStamp();
|
|
}
|
|
|
|
public function beforeFilter()
|
|
{
|
|
parent::beforeFilter(); // TODO: Change the autogenerated stub
|
|
}
|
|
|
|
public function beforeRender()
|
|
{
|
|
// parent::beforeRender();
|
|
|
|
// $this->layout = 'visitor';
|
|
}
|
|
|
|
|
|
// product List API
|
|
public function list()
|
|
{
|
|
|
|
list($data, $status, $status_desc, $error) = $this->processValidation('GET');
|
|
|
|
$input = array();
|
|
if (empty($status)) {
|
|
|
|
$activeStatus = 1;
|
|
$conditions = array('status' => $activeStatus);
|
|
$this->loadModel('Product');
|
|
$products = $this->Product->list($conditions);
|
|
|
|
if(!empty($products)){
|
|
|
|
$input["products"] = $products;
|
|
|
|
$status = "+000";
|
|
$status_desc = "SUCCESS.";
|
|
|
|
} else {
|
|
$status = "-995";
|
|
$status_desc = "Product Not Found.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->processResponse($input, $data, $status, $status_desc);
|
|
}
|
|
|
|
// myproducts API
|
|
public function myproducts()
|
|
{
|
|
list($data, $status, $status_desc, $error) = $this->processValidation('GET');
|
|
|
|
if (empty($status)) {
|
|
list($status, $status_desc, $userObj) = $this->validateUser($data['user_id']);
|
|
}
|
|
|
|
$input = array();
|
|
if (empty($status)) {
|
|
$this->loadModel('Product');
|
|
$this->loadModel('Order');
|
|
|
|
$activeStatus = 1;
|
|
$productIds = array();
|
|
$orderArr = array();
|
|
$expenseTypeArr = [1,2,3];
|
|
|
|
$orderConditions = array(
|
|
'user_id' => $data['user_id'],
|
|
'SUBSTR(order_unique_id,1,1)' => $data['expense_type'],
|
|
'expire_date > ' => $this->getSystemCurrentTimeStamp(),
|
|
);
|
|
$orders = $this->Order->list($orderConditions);
|
|
|
|
if(!empty($orders)){
|
|
|
|
foreach($orders as $k => $order){
|
|
if(!in_array($order['Order']['product_id'], $productIds)){
|
|
$productIds[] = $order['Order']['product_id'];
|
|
$orderArr[] = $order['Order'];
|
|
}
|
|
}
|
|
|
|
$prodConditions = array(
|
|
'status' => $activeStatus,
|
|
'id' => $productIds
|
|
);
|
|
if(in_array($data['expense_type'], $expenseTypeArr)){
|
|
$prodConditions['expense_type'] = $data['expense_type'];
|
|
}
|
|
$products = $this->Product->list($prodConditions);
|
|
|
|
$input["products"] = $products;
|
|
$input["orders"] = $orderArr;
|
|
|
|
$status = "+000";
|
|
$status_desc = "SUCCESS.";
|
|
|
|
} else {
|
|
$status = "-994";
|
|
$status_desc = "Order Not Found.";
|
|
}
|
|
|
|
}
|
|
|
|
$this->processResponse($input, $data, $status, $status_desc);
|
|
}
|
|
|
|
|
|
// product buy API
|
|
public function buy()
|
|
{
|
|
|
|
list($data, $status, $status_desc, $error) = $this->processValidation();
|
|
|
|
if (empty($status)) {
|
|
list($status, $status_desc) = $this->validateBuyProduct($data);
|
|
}
|
|
|
|
if (empty($status)) {
|
|
list($status, $status_desc, $userObj) = $this->validateUser($data['user_id']);
|
|
}
|
|
|
|
$input = array();
|
|
if (empty($status)) {
|
|
|
|
$this->loadModel('Product');
|
|
$this->loadModel('Order');
|
|
$this->loadModel('OrderBilling');
|
|
$this->loadModel('Transaction');
|
|
$this->loadModel('Recurring');
|
|
$this->loadModel('Wallet');
|
|
|
|
$activeStatus = 1;
|
|
$conditions = array(
|
|
'id' => $data['product_id'],
|
|
'sku' => $data['product_sku'],
|
|
'status' => $activeStatus
|
|
);
|
|
$productData = $this->Product->list($conditions);
|
|
|
|
if (!empty($productData)) {
|
|
$product = $productData[0];
|
|
|
|
// user wallet data
|
|
$wConditions = array(
|
|
'user_id' => $data['user_id'],
|
|
'status' => $activeStatus
|
|
);
|
|
$userWallet = $this->Wallet->list($wConditions);
|
|
$userWalletData = (isset($userWallet[0]['Wallet'])) ? $userWallet[0]['Wallet'] : array();
|
|
|
|
|
|
// Insert into orders
|
|
$orderInput = $this->preparingOrderInput($data, $product, $userObj['id']);
|
|
$orderObj = $this->Order->add($orderInput);
|
|
$input["order"] = $orderObj[1];
|
|
unset($input["order"]['id']);
|
|
|
|
if (isset($orderObj[1]['id']) && ($orderObj[1]['id'] > 0)) {
|
|
|
|
// Order_billings
|
|
$billingData = (isset($data['billing_info'])) ? $data['billing_info'] : array();
|
|
$orderBillingInput = $this->preparingOrderBillingInput($userObj, $orderObj[1]['id'], $billingData);
|
|
$orderBillingObj = $this->OrderBilling->add($orderBillingInput);
|
|
|
|
// transactions
|
|
$transactionInput = $this->preparingTransactionInput($data, $product, $orderObj[1], $userWalletData);
|
|
$transactionObj = $this->Transaction->add($transactionInput);
|
|
}
|
|
|
|
// incase Recurrings
|
|
if ($product['type'] == 1) // 0 = One Time, 1 = Recurring
|
|
{
|
|
$recurringInput = $this->preparingRecurringInput($data, $product);
|
|
$recurringObj = $this->Recurring->add($recurringInput);
|
|
}
|
|
|
|
// Update user table expiry date
|
|
$this->updateUserTableExpiryDate($data['user_id'], $product);
|
|
|
|
$status = "+000";
|
|
$status_desc = "SUCCESS.";
|
|
} else {
|
|
$status = "-995";
|
|
$status_desc = "Product Not Found.";
|
|
}
|
|
}
|
|
|
|
$this->processResponse($input, $data, $status, $status_desc);
|
|
}
|
|
|
|
|
|
private function preparingOrderBillingInput($user, $order_id, $billingData)
|
|
{
|
|
$returnData = array();
|
|
$returnData['order_id'] = $order_id;
|
|
$returnData['first_name'] = (isset($billingData['first_name'])) ? $billingData['first_name'] : $user['first_name'];
|
|
$returnData['last_name'] = (isset($billingData['last_name'])) ? $billingData['last_name'] : $user['last_name'];
|
|
$returnData['address1'] = (isset($billingData['address1'])) ? $billingData['address1'] : '';
|
|
$returnData['address2'] = (isset($billingData['address2'])) ? $billingData['address2'] : '';
|
|
$returnData['city'] = (isset($billingData['city'])) ? $billingData['city'] : '';
|
|
$returnData['state'] = (isset($billingData['state'])) ? $billingData['state'] : '';
|
|
$returnData['zip'] = (isset($billingData['zip'])) ? $billingData['zip'] : '';
|
|
$returnData['country'] = (isset($billingData['country'])) ? $billingData['country'] : '';
|
|
$returnData['phone'] = (isset($billingData['phone'])) ? $billingData['phone'] : '';
|
|
$returnData['email'] = (isset($billingData['email'])) ? $billingData['email'] : $user['profile_id'];
|
|
$returnData["created_date"] = $this->getSystemCurrentTimeStamp();
|
|
$returnData["updated_date"] = $this->getSystemCurrentTimeStamp();
|
|
|
|
return $returnData;
|
|
}
|
|
|
|
private function preparingTransactionInput($data, $product, $order, $userWalletData)
|
|
{
|
|
$returnData = array();
|
|
$returnData['payment_id'] = $order['payment_id'];
|
|
$returnData['user_id'] = $data['user_id'];
|
|
$returnData['type'] = 1; // 1 = Purchase, 2 = Deposit
|
|
$returnData['entity_id'] = $order['id']; //order_id / deposit_id
|
|
$returnData['description'] = '';
|
|
$returnData['product_price'] = $product['price'];
|
|
$returnData['fee'] = 0;
|
|
$returnData['gross'] = $product['price'];
|
|
$returnData['cost'] = 0;
|
|
$returnData['net'] = $product['price'];
|
|
$returnData['currency_id'] = 1; // 1 = USD
|
|
$returnData['money_flow'] = '-';
|
|
$returnData['current_balance'] = (isset($userWalletData['balance']))? $userWalletData['balance'] : 0;
|
|
$returnData['status'] = 1; //0 = Pending, 1= Paid, 2 = Refund, 3 = Payment Fail
|
|
$returnData["created_date"] = $this->getSystemCurrentTimeStamp();
|
|
$returnData["updated_date"] = $this->getSystemCurrentTimeStamp();
|
|
|
|
return $returnData;
|
|
}
|
|
|
|
private function preparingRecurringInput($data, $product)
|
|
{
|
|
/*
|
|
* id
|
|
* user_id
|
|
* product_id
|
|
* expense_type 1=Group, 2= Mess, 3 = Family
|
|
* next_action_date
|
|
* amount
|
|
* total_amount
|
|
* payment_number Total number of installments
|
|
* payment_interval after how many payment cycle
|
|
* payment_cycle D, W, M, Y
|
|
* created_date
|
|
* updated_date
|
|
* */
|
|
|
|
|
|
$returnData = array();
|
|
$returnData['user_id'] = $data['user_id'];
|
|
$returnData['product_id'] = $data['product_id'];
|
|
$returnData['expense_type'] = $product['expense_type'];
|
|
$returnData['product_price'] = $product['price'];
|
|
$returnData["start_date"] = $this->getSystemCurrentTimeStamp();
|
|
$returnData['next_action_date'] = $this->getNextActionDate($product, $returnData["start_date"]);
|
|
$returnData["amount"] = $data['amount']; // for recurring product
|
|
$returnData['total_amount'] = $data['amount'] * $product['payment_number'];
|
|
$returnData['payment_number'] = $product['payment_number']; //Total number of installments
|
|
$returnData["payment_interval"] = $product['payment_interval']; // after how many payment cycle
|
|
$returnData['payment_cycle'] = $product['payment_cycle']; // D, W, M, Y
|
|
$returnData["created_date"] = $this->getSystemCurrentTimeStamp();
|
|
$returnData["updated_date"] = $this->getSystemCurrentTimeStamp();
|
|
|
|
return $returnData;
|
|
}
|
|
|
|
private function getNextActionDate($product, $start_date)
|
|
{
|
|
if ($product['type']) { // if recurring
|
|
$intervalType = 0; // day
|
|
if ($product['payment_interval'] > 0) {
|
|
|
|
switch ($product['payment_cycle']) {
|
|
case "D":
|
|
$unit = $product['payment_interval'];
|
|
break;
|
|
case "W":
|
|
$unit = $product['payment_interval'] * 7;
|
|
break;
|
|
case "M":
|
|
$intervalType = 1;
|
|
$unit = $product['payment_interval'];
|
|
break;
|
|
case "Y":
|
|
$intervalType = 2;
|
|
$unit = $product['payment_interval'];
|
|
break;
|
|
default:
|
|
$unit = 0;
|
|
}
|
|
}
|
|
|
|
if ($intervalType == 1) { // month
|
|
return date('Y-m-d H:i:s', strtotime('+' . $unit . ' months', strtotime($start_date)));
|
|
} elseif ($intervalType == 2) { // year
|
|
return date('Y-m-d H:i:s', strtotime('+' . $unit . ' years', strtotime($start_date)));
|
|
} else {
|
|
return date('Y-m-d H:i:s', strtotime('+' . $unit . ' days', strtotime($start_date)));
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private function preparingOrderInput($data, $product, $user_id)
|
|
{
|
|
$returnData = array();
|
|
$returnData['payment_id'] = $this->systemGeneratedUniqueId($user_id, $product['expense_type']);
|
|
$order_unique_id = $this->orderUniqueId($data, $product['expense_type']);
|
|
$returnData['order_unique_id'] = $order_unique_id;
|
|
$returnData['purchase_token'] = hash('sha256',$order_unique_id);
|
|
$returnData['user_id'] = $data['user_id'];
|
|
$returnData['product_id'] = $data['product_id'];
|
|
$returnData['expire_date'] = $this->getProductExpireDate($product);
|
|
$returnData['product_price'] = $product['price'];
|
|
$returnData['fee'] = 0;
|
|
$returnData['gross'] = $product['price'];
|
|
$returnData['cost'] = 0;
|
|
$returnData['net'] = $product['price'];
|
|
$returnData['currency_id'] = $product['currency_id'];
|
|
$returnData['platform_id'] = $data['platform_id']; // 1=iOS,2=Android,3=Windows
|
|
$returnData["device_id"] = session_id();
|
|
$returnData['status'] = 1; //0 = Pending, 1= Paid, 2 = Refund, 3 = Payment Fail
|
|
$returnData['type'] = $product['type']; //0 = One Time, 1 = Recurring
|
|
$returnData["user_ip"] = $this->getClientIp();
|
|
$returnData['payment_type_id'] = $data['payment_type_id'];
|
|
$returnData["created_date"] = $this->getSystemCurrentTimeStamp();
|
|
$returnData["updated_date"] = $this->getSystemCurrentTimeStamp();
|
|
|
|
return $returnData;
|
|
}
|
|
|
|
private function orderUniqueId($data, $expense_type)
|
|
{
|
|
return $expense_type . '-' . $data['user_id'] . '-' . time();
|
|
}
|
|
|
|
private function updateUserTableExpiryDate($user_id, $product)
|
|
{
|
|
$status = false;
|
|
if ($user_id > 0) {
|
|
switch ($product['expense_type']) {
|
|
case "1":
|
|
$fields['group_expiry_date'] = '"' . $this->getProductExpireDate($product) . '"';
|
|
if ($this->User->updateFieldsById($user_id, $fields)) {
|
|
$status = true;
|
|
}
|
|
break;
|
|
case "2":
|
|
$fields['mess_expiry_date'] = '"' . $this->getProductExpireDate($product) . '"';
|
|
if ($this->User->updateFieldsById($user_id, $fields)) {
|
|
$status = true;
|
|
}
|
|
break;
|
|
case "3":
|
|
$fields['family_expiry_date'] = '"' . $this->getProductExpireDate($product) . '"';
|
|
if ($this->User->updateFieldsById($user_id, $fields)) {
|
|
$status = true;
|
|
}
|
|
break;
|
|
default:
|
|
// do nothing
|
|
break;
|
|
}
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
private function getProductExpireDate($product)
|
|
{
|
|
$unit = 0;
|
|
$intervalType = 0; // day
|
|
if ($product['payment_interval'] > 0) {
|
|
|
|
switch ($product['payment_cycle']) {
|
|
case "D":
|
|
$unit = $product['payment_interval'];
|
|
break;
|
|
case "W":
|
|
$unit = $product['payment_interval'] * 7;
|
|
break;
|
|
case "M":
|
|
$intervalType = 1;
|
|
$unit = $product['payment_interval'];
|
|
break;
|
|
case "Y":
|
|
$intervalType = 2;
|
|
$unit = $product['payment_interval'];
|
|
break;
|
|
default:
|
|
$unit = 0;
|
|
}
|
|
}
|
|
if ($intervalType == 1) { // month
|
|
return date('Y-m-d H:i:s', strtotime('+' . $unit . ' months'));
|
|
} elseif ($intervalType == 2) { // year
|
|
return date('Y-m-d H:i:s', strtotime('+' . $unit . ' years'));
|
|
} else {
|
|
return date('Y-m-d H:i:s', strtotime('+' . $unit . ' days'));
|
|
}
|
|
}
|
|
|
|
|
|
private function validateBuyProduct($data)
|
|
{
|
|
|
|
//check validity
|
|
$error = "";
|
|
$error_desc = "";
|
|
|
|
|
|
if (empty($error)) {
|
|
if (!array_key_exists('product_id', $data)
|
|
|| !array_key_exists('product_sku', $data)
|
|
|| !array_key_exists('user_id', $data)
|
|
) {
|
|
$error = "6";
|
|
$error_desc = "product_id, product_sku and user_id are required";
|
|
}
|
|
}
|
|
|
|
if (empty($error)) {
|
|
if (array_key_exists('billing_info', $data)) {
|
|
|
|
if (array_key_exists('phone', $data['billing_info']) && ($data['billing_info']['phone'] != '')) {
|
|
if (!is_numeric($data['billing_info']['phone'])) {
|
|
$error = "7";
|
|
$error_desc = "phone number must be numeric";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (empty($error)) {
|
|
if (array_key_exists('billing_info', $data)) {
|
|
|
|
if (array_key_exists('zip', $data['billing_info']) && ($data['billing_info']['zip'] != '')) {
|
|
if (!is_numeric($data['billing_info']['zip'])) {
|
|
$error = "8";
|
|
$error_desc = "zip code must be numeric";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (empty($error)) {
|
|
if (array_key_exists('billing_info', $data)) {
|
|
if (array_key_exists('email', $data['billing_info'])) {
|
|
$regex = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/';
|
|
if (!preg_match($regex, $data['billing_info']['email'])) {
|
|
$error = "9";
|
|
$error_desc = "email address is invalid";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return array($error, $error_desc);
|
|
}
|
|
|
|
|
|
}
|