%PDF- %GIF98; %PNG;
Server : ApacheSystem : Linux host.digitalbabaji.in 4.18.0-513.11.1.el8_9.x86_64 #1 SMP Wed Jan 17 02:00:40 EST 2024 x86_64 User : addictionfreeind ( 1003) PHP Version : 7.2.34 Disable Function : exec,passthru,shell_exec,system Directory : /home/addictionfreeind/public_html/admin1/app/Http/Controllers/ |
Upload File : |
<?php
namespace App\Http\Controllers;
use App\Scopes\CompanyScope;
use Carbon\Carbon;
use Stripe\Stripe;
use App\Models\Lead;
use App\Models\Role;
use App\Models\Task;
use App\Models\User;
use App\Helper\Files;
use App\Helper\Reply;
use App\Models\Order;
use App\Models\Ticket;
use GuzzleHttp\Client;
use App\Models\Company;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\Product;
use App\Models\Project;
use App\Models\Proposal;
use App\Models\TaskFile;
use App\Models\LeadSource;
use App\Models\LeadStatus;
use App\Models\TicketType;
use App\Models\CreditNotes;
use App\Models\LeadProduct;
use App\Models\TicketReply;
use App\Scopes\ActiveScope;
use App\Models\InvoiceItems;
use App\Models\ProposalItem;
use App\Models\ProposalSign;
use Illuminate\Http\Request;
use App\Models\ClientDetails;
use App\Models\LeadCustomForm;
use App\Models\TaskboardColumn;
use App\Models\TicketCustomForm;
use Froiden\RestAPI\ApiResponse;
use Illuminate\Support\Facades\DB;
use App\Models\ProjectTimeLogBreak;
use Illuminate\Support\Facades\App;
use Nwidart\Modules\Facades\Module;
use App\Traits\UniversalSearchTrait;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Artisan;
use App\Models\PaymentGatewayCredentials;
use App\Http\Requests\Lead\StorePublicLead;
use App\Http\Requests\ProposalAcceptRequest;
use App\Http\Requests\Stripe\StoreStripeDetail;
use App\Http\Requests\Tickets\StoreCustomTicket;
use App\Models\TicketGroup;
class HomeController extends Controller
{
use UniversalSearchTrait;
/**
* Show the application dashboard.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('home');
}
public function login()
{
return redirect(route('login'));
}
public function invoice($hash)
{
$this->pageTitle = 'app.menu.invoices';
$this->pageIcon = 'icon-money';
$this->invoice = Invoice::with('currency', 'project', 'project.client', 'items.invoiceItemImage', 'items', 'items.unit')->where('hash', $hash)->firstOrFail();
$this->paidAmount = $this->invoice->getPaidAmount();
$this->discount = 0;
if ($this->invoice->discount > 0) {
if ($this->invoice->discount_type == 'percent') {
$this->discount = (($this->invoice->discount / 100) * $this->invoice->sub_total);
}
else {
$this->discount = $this->invoice->discount;
}
}
$taxList = [];
$items = InvoiceItems::whereNotNull('taxes')
->where('invoice_id', $this->invoice->id)
->get();
foreach ($items as $item) {
foreach (json_decode($item->taxes) as $tax) {
$this->tax = InvoiceItems::taxbyid($tax)->first();
if ($this->tax) {
if (!isset($taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'])) {
if ($this->invoice->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = ($item->amount - ($item->amount / $this->invoice->sub_total) * $this->discount) * ($this->tax->rate_percent / 100);
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $item->amount * ($this->tax->rate_percent / 100);
}
}
else {
if ($this->invoice->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + (($item->amount - ($item->amount / $this->invoice->sub_total) * $this->discount) * ($this->tax->rate_percent / 100));
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + ($item->amount * ($this->tax->rate_percent / 100));
}
}
}
}
}
$this->taxes = $taxList;
$this->company = $this->invoice->company;
$this->credentials = $this->company->paymentGatewayCredentials;
$this->methods = $this->company->offlinePaymentMethod;
$this->invoiceSetting = $this->company->invoiceSetting;
return view('invoice', [
'companyName' => $this->company->company_name,
'pageTitle' => $this->pageTitle,
'pageIcon' => $this->pageIcon,
'company' => $this->company,
'invoice' => $this->invoice,
'paidAmount' => $this->paidAmount,
'discount' => $this->discount,
'credentials' => $this->credentials,
'taxes' => $this->taxes,
'methods' => $this->methods,
'invoiceSetting' => $this->invoiceSetting,
]);
}
public function stripeModal(Request $request)
{
$this->invoiceID = $request->invoice_id;
$this->countries = countries();
return view('public-payment.stripe.index', $this->data);
}
public function paystackModal(Request $request)
{
$this->id = $request->id;
$this->type = $request->type;
$data = match ($request->type) {
'invoice' => Invoice::findOrFail($request->id),
'order' => Order::findOrFail($request->id),
default => Invoice::findOrFail($request->id),
};
$this->company = $data->company;
return view('public-payment.paystack.index', $this->data);
}
public function flutterwaveModal(Request $request)
{
$this->id = $request->id;
$this->type = $request->type;
return view('public-payment.flutterwave.index', $this->data);
}
public function mollieModal(Request $request)
{
$this->id = $request->id;
$this->type = $request->type;
$data = match ($request->type) {
'invoice' => Invoice::findOrFail($request->id),
'order' => Order::findOrFail($request->id),
default => Invoice::findOrFail($request->id),
};
$this->company = $data->company;
return view('public-payment.mollie.index', $this->data);
}
public function authorizeModal(Request $request)
{
$this->id = $request->id;
$this->type = $request->type;
return view('public-payment.authorize.index', $this->data);
}
public function saveStripeDetail(StoreStripeDetail $request)
{
$id = $request->invoice_id;
$this->invoice = Invoice::with(['client', 'project', 'project.client'])->findOrFail($id);
$this->company = $this->invoice->company;
if ($this->invoice && $this->invoice->amountDue() == 0) {
Reply::error(__('messages.invoiceAlreadyPaid'));
}
$this->credentials = PaymentGatewayCredentials::where('company_id', $this->company->id)->first();
$client = null;
if (!is_null($this->invoice->client_id)) {
$client = $this->invoice->client;
}
else if (!is_null($this->invoice->project_id) && !is_null($this->invoice->project->client_id)) {
$client = $this->invoice->project->client;
}
if (($this->credentials->test_stripe_secret || $this->credentials->live_stripe_secret) && !is_null($client)) {
Stripe::setApiKey($this->credentials->stripe_mode == 'test' ? $this->credentials->test_stripe_secret : $this->credentials->live_stripe_secret);
$totalAmount = $this->invoice->amountDue();
$customer = \Stripe\Customer::create([
'email' => $client->email,
'name' => $request->clientName,
'address' => [
'line1' => $request->clientName,
'city' => $request->city,
'state' => $request->state,
'country' => $request->country,
],
]);
$intent = \Stripe\PaymentIntent::create([
'amount' => $totalAmount * 100,
'currency' => $this->invoice->currency->currency_code,
'customer' => $customer->id,
'setup_future_usage' => 'off_session',
'payment_method_types' => ['card'],
'description' => $this->invoice->invoice_number . ' Payment',
'metadata' => ['integration_check' => 'accept_a_payment', 'invoice_id' => $id]
]);
$this->intent = $intent;
}
$customerDetail = [
'email' => $client->email,
'name' => $request->clientName,
'line1' => $request->clientName,
'city' => $request->city,
'state' => $request->state,
'country' => $request->country,
];
$this->customerDetail = $customerDetail;
$view = view('public-payment.stripe.stripe-payment', $this->data)->render();
return Reply::dataOnly(['view' => $view, 'intent' => $this->intent]);
}
public function downloadInvoice($id)
{
$this->invoice = Invoice::whereRaw('md5(id) = ?', $id)->firstOrFail();
$this->company = $this->invoice->company;
$this->invoiceSetting = $this->company->invoiceSetting;
App::setLocale($this->invoiceSetting->locale);
// Download file uploaded
if ($this->invoice->file != null) {
return response()->download(storage_path('app/public/invoice-files') . '/' . $this->invoice->file);
}
$pdfOption = $this->domPdfObjectForDownload($this->invoice->id);
$pdf = $pdfOption['pdf'];
$filename = $pdfOption['fileName'];
return $pdf->download($filename . '.pdf');
}
public function domPdfObjectForDownload($id)
{
$this->invoice = Invoice::with('items')->findOrFail($id);
$this->company = $this->invoice->company;
$this->invoiceSetting = $this->company->invoiceSetting;
App::setLocale($this->invoiceSetting->locale);
Carbon::setLocale($this->invoiceSetting->locale);
$this->paidAmount = $this->invoice->getPaidAmount();
$this->creditNote = 0;
if ($this->invoice->credit_note) {
$this->creditNote = CreditNotes::where('invoice_id', $id)
->select('cn_number')
->first();
}
if ($this->invoice->discount > 0) {
if ($this->invoice->discount_type == 'percent') {
$this->discount = (($this->invoice->discount / 100) * $this->invoice->sub_total);
}
else {
$this->discount = $this->invoice->discount;
}
}
else {
$this->discount = 0;
}
$taxList = array();
$items = InvoiceItems::whereNotNull('taxes')
->where('invoice_id', $this->invoice->id)
->get();
foreach ($items as $item) {
foreach (json_decode($item->taxes) as $tax) {
$this->tax = InvoiceItems::taxbyid($tax)->first();
if ($this->tax) {
if (!isset($taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'])) {
if ($this->invoice->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = ($item->amount - ($item->amount / $this->invoice->sub_total) * $this->discount) * ($this->tax->rate_percent / 100);
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $item->amount * ($this->tax->rate_percent / 100);
}
}
else {
if ($this->invoice->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + (($item->amount - ($item->amount / $this->invoice->sub_total) * $this->discount) * ($this->tax->rate_percent / 100));
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + ($item->amount * ($this->tax->rate_percent / 100));
}
}
}
}
}
$this->taxes = $taxList;
$this->company = $this->invoice->company;
$this->payments = Payment::with(['offlineMethod'])->where('invoice_id', $this->invoice->id)->where('status', 'complete')->orderBy('paid_on', 'desc')->get();
$pdf = app('dompdf.wrapper');
$pdf->loadView('invoices.pdf.' . $this->invoiceSetting->template, $this->data);
$filename = $this->invoice->invoice_number;
return [
'pdf' => $pdf,
'fileName' => $filename
];
}
public function app()
{
$setting = Company::select('id', 'company_name')->first();
return ['data' => $setting];
}
public function gantt($hash)
{
$this->project = Project::with('members', 'members.user')->where('hash', $hash)->firstOrFail();
$this->company = $this->project->company;
$this->pageTitle = $this->project->project_name;
return view('gantt', [
'company' => $this->company,
'pageTitle' => $this->pageTitle,
'project' => $this->project
]);
}
public function ganttData($ganttProjectId)
{
$assignedTo = request('assignedTo');
$projectTask = request('projectTask');
if ($assignedTo != 'all') {
$tasks = Task::projectTasks($ganttProjectId, $assignedTo, 1);
}
else {
$tasks = Task::projectTasks($ganttProjectId, null, 1);
}
if ($projectTask) {
$tasks = $tasks->whereIn('id', explode(',', $projectTask));
}
$data = array();
foreach ($tasks as $key => $task) {
$data[] = [
'id' => 'task-' . $task->id,
'name' => $task->heading,
'start' => ((!is_null($task->start_date)) ? $task->start_date->format('Y-m-d') : ((!is_null($task->due_date)) ? $task->due_date->format('Y-m-d') : null)),
'end' => ((!is_null($task->due_date)) ? $task->due_date->format('Y-m-d') : $task->start_date->format('Y-m-d')),
'progress' => 0,
'bg_color' => $task->boardColumn->label_color,
'taskid' => $task->hash,
'draggable' => true
];
if (!is_null($task->dependent_task_id)) {
$data[$key]['dependencies'] = 'task-' . $task->dependent_task_id;
}
}
return response()->json($data);
}
public function taskDetail($hash)
{
$this->task = Task::with('company:id,timezone,favicon,light_logo,date_format,time_format,company_name', 'boardColumn', 'project', 'users', 'label', 'approvedTimeLogs', 'approvedTimeLogs.user', 'comments', 'comments.user')
->withCount('subtasks', 'files', 'comments', 'activeTimerAll')
->where('hash', $hash)
->firstOrFail()
->withCustomFields();
$this->pageTitle = __('app.task') . ' # ' . $this->task->task_short_code;
if ($this->task->getCustomFieldGroupsWithFields()) {
$this->fields = $this->task->getCustomFieldGroupsWithFields()->fields;
}
$this->employees = User::join('employee_details', 'users.id', '=', 'employee_details.user_id')
->leftJoin('project_time_logs', 'project_time_logs.user_id', '=', 'users.id')
->leftJoin('designations', 'employee_details.designation_id', '=', 'designations.id');
$this->employees = $this->employees->select(
'users.name',
'users.image',
'users.id',
'designations.name as designation_name'
);
$this->employees = $this->employees->where('project_time_logs.task_id', '=', $this->task->id);
$this->employees = $this->employees->groupBy('project_time_logs.user_id')
->orderBy('users.name')
->get();
$this->breakMinutes = ProjectTimeLogBreak::taskBreakMinutes($this->task->id);
$tab = request('view');
$this->tab = match ($tab) {
'sub_task' => 'front.tasks.ajax.sub_tasks',
'history' => 'front.tasks.ajax.history',
'comments' => 'front.tasks.ajax.comments',
'time_logs' => 'front.tasks.ajax.timelogs',
'notes' => 'front.tasks.ajax.notes',
default => 'front.tasks.ajax.files',
};
$this->company = $this->task->company;
if (request()->ajax()) {
if (request('json') == true) {
$html = view($this->tab, $this->data)->render();
return Reply::dataOnly(['status' => 'success', 'html' => $html, 'title' => $this->pageTitle]);
}
$html = view('front.tasks.ajax.show', $this->data)->render();
return Reply::dataOnly(['status' => 'success', 'html' => $html, 'title' => $this->pageTitle]);
}
$this->view = 'front.tasks.ajax.show';
return view('front.tasks.show', $this->data);
}
public function taskFiles($id)
{
$this->taskFiles = TaskFile::where('task_id', $id)->get();
return view('task-files', ['taskFiles' => $this->taskFiles]);
}
public function taskboard(Request $request, $hash)
{
$project = Project::where('hash', $hash)->firstOrFail();
$this->company = $project->company;
$this->pageTitle = $project->project_name . ' ' . __('modules.tasks.taskBoard');
if (request()->ajax()) {
$this->boardEdit = false;
$this->boardDelete = false;
$boardColumns = TaskboardColumn::withCount(['tasks as tasks_count' => function ($q) use ($project) {
$q->leftJoin('projects', 'projects.id', '=', 'tasks.project_id')
->leftJoin('users as client', 'client.id', '=', 'projects.client_id')
->leftJoin('task_users', 'task_users.task_id', '=', 'tasks.id')
->leftJoin('users', 'task_users.user_id', '=', 'users.id')
->leftJoin('task_labels', 'task_labels.task_id', '=', 'tasks.id')
->leftJoin('users as creator_user', 'creator_user.id', '=', 'tasks.created_by');
$q->whereNull('projects.deleted_at');
$q->where('tasks.is_private', 0);
$q->where('tasks.project_id', '=', $project->id);
$q->select(DB::raw('count(distinct tasks.id)'));
}])
->with(['tasks' => function ($q) use ($project) {
$q->withCount(['subtasks', 'completedSubtasks', 'comments'])
->leftJoin('projects', 'projects.id', '=', 'tasks.project_id')
->leftJoin('users as client', 'client.id', '=', 'projects.client_id')
->leftJoin('task_users', 'task_users.task_id', '=', 'tasks.id')
->leftJoin('users', 'task_users.user_id', '=', 'users.id')
->leftJoin('task_labels', 'task_labels.task_id', '=', 'tasks.id')
->leftJoin('users as creator_user', 'creator_user.id', '=', 'tasks.created_by')
->groupBy('tasks.id');
$q->whereNull('projects.deleted_at');
$q->where('tasks.is_private', 0);
$q->where('tasks.project_id', '=', $project->id);
}])
->where('taskboard_columns.company_id', $this->company->id)
->orderBy('priority', 'asc')
->get();
$result = array();
foreach ($boardColumns as $key => $boardColumn) {
$result['boardColumns'][] = $boardColumn;
$tasks = Task::with(['users', 'project', 'labels'])
->withCount(['subtasks', 'completedSubtasks', 'comments'])
->leftJoin('projects', 'projects.id', '=', 'tasks.project_id')
->leftJoin('users as client', 'client.id', '=', 'projects.client_id')
->leftJoin('task_users', 'task_users.task_id', '=', 'tasks.id')
->leftJoin('users', 'task_users.user_id', '=', 'users.id')
->leftJoin('task_labels', 'task_labels.task_id', '=', 'tasks.id')
->leftJoin('users as creator_user', 'creator_user.id', '=', 'tasks.created_by')
->select('tasks.*')
->where('tasks.board_column_id', $boardColumn->id)
->where('tasks.is_private', 0)
->orderBy('column_priority', 'asc')
->groupBy('tasks.id');
$tasks->whereNull('projects.deleted_at');
$tasks->where('tasks.project_id', '=', $project->id);
$tasks->skip(0)->take($this->company->taskboard_length ?? 10);
$tasks = $tasks->get();
$result['boardColumns'][$key]['tasks'] = $tasks;
}
$this->result = $result;
$view = view('taskboard_data', [
'result' => $this->result,
'boardEdit' => $this->boardEdit
])->render();
return Reply::dataOnly(['view' => $view]);
}
return view('taskboard', [
'pageTitle' => $this->pageTitle,
'company' => $this->company,
'project' => $project
]);
}
public function taskboardLoadMore(Request $request, $hash)
{
$skip = $request->currentTotalTasks;
$totalTasks = $request->totalTasks;
$project = Project::where('hash', $hash)->firstOrFail();
$this->company = $project->company;
$tasks = Task::with('users', 'project', 'labels')
->withCount(['subtasks', 'completedSubtasks', 'comments'])
->leftJoin('projects', 'projects.id', '=', 'tasks.project_id')
->leftJoin('users as client', 'client.id', '=', 'projects.client_id')
->leftJoin('task_users', 'task_users.task_id', '=', 'tasks.id')
->leftJoin('users', 'task_users.user_id', '=', 'users.id')
->leftJoin('task_labels', 'task_labels.task_id', '=', 'tasks.id')
->leftJoin('users as creator_user', 'creator_user.id', '=', 'tasks.created_by')
->select('tasks.*')
->where('tasks.board_column_id', $request->columnId)
->orderBy('column_priority', 'asc')
->groupBy('tasks.id');
$tasks->whereNull('projects.deleted_at');
$tasks->where('tasks.project_id', '=', $project->id);
$tasks->skip($skip)->take($this->company->taskboard_length ?? 10);
$tasks = $tasks->get();
$this->tasks = $tasks;
if ($totalTasks <= ($skip + $this->company->taskboard_length)) {
$loadStatus = 'hide';
}
else {
$loadStatus = 'show';
}
$view = view('taskboard_load_more', $this->data)->render();
return Reply::dataOnly(['view' => $view, 'load_more' => $loadStatus]);
}
/**
* custom lead form
*
* @return \Illuminate\Http\Response
*/
public function leadForm($id)
{
$this->withLogo = \request()->get('with_logo');
$this->styled = \request()->get('styled');
$this->pageTitle = 'modules.lead.leadForm';
$this->company = Company::where('hash', $id)->firstOrFail();
$this->globalSetting = global_setting();
$this->countries = countries();
$this->sources = LeadSource::where('company_id', $this->company->id)->get();
$this->products = Product::where('company_id', $this->company->id)->get();
$this->leadFormFields = LeadCustomForm::with('customField')
->where('status', 'active')
->where('company_id', $this->company->id)
->orderBy('field_order')->get();
return view('lead-form', $this->data);
}
/**
* save lead
*
* @return \Illuminate\Http\Response
*/
// public function leadStore(StorePublicLead $request)
public function leadStore(StorePublicLead $request)
{
$company = Company::findOrFail($request->company_id);
if (global_setting()->google_recaptcha_status == 'active') {
// Checking is google recaptcha is valid
$gRecaptchaResponseInput = global_setting()->google_recaptcha_v3_status == 'active' ? 'g_recaptcha' : 'g-recaptcha-response';
$gRecaptchaResponse = $request->{$gRecaptchaResponseInput};
$validateRecaptcha = $this->validateGoogleRecaptcha($gRecaptchaResponse);
if (!$validateRecaptcha) {
return Reply::error(__('auth.recaptchaFailed'));
}
}
$leadStatus = LeadStatus::where('default', '1')->where('company_id', $company->id)->first();
$lead = new Lead();
$lead->company_id = $company->id;
$lead->company_name = (request()->has('company_name') ? $request->company_name : '');
$lead->website = (request()->has('website') ? $request->website : '');
$lead->address = (request()->has('address') ? $request->address : '');
$lead->client_name = (request()->has('name') ? $request->name : '');
$lead->client_email = (request()->has('email') ? $request->email : '');
$lead->mobile = (request()->has('mobile') ? $request->mobile : '');
$lead->city = (request()->has('city') ? $request->city : '');
$lead->state = (request()->has('state') ? $request->state : '');
$lead->country = (request()->has('country') ? $request->country : '');
$lead->postal_code = (request()->has('postal_code') ? $request->postal_code : '');
$lead->source_id = (request()->has('source') ? $request->source : '');
$lead->status_id = $leadStatus->id;
$lead->value = 0;
$lead->currency_id = $company->currency_id;
$lead->save();
if (!is_null($request->product)) {
$products = $request->product;
foreach($products as $product)
{
$leadProduct = new LeadProduct();
$leadProduct->lead_id = $lead->id;
$leadProduct->product_id = $product;
$leadProduct->save();
}
}
// To add custom fields data
if ($request->custom_fields_data) {
$lead->updateCustomFieldData($request->custom_fields_data);
}
return Reply::success(__('messages.recordSaved'));
}
/**
* custom lead form
*
* @return \Illuminate\Http\Response
*/
public function ticketForm($id)
{
$this->pageTitle = 'modules.ticketForm';
$this->withLogo = \request()->get('with_logo');
$this->styled = \request()->get('styled');
$this->company = Company::where('hash', $id)->firstOrFail();
$this->groups = TicketGroup::where('company_id', $this->company->id)->get();
$this->ticketFormFields = TicketCustomForm::with('customField')
->where('company_id', $this->company->id)
->where('status', 'active')
->orderBy('field_order', 'asc')
->get();
$this->types = TicketType::where('company_id', $this->company->id)->get();
App::setLocale($this->company->locale);
Carbon::setLocale($this->company->locale);
setlocale(LC_TIME, $this->company->locale . '_' . mb_strtoupper($this->company->locale));
return view('ticket-form', $this->data);
}
/**
* save lead
*
* @return array
*/
public function ticketStore(StoreCustomTicket $request)
{
$company = Company::findOrFail($request->company_id);
if (global_setting()->google_recaptcha_status == 'active') {
// Checking is google recaptcha is valid
$gRecaptchaResponseInput = global_setting()->google_recaptcha_v3_status == 'active' ? 'g_recaptcha' : 'g-recaptcha-response';
$gRecaptchaResponse = $request->{$gRecaptchaResponseInput};
$validateRecaptcha = $this->validateGoogleRecaptcha($gRecaptchaResponse);
if (!$validateRecaptcha) {
return Reply::error(__('auth.recaptchaFailed'));
}
}
/* $rules['g-recaptcha-response'] = 'required'; */
$existing_user = User::withoutGlobalScope(ActiveScope::class)->select('id', 'email')->where('email', $request->email)->first();
$newUser = $existing_user;
if (!$existing_user) {
$password = str_random(8);
// create new user
$client = new User();
$client->company_id = $request->company_id;
$client->name = $request->name;
$client->email = $request->email;
$client->password = Hash::make($password);
$client->save();
// attach role
$role = Role::withoutGlobalScope(CompanyScope::class)
->where('name', 'client')
->where('company_id', $company->id)
->select('id')
->first();
$role ? $client->attachRole($role->id) : null;
$clientDetail = new ClientDetails();
$clientDetail->company_id = $client->company_id;
$clientDetail->user_id = $client->id;
$clientDetail->save();
// Log search
$this->logSearchEntry($client->id, $client->name, 'clients.edit', 'client');
$this->logSearchEntry($client->id, $client->email, 'clients.edit', 'client');
$newUser = $client;
}
// Create New Ticket
$ticket = new Ticket();
$ticket->company_id = $company->id;
$ticket->subject = (request()->has('ticket_subject') ? $request->ticket_subject : '');
$ticket->status = 'open';
$ticket->user_id = $newUser->id;
$ticket->type_id = (request()->has('type') ? $request->type : null);
$ticket->priority = (request()->has('priority') ? $request->priority : 'medium');
$ticket->group_id = (request()->has('assign_group') ? $request->assign_group : null);
$ticket->save();
// Save first message
$reply = new TicketReply();
$reply->message = (request()->has('ticket_description') ? $request->ticket_description : '');
$reply->ticket_id = $ticket->id;
$reply->user_id = $newUser->id; // Current logged in user
$reply->save();
// To add custom fields data
if ($request->custom_fields_data) {
$ticket->updateCustomFieldData($request->custom_fields_data);
}
return Reply::success(__('messages.ticketCreateSuccess'));
}
public function validateGoogleRecaptcha($googleRecaptchaResponse)
{
$secret = global_setting()->google_recaptcha_v2_status == 'active' ? global_setting()->google_recaptcha_v2_secret_key : global_setting()->google_recaptcha_v3_secret_key;
$client = new Client();
$response = $client->post(
'https://www.google.com/recaptcha/api/siteverify',
[
'form_params' => [
'secret' => $secret,
'response' => $googleRecaptchaResponse,
'remoteip' => $_SERVER['REMOTE_ADDR']
]
]
);
$body = json_decode((string)$response->getBody());
return $body->success;
}
public function installedModule()
{
$message = '';
$plugins = Module::allEnabled();
$applicationVersion = trim(
preg_replace(
'/\s\s+/',
' ',
!file_exists(File::get(public_path() . '/version.txt')) ? File::get(public_path() . '/version.txt') : '0'
)
);
$enableModules = [];
$enableModules['application'] = 'worksuite';
$enableModules['version'] = $applicationVersion;
$enableModules['worksuite'] = $applicationVersion;
foreach ($plugins as $plugin) {
$enableModules[$plugin->getName()] = trim(
preg_replace(
'/\s\s+/',
' ',
!file_exists(File::get($plugin->getPath() . '/version.txt')) ? File::get($plugin->getPath() . '/version.txt') : '0'
)
);
}
if (((int)str_replace('.', '', $enableModules['RestAPI'])) < 110) {
$message .= 'Please update Rest API module greater then 1.1.0 version';
}
if (((int)str_replace('.', '', $enableModules['worksuite'])) < 400) {
$message .= 'Please update' . config('app.name') . ' greater then 4.0.0 version';
}
$enableModules['message'] = $message;
return ApiResponse::make('Plugin data fetched successfully', $enableModules);
}
public function proposal($hash)
{
$this->pageTitle = __('app.menu.proposal');
$this->pageIcon = 'icon-people';
$this->proposal = Proposal::with(['items', 'unit'])->where('hash', $hash)->firstOrFail();
$this->company = $this->proposal->company;
if ($this->proposal->discount > 0) {
if ($this->proposal->discount_type == 'percent') {
$this->discount = (($this->proposal->discount / 100) * $this->proposal->sub_total);
}
else {
$this->discount = $this->proposal->discount;
}
}
else {
$this->discount = 0;
}
$this->taxes = ProposalItem::where('type', 'tax')
->where('proposal_id', $this->proposal->id)
->get();
$items = ProposalItem::whereNotNull('taxes')
->where('proposal_id', $this->proposal->id)
->get();
$taxList = array();
foreach ($items as $item) {
foreach (json_decode($item->taxes) as $tax) {
$this->tax = ProposalItem::taxbyid($tax)->first();
if ($this->tax) {
if (!isset($taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'])) {
if ($this->proposal->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = ($item->amount - ($item->amount / $this->proposal->sub_total) * $this->discount) * ($this->tax->rate_percent / 100);
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $item->amount * ($this->tax->rate_percent / 100);
}
}
else {
if ($this->proposal->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + (($item->amount - ($item->amount / $this->proposal->sub_total) * $this->discount) * ($this->tax->rate_percent / 100));
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + ($item->amount * ($this->tax->rate_percent / 100));
}
}
}
}
}
$this->taxes = $taxList;
$lastViewed = now();
$ipAddress = request()->ip();
$this->proposal->last_viewed = $lastViewed;
$this->proposal->ip_address = $ipAddress;
$this->proposal->save();
return view('proposal', [
'proposal' => $this->proposal,
'pageTitle' => $this->pageTitle,
'pageIcon' => $this->pageIcon,
'taxes' => $this->taxes,
'discount' => $this->discount,
'company' => $this->company,
'invoiceSetting' => $this->company->invoiceSetting,
]);
}
public function proposalActionStore(ProposalAcceptRequest $request, $id)
{
$this->proposal = Proposal::with('signature')->findOrFail($id);
if ($this->proposal && $this->proposal->signature) {
return Reply::error(__('messages.alreadySigned'));
}
if ($request->type == 'accept') {
$sign = new ProposalSign();
$sign->full_name = $request->full_name;
$sign->proposal_id = $this->proposal->id;
$sign->email = $request->email;
$imageName = null;
if ($request->signature_type == 'signature' && $request->isSignatureNull == 'false') {
$image = $request->signature; // your base64 encoded
$image = str_replace('data:image/png;base64,', '', $image);
$image = str_replace(' ', '+', $image);
$imageName = str_random(32) . '.' . 'jpg';
Files::createDirectoryIfNotExist('proposal/sign');
File::put(public_path() . '/' . Files::UPLOAD_FOLDER . '/proposal/sign/' . $imageName, base64_decode($image));
Files::uploadLocalFile($imageName, 'proposal/sign', $this->proposal->company_id);
}
else {
if ($request->hasFile('image')) {
$imageName = Files::uploadLocalOrS3($request->image, 'proposal/sign', 300);
}
}
$sign->signature = $imageName;
$sign->save();
$this->proposal->status = 'accepted';
}
else {
$this->proposal->client_comment = $request->comment;
$this->proposal->status = 'declined';
}
$this->proposal->save();
return Reply::success(__('messages.updateSuccess'));
}
public function domPdfObjectProposalDownload($id)
{
$this->proposal = Proposal::where('hash', $id)->firstOrFail();
$this->company = $this->proposal->company;
if ($this->proposal->discount > 0) {
if ($this->proposal->discount_type == 'percent') {
$this->discount = (($this->proposal->discount / 100) * $this->proposal->sub_total);
}
else {
$this->discount = $this->proposal->discount;
}
}
else {
$this->discount = 0;
}
$this->taxes = ProposalItem::where('type', 'tax')
->where('proposal_id', $this->proposal->id)
->get();
$items = ProposalItem::whereNotNull('taxes')
->where('proposal_id', $this->proposal->id)
->get();
$taxList = array();
foreach ($items as $item) {
foreach (json_decode($item->taxes) as $tax) {
$this->tax = ProposalItem::taxbyid($tax)->first();
if ($this->tax) {
if (!isset($taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'])) {
if ($this->proposal->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = ($item->amount - ($item->amount / $this->proposal->sub_total) * $this->discount) * ($this->tax->rate_percent / 100);
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $item->amount * ($this->tax->rate_percent / 100);
}
}
else {
if ($this->proposal->calculate_tax == 'after_discount' && $this->discount > 0) {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + (($item->amount - ($item->amount / $this->proposal->sub_total) * $this->discount) * ($this->tax->rate_percent / 100));
}
else {
$taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] = $taxList[$this->tax->tax_name . ': ' . $this->tax->rate_percent . '%'] + ($item->amount * ($this->tax->rate_percent / 100));
}
}
}
}
}
$this->taxes = $taxList;
$this->invoiceSetting = $this->company->invoiceSetting;
App::setLocale($this->invoiceSetting->locale);
Carbon::setLocale($this->invoiceSetting->locale);
$pdf = app('dompdf.wrapper');
$pdf->setOption('enable_php', true);
$pdf->setOption('isHtml5ParserEnabled', true);
$pdf->setOption('isRemoteEnabled', true);
$pdf->loadView('proposals.pdf.' . $this->invoiceSetting->template, $this->data);
$dom_pdf = $pdf->getDomPDF();
$canvas = $dom_pdf->getCanvas();
$canvas->page_text(530, 820, 'Page {PAGE_NUM} of {PAGE_COUNT}', null, 10);
$filename = 'proposal-' . $this->proposal->id;
return [
'pdf' => $pdf,
'fileName' => $filename
];
}
/**
* @param int $id
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
*/
public function downloadProposal($id)
{
$this->proposal = Proposal::where('hash', $id)->firstOrFail();
$this->company = $this->proposal->company;
App::setLocale(isset($this->company->locale) ? $this->company->locale : 'en');
$pdfOption = $this->domPdfObjectProposalDownload($id);
$pdf = $pdfOption['pdf'];
$filename = $pdfOption['fileName'];
return $pdf->download($filename . '.pdf');
}
public function invoicePaymentfailed($invoiceId)
{
$invoice = Invoice::findOrFail($invoiceId);
if (request()->gateway == 'Razorpay') {
$errorMessage = ['code' => request()->errorMessage['code'], 'message' => request()->errorMessage['description']];
}
if (request()->gateway == 'Stripe') {
$errorMessage = ['code' => request()->errorMessage['type'], 'message' => request()->errorMessage['message']];
}
/* make new payment entry with status=failed and other details */
$payment = new Payment();
$payment->company_id = $invoice->company->id;
$payment->invoice_id = $invoice->id;
$payment->currency_id = $invoice->currency_id;
$payment->amount = $invoice->total;
$payment->gateway = request()->gateway;
$payment->paid_on = now();
$payment->status = 'failed';
/** @phpstan-ignore-next-line */
$payment->payment_gateway_response = $errorMessage;
$payment->save();
return Reply::error(__('messages.paymentFailed'));
}
public function showImage()
{
$this->imageUrl = request()->image_url;
return view('front.image.show_image', $this->data);
}
public function syncPermissions()
{
return Artisan::call('sync-user-permissions');
}
public function changeLang($locale)
{
session(['locale' => $locale]);
return Reply::success(__('messages.updateSuccess'));
}
}