mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 18:07:35 -04:00 
			
		
		
		
	Working on manual send reminders #1234
This commit is contained in:
		
							parent
							
								
									3e4528e340
								
							
						
					
					
						commit
						d38101545f
					
				| @ -4,12 +4,20 @@ namespace App\Models; | ||||
| 
 | ||||
| use Auth; | ||||
| use Eloquent; | ||||
| use Laracasts\Presenter\PresentableTrait; | ||||
| 
 | ||||
| /** | ||||
|  * Class Activity. | ||||
|  */ | ||||
| class Activity extends Eloquent | ||||
| { | ||||
|     use PresentableTrait; | ||||
| 
 | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $presenter = 'App\Ninja\Presenters\ActivityPresenter'; | ||||
| 
 | ||||
|     /** | ||||
|      * @var bool | ||||
|      */ | ||||
|  | ||||
| @ -9,6 +9,7 @@ use App\Events\QuoteInvitationWasEmailed; | ||||
| use App\Events\QuoteWasCreated; | ||||
| use App\Events\QuoteWasUpdated; | ||||
| use App\Libraries\CurlUtils; | ||||
| use App\Models\Activity; | ||||
| use DateTime; | ||||
| use Illuminate\Database\Eloquent\SoftDeletes; | ||||
| use Laracasts\Presenter\PresentableTrait; | ||||
| @ -1441,6 +1442,16 @@ class Invoice extends EntityModel implements BalanceAffecting | ||||
| 
 | ||||
|         return $statuses; | ||||
|     } | ||||
| 
 | ||||
