1926 lines
72 KiB
PHP
1926 lines
72 KiB
PHP
<?php
|
|
|
|
namespace App\Utils;
|
|
|
|
use App\Business;
|
|
use App\BusinessLocation;
|
|
use App\Contact;
|
|
use App\Product;
|
|
use App\ReferenceCount;
|
|
use App\System;
|
|
use App\Transaction;
|
|
use App\TransactionSellLine;
|
|
use App\Unit;
|
|
use App\User;
|
|
use App\VariationLocationDetails;
|
|
use Config;
|
|
use DB;
|
|
use GuzzleHttp\Client;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Spatie\Permission\Models\Role;
|
|
use Illuminate\Support\Str; // Add this at the top with other imports
|
|
|
|
class Util
|
|
{
|
|
/**
|
|
* This function unformats a number and returns them in plain eng format
|
|
*
|
|
* @param int $input_number
|
|
* @return float
|
|
*/
|
|
public function num_uf($input_number, $currency_details = null)
|
|
{
|
|
$thousand_separator = '';
|
|
$decimal_separator = '';
|
|
|
|
if (! empty($currency_details)) {
|
|
$thousand_separator = $currency_details->thousand_separator;
|
|
$decimal_separator = $currency_details->decimal_separator;
|
|
} else {
|
|
$thousand_separator = session()->has('currency') ? session('currency')['thousand_separator'] : '';
|
|
$decimal_separator = session()->has('currency') ? session('currency')['decimal_separator'] : '';
|
|
}
|
|
|
|
$num = str_replace($thousand_separator, '', $input_number);
|
|
$num = str_replace($decimal_separator, '.', $num);
|
|
|
|
return (float) $num;
|
|
}
|
|
|
|
/**
|
|
* This function formats a number and returns them in specified format
|
|
*
|
|
* @param int $input_number
|
|
* @param bool $add_symbol = false
|
|
* @param array $business_details = null
|
|
* @param bool $is_quantity = false; If number represents quantity
|
|
* @return string
|
|
*/
|
|
public function num_f($input_number, $add_symbol = false, $business_details = null, $is_quantity = false)
|
|
{
|
|
$thousand_separator = ! empty($business_details) ? $business_details->thousand_separator : session('currency')['thousand_separator'];
|
|
$decimal_separator = ! empty($business_details) ? $business_details->decimal_separator : session('currency')['decimal_separator'];
|
|
|
|
$currency_precision = ! empty($business_details) ? $business_details->currency_precision : session('business.currency_precision', 2);
|
|
|
|
if ($is_quantity) {
|
|
$currency_precision = ! empty($business_details) ? $business_details->quantity_precision : session('business.quantity_precision', 2);
|
|
}
|
|
|
|
$formatted = number_format($input_number, $currency_precision, $decimal_separator, $thousand_separator);
|
|
|
|
if ($add_symbol) {
|
|
if (is_persian_lang() && ! $is_quantity) {
|
|
return format_currency_persian($input_number);
|
|
}
|
|
|
|
$currency_symbol_placement = ! empty($business_details) ? $business_details->currency_symbol_placement : session('business.currency_symbol_placement');
|
|
$symbol = ! empty($business_details) ? $business_details->currency_symbol : session('currency')['symbol'];
|
|
|
|
if ($currency_symbol_placement == 'after') {
|
|
$formatted = $formatted.' '.$symbol;
|
|
} else {
|
|
$formatted = $symbol.' '.$formatted;
|
|
}
|
|
}
|
|
|
|
return $formatted;
|
|
}
|
|
|
|
/**
|
|
* Calculates percentage for a given number
|
|
*
|
|
* @param int $number
|
|
* @param int $percent
|
|
* @param int $addition default = 0
|
|
* @return float
|
|
*/
|
|
public function calc_percentage($number, $percent, $addition = 0)
|
|
{
|
|
return $addition + ($number * ($percent / 100));
|
|
}
|
|
|
|
/**
|
|
* Calculates base value on which percentage is calculated
|
|
*
|
|
* @param int $number
|
|
* @param int $percent
|
|
* @return float
|
|
*/
|
|
public function calc_percentage_base($number, $percent)
|
|
{
|
|
return ($number * 100) / (100 + $percent);
|
|
}
|
|
|
|
/**
|
|
* Calculates percentage
|
|
*
|
|
* @param int $base
|
|
* @param int $number
|
|
* @return float
|
|
*/
|
|
public function get_percent($base, $number)
|
|
{
|
|
if ($base == 0) {
|
|
return 0;
|
|
}
|
|
|
|
$diff = $number - $base;
|
|
|
|
return ($diff / $base) * 100;
|
|
}
|
|
|
|
//Returns all avilable purchase statuses
|
|
public function orderStatuses()
|
|
{
|
|
return ['received' => __('lang_v1.received'), 'pending' => __('lang_v1.pending'), 'ordered' => __('lang_v1.ordered')];
|
|
}
|
|
|
|
/**
|
|
* Defines available Payment Types
|
|
*
|
|
* @return array
|
|
*/
|
|
public function payment_types($location = null, $show_advance = false, $business_id = null)
|
|
{
|
|
if (! empty($location)) {
|
|
$location = is_object($location) ? $location : BusinessLocation::find($location);
|
|
|
|
//Get custom label from business settings
|
|
$custom_labels = Business::find($location->business_id)->custom_labels;
|
|
$custom_labels = json_decode($custom_labels, true);
|
|
} else {
|
|
if (! empty($business_id)) {
|
|
$custom_labels = Business::find($business_id)->custom_labels;
|
|
$custom_labels = json_decode($custom_labels, true);
|
|
} else {
|
|
$custom_labels = [];
|
|
}
|
|
}
|
|
|
|
$payment_types = ['cash' => __('lang_v1.cash'), 'card' => __('lang_v1.card'), 'cheque' => __('lang_v1.cheque'), 'bank_transfer' => __('lang_v1.bank_transfer'), 'other' => __('lang_v1.other')];
|
|
|
|
$payment_types['custom_pay_1'] = ! empty($custom_labels['payments']['custom_pay_1']) ? $custom_labels['payments']['custom_pay_1'] : __('lang_v1.custom_payment', ['number' => 1]);
|
|
$payment_types['custom_pay_2'] = ! empty($custom_labels['payments']['custom_pay_2']) ? $custom_labels['payments']['custom_pay_2'] : __('lang_v1.custom_payment', ['number' => 2]);
|
|
$payment_types['custom_pay_3'] = ! empty($custom_labels['payments']['custom_pay_3']) ? $custom_labels['payments']['custom_pay_3'] : __('lang_v1.custom_payment', ['number' => 3]);
|
|
$payment_types['custom_pay_4'] = ! empty($custom_labels['payments']['custom_pay_4']) ? $custom_labels['payments']['custom_pay_4'] : __('lang_v1.custom_payment', ['number' => 4]);
|
|
$payment_types['custom_pay_5'] = ! empty($custom_labels['payments']['custom_pay_5']) ? $custom_labels['payments']['custom_pay_5'] : __('lang_v1.custom_payment', ['number' => 5]);
|
|
$payment_types['custom_pay_6'] = ! empty($custom_labels['payments']['custom_pay_6']) ? $custom_labels['payments']['custom_pay_6'] : __('lang_v1.custom_payment', ['number' => 6]);
|
|
$payment_types['custom_pay_7'] = ! empty($custom_labels['payments']['custom_pay_7']) ? $custom_labels['payments']['custom_pay_7'] : __('lang_v1.custom_payment', ['number' => 7]);
|
|
|
|
//Unset payment types if not enabled in business location
|
|
if (! empty($location)) {
|
|
$location_account_settings = ! empty($location->default_payment_accounts) ? json_decode($location->default_payment_accounts, true) : [];
|
|
$enabled_accounts = [];
|
|
foreach ($location_account_settings as $key => $value) {
|
|
if (! empty($value['is_enabled'])) {
|
|
$enabled_accounts[] = $key;
|
|
}
|
|
}
|
|
foreach ($payment_types as $key => $value) {
|
|
if (! in_array($key, $enabled_accounts)) {
|
|
unset($payment_types[$key]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($show_advance) {
|
|
$payment_types = ['advance' => __('lang_v1.advance')] + $payment_types;
|
|
}
|
|
|
|
return $payment_types;
|
|
}
|
|
|
|
/**
|
|
* Returns the list of modules enabled
|
|
*
|
|
* @return array
|
|
*/
|
|
public function allModulesEnabled($business_id = null)
|
|
{
|
|
$enabled_modules = session()->has('business') ? session('business')['enabled_modules'] : null;
|
|
|
|
if (! session()->has('business') && ! empty($business_id)) {
|
|
$enabled_modules = Business::find($business_id)->enabled_modules;
|
|
}
|
|
$enabled_modules = (! empty($enabled_modules) && $enabled_modules != 'null') ? $enabled_modules : [];
|
|
|
|
return $enabled_modules;
|
|
//Module::has('Restaurant');
|
|
}
|
|
|
|
/**
|
|
* Returns the list of modules enabled
|
|
*
|
|
* @return array
|
|
*/
|
|
public function isModuleEnabled($module, $business_id = null)
|
|
{
|
|
$enabled_modules = $this->allModulesEnabled($business_id);
|
|
if (in_array($module, $enabled_modules)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Converts date in business format to mysql format
|
|
*
|
|
* @param string $date
|
|
* @param bool $time (default = false)
|
|
* @return strin
|
|
*/
|
|
public function uf_date($date, $time = false)
|
|
{
|
|
if (empty($date)) {
|
|
return null;
|
|
}
|
|
|
|
// Check if Persian language is active
|
|
$is_persian = is_persian_lang();
|
|
|
|
if ($is_persian && function_exists('jalali_to_gregorian')) {
|
|
$business_format = session('business.date_format', 'Y/m/d');
|
|
$converted = jalali_to_gregorian($date, $business_format, $time);
|
|
|
|
if (empty($converted) || ! preg_match('/^\d{4}-\d{2}-\d{2}/', $converted)) {
|
|
$converted = jalali_to_gregorian($date, 'Y/m/d', $time);
|
|
}
|
|
|
|
if (! empty($converted) && preg_match('/^\d{4}-\d{2}-\d{2}/', $converted)) {
|
|
return $converted;
|
|
}
|
|
}
|
|
|
|
// Original Gregorian date handling
|
|
$date_format = session('business.date_format', 'Y/m/d');
|
|
$mysql_format = 'Y-m-d';
|
|
if ($time) {
|
|
if (session('business.time_format') == 12) {
|
|
$date_format = $date_format.' h:i A';
|
|
} else {
|
|
$date_format = $date_format.' H:i';
|
|
}
|
|
$mysql_format = 'Y-m-d H:i:s';
|
|
}
|
|
|
|
return ! empty($date_format) ? \Carbon::createFromFormat($date_format, $date)->format($mysql_format) : null;
|
|
}
|
|
|
|
/**
|
|
* Converts time in business format to mysql format
|
|
*
|
|
* @param string $time
|
|
* @return strin
|
|
*/
|
|
public function uf_time($time)
|
|
{
|
|
$time_format = 'H:i';
|
|
if (session('business.time_format') == 12) {
|
|
$time_format = 'h:i A';
|
|
}
|
|
|
|
return ! empty($time_format) ? \Carbon::createFromFormat($time_format, $time)->format('H:i') : null;
|
|
}
|
|
|
|
/**
|
|
* Converts time in business format to mysql format
|
|
*
|
|
* @param string $time
|
|
* @return string
|
|
*/
|
|
public function format_time($time)
|
|
{
|
|
if (empty($time)) {
|
|
return null;
|
|
}
|
|
|
|
$time_format = 'H:i';
|
|
if (session('business.time_format') == 12) {
|
|
$time_format = 'h:i A';
|
|
}
|
|
|
|
$formatted = \Carbon::createFromFormat('H:i:s', $time)->format($time_format);
|
|
|
|
// Convert to Persian numbers if Persian language
|
|
if (is_persian_lang()) {
|
|
return persian_number($formatted);
|
|
}
|
|
|
|
return $formatted;
|
|
}
|
|
|
|
/**
|
|
* Converts date in mysql format to business format
|
|
*
|
|
* @param string $date
|
|
* @param bool $show_time (default = false)
|
|
* @param object $business_details
|
|
* @return string
|
|
*/
|
|
public function format_date($date, $show_time = false, $business_details = null)
|
|
{
|
|
if (empty($date)) {
|
|
return null;
|
|
}
|
|
|
|
$format = ! empty($business_details) && ! empty($business_details->date_format)
|
|
? $business_details->date_format
|
|
: session('business.date_format', 'Y/m/d');
|
|
|
|
$time_format = ! empty($business_details) && isset($business_details->time_format)
|
|
? $business_details->time_format
|
|
: session('business.time_format', 24);
|
|
|
|
return format_shamsi_date($date, $format, (bool) $show_time, (int) $time_format);
|
|
}
|
|
|
|
/**
|
|
* Increments reference count for a given type and given business
|
|
* and gives the updated reference count
|
|
*
|
|
* @param string $type
|
|
* @param int $business_id
|
|
* @return int
|
|
*/
|
|
public function setAndGetReferenceCount($type, $business_id = null)
|
|
{
|
|
if (empty($business_id)) {
|
|
$business_id = request()->session()->get('user.business_id');
|
|
}
|
|
|
|
$ref = ReferenceCount::where('ref_type', $type)
|
|
->where('business_id', $business_id)
|
|
->first();
|
|
if (! empty($ref)) {
|
|
$ref->ref_count += 1;
|
|
$ref->save();
|
|
|
|
return $ref->ref_count;
|
|
} else {
|
|
$new_ref = ReferenceCount::create([
|
|
'ref_type' => $type,
|
|
'business_id' => $business_id,
|
|
'ref_count' => 1,
|
|
]);
|
|
|
|
return $new_ref->ref_count;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates reference number
|
|
*
|
|
* @param string $type
|
|
* @param int $business_id
|
|
* @return int
|
|
*/
|
|
public function generateReferenceNumber($type, $ref_count, $business_id = null, $default_prefix = null)
|
|
{
|
|
$prefix = '';
|
|
|
|
if (session()->has('business') && ! empty(request()->session()->get('business.ref_no_prefixes')[$type])) {
|
|
$prefix = request()->session()->get('business.ref_no_prefixes')[$type];
|
|
}
|
|
if (! empty($business_id)) {
|
|
$business = Business::find($business_id);
|
|
$prefixes = $business->ref_no_prefixes;
|
|
$prefix = ! empty($prefixes[$type]) ? $prefixes[$type] : '';
|
|
}
|
|
|
|
if (! empty($default_prefix)) {
|
|
$prefix = $default_prefix;
|
|
}
|
|
|
|
$ref_digits = str_pad($ref_count, 4, 0, STR_PAD_LEFT);
|
|
|
|
if (! in_array($type, ['contacts', 'business_location', 'username'])) {
|
|
$ref_year = \Carbon::now()->year;
|
|
$ref_number = $prefix.$ref_year.'/'.$ref_digits;
|
|
} else {
|
|
$ref_number = $prefix.$ref_digits;
|
|
}
|
|
|
|
return $ref_number;
|
|
}
|
|
|
|
/**
|
|
* Checks if the given user is admin
|
|
*
|
|
* @param obj $user
|
|
* @param int $business_id
|
|
* @return bool
|
|
*/
|
|
public function is_admin($user, $business_id = null)
|
|
{
|
|
$business_id = empty($business_id) ? $user->business_id : $business_id;
|
|
|
|
return $user->hasRole('Admin#'.$business_id) ? true : false;
|
|
}
|
|
|
|
/**
|
|
* Checks if the feature is allowed in demo
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function notAllowedInDemo()
|
|
{
|
|
//Disable in demo
|
|
if (config('app.env') == 'demo') {
|
|
$output = [
|
|
'success' => 0,
|
|
'msg' => __('lang_v1.disabled_in_demo'),
|
|
];
|
|
if (request()->ajax()) {
|
|
return $output;
|
|
} else {
|
|
return back()->with('status', $output);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function sendSmsViaNexmo($data)
|
|
{
|
|
$sms_settings = $data['sms_settings'];
|
|
|
|
if (empty($sms_settings['nexmo_key']) || empty($sms_settings['nexmo_secret'])) {
|
|
return false;
|
|
}
|
|
|
|
Config::set('nexmo.api_key', $sms_settings['nexmo_key']);
|
|
Config::set('nexmo.api_secret', $sms_settings['nexmo_secret']);
|
|
|
|
// $nexmo = app('Nexmo\Client');
|
|
$client = new Client();
|
|
|
|
$headers = [
|
|
'Content-Type' => 'application/json',
|
|
];
|
|
|
|
$numbers = explode(',', trim($data['mobile_number']));
|
|
|
|
foreach ($numbers as $number) {
|
|
$body = json_encode([
|
|
'api_key' => $sms_settings['nexmo_key'],
|
|
'api_secret' => $sms_settings['nexmo_secret'],
|
|
'to' => $number,
|
|
'from' => $sms_settings['nexmo_from'],
|
|
'text' => $data['sms_body'],
|
|
]);
|
|
|
|
$request = new \GuzzleHttp\Psr7\Request('POST', 'https://rest.nexmo.com/sms/json', $headers, $body);
|
|
|
|
$response = $client->sendAsync($request)->wait();
|
|
}
|
|
}
|
|
|
|
private function sendSmsViaTwilio($data)
|
|
{
|
|
$sms_settings = $data['sms_settings'];
|
|
|
|
if (empty($sms_settings['twilio_sid']) || empty($sms_settings['twilio_token'])) {
|
|
return false;
|
|
}
|
|
|
|
$twilio = new \Aloha\Twilio\Twilio($sms_settings['twilio_sid'], $sms_settings['twilio_token'], $sms_settings['twilio_from']);
|
|
|
|
$numbers = explode(',', trim($data['mobile_number']));
|
|
foreach ($numbers as $number) {
|
|
$twilio->message($number, $data['sms_body']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends SMS notification.
|
|
*
|
|
* @param array $data
|
|
* @return void
|
|
*/
|
|
public function sendSms($data)
|
|
{
|
|
$sms_settings = $data['sms_settings'];
|
|
$sms_service = isset($sms_settings['sms_service']) ? $sms_settings['sms_service'] : 'other';
|
|
$parameter_type = isset($sms_settings['data_parameter_type']) ? $sms_settings['data_parameter_type'] : 'form-data';
|
|
|
|
if ($sms_service == 'nexmo') {
|
|
return $this->sendSmsViaNexmo($data);
|
|
}
|
|
|
|
if ($sms_service == 'twilio') {
|
|
return $this->sendSmsViaTwilio($data);
|
|
}
|
|
|
|
$request_data = [
|
|
$sms_settings['send_to_param_name'] => $data['mobile_number'],
|
|
$sms_settings['msg_param_name'] => $data['sms_body'],
|
|
];
|
|
|
|
if (! empty($sms_settings['param_1'])) {
|
|
$request_data[$sms_settings['param_1']] = $sms_settings['param_val_1'];
|
|
}
|
|
if (! empty($sms_settings['param_2'])) {
|
|
$request_data[$sms_settings['param_2']] = $sms_settings['param_val_2'];
|
|
}
|
|
if (! empty($sms_settings['param_3'])) {
|
|
$request_data[$sms_settings['param_3']] = $sms_settings['param_val_3'];
|
|
}
|
|
if (! empty($sms_settings['param_4'])) {
|
|
$request_data[$sms_settings['param_4']] = $sms_settings['param_val_4'];
|
|
}
|
|
if (! empty($sms_settings['param_5'])) {
|
|
$request_data[$sms_settings['param_5']] = $sms_settings['param_val_5'];
|
|
}
|
|
if (! empty($sms_settings['param_6'])) {
|
|
$request_data[$sms_settings['param_6']] = $sms_settings['param_val_6'];
|
|
}
|
|
if (! empty($sms_settings['param_7'])) {
|
|
$request_data[$sms_settings['param_7']] = $sms_settings['param_val_7'];
|
|
}
|
|
if (! empty($sms_settings['param_8'])) {
|
|
$request_data[$sms_settings['param_8']] = $sms_settings['param_val_8'];
|
|
}
|
|
if (! empty($sms_settings['param_9'])) {
|
|
$request_data[$sms_settings['param_9']] = $sms_settings['param_val_9'];
|
|
}
|
|
if (! empty($sms_settings['param_10'])) {
|
|
$request_data[$sms_settings['param_10']] = $sms_settings['param_val_10'];
|
|
}
|
|
|
|
$client = new Client();
|
|
|
|
$headers = [];
|
|
if (! empty($sms_settings['header_1'])) {
|
|
$headers[$sms_settings['header_1']] = $sms_settings['header_val_1'];
|
|
}
|
|
if (! empty($sms_settings['header_2'])) {
|
|
$headers[$sms_settings['header_2']] = $sms_settings['header_val_2'];
|
|
}
|
|
if (! empty($sms_settings['header_3'])) {
|
|
$headers[$sms_settings['header_3']] = $sms_settings['header_val_3'];
|
|
}
|
|
|
|
$options = [];
|
|
if (! empty($headers)) {
|
|
$options['headers'] = $headers;
|
|
}
|
|
|
|
if (empty($sms_settings['url'])) {
|
|
return false;
|
|
}
|
|
|
|
if ($sms_settings['request_method'] == 'get') {
|
|
$response = $client->get($sms_settings['url'].'?'.http_build_query($request_data), $options);
|
|
} else {
|
|
// Check if the parameter type is set to 'json' and process accordingly
|
|
if($parameter_type == 'json'){
|
|
|
|
$request_data[$sms_settings['send_to_param_name']] = $data['mobile_number'];
|
|
|
|
// Split the mobile number into an array
|
|
if ($sms_settings['send_to_param_type'] == 'array') {
|
|
$request_data[$sms_settings['send_to_param_name']] = explode(',', $data['mobile_number']);
|
|
}
|
|
// Set the request data as JSON in the options
|
|
$options['json'] = $request_data;
|
|
// Make the POST request with the JSON data
|
|
return $client->post($sms_settings['url'], $options);
|
|
}
|
|
$options['form_params'] = $request_data;
|
|
|
|
$response = $client->post($sms_settings['url'], $options);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Generates Whatsapp notification link
|
|
*
|
|
* @param array $data
|
|
* @return string
|
|
*/
|
|
public function getWhatsappNotificationLink($data)
|
|
{
|
|
//Supports only integers without leading zeros
|
|
$whatsapp_number = abs((int) filter_var($data['mobile_number'], FILTER_SANITIZE_NUMBER_INT));
|
|
$text = $data['whatsapp_text'];
|
|
|
|
$base_url = config('constants.whatsapp_base_url').'/'.$whatsapp_number;
|
|
|
|
return $base_url.'?text='.urlencode($text);
|
|
}
|
|
|
|
/**
|
|
* Retrieves sub units of a base unit
|
|
*
|
|
* @param int $business_id
|
|
* @param int $unit_id
|
|
* @param bool $return_main_unit_if_empty = false
|
|
* @param int $product_id = null
|
|
* @return array
|
|
*/
|
|
public function getSubUnits($business_id, $unit_id, $return_main_unit_if_empty = false, $product_id = null)
|
|
{
|
|
$unit = Unit::where('business_id', $business_id)
|
|
->with(['sub_units'])
|
|
->findOrFail($unit_id);
|
|
|
|
//Find related subunits for the product.
|
|
$related_sub_units = [];
|
|
if (! empty($product_id)) {
|
|
$product = Product::where('business_id', $business_id)->findOrFail($product_id);
|
|
$related_sub_units = $product->sub_unit_ids;
|
|
}
|
|
|
|
$sub_units = [];
|
|
|
|
//Add main unit as per given parameter or conditions.
|
|
if (($return_main_unit_if_empty && count($unit->sub_units) == 0)) {
|
|
$sub_units[$unit->id] = [
|
|
'name' => $unit->actual_name,
|
|
'multiplier' => 1,
|
|
'allow_decimal' => $unit->allow_decimal,
|
|
];
|
|
} elseif (empty($related_sub_units) || in_array($unit->id, $related_sub_units)) {
|
|
$sub_units[$unit->id] = [
|
|
'name' => $unit->actual_name,
|
|
'multiplier' => 1,
|
|
'allow_decimal' => $unit->allow_decimal,
|
|
];
|
|
}
|
|
|
|
if (count($unit->sub_units) > 0) {
|
|
foreach ($unit->sub_units as $sub_unit) {
|
|
//Check if subunit is related to the product or not.
|
|
if (empty($related_sub_units) || in_array($sub_unit->id, $related_sub_units)) {
|
|
$sub_units[$sub_unit->id] = [
|
|
'name' => $sub_unit->actual_name,
|
|
'multiplier' => $sub_unit->base_unit_multiplier,
|
|
'allow_decimal' => $sub_unit->allow_decimal,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $sub_units;
|
|
}
|
|
|
|
public function getMultiplierOf2Units($base_unit_id, $unit_id)
|
|
{
|
|
if ($base_unit_id == $unit_id || is_null($base_unit_id) || is_null($unit_id)) {
|
|
return 1;
|
|
}
|
|
|
|
$unit = Unit::where('base_unit_id', $base_unit_id)
|
|
->where('id', $unit_id)
|
|
->first();
|
|
if (empty($unit)) {
|
|
return 1;
|
|
} else {
|
|
return $unit->base_unit_multiplier;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates unique token
|
|
*
|
|
* @param void
|
|
* @return string
|
|
*/
|
|
public function generateToken()
|
|
{
|
|
return md5(rand(1, 10).microtime());
|
|
}
|
|
|
|
/**
|
|
* Generates invoice url for the transaction
|
|
*
|
|
* @param int $transaction_id, int $business_id
|
|
* @return string
|
|
*/
|
|
public function getInvoiceUrl($transaction_id, $business_id)
|
|
{
|
|
$transaction = Transaction::where('business_id', $business_id)
|
|
->findOrFail($transaction_id);
|
|
|
|
if (empty($transaction->invoice_token)) {
|
|
$transaction->invoice_token = $this->generateToken();
|
|
$transaction->save();
|
|
}
|
|
|
|
if ($transaction->is_quotation == 1) {
|
|
return route('show_quote', ['token' => $transaction->invoice_token]);
|
|
}
|
|
|
|
return route('show_invoice', ['token' => $transaction->invoice_token]);
|
|
}
|
|
|
|
/**
|
|
* Generates payment link for the transaction
|
|
*
|
|
* @param int $transaction_id, int $business_id
|
|
* @return string
|
|
*/
|
|
public function getInvoicePaymentLink($transaction_id, $business_id)
|
|
{
|
|
$transaction = Transaction::where('business_id', $business_id)
|
|
->findOrFail($transaction_id);
|
|
|
|
if (empty($transaction->invoice_token)) {
|
|
$transaction->invoice_token = $this->generateToken();
|
|
$transaction->save();
|
|
}
|
|
|
|
if ($transaction->payment_status != 'paid' && $transaction->status == 'final') {
|
|
return route('invoice_payment', ['token' => $transaction->invoice_token]);
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Uploads document to the server if present in the request
|
|
*
|
|
* @param obj $request, string $file_name, string dir_name
|
|
* @return string
|
|
*/
|
|
public function uploadFile($request, $file_name, $dir_name, $file_type = 'document')
|
|
{
|
|
//If app environment is demo return null
|
|
if (config('app.env') == 'demo') {
|
|
return null;
|
|
}
|
|
|
|
$uploaded_file_name = null;
|
|
if ($request->hasFile($file_name) && $request->file($file_name)->isValid()) {
|
|
|
|
$file = $request->file($file_name);
|
|
|
|
// Laravel inbuilt server-side file type validation
|
|
if ($file_type == 'image') {
|
|
if (!$file->isValid() || !Str::startsWith($file->getMimeType(), 'image/')) {
|
|
throw new \Exception('Invalid image file');
|
|
}
|
|
}
|
|
|
|
if ($file_type == 'document') {
|
|
$allowed_mimes = array_keys(config('constants.document_upload_mimes_types'));
|
|
if (!in_array($file->getMimeType(), $allowed_mimes)) {
|
|
throw new \Exception('Invalid document file');
|
|
}
|
|
}
|
|
|
|
if ($file->getSize() <= config('constants.document_size_limit')) {
|
|
// Sanitize file name: slugify original name (without extension), prepend time, append extension
|
|
$original_name = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
|
|
$extension = $file->getClientOriginalExtension();
|
|
$sanitized_name = Str::slug($original_name);
|
|
$new_file_name = time() . '_' . $sanitized_name . ($extension ? '.' . $extension : '');
|
|
|
|
if ($file->storeAs($dir_name, $new_file_name)) {
|
|
$uploaded_file_name = $new_file_name;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $uploaded_file_name;
|
|
}
|
|
|
|
public function serviceStaffDropdown($business_id, $location_id = null)
|
|
{
|
|
return $this->getServiceStaff($business_id, $location_id, true);
|
|
}
|
|
|
|
public function getServiceStaff($business_id, $location_id = null, $for_dropdown = false)
|
|
{
|
|
$waiters = [];
|
|
//Get all service staff roles
|
|
$service_staff_roles = Role::where('business_id', $business_id)
|
|
->where('is_service_staff', 1)
|
|
->pluck('name')
|
|
->toArray();
|
|
|
|
//Get all users of service staff roles
|
|
if (! empty($service_staff_roles)) {
|
|
$waiters = User::where('business_id', $business_id)
|
|
->role($service_staff_roles);
|
|
|
|
if (! empty($location_id)) {
|
|
$waiters->permission(['location.'.$location_id, 'access_all_locations']);
|
|
}
|
|
|
|
if ($for_dropdown) {
|
|
$waiters = $waiters->select('id', DB::raw('CONCAT(COALESCE(first_name, ""), " ", COALESCE(last_name, "")) as full_name'))->get()->pluck('full_name', 'id');
|
|
} else {
|
|
$waiters = $waiters->get();
|
|
}
|
|
}
|
|
|
|
return $waiters;
|
|
}
|
|
|
|
/**
|
|
* Replaces tags from notification body with original value
|
|
*
|
|
* @param text $body
|
|
* @param int $transaction_id
|
|
* @return array
|
|
*/
|
|
public function replaceTags($business_id, $data, $transaction, $contact = null)
|
|
{
|
|
if (! empty($transaction) && ! is_object($transaction)) {
|
|
$transaction = Transaction::where('business_id', $business_id)
|
|
->with(['contact', 'payment_lines'])
|
|
->findOrFail($transaction);
|
|
}
|
|
|
|
$business = ! is_object($business_id) ? Business::with(['currency'])->findOrFail($business_id) : $business_id;
|
|
|
|
$contact = empty($transaction->contact) ? $contact : $transaction->contact;
|
|
|
|
foreach ($data as $key => $value) {
|
|
//Replace contact name
|
|
if (strpos($value, '{contact_name}') !== false) {
|
|
$contact_name = empty($contact) ? $transaction->contact->name : $contact->name;
|
|
|
|
$data[$key] = str_replace('{contact_name}', $contact_name, $data[$key]);
|
|
}
|
|
|
|
//Replace invoice number
|
|
if (strpos($value, '{invoice_number}') !== false) {
|
|
$invoice_number = $transaction->type == 'sell' ? $transaction->invoice_no : '';
|
|
|
|
$data[$key] = str_replace('{invoice_number}', $invoice_number, $data[$key]);
|
|
}
|
|
|
|
//Replace ref number
|
|
if (strpos($value, '{order_ref_number}') !== false) {
|
|
$order_ref_number = $transaction->ref_no;
|
|
|
|
$data[$key] = str_replace('{order_ref_number}', $order_ref_number, $data[$key]);
|
|
}
|
|
//Replace total_amount
|
|
if (strpos($value, '{total_amount}') !== false) {
|
|
$total_amount = $this->num_f($transaction->final_total, true, $business->currency);
|
|
|
|
$data[$key] = str_replace('{total_amount}', $total_amount, $data[$key]);
|
|
}
|
|
|
|
$total_paid = 0;
|
|
$payment_ref_number = [];
|
|
if (! empty($transaction)) {
|
|
foreach ($transaction->payment_lines as $payment) {
|
|
if ($payment->is_return != 1) {
|
|
$total_paid += $payment->amount;
|
|
$payment_ref_number[] = $payment->payment_ref_no;
|
|
}
|
|
}
|
|
}
|
|
|
|
$paid_amount = $this->num_f($total_paid, true, $business->currency);
|
|
|
|
//Replace paid_amount
|
|
if (strpos($value, '{paid_amount}') !== false) {
|
|
$data[$key] = str_replace('{paid_amount}', $paid_amount, $data[$key]);
|
|
}
|
|
|
|
//Replace received_amount
|
|
if (strpos($value, '{received_amount}') !== false) {
|
|
$data[$key] = str_replace('{received_amount}', $paid_amount, $data[$key]);
|
|
}
|
|
|
|
//Replace payment_ref_number
|
|
if (strpos($value, '{payment_ref_number}') !== false) {
|
|
$data[$key] = str_replace('{payment_ref_number}', implode(', ', $payment_ref_number), $data[$key]);
|
|
}
|
|
|
|
//Replace due_amount
|
|
if (strpos($value, '{due_amount}') !== false) {
|
|
$due = $transaction->final_total - $total_paid;
|
|
$due_amount = $this->num_f($due, true, $business->currency);
|
|
|
|
$data[$key] = str_replace('{due_amount}', $due_amount, $data[$key]);
|
|
}
|
|
|
|
//Replace business_name
|
|
if (strpos($value, '{business_name}') !== false) {
|
|
$business_name = $business->name;
|
|
$data[$key] = str_replace('{business_name}', $business_name, $data[$key]);
|
|
}
|
|
|
|
//Replace business_logo
|
|
if (strpos($value, '{business_logo}') !== false) {
|
|
$logo_name = $business->logo;
|
|
$business_logo = ! empty($logo_name) ? '<img src="'.url('uploads/business_logos/'.$logo_name).'" alt="Business Logo" >' : '';
|
|
|
|
$data[$key] = str_replace('{business_logo}', $business_logo, $data[$key]);
|
|
}
|
|
|
|
//Replace invoice_url
|
|
if (! empty($transaction) && strpos($value, '{invoice_url}') !== false && $transaction->type == 'sell') {
|
|
$invoice_url = $this->getInvoiceUrl($transaction->id, $transaction->business_id);
|
|
$data[$key] = str_replace('{invoice_url}', $invoice_url, $data[$key]);
|
|
}
|
|
|
|
if (! empty($transaction) && strpos($value, '{quote_url}') !== false && $transaction->type == 'sell') {
|
|
$invoice_url = $this->getInvoiceUrl($transaction->id, $transaction->business_id);
|
|
$data[$key] = str_replace('{quote_url}', $invoice_url, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{cumulative_due_amount}') !== false) {
|
|
$due = $this->getContactDue($transaction->contact_id);
|
|
$data[$key] = str_replace('{cumulative_due_amount}', $due, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{due_date}') !== false) {
|
|
$due_date = $transaction->due_date;
|
|
if (! empty($due_date)) {
|
|
$due_date = $this->format_date($due_date->toDateTimeString(), true);
|
|
}
|
|
$data[$key] = str_replace('{due_date}', $due_date, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{contact_business_name}') !== false) {
|
|
$contact_business_name = ! empty($transaction->contact->supplier_business_name) ? $transaction->contact->supplier_business_name : '';
|
|
$data[$key] = str_replace('{contact_business_name}', $contact_business_name, $data[$key]);
|
|
}
|
|
if (! empty($transaction->location)) {
|
|
if (strpos($value, '{location_name}') !== false) {
|
|
$location = $transaction->location->name;
|
|
|
|
$data[$key] = str_replace('{location_name}', $location, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{location_address}') !== false) {
|
|
$location_address = $transaction->location->location_address;
|
|
|
|
$data[$key] = str_replace('{location_address}', $location_address, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{location_email}') !== false) {
|
|
$location_email = $transaction->location->email;
|
|
|
|
$data[$key] = str_replace('{location_email}', $location_email, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{location_phone}') !== false) {
|
|
$location_phone = $transaction->location->mobile;
|
|
|
|
$data[$key] = str_replace('{location_phone}', $location_phone, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{location_custom_field_1}') !== false) {
|
|
$location_custom_field_1 = $contact->custom_field1;
|
|
|
|
$data[$key] = str_replace('{location_custom_field_1}', $location_custom_field_1, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{location_custom_field_2}') !== false) {
|
|
$location_custom_field_2 = $transaction->location->custom_field2;
|
|
|
|
$data[$key] = str_replace('{location_custom_field_2}', $location_custom_field_2, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{location_custom_field_3}') !== false) {
|
|
$location_custom_field_3 = $transaction->location->custom_field3;
|
|
|
|
$data[$key] = str_replace('{location_custom_field_3}', $location_custom_field_3, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{location_custom_field_4}') !== false) {
|
|
$location_custom_field_4 = $transaction->location->custom_field4;
|
|
|
|
$data[$key] = str_replace('{location_custom_field_4}', $location_custom_field_4, $data[$key]);
|
|
}
|
|
}
|
|
|
|
if (strpos($value, '{contact_custom_field_1}') !== false) {
|
|
$contact_custom_field_1 = $contact->custom_field1 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_1}', $contact_custom_field_1, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{contact_custom_field_2}') !== false) {
|
|
$contact_custom_field_2 = $contact->custom_field2 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_2}', $contact_custom_field_2, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{contact_custom_field_3}') !== false) {
|
|
$contact_custom_field_3 = $contact->custom_field3 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_3}', $contact_custom_field_3, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{contact_custom_field_4}') !== false) {
|
|
$contact_custom_field_4 = $contact->custom_field4 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_4}', $contact_custom_field_4, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{contact_custom_field_5}') !== false) {
|
|
$contact_custom_field_5 = $contact->custom_field5 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_5}', $contact_custom_field_5, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{contact_custom_field_6}') !== false) {
|
|
$contact_custom_field_6 = $contact->custom_field6 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_6}', $contact_custom_field_6, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{contact_custom_field_7}') !== false) {
|
|
$contact_custom_field_7 = $contact->custom_field7 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_7}', $contact_custom_field_7, $data[$key]);
|
|
}
|
|
if (strpos($value, '{contact_custom_field_8}') !== false) {
|
|
$contact_custom_field_8 = $contact->custom_field8 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_8}', $contact_custom_field_8, $data[$key]);
|
|
}
|
|
if (strpos($value, '{contact_custom_field_9}') !== false) {
|
|
$contact_custom_field_9 = $contact->custom_field9 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_9}', $contact_custom_field_9, $data[$key]);
|
|
}
|
|
if (strpos($value, '{contact_custom_field_10}') !== false) {
|
|
$contact_custom_field_10 = $contact->custom_field10 ?? '';
|
|
$data[$key] = str_replace('{contact_custom_field_10}', $contact_custom_field_10, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{sell_custom_field_1}') !== false) {
|
|
$sell_custom_field_1 = $transaction->custom_field_1 ?? '';
|
|
$data[$key] = str_replace('{sell_custom_field_1}', $sell_custom_field_1, $data[$key]);
|
|
}
|
|
if (strpos($value, '{sell_custom_field_2}') !== false) {
|
|
$sell_custom_field_2 = $transaction->custom_field_2 ?? '';
|
|
$data[$key] = str_replace('{sell_custom_field_2}', $sell_custom_field_2, $data[$key]);
|
|
}
|
|
if (strpos($value, '{sell_custom_field_3}') !== false) {
|
|
$sell_custom_field_3 = $transaction->custom_field_3 ?? '';
|
|
$data[$key] = str_replace('{sell_custom_field_3}', $sell_custom_field_3, $data[$key]);
|
|
}
|
|
if (strpos($value, '{sell_custom_field_4}') !== false) {
|
|
$sell_custom_field_4 = $transaction->custom_field_4 ?? '';
|
|
$data[$key] = str_replace('{sell_custom_field_4}', $sell_custom_field_4, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{purchase_custom_field_1}') !== false) {
|
|
$purchase_custom_field_1 = $transaction->custom_field_1 ?? '';
|
|
$data[$key] = str_replace('{purchase_custom_field_1}', $purchase_custom_field_1, $data[$key]);
|
|
}
|
|
if (strpos($value, '{purchase_custom_field_2}') !== false) {
|
|
$purchase_custom_field_2 = $transaction->custom_field_2 ?? '';
|
|
$data[$key] = str_replace('{purchase_custom_field_2}', $purchase_custom_field_2, $data[$key]);
|
|
}
|
|
if (strpos($value, '{purchase_custom_field_3}') !== false) {
|
|
$purchase_custom_field_3 = $transaction->custom_field_3 ?? '';
|
|
$data[$key] = str_replace('{purchase_custom_field_3}', $purchase_custom_field_3, $data[$key]);
|
|
}
|
|
if (strpos($value, '{purchase_custom_field_4}') !== false) {
|
|
$purchase_custom_field_4 = $transaction->custom_field_4 ?? '';
|
|
$data[$key] = str_replace('{purchase_custom_field_4}', $purchase_custom_field_4, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{shipping_custom_field_1}') !== false) {
|
|
$shipping_custom_field_1 = $transaction->shipping_custom_field_1 ?? '';
|
|
$data[$key] = str_replace('{shipping_custom_field_1}', $shipping_custom_field_1, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{shipping_custom_field_2}') !== false) {
|
|
$shipping_custom_field_2 = $transaction->shipping_custom_field_2 ?? '';
|
|
$data[$key] = str_replace('{shipping_custom_field_2}', $shipping_custom_field_2, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{shipping_custom_field_3}') !== false) {
|
|
$shipping_custom_field_3 = $transaction->shipping_custom_field_3 ?? '';
|
|
$data[$key] = str_replace('{shipping_custom_field_3}', $shipping_custom_field_3, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{shipping_custom_field_4}') !== false) {
|
|
$shipping_custom_field_4 = $transaction->shipping_custom_field_4 ?? '';
|
|
$data[$key] = str_replace('{shipping_custom_field_4}', $shipping_custom_field_4, $data[$key]);
|
|
}
|
|
|
|
if (strpos($value, '{shipping_custom_field_5}') !== false) {
|
|
$shipping_custom_field_5 = $transaction->shipping_custom_field_5 ?? '';
|
|
$data[$key] = str_replace('{shipping_custom_field_5}', $shipping_custom_field_5, $data[$key]);
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function getCronJobCommand()
|
|
{
|
|
if (function_exists('exec')) {
|
|
$php_binary_path = exec('which php');
|
|
} else {
|
|
$php_binary_path = PHP_BINARY;
|
|
}
|
|
|
|
if (empty($php_binary_path)) {
|
|
// Use a default fallback or handle the case where 'which php' doesn't return a valid path
|
|
$php_binary_path = 'php';
|
|
}
|
|
|
|
$command = '* * * * * '.$php_binary_path.' '.base_path('artisan').' schedule:run >> /dev/null 2>&1';
|
|
|
|
if (config('app.env') == 'demo') {
|
|
$command = '';
|
|
}
|
|
|
|
return $command;
|
|
}
|
|
|
|
/**
|
|
* Checks whether mail is configured or not
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function IsMailConfigured()
|
|
{
|
|
$is_mail_configured = false;
|
|
|
|
if (
|
|
! empty(env('MAIL_MAILER')) &&
|
|
! empty(env('MAIL_HOST')) &&
|
|
! empty(env('MAIL_PORT')) &&
|
|
! empty(env('MAIL_USERNAME')) &&
|
|
! empty(env('MAIL_PASSWORD')) &&
|
|
! empty(env('MAIL_FROM_ADDRESS'))
|
|
) {
|
|
$is_mail_configured = true;
|
|
}
|
|
|
|
return $is_mail_configured;
|
|
}
|
|
|
|
/**
|
|
* Returns the list of barcode types
|
|
*
|
|
* @return array
|
|
*/
|
|
public function barcode_types()
|
|
{
|
|
$types = ['C128' => 'Code 128 (C128)', 'C39' => 'Code 39 (C39)', 'EAN13' => 'EAN-13', 'EAN8' => 'EAN-8', 'UPCA' => 'UPC-A', 'UPCE' => 'UPC-E'];
|
|
|
|
return $types;
|
|
}
|
|
|
|
/**
|
|
* Returns the default barcode.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function barcode_default()
|
|
{
|
|
return 'C128';
|
|
}
|
|
|
|
/**
|
|
* Retrieves user role name.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getUserRoleName($user_id)
|
|
{
|
|
$user = User::findOrFail($user_id);
|
|
|
|
$roles = $user->getRoleNames();
|
|
|
|
$role_name = '';
|
|
|
|
if (! empty($roles[0])) {
|
|
$array = explode('#', $roles[0], 2);
|
|
$role_name = ! empty($array[0]) ? $array[0] : '';
|
|
}
|
|
|
|
return $role_name;
|
|
}
|
|
|
|
/**
|
|
* Retrieves all admins of a business
|
|
*
|
|
* @param int $business_id
|
|
* @return obj
|
|
*/
|
|
public function get_admins($business_id)
|
|
{
|
|
$admins = User::role('Admin#'.$business_id)->get();
|
|
|
|
return $admins;
|
|
}
|
|
|
|
/**
|
|
* Retrieves IP address of the user
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getUserIpAddr()
|
|
{
|
|
if (! empty($_SERVER['HTTP_CLIENT_IP'])) {
|
|
//ip from share internet
|
|
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
|
} elseif (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
|
//ip pass from proxy
|
|
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
|
} else {
|
|
$ip = $_SERVER['REMOTE_ADDR'];
|
|
}
|
|
|
|
return $ip;
|
|
}
|
|
|
|
/**
|
|
* This function updates the stock of products present in combo product and also updates transaction sell line.
|
|
*
|
|
* @param array $lines
|
|
* @param int $location_id
|
|
* @param bool $adjust_stock = true
|
|
* @return void
|
|
*/
|
|
public function updateEditedSellLineCombo($lines, $location_id, $adjust_stock = true)
|
|
{
|
|
if (empty($lines)) {
|
|
return true;
|
|
}
|
|
|
|
$change_percent = null;
|
|
|
|
foreach ($lines as $key => $line) {
|
|
$prev_line = TransactionSellLine::find($line['transaction_sell_lines_id']);
|
|
|
|
$difference = $prev_line->quantity - $line['quantity'];
|
|
if ($difference != 0) {
|
|
//Update stock in variation location details table.
|
|
//Adjust Quantity in variations location table
|
|
if ($adjust_stock) {
|
|
VariationLocationDetails::where('variation_id', $line['variation_id'])
|
|
->where('product_id', $line['product_id'])
|
|
->where('location_id', $location_id)
|
|
->increment('qty_available', $difference);
|
|
}
|
|
|
|
//Update the child line quantity
|
|
$prev_line->quantity = $line['quantity'];
|
|
$prev_line->save();
|
|
}
|
|
|
|
//Recalculate the price.
|
|
if (is_null($change_percent)) {
|
|
$parent = TransactionSellLine::findOrFail($prev_line->parent_sell_line_id);
|
|
$child_sum = TransactionSellLine::where('parent_sell_line_id', $prev_line->parent_sell_line_id)
|
|
->select(DB::raw('SUM(unit_price_inc_tax * quantity) as total_price'))
|
|
->first()
|
|
->total_price;
|
|
|
|
$change_percent = $this->get_percent($child_sum, $parent->unit_price_inc_tax * $parent->quantity);
|
|
}
|
|
|
|
$price = $this->calc_percentage($prev_line->unit_price_inc_tax, $change_percent, $prev_line->unit_price_inc_tax);
|
|
$prev_line->unit_price_before_discount = $price;
|
|
$prev_line->unit_price = $price;
|
|
$prev_line->unit_price_inc_tax = $price;
|
|
|
|
$prev_line->save();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates string to calculate sum of purchase line quantity used
|
|
*/
|
|
public function get_pl_quantity_sum_string($table_name = '')
|
|
{
|
|
$table_name = ! empty($table_name) ? $table_name.'.' : '';
|
|
$string = $table_name.'quantity_sold + '.$table_name.'quantity_adjusted + '.$table_name.'quantity_returned + '.$table_name.'mfg_quantity_used';
|
|
|
|
return $string;
|
|
}
|
|
|
|
public function shipping_statuses()
|
|
{
|
|
$statuses = [
|
|
'ordered' => __('lang_v1.ordered'),
|
|
'packed' => __('lang_v1.packed'),
|
|
'shipped' => __('lang_v1.shipped'),
|
|
'delivered' => __('lang_v1.delivered'),
|
|
'cancelled' => __('restaurant.cancelled'),
|
|
];
|
|
|
|
return $statuses;
|
|
}
|
|
|
|
/**
|
|
* Retrieves sum of due amount of a contact
|
|
*
|
|
* @param int $contact_id
|
|
* @return mixed
|
|
*/
|
|
public function getContactDue($contact_id, $business_id = null)
|
|
{
|
|
// aad type sell_return for to calculate total_sell_return
|
|
$query = Contact::where('contacts.id', $contact_id)
|
|
->join('transactions AS t', 'contacts.id', '=', 't.contact_id')
|
|
->whereIn('t.type', ['sell', 'opening_balance', 'purchase', 'sell_return'])
|
|
->select(
|
|
DB::raw("SUM(IF(t.status = 'final' AND t.type = 'sell', final_total, 0)) as total_invoice"),
|
|
DB::raw("SUM(IF(t.type = 'purchase', final_total, 0)) as total_purchase"),
|
|
DB::raw("SUM(IF(t.status = 'final' AND t.type = 'sell', (SELECT SUM(IF(is_return = 1,-1*amount,amount)) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as total_paid"),
|
|
DB::raw("SUM(IF(t.type = 'purchase', (SELECT SUM(amount) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as purchase_paid"),
|
|
DB::raw("SUM(IF(t.type = 'sell_return', (SELECT SUM(amount) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as sell_return_paid"),
|
|
DB::raw("SUM(IF(t.type = 'opening_balance', final_total, 0)) as opening_balance"),
|
|
DB::raw("SUM(IF(t.type = 'sell_return', final_total, 0)) as total_sell_return"),
|
|
DB::raw("SUM(IF(t.type = 'opening_balance', (SELECT SUM(amount) FROM transaction_payments WHERE transaction_payments.transaction_id=t.id), 0)) as opening_balance_paid")
|
|
);
|
|
if (! empty($business_id)) {
|
|
$query->where('contacts.business_id', $business_id);
|
|
}
|
|
|
|
$contact_payments = $query->first();
|
|
|
|
// + $contact_payments->sell_return_paid add this in due because after paymnet for sell return not calculated
|
|
|
|
$due = $contact_payments->total_invoice + $contact_payments->total_purchase - $contact_payments->total_paid - $contact_payments->purchase_paid + $contact_payments->opening_balance - $contact_payments->opening_balance_paid - $contact_payments->total_sell_return + $contact_payments->sell_return_paid;
|
|
|
|
return $due;
|
|
}
|
|
|
|
public function getDays()
|
|
{
|
|
return [
|
|
'sunday' => __('lang_v1.sunday'),
|
|
'monday' => __('lang_v1.monday'),
|
|
'tuesday' => __('lang_v1.tuesday'),
|
|
'wednesday' => __('lang_v1.wednesday'),
|
|
'thursday' => __('lang_v1.thursday'),
|
|
'friday' => __('lang_v1.friday'),
|
|
'saturday' => __('lang_v1.saturday'),
|
|
];
|
|
}
|
|
|
|
public function parseNotifications($notifications)
|
|
{
|
|
$notifications_data = [];
|
|
foreach ($notifications as $notification) {
|
|
$data = $notification->data;
|
|
if (in_array($notification->type, [\App\Notifications\RecurringInvoiceNotification::class, \App\Notifications\RecurringExpenseNotification::class])) {
|
|
$msg = '';
|
|
$icon_class = '';
|
|
$link = '';
|
|
if (
|
|
$notification->type ==
|
|
\App\Notifications\RecurringInvoiceNotification::class
|
|
) {
|
|
$msg = ! empty($data['invoice_status']) && $data['invoice_status'] == 'draft' ?
|
|
__(
|
|
'lang_v1.recurring_invoice_error_message',
|
|
['product_name' => $data['out_of_stock_product'], 'subscription_no' => ! empty($data['subscription_no']) ? $data['subscription_no'] : '']
|
|
) :
|
|
__(
|
|
'lang_v1.recurring_invoice_message',
|
|
['invoice_no' => ! empty($data['invoice_no']) ? $data['invoice_no'] : '', 'subscription_no' => ! empty($data['subscription_no']) ? $data['subscription_no'] : '']
|
|
);
|
|
$icon_class = ! empty($data['invoice_status']) && $data['invoice_status'] == 'draft' ? 'fas fa-exclamation-triangle bg-yellow' : 'fas fa-recycle bg-green';
|
|
$link = action([\App\Http\Controllers\SellPosController::class, 'listSubscriptions']);
|
|
} elseif (
|
|
$notification->type ==
|
|
\App\Notifications\RecurringExpenseNotification::class
|
|
) {
|
|
$msg = __(
|
|
'lang_v1.recurring_expense_message',
|
|
['ref_no' => $data['ref_no']]
|
|
);
|
|
$icon_class = 'fas fa-recycle bg-green';
|
|
$link = action([\App\Http\Controllers\ExpenseController::class, 'index']);
|
|
}
|
|
|
|
$notifications_data[] = [
|
|
'msg' => $msg,
|
|
'icon_class' => $icon_class,
|
|
'link' => $link,
|
|
'read_at' => $notification->read_at,
|
|
'created_at' => $notification->created_at->diffForHumans(),
|
|
];
|
|
} else {
|
|
$moduleUtil = new \App\Utils\ModuleUtil;
|
|
$module_notification_data = $moduleUtil->getModuleData('parse_notification', $notification);
|
|
if (! empty($module_notification_data)) {
|
|
foreach ($module_notification_data as $module_data) {
|
|
if (! empty($module_data)) {
|
|
$notifications_data[] = $module_data;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $notifications_data;
|
|
}
|
|
|
|
/**
|
|
* Formats number to words
|
|
* Requires php-intl extension
|
|
*
|
|
* @return string
|
|
*/
|
|
public function numToWord($number, $lang = null, $format = 'international')
|
|
{
|
|
if ($format == 'indian') {
|
|
return $this->numToIndianFormat($number);
|
|
}
|
|
|
|
if (! extension_loaded('intl')) {
|
|
return '';
|
|
}
|
|
|
|
if (empty($lang)) {
|
|
$lang = ! empty(auth()->user()) ? auth()->user()->language : 'en';
|
|
}
|
|
|
|
$f = new \NumberFormatter($lang, \NumberFormatter::SPELLOUT);
|
|
|
|
return $f->format($number);
|
|
}
|
|
|
|
/**
|
|
* Formats number to words in indian format
|
|
*
|
|
* @return string
|
|
*/
|
|
public function numToIndianFormat(float $number)
|
|
{
|
|
$decimal = round($number - ($no = floor($number)), 2) * 100;
|
|
$hundred = null;
|
|
$digits_length = strlen($no);
|
|
$i = 0;
|
|
$str = [];
|
|
$words = [
|
|
0 => '', 1 => 'one', 2 => 'two',
|
|
3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six',
|
|
7 => 'seven', 8 => 'eight', 9 => 'nine',
|
|
10 => 'ten', 11 => 'eleven', 12 => 'twelve',
|
|
13 => 'thirteen', 14 => 'fourteen', 15 => 'fifteen',
|
|
16 => 'sixteen', 17 => 'seventeen', 18 => 'eighteen',
|
|
19 => 'nineteen', 20 => 'twenty', 30 => 'thirty',
|
|
40 => 'forty', 50 => 'fifty', 60 => 'sixty',
|
|
70 => 'seventy', 80 => 'eighty', 90 => 'ninety',
|
|
];
|
|
$digits = ['', 'hundred', 'thousand', 'lakh', 'crore'];
|
|
while ($i < $digits_length) {
|
|
$divider = ($i == 2) ? 10 : 100;
|
|
$number = floor($no % $divider);
|
|
$no = floor($no / $divider);
|
|
$i += $divider == 10 ? 1 : 2;
|
|
if ($number) {
|
|
$plural = (($counter = count($str)) && $number > 9) ? 's' : null;
|
|
$hundred = ($counter == 1 && $str[0]) ? ' and ' : null;
|
|
$str[] = ($number < 21) ? $words[$number].' '.$digits[$counter].$plural.' '.$hundred : $words[floor($number / 10) * 10].' '.$words[$number % 10].' '.$digits[$counter].$plural.' '.$hundred;
|
|
} else {
|
|
$str[] = null;
|
|
}
|
|
}
|
|
$whole_number_part = implode('', array_reverse($str));
|
|
$decimal_part = ($decimal > 0) ? ' point '.($words[$decimal / 10].' '.$words[$decimal % 10]) : '';
|
|
|
|
return ($whole_number_part ? $whole_number_part : '').$decimal_part;
|
|
}
|
|
|
|
public function getCustomLabels($business, $type = null)
|
|
{
|
|
$business = is_object($business) ? $business : Business::find($business);
|
|
//Get custom label from business settings
|
|
$custom_labels = $business->custom_labels;
|
|
$custom_labels = json_decode($custom_labels, true);
|
|
|
|
if (! empty($type) && isset($custom_labels[$type])) {
|
|
return $custom_labels[$type];
|
|
}
|
|
|
|
return $custom_labels;
|
|
}
|
|
|
|
/**
|
|
* Logs activities to database
|
|
*
|
|
* @param $on object Model instance
|
|
* @param $action string name of the operation performed on the model instance
|
|
* @param $before object Previous state of the model instance
|
|
* @param $properties array Extra properties to be saved along with model properties
|
|
* update_note key to directly show message in note section,
|
|
* from_api key to show api client if added from api
|
|
* @param $log_changes boolean whether to log changes to modal properties
|
|
* @return string
|
|
*/
|
|
public function activityLog($on, $action = null, $before = null, $properties = [], $log_changes = true, $business_id = null)
|
|
{
|
|
if ($log_changes) {
|
|
$log_properties = $on->log_properties ?? [];
|
|
foreach ($log_properties as $property) {
|
|
if (isset($on->$property)) {
|
|
$properties['attributes'][$property] = $on->$property;
|
|
}
|
|
|
|
if (! empty($before) && isset($before->$property)) {
|
|
$properties['old'][$property] = $before->$property;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Check if session has business id
|
|
$business_id = session()->has('business') ? session('business.id') : $business_id;
|
|
|
|
//Check if subject has business id
|
|
if (empty($business_id) && ! empty($on->business_id)) {
|
|
$business_id = $on->business_id;
|
|
}
|
|
|
|
$business = session()->has('business') ? session('business') : Business::find($business_id);
|
|
|
|
date_default_timezone_set($business->time_zone);
|
|
|
|
$activity = activity()
|
|
->performedOn($on)
|
|
->withProperties($properties)
|
|
->log($action);
|
|
|
|
$activity->business_id = $business_id;
|
|
$activity->save();
|
|
}
|
|
|
|
public function getBackupCleanCronJobCommand()
|
|
{
|
|
$php_binary_path = empty(PHP_BINARY) ? 'php' : PHP_BINARY;
|
|
|
|
$command = '* * * * * '.$php_binary_path.' '.base_path('artisan').' backup:clean >> /dev/null 2>&1';
|
|
|
|
if (config('app.env') == 'demo') {
|
|
$command = '';
|
|
}
|
|
|
|
return $command;
|
|
}
|
|
|
|
/**
|
|
* Get location from latitude and longitude
|
|
* Uses Google's Geocoding api
|
|
*
|
|
* @param $lat string latitude
|
|
* @param $long string longitude
|
|
* @return string
|
|
*/
|
|
public function getLocationFromCoordinates($lat, $long)
|
|
{
|
|
try {
|
|
$access_token = env('GOOGLE_MAP_API_KEY');
|
|
$full_address = null;
|
|
$address = [];
|
|
if (! empty($access_token)) {
|
|
$client = new Client();
|
|
$url = "https://maps.googleapis.com/maps/api/geocode/json?latlng={$lat},{$long}&key={$access_token}";
|
|
|
|
$response = $client->get($url);
|
|
|
|
$address = json_decode($response->getBody()->getContents(), true);
|
|
} else {
|
|
$client = new Client();
|
|
|
|
$this->client = new Client([
|
|
'base_uri' => 'https://nominatim.openstreetmap.org/',
|
|
'timeout' => 10,
|
|
'verify' => false,
|
|
'headers' => [
|
|
'User-Agent' => 'pos' // Add a User-Agent header
|
|
],
|
|
]);
|
|
|
|
try {
|
|
$request = $this->client->get('reverse', [
|
|
'query' => [
|
|
'lat' => $lat,
|
|
'lon' => $long,
|
|
'format' => 'json',
|
|
'accept-language' => app()->getLocale(),
|
|
],
|
|
]);
|
|
|
|
if ($request->getStatusCode() == 200) {
|
|
$result = json_decode($request->getBody()->getContents());
|
|
if (! empty($result->display_name)) {
|
|
$address = ['formatted_address' => $result->display_name];
|
|
}
|
|
}
|
|
} catch (\Exception $e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
if (! empty($address['results'][0]['formatted_address'])) {
|
|
$full_address = $address['results'][0]['formatted_address'];
|
|
} elseif (! empty($address['formatted_address'])) {
|
|
$full_address = $address['formatted_address'];
|
|
}
|
|
|
|
return $full_address;
|
|
} catch (\Exception $e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public function roundQuantity($quantity)
|
|
{
|
|
$quantity_precision = session('business.quantity_precision', 2);
|
|
|
|
return round($quantity, $quantity_precision);
|
|
}
|
|
|
|
public function getDropdownForRoles($business_id)
|
|
{
|
|
$app_roles = Role::where('business_id', $business_id)
|
|
->pluck('name', 'id');
|
|
|
|
$roles = [];
|
|
foreach ($app_roles as $key => $value) {
|
|
$roles[$key] = str_replace('#'.$business_id, '', $value);
|
|
}
|
|
|
|
return $roles;
|
|
}
|
|
|
|
/**
|
|
* Register user
|
|
*/
|
|
public function createUser($request)
|
|
{
|
|
$user_details = $request->only([
|
|
'surname', 'first_name', 'last_name', 'email',
|
|
'user_type', 'crm_contact_id', 'allow_login', 'username', 'password',
|
|
'cmmsn_percent', 'max_sales_discount_percent', 'dob', 'gender', 'marital_status', 'blood_group', 'contact_number', 'alt_number', 'family_number', 'fb_link',
|
|
'twitter_link', 'social_media_1', 'social_media_2', 'custom_field_1',
|
|
'custom_field_2', 'custom_field_3', 'custom_field_4', 'guardian_name', 'id_proof_name', 'id_proof_number', 'permanent_address', 'current_address', 'bank_details', 'selected_contacts', 'is_enable_service_staff_pin', 'service_staff_pin',
|
|
]);
|
|
|
|
$user_details['status'] = ! empty($request->input('is_active')) ? $request->input('is_active') : 'inactive';
|
|
$user_details['user_type'] = ! empty($user_details['user_type']) ? $user_details['user_type'] : 'user';
|
|
|
|
$user_details['is_enable_service_staff_pin'] = ! empty($request->input('is_enable_service_staff_pin')) ? true : false;
|
|
|
|
$business_id = Auth::user()->business_id;
|
|
$user_details['business_id'] = $business_id;
|
|
|
|
//Check if subscribed or not, then check for users quota
|
|
if ($user_details['user_type'] == 'user') {
|
|
$moduleUtil = new \App\Utils\ModuleUtil;
|
|
if (! $moduleUtil->isSubscribed($business_id)) {
|
|
return $moduleUtil->expiredResponse();
|
|
} elseif (! $moduleUtil->isQuotaAvailable('users', $business_id)) {
|
|
return $moduleUtil->quotaExpiredResponse('users', $business_id, action([\App\Http\Controllers\ManageUserController::class, 'index']));
|
|
}
|
|
}
|
|
|
|
if (empty($user_details['allow_login']) || ! $user_details['allow_login']) {
|
|
unset($user_details['username']);
|
|
unset($user_details['password']);
|
|
$user_details['allow_login'] = 0;
|
|
} else {
|
|
$user_details['allow_login'] = 1;
|
|
}
|
|
|
|
$user_details['selected_contacts'] = isset($user_details['selected_contacts']) ? $user_details['selected_contacts'] : 0;
|
|
|
|
$user_details['bank_details'] = ! empty($user_details['bank_details']) ? json_encode($user_details['bank_details']) : null;
|
|
|
|
$user_details['password'] = $user_details['allow_login'] ? Hash::make($user_details['password']) : null;
|
|
|
|
if ($user_details['allow_login']) {
|
|
if (empty($user_details['username'])) {
|
|
$ref_count = $this->setAndGetReferenceCount('username', $business_id);
|
|
$user_details['username'] = $this->generateReferenceNumber('username', $ref_count, $business_id);
|
|
}
|
|
|
|
if ($user_details['user_type'] == 'user') {
|
|
$username_ext = $this->getUsernameExtension();
|
|
if (! empty($username_ext)) {
|
|
$user_details['username'] .= $username_ext;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Create the user
|
|
$user = User::create($user_details);
|
|
|
|
if ($user_details['user_type'] == 'user') {
|
|
$role = Role::findOrFail($request->input('role'));
|
|
|
|
//Remove Location permissions from role
|
|
$this->revokeLocationPermissionsFromRole($role);
|
|
|
|
$user->assignRole($role->name);
|
|
|
|
//Grant Location permissions
|
|
$this->giveLocationPermissions($user, $request);
|
|
|
|
//Assign selected contacts
|
|
if ($user_details['selected_contacts'] == 1) {
|
|
$contact_ids = $request->get('selected_contact_ids');
|
|
$user->contactAccess()->sync($contact_ids);
|
|
}
|
|
|
|
//Save module fields for user
|
|
$moduleUtil = new \App\Utils\ModuleUtil;
|
|
$moduleUtil->getModuleData('afterModelSaved', ['event' => 'user_saved', 'model_instance' => $user]);
|
|
$this->activityLog($user, 'added', null, ['name' => $user->user_full_name], true, $business_id);
|
|
}
|
|
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* Get user name extension
|
|
*/
|
|
public function getUsernameExtension()
|
|
{
|
|
$business_id = Auth::user()->business_id;
|
|
|
|
$extension = ! empty(System::getProperty('enable_business_based_username')) ? '-'.str_pad($business_id, 2, 0, STR_PAD_LEFT) : null;
|
|
|
|
return $extension;
|
|
}
|
|
|
|
/**
|
|
* Revoke location permission from role
|
|
*/
|
|
public function revokeLocationPermissionsFromRole($role)
|
|
{
|
|
if ($role->hasPermissionTo('access_all_locations')) {
|
|
$role->revokePermissionTo('access_all_locations');
|
|
}
|
|
|
|
$business_id = Auth::user()->business_id;
|
|
|
|
$all_locations = BusinessLocation::where('business_id', $business_id)->get();
|
|
foreach ($all_locations as $location) {
|
|
if ($role->hasPermissionTo('location.'.$location->id)) {
|
|
$role->revokePermissionTo('location.'.$location->id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds or updates location permissions of a user
|
|
*/
|
|
public function giveLocationPermissions($user, $request)
|
|
{
|
|
$permitted_locations = $user->permitted_locations();
|
|
$permissions = $request->input('access_all_locations');
|
|
$location_permissions = $request->input('location_permissions');
|
|
$revoked_permissions = [];
|
|
|
|
//during api call if access_all_locations = 1 then generate location permissions
|
|
if (($permissions != 'access_all_locations') && $permissions == 1) {
|
|
$permissions = 'access_all_locations';
|
|
$location_ids = $request->input('location_permissions');
|
|
$location_permissions = [];
|
|
if (! empty($location_ids)) {
|
|
foreach ($location_ids as $location_id) {
|
|
$location_permissions[] = 'location.'.$location_id;
|
|
}
|
|
}
|
|
}
|
|
|
|
//If not access all location then revoke permission
|
|
if ($permitted_locations == 'all' && $permissions != 'access_all_locations') {
|
|
$user->revokePermissionTo('access_all_locations');
|
|
}
|
|
|
|
//Include location permissions
|
|
if (empty($permissions) && ! empty($location_permissions)) {
|
|
$permissions = [];
|
|
foreach ($location_permissions as $location_permission) {
|
|
$permissions[] = $location_permission;
|
|
}
|
|
|
|
if (is_array($permitted_locations)) {
|
|
foreach ($permitted_locations as $key => $value) {
|
|
if (! in_array('location.'.$value, $permissions)) {
|
|
$revoked_permissions[] = 'location.'.$value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (! empty($revoked_permissions)) {
|
|
$user->revokePermissionTo($revoked_permissions);
|
|
}
|
|
|
|
if (! empty($permissions)) {
|
|
$user->givePermissionTo($permissions);
|
|
} else {
|
|
//if no location permission given revoke previous permissions
|
|
if (! empty($permitted_locations)) {
|
|
$revoked_permissions = [];
|
|
foreach ($permitted_locations as $key => $value) {
|
|
$revoke_permissions[] = 'location.'.$value;
|
|
}
|
|
|
|
$user->revokePermissionTo($revoke_permissions);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function getDateRange($timePeriod)
|
|
{
|
|
switch ($timePeriod) {
|
|
case 'today':
|
|
$start = \Carbon::now()->startOfDay();
|
|
$end = \Carbon::now()->endOfDay();
|
|
break;
|
|
|
|
case 'yesterday':
|
|
$start = \Carbon::now()->subDay()->startOfDay();
|
|
$end = \Carbon::now()->subDay()->endOfDay();
|
|
break;
|
|
|
|
case 'last_7_days':
|
|
$start = \Carbon::now()->subDays(6)->startOfDay();
|
|
$end = \Carbon::now()->endOfDay();
|
|
break;
|
|
|
|
case 'last_30_days':
|
|
$start = \Carbon::now()->subDays(29)->startOfDay();
|
|
$end = \Carbon::now()->endOfDay();
|
|
break;
|
|
|
|
case 'this_month':
|
|
$start = \Carbon::now()->startOfMonth();
|
|
$end = \Carbon::now()->endOfMonth();
|
|
break;
|
|
|
|
case 'last_month':
|
|
$start = \Carbon::now()->subMonth()->startOfMonth();
|
|
$end = \Carbon::now()->subMonth()->endOfMonth();
|
|
break;
|
|
|
|
case 'this_month_last_year':
|
|
$start = \Carbon::now()->subYear()->startOfMonth();
|
|
$end = \Carbon::now()->subYear()->endOfMonth();
|
|
break;
|
|
|
|
case 'this_year':
|
|
$start = \Carbon::now()->startOfYear();
|
|
$end = \Carbon::now()->endOfYear();
|
|
break;
|
|
|
|
case 'last_year':
|
|
$start = \Carbon::now()->subYear()->startOfYear();
|
|
$end = \Carbon::now()->subYear()->endOfYear();
|
|
break;
|
|
|
|
case 'current_financial_year':
|
|
// Assuming financial year starts in April
|
|
$start = \Carbon\Carbon::now()->month >= 4 ? \Carbon\Carbon::now()->startOfYear()->month(4)->startOfMonth() : \Carbon\Carbon::now()->subYear()->startOfYear()->month(4)->startOfMonth();
|
|
$end = \Carbon\Carbon::now()->month >= 4 ? \Carbon\Carbon::now()->startOfYear()->month(4)->startOfMonth()->addYear()->subDay() : \Carbon\Carbon::now()->startOfYear()->subDay();
|
|
break;
|
|
|
|
case 'last_financial_year':
|
|
// Assuming financial year starts in April
|
|
$start = \Carbon\Carbon::now()->subYear()->month >= 4 ? \Carbon\Carbon::now()->subYear()->startOfYear()->month(4)->startOfMonth() : \Carbon\Carbon::now()->subYears(2)->startOfYear()->month(4)->startOfMonth();
|
|
$end = \Carbon\Carbon::now()->subYear()->month >= 4 ? \Carbon\Carbon::now()->subYear()->startOfYear()->month(4)->startOfMonth()->addYear()->subDay() : \Carbon\Carbon::now()->subYear()->startOfYear()->subDay();
|
|
break;
|
|
|
|
default:
|
|
$start = null;
|
|
$end = null;
|
|
break;
|
|
}
|
|
|
|
return ['start' => $start, 'end' => $end];
|
|
}
|
|
|
|
|
|
function numberToCurrencyWords($amount, $currencyMain = 'dollar', $currencySub = 'cent', $locale = 'en') {
|
|
$formatter = new \NumberFormatter($locale, \NumberFormatter::SPELLOUT);
|
|
|
|
$mainUnit = floor($amount);
|
|
$subUnit = round(($amount - $mainUnit) * 100);
|
|
|
|
$mainWord = $formatter->format($mainUnit);
|
|
$subWord = $formatter->format($subUnit);
|
|
|
|
// Determine if we should add 's' for plurals based on locale
|
|
$disablePluralS = in_array($locale, ['hi', 'hi_IN', 'ar', 'ar_SA', 'ar_EG']);
|
|
|
|
if ($disablePluralS) {
|
|
$mainLabel = $currencyMain;
|
|
$subLabel = $currencySub;
|
|
} else {
|
|
$mainLabel = ($mainUnit == 1) ? $currencyMain : $currencyMain . 's';
|
|
$subLabel = ($subUnit == 1) ? $currencySub : $currencySub . 's';
|
|
}
|
|
$result = ucfirst($mainWord) . " " . $mainLabel;
|
|
|
|
if ($subUnit > 0) {
|
|
$result .= " " . $subWord . " " . $subLabel;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
}
|