1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-05 18:52:44 +01:00

Fixes for credit PDF

This commit is contained in:
David Bomba 2020-11-11 11:13:39 +11:00
parent c5643bea7b
commit 28cbd75fcb
21 changed files with 136 additions and 54 deletions

View File

@ -364,10 +364,14 @@ class DemoMode extends Command
private function createProject($client, $assigned_user_id = null)
{
$vendor = Project::factory()->create([
$project = Project::factory()->create([
'user_id' => $client->user->id,
'company_id' => $client->company_id,
'client_id' => $client->id,
]);
$project->number = $this->getNextProjectNumber($project);
$project->save();
}
private function createInvoice($client, $assigned_user_id = null)

View File

@ -12,6 +12,10 @@
namespace App\Console\Commands;
use App\Jobs\Ninja\SendReminders;
use App\Jobs\Util\WebHookHandler;
use App\Models\Invoice;
use App\Models\Quote;
use App\Models\Webhook;
use Illuminate\Console\Command;
class SendRemindersCron extends Command
@ -48,5 +52,34 @@ class SendRemindersCron extends Command
public function handle()
{
SendReminders::dispatchNow();
$this->webHookOverdueInvoices();
$this->webHookExpiredQuotes();
}
private function webHookOverdueInvoices()
{
$invoices = Invoice::where('is_deleted', 0)
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
->where('balance', '>', 0)
->whereDate('due_date', now()->subDays(1)->startOfDay())
->cursor();
$invoices->each(function ($invoice){
WebHookHandler::dispatch(Webhook::EVENT_LATE_INVOICE, $invoice);
});
}
private function webHookExpiredQuotes()
{
$quotes = Quote::where('is_deleted', 0)
->where('status_id', Quote::STATUS_SENT)
->whereDate('due_date', now()->subDays(1)->startOfDay())
->cursor();
$quotes->each(function ($quote){
WebHookHandler::dispatch(Webhook::EVENT_EXPIRED_QUOTE, $quote);
});
}
}

View File

@ -40,7 +40,7 @@ class InvitationController extends Controller
$key = $entity.'_id';
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation'; //todo sensitive to the route parameters here
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
$invitation = $entity_obj::whereRaw('BINARY `key`= ?', [$invitation_key])
->with('contact.client')

View File

@ -572,10 +572,10 @@ class CreditController extends BaseController
public function downloadPdf($invitation_key)
{
$invitation = $this->credit_repository->getInvitationByKey($invitation_key);
$contact = $invitation->contact;
// $contact = $invitation->contact;
$credit = $invitation->credit;
$file_path = $credit->service()->getCreditPdf($contact);
$file_path = $credit->service()->getCreditPdf($invitation);
return response()->download($file_path);
}

View File

@ -34,8 +34,10 @@ use App\Jobs\Util\UnlinkFile;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\InvoiceInvitation;
use App\Models\Quote;
use App\Repositories\InvoiceRepository;
use App\Transformers\InvoiceTransformer;
use App\Transformers\QuoteTransformer;
use App\Utils\Ninja;
use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
@ -639,7 +641,12 @@ class InvoiceController extends BaseController
break;
case 'clone_to_quote':
$quote = CloneInvoiceToQuoteFactory::create($invoice, auth()->user()->id);
// todo build the quote transformer and return response here
$this->entity_transformer = QuoteTransformer::class;
$this->entity_type = Quote::class;
return $this->itemResponse($quote);
break;
case 'history':
// code...

View File

@ -23,9 +23,11 @@ use App\Http\Requests\RecurringQuote\ShowRecurringQuoteRequest;
use App\Http\Requests\RecurringQuote\StoreRecurringQuoteRequest;
use App\Http\Requests\RecurringQuote\UpdateRecurringQuoteRequest;
use App\Jobs\Entity\ActionEntity;
use App\Models\Quote;
use App\Models\RecurringQuote;
use App\Repositories\BaseRepository;
use App\Repositories\RecurringQuoteRepository;
use App\Transformers\QuoteTransformer;
use App\Transformers\RecurringQuoteTransformer;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
@ -583,8 +585,11 @@ class RecurringQuoteController extends BaseController
// return $this->itemResponse($recurring_invoice);
break;
case 'clone_to_quote':
// $quote = CloneRecurringQuoteToQuoteFactory::create($recurring_invoice, auth()->user()->id);
// todo build the quote transformer and return response here
$quote = CloneRecurringQuoteToQuoteFactory::create($recurring_invoice, auth()->user()->id);
$this->entity_transformer = QuoteTransformer::class;
$this->entity_type = Quote::class;
return $this->itemResponse($quote);
break;
case 'history':
// code...

View File

@ -84,4 +84,9 @@ class SelfUpdateController extends BaseController
return response()->json(['message' => ''], 200);
}
public function checkVersion()
{
return trim(file_get_contents(config('ninja.version_url')));
}
}

