mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #6781 from turbo124/v5-develop
Fixes for displaying valid credits
This commit is contained in:
commit
c401aceac1
@ -19,6 +19,7 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Jobs\Entity\CreateRawPdf;
|
use App\Jobs\Entity\CreateRawPdf;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\InvoiceInvitation;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\MakesDates;
|
use App\Utils\Traits\MakesDates;
|
||||||
@ -65,6 +66,9 @@ class InvitationController extends Controller
|
|||||||
private function genericRouter(string $entity, string $invitation_key)
|
private function genericRouter(string $entity, string $invitation_key)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(!in_array($entity, ['invoice', 'credit', 'quote', 'recurring_invoice']))
|
||||||
|
return response()->json(['message' => 'Invalid resource request']);
|
||||||
|
|
||||||
$key = $entity.'_id';
|
$key = $entity.'_id';
|
||||||
|
|
||||||
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
|
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
|
||||||
@ -133,6 +137,9 @@ class InvitationController extends Controller
|
|||||||
private function returnRawPdf(string $entity, string $invitation_key)
|
private function returnRawPdf(string $entity, string $invitation_key)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(!in_array($entity, ['invoice', 'credit', 'quote', 'recurring_invoice']))
|
||||||
|
return response()->json(['message' => 'Invalid resource request']);
|
||||||
|
|
||||||
$key = $entity.'_id';
|
$key = $entity.'_id';
|
||||||
|
|
||||||
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
|
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
|
||||||
@ -181,4 +188,12 @@ class InvitationController extends Controller
|
|||||||
return redirect()->route('client.payments.show', $payment->hashed_id);
|
return redirect()->route('client.payments.show', $payment->hashed_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function payInvoice(string $invitation_key)
|
||||||
|
{
|
||||||
|
$invitation = InvoiceInvitation::where('key', $invitation_key)
|
||||||
|
->with('contact.client')
|
||||||
|
->firstOrFail();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ class EmailController extends BaseController
|
|||||||
|
|
||||||
$entity_obj->invitations->each(function ($invitation) use ($data, $entity_string, $entity_obj, $template) {
|
$entity_obj->invitations->each(function ($invitation) use ($data, $entity_string, $entity_obj, $template) {
|
||||||
|
|
||||||
if (!$invitation->contact->trashed() && $invitation->contact->send_email && $invitation->contact->email) {
|
if (!$invitation->contact->trashed() && $invitation->contact->email) {
|
||||||
|
|
||||||
$entity_obj->service()->markSent()->save();
|
$entity_obj->service()->markSent()->save();
|
||||||
|
|
||||||
|
@ -234,21 +234,24 @@ class MigrationController extends BaseController
|
|||||||
public function startMigration(Request $request)
|
public function startMigration(Request $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
// v4 Laravel 6
|
|
||||||
|
|
||||||
// $companies = [];
|
|
||||||
|
|
||||||
// foreach($request->all() as $input){
|
|
||||||
|
|
||||||
// if($input instanceof UploadedFile)
|
|
||||||
// nlog('is file');
|
|
||||||
// else
|
|
||||||
// $companies[] = json_decode($input);
|
|
||||||
// }
|
|
||||||
|
|
||||||
nlog("Starting Migration");
|
nlog("Starting Migration");
|
||||||
|
|
||||||
$companies = json_decode($request->companies,1);
|
if($request->companies){
|
||||||
|
//handle Laravel 5.5 UniHTTP
|
||||||
|
$companies = json_decode($request->companies,1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//handle Laravel 6 Guzzle
|
||||||
|
$companies = [];
|
||||||
|
|
||||||
|
foreach($request->all() as $input){
|
||||||
|
|
||||||
|
if($input instanceof UploadedFile)
|
||||||
|
nlog('is file');
|
||||||
|
else
|
||||||
|
$companies[] = json_decode($input,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (app()->environment() === 'local') {
|
if (app()->environment() === 'local') {
|
||||||
nlog($request->all());
|
nlog($request->all());
|
||||||
@ -267,22 +270,11 @@ class MigrationController extends BaseController
|
|||||||
foreach($companies as $company)
|
foreach($companies as $company)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(!is_array($company))
|
||||||
|
continue;
|
||||||
|
|
||||||
$company = (array)$company;
|
$company = (array)$company;
|
||||||
|
|
||||||
// v4 Laravel 6
|
|
||||||
// $input = $request->all();
|
|
||||||
|
|
||||||
// foreach ($input as $company) {
|
|
||||||
|
|
||||||
// if($company instanceof UploadedFile)
|
|
||||||
// continue;
|
|
||||||
// else
|
|
||||||
// $company = json_decode($company,1);
|
|
||||||
|
|
||||||
// if (!$company || !is_int($company['company_index'] || !$request->file($company['company_index'])->isValid())) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$company_count = $user->account->companies()->count();
|
$company_count = $user->account->companies()->count();
|
||||||
|
@ -41,8 +41,9 @@ class CreditsTable extends Component
|
|||||||
->where('status_id', '<>', Credit::STATUS_DRAFT)
|
->where('status_id', '<>', Credit::STATUS_DRAFT)
|
||||||
->where('is_deleted', 0)
|
->where('is_deleted', 0)
|
||||||
->where(function ($query){
|
->where(function ($query){
|
||||||
$query->whereDate('due_date', '<=', now())
|
$query->whereDate('due_date', '>=', now())
|
||||||
->orWhereNull('due_date');
|
->orWhereNull('due_date')
|
||||||
|
->orWhere('due_date', '=', '');
|
||||||
})
|
})
|
||||||
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
|
@ -59,15 +59,15 @@ class SendRecurring implements ShouldQueue
|
|||||||
public function handle() : void
|
public function handle() : void
|
||||||
{
|
{
|
||||||
//reset all contacts here
|
//reset all contacts here
|
||||||
$this->recurring_invoice->client->contacts()->update(['send_email' => false]);
|
// $this->recurring_invoice->client->contacts()->update(['send_email' => false]);
|
||||||
|
|
||||||
$this->recurring_invoice->invitations->each(function ($invitation){
|
// $this->recurring_invoice->invitations->each(function ($invitation){
|
||||||
|
|
||||||
$contact = $invitation->contact;
|
// $contact = $invitation->contact;
|
||||||
$contact->send_email = true;
|
// $contact->send_email = true;
|
||||||
$contact->save();
|
// $contact->save();
|
||||||
|
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Generate Standard Invoice
|
// Generate Standard Invoice
|
||||||
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client);
|
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client);
|
||||||
@ -153,7 +153,7 @@ class SendRecurring implements ShouldQueue
|
|||||||
}
|
}
|
||||||
|
|
||||||
//important catch all here - we should never leave contacts send_email to false incase they are permanently set to false in the future.
|
//important catch all here - we should never leave contacts send_email to false incase they are permanently set to false in the future.
|
||||||
$this->recurring_invoice->client->contacts()->update(['send_email' => true]);
|
// $this->recurring_invoice->client->contacts()->update(['send_email' => true]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +395,7 @@ class BaseDriver extends AbstractPaymentDriver
|
|||||||
|
|
||||||
$invoices->first()->invitations->each(function ($invitation) use ($nmo) {
|
$invoices->first()->invitations->each(function ($invitation) use ($nmo) {
|
||||||
|
|
||||||
if ($invitation->contact->send_email && $invitation->contact->email) {
|
if ($invitation->contact->email) {
|
||||||
|
|
||||||
$nmo->to_user = $invitation->contact;
|
$nmo->to_user = $invitation->contact;
|
||||||
NinjaMailerJob::dispatch($nmo);
|
NinjaMailerJob::dispatch($nmo);
|
||||||
@ -459,7 +459,7 @@ class BaseDriver extends AbstractPaymentDriver
|
|||||||
|
|
||||||
$invoices->first()->invitations->each(function ($invitation) use ($nmo){
|
$invoices->first()->invitations->each(function ($invitation) use ($nmo){
|
||||||
|
|
||||||
if (!$invitation->contact->trashed() && $invitation->contact->send_email && $invitation->contact->email) {
|
if (!$invitation->contact->trashed() && $invitation->contact->email) {
|
||||||
|
|
||||||
$nmo->to_user = $invitation->contact;
|
$nmo->to_user = $invitation->contact;
|
||||||
NinjaMailerJob::dispatch($nmo);
|
NinjaMailerJob::dispatch($nmo);
|
||||||
|
@ -44,7 +44,7 @@ class SendEmail
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->credit->invitations->each(function ($invitation) {
|
$this->credit->invitations->each(function ($invitation) {
|
||||||
if (!$invitation->contact->trashed() && $invitation->contact->send_email && $invitation->contact->email) {
|
if (!$invitation->contact->trashed() && $invitation->contact->email) {
|
||||||
$email_builder = (new CreditEmail())->build($invitation, $this->reminder_template);
|
$email_builder = (new CreditEmail())->build($invitation, $this->reminder_template);
|
||||||
|
|
||||||
// EmailCredit::dispatchNow($email_builder, $invitation, $invitation->company);
|
// EmailCredit::dispatchNow($email_builder, $invitation, $invitation->company);
|
||||||
|
@ -44,7 +44,7 @@ class SendEmail extends AbstractService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->invoice->invitations->each(function ($invitation) {
|
$this->invoice->invitations->each(function ($invitation) {
|
||||||
if (!$invitation->contact->trashed() && $invitation->contact->send_email && $invitation->contact->email) {
|
if (!$invitation->contact->trashed() && $invitation->contact->email) {
|
||||||
EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template);
|
EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -33,7 +33,7 @@ class SendEmail
|
|||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$this->payment->client->contacts->each(function ($contact) {
|
$this->payment->client->contacts->each(function ($contact) {
|
||||||
if ($contact->send_email && $contact->email) {
|
if ($contact->email) {
|
||||||
EmailPayment::dispatchNow($this->payment, $this->payment->company, $contact);
|
EmailPayment::dispatchNow($this->payment, $this->payment->company, $contact);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -42,7 +42,7 @@ class SendEmail
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->quote->invitations->each(function ($invitation) {
|
$this->quote->invitations->each(function ($invitation) {
|
||||||
if (!$invitation->contact->trashed() && $invitation->contact->send_email && $invitation->contact->email) {
|
if (!$invitation->contact->trashed() && $invitation->contact->email) {
|
||||||
EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template);
|
EmailEntity::dispatchNow($invitation, $invitation->company, $this->reminder_template);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -270,7 +270,7 @@ trait MakesInvoiceValues
|
|||||||
if (! is_array($items)) {
|
if (! is_array($items)) {
|
||||||
$data;
|
$data;
|
||||||
}
|
}
|
||||||
|
nlog($items);
|
||||||
$locale_info = localeconv();
|
$locale_info = localeconv();
|
||||||
|
|
||||||
foreach ($items as $key => $item) {
|
foreach ($items as $key => $item) {
|
||||||
@ -297,10 +297,6 @@ trait MakesInvoiceValues
|
|||||||
$data[$key][$table_type.'.notes'] = Helpers::processReservedKeywords($item->notes, $this->client);
|
$data[$key][$table_type.'.notes'] = Helpers::processReservedKeywords($item->notes, $this->client);
|
||||||
$data[$key][$table_type.'.description'] = Helpers::processReservedKeywords($item->notes, $this->client);
|
$data[$key][$table_type.'.description'] = Helpers::processReservedKeywords($item->notes, $this->client);
|
||||||
|
|
||||||
/* need to test here as this is new - 18/09/2021*/
|
|
||||||
if(!array_key_exists($table_type.'.gross_line_total', $data[$key]))
|
|
||||||
$data[$key][$table_type.'.gross_line_total'] = 0;
|
|
||||||
|
|
||||||
$data[$key][$table_type . ".{$_table_type}1"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}1", $item->custom_value1, $this->client);
|
$data[$key][$table_type . ".{$_table_type}1"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}1", $item->custom_value1, $this->client);
|
||||||
$data[$key][$table_type . ".{$_table_type}2"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}2", $item->custom_value2, $this->client);
|
$data[$key][$table_type . ".{$_table_type}2"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}2", $item->custom_value2, $this->client);
|
||||||
$data[$key][$table_type . ".{$_table_type}3"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}3", $item->custom_value3, $this->client);
|
$data[$key][$table_type . ".{$_table_type}3"] = $helpers->formatCustomFieldValue($this->client->company->custom_fields, "{$_table_type}3", $item->custom_value3, $this->client);
|
||||||
@ -315,6 +311,10 @@ trait MakesInvoiceValues
|
|||||||
|
|
||||||
$data[$key][$table_type.'.line_total'] = Number::formatMoney($item->line_total, $this->client);
|
$data[$key][$table_type.'.line_total'] = Number::formatMoney($item->line_total, $this->client);
|
||||||
|
|
||||||
|
if(property_exists($item, 'gross_line_total'))
|
||||||
|
$data[$key][$table_type.'.gross_line_total'] = Number::formatMoney($item->gross_line_total, $this->client);
|
||||||
|
else
|
||||||
|
$data[$key][$table_type.'.gross_line_total'] = 0;
|
||||||
|
|
||||||
if (isset($item->discount) && $item->discount > 0) {
|
if (isset($item->discount) && $item->discount > 0) {
|
||||||
if ($item->is_amount_discount) {
|
if ($item->is_amount_discount) {
|
||||||
|
@ -103,6 +103,7 @@ Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'clie
|
|||||||
Route::get('quote/{invitation_key}/download_pdf', 'QuoteController@downloadPdf')->name('quote.download_invitation_key');
|
Route::get('quote/{invitation_key}/download_pdf', 'QuoteController@downloadPdf')->name('quote.download_invitation_key');
|
||||||
Route::get('credit/{invitation_key}/download_pdf', 'CreditController@downloadPdf')->name('credit.download_invitation_key');
|
Route::get('credit/{invitation_key}/download_pdf', 'CreditController@downloadPdf')->name('credit.download_invitation_key');
|
||||||
Route::get('{entity}/{invitation_key}/download', 'ClientPortal\InvitationController@routerForDownload');
|
Route::get('{entity}/{invitation_key}/download', 'ClientPortal\InvitationController@routerForDownload');
|
||||||
|
Route::get('pay/{invitation_key}', 'ClientPortal\InvitationController@payInvoice')->name('pay.invoice');
|
||||||
// Route::get('{entity}/{client_hash}/{invitation_key}', 'ClientPortal\InvitationController@routerForIframe')->name('invoice.client_hash_and_invitation_key'); //should never need this
|
// Route::get('{entity}/{client_hash}/{invitation_key}', 'ClientPortal\InvitationController@routerForIframe')->name('invoice.client_hash_and_invitation_key'); //should never need this
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -93,9 +93,9 @@ class CreditsTest extends TestCase
|
|||||||
$this->actingAs($client->contacts->first(), 'contact');
|
$this->actingAs($client->contacts->first(), 'contact');
|
||||||
|
|
||||||
Livewire::test(CreditsTable::class, ['company' => $company])
|
Livewire::test(CreditsTable::class, ['company' => $company])
|
||||||
->assertSee('testing-number-01')
|
->assertDontSee('testing-number-01')
|
||||||
->assertSee('testing-number-02')
|
->assertSee('testing-number-02')
|
||||||
->assertDontSee('testing-number-03');
|
->assertSee('testing-number-03');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testShowingCreditsWithNullDueDate()
|
public function testShowingCreditsWithNullDueDate()
|
||||||
@ -122,6 +122,7 @@ class CreditsTest extends TestCase
|
|||||||
'client_id' => $client->id,
|
'client_id' => $client->id,
|
||||||
'number' => 'testing-number-01',
|
'number' => 'testing-number-01',
|
||||||
'status_id' => Credit::STATUS_SENT,
|
'status_id' => Credit::STATUS_SENT,
|
||||||
|
'due_date' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Credit::factory()->create([
|
Credit::factory()->create([
|
||||||
@ -142,12 +143,21 @@ class CreditsTest extends TestCase
|
|||||||
'status_id' => Credit::STATUS_SENT,
|
'status_id' => Credit::STATUS_SENT,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
Credit::factory()->create([
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'company_id' => $company->id,
|
||||||
|
'client_id' => $client->id,
|
||||||
|
'number' => 'testing-number-04',
|
||||||
|
'due_date' => '',
|
||||||
|
'status_id' => Credit::STATUS_SENT,
|
||||||
|
]);
|
||||||
|
|
||||||
$this->actingAs($client->contacts->first(), 'contact');
|
$this->actingAs($client->contacts->first(), 'contact');
|
||||||
|
|
||||||
Livewire::test(CreditsTable::class, ['company' => $company])
|
Livewire::test(CreditsTable::class, ['company' => $company])
|
||||||
->assertSee('testing-number-01')
|
->assertSee('testing-number-01')
|
||||||
->assertSee('testing-number-02')
|
->assertSee('testing-number-02')
|
||||||
->assertDontSee('testing-number-03');
|
->assertSee('testing-number-03');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user