mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
4ff96c0f58
@ -389,8 +389,8 @@ class CheckData extends Command
|
|||||||
$invoice_balance = $client->invoices->where('is_deleted', false)->where('status_id', '>', 1)->sum('balance');
|
$invoice_balance = $client->invoices->where('is_deleted', false)->where('status_id', '>', 1)->sum('balance');
|
||||||
$credit_balance = $client->credits->where('is_deleted', false)->sum('balance');
|
$credit_balance = $client->credits->where('is_deleted', false)->sum('balance');
|
||||||
|
|
||||||
if($client->balance != $invoice_balance)
|
// if($client->balance != $invoice_balance)
|
||||||
$invoice_balance -= $credit_balance;//doesn't make sense to remove the credit amount
|
// $invoice_balance -= $credit_balance;//doesn't make sense to remove the credit amount
|
||||||
|
|
||||||
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
|
$ledger = CompanyLedger::where('client_id', $client->id)->orderBy('id', 'DESC')->first();
|
||||||
|
|
||||||
|
@ -12,8 +12,10 @@
|
|||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Password;
|
use Illuminate\Support\Facades\Password;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
@ -65,4 +67,31 @@ class ContactForgotPasswordController extends Controller
|
|||||||
{
|
{
|
||||||
return Password::broker('contacts');
|
return Password::broker('contacts');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sendResetLinkEmail(Request $request)
|
||||||
|
{
|
||||||
|
//MultiDB::userFindAndSetDb($request->input('email'));
|
||||||
|
|
||||||
|
$user = MultiDB::hasContact(['email' => $request->input('email')]);
|
||||||
|
|
||||||
|
$this->validateEmail($request);
|
||||||
|
|
||||||
|
// We will send the password reset link to this user. Once we have attempted
|
||||||
|
// to send the link, we will examine the response then see the message we
|
||||||
|
// need to show to the user. Finally, we'll send out a proper response.
|
||||||
|
$response = $this->broker()->sendResetLink(
|
||||||
|
$this->credentials($request)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($request->ajax()) {
|
||||||
|
return $response == Password::RESET_LINK_SENT
|
||||||
|
? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
|
||||||
|
: response()->json(['message' => 'Email not found', 'status' => false], 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response == Password::RESET_LINK_SENT
|
||||||
|
? $this->sendResetLinkResponse($request, $response)
|
||||||
|
: $this->sendResetLinkFailedResponse($request, $response);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Http\Controllers\Auth;
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Password;
|
use Illuminate\Support\Facades\Password;
|
||||||
@ -103,6 +104,10 @@ class ForgotPasswordController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function sendResetLinkEmail(Request $request)
|
public function sendResetLinkEmail(Request $request)
|
||||||
{
|
{
|
||||||
|
//MultiDB::userFindAndSetDb($request->input('email'));
|
||||||
|
|
||||||
|
$user = MultiDB::hasUser(['email' => $request->input('email')]);
|
||||||
|
|
||||||
$this->validateEmail($request);
|
$this->validateEmail($request);
|
||||||
|
|
||||||
// We will send the password reset link to this user. Once we have attempted
|
// We will send the password reset link to this user. Once we have attempted
|
||||||
|
@ -21,6 +21,7 @@ use App\Http\Requests\Client\EditClientRequest;
|
|||||||
use App\Http\Requests\Client\ShowClientRequest;
|
use App\Http\Requests\Client\ShowClientRequest;
|
||||||
use App\Http\Requests\Client\StoreClientRequest;
|
use App\Http\Requests\Client\StoreClientRequest;
|
||||||
use App\Http\Requests\Client\UpdateClientRequest;
|
use App\Http\Requests\Client\UpdateClientRequest;
|
||||||
|
use App\Http\Requests\Client\UploadClientRequest;
|
||||||
use App\Jobs\Client\StoreClient;
|
use App\Jobs\Client\StoreClient;
|
||||||
use App\Jobs\Client\UpdateClient;
|
use App\Jobs\Client\UpdateClient;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
@ -29,6 +30,7 @@ use App\Transformers\ClientTransformer;
|
|||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\BulkOptions;
|
use App\Utils\Traits\BulkOptions;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use App\Utils\Traits\Uploadable;
|
use App\Utils\Traits\Uploadable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
@ -42,6 +44,7 @@ class ClientController extends BaseController
|
|||||||
use MakesHash;
|
use MakesHash;
|
||||||
use Uploadable;
|
use Uploadable;
|
||||||
use BulkOptions;
|
use BulkOptions;
|
||||||
|
use SavesDocuments;
|
||||||
|
|
||||||
protected $entity_type = Client::class;
|
protected $entity_type = Client::class;
|
||||||
|
|
||||||
@ -269,6 +272,7 @@ class ClientController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function update(UpdateClientRequest $request, Client $client)
|
public function update(UpdateClientRequest $request, Client $client)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($request->entityIsDeleted($client)) {
|
if ($request->entityIsDeleted($client)) {
|
||||||
return $request->disallowUpdate();
|
return $request->disallowUpdate();
|
||||||
}
|
}
|
||||||
@ -515,4 +519,66 @@ class ClientController extends BaseController
|
|||||||
{
|
{
|
||||||
//todo
|
//todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param UploadClientRequest $request
|
||||||
|
* @param Client $client
|
||||||
|
* @return Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/clients/{id}/upload",
|
||||||
|
* operationId="uploadClient",
|
||||||
|
* tags={"clients"},
|
||||||
|
* summary="Uploads a document to a client",
|
||||||
|
* description="Handles the uploading of a document to a client",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Client Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the client object",
|
||||||
|
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Client"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function upload(UploadClientRequest $request, Client $client)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($request->has('documents'))
|
||||||
|
$this->saveDocuments($request->file('documents'), $client);
|
||||||
|
|
||||||
|
return $this->itemResponse($client->fresh());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,15 @@ namespace App\Http\Controllers\ClientPortal;
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\ClientPortal\ShowRecurringInvoiceRequest;
|
use App\Http\Requests\ClientPortal\ShowRecurringInvoiceRequest;
|
||||||
|
use App\Jobs\Mail\NinjaMailer;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
|
use App\Mail\RecurringInvoice\ClientContactRequestCancellationObject;
|
||||||
use App\Models\RecurringInvoice;
|
use App\Models\RecurringInvoice;
|
||||||
use App\Notifications\ClientContactRequestCancellation;
|
use App\Notifications\ClientContactRequestCancellation;
|
||||||
use App\Utils\Traits\MakesDates;
|
use App\Utils\Traits\MakesDates;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\Notifications\UserNotifies;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
@ -28,6 +33,7 @@ class RecurringInvoiceController extends Controller
|
|||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
use MakesDates;
|
use MakesDates;
|
||||||
|
use UserNotifies;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the list of recurring invoices.
|
* Show the list of recurring invoices.
|
||||||
@ -57,7 +63,22 @@ class RecurringInvoiceController extends Controller
|
|||||||
{
|
{
|
||||||
//todo double check the user is able to request a cancellation
|
//todo double check the user is able to request a cancellation
|
||||||
//can add locale specific by chaining ->locale();
|
//can add locale specific by chaining ->locale();
|
||||||
$recurring_invoice->user->notify(new ClientContactRequestCancellation($recurring_invoice, auth()->user()));
|
|
||||||
|
$nmo = new NinjaMailerObject;
|
||||||
|
$nmo->mailable = (new NinjaMailer((new ClientContactRequestCancellationObject($recurring_invoice, auth()->user()))->build()));
|
||||||
|
$nmo->company = $recurring_invoice->company;
|
||||||
|
$nmo->settings = $recurring_invoice->company->settings;
|
||||||
|
|
||||||
|
$notifiable_users = $this->filterUsersByPermissions($recurring_invoice->company->company_users, $recurring_invoice, ['recurring_cancellation']);
|
||||||
|
|
||||||
|
$notifiable_users->each(function ($company_user) use($nmo){
|
||||||
|
|
||||||
|
$nmo->to_user = $company_user->user;
|
||||||
|
NinjaMailerJob::dispatch($nmo);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//$recurring_invoice->user->notify(new ClientContactRequestCancellation($recurring_invoice, auth()->user()));
|
||||||
|
|
||||||
return $this->render('recurring_invoices.cancellation.index', [
|
return $this->render('recurring_invoices.cancellation.index', [
|
||||||
'invoice' => $recurring_invoice,
|
'invoice' => $recurring_invoice,
|
||||||
|
@ -20,6 +20,7 @@ use App\Http\Requests\Company\EditCompanyRequest;
|
|||||||
use App\Http\Requests\Company\ShowCompanyRequest;
|
use App\Http\Requests\Company\ShowCompanyRequest;
|
||||||
use App\Http\Requests\Company\StoreCompanyRequest;
|
use App\Http\Requests\Company\StoreCompanyRequest;
|
||||||
use App\Http\Requests\Company\UpdateCompanyRequest;
|
use App\Http\Requests\Company\UpdateCompanyRequest;
|
||||||
|
use App\Http\Requests\Company\UploadCompanyRequest;
|
||||||
use App\Jobs\Company\CreateCompany;
|
use App\Jobs\Company\CreateCompany;
|
||||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||||
@ -503,4 +504,65 @@ class CompanyController extends BaseController
|
|||||||
|
|
||||||
return response()->json(['message' => ctrans('texts.success')], 200);
|
return response()->json(['message' => ctrans('texts.success')], 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param UploadCompanyRequest $request
|
||||||
|
* @param Company $client
|
||||||
|
* @return Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/companies/{id}/upload",
|
||||||
|
* operationId="uploadCompanies",
|
||||||
|
* tags={"companies"},
|
||||||
|
* summary="Uploads a document to a company",
|
||||||
|
* description="Handles the uploading of a document to a company",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Company Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the client object",
|
||||||
|
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Company"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function upload(UploadCompanyRequest $request, Company $company)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($request->has('documents'))
|
||||||
|
$this->saveDocuments($request->file('documents'), $company);
|
||||||
|
|
||||||
|
return $this->itemResponse($company->fresh());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ use App\Http\Requests\Credit\EditCreditRequest;
|
|||||||
use App\Http\Requests\Credit\ShowCreditRequest;
|
use App\Http\Requests\Credit\ShowCreditRequest;
|
||||||
use App\Http\Requests\Credit\StoreCreditRequest;
|
use App\Http\Requests\Credit\StoreCreditRequest;
|
||||||
use App\Http\Requests\Credit\UpdateCreditRequest;
|
use App\Http\Requests\Credit\UpdateCreditRequest;
|
||||||
|
use App\Http\Requests\Credit\UploadCreditRequest;
|
||||||
use App\Jobs\Entity\EmailEntity;
|
use App\Jobs\Entity\EmailEntity;
|
||||||
use App\Jobs\Invoice\EmailCredit;
|
use App\Jobs\Invoice\EmailCredit;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
@ -24,6 +25,7 @@ use App\Transformers\CreditTransformer;
|
|||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\TempFile;
|
use App\Utils\TempFile;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,7 +34,8 @@ use Illuminate\Http\Response;
|
|||||||
class CreditController extends BaseController
|
class CreditController extends BaseController
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
use SavesDocuments;
|
||||||
|
|
||||||
protected $entity_type = Credit::class;
|
protected $entity_type = Credit::class;
|
||||||
|
|
||||||
protected $entity_transformer = CreditTransformer::class;
|
protected $entity_transformer = CreditTransformer::class;
|
||||||
@ -56,7 +59,7 @@ class CreditController extends BaseController
|
|||||||
* @OA\Get(
|
* @OA\Get(
|
||||||
* path="/api/v1/credits",
|
* path="/api/v1/credits",
|
||||||
* operationId="getCredits",
|
* operationId="getCredits",
|
||||||
* tags={"invoices"},
|
* tags={"credits"},
|
||||||
* summary="Gets a list of credits",
|
* summary="Gets a list of credits",
|
||||||
* description="Lists credits, search and filters allow fine grained lists to be generated.
|
* description="Lists credits, search and filters allow fine grained lists to be generated.
|
||||||
*
|
*
|
||||||
@ -576,4 +579,66 @@ class CreditController extends BaseController
|
|||||||
|
|
||||||
return response()->download($file_path);
|
return response()->download($file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param UploadCreditRequest $request
|
||||||
|
* @param Credit $client
|
||||||
|
* @return Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/credits/{id}/upload",
|
||||||
|
* operationId="uploadCredits",
|
||||||
|
* tags={"credits"},
|
||||||
|
* summary="Uploads a document to a credit",
|
||||||
|
* description="Handles the uploading of a document to a credit",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Credit Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the Credit object",
|
||||||
|
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Credit"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function upload(UploadCreditRequest $request, Credit $credit)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($request->has('documents'))
|
||||||
|
$this->saveDocuments($request->file('documents'), $credit);
|
||||||
|
|
||||||
|
return $this->itemResponse($credit->fresh());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,14 @@ use App\Http\Requests\Expense\EditExpenseRequest;
|
|||||||
use App\Http\Requests\Expense\ShowExpenseRequest;
|
use App\Http\Requests\Expense\ShowExpenseRequest;
|
||||||
use App\Http\Requests\Expense\StoreExpenseRequest;
|
use App\Http\Requests\Expense\StoreExpenseRequest;
|
||||||
use App\Http\Requests\Expense\UpdateExpenseRequest;
|
use App\Http\Requests\Expense\UpdateExpenseRequest;
|
||||||
|
use App\Http\Requests\Expense\UploadExpenseRequest;
|
||||||
use App\Models\Expense;
|
use App\Models\Expense;
|
||||||
use App\Repositories\ExpenseRepository;
|
use App\Repositories\ExpenseRepository;
|
||||||
use App\Transformers\ExpenseTransformer;
|
use App\Transformers\ExpenseTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\BulkOptions;
|
use App\Utils\Traits\BulkOptions;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use App\Utils\Traits\Uploadable;
|
use App\Utils\Traits\Uploadable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
@ -40,7 +42,8 @@ class ExpenseController extends BaseController
|
|||||||
use MakesHash;
|
use MakesHash;
|
||||||
use Uploadable;
|
use Uploadable;
|
||||||
use BulkOptions;
|
use BulkOptions;
|
||||||
|
use SavesDocuments;
|
||||||
|
|
||||||
protected $entity_type = Expense::class;
|
protected $entity_type = Expense::class;
|
||||||
|
|
||||||
protected $entity_transformer = ExpenseTransformer::class;
|
protected $entity_transformer = ExpenseTransformer::class;
|
||||||
@ -507,4 +510,65 @@ class ExpenseController extends BaseController
|
|||||||
{
|
{
|
||||||
//todo
|
//todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param UploadExpenseRequest $request
|
||||||
|
* @param Expense $expense
|
||||||
|
* @return Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/expenses/{id}/upload",
|
||||||
|
* operationId="uploadExpense",
|
||||||
|
* tags={"expense"},
|
||||||
|
* summary="Uploads a document to a expense",
|
||||||
|
* description="Handles the uploading of a document to a expense",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Expense Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the Expense object",
|
||||||
|
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Expense"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function upload(UploadExpenseRequest $request, Expense $expense)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($request->has('documents'))
|
||||||
|
$this->saveDocuments($request->file('documents'), $expense);
|
||||||
|
|
||||||
|
return $this->itemResponse($expense->fresh());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ use App\Http\Requests\Invoice\EditInvoiceRequest;
|
|||||||
use App\Http\Requests\Invoice\ShowInvoiceRequest;
|
use App\Http\Requests\Invoice\ShowInvoiceRequest;
|
||||||
use App\Http\Requests\Invoice\StoreInvoiceRequest;
|
use App\Http\Requests\Invoice\StoreInvoiceRequest;
|
||||||
use App\Http\Requests\Invoice\UpdateInvoiceRequest;
|
use App\Http\Requests\Invoice\UpdateInvoiceRequest;
|
||||||
|
use App\Http\Requests\Invoice\UploadInvoiceRequest;
|
||||||
use App\Jobs\Entity\EmailEntity;
|
use App\Jobs\Entity\EmailEntity;
|
||||||
use App\Jobs\Invoice\StoreInvoice;
|
use App\Jobs\Invoice\StoreInvoice;
|
||||||
use App\Jobs\Invoice\ZipInvoices;
|
use App\Jobs\Invoice\ZipInvoices;
|
||||||
@ -38,6 +39,7 @@ use App\Transformers\QuoteTransformer;
|
|||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\TempFile;
|
use App\Utils\TempFile;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Illuminate\Support\Facades\File;
|
use Illuminate\Support\Facades\File;
|
||||||
@ -49,7 +51,8 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
class InvoiceController extends BaseController
|
class InvoiceController extends BaseController
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
use SavesDocuments;
|
||||||
|
|
||||||
protected $entity_type = Invoice::class;
|
protected $entity_type = Invoice::class;
|
||||||
|
|
||||||
protected $entity_transformer = InvoiceTransformer::class;
|
protected $entity_transformer = InvoiceTransformer::class;
|
||||||
@ -393,8 +396,6 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
$invoice = $this->invoice_repo->save($request->all(), $invoice);
|
$invoice = $this->invoice_repo->save($request->all(), $invoice);
|
||||||
|
|
||||||
UnlinkFile::dispatchNow(config('filesystems.default'), $invoice->client->invoice_filepath().$invoice->number.'.pdf');
|
|
||||||
|
|
||||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars()));
|
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars()));
|
||||||
|
|
||||||
return $this->itemResponse($invoice);
|
return $this->itemResponse($invoice);
|
||||||
@ -851,4 +852,65 @@ class InvoiceController extends BaseController
|
|||||||
return response(['message' => 'Oops, something went wrong. Make sure you have symlink to storage/ in public/ directory.'], 500);
|
return response(['message' => 'Oops, something went wrong. Make sure you have symlink to storage/ in public/ directory.'], 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param UploadInvoiceRequest $request
|
||||||
|
* @param Invoice $invoice
|
||||||
|
* @return Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/invoices/{id}/upload",
|
||||||
|
* operationId="uploadInvoice",
|
||||||
|
* tags={"invoices"},
|
||||||
|
* summary="Uploads a document to a invoice",
|
||||||
|
* description="Handles the uploading of a document to a invoice",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Invoice Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the Invoice object",
|
||||||
|
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Invoice"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function upload(UploadInvoiceRequest $request, Invoice $invoice)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($request->has('documents'))
|
||||||
|
$this->saveDocuments($request->file('documents'), $invoice);
|
||||||
|
|
||||||
|
return $this->itemResponse($invoice->fresh());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
39
app/Http/Requests/Client/UploadClientRequest.php
Normal file
39
app/Http/Requests/Client/UploadClientRequest.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Client;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
|
||||||
|
class UploadClientRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
if($this->input('documents'))
|
||||||
|
$rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000';
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
39
app/Http/Requests/Company/UploadCompanyRequest.php
Normal file
39
app/Http/Requests/Company/UploadCompanyRequest.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Company;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
|
||||||
|
class UploadCompanyRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->company);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
if($this->input('documents'))
|
||||||
|
$rules['documents'] = 'file|mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:20000';
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
39
app/Http/Requests/Credit/UploadCreditRequest.php
Normal file
39
app/Http/Requests/Credit/UploadCreditRequest.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Credit;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
|
||||||
|
class UploadCreditRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->credit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
if($this->input('documents'))
|
||||||
|
$rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000';
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
39
app/Http/Requests/Expense/UploadExpenseRequest.php
Normal file
39
app/Http/Requests/Expense/UploadExpenseRequest.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Expense;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
|
||||||
|
class UploadExpenseRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->expense);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
if($this->input('documents'))
|
||||||
|
$rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000';
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
39
app/Http/Requests/Invoice/UploadInvoiceRequest.php
Normal file
39
app/Http/Requests/Invoice/UploadInvoiceRequest.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Invoice;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
|
||||||
|
class UploadInvoiceRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->invoice);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
if($this->input('documents'))
|
||||||
|
$rules['documents'] = 'file|mimes:html,csv,png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000';
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -17,8 +17,12 @@ use App\Jobs\Company\CreateCompany;
|
|||||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||||
use App\Jobs\Company\CreateCompanyToken;
|
use App\Jobs\Company\CreateCompanyToken;
|
||||||
|
use App\Jobs\Mail\NinjaMailer;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
use App\Jobs\User\CreateUser;
|
use App\Jobs\User\CreateUser;
|
||||||
use App\Jobs\Util\VersionCheck;
|
use App\Jobs\Util\VersionCheck;
|
||||||
|
use App\Mail\Admin\AccountCreatedObject;
|
||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Notifications\Ninja\NewAccountCreated;
|
use App\Notifications\Ninja\NewAccountCreated;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
@ -88,7 +92,16 @@ class CreateAccount
|
|||||||
|
|
||||||
$spaa9f78->fresh();
|
$spaa9f78->fresh();
|
||||||
|
|
||||||
$sp035a66->notification(new NewAccountCreated($spaa9f78, $sp035a66))->ninja();
|
//todo implement SLACK notifications
|
||||||
|
//$sp035a66->notification(new NewAccountCreated($spaa9f78, $sp035a66))->ninja();
|
||||||
|
|
||||||
|
$nmo = new NinjaMailerObject;
|
||||||
|
$nmo->mailable = new NinjaMailer((new AccountCreatedObject($spaa9f78, $sp035a66))->build());
|
||||||
|
$nmo->company = $sp035a66;
|
||||||
|
$nmo->to_user = $spaa9f78;
|
||||||
|
$nmo->settings = $sp035a66->settings;
|
||||||
|
|
||||||
|
NinjaMailerJob::dispatchNow($nmo);
|
||||||
|
|
||||||
VersionCheck::dispatchNow();
|
VersionCheck::dispatchNow();
|
||||||
|
|
||||||
|
@ -29,7 +29,10 @@ use Illuminate\Support\Facades\Config;
|
|||||||
use Illuminate\Support\Facades\Lang;
|
use Illuminate\Support\Facades\Lang;
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
|
||||||
/*Multi Mailer implemented*/
|
/*
|
||||||
|
Multi Mailer implemented
|
||||||
|
@Deprecated 14/02/2021
|
||||||
|
*/
|
||||||
|
|
||||||
class BaseMailerJob implements ShouldQueue
|
class BaseMailerJob implements ShouldQueue
|
||||||
{
|
{
|
||||||
|
46
app/Jobs/Mail/NinjaMailer.php
Normal file
46
app/Jobs/Mail/NinjaMailer.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Jobs\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
|
||||||
|
class NinjaMailer extends Mailable
|
||||||
|
{
|
||||||
|
public $mail_obj;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @param $mail_obj
|
||||||
|
*/
|
||||||
|
public function __construct($mail_obj)
|
||||||
|
{
|
||||||
|
$this->mail_obj = $mail_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||||
|
->subject($this->mail_obj->subject)
|
||||||
|
->markdown($this->mail_obj->markdown, $this->mail_obj->data)
|
||||||
|
->withSwiftMessage(function ($message) {
|
||||||
|
$message->getHeaders()->addTextHeader('Tag', $this->mail_obj->tag);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
155
app/Jobs/Mail/NinjaMailerJob.php
Normal file
155
app/Jobs/Mail/NinjaMailerJob.php
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Jobs\Mail;
|
||||||
|
|
||||||
|
use App\DataMapper\Analytics\EmailFailure;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
|
use App\Libraries\Google\Google;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\SystemLog;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Providers\MailServiceProvider;
|
||||||
|
use App\Utils\Ninja;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\Lang;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
|
||||||
|
/*Multi Mailer implemented*/
|
||||||
|
|
||||||
|
class NinjaMailerJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash;
|
||||||
|
|
||||||
|
public $tries = 5; //number of retries
|
||||||
|
|
||||||
|
public $backoff = 5; //seconds to wait until retry
|
||||||
|
|
||||||
|
public $deleteWhenMissingModels = true;
|
||||||
|
|
||||||
|
public $nmo;
|
||||||
|
|
||||||
|
public function __construct(NinjaMailerObject $nmo)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->nmo = $nmo;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
/*If we are migrating data we don't want to fire any emails*/
|
||||||
|
if ($this->nmo->company->is_disabled)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
MultiDB::setDb($this->nmo->company->db);
|
||||||
|
|
||||||
|
//if we need to set an email driver do it now
|
||||||
|
$this->setMailDriver();
|
||||||
|
|
||||||
|
//send email
|
||||||
|
try {
|
||||||
|
nlog("trying to send");
|
||||||
|
Mail::to($this->nmo->to_user->email)
|
||||||
|
->send($this->nmo->mailable);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
//$this->failed($e);
|
||||||
|
nlog("error failed with {$e->getMessage()}");
|
||||||
|
if ($this->nmo->to_user instanceof ClientContact) {
|
||||||
|
$this->logMailError($e->getMessage(), $this->nmo->to_user->client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setMailDriver()
|
||||||
|
{
|
||||||
|
/* Singletons need to be rebooted each time just in case our Locale is changing*/
|
||||||
|
App::forgetInstance('translator');
|
||||||
|
App::forgetInstance('mail.manager'); //singletons must be destroyed!
|
||||||
|
|
||||||
|
/* Inject custom translations if any exist */
|
||||||
|
Lang::replace(Ninja::transformTranslations($this->nmo->settings));
|
||||||
|
|
||||||
|
switch ($this->nmo->settings->email_sending_method) {
|
||||||
|
case 'default':
|
||||||
|
break;
|
||||||
|
case 'gmail':
|
||||||
|
$this->setGmailMailer();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setGmailMailer()
|
||||||
|
{
|
||||||
|
$sending_user = $this->settings->gmail_sending_user_id;
|
||||||
|
|
||||||
|
$user = User::find($this->decodePrimaryKey($sending_user));
|
||||||
|
|
||||||
|
$google = (new Google())->init();
|
||||||
|
$google->getClient()->setAccessToken(json_encode($user->oauth_user_token));
|
||||||
|
|
||||||
|
if ($google->getClient()->isAccessTokenExpired()) {
|
||||||
|
$google->refreshToken($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that our token is refreshed and valid we can boot the
|
||||||
|
* mail driver at runtime and also set the token which will persist
|
||||||
|
* just for this request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
config(['mail.driver' => 'gmail']);
|
||||||
|
config(['services.gmail.token' => $user->oauth_user_token->access_token]);
|
||||||
|
config(['mail.from.address' => $user->email]);
|
||||||
|
config(['mail.from.name' => $user->present()->name()]);
|
||||||
|
|
||||||
|
//(new MailServiceProvider(app()))->register();
|
||||||
|
|
||||||
|
nlog("after registering mail service provider");
|
||||||
|
nlog(config('services.gmail.token'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function logMailError($errors, $recipient_object)
|
||||||
|
{
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$errors,
|
||||||
|
SystemLog::CATEGORY_MAIL,
|
||||||
|
SystemLog::EVENT_MAIL_SEND,
|
||||||
|
SystemLog::TYPE_FAILURE,
|
||||||
|
$recipient_object
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function failed($exception = null)
|
||||||
|
{
|
||||||
|
nlog('mailer job failed');
|
||||||
|
nlog($exception->getMessage());
|
||||||
|
|
||||||
|
$job_failure = new EmailFailure();
|
||||||
|
$job_failure->string_metric5 = get_parent_class($this);
|
||||||
|
$job_failure->string_metric6 = $exception->getMessage();
|
||||||
|
|
||||||
|
LightLogs::create($job_failure)
|
||||||
|
->batch();
|
||||||
|
}
|
||||||
|
}
|
32
app/Jobs/Mail/NinjaMailerObject.php
Normal file
32
app/Jobs/Mail/NinjaMailerObject.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Jobs\Mail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NinjaMailerObject.
|
||||||
|
*/
|
||||||
|
class NinjaMailerObject
|
||||||
|
{
|
||||||
|
|
||||||
|
public $mailable;
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
|
||||||
|
public $from_user; //not yet used
|
||||||
|
|
||||||
|
public $to_user;
|
||||||
|
|
||||||
|
public $settings;
|
||||||
|
|
||||||
|
public $transport; //not yet used
|
||||||
|
|
||||||
|
}
|
@ -11,9 +11,12 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Mail;
|
namespace App\Jobs\Mail;
|
||||||
|
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Mail\Admin\EntityNotificationMailer;
|
use App\Mail\Admin\EntityNotificationMailer;
|
||||||
use App\Mail\Admin\PaymentFailureObject;
|
use App\Mail\Admin\PaymentFailureObject;
|
||||||
|
use App\Mail\NinjaMailer;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Utils\Traits\Notifications\UserNotifies;
|
use App\Utils\Traits\Notifications\UserNotifies;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
@ -70,17 +73,9 @@ class PaymentFailureMailer extends BaseMailerJob implements ShouldQueue
|
|||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
|
||||||
/*If we are migrating data we don't want to fire these notification*/
|
|
||||||
if ($this->company->is_disabled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set DB
|
//Set DB
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
|
|
||||||
//if we need to set an email driver do it now
|
|
||||||
$this->setMailDriver();
|
|
||||||
|
|
||||||
//iterate through company_users
|
//iterate through company_users
|
||||||
$this->company->company_users->each(function ($company_user) {
|
$this->company->company_users->each(function ($company_user) {
|
||||||
|
|
||||||
@ -93,16 +88,15 @@ class PaymentFailureMailer extends BaseMailerJob implements ShouldQueue
|
|||||||
unset($methods[$key]);
|
unset($methods[$key]);
|
||||||
|
|
||||||
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $this->payment_hash))->build();
|
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $this->payment_hash))->build();
|
||||||
$mail_obj->from = [config('mail.from.address'), config('mail.from.name')];
|
|
||||||
|
|
||||||
//send email
|
$nmo = new NinjaMailerObject;
|
||||||
try {
|
$nmo->mailable = new NinjaMailer($mail_obj);
|
||||||
Mail::to($company_user->user->email)
|
$nmo->company = $this->company;
|
||||||
->send(new EntityNotificationMailer($mail_obj));
|
$nmo->to_user = $company_user->user;
|
||||||
} catch (\Exception $e) {
|
$nmo->settings = $this->settings;
|
||||||
//$this->failed($e);
|
|
||||||
$this->logMailError($e->getMessage(), $this->client);
|
NinjaMailerJob::dispatch($nmo);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ use App\Http\ValidationRules\ValidUserForCompany;
|
|||||||
use App\Jobs\Company\CreateCompanyToken;
|
use App\Jobs\Company\CreateCompanyToken;
|
||||||
use App\Jobs\Ninja\CheckCompanyData;
|
use App\Jobs\Ninja\CheckCompanyData;
|
||||||
use App\Jobs\Ninja\CompanySizeCheck;
|
use App\Jobs\Ninja\CompanySizeCheck;
|
||||||
|
use App\Jobs\Util\VersionCheck;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Mail\MigrationCompleted;
|
use App\Mail\MigrationCompleted;
|
||||||
use App\Models\Activity;
|
use App\Models\Activity;
|
||||||
@ -81,10 +82,10 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
|||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
class Import implements ShouldQueue
|
class Import implements ShouldQueue
|
||||||
{
|
{
|
||||||
@ -226,15 +227,22 @@ class Import implements ShouldQueue
|
|||||||
private function setInitialCompanyLedgerBalances()
|
private function setInitialCompanyLedgerBalances()
|
||||||
{
|
{
|
||||||
Client::cursor()->each(function ($client) {
|
Client::cursor()->each(function ($client) {
|
||||||
|
|
||||||
|
$invoice_balances = $client->invoices->where('is_deleted', false)->where('status_id', '>', 1)->sum('balance');
|
||||||
|
|
||||||
$company_ledger = CompanyLedgerFactory::create($client->company_id, $client->user_id);
|
$company_ledger = CompanyLedgerFactory::create($client->company_id, $client->user_id);
|
||||||
$company_ledger->client_id = $client->id;
|
$company_ledger->client_id = $client->id;
|
||||||
$company_ledger->adjustment = $client->balance;
|
$company_ledger->adjustment = $invoice_balances;
|
||||||
$company_ledger->notes = 'Migrated Client Balance';
|
$company_ledger->notes = 'Migrated Client Balance';
|
||||||
$company_ledger->balance = $client->balance;
|
$company_ledger->balance = $invoice_balances;
|
||||||
$company_ledger->activity_id = Activity::CREATE_CLIENT;
|
$company_ledger->activity_id = Activity::CREATE_CLIENT;
|
||||||
$company_ledger->save();
|
$company_ledger->save();
|
||||||
|
|
||||||
$client->company_ledger()->save($company_ledger);
|
$client->company_ledger()->save($company_ledger);
|
||||||
|
|
||||||
|
$client->balance = $invoice_balances;
|
||||||
|
$client->save();
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,10 +1037,36 @@ class Import implements ShouldQueue
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('invoice_id', $resource) && $resource['invoice_id'] && array_key_exists('invoices', $this->ids)) {
|
if (array_key_exists('invoice_id', $resource) && $resource['invoice_id'] && array_key_exists('invoices', $this->ids)) {
|
||||||
$invoice_id = $this->transformId('invoices', $resource['invoice_id']);
|
|
||||||
$entity = Invoice::where('id', $invoice_id)->withTrashed()->first();
|
$try_quote = false;
|
||||||
|
$exception = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
$invoice_id = $this->transformId('invoices', $resource['invoice_id']);
|
||||||
|
$entity = Invoice::where('id', $invoice_id)->withTrashed()->first();
|
||||||
|
}
|
||||||
|
catch(\Exception $e){
|
||||||
|
nlog("i couldn't find the invoice document {$resource['invoice_id']}, perhaps it is a quote?");
|
||||||
|
nlog($e->getMessage());
|
||||||
|
|
||||||
|
$try_quote = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($try_quote && array_key_exists('quotes', $this->ids) ) {
|
||||||
|
|
||||||
|
$quote_id = $this->transformId('quotes', $resource['invoice_id']);
|
||||||
|
$entity = Quote::where('id', $quote_id)->withTrashed()->first();
|
||||||
|
$exception = $e;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$entity)
|
||||||
|
throw new Exception("Resource invoice/quote document not available.");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (array_key_exists('expense_id', $resource) && $resource['expense_id'] && array_key_exists('expenses', $this->ids)) {
|
if (array_key_exists('expense_id', $resource) && $resource['expense_id'] && array_key_exists('expenses', $this->ids)) {
|
||||||
$expense_id = $this->transformId('expenses', $resource['expense_id']);
|
$expense_id = $this->transformId('expenses', $resource['expense_id']);
|
||||||
$entity = Expense::where('id', $expense_id)->withTrashed()->first();
|
$entity = Expense::where('id', $expense_id)->withTrashed()->first();
|
||||||
|
@ -78,7 +78,7 @@ class UploadFile implements ShouldQueue
|
|||||||
$instance = Storage::disk($this->disk)->putFileAs(
|
$instance = Storage::disk($this->disk)->putFileAs(
|
||||||
$path,
|
$path,
|
||||||
$this->file,
|
$this->file,
|
||||||
$this->file->hashName()
|
$this->file->hashName()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (in_array($this->file->extension(), ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'psd'])) {
|
if (in_array($this->file->extension(), ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'psd'])) {
|
||||||
|
@ -142,6 +142,31 @@ class MultiDB
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return User|null
|
||||||
|
*/
|
||||||
|
public static function hasContact(array $data) : ?ClientContact
|
||||||
|
{
|
||||||
|
if (! config('ninja.db.multi_db_enabled')) {
|
||||||
|
return ClientContact::where($data)->withTrashed()->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (self::$dbs as $db) {
|
||||||
|
self::setDB($db);
|
||||||
|
|
||||||
|
$user = ClientContacts::where($data)->withTrashed()->first();
|
||||||
|
|
||||||
|
if ($user) {
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self::setDefaultDatabase();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static function contactFindAndSetDb($token) :bool
|
public static function contactFindAndSetDb($token) :bool
|
||||||
{
|
{
|
||||||
foreach (self::$dbs as $db) {
|
foreach (self::$dbs as $db) {
|
||||||
@ -160,7 +185,7 @@ class MultiDB
|
|||||||
public static function userFindAndSetDb($email) : bool
|
public static function userFindAndSetDb($email) : bool
|
||||||
{
|
{
|
||||||
|
|
||||||
//multi-db active
|
//multi-db active
|
||||||
foreach (self::$dbs as $db) {
|
foreach (self::$dbs as $db) {
|
||||||
if (User::on($db)->where(['email' => $email])->get()->count() >= 1) { // if user already exists, validation will fail
|
if (User::on($db)->where(['email' => $email])->get()->count() >= 1) { // if user already exists, validation will fail
|
||||||
return true;
|
return true;
|
||||||
|
@ -12,7 +12,11 @@
|
|||||||
namespace App\Listeners\Credit;
|
namespace App\Listeners\Credit;
|
||||||
|
|
||||||
use App\Jobs\Mail\EntitySentMailer;
|
use App\Jobs\Mail\EntitySentMailer;
|
||||||
|
use App\Jobs\Mail\NinjaMailer;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Mail\Admin\EntitySentObject;
|
||||||
use App\Notifications\Admin\EntitySentNotification;
|
use App\Notifications\Admin\EntitySentNotification;
|
||||||
use App\Utils\Traits\Notifications\UserNotifies;
|
use App\Utils\Traits\Notifications\UserNotifies;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
@ -41,6 +45,11 @@ class CreditEmailedNotification implements ShouldQueue
|
|||||||
$credit->last_sent_date = now();
|
$credit->last_sent_date = now();
|
||||||
$credit->save();
|
$credit->save();
|
||||||
|
|
||||||
|
$nmo = new NinjaMailerObject;
|
||||||
|
$nmo->mailable = new NinjaMailer( (new EntitySentObject($event->invitation, 'credit', $event->template))->build() );
|
||||||
|
$nmo->company = $credit->company;
|
||||||
|
$nmo->settings = $credit->company->settings;
|
||||||
|
|
||||||
foreach ($event->invitation->company->company_users as $company_user) {
|
foreach ($event->invitation->company->company_users as $company_user) {
|
||||||
$user = $company_user->user;
|
$user = $company_user->user;
|
||||||
|
|
||||||
@ -51,7 +60,11 @@ class CreditEmailedNotification implements ShouldQueue
|
|||||||
if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) {
|
if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) {
|
||||||
unset($methods[$key]);
|
unset($methods[$key]);
|
||||||
|
|
||||||
EntitySentMailer::dispatch($event->invitation, 'credit', $user, $event->invitation->company, $event->template);
|
$nmo->to_user = $user;
|
||||||
|
|
||||||
|
NinjaMailerJob::dispatch($nmo);
|
||||||
|
|
||||||
|
//EntitySentMailer::dispatch($event->invitation, 'credit', $user, $event->invitation->company, $event->template);
|
||||||
$first_notification_sent = false;
|
$first_notification_sent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,11 @@
|
|||||||
|
|
||||||
namespace App\Listeners;
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use App\Jobs\Mail\NinjaMailer;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Mail\Admin\VerifyUserObject;
|
||||||
use App\Notifications\Ninja\VerifyUser;
|
use App\Notifications\Ninja\VerifyUser;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use Exception;
|
use Exception;
|
||||||
@ -45,7 +49,16 @@ class SendVerificationNotification implements ShouldQueue
|
|||||||
MultiDB::setDB($event->company->db);
|
MultiDB::setDB($event->company->db);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$event->user->notify(new VerifyUser($event->user, $event->company));
|
|
||||||
|
$nmo = new NinjaMailerObject;
|
||||||
|
$nmo->mailable = new NinjaMailer((new VerifyUserObject($event->user, $event->company))->build());
|
||||||
|
$nmo->company = $event->company;
|
||||||
|
$nmo->to_user = $event->user;
|
||||||
|
$nmo->settings = $event->company->settings;
|
||||||
|
|
||||||
|
NinjaMailerJob::dispatch($nmo);
|
||||||
|
|
||||||
|
// $event->user->notify(new VerifyUser($event->user, $event->company));
|
||||||
|
|
||||||
Ninja::registerNinjaUser($event->user);
|
Ninja::registerNinjaUser($event->user);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
52
app/Mail/Admin/AccountCreatedObject.php
Normal file
52
app/Mail/Admin/AccountCreatedObject.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Mail\Admin;
|
||||||
|
|
||||||
|
class AccountCreatedObject
|
||||||
|
{
|
||||||
|
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct($user, $company)
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
$this->company = $company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'title' => ctrans('texts.new_signup'),
|
||||||
|
'message' => ctrans('texts.new_signup_text', ['user' => $this->user->present()->name(), 'email' => $this->user->email, 'ip' => $this->user->ip]),
|
||||||
|
'url' => config('ninja.web_url'),
|
||||||
|
'button' => ctrans('texts.account_login'),
|
||||||
|
'signature' => $this->company->settings->email_signature,
|
||||||
|
'settings' => $this->company->settings,
|
||||||
|
'logo' => $this->company->present()->logo(),
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$mail_obj = new \stdClass;
|
||||||
|
$mail_obj->subject = ctrans('texts.new_signup');
|
||||||
|
$mail_obj->data = $data;
|
||||||
|
$mail_obj->markdown = 'email.admin.generic';
|
||||||
|
$mail_obj->tag = $this->company->company_key;
|
||||||
|
|
||||||
|
return $mail_obj;
|
||||||
|
}
|
||||||
|
}
|
53
app/Mail/Admin/ResetPasswordObject.php
Normal file
53
app/Mail/Admin/ResetPasswordObject.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Mail\Admin;
|
||||||
|
|
||||||
|
class ResetPasswordObject
|
||||||
|
{
|
||||||
|
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
public $token;
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct($token, $user, $company)
|
||||||
|
{
|
||||||
|
$this->token = $token;
|
||||||
|
$this->user = $user;
|
||||||
|
$this->company = $company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'title' => ctrans('texts.your_password_reset_link'),
|
||||||
|
'message' => ctrans('texts.reset_password'),
|
||||||
|
'url' => route('password.reset', ['token' => $this->token, 'email' => $this->user->email]),
|
||||||
|
'button' => ctrans('texts.reset'),
|
||||||
|
'signature' => $this->company->settings->email_signature,
|
||||||
|
'settings' => $this->company->settings,
|
||||||
|
'logo' => $this->company->present()->logo(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$mail_obj = new \stdClass;
|
||||||
|
$mail_obj->subject = ctrans('texts.your_password_reset_link');
|
||||||
|
$mail_obj->data = $data;
|
||||||
|
$mail_obj->markdown = 'email.admin.generic';
|
||||||
|
$mail_obj->tag = $this->company->company_key;
|
||||||
|
|
||||||
|
return $mail_obj;
|
||||||
|
}
|
||||||
|
}
|
58
app/Mail/Admin/VerifyUserObject.php
Normal file
58
app/Mail/Admin/VerifyUserObject.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Mail\Admin;
|
||||||
|
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
|
||||||
|
class VerifyUserObject
|
||||||
|
{
|
||||||
|
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct($user, $company)
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
$this->company = $company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$this->user->confirmation_code = $this->createDbHash($this->company->db);
|
||||||
|
$this->user->save();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'title' => ctrans('texts.confirmation_subject'),
|
||||||
|
'message' => ctrans('texts.confirmation_message'),
|
||||||
|
'url' => url("/user/confirm/{$this->user->confirmation_code}"),
|
||||||
|
'button' => ctrans('texts.button_confirmation_message'),
|
||||||
|
'settings' => $this->company->settings,
|
||||||
|
'logo' => $this->company->present()->logo(),
|
||||||
|
'signature' => $this->company->settings->email_signature,
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$mail_obj = new \stdClass;
|
||||||
|
$mail_obj->subject = ctrans('texts.confirmation_subject');
|
||||||
|
$mail_obj->data = $data;
|
||||||
|
$mail_obj->markdown = 'email.admin.generic';
|
||||||
|
$mail_obj->tag = $this->company->company_key;
|
||||||
|
|
||||||
|
return $mail_obj;
|
||||||
|
}
|
||||||
|
}
|
54
app/Mail/ClientContact/ClientContactResetPasswordObject.php
Normal file
54
app/Mail/ClientContact/ClientContactResetPasswordObject.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Mail\ClientContact;
|
||||||
|
|
||||||
|
class ClientContactResetPasswordObject
|
||||||
|
{
|
||||||
|
|
||||||
|
public $client_contact;
|
||||||
|
|
||||||
|
public $token;
|
||||||
|
|
||||||
|
private $company;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct($token, $client_contact)
|
||||||
|
{
|
||||||
|
$this->token = $token;
|
||||||
|
$this->client_contact = $client_contact;
|
||||||
|
$this->company = $client_contact->company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'title' => ctrans('texts.your_password_reset_link'),
|
||||||
|
'message' => ctrans('texts.reset_password'),
|
||||||
|
'url' => route('client.password.reset', ['token' => $this->token, 'email' => $this->client_contact->email]),
|
||||||
|
'button' => ctrans('texts.reset'),
|
||||||
|
'signature' => $this->company->settings->email_signature,
|
||||||
|
'settings' => $this->company->settings,
|
||||||
|
'logo' => $this->company->present()->logo(),
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$mail_obj = new \stdClass;
|
||||||
|
$mail_obj->subject = ctrans('texts.your_password_reset_link');
|
||||||
|
$mail_obj->data = $data;
|
||||||
|
$mail_obj->markdown = 'email.admin.generic';
|
||||||
|
$mail_obj->tag = $this->company->company_key;
|
||||||
|
|
||||||
|
return $mail_obj;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Mail\RecurringInvoice;
|
||||||
|
|
||||||
|
class ClientContactRequestCancellationObject
|
||||||
|
{
|
||||||
|
|
||||||
|
public $recurring_invoice;
|
||||||
|
|
||||||
|
public $client_contact;
|
||||||
|
|
||||||
|
private $company;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct($recurring_invoice, $client_contact)
|
||||||
|
{
|
||||||
|
$this->recurring_invoice = $recurring_invoice;
|
||||||
|
$this->client_contact = $client_contact;
|
||||||
|
$this->company = $recurring_invoice->company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'title' => ctrans('texts.recurring_cancellation_request', ['contact' => $this->client_contact->present()->name()]),
|
||||||
|
'message' => ctrans('texts.recurring_cancellation_request_body', ['contact' => $this->client_contact->present()->name(), 'client' => $this->client_contact->client->present()->name(), 'invoice' => $this->recurring_invoice->number]),
|
||||||
|
'url' => config('ninja.web_url'),
|
||||||
|
'button' => ctrans('texts.account_login'),
|
||||||
|
'signature' => $this->company->settings->email_signature,
|
||||||
|
'settings' => $this->company->settings,
|
||||||
|
'logo' => $this->company->present()->logo(),
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$mail_obj = new \stdClass;
|
||||||
|
$mail_obj->subject = ctrans('texts.recurring_cancellation_request', ['contact' => $this->client_contact->present()->name()]);
|
||||||
|
$mail_obj->data = $data;
|
||||||
|
$mail_obj->markdown = 'email.admin.generic';
|
||||||
|
$mail_obj->tag = $this->company->company_key;
|
||||||
|
|
||||||
|
return $mail_obj;
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,10 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Jobs\Mail\NinjaMailer;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
|
use App\Mail\ClientContact\ClientContactResetPasswordObject;
|
||||||
use App\Models\Presenters\ClientContactPresenter;
|
use App\Models\Presenters\ClientContactPresenter;
|
||||||
use App\Notifications\ClientContactResetPassword;
|
use App\Notifications\ClientContactResetPassword;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
@ -151,7 +155,15 @@ class ClientContact extends Authenticatable implements HasLocalePreference
|
|||||||
|
|
||||||
public function sendPasswordResetNotification($token)
|
public function sendPasswordResetNotification($token)
|
||||||
{
|
{
|
||||||
$this->notify(new ClientContactResetPassword($token));
|
$nmo = new NinjaMailerObject;
|
||||||
|
$nmo->mailable = new NinjaMailer((new ClientContactResetPasswordObject($token, $this))->build());
|
||||||
|
$nmo->to_user = $this;
|
||||||
|
$nmo->company = $this->company;
|
||||||
|
$nmo->settings = $this->company->settings;
|
||||||
|
|
||||||
|
NinjaMailerJob::dispatch($nmo);
|
||||||
|
|
||||||
|
//$this->notify(new ClientContactResetPassword($token));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function preferredLocale()
|
public function preferredLocale()
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Jobs\Mail\NinjaMailer;
|
||||||
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
|
use App\Mail\Admin\ResetPasswordObject;
|
||||||
use App\Models\Presenters\UserPresenter;
|
use App\Models\Presenters\UserPresenter;
|
||||||
use App\Notifications\ResetPasswordNotification;
|
use App\Notifications\ResetPasswordNotification;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
@ -371,6 +375,15 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
*/
|
*/
|
||||||
public function sendPasswordResetNotification($token)
|
public function sendPasswordResetNotification($token)
|
||||||
{
|
{
|
||||||
$this->notify(new ResetPasswordNotification($token));
|
|
||||||
|
$nmo = new NinjaMailerObject;
|
||||||
|
$nmo->mailable = new NinjaMailer( (new ResetPasswordObject($token, $this, $this->account->default_company))->build());
|
||||||
|
$nmo->to_user = $this;
|
||||||
|
$nmo->settings = $this->account->default_company->settings;
|
||||||
|
$nmo->company = $this->account->default_company;
|
||||||
|
|
||||||
|
NinjaMailerJob::dispatch($nmo);
|
||||||
|
|
||||||
|
//$this->notify(new ResetPasswordNotification($token));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ use Illuminate\Notifications\Notification;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
class EntitySentNotification extends Notification implements ShouldQueue
|
class EntitySentNotification extends Notification implements ShouldQueue
|
||||||
{
|
{
|
||||||
//use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
//use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
@ -77,39 +78,6 @@ class EntitySentNotification extends Notification implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function toMail($notifiable)
|
public function toMail($notifiable)
|
||||||
{
|
{
|
||||||
//@TODO THESE ARE @DEPRECATED NOW we are now using app/Mail/Admin/*
|
|
||||||
$amount = Number::formatMoney($this->entity->amount, $this->entity->client);
|
|
||||||
$subject = ctrans(
|
|
||||||
"texts.notification_{$this->entity_name}_sent_subject",
|
|
||||||
[
|
|
||||||
'client' => $this->contact->present()->name(),
|
|
||||||
'invoice' => $this->entity->number,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'title' => $subject,
|
|
||||||
'message' => ctrans(
|
|
||||||
"texts.notification_{$this->entity_name}_sent",
|
|
||||||
[
|
|
||||||
'amount' => $amount,
|
|
||||||
'client' => $this->contact->present()->name(),
|
|
||||||
'invoice' => $this->entity->number,
|
|
||||||
]
|
|
||||||
),
|
|
||||||
'url' => $this->invitation->getAdminLink(),
|
|
||||||
'button' => ctrans("texts.view_{$this->entity_name}"),
|
|
||||||
'signature' => $this->settings->email_signature,
|
|
||||||
'logo' => $this->company->present()->logo(),
|
|
||||||
'settings' => $this->settings,
|
|
||||||
];
|
|
||||||
|
|
||||||
return (new MailMessage)
|
|
||||||
->subject($subject)
|
|
||||||
->markdown('email.admin.generic', $data)
|
|
||||||
->withSwiftMessage(function ($message) {
|
|
||||||
$message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,9 +88,7 @@ class EntitySentNotification extends Notification implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function toArray($notifiable)
|
public function toArray($notifiable)
|
||||||
{
|
{
|
||||||
return [
|
return [];
|
||||||
//
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toSlack($notifiable)
|
public function toSlack($notifiable)
|
||||||
|
@ -22,6 +22,7 @@ use Illuminate\Queue\InteractsWithQueue;
|
|||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
|
//@deprecated for mail
|
||||||
class ClientContactRequestCancellation extends Notification
|
class ClientContactRequestCancellation extends Notification
|
||||||
{
|
{
|
||||||
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
@ -56,7 +57,7 @@ class ClientContactRequestCancellation extends Notification
|
|||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
{
|
{
|
||||||
return ['mail', 'slack'];
|
return ['slack'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,19 +68,6 @@ class ClientContactRequestCancellation extends Notification
|
|||||||
*/
|
*/
|
||||||
public function toMail($notifiable)
|
public function toMail($notifiable)
|
||||||
{
|
{
|
||||||
if (static::$toMailCallback) {
|
|
||||||
return call_user_func(static::$toMailCallback, $notifiable, $this->client_contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
$client_contact_name = $this->client_contact->present()->name();
|
|
||||||
$client_name = $this->client_contact->client->present()->name();
|
|
||||||
$recurring_invoice_number = $this->recurring_invoice->number;
|
|
||||||
|
|
||||||
return (new MailMessage)
|
|
||||||
->subject('Request for recurring invoice cancellation from '.$client_contact_name)
|
|
||||||
->markdown('email.support.cancellation', [
|
|
||||||
'message' => "Contact [{$client_contact_name}] from Client [{$client_name}] requested to cancel Recurring Invoice [#{$recurring_invoice_number}]",
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,7 @@ use Illuminate\Notifications\Notification;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
class ClientContactResetPassword extends Notification
|
class ClientContactResetPassword extends Notification
|
||||||
{
|
{
|
||||||
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
@ -55,7 +56,7 @@ class ClientContactResetPassword extends Notification
|
|||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
{
|
{
|
||||||
return ['mail'];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Invoice Ninja (https://invoiceninja.com).
|
|
||||||
*
|
|
||||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @license https://opensource.org/licenses/AAL
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Notifications;
|
|
||||||
|
|
||||||
use Illuminate\Bus\Queueable;
|
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
|
||||||
use Illuminate\Notifications\Notification;
|
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
class GmailTestNotification extends Notification
|
|
||||||
{
|
|
||||||
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new notification instance.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the notification's delivery channels.
|
|
||||||
*
|
|
||||||
* @param mixed $notifiable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function via($notifiable)
|
|
||||||
{
|
|
||||||
return ['mail'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the mail representation of the notification.
|
|
||||||
*
|
|
||||||
* @param mixed $notifiable
|
|
||||||
* @return MailMessage
|
|
||||||
*/
|
|
||||||
public function toMail($notifiable)
|
|
||||||
{
|
|
||||||
return (new MailMessage)
|
|
||||||
->line('The introduction to the notification.')
|
|
||||||
->action('Notification Action', url('/'))
|
|
||||||
->line('Thank you for using our application!');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the array representation of the notification.
|
|
||||||
*
|
|
||||||
* @param mixed $notifiable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function toArray($notifiable)
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
//
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,6 +20,7 @@ use Illuminate\Notifications\Notification;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
class NewAccountCreated extends Notification
|
class NewAccountCreated extends Notification
|
||||||
{
|
{
|
||||||
//use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
//use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
@ -50,7 +51,7 @@ class NewAccountCreated extends Notification
|
|||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
{
|
{
|
||||||
return ['slack', 'mail'];
|
return ['slack'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,26 +62,6 @@ class NewAccountCreated extends Notification
|
|||||||
*/
|
*/
|
||||||
public function toMail($notifiable)
|
public function toMail($notifiable)
|
||||||
{
|
{
|
||||||
$user_name = $this->user->first_name.' '.$this->user->last_name;
|
|
||||||
$email = $this->user->email;
|
|
||||||
$ip = $this->user->ip;
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'title' => ctrans('texts.new_signup'),
|
|
||||||
'message' => ctrans('texts.new_signup_text', ['user' => $user_name, 'email' => $email, 'ip' => $ip]),
|
|
||||||
'url' => config('ninja.web_url'),
|
|
||||||
'button' => ctrans('texts.account_login'),
|
|
||||||
'signature' => $this->company->settings->email_signature,
|
|
||||||
'logo' => $this->company->present()->logo(),
|
|
||||||
'settings' => $this->company->settings,
|
|
||||||
];
|
|
||||||
|
|
||||||
return (new MailMessage)
|
|
||||||
->subject(ctrans('texts.new_signup'))
|
|
||||||
->withSwiftMessage(function ($message) {
|
|
||||||
$message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
|
||||||
})
|
|
||||||
->markdown('email.admin.generic', $data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,8 @@ use Illuminate\Notifications\Notification;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
class NewAccountCreated extends Notification
|
class NewAccountCreated extends Notification
|
||||||
{
|
{
|
||||||
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
@ -50,7 +52,7 @@ class NewAccountCreated extends Notification
|
|||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
{
|
{
|
||||||
return ['slack', 'mail'];
|
return ['slack'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,26 +63,6 @@ class NewAccountCreated extends Notification
|
|||||||
*/
|
*/
|
||||||
public function toMail($notifiable)
|
public function toMail($notifiable)
|
||||||
{
|
{
|
||||||
$user_name = $this->user->first_name.' '.$this->user->last_name;
|
|
||||||
$email = $this->user->email;
|
|
||||||
$ip = $this->user->ip;
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'title' => ctrans('texts.new_signup'),
|
|
||||||
'message' => ctrans('texts.new_signup_text', ['user' => $user_name, 'email' => $email, 'ip' => $ip]),
|
|
||||||
'url' => config('ninja.web_url'),
|
|
||||||
'button' => ctrans('texts.account_login'),
|
|
||||||
'signature' => $this->company->settings->email_signature,
|
|
||||||
'logo' => $this->company->present()->logo(),
|
|
||||||
'settings' => $this->company->settings,
|
|
||||||
];
|
|
||||||
|
|
||||||
return (new MailMessage)
|
|
||||||
->subject(ctrans('texts.new_signup'))
|
|
||||||
->markdown('email.admin.generic', $data)
|
|
||||||
->withSwiftMessage(function ($message) {
|
|
||||||
$message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,7 @@ use Illuminate\Notifications\Notification;
|
|||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
class VerifyUser extends Notification
|
class VerifyUser extends Notification
|
||||||
{
|
{
|
||||||
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
// use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
@ -46,7 +47,7 @@ class VerifyUser extends Notification
|
|||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
{
|
{
|
||||||
return ['mail'];
|
return [''];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,19 +58,6 @@ class VerifyUser extends Notification
|
|||||||
*/
|
*/
|
||||||
public function toMail($notifiable)
|
public function toMail($notifiable)
|
||||||
{
|
{
|
||||||
$data = [
|
|
||||||
'title' => ctrans('texts.confirmation_subject'),
|
|
||||||
'message' => ctrans('texts.confirmation_message'),
|
|
||||||
'url' => url("/user/confirm/{$this->user->confirmation_code}"),
|
|
||||||
'button' => ctrans('texts.button_confirmation_message'),
|
|
||||||
'signature' => '',
|
|
||||||
'logo' => 'https://www.invoiceninja.com/wp-content/uploads/2019/01/InvoiceNinja-Logo-Round-300x300.png',
|
|
||||||
'settings' => $this->company->settings,
|
|
||||||
];
|
|
||||||
|
|
||||||
return (new MailMessage)
|
|
||||||
->subject(ctrans('texts.confirmation_subject'))
|
|
||||||
->markdown('email.admin.generic', $data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,6 +6,7 @@ use Illuminate\Bus\Queueable;
|
|||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
class ResetPasswordNotification extends Notification
|
class ResetPasswordNotification extends Notification
|
||||||
{
|
{
|
||||||
// use Queueable;
|
// use Queueable;
|
||||||
@ -30,7 +31,7 @@ class ResetPasswordNotification extends Notification
|
|||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
{
|
{
|
||||||
return ['mail'];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,124 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Invoice Ninja (https://invoiceninja.com).
|
|
||||||
*
|
|
||||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @license https://opensource.org/licenses/AAL
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Notifications;
|
|
||||||
|
|
||||||
use App\Models\Invoice;
|
|
||||||
use App\Utils\Number;
|
|
||||||
use Illuminate\Bus\Queueable;
|
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
|
||||||
use Illuminate\Notifications\Messages\SlackMessage;
|
|
||||||
use Illuminate\Notifications\Notification;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
class SendGenericNotification extends BaseNotification
|
|
||||||
{
|
|
||||||
// use Queueable;
|
|
||||||
// use Dispatchable;
|
|
||||||
// use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new notification instance.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected $invitation;
|
|
||||||
|
|
||||||
protected $entity;
|
|
||||||
|
|
||||||
protected $contact;
|
|
||||||
|
|
||||||
protected $entity_string;
|
|
||||||
|
|
||||||
protected $settings;
|
|
||||||
|
|
||||||
public $is_system;
|
|
||||||
|
|
||||||
protected $body;
|
|
||||||
|
|
||||||
protected $subject;
|
|
||||||
|
|
||||||
public function __construct($invitation, $entity_string, $subject, $body)
|
|
||||||
{
|
|
||||||
$this->entity = $invitation->{$entity_string};
|
|
||||||
$this->contact = $invitation->contact;
|
|
||||||
$this->settings = $this->entity->client->getMergedSettings();
|
|
||||||
$this->subject = $subject;
|
|
||||||
$this->body = $body;
|
|
||||||
$this->invitation = $invitation;
|
|
||||||
$this->entity_string = $entity_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the notification's delivery channels.
|
|
||||||
*
|
|
||||||
* @param mixed $notifiable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function via($notifiable)
|
|
||||||
{
|
|
||||||
return ['mail'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the mail representation of the notification.
|
|
||||||
*
|
|
||||||
* @param mixed $notifiable
|
|
||||||
* @return MailMessage
|
|
||||||
*/
|
|
||||||
public function toMail($notifiable)
|
|
||||||
{
|
|
||||||
$mail_message = (new MailMessage)
|
|
||||||
->withSwiftMessage(function ($message) {
|
|
||||||
$message->getHeaders()->addTextHeader('Tag', $this->invitation->company->company_key);
|
|
||||||
})->markdown($this->getTemplateView(), $this->buildMailMessageData());
|
|
||||||
//})->markdown('email.template.plain', $this->buildMailMessageData());
|
|
||||||
|
|
||||||
$mail_message = $this->buildMailMessageSettings($mail_message);
|
|
||||||
|
|
||||||
return $mail_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the array representation of the notification.
|
|
||||||
*
|
|
||||||
* @param mixed $notifiable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function toArray($notifiable)
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
//
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function toSlack($notifiable)
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
// $logo = $this->company->present()->logo();
|
|
||||||
// $amount = Number::formatMoney($this->invoice->amount, $this->invoice->client);
|
|
||||||
|
|
||||||
// return (new SlackMessage)
|
|
||||||
// ->success()
|
|
||||||
// ->from(ctrans('texts.notification_bot'))
|
|
||||||
// ->image($logo)
|
|
||||||
// ->content(ctrans(
|
|
||||||
// 'texts.notification_invoice_viewed',
|
|
||||||
// [
|
|
||||||
// 'amount' => $amount,
|
|
||||||
// 'client' => $this->contact->present()->name(),
|
|
||||||
// 'invoice' => $this->invoice->number
|
|
||||||
// ]
|
|
||||||
// ));
|
|
||||||
}
|
|
||||||
}
|
|
75
app/Observers/CreditObserver.php
Normal file
75
app/Observers/CreditObserver.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Credit Ninja (https://creditninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/creditninja/creditninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Credit Ninja LLC (https://creditninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Observers;
|
||||||
|
|
||||||
|
use App\Jobs\Util\UnlinkFile;
|
||||||
|
use App\Jobs\Util\WebhookHandler;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\Credit;
|
||||||
|
use App\Models\Webhook;
|
||||||
|
|
||||||
|
class CreditObserver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle the client "created" event.
|
||||||
|
*
|
||||||
|
* @param Credit $credit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function created(Credit $credit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the client "updated" event.
|
||||||
|
*
|
||||||
|
* @param Credit $credit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updated(Credit $credit)
|
||||||
|
{
|
||||||
|
UnlinkFile::dispatchNow(config('filesystems.default'), $credit->client->credit_filepath() . $credit->number.'.pdf');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the client "deleted" event.
|
||||||
|
*
|
||||||
|
* @param Credit $credit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleted(Credit $credit)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the client "restored" event.
|
||||||
|
*
|
||||||
|
* @param Credit $credit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function restored(Credit $credit)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the client "force deleted" event.
|
||||||
|
*
|
||||||
|
* @param Credit $credit
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function forceDeleted(Credit $credit)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Observers;
|
namespace App\Observers;
|
||||||
|
|
||||||
|
use App\Jobs\Util\UnlinkFile;
|
||||||
use App\Jobs\Util\WebhookHandler;
|
use App\Jobs\Util\WebhookHandler;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
@ -50,6 +51,9 @@ class InvoiceObserver
|
|||||||
if ($subscriptions) {
|
if ($subscriptions) {
|
||||||
WebhookHandler::dispatch(Webhook::EVENT_UPDATE_INVOICE, $invoice, $invoice->company);
|
WebhookHandler::dispatch(Webhook::EVENT_UPDATE_INVOICE, $invoice, $invoice->company);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnlinkFile::dispatchNow(config('filesystems.default'), $invoice->client->invoice_filepath() . $invoice->number.'.pdf');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Observers;
|
namespace App\Observers;
|
||||||
|
|
||||||
|
use App\Jobs\Util\UnlinkFile;
|
||||||
use App\Jobs\Util\WebhookHandler;
|
use App\Jobs\Util\WebhookHandler;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Models\Webhook;
|
use App\Models\Webhook;
|
||||||
@ -49,6 +50,9 @@ class QuoteObserver
|
|||||||
if ($subscriptions) {
|
if ($subscriptions) {
|
||||||
WebhookHandler::dispatch(Webhook::EVENT_UPDATE_QUOTE, $quote, $quote->company);
|
WebhookHandler::dispatch(Webhook::EVENT_UPDATE_QUOTE, $quote, $quote->company);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnlinkFile::dispatchNow(config('filesystems.default'), $quote->client->quote_filepath() . $quote->number.'.pdf');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@ use App\Models\Client;
|
|||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CompanyGateway;
|
use App\Models\CompanyGateway;
|
||||||
use App\Models\CompanyToken;
|
use App\Models\CompanyToken;
|
||||||
|
use App\Models\Credit;
|
||||||
use App\Models\Expense;
|
use App\Models\Expense;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
@ -29,6 +30,7 @@ use App\Observers\ClientObserver;
|
|||||||
use App\Observers\CompanyGatewayObserver;
|
use App\Observers\CompanyGatewayObserver;
|
||||||
use App\Observers\CompanyObserver;
|
use App\Observers\CompanyObserver;
|
||||||
use App\Observers\CompanyTokenObserver;
|
use App\Observers\CompanyTokenObserver;
|
||||||
|
use App\Observers\CreditObserver;
|
||||||
use App\Observers\ExpenseObserver;
|
use App\Observers\ExpenseObserver;
|
||||||
use App\Observers\InvoiceObserver;
|
use App\Observers\InvoiceObserver;
|
||||||
use App\Observers\PaymentObserver;
|
use App\Observers\PaymentObserver;
|
||||||
@ -79,6 +81,7 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
Company::observe(CompanyObserver::class);
|
Company::observe(CompanyObserver::class);
|
||||||
CompanyGateway::observe(CompanyGatewayObserver::class);
|
CompanyGateway::observe(CompanyGatewayObserver::class);
|
||||||
CompanyToken::observe(CompanyTokenObserver::class);
|
CompanyToken::observe(CompanyTokenObserver::class);
|
||||||
|
Credit::observe(CreditObserver::class);
|
||||||
Expense::observe(ExpenseObserver::class);
|
Expense::observe(ExpenseObserver::class);
|
||||||
Invoice::observe(InvoiceObserver::class);
|
Invoice::observe(InvoiceObserver::class);
|
||||||
Payment::observe(PaymentObserver::class);
|
Payment::observe(PaymentObserver::class);
|
||||||
|
@ -147,7 +147,7 @@ class ApplyPayment
|
|||||||
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars()));
|
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars()));
|
||||||
|
|
||||||
if ((int)$this->invoice->balance == 0) {
|
if ((int)$this->invoice->balance == 0) {
|
||||||
$this->invoice->service()->deletePdf();
|
// $this->invoice->service()->deletePdf();
|
||||||
event(new InvoiceWasPaid($this->invoice, $payment, $this->payment->company, Ninja::eventVars()));
|
event(new InvoiceWasPaid($this->invoice, $payment, $this->payment->company, Ninja::eventVars()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,13 @@ class CreditService
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateBalance($adjustment)
|
||||||
|
{
|
||||||
|
$this->credit->balance -= $adjustment;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function fillDefaults()
|
public function fillDefaults()
|
||||||
{
|
{
|
||||||
$settings = $this->credit->client->getMergedSettings();
|
$settings = $this->credit->client->getMergedSettings();
|
||||||
|
@ -266,7 +266,7 @@ class InvoiceService
|
|||||||
|
|
||||||
//$this->invoice = $this->invoice->calc()->getInvoice();
|
//$this->invoice = $this->invoice->calc()->getInvoice();
|
||||||
|
|
||||||
$this->deletePdf();
|
// $this->deletePdf();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ class DeletePayment
|
|||||||
|
|
||||||
private function updateClient()
|
private function updateClient()
|
||||||
{
|
{
|
||||||
$this->payment->client->service()->updatePaidToDate(-1 * $this->payment->amount)->save();
|
//$this->payment->client->service()->updatePaidToDate(-1 * $this->payment->amount)->save();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -92,6 +92,7 @@ class DeletePayment
|
|||||||
$paymentable_invoice->client
|
$paymentable_invoice->client
|
||||||
->service()
|
->service()
|
||||||
->updateBalance($paymentable_invoice->pivot->amount)
|
->updateBalance($paymentable_invoice->pivot->amount)
|
||||||
|
->updatePaidToDate($paymentable_invoice->pivot->amount * -1)
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
if ($paymentable_invoice->balance == $paymentable_invoice->amount) {
|
if ($paymentable_invoice->balance == $paymentable_invoice->amount) {
|
||||||
|
@ -13,6 +13,10 @@ namespace App\Utils\Traits\Notifications;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UserNotifies.
|
* Class UserNotifies.
|
||||||
|
*
|
||||||
|
* I think the term $required_permissions is confusing here, what
|
||||||
|
* we are actually defining is the notifications available on the
|
||||||
|
* user itself.
|
||||||
*/
|
*/
|
||||||
trait UserNotifies
|
trait UserNotifies
|
||||||
{
|
{
|
||||||
@ -74,10 +78,41 @@ trait UserNotifies
|
|||||||
$notifiable_methods = [];
|
$notifiable_methods = [];
|
||||||
$notifications = $company_user->notifications;
|
$notifications = $company_user->notifications;
|
||||||
|
|
||||||
|
//conditional to define whether the company user has the required notification for the MAIL notification TYPE
|
||||||
if (count(array_intersect($required_permissions, $notifications->email)) >= 1 || count(array_intersect($required_permissions, ['all_user_notifications'])) >= 1 || count(array_intersect($required_permissions, ['all_notifications'])) >= 1) {
|
if (count(array_intersect($required_permissions, $notifications->email)) >= 1 || count(array_intersect($required_permissions, ['all_user_notifications'])) >= 1 || count(array_intersect($required_permissions, ['all_notifications'])) >= 1) {
|
||||||
array_push($notifiable_methods, 'mail');
|
array_push($notifiable_methods, 'mail');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $notifiable_methods;
|
return $notifiable_methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a filtered collection of users with the
|
||||||
|
* required notification - NOTE this is only implemented for
|
||||||
|
* EMAIL notification types - we'll need to chain
|
||||||
|
* additional types at a later stage.
|
||||||
|
*/
|
||||||
|
public function filterUsersByPermissions($company_users, $entity, array $required_notification)
|
||||||
|
{
|
||||||
|
|
||||||
|
return $company_users->filter(function($company_user) use($required_notification, $entity){
|
||||||
|
|
||||||
|
return $this->checkNotificationExists($company_user, $entity, $required_notification);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkNotificationExists($company_user, $entity, $required_notification)
|
||||||
|
{
|
||||||
|
/* Always make sure we push the `all_notificaitons` into the mix */
|
||||||
|
array_push($required_notification, 'all_notifications');
|
||||||
|
|
||||||
|
/* Selectively add the all_user if the user is associated with the entity */
|
||||||
|
if ($entity->user_id == $company_user->_user_id || $entity->assigned_user_id == $company_user->user_id)
|
||||||
|
array_push($required_notification, 'all_user_notifications');
|
||||||
|
|
||||||
|
|
||||||
|
return count(array_intersect($required_notification, $company_user->notifications->email)) >= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
50
config/trustedproxy.php
Normal file
50
config/trustedproxy.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set trusted proxy IP addresses.
|
||||||
|
*
|
||||||
|
* Both IPv4 and IPv6 addresses are
|
||||||
|
* supported, along with CIDR notation.
|
||||||
|
*
|
||||||
|
* The "*" character is syntactic sugar
|
||||||
|
* within TrustedProxy to trust any proxy
|
||||||
|
* that connects directly to your server,
|
||||||
|
* a requirement when you cannot know the address
|
||||||
|
* of your proxy (e.g. if using ELB or similar).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
'proxies' => null, // [<ip addresses>,], '*', '<ip addresses>,'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To trust one or more specific proxies that connect
|
||||||
|
* directly to your server, use an array or a string separated by comma of IP addresses:
|
||||||
|
*/
|
||||||
|
// 'proxies' => ['192.168.1.1'],
|
||||||
|
// 'proxies' => '192.168.1.1, 192.168.1.2',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Or, to trust all proxies that connect
|
||||||
|
* directly to your server, use a "*"
|
||||||
|
*/
|
||||||
|
// 'proxies' => '*',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Which headers to use to detect proxy related data (For, Host, Proto, Port)
|
||||||
|
*
|
||||||
|
* Options include:
|
||||||
|
*
|
||||||
|
* - Illuminate\Http\Request::HEADER_X_FORWARDED_ALL (use all x-forwarded-* headers to establish trust)
|
||||||
|
* - Illuminate\Http\Request::HEADER_FORWARDED (use the FORWARDED header to establish trust)
|
||||||
|
* - Illuminate\Http\Request::HEADER_X_FORWARDED_AWS_ELB (If you are using AWS Elastic Load Balancer)
|
||||||
|
*
|
||||||
|
* - 'HEADER_X_FORWARDED_ALL' (use all x-forwarded-* headers to establish trust)
|
||||||
|
* - 'HEADER_FORWARDED' (use the FORWARDED header to establish trust)
|
||||||
|
* - 'HEADER_X_FORWARDED_AWS_ELB' (If you are using AWS Elastic Load Balancer)
|
||||||
|
*
|
||||||
|
* @link https://symfony.com/doc/current/deployment/proxies.html
|
||||||
|
*/
|
||||||
|
'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL,
|
||||||
|
|
||||||
|
];
|
@ -4138,6 +4138,9 @@ $LANG = array(
|
|||||||
|
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
'start_migration' => 'Start Migration',
|
'start_migration' => 'Start Migration',
|
||||||
|
'recurring_cancellation_request' => 'Request for recurring invoice cancellation from :contact',
|
||||||
|
'recurring_cancellation_request_body' => ':contact from Client :client requested to cancel Recurring Invoice :invoice',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
@component('email.template.master', ['design' => 'light', 'whitelabel' => false])
|
@component('email.template.master', ['design' => 'light', 'whitelabel' => false])
|
||||||
|
|
||||||
@slot('header')
|
@slot('header')
|
||||||
@include('email.components.header', ['logo' => 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
|
@include('email.components.header', ['logo' => $logo])
|
||||||
@endslot
|
@endslot
|
||||||
|
|
||||||
<p>You are receiving this email because we received a password reset request for your account.</p>
|
<p>{{ ctrans('texts.reset_password') }}</p>
|
||||||
|
|
||||||
<a href="{{ $link }}" target="_blank" class="button">
|
<a href="{{ $link }}" target="_blank" class="button">
|
||||||
Reset Password
|
{{ ctrans('texts.reset') }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<p>
|
|
||||||
If you’re having trouble clicking the "Reset Password" button, copy and paste the URL below into your web
|
|
||||||
browser:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<a href="{{ $link }}">{{ $link }}</a>
|
<a href="{{ $link }}">{{ $link }}</a>
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
@ -32,6 +32,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
|
|||||||
Route::get('activities/download_entity/{activity}', 'ActivityController@downloadHistoricalEntity');
|
Route::get('activities/download_entity/{activity}', 'ActivityController@downloadHistoricalEntity');
|
||||||
|
|
||||||
Route::resource('clients', 'ClientController'); // name = (clients. index / create / show / update / destroy / edit
|
Route::resource('clients', 'ClientController'); // name = (clients. index / create / show / update / destroy / edit
|
||||||
|
Route::put('clients/{client}/upload', 'ClientController@upload')->name('clients.upload');
|
||||||
|
|
||||||
Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk');
|
Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk');
|
||||||
|
|
||||||
@ -40,12 +41,14 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
|
|||||||
Route::get('invoices/{invoice}/delivery_note', 'InvoiceController@deliveryNote')->name('invoices.delivery_note');
|
Route::get('invoices/{invoice}/delivery_note', 'InvoiceController@deliveryNote')->name('invoices.delivery_note');
|
||||||
|
|
||||||
Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action');
|
Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action');
|
||||||
|
Route::put('invoices/{invoice}/upload', 'InvoiceController@upload')->name('invoices.upload');
|
||||||
|
|
||||||
Route::get('invoice/{invitation_key}/download', 'InvoiceController@downloadPdf')->name('invoices.downloadPdf');
|
Route::get('invoice/{invitation_key}/download', 'InvoiceController@downloadPdf')->name('invoices.downloadPdf');
|
||||||
|
|
||||||
Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk');
|
Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk');
|
||||||
|
|
||||||
Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
|
Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
|
||||||
|
Route::put('credits/{credit}/upload', 'CreditController@upload')->name('credits.upload');
|
||||||
|
|
||||||
Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action');
|
Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action');
|
||||||
|
|
||||||
@ -70,6 +73,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
|
|||||||
Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
|
Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
|
||||||
|
|
||||||
Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit
|
Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit
|
||||||
|
Route::put('expenses/{expense}/upload', 'ExpenseController@upload');
|
||||||
|
|
||||||
Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
|
Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
|
||||||
|
|
||||||
@ -128,6 +132,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
|
|||||||
Route::post('migration/start', 'MigrationController@startMigration');
|
Route::post('migration/start', 'MigrationController@startMigration');
|
||||||
|
|
||||||
Route::resource('companies', 'CompanyController'); // name = (companies. index / create / show / update / destroy / edit
|
Route::resource('companies', 'CompanyController'); // name = (companies. index / create / show / update / destroy / edit
|
||||||
|
Route::put('companies/{company}/upload', 'CompanyController@upload');
|
||||||
|
|
||||||
Route::resource('tokens', 'TokenController')->middleware('password_protected'); // name = (tokens. index / create / show / update / destroy / edit
|
Route::resource('tokens', 'TokenController')->middleware('password_protected'); // name = (tokens. index / create / show / update / destroy / edit
|
||||||
Route::post('tokens/bulk', 'TokenController@bulk')->name('tokens.bulk')->middleware('password_protected');
|
Route::post('tokens/bulk', 'TokenController@bulk')->name('tokens.bulk')->middleware('password_protected');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user