View File

@ -55,7 +55,7 @@ class ContactTokenAuth
//stateless, don't remember the contact.
auth()->guard('contact')->login($client_contact, false);
event(new ContactLoggedIn($client_contact, $client_contact->company, Ninja::eventVars())); //todo
event(new ContactLoggedIn($client_contact, $client_contact->company, Ninja::eventVars()));
} else {
$error = [
'message' => 'Invalid token',

View File

@ -75,7 +75,7 @@ class StoreClientRequest extends Request
$input = $this->all();
//@todo implement feature permissions for > 100 clients
//
$settings = ClientSettings::defaults();
if (array_key_exists('settings', $input) && ! empty($input['settings'])) {

View File

@ -77,7 +77,7 @@ class StorePaymentRequest extends Request
}
if (! isset($input['amount']) || $input['amount'] == 0) {
$input['amount'] = $invoices_total - $credits_total; //todo the payment amount is always less the credit amount applied
$input['amount'] = $invoices_total - $credits_total;
}
$input['is_manual'] = true;

View File

@ -109,22 +109,20 @@ class StoreRecurringInvoiceRequest extends Request
}
$this->replace($input);
}
private function setAutoBillFlag($auto_bill)
{
if($auto_bill == 'always')
return true;
if($auto_bill == 'off')
return false;
//todo do we need to handle optin / optout here?
}
public function messages()
{
return [];
}
private function setAutoBillFlag($auto_bill)
{
if($auto_bill == 'always')
return true;
if($auto_bill == 'off')
return false;
}
public function messages()
{
return [];
}
}

View File

@ -46,16 +46,28 @@ class ValidCreditsPresentRule implements Rule
{
//todo need to ensure the clients credits are here not random ones!
if (request()->input('credits') && is_array(request()->input('credits'))) {
foreach (request()->input('credits') as $credit) {
$cred = Credit::find($this->decodePrimaryKey($credit['credit_id']));
// if (request()->input('credits') && is_array(request()->input('credits'))) {
// foreach (request()->input('credits') as $credit) {
// $cred = Credit::find($this->decodePrimaryKey($credit['credit_id']));
if (! $cred || $cred->balance == 0) {
return false;
}
}
// if (! $cred || $cred->balance == 0) {
// return false;
// }
// }
// }
// return true;
if (request()->input('credits') && is_array(request()->input('credits'))) {
$credit_collection = Credit::whereIn('id', $this->transformKeys(array_column(request()->input('credits'), 'credit_id')))
->where('balance', '>', 0)
->get();
return $credit_collection->count() == count(request()->input('credits'));
}
return true;
return true;
}
}

View File

@ -285,10 +285,13 @@ class SendReminders implements ShouldQueue
* @param Invoice $invoice
* @param float $amount The fee amount
* @param float $percent The fee percentage amount
*
* @return Invoice
*/
private function setLateFee($invoice, $amount, $percent) :Invoice
{
$temp_invoice_balance = $invoice->balance;
if ($amount <= 0 && $percent <= 0)
return $invoice;
@ -314,7 +317,9 @@ class SendReminders implements ShouldQueue
/**Refresh Invoice values*/
$invoice = $invoice->calc()->getInvoice();
//@todo update the ledger!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$this->invoice->client->service()->updateBalance($this->invoice->balance - $temp_invoice_balance)->save();
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance - $temp_invoice_balance);
return $invoice;
}