|     public function emailHistory() | ||||
|     { | ||||
|         return Activity::scope() | ||||
|                 ->with(['contact']) | ||||
|                 ->whereInvoiceId($this->id) | ||||
|                 ->whereIn('activity_type_id', [ACTIVITY_TYPE_EMAIL_INVOICE, ACTIVITY_TYPE_EMAIL_QUOTE]) | ||||
|                 ->orderBy('id', 'desc') | ||||
|                 ->get(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Invoice::creating(function ($invoice) { | ||||
|  | ||||
							
								
								
									
										39
									
								
								app/Ninja/Presenters/ActivityPresenter.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Ninja/Presenters/ActivityPresenter.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace App\Ninja\Presenters; | ||||
| 
 | ||||
| use Laracasts\Presenter\Presenter; | ||||
| use Utils; | ||||
| 
 | ||||
| class ActivityPresenter extends Presenter | ||||
| { | ||||
|     public function createdAt() | ||||
|     { | ||||
|         return Utils::timestampToDateTimeString(strtotime($this->entity->created_at)); | ||||
|     } | ||||
| 
 | ||||
|     public function createdAtDate() | ||||
|     { | ||||
|         return Utils::dateToString($this->entity->created_at); | ||||
|     } | ||||
| 
 | ||||
|     public function user() | ||||
|     { | ||||
|         if ($this->entity->is_system) { | ||||
|             return '<i>' . trans('texts.system') . '</i>'; | ||||
|         } else { | ||||
|             return $this->entity->user->getDisplayName(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public function notes() | ||||
|     { | ||||
|         if ($this->entity->notes) { | ||||
|             return trans('texts.notes_' . $this->entity->notes); | ||||
|         } elseif (in_array($this->entity->activity_type_id, [ACTIVITY_TYPE_EMAIL_INVOICE, ACTIVITY_TYPE_EMAIL_QUOTE])) { | ||||
|             return trans('texts.initial_email'); | ||||
|         } else { | ||||
|             return ''; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -3,6 +3,7 @@ | ||||
| namespace App\Ninja\Presenters; | ||||
| 
 | ||||
| use App\Libraries\Skype\InvoiceCard; | ||||
| use App\Models\Activity; | ||||
| use Carbon; | ||||
| use DropdownButton; | ||||
| use stdClass; | ||||
|  | ||||
| @ -494,7 +494,7 @@ $LANG = array( | ||||
|     'email_address' => 'Email address', | ||||
|     'lets_go' => 'Let\'s go', | ||||
|     'password_recovery' => 'Password Recovery', | ||||
|     'send_email' => 'Send email', | ||||
|     'send_email' => 'Send Email', | ||||
|     'set_password' => 'Set Password', | ||||
|     'converted' => 'Converted', | ||||
|     'email_approved' => 'Email me when a quote is <b>approved</b>', | ||||
| @ -2347,6 +2347,13 @@ $LANG = array( | ||||
|     'inactivity_logout' => 'Due to inactivity, you have been automatically logged out.', | ||||
|     'mark_active' => 'Mark Active', | ||||
|     'send_automatically' => 'Send Automatically', | ||||
|     'template' => 'Template', | ||||
|     'initial_email' => 'Initial Email', | ||||
|     'invoice_not_emailed' => 'This invoice hasn\'t been emailed.', | ||||
|     'quote_not_emailed' => 'This quote hasn\'t been emailed.', | ||||
|     'days_ago' => ':count day ago|:count days ago', | ||||
|     'sent_by' => 'Sent by :user', | ||||
|     'recipients' => 'Recipients', | ||||
| 
 | ||||
| ); | ||||
| 
 | ||||
|  | ||||
| @ -799,6 +799,8 @@ | ||||
| 	  </div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	@include('invoices.email') | ||||
| 
 | ||||
|     {!! Former::close() !!} | ||||
|     </form> | ||||
| 
 | ||||
| @ -1284,7 +1286,11 @@ | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 		sweetConfirm(function() { | ||||
| 		$('#recipients').html(getSendToEmails()); | ||||
| 		$('#emailModal').modal('show'); | ||||
| 	} | ||||
| 
 | ||||
| 	function onConfirmEmailClick() { | ||||
| 		model.invoice().is_public(true); | ||||
| 		var accountLanguageId = parseInt({{ $account->language_id ?: '0' }}); | ||||
| 		var clientLanguageId = parseInt(model.invoice().client().language_id()) || 0; | ||||
| @ -1299,9 +1305,14 @@ | ||||
| 		} else { | ||||
| 			preparePdfData('email'); | ||||
| 		} | ||||
| 		}, getSendToEmails()); | ||||
| 	} | ||||
| 
 | ||||
| 	@if (Utils::isNinjaDev()) | ||||
| 		$(function() { | ||||
| 			onEmailClick(); | ||||
| 		}) | ||||
| 	@endif | ||||
| 
 | ||||
| 	function onSaveDraftClick() { | ||||
| 		model.invoice().is_public(false); | ||||
| 		onSaveClick(); | ||||
| @ -1310,7 +1321,7 @@ | ||||
| 	function onMarkSentClick() { | ||||
| 		if (model.invoice().is_recurring()) { | ||||
|             // warn invoice will be emailed when saving new recurring invoice
 | ||||
|             var text = getSendToEmails() + '\n' + "{!! trans("texts.confirm_recurring_timing") !!}"; | ||||
|             var text = '\n' + getSendToEmails() + '\n\n' + "{!! trans("texts.confirm_recurring_timing") !!}"; | ||||
|             var title = "{!! trans("texts.confirm_recurring_email_$entityType") !!}"; | ||||
|             sweetConfirm(function() { | ||||
| 				model.invoice().is_public(true); | ||||
|  | ||||
							
								
								
									
										93
									
								
								resources/views/invoices/email.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								resources/views/invoices/email.blade.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | ||||
| <div class="modal fade" id="emailModal" tabindex="-1" role="dialog" aria-labelledby="emailModalLabel" aria-hidden="true"> | ||||
|     <div class="modal-dialog" style="min-width:150px"> | ||||
|         <div class="modal-content"> | ||||
| 
 | ||||
|             <div class="modal-header"> | ||||
|                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||||
|                 <h4 class="modal-title" id="emailModalLabel">{{ trans('texts.email_invoice') }}</h4> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="modal-body"> | ||||
|             <div class="panel-body"> | ||||
| 
 | ||||
|                 {!! Former::plaintext('recipients') | ||||
|                         ->value('') !!} | ||||
| 
 | ||||
|                 {!! Former::select('template') | ||||
|                         ->options([ | ||||
|                             'initial' => trans('texts.initial_email'), | ||||
|                             'reminder1' => trans('texts.first_reminder'), | ||||
|                             'reminder2' => trans('texts.second_reminder'), | ||||
|                             'reminder3' => trans('texts.third_reminder'), | ||||
|                         ]) !!} | ||||
| 
 | ||||
|                 <br/> | ||||
|                 <div role="tabpanel"> | ||||
|                     <ul class="nav nav-tabs" role="tablist" style="border: none"> | ||||
|                         <li role="presentation" class="active"> | ||||
|                             <a href="#preview" aria-controls="preview" role="tab" data-toggle="tab">{{ trans('texts.preview') }}</a> | ||||
|                         </li> | ||||
|                         <li role="presentation"> | ||||
|                             <a href="#customize" aria-controls="customize" role="tab" data-toggle="tab">{{ trans('texts.customize') }}</a> | ||||
|                         </li> | ||||
|                         <li role="presentation"> | ||||
|                             <a href="#history" aria-controls="history" role="tab" data-toggle="tab">{{ trans('texts.history') }}</a> | ||||
|                         </li> | ||||
|                     </ul> | ||||
|                 </div> | ||||
|                 <div class="tab-content"> | ||||
|                     <div role="tabpanel" class="tab-pane active" id="preview"> | ||||
|                         <div id="emailSubject"></div> | ||||
|                         <div id="emailBody"></div> | ||||
|                     </div> | ||||
|                     <div role="tabpanel" class="tab-pane" id="customize"> | ||||
| 
 | ||||
|                     </div> | ||||
|                     <div role="tabpanel" class="tab-pane" id="history"> | ||||
|                         <br/> | ||||
|                         @if (count($activities = $invoice->emailHistory())) | ||||
|                         <table class="table table-striped data-table"> | ||||
|                             <tr> | ||||
|                                 <th>{{ trans('texts.template')}}</th> | ||||
|                                 <th>{{ trans('texts.contact')}}</th> | ||||
|                                 <th>{{ trans('texts.date')}}</th> | ||||
|                             </tr> | ||||
|                             @foreach ($activities as $activity) | ||||
|                             <tr> | ||||
|                                 <td>{{ $activity->present()->notes }}</td> | ||||
|                                 <td> | ||||
|                                     <span title="{{ trans('texts.sent_by', ['user' => $activity->present()->user]) }}"> | ||||
|                                         {{ $activity->contact->getDisplayName() }} | ||||
|                                     </span> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     <span title="{{ $activity->present()->createdAt }}"> | ||||
|                                         {{ $activity->present()->createdAtDate }} - {{ trans_choice('texts.days_ago', $activity->created_at->diffInDays()) }} | ||||
|                                     </span> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             @endforeach | ||||
|                         </table> | ||||
|                         @else | ||||
|                             <center style="font-size:16px;color:#888888;padding-top:20px;"> | ||||
|                                 {{ trans("texts.{$invoice->getEntityType()}_not_emailed") }} | ||||
|                             </center> | ||||
|                         @endif | ||||
|                     </div> | ||||
|                 </div> | ||||
| 
 | ||||
|             </div> | ||||
|             </div> | ||||
| 
 | ||||
|             <div class="modal-footer" style="margin-top: 0px"> | ||||
|                 <button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button> | ||||
|                 <button type="button" class="btn btn-info" onclick="onConfirmEmailClick()">{{ trans('texts.send_email') }}</button> | ||||
|             </div> | ||||
| 
 | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <script type="text/javascript"> | ||||
| 
 | ||||
| </script> | ||||
| @ -641,13 +641,13 @@ function ContactModel(data) { | ||||
|     self.displayName = ko.computed(function() { | ||||
|         var str = ''; | ||||
|         if (self.first_name() || self.last_name()) { | ||||
|             str += (self.first_name() || '') + ' ' + (self.last_name() || '') + '\n'; | ||||
|             str += (self.first_name() || '') + ' ' + (self.last_name() || '') + ' '; | ||||
|         } | ||||
|         if (self.email()) { | ||||
|             str += self.email() + '\n'; | ||||
|             str += '<' + self.email() + '>'; | ||||
|         } | ||||
| 
 | ||||
|         return str; | ||||
|         return str + '<br/>'; | ||||
|     }); | ||||
| 
 | ||||
|     self.email.display = ko.computed(function() { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user