diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index 3aadd6cea67f..ef9ac873343d 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -30,7 +30,7 @@ class CompanySettings extends BaseSettings public $enable_client_portal_tasks = false; //@ben to implement public $enable_client_portal_password = false; //@implemented public $enable_client_portal = true; //@implemented - public $enable_client_portal_dashboard = true; // @TODO There currently is no dashboard so this is pending + public $enable_client_portal_dashboard = false; // @TODO There currently is no dashboard so this is pending public $signature_on_pdf = false; //@implemented public $document_email_attachment = false; //@TODO I assume this is 3rd party attachments on the entity to be included @@ -634,6 +634,7 @@ class CompanySettings extends BaseSettings '$product.description', '$product.unit_cost', '$product.quantity', + '$product.discount', '$product.tax', '$product.line_total', ], @@ -642,6 +643,7 @@ class CompanySettings extends BaseSettings '$task.description', '$task.rate', '$task.hours', + '$task.discount', '$task.tax', '$task.line_total', ], diff --git a/app/Events/Credit/CreditWasEmailed.php b/app/Events/Credit/CreditWasEmailed.php index ddb33ef8ee0c..68b6f1acfc93 100644 --- a/app/Events/Credit/CreditWasEmailed.php +++ b/app/Events/Credit/CreditWasEmailed.php @@ -27,6 +27,7 @@ class CreditWasEmailed public $event_vars; + public $template; /** * Create a new event instance. * @@ -34,10 +35,11 @@ class CreditWasEmailed * @param Company $company * @param array $event_vars */ - public function __construct(CreditInvitation $invitation, Company $company, array $event_vars) + public function __construct(CreditInvitation $invitation, Company $company, array $event_vars, string $template) { $this->invitation = $invitation; $this->company = $company; $this->event_vars = $event_vars; + $this->template = $template; } } diff --git a/app/Events/Invoice/InvoiceWasEmailed.php b/app/Events/Invoice/InvoiceWasEmailed.php index de0329a1028d..ce94a97e8089 100644 --- a/app/Events/Invoice/InvoiceWasEmailed.php +++ b/app/Events/Invoice/InvoiceWasEmailed.php @@ -31,6 +31,8 @@ class InvoiceWasEmailed public $event_vars; + public $template; + /** * Create a new event instance. * @@ -38,10 +40,11 @@ class InvoiceWasEmailed * @param Company $company * @param array $event_vars */ - public function __construct(InvoiceInvitation $invitation, Company $company, array $event_vars) + public function __construct(InvoiceInvitation $invitation, Company $company, array $event_vars, string $template) { $this->invitation = $invitation; $this->company = $company; $this->event_vars = $event_vars; + $this->template = $template; } } diff --git a/app/Events/Quote/QuoteWasEmailed.php b/app/Events/Quote/QuoteWasEmailed.php index 58b9846c9fda..2bbb548f49ab 100644 --- a/app/Events/Quote/QuoteWasEmailed.php +++ b/app/Events/Quote/QuoteWasEmailed.php @@ -29,6 +29,7 @@ class QuoteWasEmailed public $event_vars; + public $template; /** * Create a new event instance. * @@ -37,10 +38,11 @@ class QuoteWasEmailed * @param Company $company * @param array $event_vars */ - public function __construct(QuoteInvitation $invitation, Company $company, array $event_vars) + public function __construct(QuoteInvitation $invitation, Company $company, array $event_vars, string $template) { $this->invitation = $invitation; $this->company = $company; $this->event_vars = $event_vars; + $this->template = $template; } } diff --git a/app/Factory/CloneQuoteToInvoiceFactory.php b/app/Factory/CloneQuoteToInvoiceFactory.php index e77f4611f0c4..e147cb7a3444 100644 --- a/app/Factory/CloneQuoteToInvoiceFactory.php +++ b/app/Factory/CloneQuoteToInvoiceFactory.php @@ -37,7 +37,7 @@ class CloneQuoteToInvoiceFactory $invoice->due_date = null; $invoice->partial_due_date = null; $invoice->number = null; - + $invoice->date = now()->format('Y-m-d'); return $invoice; } } diff --git a/app/Http/Controllers/ClientPortal/DashboardController.php b/app/Http/Controllers/ClientPortal/DashboardController.php index 71fa6c26c7d9..7074b8189f39 100644 --- a/app/Http/Controllers/ClientPortal/DashboardController.php +++ b/app/Http/Controllers/ClientPortal/DashboardController.php @@ -22,6 +22,6 @@ class DashboardController extends Controller */ public function index() { - return redirect()->route('client.invoices.index'); + return $this->render('dashboard.index'); } } diff --git a/app/Http/Controllers/ClientPortal/InvitationController.php b/app/Http/Controllers/ClientPortal/InvitationController.php index df6b73d50520..460020db838b 100644 --- a/app/Http/Controllers/ClientPortal/InvitationController.php +++ b/app/Http/Controllers/ClientPortal/InvitationController.php @@ -51,6 +51,7 @@ class InvitationController extends Controller ->with('contact.client') ->firstOrFail(); + /* Return early if we have the correct client_hash embedded */ if (request()->has('client_hash') && request()->input('client_hash') == $invitation->contact->client->client_hash) { diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index fef8c50add14..e03599b1cf4b 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -32,6 +32,7 @@ use App\Transformers\CompanyTransformer; use App\Transformers\CompanyUserTransformer; use App\Utils\Ninja; use App\Utils\Traits\MakesHash; +use App\Utils\Traits\SavesDocuments; use App\Utils\Traits\Uploadable; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Http\Request; @@ -47,6 +48,7 @@ class CompanyController extends BaseController use DispatchesJobs; use MakesHash; use Uploadable; + use SavesDocuments; protected $entity_type = Company::class; @@ -402,14 +404,17 @@ class CompanyController extends BaseController */ public function update(UpdateCompanyRequest $request, Company $company) { - if ($request->hasFile('company_logo') || (is_array($request->input('settings')) && !array_key_exists('company_logo', $request->input('settings')))) { + if ($request->hasFile('company_logo') || (is_array($request->input('settings')) && !array_key_exists('company_logo', $request->input('settings')))) $this->removeLogo($company); - } + $company = $this->company_repo->save($request->all(), $company); $company->saveSettings($request->input('settings'), $company); + if ($request->has('documents')) + $this->saveDocuments($request->input('documents'), $company, false); + $this->uploadLogo($request->file('company_logo'), $company, $company); return $this->itemResponse($company); diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php deleted file mode 100644 index 858d09c8eb48..000000000000 --- a/app/Http/Controllers/DashboardController.php +++ /dev/null @@ -1,38 +0,0 @@ -middleware('auth:user'); - } - - /** - * Show the application dashboard. - * - * @return Response - */ - public function index() - { - // dd(json_decode(auth()->user()->permissions(),true)); - return view('dashboard.index'); - } -} diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index 97a325f0fa1e..ef1515fc7407 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -140,15 +140,13 @@ class EmailController extends BaseController $entity_obj->save(); /*Only notify the admin ONCE, not once per contact/invite*/ - // $invitation = $entity_obj->invitations->first(); - // EntitySentMailer::dispatch($invitation, $entity_string, $entity_obj->user, $invitation->company); if ($entity_obj instanceof Invoice) { $this->entity_type = Invoice::class; $this->entity_transformer = InvoiceTransformer::class; if ($entity_obj->invitations->count() >= 1) { - $entity_obj->entityEmailEvent($entity_obj->invitations->first(), 'invoice'); + $entity_obj->entityEmailEvent($entity_obj->invitations->first(), 'invoice', $template); } } @@ -157,7 +155,7 @@ class EmailController extends BaseController $this->entity_transformer = QuoteTransformer::class; if ($entity_obj->invitations->count() >= 1) { - event(new QuoteWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars())); + event(new QuoteWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars(), 'quote')); } } @@ -166,7 +164,7 @@ class EmailController extends BaseController $this->entity_transformer = CreditTransformer::class; if ($entity_obj->invitations->count() >= 1) { - event(new CreditWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars())); + event(new CreditWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars(), 'credit')); } } diff --git a/app/Http/Controllers/ExpenseController.php b/app/Http/Controllers/ExpenseController.php index fa4676ab01b7..c2c2fede38a8 100644 --- a/app/Http/Controllers/ExpenseController.php +++ b/app/Http/Controllers/ExpenseController.php @@ -426,10 +426,9 @@ class ExpenseController extends BaseController */ public function destroy(DestroyExpenseRequest $request, Expense $expense) { - //may not need these destroy routes as we are using actions to 'archive/delete' - $expense->delete(); + $this->expense_repo->delete($expense); - return response()->json([], 200); + return $this->itemResponse($expense->fresh()); } /** diff --git a/app/Http/Requests/Client/StoreClientRequest.php b/app/Http/Requests/Client/StoreClientRequest.php index 4dbb2fca3d94..6d70b3a29302 100644 --- a/app/Http/Requests/Client/StoreClientRequest.php +++ b/app/Http/Requests/Client/StoreClientRequest.php @@ -50,7 +50,7 @@ class StoreClientRequest extends Request //$rules['name'] = 'required|min:1'; $rules['id_number'] = 'unique:clients,id_number,'.$this->id.',id,company_id,'.$this->company_id; $rules['settings'] = new ValidClientGroupSettingsRule(); - $rules['contacts.*.email'] = 'nullable|distinct'; + $rules['contacts.*.email'] = 'bail|nullable|distinct|sometimes|email'; $rules['contacts.*.password'] = [ 'nullable', 'sometimes', diff --git a/app/Http/Requests/Client/UpdateClientRequest.php b/app/Http/Requests/Client/UpdateClientRequest.php index 770d90914363..e322ad0a29f3 100644 --- a/app/Http/Requests/Client/UpdateClientRequest.php +++ b/app/Http/Requests/Client/UpdateClientRequest.php @@ -54,7 +54,7 @@ class UpdateClientRequest extends Request //$rules['id_number'] = 'unique:clients,id_number,,id,company_id,' . auth()->user()->company()->id; $rules['id_number'] = 'unique:clients,id_number,'.$this->id.',id,company_id,'.$this->company_id; $rules['settings'] = new ValidClientGroupSettingsRule(); - $rules['contacts.*.email'] = 'nullable|distinct'; + $rules['contacts.*.email'] = 'bail|nullable|distinct|sometimes|email'; $rules['contacts.*.password'] = [ 'nullable', 'sometimes', diff --git a/app/Http/Requests/User/StoreUserRequest.php b/app/Http/Requests/User/StoreUserRequest.php index a4a73685e1e3..0786dda42de9 100644 --- a/app/Http/Requests/User/StoreUserRequest.php +++ b/app/Http/Requests/User/StoreUserRequest.php @@ -39,9 +39,9 @@ class StoreUserRequest extends Request $rules['last_name'] = 'required|string|max:100'; if (config('ninja.db.multi_db_enabled')) { - $rules['email'] = [new ValidUserForCompany(), Rule::unique('users')]; + $rules['email'] = ['email', new ValidUserForCompany(), Rule::unique('users')]; } else { - $rules['email'] = Rule::unique('users'); + $rules['email'] = ['email',Rule::unique('users')]; } diff --git a/app/Http/Requests/User/UpdateUserRequest.php b/app/Http/Requests/User/UpdateUserRequest.php index 04adff66a7a1..cb2ca75f3fa9 100644 --- a/app/Http/Requests/User/UpdateUserRequest.php +++ b/app/Http/Requests/User/UpdateUserRequest.php @@ -35,7 +35,7 @@ class UpdateUserRequest extends Request ]; if (isset($input['email'])) { - $rules['email'] = ['email:rfc,dns', 'sometimes', new UniqueUserRule($this->user, $input['email'])]; + $rules['email'] = ['email', 'sometimes', new UniqueUserRule($this->user, $input['email'])]; } return $rules; diff --git a/app/Http/ViewComposers/PortalComposer.php b/app/Http/ViewComposers/PortalComposer.php index 45a8f87b9bb0..d7d7ae179d9b 100644 --- a/app/Http/ViewComposers/PortalComposer.php +++ b/app/Http/ViewComposers/PortalComposer.php @@ -21,6 +21,8 @@ use Illuminate\View\View; */ class PortalComposer { + public $settings; + /** * Bind data to the view. * @@ -45,13 +47,15 @@ class PortalComposer return []; } + $this->settings = auth()->user()->client->getMergedSettings(); + $data['sidebar'] = $this->sidebarMenu(); $data['header'] = []; $data['footer'] = []; $data['countries'] = TranslationHelper::getCountries(); $data['company'] = auth()->user()->company; $data['client'] = auth()->user()->client; - $data['settings'] = auth()->user()->client->getMergedSettings(); + $data['settings'] = $this->settings; $data['currencies'] = TranslationHelper::getCurrencies(); $data['multiple_contacts'] = session()->get('multiple_contacts'); @@ -63,7 +67,9 @@ class PortalComposer { $data = []; - // $data[] = [ 'title' => ctrans('texts.dashboard'), 'url' => 'client.dashboard', 'icon' => 'activity']; + if($this->settings->enable_client_portal_dashboard == TRUE) + $data[] = [ 'title' => ctrans('texts.dashboard'), 'url' => 'client.dashboard', 'icon' => 'activity']; + $data[] = ['title' => ctrans('texts.invoices'), 'url' => 'client.invoices.index', 'icon' => 'file-text']; $data[] = ['title' => ctrans('texts.recurring_invoices'), 'url' => 'client.recurring_invoices.index', 'icon' => 'file']; $data[] = ['title' => ctrans('texts.payments'), 'url' => 'client.payments.index', 'icon' => 'credit-card']; diff --git a/app/Jobs/Mail/EntitySentMailer.php b/app/Jobs/Mail/EntitySentMailer.php index e36cd521e9c9..b8c5bc988906 100644 --- a/app/Jobs/Mail/EntitySentMailer.php +++ b/app/Jobs/Mail/EntitySentMailer.php @@ -39,6 +39,7 @@ class EntitySentMailer extends BaseMailerJob implements ShouldQueue public $settings; + public $template; /** * Create a new job instance. * @@ -47,7 +48,7 @@ class EntitySentMailer extends BaseMailerJob implements ShouldQueue * @param $user * @param $company */ - public function __construct($invitation, $entity_type, $user, $company) + public function __construct($invitation, $entity_type, $user, $company, $template) { $this->company = $company; @@ -60,6 +61,8 @@ class EntitySentMailer extends BaseMailerJob implements ShouldQueue $this->entity_type = $entity_type; $this->settings = $invitation->contact->client->getMergedSettings(); + + $this->template = $template; } /** @@ -69,6 +72,8 @@ class EntitySentMailer extends BaseMailerJob implements ShouldQueue */ public function handle() { + nlog("entity sent mailer"); + /*If we are migrating data we don't want to fire these notification*/ if ($this->company->is_disabled) { return true; @@ -80,7 +85,7 @@ class EntitySentMailer extends BaseMailerJob implements ShouldQueue //if we need to set an email driver do it now $this->setMailDriver(); - $mail_obj = (new EntitySentObject($this->invitation, $this->entity_type))->build(); + $mail_obj = (new EntitySentObject($this->invitation, $this->entity_type, $this->template))->build(); $mail_obj->from = [config('mail.from.address'), config('mail.from.name')]; try { diff --git a/app/Jobs/Ninja/SendReminders.php b/app/Jobs/Ninja/SendReminders.php index 02c51f9f7693..278cbb9898d9 100644 --- a/app/Jobs/Ninja/SendReminders.php +++ b/app/Jobs/Ninja/SendReminders.php @@ -216,7 +216,7 @@ class SendReminders implements ShouldQueue if ($this->checkSendSetting($invoice, $template)) { - event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars())); + event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(), $template)); } $invoice->last_sent_date = now(); diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index ea75bd00d5a9..b66f1a164ae1 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -94,10 +94,7 @@ class SendRecurring implements ShouldQueue nlog("last send date = " . $this->recurring_invoice->last_sent_date); $this->recurring_invoice->save(); - - //this is duplicated!! - // if ($invoice->invitations->count() > 0) - // event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars())); + } public function failed($exception = null) diff --git a/app/Jobs/Util/ReminderJob.php b/app/Jobs/Util/ReminderJob.php index 70a8cb378888..ea72979d617d 100644 --- a/app/Jobs/Util/ReminderJob.php +++ b/app/Jobs/Util/ReminderJob.php @@ -66,7 +66,7 @@ class ReminderJob implements ShouldQueue }); if ($invoice->invitations->count() > 0) { - event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars())); + event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars(), $reminder_template)); } } else { $invoice->next_send_date = null; diff --git a/app/Jobs/Util/UploadFile.php b/app/Jobs/Util/UploadFile.php index 68d896ab7424..4f070a8c9392 100644 --- a/app/Jobs/Util/UploadFile.php +++ b/app/Jobs/Util/UploadFile.php @@ -66,6 +66,9 @@ class UploadFile implements ShouldQueue */ public function handle() : ?Document { + if(!$this->file) + return null; + $path = self::PROPERTIES[$this->type]['path']; if ($this->company) { diff --git a/app/Listeners/Credit/CreditEmailedNotification.php b/app/Listeners/Credit/CreditEmailedNotification.php index 085f2c6201b5..83d334d98a67 100644 --- a/app/Listeners/Credit/CreditEmailedNotification.php +++ b/app/Listeners/Credit/CreditEmailedNotification.php @@ -51,7 +51,7 @@ class CreditEmailedNotification implements ShouldQueue if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) { unset($methods[$key]); - EntitySentMailer::dispatch($event->invitation, 'credit', $user, $event->invitation->company); + EntitySentMailer::dispatch($event->invitation, 'credit', $user, $event->invitation->company, $event->template); $first_notification_sent = false; } diff --git a/app/Listeners/Invoice/CreateInvoicePdf.php b/app/Listeners/Invoice/CreateInvoicePdf.php index 56408b4037f9..91d5428fc6b1 100644 --- a/app/Listeners/Invoice/CreateInvoicePdf.php +++ b/app/Listeners/Invoice/CreateInvoicePdf.php @@ -36,8 +36,26 @@ class CreateInvoicePdf implements ShouldQueue { MultiDB::setDb($event->company->db); - $event->invoice->invitations->each(function ($invitation) { - CreateEntityPdf::dispatch($invitation); - }); + if(isset($event->invoice)) + { + $event->invoice->invitations->each(function ($invitation) { + CreateEntityPdf::dispatch($invitation); + }); + } + + if(isset($event->quote)) + { + $event->quote->invitations->each(function ($invitation) { + CreateEntityPdf::dispatch($invitation); + }); + } + + if(isset($event->credit)) + { + $event->credit->invitations->each(function ($invitation) { + CreateEntityPdf::dispatch($invitation); + }); + } + } } diff --git a/app/Listeners/Invoice/InvoiceEmailedNotification.php b/app/Listeners/Invoice/InvoiceEmailedNotification.php index e31356728ab3..08e9377dce1d 100644 --- a/app/Listeners/Invoice/InvoiceEmailedNotification.php +++ b/app/Listeners/Invoice/InvoiceEmailedNotification.php @@ -51,7 +51,7 @@ class InvoiceEmailedNotification implements ShouldQueue if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) { unset($methods[$key]); - EntitySentMailer::dispatch($event->invitation, 'invoice', $user, $event->invitation->company); + EntitySentMailer::dispatch($event->invitation, 'invoice', $user, $event->invitation->company, $event->template); $first_notification_sent = false; } diff --git a/app/Listeners/Quote/QuoteEmailedNotification.php b/app/Listeners/Quote/QuoteEmailedNotification.php index a04e3595f96f..5098707380cd 100644 --- a/app/Listeners/Quote/QuoteEmailedNotification.php +++ b/app/Listeners/Quote/QuoteEmailedNotification.php @@ -51,7 +51,7 @@ class QuoteEmailedNotification implements ShouldQueue if (($key = array_search('mail', $methods)) !== false && $first_notification_sent === true) { unset($methods[$key]); - EntitySentMailer::dispatch($event->invitation, 'quote', $user, $event->invitation->company); + EntitySentMailer::dispatch($event->invitation, 'quote', $user, $event->invitation->company, $event->template); $first_notification_sent = false; } @@ -60,4 +60,4 @@ class QuoteEmailedNotification implements ShouldQueue $user->notify($notification); } } -} +} \ No newline at end of file diff --git a/app/Mail/Admin/EntitySentObject.php b/app/Mail/Admin/EntitySentObject.php index cf9da0f7dd28..f8cd6a2a8e3b 100644 --- a/app/Mail/Admin/EntitySentObject.php +++ b/app/Mail/Admin/EntitySentObject.php @@ -28,17 +28,26 @@ class EntitySentObject public $settings; - public function __construct($invitation, $entity_type) + public $template; + + private $template_subject; + + private $template_body; + + public function __construct($invitation, $entity_type, $template) { $this->invitation = $invitation; $this->entity_type = $entity_type; $this->entity = $invitation->{$entity_type}; $this->contact = $invitation->contact; $this->company = $invitation->company; + $this->template = $template; } public function build() { + $this->setTemplate(); + $mail_obj = new stdClass; $mail_obj->amount = $this->getAmount(); $mail_obj->subject = $this->getSubject(); @@ -49,6 +58,47 @@ class EntitySentObject return $mail_obj; } + private function setTemplate() + { + nlog($this->template); + + switch ($this->template) { + case 'invoice': + $this->template_subject = "texts.notification_invoice_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'reminder1': + $this->template_subject = "texts.notification_invoice_reminder1_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'reminder2': + $this->template_subject = "texts.notification_invoice_reminder2_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'reminder3': + $this->template_subject = "texts.notification_invoice_reminder3_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'reminder_endless': + $this->template_subject = "texts.notification_invoice_reminder_endless_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + case 'quote': + $this->template_subject = "texts.notification_quote_sent_subject"; + $this->template_body = "texts.notification_quote_sent"; + break; + case 'credit': + $this->template_subject = "texts.notification_credit_sent_subject"; + $this->template_body = "texts.notification_credit_sent"; + break; + + default: + $this->template_subject = "texts.notification_invoice_sent_subject"; + $this->template_body = "texts.notification_invoice_sent"; + break; + } + } + private function getAmount() { return Number::formatMoney($this->entity->amount, $this->entity->client); @@ -58,7 +108,7 @@ class EntitySentObject { return ctrans( - "texts.notification_{$this->entity_type}_sent_subject", + $this->template_subject, [ 'client' => $this->contact->present()->name(), 'invoice' => $this->entity->number, @@ -73,7 +123,7 @@ class EntitySentObject return [ 'title' => $this->getSubject(), 'message' => ctrans( - "texts.notification_{$this->entity_type}_sent", + $this->template_body, [ 'amount' => $this->getAmount(), 'client' => $this->contact->present()->name(), diff --git a/app/Models/Credit.php b/app/Models/Credit.php index 5ef477ff4fe7..e30520c04c64 100644 --- a/app/Models/Credit.php +++ b/app/Models/Credit.php @@ -52,7 +52,6 @@ class Credit extends BaseModel 'terms', 'public_notes', 'private_notes', - 'invoice_type_id', 'tax_name1', 'tax_rate1', 'tax_name2', diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index d8982aa2ad70..6886629fc7ae 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -63,7 +63,6 @@ class Invoice extends BaseModel 'terms', 'public_notes', 'private_notes', - 'invoice_type_id', 'tax_name1', 'tax_rate1', 'tax_name2', @@ -434,12 +433,11 @@ class Invoice extends BaseModel return $this->calc()->getTotal(); } - - public function entityEmailEvent($invitation, $reminder_template) + public function entityEmailEvent($invitation, $reminder_template, $template) { switch ($reminder_template) { case 'invoice': - event(new InvoiceWasEmailed($invitation, $invitation->company, Ninja::eventVars())); + event(new InvoiceWasEmailed($invitation, $invitation->company, Ninja::eventVars(), $template)); break; case 'reminder1': event(new InvoiceReminderWasEmailed($invitation, $invitation->company, Ninja::eventVars(), Activity::INVOICE_REMINDER1_SENT)); diff --git a/app/Models/Quote.php b/app/Models/Quote.php index c1936530632a..8421a3e02c74 100644 --- a/app/Models/Quote.php +++ b/app/Models/Quote.php @@ -52,7 +52,6 @@ class Quote extends BaseModel 'public_notes', 'private_notes', 'project_id', - 'invoice_type_id', 'tax_name1', 'tax_rate1', 'tax_name2', diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 12f366d41576..9392b87c3349 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -226,6 +226,7 @@ class EventServiceProvider extends ServiceProvider ], CreditWasUpdated::class => [ UpdatedCreditActivity::class, + CreateInvoicePdf::class, ], CreditWasEmailedAndFailed::class => [ ], @@ -334,6 +335,7 @@ class EventServiceProvider extends ServiceProvider ], QuoteWasUpdated::class => [ QuoteUpdatedActivity::class, + CreateInvoicePdf::class, ], QuoteWasEmailed::class => [ QuoteEmailActivity::class, diff --git a/app/Services/Invoice/TriggeredActions.php b/app/Services/Invoice/TriggeredActions.php index 8c3b4a5d5787..74dc9dcbbe7e 100644 --- a/app/Services/Invoice/TriggeredActions.php +++ b/app/Services/Invoice/TriggeredActions.php @@ -66,7 +66,7 @@ class TriggeredActions extends AbstractService }); if ($this->invoice->invitations->count() > 0) { - event(new InvoiceWasEmailed($this->invoice->invitations->first(), $this->invoice->company, Ninja::eventVars())); + event(new InvoiceWasEmailed($this->invoice->invitations->first(), $this->invoice->company, Ninja::eventVars(), 'invoice')); } } } diff --git a/app/Services/Quote/GetQuotePdf.php b/app/Services/Quote/GetQuotePdf.php index cad03cf3e250..63eb15ef5dca 100644 --- a/app/Services/Quote/GetQuotePdf.php +++ b/app/Services/Quote/GetQuotePdf.php @@ -34,7 +34,7 @@ class GetQuotePdf extends AbstractService $invitation = $this->quote->invitations->where('client_contact_id', $this->contact->id)->first(); - $path = $this->quote->client->invoice_filepath(); + $path = $this->quote->client->quote_filepath(); $file_path = $path.$this->quote->number.'.pdf'; diff --git a/app/Services/Quote/QuoteService.php b/app/Services/Quote/QuoteService.php index ea17b3deb875..33939e362615 100644 --- a/app/Services/Quote/QuoteService.php +++ b/app/Services/Quote/QuoteService.php @@ -58,9 +58,9 @@ class QuoteService return $this; } - $convert_quote = new ConvertQuote($this->quote->client); + $convert_quote = (new ConvertQuote($this->quote->client))->run($this->quote); - $this->invoice = $convert_quote->run($this->quote); + $this->invoice = $convert_quote; $this->quote->fresh(); @@ -96,9 +96,7 @@ class QuoteService public function markSent() :self { - $mark_sent = new MarkSent($this->quote->client, $this->quote); - - $this->quote = $mark_sent->run(); + $this->quote = (new MarkSent($this->quote->client, $this->quote))->run(); return $this; } diff --git a/app/Transformers/Contact/InvoiceTransformer.php b/app/Transformers/Contact/InvoiceTransformer.php index 29a69f9419da..f850d165faa7 100644 --- a/app/Transformers/Contact/InvoiceTransformer.php +++ b/app/Transformers/Contact/InvoiceTransformer.php @@ -43,7 +43,6 @@ class InvoiceTransformer extends EntityTransformer 'terms' => $invoice->terms ?: '', 'public_notes' => $invoice->public_notes ?: '', 'is_deleted' => (bool) $invoice->is_deleted, - 'invoice_type_id' => (int) $invoice->invoice_type_id, 'tax_name1' => $invoice->tax_name1 ? $invoice->tax_name1 : '', 'tax_rate1' => (float) $invoice->tax_rate1, 'tax_name2' => $invoice->tax_name2 ? $invoice->tax_name2 : '', diff --git a/app/Utils/Traits/SavesDocuments.php b/app/Utils/Traits/SavesDocuments.php index ac2567c06a7e..8ac249650b37 100644 --- a/app/Utils/Traits/SavesDocuments.php +++ b/app/Utils/Traits/SavesDocuments.php @@ -22,9 +22,11 @@ trait SavesDocuments if ($entity instanceof Company) { $account = $entity->account; $company = $entity; + $user = auth()->user(); } else { $account = $entity->company->account; $company = $entity->company; + $user = $entity->user; } if (! $account->hasFeature(Account::FEATURE_DOCUMENTS)) { @@ -35,8 +37,8 @@ trait SavesDocuments $document = UploadFile::dispatchNow( $document, UploadFile::DOCUMENT, - $entity->user, - $entity->company, + $user, + $company, $entity, null, $is_public @@ -49,9 +51,11 @@ trait SavesDocuments if ($entity instanceof Company) { $account = $entity->account; $company = $entity; + $user = auth()->user(); } else { $account = $entity->company->account; $company = $entity->company; + $user = $entity->user; } if (! $account->hasFeature(Account::FEATURE_DOCUMENTS)) { @@ -61,8 +65,8 @@ trait SavesDocuments $document = UploadFile::dispatchNow( $document, UploadFile::DOCUMENT, - $entity->user, - $entity->company, + $user, + $company, $entity, null, $is_public diff --git a/resources/js/clients/invoices/action-selectors.js b/resources/js/clients/invoices/action-selectors.js index 7f2792def0fb..3b8963761988 100644 --- a/resources/js/clients/invoices/action-selectors.js +++ b/resources/js/clients/invoices/action-selectors.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/invoices/payment.js b/resources/js/clients/invoices/payment.js index 41fabfbec3fd..08c6e4bdc29e 100644 --- a/resources/js/clients/invoices/payment.js +++ b/resources/js/clients/invoices/payment.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/payment_methods/authorize-authorize-card.js b/resources/js/clients/payment_methods/authorize-authorize-card.js index c154372f5d1f..fbca10ab7b63 100644 --- a/resources/js/clients/payment_methods/authorize-authorize-card.js +++ b/resources/js/clients/payment_methods/authorize-authorize-card.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/payments/authorize-credit-card-payment.js b/resources/js/clients/payments/authorize-credit-card-payment.js index c4b2dc1a1258..972a6902a52d 100644 --- a/resources/js/clients/payments/authorize-credit-card-payment.js +++ b/resources/js/clients/payments/authorize-credit-card-payment.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/payments/checkout.com.js b/resources/js/clients/payments/checkout.com.js index bf06abbbf45e..721e8a30c650 100644 --- a/resources/js/clients/payments/checkout.com.js +++ b/resources/js/clients/payments/checkout.com.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/payments/stripe-ach.js b/resources/js/clients/payments/stripe-ach.js index 0b38bdf6a6d0..156b9ed1961d 100644 --- a/resources/js/clients/payments/stripe-ach.js +++ b/resources/js/clients/payments/stripe-ach.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/payments/stripe-alipay.js b/resources/js/clients/payments/stripe-alipay.js index 7acb9d788264..417267565154 100644 --- a/resources/js/clients/payments/stripe-alipay.js +++ b/resources/js/clients/payments/stripe-alipay.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/payments/stripe-credit-card.js b/resources/js/clients/payments/stripe-credit-card.js index a23e62ab1b34..d1ac338b9df1 100644 --- a/resources/js/clients/payments/stripe-credit-card.js +++ b/resources/js/clients/payments/stripe-credit-card.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/payments/stripe-sofort.js b/resources/js/clients/payments/stripe-sofort.js index 58dac03e1014..71e0d58f97bf 100644 --- a/resources/js/clients/payments/stripe-sofort.js +++ b/resources/js/clients/payments/stripe-sofort.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/quotes/action-selectors.js b/resources/js/clients/quotes/action-selectors.js index 55442d248d36..f45041778ea6 100644 --- a/resources/js/clients/quotes/action-selectors.js +++ b/resources/js/clients/quotes/action-selectors.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/quotes/approve.js b/resources/js/clients/quotes/approve.js index 37e7ed48cbfe..b4d7e18eb32e 100644 --- a/resources/js/clients/quotes/approve.js +++ b/resources/js/clients/quotes/approve.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/shared/multiple-downloads.js b/resources/js/clients/shared/multiple-downloads.js index 9ce39ba0fd0c..d3662fff8377 100644 --- a/resources/js/clients/shared/multiple-downloads.js +++ b/resources/js/clients/shared/multiple-downloads.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/clients/shared/pdf.js b/resources/js/clients/shared/pdf.js index e1e335343edf..10ccb64e1222 100644 --- a/resources/js/clients/shared/pdf.js +++ b/resources/js/clients/shared/pdf.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/js/setup/setup.js b/resources/js/setup/setup.js index e925447f313b..0c9ae19bcd84 100644 --- a/resources/js/setup/setup.js +++ b/resources/js/setup/setup.js @@ -3,7 +3,7 @@ * * @link https://github.com/invoiceninja/invoiceninja source repository * - * @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com) + * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * * @license https://opensource.org/licenses/AAL */ diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 871f57b567b2..9d67109ff33b 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -3242,7 +3242,7 @@ return [ 'checkout_com' => 'Checkout.com', - 'footer_label' => 'Copyright © :year :company. All rights reserved.', + 'footer_label' => 'Copyright © :year :company.', 'credit_card_invalid' => 'Provided credit card number is not valid.', 'month_invalid' => 'Provided month is not valid.', diff --git a/resources/views/portal/ninja2020/components/general/footer.blade.php b/resources/views/portal/ninja2020/components/general/footer.blade.php index 0bc065662e54..7e11fa5d9e66 100644 --- a/resources/views/portal/ninja2020/components/general/footer.blade.php +++ b/resources/views/portal/ninja2020/components/general/footer.blade.php @@ -8,9 +8,9 @@ @endif @if(strlen($client->getSetting('client_portal_privacy_policy')) > 1 && strlen($client->getSetting('client_portal_terms')) > 1) - Long dash between items. --> @endif @if(strlen($client->getSetting('client_portal_terms')) > 1) diff --git a/resources/views/portal/ninja2020/components/general/sidebar/desktop.blade.php b/resources/views/portal/ninja2020/components/general/sidebar/desktop.blade.php index acb371424aaf..9887232bd1f7 100644 --- a/resources/views/portal/ninja2020/components/general/sidebar/desktop.blade.php +++ b/resources/views/portal/ninja2020/components/general/sidebar/desktop.blade.php @@ -2,7 +2,7 @@