View File

@ -1,5 +1,13 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Jobs\Util;
use App\Models\Webhook;
@ -40,7 +48,7 @@ class WebhookHandler implements ShouldQueue
* @return bool
*/
public function handle() :bool
{
{//todo set multidb here
if (! $this->entity->company || $this->entity->company->is_disabled) {
return true;
}

View File

@ -384,7 +384,7 @@ class Client extends BaseModel implements HasLocalePreference
return array_search($model->id, $transformed_ids);
});
} else {
$gateways = $this->company->company_gateways; //todo perhaps we can remove this or keep as a catch all.
$gateways = $this->company->company_gateways;
}
foreach ($gateways as $gateway) {

View File

@ -224,8 +224,6 @@ class Credit extends BaseModel
if ($this->balance == 0) {
$this->status_id = self::STATUS_APPLIED;
$this->save();
//event(new InvoiceWasPaid($this, $this->company));//todo
return;
}
@ -248,10 +246,10 @@ class Credit extends BaseModel
if (! $invitation) {
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars()));
CreateEntityPdf::dispatchNow($this, $this->company, $this->client->primary_contact()->first());
CreateEntityPdf::dispatchNow($this->invitations->first());
} else {
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars()));
CreateEntityPdf::dispatchNow($invitation->credit, $invitation->company, $invitation->contact);
CreateEntityPdf::dispatchNow($invitation);
}
return $storage_path;

View File

@ -40,7 +40,10 @@ class Webhook extends BaseModel
const EVENT_UPDATE_TASK = 19;
const EVENT_DELETE_TASK = 20;
const EVENT_APPROVE_QUOTE = 21;
const EVENT_LATE_INVOICE = 22;
const EVENT_EXPIRED_QUOTE = 23;
const EVENT_REMIND_INVOICE = 24;
public static $valid_events = [
self::EVENT_CREATE_CLIENT,
self::EVENT_CREATE_PAYMENT,

View File

@ -29,9 +29,9 @@ class CreditService
$this->credit = $credit;
}
public function getCreditPdf($contact)
public function getCreditPdf($invitation)
{
return (new GetCreditPdf($this->credit, $contact))->run();
return (new GetCreditPdf($invitation))->run();
}
/**

View File

@ -19,14 +19,17 @@ use Illuminate\Support\Facades\Storage;
class GetCreditPdf extends AbstractService
{
private $credit;
public $credit;
private $contact;
public $contact;
public function __construct(Credit $credit, ClientContact $contact = null)
public $invitation;
public function __construct($invitation)
{
$this->credit = $credit;
$this->contact = $contact;
$this->invitation = $invitation;
$this->credit = $invitation->credit;
$this->contact = $invitation->contact;
}
public function run()
@ -44,7 +47,7 @@ class GetCreditPdf extends AbstractService
$file = Storage::disk($disk)->exists($file_path);
if (! $file) {
$file_path = CreateEntityPdf::dispatchNow($this->credit, $this->credit->company, $this->contact);
$file_path = CreateEntityPdf::dispatchNow($this->invitation);
}
return Storage::disk($disk)->path($file_path);

View File

@ -74,7 +74,7 @@ class AccountTransformer extends EntityTransformer
'utm_content' => (string) $account->utm_content,
'utm_term' => (string) $account->utm_term,
'referral_code' => (string) $account->referral_code,
'latest_version' => (string) $account->latest_version,
'latest_version' => (string) trim($account->latest_version),
'current_version' => (string) config('ninja.app_version'),
'updated_at' => (int) $account->updated_at,
'archived_at' => (int) $account->deleted_at,

View File

@ -9,7 +9,8 @@
"expenses",
"CRM",
"Credit card billing",
"projects"
"projects",
"tasks"
],
"license": "Attribution Assurance License",
"authors": [