File: /home/assibfaf/www/prox-classes/Module/PaymentModule.php
<?php
/**
* @package Proxim
* @author Davison Pro <davis@davisonpro.dev | https://davisonpro.dev>
* @copyright 2019 Proxim
* @version 1.5.0
* @since File available since Release 1.0.0
*/
namespace Proxim\Module;
use Db;
use PrePaper;
use Proxim\Application;
use Proxim\Configuration;
use Proxim\Currency;
use Proxim\Database\DbQuery;
use Proxim\Mail;
use Proxim\Order\AdditionalService;
use Proxim\Order\Order;
use Proxim\Order\OrderMessage;
use Proxim\Payment;
use Proxim\Preference\Deadline;
use Proxim\Presenter\Order\OrderPresenter;
use Proxim\Site\Site;
use Proxim\Tools;
use Proxim\User\Customer;
use Proxim\User\Wallet as CustomerWallet;
use Proxim\User\Employee;
use Proxim\Util\ArrayUtils;
use Proxim\Util\DateUtils;
use Proxim\Validate;
use Wallet;
abstract class PaymentModule extends Module
{
public $currencies = true;
const DEBUG_MODE = false;
/**
* List all installed and active payment modules.
*
* @see Module::getPaymentModules() if you need a list of module
*
* @return array module informations
*/
public static function getInstalledPaymentModules()
{
$hook_payment = 'Payment';
if (Db::getInstance()->getValue('SELECT `hook_id` FROM ' . Db::prefix('hook') . 's WHERE `name` = \'paymentOptions\'')) {
$hook_payment = 'paymentOptions';
}
return Db::getInstance()->executeS('
SELECT DISTINCT m.`module_id`, h.`hook_id`, m.`name`, hm.`position`
FROM ' . Db::prefix('module') . ' m
LEFT JOIN ' . Db::prefix('hook_module') . ' hm ON hm.`module_id` = m.`module_id`
LEFT JOIN ' . Db::prefix('hook') . ' h ON hm.`hook_id` = h.`hook_id`
WHERE h.`name` = \'' . pSQL($hook_payment) . '\'
');
}
public static function processPayment($nodeId, $handle, $payload = array())
{
$app = Application::getInstance();
$smarty = $app->container->smarty;
switch( $handle ) {
case 'order':
$transaction_id = ArrayUtils::get($payload, 'paymentId');
$order = new Order( (int) $nodeId );
if (!Validate::isLoadedObject($order)) {
return false;
}
$currency = $order->currency;
$options['currency'] = array(
'symbol' => $currency->symbol,
'rate' => $currency->conversion_rate
);
$order->total_paid = $order->total_paid + $order->total;
$old_status = $order->status_id;
$payment = new Payment();
$payment->transaction_id = $transaction_id;
$payment->currency_id = $order->currency_id;
$payment->payment_method = ArrayUtils::get($payload, 'payment_method');
$payment->conversion_rate = $order->currency_to_usd_rate;
$payment->node_id = $order->id;
$payment->node_type = 'order';
$payment->amount = $order->total;
$payment->add();
if (
$old_status == Order::FAKE ||
$old_status == Order::FREE_INQUIRY ||
$old_status == Order::INQUIRY
) {
$customer_deadline = time() + ($order->hrs_customer*60*60);
$writer_deadline = time() + ($order->hrs_writer*60*60);
$order->customer_deadline = DateUtils::date($customer_deadline);
$order->writer_deadline = DateUtils::date($writer_deadline);
if ($order->progressive_delivery) {
$order->status_id = Order::NEW_PAID;
} else {
if(Configuration::get('NEW_ORDER_STATUS', PROX_ADMIN_SITE_ID)) {
$order->status_id = (int) Configuration::get('NEW_ORDER_STATUS', PROX_ADMIN_SITE_ID);
} else {
$order->status_id = Order::ORDER_PUBLISHED;
}
}
$order->is_paid = 1;
$order->paid_at = DateUtils::now();
if ($order->requested_writer_id && Configuration::get('AUTOASSIGN_REQUESTED_WRITER', PROX_ADMIN_SITE_ID)) {
$writer = new Employee( $order->requested_writer_id );
if(Validate::isLoadedObject($writer)) {
$order->status_id = Order::WRITER_ASSIGNED;
$order->writer_id = $writer->id;
$order->writer_assigned = 1;
$order->writer_assigned_at = DateUtils::now();
$order->is_writer_confirmed = 0;
$smarty->assign([
'order_id' => $order->id,
'first_name' => $writer->first_name,
'last_name' => $writer->last_name,
]);
$confirm_order_body = $smarty->fetch('messages/confirm_order.tpl');
$message = new OrderMessage();
$message->order_id = $order->id;
$message->sender_id = Employee::START_ID;
$message->from_department = DEPARTMENT_SUPPORT;
$message->to_department = DEPARTMENT_WRITER;
$message->subject = "Order #".$order->id.": Please confirm that you are working";
$message->body = $confirm_order_body;
$message->is_verified = 1;
$message->verified_at = DateUtils::now();
$message->add();
try {
Mail::Send(
'order_assign',
$message->subject,
array(
'message' => Tools::nl2br($confirm_order_body)
),
$writer->email,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
PROX_ADMIN_SITE_ID
);
} catch( \Exception $e ) {
}
}
}
}
$order->update();
if (
$old_status == Order::FAKE ||
$old_status == Order::FREE_INQUIRY ||
$old_status == Order::INQUIRY
) {
$customer = new Customer( (int) $order->customer_id );
if(Validate::isLoadedObject($customer)) {
$customer->total_spent = $customer->total_spent + $order->total;
$customer->update();
/** process affiliates */
if ( $customer->referrer_id && !$customer->affiliate_used ) {
$app->processAffiliates( $customer->id, $customer->referrer_id );
}
$site = new Site( (int) $customer->site_id );
if( Validate::isLoadedObject($site) ) {
$site->orders = $site->orders+1;
$site->payments = $site->payments + $order->total;
$site->update();
}
try {
$orderPresenter = new OrderPresenter();
Mail::Send(
'payment',
'Payment confirmation for order #' . $order->id,
array(
'type' => 'order',
'order' => $orderPresenter->present($order),
'payment_method' => Tools::ucfirst($order->payment_method),
'paid_at' => DateUtils::date( strtotime($order->paid_at) , null, 'M jS, Y \\a\\t g:i A'),
'paid_amount' => formatPrice($order->total, $options),
'order_url' => $app->base_uri . '/dashboard/order/' . (int) $order->id,
),
$customer->email
);
} catch(\Exception $e) {
}
}
$receivers = array();
$site_email = Configuration::get('SITE_EMAIL', PROX_ADMIN_SITE_ID);
if(!empty($site_email)) {
$receivers[] = $site_email;
}
$notification_emails = $app->getNotificationEmails();
$receivers = array_merge($receivers, $notification_emails);
$receivers = array_unique($receivers);
$sql = new DbQuery();
$sql->select('e.email');
$sql->from('employee', 'e');
$sql->where('employee_group = ' . (int) Employee::GROUP_WRITER);
$sql->where('is_started = 1');
$sql->where('is_banned = 0');
$result = Db::getInstance(PROX_USE_SQL_SLAVE)->executeS($sql);
foreach ($result as $writer) {
if( ArrayUtils::has($writer, 'email') && Validate::isEmail(ArrayUtils::get($writer, 'email')) ) {
$receivers[] = ArrayUtils::get($writer, 'email');
}
}
$mailParams = array(
'type' => 'order',
'order' => $orderPresenter->present($order),
'admin_site_name' => Configuration::get('SITE_NAME', PROX_ADMIN_SITE_ID),
'order_url' => Configuration::get('SITE_DOMAIN', PROX_ADMIN_SITE_ID) . '/order/' . (int) $order->id,
);
foreach ($receivers as $receiver) {
try {
Mail::Send(
'new_order',
'New Order #' . $order->id . ' available',
$mailParams,
$receiver,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
PROX_ADMIN_SITE_ID
);
} catch(\Exception $e) {
}
}
}
return true;
break;
case 'add-payment':
$transaction_id =ArrayUtils::get($payload, 'paymentId');
$addPayment = new AdditionalService( (int) $nodeId );
if (!Validate::isLoadedObject($addPayment)) {
return false;
}
$order = new Order( (int) $addPayment->order_id );
if (!Validate::isLoadedObject($order)) {
return false;
}
if (!$addPayment->is_paid) {
// pages
if($addPayment->pages) $order->pages = $order->pages + $addPayment->pages;
// charts
if($addPayment->charts) $order->charts = $addPayment->charts + $addPayment->charts;
// slides
if($addPayment->slides) $order->slides = $addPayment->slides + $addPayment->slides;
// writer samples
if($addPayment->writer_samples) $order->writer_samples = 1;
// used sources
if($addPayment->used_sources) $order->used_sources = 1;
// expert proofreading
if($addPayment->expert_proofreading) $order->expert_proofreading = 1;
// progressive delivery
if($addPayment->progressive_delivery) $order->progressive_delivery = 1;
// writer category
if($addPayment->writer_category_id) $order->writer_category_id = $addPayment->writer_category_id;
// shorten deadline
if($addPayment->tariff_id) {
$tariff = new Deadline($addPayment->tariff_id);
if ( Validate::isLoadedObject($tariff) ) {
$price_per_page = (float) $tariff->price_per_page;
$hrs_customer = (int) $tariff->hrs_customer;
$hrs_writer = (int) $tariff->hrs_writer;
$customer_deadline = time() + ($hrs_customer*60*60);
$writer_deadline = time() + ($hrs_writer*60*60);
$order->tariff_id = $addPayment->tariff_id;
$order->price_per_page = $price_per_page;
$order->hrs_customer = $hrs_customer;
$order->hrs_writer = $hrs_writer;
$order->customer_deadline = DateUtils::date($customer_deadline);
$order->writer_deadline = DateUtils::date($writer_deadline);
}
}
$order->update();
$addPayment->is_paid = 1;
$addPayment->paid_at = DateUtils::now();
$addPayment->update();
$payment = new Payment();
$payment->transaction_id = $transaction_id;
$payment->currency_id = $order->currency_id;
$payment->payment_method = ArrayUtils::get($payload, 'payment_method');
$payment->conversion_rate = $order->currency_to_usd_rate;
$payment->node_id = $order->id;
$payment->node_type = 'add-payment';
$payment->amount = $addPayment->total;
$payment->add();
$customer = new Customer( (int) $order->customer_id );
if(Validate::isLoadedObject($customer)) {
$customer->total_spent = $customer->total_spent + $addPayment->total;
$customer->update();
$site = new Site( (int) $customer->site_id );
if( Validate::isLoadedObject($site) ) {
$site->payments = $site->payments + $addPayment->total;
$site->update();
}
}
}
return true;
break;
case 'tip':
$amount = (float) ArrayUtils::get($payload, 'amount');
$payment_method = ArrayUtils::get($payload, 'payment_method');
$currency_code = ArrayUtils::get($payload, 'currency');
$transaction_id =ArrayUtils::get($payload, 'paymentId');
$order = new Order( (int) $nodeId );
if (!Validate::isLoadedObject($order)) {
return false;
}
$currencyId = Currency::getIdByIsoCode( $currency_code );
$currency = Currency::getCurrencyInstance( (int) $currencyId);
// check if transaction exists
$query = new DbQuery();
$query->select('order_tip_id');
$query->from('order_tip');
$query->where('transaction_id = \'' . pSQL($transaction_id) . '\'');
$exists = Db::getInstance()->getValue($query);
if(!$exists) {
$result = Db::getInstance()->insert(
'order_tip',
array(
'order_id' => $order->id,
'currency_id' => $currency->id,
'transaction_id' => $transaction_id,
'payment_method' => $payment_method,
'amount' => $amount,
'date_add' => DateUtils::now(),
)
);
$writer_tip_amount = ($amount * Configuration::get('TIP_WRITER_PERCENT', PROX_ADMIN_SITE_ID)) / 100;
$editor_tip_amount = ($amount * Configuration::get('TIP_EDITOR_PERCENT', PROX_ADMIN_SITE_ID)) / 100;
if($writer_tip_amount > 0) {
$order->writer_pay = $order->writer_pay + $writer_tip_amount;
}
if($editor_tip_amount > 0) {
$order->editor_pay = $order->editor_pay + $editor_tip_amount;
}
$order->update();
$payment = new Payment();
$payment->currency_id = $order->currency_id;
$payment->conversion_rate = $order->currency_to_usd_rate;
$payment->node_id = $order->id;
$payment->node_type = 'tip';
$payment->transaction_id = $transaction_id;
$payment->payment_method = $payment_method;
$payment->amount = $amount;
$payment->add();
}
break;
case 'wallet':
$amount = (float) ArrayUtils::get($payload, 'amount');
$payment_method = ArrayUtils::get($payload, 'payment_method');
$currency_code = ArrayUtils::get($payload, 'currency');
$transaction_id =ArrayUtils::get($payload, 'paymentId');
$customer = new Customer( (int) $nodeId );
if (!Validate::isLoadedObject($customer)) {
return false;
}
$currencyId = Currency::getIdByIsoCode( $currency_code );
$currency = Currency::getCurrencyInstance( (int) $currencyId);
// check if transaction exists
$query = new DbQuery();
$query->select('wallet_transaction_id');
$query->from('wallet_transaction');
$query->where('transaction_id = \'' . pSQL($transaction_id) . '\'');
$exists = Db::getInstance()->getValue($query);
if(!$exists) {
$walletId = CustomerWallet::getIdByCustomerId( $customer->id );
if($walletId) {
$wallet = new CustomerWallet( (int) $walletId );
}
if(
!isset($wallet) ||
!Validate::isLoadedObject($wallet)
) {
$wallet = new CustomerWallet();
$wallet->customer_id = $customer->id;
$wallet->wallet_balance = 0;
$wallet->add();
}
$result = Db::getInstance()->insert(
'wallet_transaction',
array(
'wallet_id' => $wallet->id,
'currency_id' => $currency->id,
'transaction_id' => $transaction_id,
'source' => 'deposit',
'payment_method' => $payment_method,
'amount' => $amount,
'date_add' => DateUtils::now(),
)
);
if(!$result) {
return false;
}
$wallet->wallet_balance = $wallet->wallet_balance + $amount;
$wallet->update();
$payment = new Payment();
$payment->currency_id = $currency->id;
$payment->conversion_rate = $currency->conversion_rate;
$payment->node_id = $customer->id;
$payment->node_type = 'wallet';
$payment->transaction_id = $transaction_id;
$payment->payment_method = $payment_method;
$payment->amount = $amount;
$payment->add();
}
return true;
break;
case 'paper':
if(!Module::getInstanceByName('prepapers')) {
return false;
}
$customer_id = (int) ArrayUtils::get($payload, 'customer_id');
$payment_method = ArrayUtils::get($payload, 'payment_method');
$currency_code = ArrayUtils::get($payload, 'currency');
$transaction_id =ArrayUtils::get($payload, 'paymentId');
$prepaper = new PrePaper( (int) $nodeId );
if (!Validate::isLoadedObject($prepaper)) {
return false;
}
$amount = $prepaper->price;
$customer = new Customer( (int) $customer_id );
if (!Validate::isLoadedObject($customer)) {
return false;
}
// check if payment exists
$query = new DbQuery();
$query->select('prepaper_payment_id');
$query->from('prepaper_payment');
$query->where('prepaper_id = ' . (int) $prepaper->id);
$query->where('customer_id = ' . (int) $customer->id);
$exists = Db::getInstance()->getValue($query);
if(!$exists) {
$currency_id = Currency::getIdByIsoCode('USD');
$currency = new Currency($currency_id);
$result = Db::getInstance()->insert(
'prepaper_payment',
array(
'prepaper_id' => $prepaper->id,
'customer_id' => $customer->id,
'payment_token' => $transaction_id,
'payment_method' => $payment_method,
'amount' => $amount,
'is_paid' => true,
'paid_at' => DateUtils::now(),
'date_add' => DateUtils::now(),
)
);
if(!$result) {
return false;
}
$payment = new Payment();
$payment->currency_id = $currency->id;
$payment->conversion_rate = $currency->conversion_rate;
$payment->node_id = $prepaper->id;
$payment->node_type = 'paper';
$payment->transaction_id = $transaction_id;
$payment->payment_method = $payment_method;
$payment->amount = $amount;
$payment->add();
}
return true;
break;
}
}
}