diff --git a/VERSION.txt b/VERSION.txt index 9b4bab7a7e41..3113d499b22c 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.7.7 \ No newline at end of file +5.7.8 \ No newline at end of file diff --git a/app/Console/Commands/SendRemindersCron.php b/app/Console/Commands/SendRemindersCron.php index 4ffec48476c1..8328611b836c 100644 --- a/app/Console/Commands/SendRemindersCron.php +++ b/app/Console/Commands/SendRemindersCron.php @@ -173,7 +173,7 @@ class SendRemindersCron extends Command /**Refresh Invoice values*/ $invoice->calc()->getInvoice()->save(); $invoice->fresh(); - $invoice->service()->deletePdf()->save(); + // $invoice->service()->deletePdf()->save(); if ($invoice->client->getSetting('enable_e_invoice')){ $invoice->service()->deleteEInvoice()->save(); } diff --git a/app/Http/Controllers/BankTransactionRuleController.php b/app/Http/Controllers/BankTransactionRuleController.php index 0e8747109084..a17cf4cfe76c 100644 --- a/app/Http/Controllers/BankTransactionRuleController.php +++ b/app/Http/Controllers/BankTransactionRuleController.php @@ -12,9 +12,7 @@ namespace App\Http\Controllers; use App\Utils\Traits\MakesHash; -use Illuminate\Support\Collection; use App\Models\BankTransactionRule; -use App\Filters\BankTransactionFilters; use App\Factory\BankTransactionRuleFactory; use App\Filters\BankTransactionRuleFilters; use App\Repositories\BankTransactionRuleRepository; @@ -26,6 +24,7 @@ use App\Http\Requests\BankTransactionRule\StoreBankTransactionRuleRequest; use App\Http\Requests\BankTransactionRule\CreateBankTransactionRuleRequest; use App\Http\Requests\BankTransactionRule\UpdateBankTransactionRuleRequest; use App\Http\Requests\BankTransactionRule\DestroyBankTransactionRuleRequest; +use App\Services\Bank\BankMatchingService; class BankTransactionRuleController extends BaseController { @@ -256,8 +255,12 @@ class BankTransactionRuleController extends BaseController */ public function update(UpdateBankTransactionRuleRequest $request, BankTransactionRule $bank_transaction_rule) { - //stubs for updating the model - $bank_transaction = $this->bank_transaction_repo->save($request->all(), $bank_transaction_rule); + /** @var \App\Models\User $user */ + $user = auth()->user(); + + $bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), $bank_transaction_rule); + + BankMatchingService::dispatch($user->company()->id, $user->company()->db); return $this->itemResponse($bank_transaction_rule->fresh()); } @@ -304,6 +307,7 @@ class BankTransactionRuleController extends BaseController { /** @var \App\Models\User $user **/ $user = auth()->user(); + $bank_transaction_rule = BankTransactionRuleFactory::create($user->company()->id, $user->id); return $this->itemResponse($bank_transaction_rule); @@ -355,6 +359,8 @@ class BankTransactionRuleController extends BaseController $bank_transaction_rule = $this->bank_transaction_repo->save($request->all(), BankTransactionRuleFactory::create($user->company()->id, $user->id)); + BankMatchingService::dispatch($user->company()->id, $user->company()->db); + return $this->itemResponse($bank_transaction_rule); } diff --git a/app/Http/Controllers/ClientPortal/EntityViewController.php b/app/Http/Controllers/ClientPortal/EntityViewController.php index e46cf1a8178d..f5c40de3a312 100644 --- a/app/Http/Controllers/ClientPortal/EntityViewController.php +++ b/app/Http/Controllers/ClientPortal/EntityViewController.php @@ -17,6 +17,10 @@ use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; use Illuminate\View\View; +/** + * EntityViewController + * @deprecated 5.7 ? + */ class EntityViewController extends Controller { use MakesHash; diff --git a/app/Http/Controllers/ClientPortal/QuoteController.php b/app/Http/Controllers/ClientPortal/QuoteController.php index 98750aa683b9..39d48aab2904 100644 --- a/app/Http/Controllers/ClientPortal/QuoteController.php +++ b/app/Http/Controllers/ClientPortal/QuoteController.php @@ -12,21 +12,22 @@ namespace App\Http\Controllers\ClientPortal; -use App\Events\Misc\InvitationWasViewed; +use App\Utils\Ninja; +use App\Models\Quote; +use Illuminate\View\View; +use Illuminate\Http\Request; +use App\Models\QuoteInvitation; +use App\Utils\Traits\MakesHash; use App\Events\Quote\QuoteWasViewed; use App\Http\Controllers\Controller; -use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest; +use App\Jobs\Invoice\InjectSignature; +use Illuminate\Contracts\View\Factory; +use Illuminate\Support\Facades\Storage; +use App\Events\Misc\InvitationWasViewed; +use Symfony\Component\HttpFoundation\BinaryFileResponse; use App\Http\Requests\ClientPortal\Quotes\ShowQuoteRequest; use App\Http\Requests\ClientPortal\Quotes\ShowQuotesRequest; -use App\Jobs\Invoice\InjectSignature; -use App\Models\Quote; -use App\Utils\Ninja; -use App\Utils\Traits\MakesHash; -use Illuminate\Contracts\View\Factory; -use Illuminate\Http\Request; -use Illuminate\Support\Facades\Storage; -use Illuminate\View\View; -use Symfony\Component\HttpFoundation\BinaryFileResponse; +use App\Http\Requests\ClientPortal\Quotes\ProcessQuotesInBulkRequest; class QuoteController extends Controller { @@ -121,37 +122,38 @@ class QuoteController extends Controller /** @var \App\Models\ClientContact $client_contact **/ $client_contact = auth()->user(); - $quotes = Quote::query() - ->whereIn('id', $ids) - ->whereClientId($client_contact->client_id) + $quote_invitations = QuoteInvitation::query() + ->with('quote','company') + ->whereIn('quote_id', $ids) + ->where('client_contact_id', $client_contact->id) ->withTrashed() ->get(); - if (! $quotes || $quotes->count() == 0) { + if (! $quote_invitations || $quote_invitations->count() == 0) { return redirect() ->route('client.quotes.index') ->with('message', ctrans('texts.no_quotes_available_for_download')); } - if ($quotes->count() == 1) { - $file = $quotes->first()->service()->getQuotePdf(); - // return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true); + if ($quote_invitations->count() == 1) { + $invitation = $quote_invitations->first(); + $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle(); return response()->streamDownload(function () use ($file) { - echo Storage::get($file); - }, basename($file), ['Content-Type' => 'application/pdf']); + echo $file; + }, $invitation->quote->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']); } - return $this->buildZip($quotes); + return $this->buildZip($quote_invitations); } - private function buildZip($quotes) + private function buildZip($quote_invitations) { // create new archive $zipFile = new \PhpZip\ZipFile(); try { - foreach ($quotes as $quote) { - //add it to the zip - $zipFile->addFromString(basename($quote->pdf_file_path()), file_get_contents($quote->pdf_file_path(null, 'url', true))); + foreach ($quote_invitations as $invitation) { + $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $invitation->company->db))->handle(); + $zipFile->addFromString($invitation->quote->numberFormatter() . '.pdf', $file); } $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip'; @@ -162,7 +164,6 @@ class QuoteController extends Controller return response()->download($filepath, $filename)->deleteFileAfterSend(true); } catch (\PhpZip\Exception\ZipException $e) { - // handle exception } finally { $zipFile->close(); } diff --git a/app/Http/Controllers/CompanyUserController.php b/app/Http/Controllers/CompanyUserController.php index 22d1a0ee2ae9..c3d1c6ed45b1 100644 --- a/app/Http/Controllers/CompanyUserController.php +++ b/app/Http/Controllers/CompanyUserController.php @@ -111,8 +111,9 @@ class CompanyUserController extends BaseController */ public function update(UpdateCompanyUserRequest $request, User $user) { - - $company = auth()->user()->company(); + /** @var \App\Models\User $auth_user */ + $auth_user = auth()->user(); + $company = $auth_user->company(); $company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first(); @@ -122,7 +123,7 @@ class CompanyUserController extends BaseController return; } - if (auth()->user()->isAdmin()) { + if ($auth_user->isAdmin()) { $company_user->fill($request->input('company_user')); } else { $company_user->settings = $request->input('company_user')['settings']; @@ -136,8 +137,11 @@ class CompanyUserController extends BaseController public function updatePreferences(UpdateCompanyUserPreferencesRequest $request, User $user) { + /** @var \App\Models\User $auth_user */ + $auth_user = auth()->user(); + $company = $auth_user->company(); - $company = auth()->user()->company(); + $company = $auth_user->company(); $company_user = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first(); diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index f64b5efce971..b2be03691eb7 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -385,8 +385,8 @@ class CreditController extends BaseController $credit = $this->credit_repository->save($request->all(), $credit); $credit->service() - ->triggeredActions($request) - ->deletePdf(); + ->triggeredActions($request); + // ->deletePdf(); /** @var \App\Models\User $user**/ $user = auth()->user(); @@ -529,20 +529,18 @@ class CreditController extends BaseController if ($action == 'bulk_download' && $credits->count() > 1) { $credits->each(function ($credit) use($user){ if ($user->cannot('view', $credit)) { - nlog('access denied'); - return response()->json(['message' => ctrans('text.access_denied')]); } }); - ZipCredits::dispatch($credits, $credits->first()->company, $user); + ZipCredits::dispatch($credits->pluck('id')->toArray(), $credits->first()->company, $user); return response()->json(['message' => ctrans('texts.sent_message')], 200); } if ($action == 'bulk_print' && $user->can('view', $credits->first())) { $paths = $credits->map(function ($credit) { - return $credit->service()->getCreditPdf($credit->invitations->first()); + return (new \App\Jobs\Entity\CreateRawPdf($credit->invitations->first(), $credit->company->db))->handle(); }); $merge = (new PdfMerge($paths->toArray()))->run(); @@ -592,11 +590,8 @@ class CreditController extends BaseController } break; case 'download': - // $file = $credit->pdf_file_path(); $file = $credit->service()->getCreditPdf($credit->invitations->first()); - // return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true); - return response()->streamDownload(function () use ($file) { echo Storage::get($file); }, basename($file), ['Content-Type' => 'application/pdf']); diff --git a/app/Http/Controllers/EmailHistoryController.php b/app/Http/Controllers/EmailHistoryController.php index e8f2d4894fda..42dea4c1625a 100644 --- a/app/Http/Controllers/EmailHistoryController.php +++ b/app/Http/Controllers/EmailHistoryController.php @@ -34,7 +34,6 @@ class EmailHistoryController extends BaseController ->map(function ($system_log) { if($system_log->log['history'] ?? false) { return $system_log->log['history']; - // return json_decode($system_log->log['history'], true); } }); @@ -60,7 +59,6 @@ class EmailHistoryController extends BaseController ->map(function ($system_log) { if($system_log->log['history'] ?? false) { return $system_log->log['history']; - // return json_decode($system_log->log['history'], true); } }); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 790755168c2f..2eca29cedd34 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -415,7 +415,7 @@ class InvoiceController extends BaseController $invoice->service() ->triggeredActions($request) - ->deletePdf() + // ->deletePdf() ->adjustInventory($old_invoice); event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); @@ -527,7 +527,7 @@ class InvoiceController extends BaseController if ($action == 'bulk_print' && $user->can('view', $invoices->first())) { $paths = $invoices->map(function ($invoice) { - return $invoice->service()->getInvoicePdf(); + return (new \App\Jobs\Entity\CreateRawPdf($invoice->invitations->first(), $invoice->company->db))->handle(); }); $merge = (new PdfMerge($paths->toArray()))->run(); @@ -700,7 +700,7 @@ class InvoiceController extends BaseController } break; case 'cancel': - $invoice = $invoice->service()->handleCancellation()->deletePdf()->save(); + $invoice = $invoice->service()->handleCancellation()->save(); if (! $bulk) { $this->itemResponse($invoice); } diff --git a/app/Http/Controllers/OneTimeTokenController.php b/app/Http/Controllers/OneTimeTokenController.php index b065a50529ac..b51cfcc111bd 100644 --- a/app/Http/Controllers/OneTimeTokenController.php +++ b/app/Http/Controllers/OneTimeTokenController.php @@ -74,7 +74,7 @@ class OneTimeTokenController extends BaseController 'user_id' => $user->id, 'company_key'=> $user->company()->company_key, 'context' => $request->input('context'), - 'is_react' => $request->has('react') && $request->query('react') == 'true' ? true : false, + 'is_react' => $request->request()->hasHeader('X-REACT') ? true : false, ]; Cache::put($hash, $data, 3600); diff --git a/app/Http/Controllers/PurchaseOrderController.php b/app/Http/Controllers/PurchaseOrderController.php index f5eefe0fdc69..4ed383f30870 100644 --- a/app/Http/Controllers/PurchaseOrderController.php +++ b/app/Http/Controllers/PurchaseOrderController.php @@ -139,7 +139,10 @@ class PurchaseOrderController extends BaseController */ public function create(CreatePurchaseOrderRequest $request) { - $purchase_order = PurchaseOrderFactory::create(auth()->user()->company()->id, auth()->user()->id); + /** @var \App\Models\User $user */ + $user = auth()->user(); + + $purchase_order = PurchaseOrderFactory::create($user->company()->id, $user->id); return $this->itemResponse($purchase_order); } @@ -183,7 +186,10 @@ class PurchaseOrderController extends BaseController */ public function store(StorePurchaseOrderRequest $request) { - $purchase_order = $this->purchase_order_repository->save($request->all(), PurchaseOrderFactory::create(auth()->user()->company()->id, auth()->user()->id)); + /** @var \App\Models\User $user */ + $user = auth()->user(); + + $purchase_order = $this->purchase_order_repository->save($request->all(), PurchaseOrderFactory::create($user->company()->id, $user->id)); $purchase_order = $purchase_order->service() ->fillDefaults() @@ -361,7 +367,7 @@ class PurchaseOrderController extends BaseController $purchase_order = $purchase_order->service() ->triggeredActions($request) - ->touchPdf() + // ->touchPdf() ->save(); event(new PurchaseOrderWasUpdated($purchase_order, $purchase_order->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); @@ -475,11 +481,14 @@ class PurchaseOrderController extends BaseController */ public function bulk(BulkPurchaseOrderRequest $request) { + /** @var \App\Models\User $user */ + $user = auth()->user(); + $action = $request->input('action'); $ids = $request->input('ids'); - if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !auth()->user()->company()->account->account_sms_verified) { + if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->company()->account->account_sms_verified) { return response(['message' => 'Please verify your account to send emails.'], 400); } @@ -493,20 +502,20 @@ class PurchaseOrderController extends BaseController * Download Purchase Order/s */ if ($action == 'bulk_download' && $purchase_orders->count() >= 1) { - $purchase_orders->each(function ($purchase_order) { - if (auth()->user()->cannot('view', $purchase_order)) { + $purchase_orders->each(function ($purchase_order) use ($user){ + if ($user->cannot('view', $purchase_order)) { return response()->json(['message' => ctrans('text.access_denied')]); } }); - ZipPurchaseOrders::dispatch($purchase_orders, $purchase_orders->first()->company, auth()->user()); + ZipPurchaseOrders::dispatch($purchase_orders->pluck("id")->toArray(), $purchase_orders->first()->company, auth()->user()); return response()->json(['message' => ctrans('texts.sent_message')], 200); } - if ($action == 'bulk_print' && auth()->user()->can('view', $purchase_orders->first())) { + if ($action == 'bulk_print' && $user->can('view', $purchase_orders->first())) { $paths = $purchase_orders->map(function ($purchase_order) { - return $purchase_order->service()->getPurchaseOrderPdf(); + return (new \App\Jobs\Vendor\CreatePurchaseOrderPdf($purchase_order->invitations->first()))->rawPdf(); }); $merge = (new PdfMerge($paths->toArray()))->run(); @@ -519,8 +528,8 @@ class PurchaseOrderController extends BaseController /* * Send the other actions to the switch */ - $purchase_orders->each(function ($purchase_order, $key) use ($action) { - if (auth()->user()->can('edit', $purchase_order)) { + $purchase_orders->each(function ($purchase_order, $key) use ($action, $user) { + if ($user->can('edit', $purchase_order)) { $this->performAction($purchase_order, $action, true); } }); diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 47eab0e96828..4d06e8bc5ca6 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -395,8 +395,8 @@ class QuoteController extends BaseController $quote = $this->quote_repo->save($request->all(), $quote); $quote->service() - ->triggeredActions($request) - ->deletePdf(); + ->triggeredActions($request); + // ->deletePdf(); event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); @@ -524,16 +524,15 @@ class QuoteController extends BaseController return response(['message' => 'Please verify your account to send emails.'], 400); } - $quotes = Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get(); + $quotes = Quote::query()->with('invitations')->withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get(); if (! $quotes) { return response()->json(['message' => ctrans('texts.quote_not_found')]); } /* - * Download Invoice/s + * Download Quote/s */ - if ($action == 'bulk_download' && $quotes->count() >= 1) { $quotes->each(function ($quote) use($user){ if ($user->cannot('view', $quote)) { @@ -541,7 +540,7 @@ class QuoteController extends BaseController } }); - ZipQuotes::dispatch($quotes, $quotes->first()->company, auth()->user()); + ZipQuotes::dispatch($quotes->pluck('id')->toArray(), $quotes->first()->company, auth()->user()); return response()->json(['message' => ctrans('texts.sent_message')], 200); } @@ -561,7 +560,7 @@ class QuoteController extends BaseController if ($action == 'bulk_print' && $user->can('view', $quotes->first())) { $paths = $quotes->map(function ($quote) { - return $quote->service()->getQuotePdf(); + return (new \App\Jobs\Entity\CreateRawPdf($quote->invitations->first(), $quote->company->db))->handle(); }); $merge = (new PdfMerge($paths->toArray()))->run(); @@ -720,7 +719,6 @@ class QuoteController extends BaseController break; case 'download': - //$file = $quote->pdf_file_path(); $file = $quote->service()->getQuotePdf(); return response()->streamDownload(function () use ($file) { diff --git a/app/Http/Controllers/RecurringInvoiceController.php b/app/Http/Controllers/RecurringInvoiceController.php index 271c6e57df30..d09d31e80220 100644 --- a/app/Http/Controllers/RecurringInvoiceController.php +++ b/app/Http/Controllers/RecurringInvoiceController.php @@ -153,7 +153,10 @@ class RecurringInvoiceController extends BaseController */ public function create(CreateRecurringInvoiceRequest $request) { - $recurring_invoice = RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id); + /** @var \App\Models\User $user */ + $user = auth()->user(); + + $recurring_invoice = RecurringInvoiceFactory::create($user->company()->id, $user->id); return $this->itemResponse($recurring_invoice); } @@ -199,7 +202,10 @@ class RecurringInvoiceController extends BaseController */ public function store(StoreRecurringInvoiceRequest $request) { - $recurring_invoice = $this->recurring_invoice_repo->save($request->all(), RecurringInvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id)); + /** @var \App\Models\User $user */ + $user = auth()->user(); + + $recurring_invoice = $this->recurring_invoice_repo->save($request->all(), RecurringInvoiceFactory::create($user->company()->id, $user->id)); $recurring_invoice->service() ->triggeredActions($request) @@ -380,7 +386,7 @@ class RecurringInvoiceController extends BaseController $recurring_invoice->service() ->triggeredActions($request) - ->deletePdf() + // ->deletePdf() ->save(); event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); @@ -405,18 +411,21 @@ class RecurringInvoiceController extends BaseController */ public function bulk(BulkRecurringInvoiceRequest $request) { + /** @var \App\Models\User $user */ + $user = auth()->user(); + $percentage_increase = request()->has('percentage_increase') ? request()->input('percentage_increase') : 0; if (in_array($request->action, ['increase_prices', 'update_prices'])) { - UpdateRecurring::dispatch($request->ids, auth()->user()->company(), auth()->user(), $request->action, $percentage_increase); + UpdateRecurring::dispatch($request->ids, $user->company(), $user, $request->action, $percentage_increase); return response()->json(['message' => 'Update in progress.'], 200); } $recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids); - $recurring_invoices->each(function ($recurring_invoice, $key) use ($request) { - if (auth()->user()->can('edit', $recurring_invoice)) { + $recurring_invoices->each(function ($recurring_invoice, $key) use ($request, $user) { + if ($user->can('edit', $recurring_invoice)) { $this->performAction($recurring_invoice, $request->action, true); } }); diff --git a/app/Http/Controllers/StripeConnectController.php b/app/Http/Controllers/StripeConnectController.php index d9ab04eccf17..5f8900e6705f 100644 --- a/app/Http/Controllers/StripeConnectController.php +++ b/app/Http/Controllers/StripeConnectController.php @@ -15,11 +15,9 @@ use App\DataMapper\FeesAndLimits; use App\Factory\CompanyGatewayFactory; use App\Http\Requests\StripeConnect\InitializeStripeConnectRequest; use App\Libraries\MultiDB; -use App\Models\Client; use App\Models\Company; use App\Models\CompanyGateway; use App\Models\GatewayType; -use App\PaymentDrivers\Stripe\Jobs\StripeWebhook; use Stripe\Exception\ApiErrorException; class StripeConnectController extends BaseController @@ -124,12 +122,27 @@ class StripeConnectController extends BaseController $company_gateway->setConfig($payload); $company_gateway->save(); + try{ + $stripe = $company_gateway->driver()->init(); + $a = \Stripe\Account::retrieve($response->stripe_user_id, $stripe->stripe_connect_auth); + + if($a->business_name ?? false) { + $company_gateway->label = substr("Stripe - {$a->business_name}", 0, 250); + $company_gateway->save(); + } + } + catch(\Exception $e){ + nlog("could not harvest stripe company name"); + } + + // nlog("Stripe Connect Redirect URI = {$redirect_uri}"); + // StripeWebhook::dispatch($company->company_key, $company_gateway->id); - // if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) { + if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) { $redirect_uri = 'https://app.invoicing.co/#/settings/online_payments'; - // } else { - // $redirect_uri = 'https://invoicing.co/stripe/completed'; - // } + } else { + $redirect_uri = 'https://invoicing.co/stripe/completed'; + } //response here return view('auth.connect.completed', ['url' => $redirect_uri]); diff --git a/app/Http/Controllers/VendorPortal/PurchaseOrderController.php b/app/Http/Controllers/VendorPortal/PurchaseOrderController.php index 775758dc893d..74d66f0542fd 100644 --- a/app/Http/Controllers/VendorPortal/PurchaseOrderController.php +++ b/app/Http/Controllers/VendorPortal/PurchaseOrderController.php @@ -21,7 +21,6 @@ use App\Jobs\Invoice\InjectSignature; use Illuminate\Support\Facades\Cache; use Illuminate\Contracts\View\Factory; use App\Models\PurchaseOrderInvitation; -use Illuminate\Support\Facades\Storage; use App\Events\Misc\InvitationWasViewed; use App\Jobs\Vendor\CreatePurchaseOrderPdf; use App\Events\PurchaseOrder\PurchaseOrderWasViewed; @@ -119,14 +118,8 @@ class PurchaseOrderController extends Controller $file = (new CreatePurchaseOrderPdf($invitation, $invitation->company->db))->rawPdf(); - // $headers = ['Content-Type' => 'application/pdf']; - // $entity_string = $data['entity_type']; - // $file_name = $invitation->{$entity_string}->numberFormatter().'.pdf'; - // return response()->streamDownload(function () use ($file) { - // echo $file; - // }, $file_name, $headers); - $headers = ['Content-Type' => 'application/pdf']; + return response()->make($file, 200, $headers); } @@ -156,7 +149,7 @@ class PurchaseOrderController extends Controller $transformed_ids = $this->transformKeys($request->purchase_orders); if ($request->input('action') == 'download') { - return $this->downloadInvoices((array) $transformed_ids); + return $this->downloadPurchaseOrders((array) $transformed_ids); } elseif ($request->input('action') == 'accept') { return $this->acceptPurchaseOrder($request->all()); } @@ -177,7 +170,8 @@ class PurchaseOrderController extends Controller $purchase_count_query = clone $purchase_orders; $purchase_orders->whereIn('status_id', [PurchaseOrder::STATUS_DRAFT, PurchaseOrder::STATUS_SENT]) - ->cursor()->each(function ($purchase_order) { + ->cursor() + ->each(function ($purchase_order) { $purchase_order->service() ->markSent() @@ -201,39 +195,39 @@ class PurchaseOrderController extends Controller } } - public function downloadInvoices($ids) + public function downloadPurchaseOrders($ids) { - $purchase_orders = PurchaseOrder::query() - ->whereIn('id', $ids) - ->where('vendor_id', auth()->guard('vendor')->user()->vendor_id) + $purchase_order_invitations = PurchaseOrderInvitation::query() + ->with('purchase_order', 'company') + ->whereIn('purchase_order_id', $ids) + ->where('vendor_contact_id', auth()->guard('vendor')->user()->id) ->withTrashed() ->get(); - if (count($purchase_orders) == 0) { + if (count($purchase_order_invitations) == 0) { return back()->with(['message' => ctrans('texts.no_items_selected')]); } - if (count($purchase_orders) == 1) { - $purchase_order = $purchase_orders->first(); - - $file = $purchase_order->service()->getPurchaseOrderPdf(auth()->guard('vendor')->user()); + if (count($purchase_order_invitations) == 1) { + $invitation = $purchase_order_invitations->first(); + $file = (new CreatePurchaseOrderPdf($invitation, $invitation->company->db))->rawPdf(); return response()->streamDownload(function () use ($file) { - echo Storage::get($file); - }, basename($file), ['Content-Type' => 'application/pdf']); + echo $file; + }, $invitation->purchase_order->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']); } - return $this->buildZip($purchase_orders); + return $this->buildZip($purchase_order_invitations); } - private function buildZip($purchase_orders) + private function buildZip($invitations) { // create new archive $zipFile = new \PhpZip\ZipFile(); try { - foreach ($purchase_orders as $purchase_order) { - //add it to the zip - $zipFile->addFromString(basename($purchase_order->pdf_file_path()), file_get_contents($purchase_order->pdf_file_path(null, 'url', true))); + foreach ($invitations as $invitation) { + $file = (new CreatePurchaseOrderPdf($invitation, $invitation->company->db))->rawPdf(); + $zipFile->addFromString($invitation->purchase_order->numberFormatter().".pdf", $file); } $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.purchase_orders')).'.zip'; diff --git a/app/Http/Requests/BankTransactionRule/BulkBankTransactionRuleRequest.php b/app/Http/Requests/BankTransactionRule/BulkBankTransactionRuleRequest.php index 1d5ae4b5b6f4..de6c3044bf52 100644 --- a/app/Http/Requests/BankTransactionRule/BulkBankTransactionRuleRequest.php +++ b/app/Http/Requests/BankTransactionRule/BulkBankTransactionRuleRequest.php @@ -22,7 +22,10 @@ class BulkBankTransactionRuleRequest extends Request */ public function authorize() : bool { - return auth()->user()->isAdmin(); + /** @var \App\Models\User $user */ + $user = auth()->user(); + + return $user->isAdmin(); } public function rules() diff --git a/app/Jobs/Credit/ZipCredits.php b/app/Jobs/Credit/ZipCredits.php index 3b648bd7a2c7..2239fad4f83c 100644 --- a/app/Jobs/Credit/ZipCredits.php +++ b/app/Jobs/Credit/ZipCredits.php @@ -18,6 +18,7 @@ use App\Jobs\Util\UnlinkFile; use App\Libraries\MultiDB; use App\Mail\DownloadCredits; use App\Models\Company; +use App\Models\CreditInvitation; use App\Models\User; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -30,32 +31,12 @@ class ZipCredits implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public $credits; - - private $company; - - private $user; - public $settings; public $tries = 1; - /** - * @param $invoices - * @param Company $company - * @param $email - * @deprecated confirm to be deleted - * Create a new job instance. - */ - public function __construct($credits, Company $company, User $user) + public function __construct(protected array $credit_ids, protected Company $company, protected User $user) { - $this->credits = $credits; - - $this->company = $company; - - $this->user = $user; - - $this->settings = $company->settings; } /** @@ -67,21 +48,18 @@ class ZipCredits implements ShouldQueue { MultiDB::setDb($this->company->db); - // create new zip object + $this->settings = $this->company->settings; $zipFile = new \PhpZip\ZipFile(); - $file_name = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.credits')).'.zip'; - $invitation = $this->credits->first()->invitations->first(); - $path = $this->credits->first()->client->quote_filepath($invitation); + $file_name = now()->addSeconds($this->company->timezone_offset())->format('Y-m-d-h-m-s').'_'.str_replace(' ', '_', trans('texts.credits')).'.zip'; - $this->credits->each(function ($credit) { - (new CreateEntityPdf($credit->invitations()->first()))->handle(); - }); + $invitations = CreditInvitation::query()->with('credit')->whereIn('credit_id', $this->credit_ids)->get(); + $invitation = $invitations->first(); + $path = $invitation->contact->client->credit_filepath($invitation); try { - foreach ($this->credits as $credit) { - $file = $credit->service()->getCreditPdf($credit->invitations()->first()); - $zip_file_name = basename($file); - $zipFile->addFromString($zip_file_name, Storage::get($file)); + foreach ($invitations as $invitation) { + $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $this->company->db))->handle(); + $zipFile->addFromString($invitation->credit->numberFormatter() . '.pdf', $file); } Storage::put($path.$file_name, $zipFile->outputAsString()); diff --git a/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php b/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php index ae545c66626c..00ee4aa39a27 100644 --- a/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php +++ b/app/Jobs/PurchaseOrder/ZipPurchaseOrders.php @@ -18,6 +18,7 @@ use App\Jobs\Vendor\CreatePurchaseOrderPdf; use App\Libraries\MultiDB; use App\Mail\DownloadPurchaseOrders; use App\Models\Company; +use App\Models\PurchaseOrderInvitation; use App\Models\User; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -30,32 +31,12 @@ class ZipPurchaseOrders implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public $purchase_orders; - - private $company; - - private $user; - public $settings; public $tries = 1; - /** - * @param $purchase_orders - * @param Company $company - * @param $email - * @deprecated confirm to be deleted - * Create a new job instance. - */ - public function __construct($purchase_orders, Company $company, User $user) + public function __construct(protected array $purchase_order_ids, protected Company $company, protected User $user) { - $this->purchase_orders = $purchase_orders; - - $this->company = $company; - - $this->user = $user; - - $this->settings = $company->settings; } /** @@ -67,21 +48,23 @@ class ZipPurchaseOrders implements ShouldQueue { MultiDB::setDb($this->company->db); + $this->settings = $this->company->settings; + // create new zip object $zipFile = new \PhpZip\ZipFile(); - $file_name = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.purchase_orders')).'.zip'; - $invitation = $this->purchase_orders->first()->invitations->first(); - $path = $this->purchase_orders->first()->vendor->purchase_order_filepath($invitation); + $file_name = now()->addSeconds($this->company->timezone_offset())->format('Y-m-d-h-m-s').'_'.str_replace(' ', '_', trans('texts.purchase_orders')).'.zip'; - $this->purchase_orders->each(function ($purchase_order) { - (new CreatePurchaseOrderPdf($purchase_order->invitations()->first()))->handle(); - }); + $invitations = PurchaseOrderInvitation::query() + ->with('purchase_order') + ->whereIn('purchase_order_id', $this->purchase_order_ids) + ->get(); + $invitation = $invitations->first(); + $path = $invitation->contact->vendor->purchase_order_filepath($invitation); try { - foreach ($this->purchase_orders as $purchase_order) { - $file = $purchase_order->service()->getPurchaseOrderPdf(); - $zip_file_name = basename($file); - $zipFile->addFromString($zip_file_name, Storage::get($file)); + foreach ($invitations as $invitation) { + $file = (new \App\Jobs\Vendor\CreatePurchaseOrderPdf($invitation))->rawPdf(); + $zipFile->addFromString($invitation->purchase_order->numberFormatter().".pdf", $file); } Storage::put($path.$file_name, $zipFile->outputAsString()); diff --git a/app/Jobs/Quote/ZipQuotes.php b/app/Jobs/Quote/ZipQuotes.php index 14693ac3fc41..b1675b7c0e27 100644 --- a/app/Jobs/Quote/ZipQuotes.php +++ b/app/Jobs/Quote/ZipQuotes.php @@ -11,51 +11,31 @@ namespace App\Jobs\Quote; -use App\Jobs\Entity\CreateEntityPdf; -use App\Jobs\Mail\NinjaMailerJob; -use App\Jobs\Mail\NinjaMailerObject; -use App\Jobs\Util\UnlinkFile; +use App\Models\User; +use App\Models\Company; use App\Libraries\MultiDB; use App\Mail\DownloadQuotes; -use App\Models\Company; -use App\Models\User; +use App\Jobs\Util\UnlinkFile; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Foundation\Bus\Dispatchable; -use Illuminate\Queue\InteractsWithQueue; +use App\Models\QuoteInvitation; +use App\Jobs\Mail\NinjaMailerJob; +use App\Jobs\Mail\NinjaMailerObject; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Storage; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; class ZipQuotes implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public $quotes; - - private $company; - - private $user; - public $settings; public $tries = 1; - /** - * @param $invoices - * @param Company $company - * @param $email - * @deprecated confirm to be deleted - * Create a new job instance. - */ - public function __construct($quotes, Company $company, User $user) + public function __construct(protected array $quote_ids, protected Company $company, protected User $user) { - $this->quotes = $quotes; - - $this->company = $company; - - $this->user = $user; - - $this->settings = $company->settings; } /** @@ -66,27 +46,22 @@ class ZipQuotes implements ShouldQueue public function handle() { MultiDB::setDb($this->company->db); + + $this->settings = $this->company->settings; // create new zip object $zipFile = new \PhpZip\ZipFile(); - $file_name = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip'; - $invitation = $this->quotes->first()->invitations->first(); - $path = $this->quotes->first()->client->quote_filepath($invitation); + $file_name = now()->addSeconds($this->company->timezone_offset())->format('Y-m-d-h-m-s').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip'; - $this->quotes->each(function ($quote) { - $quote->service()->createInvitations(); - - (new CreateEntityPdf($quote->invitations()->first()))->handle(); - }); + $invitations = QuoteInvitation::query()->with('quote')->whereIn('quote_id', $this->quote_ids)->get(); + $invitation = $invitations->first(); + $path = $invitation->contact->client->quote_filepath($invitation); try { - foreach ($this->quotes as $quote) { - $file = $quote->service()->getQuotePdf(); - $zip_file_name = basename($file); - $zipFile->addFromString($zip_file_name, Storage::get($file)); - // $download_file = file_get_contents($quote->pdf_file_path($invitation, 'url', true)); - // $zipFile->addFromString(basename($quote->pdf_file_path($invitation)), $download_file); + foreach ($invitations as $invitation) { + $file = (new \App\Jobs\Entity\CreateRawPdf($invitation, $this->company->db))->handle(); + $zipFile->addFromString($invitation->quote->numberFormatter() . '.pdf', $file); } Storage::put($path.$file_name, $zipFile->outputAsString()); @@ -100,8 +75,9 @@ class ZipQuotes implements ShouldQueue NinjaMailerJob::dispatch($nmo); UnlinkFile::dispatch(config('filesystems.default'), $path.$file_name)->delay(now()->addHours(1)); + } catch (\PhpZip\Exception\ZipException $e) { - // handle exception + nlog("zip build failed: ".$e->getMessage()); } finally { $zipFile->close(); } diff --git a/app/Mail/Engine/CreditEmailEngine.php b/app/Mail/Engine/CreditEmailEngine.php index 09ef15e70abb..6e2191b6594c 100644 --- a/app/Mail/Engine/CreditEmailEngine.php +++ b/app/Mail/Engine/CreditEmailEngine.php @@ -114,11 +114,6 @@ class CreditEmailEngine extends BaseEmailEngine ->setTextBody($text_body); if ($this->client->getSetting('pdf_email_attachment') !== false && $this->credit->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) { - // if (Ninja::isHosted()) { - // $this->setAttachments([$this->credit->pdf_file_path($this->invitation, 'url', true)]); - // } else { - // $this->setAttachments([$this->credit->pdf_file_path($this->invitation)]); - // } $pdf = ((new CreateRawPdf($this->invitation, $this->invitation->company->db))->handle()); diff --git a/app/Models/QuoteInvitation.php b/app/Models/QuoteInvitation.php index a183d3d5b63f..abe0f5668ca6 100644 --- a/app/Models/QuoteInvitation.php +++ b/app/Models/QuoteInvitation.php @@ -87,41 +87,41 @@ class QuoteInvitation extends BaseModel } /** - * @return mixed + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function quote() + public function quote(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Quote::class)->withTrashed(); } /** - * @return mixed + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function entity() + public function entity(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Quote::class)->withTrashed(); } /** - * @return mixed + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function contact() + public function contact(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(ClientContact::class, 'client_contact_id', 'id')->withTrashed(); } /** - * @return mixed + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function user() + public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class)->withTrashed(); } /** - * @return BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function company() + public function company(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Company::class); } diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index 940727d9f917..183578d89342 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -530,9 +530,9 @@ class BaseDriver extends AbstractPaymentDriver $invoices = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->get(); - $invoices->each(function ($invoice) { - $invoice->service()->deletePdf(); - }); + // $invoices->each(function ($invoice) { + // $invoice->service()->deletePdf(); + // }); $invoices->first()->invitations->each(function ($invitation) use ($nmo) { if ((bool) $invitation->contact->send_email !== false && $invitation->contact->email) { @@ -575,9 +575,9 @@ class BaseDriver extends AbstractPaymentDriver $invoices = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->get(); - $invoices->each(function ($invoice) { - $invoice->service()->deletePdf(); - }); + // $invoices->each(function ($invoice) { + // $invoice->service()->deletePdf(); + // }); $invoices->first()->invitations->each(function ($invitation) use ($nmo) { if (! $invitation->contact->trashed()) { diff --git a/app/Services/Bank/BankMatchingService.php b/app/Services/Bank/BankMatchingService.php index 30eb58943e1a..4f88fdc31972 100644 --- a/app/Services/Bank/BankMatchingService.php +++ b/app/Services/Bank/BankMatchingService.php @@ -23,6 +23,7 @@ use Illuminate\Queue\SerializesModels; class BankMatchingService implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + public function __construct(public $company_id, public $db) { } diff --git a/app/Services/Client/EmailHistory.php b/app/Services/Client/EmailHistory.php deleted file mode 100644 index f0715c49b3e3..000000000000 --- a/app/Services/Client/EmailHistory.php +++ /dev/null @@ -1,96 +0,0 @@ - 'Message not found.', - 'status' => '', - 'recipient' => '', - 'type' => '', - 'delivery_message' => '', - 'server' => '', - 'server_ip' => '', - ]; - - public function __construct(public Client $client) - { - } - - public function run(): array - { - // $settings = $this->client->getMergedSettings(); - - // if($settings->email_sending_method == 'default'){ - // $this->postmark_token = config('services.postmark.token'); - // } - // elseif($settings->email_sending_method == 'client_postmark'){ - // $this->postmark_token = $settings->postmark_secret; - // } - // else{ - // return []; - // } - - // $this->postmark = new PostmarkClient($this->postmark_token); - - return SystemLog::query() - ->where('client_id', $this->client->id) - ->where('category_id', SystemLog::CATEGORY_MAIL) - ->orderBy('id','DESC') - ->cursor() - ->map(function ($system_log) { - - if($system_log->log['history'] ?? false){ - return json_decode($system_log->log['history'],true); - } - })->toArray(); - } - - private function fetchMessage(string $message_id): array - { - if(strlen($message_id) < 1){ - return $this->default_response; - } - - try { - - $messageDetail = $this->postmark->getOutboundMessageDetails($message_id); - - return [ - 'subject' => $messageDetail->subject ?? '', - 'status' => $messageDetail->status ?? '', - 'recipient' => $messageDetail->messageevents[0]['Recipient'] ?? '', - 'type' => $messageDetail->messageevents[0]->Type ?? '', - 'delivery_message' => $messageDetail->messageevents[0]->Details->DeliveryMessage ?? '', - 'server' => $messageDetail->messageevents[0]->Details->DestinationServer ?? '', - 'server_ip' => $messageDetail->messageevents[0]->Details->DestinationIP ?? '', - ]; - - } - catch (\Exception $e) { - - return $this->default_response; - - } - } -} \ No newline at end of file diff --git a/app/Services/Credit/ApplyPayment.php b/app/Services/Credit/ApplyPayment.php index 70639ce02001..99a3d9f28729 100644 --- a/app/Services/Credit/ApplyPayment.php +++ b/app/Services/Credit/ApplyPayment.php @@ -137,7 +137,7 @@ class ApplyPayment ->updateBalance($this->amount_applied * -1) ->updatePaidToDate($this->amount_applied) ->updateStatus() - ->deletePdf() + // ->deletePdf() ->save(); $this->credit @@ -147,7 +147,7 @@ class ApplyPayment event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); if ((int) $this->invoice->balance == 0) { - $this->invoice->service()->deletePdf(); + // $this->invoice->service()->deletePdf(); $this->invoice = $this->invoice->fresh(); event(new InvoiceWasPaid($this->invoice, $this->payment, $this->payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); } diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index 648bed322e1c..7b00f0ead97d 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -154,7 +154,7 @@ class CreditService { $this->credit = (new ApplyPayment($this->credit, $invoice, $amount, $payment))->run(); - $this->deletePdf(); + // $this->deletePdf(); return $this; } diff --git a/app/Services/Credit/MarkSent.php b/app/Services/Credit/MarkSent.php index 890f6887c741..ea38f9c43dc9 100644 --- a/app/Services/Credit/MarkSent.php +++ b/app/Services/Credit/MarkSent.php @@ -42,7 +42,7 @@ class MarkSent ->setStatus(Credit::STATUS_SENT) ->applyNumber() ->adjustBalance($this->credit->amount) - ->deletePdf() + // ->deletePdf() ->save(); $this->client diff --git a/app/Services/Invoice/ApplyPayment.php b/app/Services/Invoice/ApplyPayment.php index a0a2fb5f83fd..de4e5791b594 100644 --- a/app/Services/Invoice/ApplyPayment.php +++ b/app/Services/Invoice/ApplyPayment.php @@ -92,7 +92,12 @@ class ApplyPayment extends AbstractService } }); - $this->invoice->service()->applyNumber()->workFlow()->deletePdf()->save(); + $this->invoice + ->service() + ->applyNumber() + ->workFlow() + // ->deletePdf() + ->save(); return $this->invoice; } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 148f0cae88d5..1122683a7735 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -346,7 +346,7 @@ class InvoiceService return $item; })->toArray(); - $this->deletePdf(); + // $this->deletePdf(); $this->deleteEInvoice(); return $this; @@ -414,7 +414,7 @@ class InvoiceService })->toArray(); $this->invoice = $this->invoice->calc()->getInvoice(); - $this->deletePdf(); + // $this->deletePdf(); $this->deleteEInvoice(); /* 24-03-2022 */ diff --git a/app/Services/Invoice/MarkPaid.php b/app/Services/Invoice/MarkPaid.php index 6b2c515a97cb..dd9ef12b552c 100644 --- a/app/Services/Invoice/MarkPaid.php +++ b/app/Services/Invoice/MarkPaid.php @@ -102,7 +102,7 @@ class MarkPaid extends AbstractService $this->invoice ->service() ->applyNumber() - ->deletePdf() + // ->deletePdf() ->save(); $payment->ledger() diff --git a/app/Services/Payment/UpdateInvoicePayment.php b/app/Services/Payment/UpdateInvoicePayment.php index e0e793bd6e2b..10243007fc70 100644 --- a/app/Services/Payment/UpdateInvoicePayment.php +++ b/app/Services/Payment/UpdateInvoicePayment.php @@ -79,7 +79,7 @@ class UpdateInvoicePayment $invoice = $invoice->service() ->clearPartial() ->updateStatus() - ->deletePdf() + // ->deletePdf() ->workFlow() ->save(); diff --git a/app/Services/PdfMaker/PdfMerge.php b/app/Services/PdfMaker/PdfMerge.php index 8f515f63146e..7d320f5cf58e 100644 --- a/app/Services/PdfMaker/PdfMerge.php +++ b/app/Services/PdfMaker/PdfMerge.php @@ -13,12 +13,18 @@ namespace App\Services\PdfMaker; use \setasign\Fpdi\Fpdi; -use Illuminate\Support\Facades\Storage; use setasign\Fpdi\PdfParser\StreamReader; class PdfMerge { - public function __construct(private array $file_paths) + + /** + * __construct + * + * @param array $files + * @return void + */ + public function __construct(private array $files) { } @@ -26,8 +32,8 @@ class PdfMerge { $pdf = new FPDI(); - foreach ($this->file_paths as $file) { - $pageCount = $pdf->setSourceFile(StreamReader::createByString(Storage::get($file))); + foreach ($this->files as $file) { + $pageCount = $pdf->setSourceFile(StreamReader::createByString($file)); for ($i = 0; $i < $pageCount; $i++) { $tpl = $pdf->importPage($i + 1, '/MediaBox'); $pdf->addPage(); diff --git a/app/Services/PurchaseOrder/GetPurchaseOrderPdf.php b/app/Services/PurchaseOrder/GetPurchaseOrderPdf.php index 5735b6eadeed..32dc93f1083e 100644 --- a/app/Services/PurchaseOrder/GetPurchaseOrderPdf.php +++ b/app/Services/PurchaseOrder/GetPurchaseOrderPdf.php @@ -31,7 +31,6 @@ class GetPurchaseOrderPdf extends AbstractService $invitation = $this->purchase_order->invitations()->where('vendor_contact_id', $this->contact->id)->first(); - if (! $invitation) { $invitation = $this->purchase_order->invitations()->first(); } diff --git a/app/Services/PurchaseOrder/TriggeredActions.php b/app/Services/PurchaseOrder/TriggeredActions.php index 38510fc70962..624efc3ac4fd 100644 --- a/app/Services/PurchaseOrder/TriggeredActions.php +++ b/app/Services/PurchaseOrder/TriggeredActions.php @@ -35,12 +35,21 @@ class TriggeredActions extends AbstractService public function run() { if ($this->request->has('send_email') && $this->request->input('send_email') == 'true') { - $this->purchase_order->service()->markSent()->touchPdf()->save(); + $this->purchase_order + ->service() + ->markSent() + // ->touchPdf() + ->save(); + $this->sendEmail(); } if ($this->request->has('mark_sent') && $this->request->input('mark_sent') == 'true') { - $this->purchase_order = $this->purchase_order->service()->markSent()->touchPdf()->save(); + $this->purchase_order = $this->purchase_order + ->service() + ->markSent() + // ->touchPdf() + ->save(); } if ($this->request->has('save_default_footer') && $this->request->input('save_default_footer') == 'true') { diff --git a/app/Services/Quote/MarkSent.php b/app/Services/Quote/MarkSent.php index c6a615efd9a5..263ce043ce20 100644 --- a/app/Services/Quote/MarkSent.php +++ b/app/Services/Quote/MarkSent.php @@ -42,7 +42,7 @@ class MarkSent ->service() ->setStatus(Quote::STATUS_SENT) ->applyNumber() - ->deletePdf() + // ->deletePdf() ->save(); event(new QuoteWasMarkedSent($this->quote, $this->quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); diff --git a/app/Services/Quote/QuoteService.php b/app/Services/Quote/QuoteService.php index 45b38cc0b52b..908cb257c151 100644 --- a/app/Services/Quote/QuoteService.php +++ b/app/Services/Quote/QuoteService.php @@ -116,7 +116,7 @@ class QuoteService $this->invoice ->service() ->markSent() - ->deletePdf() + // ->deletePdf() ->save(); } diff --git a/app/Services/Subscription/SubscriptionService.php b/app/Services/Subscription/SubscriptionService.php index 0b36900c312d..64b13fa38db3 100644 --- a/app/Services/Subscription/SubscriptionService.php +++ b/app/Services/Subscription/SubscriptionService.php @@ -188,7 +188,7 @@ class SubscriptionService //update the invoice and attach to the recurring invoice!!!!! $invoice->recurring_id = $recurring_invoice->id; $invoice->is_proforma = false; - $invoice->service()->deletePdf(); + // $invoice->service()->deletePdf(); $invoice->save(); $contact = $invoice->client->contacts()->whereNotNull('email')->first(); @@ -959,11 +959,17 @@ class SubscriptionService 'date' => now()->format('Y-m-d'), ]; - return $invoice_repo->save($data, $invoice) + $invoice_repo->save($data, $invoice) ->service() ->markSent() ->fillDefaults() ->save(); + + if($invoice->fresh()->balance == 0){ + $invoice->service()->markPaid()->save(); + } + + return $invoice; } diff --git a/app/Utils/Traits/PaymentEmailBuilder.php b/app/Utils/Traits/PaymentEmailBuilder.php deleted file mode 100644 index db1924343c4d..000000000000 --- a/app/Utils/Traits/PaymentEmailBuilder.php +++ /dev/null @@ -1,89 +0,0 @@ -client; - - //Need to determine which email template we are producing - return $this->generateTemplateData($reminder_template, $contact); - } - - private function generateTemplateData(string $reminder_template, $contact) :array - { - $data = []; - - $client = $this->client; - - $body_template = $client->getSetting('email_template_'.$reminder_template); - - /* Use default translations if a custom message has not been set*/ - if (iconv_strlen($body_template) == 0) { - $body_template = trans('texts.payment_message', ['amount'=>$this->present()->amount(), 'account'=>$this->company->present()->name()], null, $this->client->locale()); - } - - $subject_template = $client->getSetting('payment_subject'); - - if (iconv_strlen($subject_template) == 0) { - $subject_template = trans('texts.invoice_subject', ['number'=>$this->present()->invoice_number(), 'account'=>$this->company->present()->name()], null, $this->client->locale()); - } - - $data['body'] = $this->parseTemplate($body_template, false, $contact); - $data['subject'] = $this->parseTemplate($subject_template, true, $contact); - - if ($client->getSetting('pdf_email_attachment') !== false) { - $data['files'][] = $this->pdf_file_path(); - } - - return $data; - } - - private function parseTemplate(string $template_data, bool $is_markdown, $contact) :string - { - //$invoice_variables = $this->makeValues($contact); - - //process variables - //$data = str_replace(array_keys($invoice_variables), array_values($invoice_variables), $template_data); - - $data = strtr($template_data, $invoice_variables); - - //process markdown - if ($is_markdown) { - //$data = Parsedown::instance()->line($data); - - $converter = new CommonMarkConverter([ - 'html_input' => 'strip', - 'allow_unsafe_links' => false, - ]); - - $data = $converter->convert($data); - } - - return $data; - } -} diff --git a/app/Utils/Traits/QuoteEmailBuilder.php b/app/Utils/Traits/QuoteEmailBuilder.php deleted file mode 100644 index 6aa136d815d0..000000000000 --- a/app/Utils/Traits/QuoteEmailBuilder.php +++ /dev/null @@ -1,136 +0,0 @@ -calculateTemplate('quote'); - } - - //Need to determine which email template we are producing - return $this->generateTemplateData($reminder_template, $contact); - } - - private function generateTemplateData(string $reminder_template, $contact) :array - { - $data = []; - - $client = $this->client; - - $body_template = $client->getSetting('email_template_'.$reminder_template); - - /* Use default translations if a custom message has not been set*/ - if (iconv_strlen($body_template) == 0) { - $body_template = trans('texts.quote_message', ['amount'=>$this->present()->amount(), 'account'=>$this->company->present()->name()], null, $this->client->locale()); - } - - $subject_template = $client->getSetting('email_subject_'.$reminder_template); - - if (iconv_strlen($subject_template) == 0) { - if ($reminder_template == 'quote') { - $subject_template = trans('texts.quote_subject', ['number'=>$this->present()->invoice_number(), 'account'=>$this->company->present()->name()], null, $this->client->locale()); - } else { - $subject_template = trans('texts.reminder_subject', ['number'=>$this->present()->invoice_number(), 'account'=>$this->company->present()->name()], null, $this->client->locale()); - } - } - - $data['body'] = $this->parseTemplate($body_template, true, $contact); - $data['subject'] = $this->parseTemplate($subject_template, false, $contact); - - if ($client->getSetting('pdf_email_attachment') !== false) { - $data['files'][] = $this->pdf_file_path(); - } - - return $data; - } - - private function parseTemplate(string $template_data, bool $is_markdown, $contact) :string - { - // $quote_variables = $this->makeValues($contact); - - //process variables -// $data = str_replace(array_keys($quote_variables), array_values($quote_variables), $template_data); - $data = strtr($template_data, $quote_variables); - - //process markdown - if ($is_markdown) { - //$data = Parsedown::instance()->line($data); - - $converter = new CommonMarkConverter([ - 'html_input' => 'allow', - 'allow_unsafe_links' => true, - ]); - - $data = $converter->convert($data); - } - - return $data; - } - - private function calculateTemplate() :string - { - //if invoice is currently a draft, or being marked as sent, this will be the initial email - $client = $this->client; - - //if the invoice - if ($this->status_id == Quote::STATUS_DRAFT || Carbon::parse($this->due_date) > now()) { - return 'quote'; - } elseif ($client->getSetting('enable_reminder1') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder1'), $client->getSetting('num_days_reminder1'))) { - return 'template1'; - } elseif ($client->getSetting('enable_reminder2') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder2'), $client->getSetting('num_days_reminder2'))) { - return 'template2'; - } elseif ($client->getSetting('enable_reminder3') !== false && $this->inReminderWindow($client->getSetting('schedule_reminder3'), $client->getSetting('num_days_reminder3'))) { - return 'template3'; - } else { - return 'quote'; - } - - //also implement endless reminders here - } - - private function inReminderWindow($schedule_reminder, $num_days_reminder) - { - switch ($schedule_reminder) { - case 'after_invoice_date': - return Carbon::parse($this->date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay()); - break; - case 'before_due_date': - return Carbon::parse($this->due_date)->subDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay()); - break; - case 'after_due_date': - return Carbon::parse($this->due_date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay()); - break; - default: - // code... - break; - } - } -} diff --git a/composer.json b/composer.json index 2c157beac4be..ae61a4b6334e 100644 --- a/composer.json +++ b/composer.json @@ -72,7 +72,7 @@ "microsoft/microsoft-graph": "^1.69", "mollie/mollie-api-php": "^2.36", "nelexa/zip": "^4.0", - "nwidart/laravel-modules": "8.3", + "nwidart/laravel-modules": "^10.0", "omnipay/paypal": "^3.0", "payfast/payfast-php-sdk": "^1.1", "pragmarx/google2fa": "^8.0", diff --git a/composer.lock b/composer.lock index 7e653e11e884..fb13b2f575ac 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7c3f126aafc640beb01f58c7047f6e23", + "content-hash": "fe4e98a48b87b1d62a7c93b6f56c57cc", "packages": [ { "name": "adrienrn/php-mimetyper", @@ -2586,16 +2586,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.313.0", + "version": "v0.314.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "e41289c4488563af75bd291972f0fa00949e084a" + "reference": "fe2f7513dc5a4a6cf82715fd0edf7589423d6535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/e41289c4488563af75bd291972f0fa00949e084a", - "reference": "e41289c4488563af75bd291972f0fa00949e084a", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/fe2f7513dc5a4a6cf82715fd0edf7589423d6535", + "reference": "fe2f7513dc5a4a6cf82715fd0edf7589423d6535", "shasum": "" }, "require": { @@ -2624,9 +2624,9 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.313.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.314.0" }, - "time": "2023-08-25T01:10:13+00:00" + "time": "2023-09-03T01:04:12+00:00" }, { "name": "google/auth", @@ -6800,30 +6800,30 @@ }, { "name": "nwidart/laravel-modules", - "version": "v8.3.0", + "version": "v10.0.0", "source": { "type": "git", "url": "https://github.com/nWidart/laravel-modules.git", - "reference": "ee06dc0ac019cc392bd66a1c3e6cec0412fcc52d" + "reference": "35e514f13cb8ae8dce093e9794785fea27319d81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/ee06dc0ac019cc392bd66a1c3e6cec0412fcc52d", - "reference": "ee06dc0ac019cc392bd66a1c3e6cec0412fcc52d", + "url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/35e514f13cb8ae8dce093e9794785fea27319d81", + "reference": "35e514f13cb8ae8dce093e9794785fea27319d81", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "laravel/framework": "^8.0", - "mockery/mockery": "~1.0", - "orchestra/testbench": "^6.2", - "phpstan/phpstan": "^0.12.14", - "phpunit/phpunit": "^8.5", - "spatie/phpunit-snapshot-assertions": "^2.1.0|^4.2" + "friendsofphp/php-cs-fixer": "^3.6", + "laravel/framework": "^10.0", + "mockery/mockery": "^1.5", + "orchestra/testbench": "^8.0", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^10.0", + "spatie/phpunit-snapshot-assertions": "^5.0" }, "type": "library", "extra": { @@ -6836,7 +6836,7 @@ } }, "branch-alias": { - "dev-master": "8.0-dev" + "dev-master": "10.0-dev" } }, "autoload": { @@ -6869,7 +6869,7 @@ ], "support": { "issues": "https://github.com/nWidart/laravel-modules/issues", - "source": "https://github.com/nWidart/laravel-modules/tree/v8.3.0" + "source": "https://github.com/nWidart/laravel-modules/tree/v10.0.0" }, "funding": [ { @@ -6877,7 +6877,7 @@ "type": "github" } ], - "time": "2022-02-10T20:30:19+00:00" + "time": "2023-02-16T11:08:15+00:00" }, { "name": "nyholm/psr7", @@ -15068,16 +15068,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.25.0", + "version": "v3.25.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "9025b7d2b6e1d90a63d0ac0905018ce5d03ec88d" + "reference": "8e21d69801de6b5ecb0dbe0bcdf967b335b1260b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/9025b7d2b6e1d90a63d0ac0905018ce5d03ec88d", - "reference": "9025b7d2b6e1d90a63d0ac0905018ce5d03ec88d", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8e21d69801de6b5ecb0dbe0bcdf967b335b1260b", + "reference": "8e21d69801de6b5ecb0dbe0bcdf967b335b1260b", "shasum": "" }, "require": { @@ -15151,7 +15151,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.25.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.25.1" }, "funding": [ { @@ -15159,7 +15159,7 @@ "type": "github" } ], - "time": "2023-08-31T21:27:18+00:00" + "time": "2023-09-04T01:22:52+00:00" }, { "name": "hamcrest/hamcrest-php", diff --git a/config/ninja.php b/config/ninja.php index 8bf9e3de1475..a530a2dd26d4 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -15,8 +15,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION','5.7.7'), - 'app_tag' => env('APP_TAG','5.7.7'), + 'app_version' => env('APP_VERSION','5.7.8'), + 'app_tag' => env('APP_TAG','5.7.8'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''), diff --git a/lang/en/texts.php b/lang/en/texts.php index b97c5cdf20fc..a5bc8f47feda 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -5160,6 +5160,7 @@ $LANG = array( 'marked_sent_credits' => 'Successfully marked credits sent', 'show_document_preview' => 'Show Document Preview', 'cash_accounting' => 'Cash accounting', + 'click_or_drop_files_here' => 'Click or drop files here', ); return $LANG; diff --git a/resources/views/portal/ninja2020/components/statement-pdf-viewer.blade.php b/resources/views/portal/ninja2020/components/statement-pdf-viewer.blade.php index c40b22e62496..4a03f039f33c 100644 --- a/resources/views/portal/ninja2020/components/statement-pdf-viewer.blade.php +++ b/resources/views/portal/ninja2020/components/statement-pdf-viewer.blade.php @@ -1,16 +1,6 @@ -@php - //$mobile = stripos(request()->server('HTTP_USER_AGENT'), 'Android') || stripos(request()->server('HTTP_USER_AGENT'), 'iPhone') || stripos(request()->server('HTTP_USER_AGENT'), 'iPod') || stripos(request()->server('HTTP_USER_AGENT'), 'iPad'); - $mobile = false; -@endphp - -@push('head') - - -@endpush -
-
+ - {{ ctrans('texts.page') }}: +
-
+ -
-
- -
- -
-@if($mobile) -
- -
-@else - -@endif - - -@if($mobile) - @push('footer') - - @endpush -@endif \ No newline at end of file +