File "Helper.php"
Full Path: /home/clickysoft/public_html/jmapi5.clickysoft.net/app/Helpers/Helper.php
File size: 28.72 KB
MIME-type: text/x-php
Charset: utf-8
<?php
use App\Models\AddressBook;
use App\Models\Coupon;
use App\Models\Order;
use App\Models\PayJunctionPayments;
use App\Models\ProductPrice;
use App\Models\User;
use Carbon\Carbon;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\Response as HTTPResponse;
if (!function_exists('getShippingQuoteServices')) {
function getShippingQuoteServices($request_body, $endpoint): array
{
$api_key = config('app.web_ship_api_key');
$client = new Client();
$headers = [
'Authorization' => $api_key,
'accept' => 'application/json',
'Content-Type' => 'application/json',
];
try {
$request = new \GuzzleHttp\Psr7\Request('POST', $endpoint, $headers, json_encode($request_body));
$res = $client->sendAsync($request)->wait();
$statusCode = $res->getStatusCode();
if ($statusCode == 200) {
$response = json_decode($res->getBody(), true);
$data = [];
if (isset($response['quotes'])) {
foreach ($response['quotes'] as $value) {
if (array_key_exists($value['serviceCode'], Order::DELIVERY_PACKAGES)) {
$data[] = [
"carrierCode" => $value['carrierCode'],
"serviceCode" => $value['serviceCode'],
"serviceDescription" => $value['serviceDescription'],
"visualDescription" => Order::DELIVERY_PACKAGES[$value['serviceCode']] . ' - $' . $value['totalAmount'],
"packageTypeCode" => $value['packageTypeCode'],
"currency" => $value['currency'],
"totalAmount" => $value['totalAmount'],
];
}
}
} else {
$data = $response;
};
return [
'success' => true,
'data' => $data
];
} else {
return [
'success' => false,
'data' => []
];
}
} catch (GuzzleException $exception) {
Log::info('getShippingQuoteServices error');
Log::info($exception->getMessage());
return [
'success' => false,
'data' => []
];
}
}
}
if (!function_exists('prepareDataForShippingQuote')) {
function prepareDataForShippingQuote(Request $request): array
{
$shipping_address = AddressBook::find($request->get('shipping_address_id'));
$request_body = [
"carrierCode" => $request->get('career_code', 'ups'), //ups
"serviceCode" => $request->get('service_code', ''), //ups_ground
"packageTypeCode" => $request->get('package_type_code', ''), //ups_custom_package
"residential" => (bool) $request->get('is_residential'),
"signatureOptionCode" => null,
"sender" => [
"country" => "US",
"zip" => "92373"
],
"receiver" => [
"country" => "US",
"zip" => $shipping_address->zipcode ?? $request->get('zipcode'),
],
"weightUnit" => "lb",
"dimUnit" => "in",
"currency" => "USD",
"customsCurrency" => "USD",
];
$pieces = [];
foreach ($request->get('products') as $product) {
$price = ProductPrice::find($product['price_id']);
for ($i = 0; $i < $product['quantity']; $i++) {
$pieces[] = [
'weight' => (string) $price->shipping_weight,
'length' => $price->length ?? null,
'width' => $price->width ?? null,
'height' => $price->height ?? null,
'insuranceAmount' => null,
'declaredValue' => null,
];
}
}
$request_body['pieces'] = $pieces;
return $request_body;
}
}
if (!function_exists('reportDateRange')) {
function reportDateRange(Request $request): array
{
switch ($request->get('report_type')) {
case 'daily':
$start_year = $request->get('date');
$date_range = [
'year_from' => Carbon::createFromFormat('Y-m-d', $start_year)->startOfDay(),
'year_to' => Carbon::createFromFormat('Y-m-d', $start_year)->endOfDay(),
];
break;
case 'weekly':
$start_year = $request->get('date');
$date_range = [
'year_from' => Carbon::createFromFormat('Y-m-d', $start_year)->startOfDay(),
'year_to' => Carbon::createFromFormat('Y-m-d', $start_year)->addDays(6)->endOfDay(),
];
break;
case 'monthly':
$start_year = $request->get('date');
$date_range = [
'year_from' => Carbon::make($start_year)->startOfMonth(),
'year_to' => Carbon::make($start_year)->endOfMonth(),
];
break;
case 'current_year':
$date_range = [
'year_from' => now()->startOfYear(),
'year_to' => now()->endOfYear(),
];
break;
case 'current_month':
$date_range = [
'year_from' => now()->startOfMonth(),
'year_to' => now()->endOfMonth(),
];
break;
case 'previous_month':
$date_range = [
'year_from' => now()->subMonth()->startOfMonth(),
'year_to' => now()->subMonth()->endOfMonth(),
];
break;
case 'custom':
$start_year = $request->get('year_from');
$end_year = $request->get('year_to');
$date_range = [
'year_from' => Carbon::createFromFormat('Y-m-d', "$start_year-01-01"),
'year_to' => Carbon::createFromFormat('Y-m-d', "$end_year-12-31"),
];
break;
default:
$date_range = [
'year_from' => now()->startOfYear()->subYear(),
'year_to' => now()->endOfYear()->subYear(),
];
break;
}
return $date_range;
}
}
function getPJClient(): Client
{
$pj_user = config("app.pj_user");
$pj_pass = config("app.pj_pass");
$pj_app_key = config("app.pj_key");
$headers = [
"X-PJ-Application-Key" => $pj_app_key,
"Authorization" => "Basic " . base64_encode("{$pj_user}:{$pj_pass}"),
];
return new Client([
'base_uri' => config("app.pj_url"),
"headers" => $headers,
]);
}
if (!function_exists('createPJCustomer')) {
function createPJCustomer($billing_address_id, User $user): bool
{
$client = getPJClient();
$billingAddress = AddressBook::find($billing_address_id);
$data = [
"firstName" => $billingAddress->primary_contact_name,
"email" => $billingAddress->primary_contact_email,
"address" => $billingAddress->address_line_1,
"zip" => $billingAddress->zipcode,
];
try {
$res = $client->post("/customers", ["form_params" => $data]);
if ($res->getStatusCode() == 200) {
$contents = json_decode($res->getBody()->getContents());
$user->update(['pj_customer_id' => $contents->customerId]);
$user->save();
return true;
} else {
return false;
}
} catch (GuzzleException $e) {
Log::info('Pay Junction Create Customer Error');
Log::info($e->getMessage());
return false;
}
}
}
if (!function_exists('createPJCustomerVault')) {
function createPJCustomerVault(User $user, $billing_address_id, $card_data): array
{
$billingAddress = AddressBook::find($billing_address_id);
$data = [
"cardNumber" => $card_data['cardNumber'],
"cardExpMonth" => $card_data['cardExpMonth'],
"cardExpYear" => $card_data['cardExpYear'],
"cvv" => $card_data['cvv'],
"address" => $billingAddress->address_line_1,
"zip" => $billingAddress->zipcode,
];
$client = getPJClient();
try {
$res = $client->post("/customers/{$user->pj_id}/vaults", ["form_params" => $data]);
if ($res->getStatusCode() == 200) {
$contents = json_decode($res->getBody()->getContents());
return [
'success' => true,
'vault_id' => $contents->vaultId,
];
} else {
return [
'success' => false,
'error' => 'Could not create customer vault.',
];
}
} catch (GuzzleException $e) {
Log::info('Pay Junction Create Customer Vault Error');
Log::info($e->getMessage());
return [
'success' => false,
'vault_id' => 'Unable to create customer vault.',
];
}
}
}
if (!function_exists('chargeByVaultId')) {
function chargeByVaultId($billing_address_id, $vault_id, $amount): array
{
$billingAddress = AddressBook::find($billing_address_id);
$details = [
"vaultId" => $vault_id,
"action" => "CHARGE",
"amountBase" => number_format($amount, 2, '.', ''),
"billingAddress" => $billingAddress->address_line_1,
"billingZip" => $billingAddress->zipcode,
"invoiceNumber" => time()
];
try {
$client = getPJClient();
$res = $client->post("/transactions", ["form_params" => $details]);
if (!$res->getStatusCode() == 200) {
return [
'success' => false,
'error' => 'Unable to process payment.',
];
}
$response = json_decode($res->getBody()->getContents());
if (!$response?->response?->approved) {
return [
'success' => false,
'error' => $response?->response?->message,
];
}
$transactionData = [
"transaction_id" => $response->transactionId,
"terminal_id" => $response->terminalId,
"action" => $response->action,
"amount_base" => $response->amountBase,
"amount_total" => $response->amountTotal,
"method" => $response->method,
"status" => $response->status,
"approved" => $response?->response?->approved,
"message" => $response?->response?->message,
"account_type" => $response?->vault?->accountType,
"last_four" => $response?->vault?->lastFour,
];
$rec = PayJunctionPayments::create($transactionData);
return [
'success' => true,
'response' => $rec,
];
} catch (GuzzleException $e) {
Log::info('Pay Junction Charge Via Vault Error');
Log::info($e->getMessage());
return [
'success' => false,
'error' => 'Unable to process payment.',
];
}
}
}
if (!function_exists('chargeByCard')) {
function chargeByCard($billing_address_id, $amount, $data)
{
$billingAddress = AddressBook::find($billing_address_id);
$cardData = [
"cardNumber" => $data['card_number'], //Valid Credit Card Number.
"cardExpMonth" => $data['expiry_month'], //1-12, Ex: 8
"cardExpYear" => $data['expiry_year'], //4 Digit Format. Ex: 2015
"cardCvv" => $data['ccv'], //Valid CVV. Max Length 4
];
$exploded = explode(" ", $billingAddress->primary_contact_name);
$first_name = $exploded[0];
unset($exploded[0]);
$last_name = implode(' ', $exploded);
$otherFields = [
"status" => "CAPTURE",
"action" => "CHARGE",
"amountBase" => number_format($amount, 2, '.', ''),
"billingFirstName" => $first_name,
"billingAddress" => $billingAddress->address_line_1,
"billingZip" => $billingAddress->zipcode,
"invoiceNumber" => time(),
];
if ($last_name != '') {
$otherFields['billingLastName'] = $last_name;
}
try {
$client = getPJClient();
$res = $client->post("/transactions", ["form_params" => array_merge($cardData, $otherFields)]);
if ($res->getStatusCode() == 200) {
$response = json_decode($res->getBody()->getContents());
if (!$response?->response?->approved) {
return [
'success' => false,
'error' => $response?->response?->message,
];
}
$transactionData = [
"transaction_id" => $response->transactionId,
"terminal_id" => $response->terminalId,
"action" => $response->action,
"amount_base" => $response->amountBase,
"amount_total" => $response->amountTotal,
"method" => $response->method,
"status" => $response->status,
"approved" => $response?->response?->approved,
"message" => $response?->response?->message,
"account_type" => $response?->vault?->accountType,
"last_four" => $response?->vault?->lastFour,
];
$rec = PayJunctionPayments::create($transactionData);
return [
'success' => true,
'response' => $rec,
];
}
} catch (GuzzleException $e) {
Log::info('Pay Junction Charge Via Card Error');
Log::info($e->getMessage());
return [
'success' => false,
'error' => isset(json_decode($e->getResponse()->getBody(true))->errors[0]->message)
? json_decode($e->getResponse()->getBody(true))->errors[0]->message
: 'Unable to process payment.',
];
}
}
}
if (!function_exists('getCustomerVaults')) {
function getCustomerVaults($customer_id)
{
$client = getPJClient();
$customer_vaults = [];
try {
$api_response = $client->get("/customers/{$customer_id}/vaults");
if ($api_response->getStatusCode() == 200) {
$response = json_decode($api_response->getBody()->getContents());
foreach ($response->results as $card) {
$customer_vaults[] = [
'vault_id' => $card->vaultId,
'type' => $card->type,
'account_type' => $card->accountType,
'last_four' => $card->lastFour,
'expiry_month' => $card->cardExpMonth,
'expiry_year' => $card->cardExpYear,
];
}
return $customer_vaults;
}
} catch (GuzzleException $e) {
Log::info('Pay Junction Get Customer Vaults. ID : ' . $customer_id);
Log::info($e->getMessage());
return $customer_vaults;
}
}
}
function createPJInvoice($data)
{
$client = getPJClient();
$details = [
'amountBase' => $data['amount'],
'customerEmail' => $data['customer_email'],
'message' => 'Invoice for order #' . $data['order_number'],
'terminalId' => config('app.pj_tid'),
'notificationType' => 'NONE',
];
try {
$api_response = $client->post("/invoices", ["form_params" => $details]);
if ($api_response->getStatusCode() == 200) {
return json_decode($api_response->getBody()->getContents());
}
} catch (GuzzleException $e) {
Log::info('Pay Junction Create Invoice Error');
Log::info($e->getMessage());
return null;
}
}
function getPJInvoice($invoice_id)
{
$client = getPJClient();
try {
$api_response = $client->get("/invoices/$invoice_id");
if ($api_response->getStatusCode() == 200) {
return json_decode($api_response->getBody()->getContents());
}
} catch (GuzzleException $e) {
Log::info('Pay Junction Get Invoice Error');
Log::info($e->getMessage());
return null;
}
}
function voidPJInvoice($invoice_id)
{
$client = getPJClient();
try {
$api_response = $client->post("/invoices/$invoice_id/void");
if ($api_response->getStatusCode() == 200) {
return true;
}
} catch (GuzzleException $e) {
Log::info('Pay Junction Void Invoice Error');
Log::info($e->getMessage());
return null;
}
}
if (!function_exists('generatePJInvoice')) {
function generatePJInvoice(Order $order)
{
$response = null;
if ($order->remaining_order_amount > 0 && $order->remaining_order_amount < 1) {
$order->payment_status = 'Paid';
$order->remaining_order_amount = 0;
$order->paid_order_amount = $order->grand_total;
$order->payment_date = new DateTime();
$order->save();
} else {
$formated_remaining_amount = (float) number_format($order->remaining_order_amount, 2, '.', '');
//Get invoice if exists
$data = [
'amount' => $formated_remaining_amount,
'customer_email' => $order->user->email,
'order_number' => $order->order_number,
];
if ($order->pj_invoice_id == null) { // If an invoice doesn't exist for this order
$response = createPJInvoice($data); // Create a new invoice
if ($response) {
$order->pj_invoice_id = $response->invoiceId;
$order->save();
}
} else {
$pj_invoice = getPJInvoice($order->pj_invoice_id);
if ($pj_invoice->status == "OPEN") { // If the invoice is created but not paid yet
if ($pj_invoice->amountBase == $formated_remaining_amount) { //Do not create new invoice if amount is same
$response = $pj_invoice;
} else { // Void the previous invoice and create a new one with updated data
voidPJInvoice($pj_invoice->invoiceId);
Log::channel('info_errors')->info("PJ invoice ID $order->pj_invoice_id will removed for order id $order->id.");
$order->pj_invoice_id = null;
$order->save();
if ($response = createPJInvoice($data)) {
$order->pj_invoice_id = $response->invoiceId;
$order->save();
Log::channel('info_errors')->info("PJ invoice new ID $order->pj_invoice_id for order id $order->id.");
}
}
} else if ($pj_invoice->status == "PAID") { // If the invoice is already paid
$order->payment_status = 'Paid';
$order->remaining_order_amount = 0;
$order->paid_order_amount = $order->grand_total;
$order->payment_date = new DateTime();
$order->save();
}
}
}
return $response; // Return the invoice response
}
}
if (!function_exists('validateCouponDetails')) {
function validateCouponDetails($code)
{
$coupon = Coupon::where('code', $code)->where('status', 1)->first();
if (!$coupon) {
return [
'coupon' => null,
'code' => HTTPResponse::HTTP_OK,
'message' => "Invalid coupon code.",
'errors' => ["error" => ["Invalid coupon."]]
];
}
if ($coupon->expiry_date) {
$day_end = $coupon->expiry_date->endOfDay();
if (!now()->lte($day_end)) {
return [
'coupon' => null,
'code' => HTTPResponse::HTTP_OK,
'message' => "Coupon has expired.",
'errors' => ["error" => ["Coupon has expired."]]
];
}
}
if ($coupon->number_of_usage > 0 && $coupon->redemption_count >= $coupon->number_of_usage) {
return [
'coupon' => null,
'code' => HTTPResponse::HTTP_OK,
'message' => "Coupon usage limit reached.",
'errors' => ["error" => ["Coupon usage limit reached."]]
];
}
return [
'coupon' => [
'type' => $coupon->discount_type,
'value' => $coupon->discount_value,
],
'code' => HTTPResponse::HTTP_OK,
'message' => "Coupon is valid.",
'errors' => ["error" => []]
];
}
}
if (!function_exists('pdfToImages')) {
function pdfToImages($order_id, $item_id, $template_path): void
{
$folder_name = $order_id . '_' . $item_id;
$imagick = new \Imagick();
if (Storage::disk('order')->exists("$order_id/$folder_name")) {
Storage::disk('order')->deleteDirectory("$order_id/$folder_name");
}
Storage::disk('order')->makeDirectory("$order_id/$folder_name");
$path = Storage::disk('order')->path("$order_id/$folder_name");
$imagick->readImage(Storage::disk('order')->path($template_path));
$format = "png";
$imagick->setImageFormat($format);
foreach ($imagick as $pageNumber => $page) {
$image = $page->clone();
$image->setIteratorIndex((int)$pageNumber);
$image->writeImage($path . '/page_' . ($pageNumber + 1) . '.' . $format);
}
$imagick->clear();
}
}
if (!function_exists('getTemplatePngs')) {
function getTemplatePngs($order_id, $item_id)
{
$folder_name = $order_id . '_' . $item_id;
$disk = 'order';
$pngUrls = [];
if (!Storage::disk('order')->exists("$order_id/$folder_name")) {
return $pngUrls;
}
$files = Storage::disk($disk)->files("$order_id/$folder_name");
foreach ($files as $file) {
$pngUrls[] = Storage::disk($disk)->url($file);
}
return $pngUrls;
}
}
function handleOrderCharge($request, $order_totals): array
{
//Charge via vault_id if we are receiving vault_id
if ($request->get('vault_id')) {
//Charge customer using vault it just created.
$charge_response = chargeByVaultId(
$request->get('billing_address_id'),
$request->get('vault_id'),
$order_totals['grand_total'],
);
if (!$charge_response['success']) {
return [
'charged_successfully' => false,
'message' => "Can not create order.",
'errors' => ["error" => $charge_response["error"]],
'error_code' => HTTPResponse::HTTP_INTERNAL_SERVER_ERROR
];
}
$charge_response['charged_successfully'] = true;
} else {
//If customers allowed to save card
if ($request->get('save_card', false)) {
$customer = User::find($request->get('user_id'));
//Check if PayJunction customerId exists. Create if not present.
if (!$customer->pj_id) {
$customerCreated = createPJCustomer(
$request->get('billing_address_id'),
$customer
);
if (!$customerCreated) {
return [
'charged_successfully' => false,
'message' => "Can not create order.",
'errors' => ["error" => ["Customer creation failed."]],
'error_code' => HTTPResponse::HTTP_INTERNAL_SERVER_ERROR
];
}
}
$card_data = [
"cardNumber" => $request->get('card_number'),
"cardExpMonth" => $request->get('expiry_month'),
"cardExpYear" => $request->get('expiry_year'),
"cvv" => $request->get('ccv')
];
$vaultId = createPJCustomerVault(
$customer,
$request->get('billing_address_id'),
$card_data,
);
if (!$vaultId['success']) {
return [
'charged_successfully' => false,
'message' => "Can not create order.",
'errors' => ["error" => ["Customer vault creation failed. Make sure you enter valid card credentials."]],
'error_code' => HTTPResponse::HTTP_INTERNAL_SERVER_ERROR
];
}
//Charge customer using vault it just created.
$charge_response = chargeByVaultId(
$request->get('billing_address_id'),
$vaultId['vault_id'],
$order_totals['grand_total'],
);
$charge_response['charged_successfully'] = true;
} else {
//Charge by card information
$card_data = [
'card_number' => $request->get('card_number'),
'expiry_month' => $request->get('expiry_month'),
'expiry_year' => $request->get('expiry_year'),
'ccv' => $request->get('ccv'),
];
$charge_response = chargeByCard(
$request->get('billing_address_id'),
$order_totals['grand_total'],
$card_data
);
}
if (!$charge_response['success']) {
return [
'charged_successfully' => false,
'message' => "Can not create order.",
'errors' => ["error" => $charge_response["error"]],
'error_code' => HTTPResponse::HTTP_INTERNAL_SERVER_ERROR
];
} else {
$charge_response['charged_successfully'] = true;
}
}
return $charge_response;
}
function getOrderShippingResponse($request): array
{
$shipping_data = [];
if ($request->has("third_party_shipping")) {
$shipping_data = [
'career_code' => '3ps',
'service_code' => "3rd party shipping",
'package_type_code' => "3rd party shipping",
'shipping_charges' => (float)$request->get("shipping_total_amount"),
];
} else {
$customer_id = config('app.web_ship_customer_id');
$base_url = config('app.web_ship_base_url');
$endpoint = "{$base_url}/customers/{$customer_id}/quote";
$request_body = prepareDataForShippingQuote($request);
$response = getShippingQuoteServices($request_body, $endpoint);
if ($response['data']) {
$shipping_data = [
'career_code' => $response['data']['carrierCode'],
'service_code' => $response['data']['serviceCode'],
'package_type_code' => $response['data']['packageTypeCode'],
'shipping_charges' => $response['data']['totalAmount'],
];
}
}
return $shipping_data;
}
function updatePJTransaction($transaction_id, $invoice_number)
{
try {
$client = getPJClient();
$details = ['invoiceNumber' => $invoice_number];
$client->put("/transactions/$transaction_id", ["form_params" => $details]);
return ['success' => true];
} catch (GuzzleException $exception) {
Log::info('Unable to update PJ transaction: ' . $exception->getMessage());
return ['success' => false];
}
}
function voidPJTransaction($transaction_id)
{
try {
$client = getPJClient();
$details = ['status' => 'VOID'];
$client->put("/transactions/$transaction_id", ["form_params" => $details]);
return ['success' => true];
} catch (GuzzleException $exception) {
Log::info('Unable to void PJ transaction: ' . $exception->getMessage());
return ['success' => false];
}
}