mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-21 08:51:34 +02:00
Merge pull request #4211 from turbo124/v5-develop
Refactor PDF generation
This commit is contained in:
commit
fe46bba383
@ -242,6 +242,8 @@ class CreateSingleAccount extends Command
|
||||
|
||||
$settings = $client->settings;
|
||||
$settings->currency_id = "1";
|
||||
$settings->use_credits_payment = "always";
|
||||
|
||||
$client->settings = $settings;
|
||||
|
||||
$country = Country::all()->random();
|
||||
|
@ -18,7 +18,7 @@ use App\Factory\CompanyUserFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\InvoiceInvitationFactory;
|
||||
use App\Helpers\Email\InvoiceEmail;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Invoice\CreateEntityPdf;
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
@ -149,7 +149,7 @@ class SendTestEmails extends Command
|
||||
$invoice->setRelation('invitations', $ii);
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
CreateInvoicePdf::dispatch($invoice->invitations()->first());
|
||||
CreateEntityPdf::dispatch($invoice->invitations()->first());
|
||||
|
||||
$cc_emails = [config('ninja.testvars.test_email')];
|
||||
$bcc_emails = [config('ninja.testvars.test_email')];
|
||||
|
@ -253,7 +253,10 @@ class CompanySettings extends BaseSettings
|
||||
public $client_portal_under_payment_minimum = 0;
|
||||
public $client_portal_allow_over_payment = false;
|
||||
|
||||
public $use_credits_payment = 'off'; //always, option, off
|
||||
|
||||
public static $casts = [
|
||||
'use_credits_payment' => 'string',
|
||||
'recurring_invoice_number_pattern' => 'string',
|
||||
'recurring_invoice_number_counter' => 'int',
|
||||
'client_portal_under_payment_minimum'=> 'float',
|
||||
|
@ -60,12 +60,15 @@ class BaseController extends Controller
|
||||
|
||||
private $first_load = [
|
||||
'account',
|
||||
'user.company_user',
|
||||
'token.company_user',
|
||||
'company.activities',
|
||||
'company.designs.company',
|
||||
'company.task_statuses',
|
||||
'company.expense_categories',
|
||||
'company.documents',
|
||||
'company.users.company_users',
|
||||
'company.clients.contacts',
|
||||
'company.users.company_user',
|
||||
'company.clients.contacts.company',
|
||||
'company.clients.gateway_tokens',
|
||||
'company.clients.documents',
|
||||
'company.company_gateways.gateway',
|
||||
@ -90,11 +93,11 @@ class BaseController extends Controller
|
||||
'company.quotes.invitations.contact',
|
||||
'company.quotes.invitations.company',
|
||||
'company.quotes.documents',
|
||||
'company.tasks',
|
||||
'company.tasks.documents',
|
||||
'company.tax_rates',
|
||||
'company.tokens_hashed',
|
||||
'company.vendors.contacts',
|
||||
'company.vendors.contacts.company',
|
||||
'company.vendors.documents',
|
||||
'company.webhooks',
|
||||
];
|
||||
|
||||
@ -257,6 +260,12 @@ class BaseController extends Controller
|
||||
'company.vendors'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('contacts','documents' );
|
||||
},
|
||||
'company.expense_categories'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.task_statuses'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
@ -418,7 +427,8 @@ class BaseController extends Controller
|
||||
|
||||
public function flutterRoute()
|
||||
{
|
||||
if ((bool) $this->checkAppSetup() !== false && Schema::hasTable('accounts') && $account = Account::first()) {
|
||||
// if ((bool) $this->checkAppSetup() !== false && Schema::hasTable('accounts') && $account = Account::first()) {
|
||||
if ((bool) $this->checkAppSetup() !== false && $account = Account::first()) {
|
||||
if (config('ninja.require_https') && ! request()->isSecure()) {
|
||||
return redirect()->secure(request()->getRequestUri());
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ class PaymentController extends Controller
|
||||
$payment_method_id = $request->input('payment_method_id');
|
||||
$invoice_totals = $payable_invoices->sum('amount');
|
||||
$first_invoice = $invoices->first();
|
||||
$credit_totals = $first_invoice->company->use_credits_payment == 'off' ? 0 : $first_invoice->client->service()->getCreditBalance();
|
||||
$credit_totals = $first_invoice->client->getSetting('use_credits_payment') == 'off' ? 0 : $first_invoice->client->service()->getCreditBalance();
|
||||
$starting_invoice_amount = $first_invoice->amount;
|
||||
|
||||
if($gateway)
|
||||
|
@ -28,7 +28,6 @@ use App\Http\Requests\Invoice\EditInvoiceRequest;
|
||||
use App\Http\Requests\Invoice\ShowInvoiceRequest;
|
||||
use App\Http\Requests\Invoice\StoreInvoiceRequest;
|
||||
use App\Http\Requests\Invoice\UpdateInvoiceRequest;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Invoice\EmailInvoice;
|
||||
use App\Jobs\Invoice\StoreInvoice;
|
||||
use App\Jobs\Invoice\ZipInvoices;
|
||||
|
@ -14,7 +14,6 @@ namespace App\Http\Controllers;
|
||||
use App\Designs\Custom;
|
||||
use App\Designs\Designer;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Util\PreviewPdf;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
|
@ -16,6 +16,7 @@ use App\Http\Requests\Setup\CheckDatabaseRequest;
|
||||
use App\Http\Requests\Setup\CheckMailRequest;
|
||||
use App\Http\Requests\Setup\StoreSetupRequest;
|
||||
use App\Jobs\Account\CreateAccount;
|
||||
use App\Jobs\Util\VersionCheck;
|
||||
use App\Models\Account;
|
||||
use App\Utils\SystemHealth;
|
||||
use Illuminate\Http\Response;
|
||||
@ -124,6 +125,8 @@ class SetupController extends Controller
|
||||
CreateAccount::dispatchNow($request->all());
|
||||
}
|
||||
|
||||
VersionCheck::dispatchNow();
|
||||
|
||||
return redirect('/');
|
||||
} catch (\Exception $e) {
|
||||
info($e->getMessage());
|
||||
|
@ -33,8 +33,6 @@ class ContactKeyLogin
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
info($request->segment(3));
|
||||
info($request->route('contact_key'));
|
||||
|
||||
if(Auth::guard('contact')->check())
|
||||
Auth::guard('contact')->logout();
|
||||
|
@ -42,12 +42,8 @@ class StoreProjectRequest extends Request
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
|
@ -36,12 +36,8 @@ class UpdateProjectRequest extends Request
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
unset($input['client_id']);
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
@ -37,49 +37,17 @@ class StoreTaskRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
//$rules['name'] = 'required|min:1';
|
||||
//$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||
|
||||
// $rules['number'] = new UniqueTaskNumberRule($this->all());
|
||||
|
||||
|
||||
return $rules;
|
||||
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('project_id', $input) && is_string($input['project_id'])) {
|
||||
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('invoice_id', $input) && is_string($input['invoice_id'])) {
|
||||
$input['invoice_id'] = $this->decodePrimaryKey($input['invoice_id']);
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
// public function messages()
|
||||
// {
|
||||
// // return [
|
||||
// // 'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
// // //'required' => trans('validation.required', ['attribute' => 'email']),
|
||||
// // 'contacts.*.email.required' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
// // ];
|
||||
// }
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class UpdateTaskRequest extends Request
|
||||
$rules['number'] = 'unique:tasks,number,'.$this->id.',id,company_id,'.$this->taskss->company_id;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
// public function messages()
|
||||
@ -58,28 +58,9 @@ class UpdateTaskRequest extends Request
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('project_id', $input) && is_string($input['project_id'])) {
|
||||
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('invoice_id', $input) && is_string($input['invoice_id'])) {
|
||||
$input['invoice_id'] = $this->decodePrimaryKey($input['invoice_id']);
|
||||
}
|
||||
|
||||
$this->replace($input);
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
166
app/Jobs/Entity/CreateEntityPdf.php
Normal file
166
app/Jobs/Entity/CreateEntityPdf.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Entity Ninja (https://entityninja.com).
|
||||
*
|
||||
* @link https://github.com/entityninja/entityninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Entity Ninja LLC (https://entityninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Entity;
|
||||
|
||||
use App\Designs\Custom;
|
||||
use App\Designs\Designer;
|
||||
use App\Designs\Modern;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Credit;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\Design;
|
||||
use App\Models\Entity;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\Quote;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Services\PdfMaker\Design as PdfDesignModel;
|
||||
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
||||
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\MakesInvoiceHtml;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
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\Storage;
|
||||
use Spatie\Browsershot\Browsershot;
|
||||
|
||||
class CreateEntityPdf implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml, PdfMaker, MakesHash;
|
||||
|
||||
public $entity;
|
||||
|
||||
public $company;
|
||||
|
||||
public $contact;
|
||||
|
||||
private $disk;
|
||||
|
||||
public $invitation;
|
||||
|
||||
public $entity_string = '';
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invitation)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
|
||||
if($invitation instanceof InvoiceInvitation){
|
||||
$this->entity = $invitation->invoice;
|
||||
$this->entity_string = 'invoice';
|
||||
}
|
||||
elseif($invitation instanceof QuoteInvitation){
|
||||
$this->entity = $invitation->quote;
|
||||
$this->entity_string = 'quote';
|
||||
}
|
||||
elseif($invitation instanceof CreditInvitation){
|
||||
$this->entity = $invitation->credit;
|
||||
$this->entity_string = 'credit';
|
||||
}
|
||||
elseif($invitation instanceof RecurringInvoiceInvitation){
|
||||
$this->entity = $invitation->recurring_invoice;
|
||||
$this->entity_string = 'recurring_invoice';
|
||||
}
|
||||
|
||||
$this->company = $invitation->company;
|
||||
|
||||
$this->contact = $invitation->contact;
|
||||
|
||||
$this->disk = $disk ?? config('filesystems.default');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
|
||||
if (config('ninja.phantomjs_key')) {
|
||||
return (new Phantom)->generate($this->invitation);
|
||||
}
|
||||
|
||||
App::setLocale($this->contact->preferredLocale());
|
||||
|
||||
$entity_design_id = '';
|
||||
|
||||
if($this->entity instanceof Invoice){
|
||||
$path = $this->entity->client->invoice_filepath();
|
||||
$entity_design_id = 'invoice_design_id';
|
||||
}
|
||||
elseif($this->entity instanceof Quote){
|
||||
$path = $this->entity->client->quote_filepath();
|
||||
$entity_design_id = 'quote_design_id';
|
||||
}
|
||||
elseif($this->entity instanceof Credit){
|
||||
$path = $this->entity->client->credit_filepath();
|
||||
$entity_design_id = 'credit_design_id';
|
||||
}
|
||||
|
||||
$file_path = $path.$this->entity->number.'.pdf';
|
||||
|
||||
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->entity->client->getSetting($entity_design_id));
|
||||
|
||||
$design = Design::find($entity_design_id);
|
||||
$html = new HtmlEngine(null, $this->invitation, $this->entity_string);
|
||||
|
||||
if ($design->is_custom) {
|
||||
$options = [
|
||||
'custom_partials' => json_decode(json_encode($design->design), true)
|
||||
];
|
||||
$template = new PdfMakerDesign(PdfDesignModel::CUSTOM, $options);
|
||||
} else {
|
||||
$template = new PdfMakerDesign(strtolower($design->name));
|
||||
}
|
||||
|
||||
$state = [
|
||||
'template' => $template->elements([
|
||||
'client' => $this->entity->client,
|
||||
'entity' => $this->entity,
|
||||
'pdf_variables' => (array) $this->entity->company->settings->pdf_variables,
|
||||
'products' => $design->design->product,
|
||||
]),
|
||||
'variables' => $html->generateLabelsAndValues(),
|
||||
'options' => [
|
||||
'all_pages_header' => $this->entity->client->getSetting('all_pages_header'),
|
||||
'all_pages_footer' => $this->entity->client->getSetting('all_pages_footer'),
|
||||
],
|
||||
];
|
||||
|
||||
$maker = new PdfMakerService($state);
|
||||
|
||||
$maker
|
||||
->design($template)
|
||||
->build();
|
||||
|
||||
//todo - move this to the client creation stage so we don't keep hitting this unnecessarily
|
||||
Storage::makeDirectory($path, 0775);
|
||||
|
||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
||||
|
||||
$instance = Storage::disk($this->disk)->put($file_path, $pdf);
|
||||
|
||||
return $file_path;
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Jobs\Invoice;
|
||||
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@ -51,6 +52,6 @@ class InjectSignature implements ShouldQueue
|
||||
$invitation->signature_base64 = $this->signature;
|
||||
$invitation->save();
|
||||
|
||||
CreateInvoicePdf::dispatch($invitation);
|
||||
CreateEntityPdf::dispatch($invitation);
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class VersionCheck implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$version_file = file_get_contents(config('ninja.version_url'));
|
||||
$version_file = trim(file_get_contents(config('ninja.version_url')));
|
||||
|
||||
info("latest version = {$version_file}");
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace App\Listeners\Invoice;
|
||||
|
||||
use App\Jobs\Invoice\CreateInvoicePdf as PdfCreator;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@ -38,7 +38,7 @@ class CreateInvoicePdf implements ShouldQueue
|
||||
MultiDB::setDb($event->company->db);
|
||||
|
||||
$event->invoice->invitations->each(function ($invitation) {
|
||||
PdfCreator::dispatch($invitation);
|
||||
CreateEntityPdf::dispatch($invitation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,8 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
];
|
||||
|
||||
protected $with = [
|
||||
'gateway_tokens',
|
||||
'documents'
|
||||
//'currency',
|
||||
// 'primary_contact',
|
||||
// 'country',
|
||||
@ -523,7 +525,7 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
}
|
||||
}
|
||||
|
||||
if(($this->company->use_credits_payment == 'option' || $this->company->use_credits_payment == 'always') && $this->service()->getCreditBalance() > 0) {
|
||||
if(($this->getSetting('use_credits_payment') == 'option' || $this->getSetting('use_credits_payment') == 'always') && $this->service()->getCreditBalance() > 0) {
|
||||
$payment_urls[] = [
|
||||
'label' => ctrans('texts.apply_credit'),
|
||||
'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT,
|
||||
|
@ -71,7 +71,6 @@ class Company extends BaseModel
|
||||
protected $fillable = [
|
||||
'mark_expenses_invoiceable',
|
||||
'mark_expenses_paid',
|
||||
'use_credits_payment',
|
||||
'enabled_item_tax_rates',
|
||||
'fill_products',
|
||||
'industry_id',
|
||||
@ -98,6 +97,8 @@ class Company extends BaseModel
|
||||
'google_analytics_key',
|
||||
'client_can_register',
|
||||
'enable_shop_api',
|
||||
'invoice_task_timelog',
|
||||
'auto_start_tasks',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
@ -165,14 +166,20 @@ class Company extends BaseModel
|
||||
return $this->hasManyThrough(User::class, CompanyUser::class, 'company_id', 'id', 'id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function expense_categories()
|
||||
{
|
||||
return $this->hasMany(ExpenseCategory::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function task_statuses()
|
||||
{
|
||||
return $this->hasMany(TaskStatus::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function clients()
|
||||
{
|
||||
return $this->hasMany(Client::class)->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
|
@ -14,7 +14,7 @@ namespace App\Models;
|
||||
use App\Events\Credit\CreditWasUpdated;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||
use App\Jobs\Credit\CreateCreditPdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\Filterable;
|
||||
use App\Services\Credit\CreditService;
|
||||
use App\Services\Ledger\LedgerService;
|
||||
@ -244,10 +244,10 @@ class Credit extends BaseModel
|
||||
|
||||
if (! $invitation) {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars()));
|
||||
CreateCreditPdf::dispatchNow($this, $this->company, $this->client->primary_contact()->first());
|
||||
CreateEntityPdf::dispatchNow($this, $this->company, $this->client->primary_contact()->first());
|
||||
} else {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars()));
|
||||
CreateCreditPdf::dispatchNow($invitation->credit, $invitation->company, $invitation->contact);
|
||||
CreateEntityPdf::dispatchNow($invitation->credit, $invitation->company, $invitation->contact);
|
||||
}
|
||||
|
||||
return $storage_path;
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Events\Credit\CreditWasUpdated;
|
||||
use App\Jobs\Credit\CreateCreditPdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\Inviteable;
|
||||
@ -131,7 +131,7 @@ class CreditInvitation extends BaseModel
|
||||
|
||||
if (! Storage::exists($this->credit->client->credit_filepath().$this->credit->number.'.pdf')) {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars()));
|
||||
CreateCreditPdf::dispatchNow($this);
|
||||
CreateEntityPdf::dispatchNow($this);
|
||||
}
|
||||
|
||||
return $storage_path;
|
||||
|
@ -18,7 +18,7 @@ use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||
use App\Jobs\Client\UpdateClientBalance;
|
||||
use App\Jobs\Company\UpdateCompanyLedgerWithInvoice;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\Backup;
|
||||
use App\Models\CompanyLedger;
|
||||
use App\Models\Currency;
|
||||
@ -29,8 +29,8 @@ use App\Services\Ledger\LedgerService;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use App\Utils\Traits\Archivable;
|
||||
use App\Utils\Traits\Invoice\ActionsInvoice;
|
||||
use App\Utils\Traits\InvoiceEmailBuilder;
|
||||
use App\Utils\Traits\Invoice\ActionsInvoice;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
use App\Utils\Traits\MakesInvoiceValues;
|
||||
use App\Utils\Traits\MakesReminders;
|
||||
@ -395,7 +395,7 @@ class Invoice extends BaseModel
|
||||
|
||||
if (! Storage::exists($this->client->invoice_filepath().$this->number.'.pdf')) {
|
||||
event(new InvoiceWasUpdated($this, $this->company, Ninja::eventVars()));
|
||||
CreateInvoicePdf::dispatchNow($invitation);
|
||||
CreateEntityPdf::dispatchNow($invitation);
|
||||
}
|
||||
|
||||
return $storage_path;
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Events\Invoice\InvoiceWasUpdated;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\Inviteable;
|
||||
@ -144,7 +144,7 @@ class InvoiceInvitation extends BaseModel
|
||||
|
||||
if (! Storage::exists($this->invoice->client->invoice_filepath().$this->invoice->number.'.pdf')) {
|
||||
event(new InvoiceWasUpdated($this->invoice, $this->company, Ninja::eventVars()));
|
||||
CreateInvoicePdf::dispatchNow($this);
|
||||
CreateEntityPdf::dispatchNow($this);
|
||||
}
|
||||
|
||||
return $storage_path;
|
||||
|
@ -14,8 +14,7 @@ namespace App\Models;
|
||||
use App\Events\Quote\QuoteWasUpdated;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Quote\CreateQuotePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\Filterable;
|
||||
use App\Services\Quote\QuoteService;
|
||||
use App\Utils\Ninja;
|
||||
@ -206,7 +205,7 @@ class Quote extends BaseModel
|
||||
|
||||
event(new QuoteWasUpdated($this, $this->company, Ninja::eventVars()));
|
||||
|
||||
CreateQuotePdf::dispatchNow($invitation);
|
||||
CreateEntityPdf::dispatchNow($invitation);
|
||||
|
||||
return $storage_path;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Events\Quote\QuoteWasUpdated;
|
||||
use App\Jobs\Quote\CreateQuotePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\Quote;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\Inviteable;
|
||||
@ -135,7 +135,7 @@ class QuoteInvitation extends BaseModel
|
||||
|
||||
if (! Storage::exists($this->quote->client->quote_filepath().$this->quote->number.'.pdf')) {
|
||||
event(new QuoteWasUpdated($this->quote, $this->company, Ninja::eventVars()));
|
||||
CreateQuotePdf::dispatchNow($this);
|
||||
CreateEntityPdf::dispatchNow($this);
|
||||
}
|
||||
|
||||
return $storage_path;
|
||||
|
@ -33,6 +33,8 @@ class Task extends BaseModel
|
||||
'description',
|
||||
'is_running',
|
||||
'time_log',
|
||||
'status_id',
|
||||
'status_sort_order',
|
||||
];
|
||||
|
||||
protected $touches = [];
|
||||
|
@ -11,8 +11,7 @@
|
||||
|
||||
namespace App\Services\Credit;
|
||||
|
||||
use App\Jobs\Credit\CreateCreditPdf;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Credit;
|
||||
use App\Services\AbstractService;
|
||||
@ -45,7 +44,7 @@ class GetCreditPdf extends AbstractService
|
||||
$file = Storage::disk($disk)->exists($file_path);
|
||||
|
||||
if (! $file) {
|
||||
$file_path = CreateCreditPdf::dispatchNow($this->credit, $this->credit->company, $this->contact);
|
||||
$file_path = CreateEntityPdf::dispatchNow($this->credit, $this->credit->company, $this->contact);
|
||||
}
|
||||
|
||||
return Storage::disk($disk)->path($file_path);
|
||||
|
@ -19,6 +19,7 @@ use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use App\Services\AbstractService;
|
||||
use App\Services\Client\ClientService;
|
||||
use App\Services\Payment\PaymentService;
|
||||
@ -56,7 +57,7 @@ class AutoBillInvoice extends AbstractService
|
||||
|
||||
//if the credits cover the payments, we stop here, build the payment with credits and exit early
|
||||
|
||||
if($this->invoice->company->use_credits_payment != 'off')
|
||||
if($this->client->getSetting('use_credits_payment') != 'off')
|
||||
$this->applyCreditPayment();
|
||||
|
||||
info("partial = {$this->invoice->partial}");
|
||||
@ -116,6 +117,7 @@ class AutoBillInvoice extends AbstractService
|
||||
$payment->currency_id = $this->invoice->client->getSetting('currency_id');
|
||||
$payment->date = now();
|
||||
$payment->status_id = Payment::STATUS_COMPLETED;
|
||||
$payment->type_id = PaymentType::CREDIT;
|
||||
$payment->service()->applyNumber()->save();
|
||||
|
||||
$payment->invoices()->attach($this->invoice->id, ['amount' => $amount]);
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace App\Services\Invoice;
|
||||
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Invoice;
|
||||
use App\Services\AbstractService;
|
||||
@ -43,7 +43,7 @@ class GetInvoicePdf extends AbstractService
|
||||
$file = Storage::disk($disk)->exists($file_path);
|
||||
|
||||
if (! $file) {
|
||||
$file_path = CreateInvoicePdf::dispatchNow($invitation);
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
||||
}
|
||||
|
||||
return Storage::disk($disk)->path($file_path);
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace App\Services\Invoice;
|
||||
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Jobs\Util\UnlinkFile;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\Invoice;
|
||||
@ -295,7 +295,7 @@ class InvoiceService
|
||||
public function touchPdf()
|
||||
{
|
||||
$this->invoice->invitations->each(function ($invitation){
|
||||
CreateInvoicePdf::dispatch($invitation);
|
||||
CreateEntityPdf::dispatch($invitation);
|
||||
});
|
||||
|
||||
return $this;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Jobs\Quote\CreateQuotePdf;
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Quote;
|
||||
use App\Services\AbstractService;
|
||||
@ -43,7 +43,7 @@ class GetQuotePdf extends AbstractService
|
||||
$file = Storage::disk($disk)->exists($file_path);
|
||||
|
||||
if (! $file) {
|
||||
$file_path = CreateQuotePdf::dispatchNow($invitation);
|
||||
$file_path = CreateEntityPdf::dispatchNow($invitation);
|
||||
}
|
||||
|
||||
return Storage::disk($disk)->path($file_path);
|
||||
|
@ -23,6 +23,7 @@ use App\Models\Credit;
|
||||
use App\Models\Design;
|
||||
use App\Models\Document;
|
||||
use App\Models\Expense;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Models\GroupSetting;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentTerm;
|
||||
@ -32,6 +33,7 @@ use App\Models\Quote;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\Task;
|
||||
use App\Models\TaskStatus;
|
||||
use App\Models\TaxRate;
|
||||
use App\Models\User;
|
||||
use App\Models\Webhook;
|
||||
@ -40,9 +42,11 @@ use App\Transformers\CompanyTokenHashedTransformer;
|
||||
use App\Transformers\CompanyTokenTransformer;
|
||||
use App\Transformers\CreditTransformer;
|
||||
use App\Transformers\DocumentTransformer;
|
||||
use App\Transformers\ExpenseCategoryTransformer;
|
||||
use App\Transformers\PaymentTermTransformer;
|
||||
use App\Transformers\RecurringInvoiceTransformer;
|
||||
use App\Transformers\SystemLogTransformer;
|
||||
use App\Transformers\TaskStatusTransformer;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Transformers\WebhookTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
@ -95,6 +99,8 @@ class CompanyTransformer extends EntityTransformer
|
||||
'tokens',
|
||||
'tokens_hashed',
|
||||
'system_logs',
|
||||
'expense_categories',
|
||||
'task_statuses',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -147,10 +153,24 @@ class CompanyTransformer extends EntityTransformer
|
||||
'invoice_expense_documents' => (bool) $company->invoice_expense_documents,
|
||||
'invoice_task_timelog' => (bool) $company->invoice_task_timelog,
|
||||
'auto_start_tasks' => (bool) $company->auto_start_tasks,
|
||||
'use_credits_payment' => (string) $company->use_credits_payment,
|
||||
'invoice_task_documents' => (bool) $company->invoice_task_documents,
|
||||
];
|
||||
}
|
||||
|
||||
public function includeExpenseCategories(Company $company)
|
||||
{
|
||||
$transformer = new ExpenseCategoryTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($company->expense_categories, $transformer, ExpenseCategory::class);
|
||||
}
|
||||
|
||||
public function includeTaskStatuses(Company $company)
|
||||
{
|
||||
$transformer = new TaskStatusTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($company->task_statuses, $transformer, TaskStatus::class);
|
||||
}
|
||||
|
||||
public function includeDocuments(Company $company)
|
||||
{
|
||||
$transformer = new DocumentTransformer($this->serializer);
|
||||
|
@ -59,7 +59,7 @@ class ExpenseTransformer extends EntityTransformer
|
||||
'bank_id' => (string) $expense->bank_id ?: '',
|
||||
'invoice_currency_id' => (string) $expense->invoice_currency_id ?: '',
|
||||
'expense_currency_id' => (string) $expense->expense_currency_id ?: '',
|
||||
'category_id' => (string) $expense->category_id ?: '',
|
||||
'category_id' => $this->encodePrimaryKey($expense->category_id),
|
||||
'payment_type_id' => (string) $expense->payment_type_id ?: '',
|
||||
'recurring_expense_id' => (string) $expense->recurring_expense_id ?: '',
|
||||
'is_deleted' => (bool) $expense->is_deleted,
|
||||
|
@ -23,6 +23,7 @@ class TaskStatusTransformer extends EntityTransformer
|
||||
return [
|
||||
'id' => (string) $this->encodePrimaryKey($task_status->id),
|
||||
'name' => (string) $task_status->name,
|
||||
'sort_order' => (int) $task_status->sort_order,
|
||||
'is_deleted' => (bool) $task_status->is_deleted,
|
||||
'created_at' => (int) $task_status->created_at,
|
||||
'updated_at' => (int) $task_status->updated_at,
|
||||
|
@ -50,6 +50,7 @@ class TaskTransformer extends EntityTransformer
|
||||
'start_time' => (int) $task->start_time,
|
||||
'description' => $task->description ?: '',
|
||||
'duration' => 0,
|
||||
'rate' => (float) $task->rate ?: 0,
|
||||
'created_at' => (int) $task->created_at,
|
||||
'updated_at' => (int) $task->updated_at,
|
||||
'archived_at' => (int) $task->deleted_at,
|
||||
@ -63,8 +64,8 @@ class TaskTransformer extends EntityTransformer
|
||||
'custom_value2' => $task->custom_value2 ?: '',
|
||||
'custom_value3' => $task->custom_value3 ?: '',
|
||||
'custom_value4' => $task->custom_value4 ?: '',
|
||||
'task_status_id' => $this->encodePrimaryKey($task->task_status_id),
|
||||
'task_status_sort_order' => (int) $task->task_status_sort_order,
|
||||
'status_id' => $this->encodePrimaryKey($task->status_id),
|
||||
'status_sort_order' => (int) $task->status_sort_order,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ class HtmlEngine
|
||||
$data['$entity.terms'] = ['value' => $this->entity->terms ?: ' ', 'label' => ctrans('texts.quote_terms')];
|
||||
$data['$terms'] = &$data['$entity.terms'];
|
||||
$data['$view_link'] = ['value' => '<a href="'.$this->invitation->getLink().'">'.ctrans('texts.view_quote').'</a>', 'label' => ctrans('texts.view_quote')];
|
||||
// $data['$view_link'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_quote')];
|
||||
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_quote')];
|
||||
}
|
||||
|
||||
if ($this->entity_string == 'credit') {
|
||||
@ -142,6 +142,7 @@ class HtmlEngine
|
||||
$data['$entity.terms'] = ['value' => $this->entity->terms ?: ' ', 'label' => ctrans('texts.credit_terms')];
|
||||
$data['$terms'] = &$data['$entity.terms'];
|
||||
$data['$view_link'] = ['value' => '<a href="'.$this->invitation->getLink().'">'.ctrans('texts.view_credit').'</a>', 'label' => ctrans('texts.view_credit')];
|
||||
$data['$view_url'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_credit')];
|
||||
// $data['$view_link'] = ['value' => $this->invitation->getLink(), 'label' => ctrans('texts.view_credit')];
|
||||
}
|
||||
|
||||
@ -210,10 +211,10 @@ class HtmlEngine
|
||||
// $data['$details'] = ;
|
||||
$data['$invoice_no'] = &$data['$number'];
|
||||
$data['$invoice.invoice_no'] = &$data['$number'];
|
||||
$data['$client1'] = ['value' => $this->client->custom_value1 ?: ' ', 'label' => $this->makeCustomField('client1')];
|
||||
$data['$client2'] = ['value' => $this->client->custom_value2 ?: ' ', 'label' => $this->makeCustomField('client2')];
|
||||
$data['$client3'] = ['value' => $this->client->custom_value3 ?: ' ', 'label' => $this->makeCustomField('client3')];
|
||||
$data['$client4'] = ['value' => $this->client->custom_value4 ?: ' ', 'label' => $this->makeCustomField('client4')];
|
||||
$data['$client1'] = ['value' => $this->formatCustomFieldValue('client1', $this->client->custom_value1) ?: ' ', 'label' => $this->makeCustomField('client1')];
|
||||
$data['$client2'] = ['value' => $this->formatCustomFieldValue('client2', $this->client->custom_value2) ?: ' ', 'label' => $this->makeCustomField('client2')];
|
||||
$data['$client3'] = ['value' => $this->formatCustomFieldValue('client3', $this->client->custom_value3) ?: ' ', 'label' => $this->makeCustomField('client3')];
|
||||
$data['$client4'] = ['value' => $this->formatCustomFieldValue('client4', $this->client->custom_value4) ?: ' ', 'label' => $this->makeCustomField('client4')];
|
||||
$data['$address1'] = ['value' => $this->client->address1 ?: ' ', 'label' => ctrans('texts.address1')];
|
||||
$data['$address2'] = ['value' => $this->client->address2 ?: ' ', 'label' => ctrans('texts.address2')];
|
||||
$data['$id_number'] = ['value' => $this->client->id_number ?: ' ', 'label' => ctrans('texts.id_number')];
|
||||
@ -276,10 +277,10 @@ class HtmlEngine
|
||||
|
||||
$data['$company.logo'] = ['value' => $logo ?: ' ', 'label' => ctrans('texts.logo')];
|
||||
$data['$company_logo'] = &$data['$company.logo'];
|
||||
$data['$company1'] = ['value' => $this->settings->custom_value1 ?: ' ', 'label' => $this->makeCustomField('company1')];
|
||||
$data['$company2'] = ['value' => $this->settings->custom_value2 ?: ' ', 'label' => $this->makeCustomField('company2')];
|
||||
$data['$company3'] = ['value' => $this->settings->custom_value3 ?: ' ', 'label' => $this->makeCustomField('company3')];
|
||||
$data['$company4'] = ['value' => $this->settings->custom_value4 ?: ' ', 'label' => $this->makeCustomField('company4')];
|
||||
$data['$company1'] = ['value' => $this->formatCustomFieldValue('company1', $this->settings->custom_value1) ?: ' ', 'label' => $this->makeCustomField('company1')];
|
||||
$data['$company2'] = ['value' => $this->formatCustomFieldValue('company2', $this->settings->custom_value2) ?: ' ', 'label' => $this->makeCustomField('company2')];
|
||||
$data['$company3'] = ['value' => $this->formatCustomFieldValue('company3', $this->settings->custom_value3) ?: ' ', 'label' => $this->makeCustomField('company3')];
|
||||
$data['$company4'] = ['value' => $this->formatCustomFieldValue('company4', $this->settings->custom_value4) ?: ' ', 'label' => $this->makeCustomField('company4')];
|
||||
|
||||
$data['$custom_surcharge1'] = ['value' => $this->entity->custom_surcharge1 ?: ' ', 'label' => $this->makeCustomField('custom_surcharge1')];
|
||||
$data['$custom_surcharge2'] = ['value' => $this->entity->custom_surcharge2 ?: ' ', 'label' => $this->makeCustomField('custom_surcharge2')];
|
||||
|
@ -109,7 +109,7 @@ trait GeneratesCounter
|
||||
|
||||
$credit_number = $this->checkEntityNumber(Credit::class, $client, $counter, $padding, $pattern);
|
||||
|
||||
$this->incrementCounter($client->company, 'credit_number_counter');
|
||||
$this->incrementCounter($counter_entity, 'credit_number_counter');
|
||||
|
||||
return $credit_number;
|
||||
}
|
||||
|
37
database/factories/CreditInvitationFactory.php
Normal file
37
database/factories/CreditInvitationFactory.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?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 Database\Factories;
|
||||
|
||||
use App\Models\CreditInvitation;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CreditInvitationFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = CreditInvitation::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'key' => Str::random(40),
|
||||
];
|
||||
}
|
||||
}
|
@ -15,6 +15,12 @@ class CompanyTableFields extends Migration
|
||||
{
|
||||
Schema::table('companies', function(Blueprint $table){
|
||||
$table->boolean('invoice_task_timelog')->default(true);
|
||||
$table->boolean('invoice_task_documents')->default(false);
|
||||
$table->dropColumn('use_credits_payment');
|
||||
});
|
||||
|
||||
Schema::table('task_statuses', function(Blueprint $table){
|
||||
$table->unsignedInteger('status_sort_order')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ class GatewayTypesSeeder extends Seeder
|
||||
['id' => 11, 'alias' => 'apple_pay', 'name' => 'Apple Pay'],
|
||||
['id' => 12, 'alias' => 'custom2', 'name' => 'Custom'],
|
||||
['id' => 13, 'alias' => 'custom3', 'name' => 'Custom'],
|
||||
['id' => 14, 'alias' => 'credit', 'name' => 'Credit'],
|
||||
];
|
||||
|
||||
foreach ($gateway_types as $gateway_type) {
|
||||
|
@ -31,6 +31,7 @@ class PaymentTypesSeeder extends Seeder
|
||||
const GATEWAY_TYPE_APPLE_PAY = 11;
|
||||
const GATEWAY_TYPE_CUSTOM2 = 12;
|
||||
const GATEWAY_TYPE_CUSTOM3 = 13;
|
||||
const GATEWAY_TYPE_CREDIT = 14;
|
||||
|
||||
public function run()
|
||||
{
|
||||
@ -69,6 +70,7 @@ class PaymentTypesSeeder extends Seeder
|
||||
['name' => 'SEPA', 'gateway_type_id' => self::GATEWAY_TYPE_SEPA],
|
||||
['name' => 'GoCardless', 'gateway_type_id' => self::GATEWAY_TYPE_GOCARDLESS],
|
||||
['name' => 'Crypto', 'gateway_type_id' => self::GATEWAY_TYPE_CRYPTO],
|
||||
['name' => 'Credit', 'gateway_type_id' => self::GATEWAY_TYPE_CREDIT],
|
||||
];
|
||||
|
||||
$x = 1;
|
||||
|
@ -3285,5 +3285,7 @@ return [
|
||||
|
||||
'credit_subject' => 'New credit :number from :account',
|
||||
'credit_message' => 'To view your credit for :amount, click the link below.',
|
||||
'payment_type_Crypto' => 'Cryptocurrency',
|
||||
'payment_type_Credit' => 'Credit',
|
||||
|
||||
];
|
||||
|
63
tests/Feature/PdfCreatorTest.php
Normal file
63
tests/Feature/PdfCreatorTest.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?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 Tests\Feature;
|
||||
|
||||
use App\Jobs\Entity\CreateEntityPdf;
|
||||
use Faker\Factory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
class PdfCreatorTest extends TestCase
|
||||
{
|
||||
|
||||
use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->makeTestData();
|
||||
|
||||
$this->withoutMiddleware(
|
||||
ThrottleRequests::class
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreditPdfCreated()
|
||||
{
|
||||
$credit_path = CreateEntityPdf::dispatchNow($this->credit->invitations->first());
|
||||
|
||||
$this->assertTrue(Storage::exists($this->client->credit_filepath().$this->credit->number.'.pdf'));
|
||||
}
|
||||
|
||||
public function testInvoicePdfCreated()
|
||||
{
|
||||
$invoice_path = CreateEntityPdf::dispatchNow($this->invoice->invitations->first());
|
||||
|
||||
$this->assertTrue(Storage::exists($this->client->invoice_filepath().$this->invoice->number.'.pdf'));
|
||||
}
|
||||
|
||||
public function testQuotePdfCreated()
|
||||
{
|
||||
$quote_path = CreateEntityPdf::dispatchNow($this->quote->invitations->first());
|
||||
|
||||
$this->assertTrue(Storage::exists($this->client->quote_filepath().$this->quote->number.'.pdf'));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -31,6 +31,7 @@ use App\Models\Company;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\CompanyToken;
|
||||
use App\Models\Credit;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\Expense;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Models\GroupSetting;
|
||||
@ -135,7 +136,8 @@ trait MockAccountData
|
||||
$settings->country_id = '840';
|
||||
$settings->vat_number = 'vat number';
|
||||
$settings->id_number = 'id number';
|
||||
|
||||
$settings->use_credits_payment = 'always';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
@ -350,19 +352,45 @@ trait MockAccountData
|
||||
$this->credit->tax_rate3 = 0;
|
||||
|
||||
$this->credit->uses_inclusive_taxes = false;
|
||||
|
||||
$this->credit->save();
|
||||
$this->credit->service()->createInvitations()->markSent();
|
||||
|
||||
|
||||
$this->credit_calc = new InvoiceSum($this->credit);
|
||||
$this->credit_calc->build();
|
||||
|
||||
$this->credit = $this->credit_calc->getCredit();
|
||||
$this->credit->service()->markSent();
|
||||
|
||||
$this->client->service()->adjustCreditBalance($this->credit->balance)->save();
|
||||
$this->credit->ledger()->updateCreditBalance($this->credit->balance)->save();
|
||||
|
||||
$this->credit->number = $this->getNextCreditNumber($this->client);
|
||||
|
||||
|
||||
CreditInvitation::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'client_contact_id' => $contact->id,
|
||||
'credit_id' => $this->credit->id,
|
||||
]);
|
||||
|
||||
CreditInvitation::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'client_contact_id' => $contact2->id,
|
||||
'credit_id' => $this->credit->id,
|
||||
]);
|
||||
|
||||
$invitations = CreditInvitation::whereCompanyId($this->credit->company_id)
|
||||
->whereCreditId($this->credit->id);
|
||||
|
||||
$this->credit->setRelation('invitations', $invitations);
|
||||
|
||||
$this->credit->service()->markSent();
|
||||
|
||||
$this->credit->setRelation('client', $this->client);
|
||||
$this->credit->setRelation('company', $this->company);
|
||||
|
||||
$this->credit->save();
|
||||
|
||||
$contacts = $this->invoice->client->contacts;
|
||||
|
||||
$contacts->each(function ($contact) {
|
||||
|
@ -33,8 +33,6 @@ class AutoBillInvoiceTest extends TestCase
|
||||
|
||||
public function testAutoBillFunctionality()
|
||||
{
|
||||
$this->company->use_credits_payment = 'always';
|
||||
$this->company->save();
|
||||
|
||||
$this->assertEquals($this->client->balance, 10);
|
||||
$this->assertEquals($this->client->paid_to_date, 0);
|
||||
@ -52,23 +50,27 @@ class AutoBillInvoiceTest extends TestCase
|
||||
}
|
||||
|
||||
|
||||
public function testAutoBillSetOffFunctionality()
|
||||
{
|
||||
$this->company->use_credits_payment = 'off';
|
||||
$this->company->save();
|
||||
// public function testAutoBillSetOffFunctionality()
|
||||
// {
|
||||
|
||||
// $settings = $this->company->settings;
|
||||
// $settings->use_credits_payment = 'off';
|
||||
|
||||
$this->assertEquals($this->client->balance, 10);
|
||||
$this->assertEquals($this->client->paid_to_date, 0);
|
||||
$this->assertEquals($this->client->credit_balance, 10);
|
||||
// $this->company->settings = $settings;
|
||||
// $this->company->save();
|
||||
|
||||
$this->invoice->service()->markSent()->autoBill()->save();
|
||||
// $this->assertEquals($this->client->balance, 10);
|
||||
// $this->assertEquals($this->client->paid_to_date, 0);
|
||||
// $this->assertEquals($this->client->credit_balance, 10);
|
||||
|
||||
$this->assertNotNull($this->invoice->payments());
|
||||
$this->assertEquals(0, $this->invoice->payments()->sum('payments.amount'));
|
||||
// $this->invoice->service()->markSent()->autoBill()->save();
|
||||
|
||||
$this->assertEquals($this->client->balance, 10);
|
||||
$this->assertEquals($this->client->paid_to_date, 0);
|
||||
$this->assertEquals($this->client->credit_balance, 10);
|
||||
// $this->assertNotNull($this->invoice->payments());
|
||||
// $this->assertEquals(0, $this->invoice->payments()->sum('payments.amount'));
|
||||
|
||||
// $this->assertEquals($this->client->balance, 10);
|
||||
// $this->assertEquals($this->client->paid_to_date, 0);
|
||||
// $this->assertEquals($this->client->credit_balance, 10);
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user