1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-27 03:37:11 +02:00

Merge pull request #6614 from turbo124/v5-stable

v5.3.9
This commit is contained in:
David Bomba 2021-09-10 18:45:15 +10:00 committed by GitHub
commit d114445ab2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 262799 additions and 261866 deletions

View File

@ -1 +1 @@
5.3.8 5.3.9

View File

@ -24,12 +24,14 @@ use App\Models\Invoice;
use App\Models\InvoiceInvitation; use App\Models\InvoiceInvitation;
use App\Models\Payment; use App\Models\Payment;
use App\Models\Paymentable; use App\Models\Paymentable;
use App\Models\QuoteInvitation;
use App\Models\RecurringInvoiceInvitation;
use App\Utils\Ninja; use App\Utils\Ninja;
use DB;
use Exception; use Exception;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Mail;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
/* /*
@ -103,6 +105,7 @@ class CheckData extends Command
// $this->checkPaidToCompanyDates(); // $this->checkPaidToCompanyDates();
$this->checkClientBalances(); $this->checkClientBalances();
$this->checkContacts(); $this->checkContacts();
$this->checkEntityInvitations();
$this->checkCompanyData(); $this->checkCompanyData();
@ -197,7 +200,7 @@ class CheckData extends Command
->where('id', '=', $contact->id) ->where('id', '=', $contact->id)
->whereNull('contact_key') ->whereNull('contact_key')
->update([ ->update([
'contact_key' => str_random(config('ninja.key_length')), 'contact_key' => Str::random(config('ninja.key_length')),
]); ]);
} }
} }
@ -307,13 +310,73 @@ class CheckData extends Command
$invitation->company_id = $invoice->company_id; $invitation->company_id = $invoice->company_id;
$invitation->user_id = $invoice->user_id; $invitation->user_id = $invoice->user_id;
$invitation->invoice_id = $invoice->id; $invitation->invoice_id = $invoice->id;
$invitation->contact_id = ClientContact::whereClientId($invoice->client_id)->whereIsPrimary(true)->first()->id; $invitation->contact_id = ClientContact::whereClientId($invoice->client_id)->first()->id;
$invitation->invitation_key = str_random(config('ninja.key_length')); $invitation->invitation_key = Str::random(config('ninja.key_length'));
$invitation->save(); $invitation->save();
} }
} }
} }
private function checkEntityInvitations()
{
RecurringInvoiceInvitation::where('deleted_at',"0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
InvoiceInvitation::where('deleted_at',"0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
QuoteInvitation::where('deleted_at',"0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
$entities = ['invoice', 'quote', 'credit', 'recurring_invoice'];
foreach($entities as $entity)
{
$table = "{$entity}s";
$invitation_table = "{$entity}_invitations";
$entities = DB::table($table)
->leftJoin($invitation_table, function ($join) use($invitation_table, $table, $entity){
$join->on("{$invitation_table}.{$entity}_id", '=', "{$table}.id");
// ->whereNull("{$invitation_table}.deleted_at");
})
->groupBy("{$table}.id", "{$table}.user_id", "{$table}.company_id", "{$table}.client_id")
->havingRaw("count({$invitation_table}.id) = 0")
->get(["{$table}.id", "{$table}.user_id", "{$table}.company_id", "{$table}.client_id"]);
$this->logMessage($entities->count()." {$table} without any invitations");
if ($this->option('fix') == 'true')
$this->fixInvitations($entities, $entity);
}
}
private function fixInvitations($entities, $entity)
{
$entity_key = "{$entity}_id";
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
foreach($entities as $entity)
{
$invitation = new $entity_obj();
$invitation->company_id = $entity->company_id;
$invitation->user_id = $entity->user_id;
$invitation->{$entity_key} = $entity->id;
$invitation->client_contact_id = ClientContact::whereClientId($entity->client_id)->first()->id;
$invitation->key = Str::random(config('ninja.key_length'));
try{
$invitation->save();
}
catch(\Exception $e){
$invitation = null;
}
}
}
// private function checkPaidToCompanyDates() // private function checkPaidToCompanyDates()
// { // {
// Company::cursor()->each(function ($company){ // Company::cursor()->each(function ($company){

View File

@ -15,12 +15,14 @@ class S3Cleanup extends Command
*/ */
protected $signature = 'ninja:s3-cleanup'; protected $signature = 'ninja:s3-cleanup';
protected $log = '';
/** /**
* The console command description. * The console command description.
* *
* @var string * @var string
*/ */
protected $description = 'Remove orphan folders'; protected $description = 'Remove orphan folders/files';
/** /**
* Create a new command instance. * Create a new command instance.
@ -54,7 +56,11 @@ class S3Cleanup extends Command
if(!in_array($dir, $merged)) if(!in_array($dir, $merged))
{ {
$this->logMessage("Deleting $dir"); $this->logMessage("Deleting $dir");
Storage::disk(config('filesystems.default'))->deleteDirectory($dir);
/* Ensure we are not deleting the root folder */
if(strlen($dir) > 1)
Storage::disk(config('filesystems.default'))->deleteDirectory($dir);
} }
} }

View File

@ -71,7 +71,8 @@ class Kernel extends ConsoleKernel
$schedule->job(new AdjustEmailQuota)->dailyAt('23:00')->withoutOverlapping(); $schedule->job(new AdjustEmailQuota)->dailyAt('23:00')->withoutOverlapping();
$schedule->job(new SendFailedEmails)->daily()->withoutOverlapping(); $schedule->job(new SendFailedEmails)->daily()->withoutOverlapping();
$schedule->command('ninja:check-data --database=db-ninja-02')->daily()->withoutOverlapping(); $schedule->command('ninja:check-data --database=db-ninja-02')->dailyAt('00:15')->withoutOverlapping();
$schedule->command('ninja:s3-cleanup')->dailyAt('23:15')->withoutOverlapping();
} }

View File

@ -79,7 +79,7 @@ class DocumentController extends Controller
$zip = new ZipStream(now() . '-documents.zip', $options); $zip = new ZipStream(now() . '-documents.zip', $options);
foreach ($documents as $document) { foreach ($documents as $document) {
$zip->addFileFromPath(basename($document->diskPath()), TempFile::path($document->diskPath())); $zip->addFileFromPath(basename($document->diskPath()), TempFile::path($document->filePath()));
} }
$zip->finish(); $zip->finish();

View File

@ -18,10 +18,10 @@ use App\Libraries\MultiDB;
use App\Models\ClientContact; use App\Models\ClientContact;
use App\Models\Company; use App\Models\Company;
use App\Utils\Ninja; use App\Utils\Ninja;
use Auth;
use Illuminate\Contracts\Routing\ResponseFactory; use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
class NinjaPlanController extends Controller class NinjaPlanController extends Controller
{ {

View File

@ -2,6 +2,7 @@
namespace App\Http\Requests\Gateways\Checkout3ds; namespace App\Http\Requests\Gateways\Checkout3ds;
use App\Libraries\MultiDB;
use App\Models\Client; use App\Models\Client;
use App\Models\Company; use App\Models\Company;
use App\Models\CompanyGateway; use App\Models\CompanyGateway;
@ -37,6 +38,7 @@ class Checkout3dsRequest extends FormRequest
public function getCompany() public function getCompany()
{ {
MultiDB::findAndSetDbByCompanyKey($this->company_key);
return Company::where('company_key', $this->company_key)->first(); return Company::where('company_key', $this->company_key)->first();
} }

View File

@ -67,7 +67,7 @@ class InvoiceTransformer extends BaseTransformer {
if ( $transformed['balance'] < $transformed['amount'] ) { if ( $transformed['balance'] < $transformed['amount'] ) {
$transformed['payments'] = [[ $transformed['payments'] = [[
'date' => date( 'Y-m-d' ), 'date' => isset( $invoice_data['Last Payment Date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['Invoice Date'] ) ) : date( 'Y-m-d' ),
'amount' => $transformed['amount'] - $transformed['balance'], 'amount' => $transformed['amount'] - $transformed['balance'],
]]; ]];
} }
@ -75,3 +75,4 @@ class InvoiceTransformer extends BaseTransformer {
return $transformed; return $transformed;
} }
} }

View File

@ -121,18 +121,29 @@ class NinjaMailerJob implements ShouldQueue
$message = $e->getMessage(); $message = $e->getMessage();
/**
* Post mark buries the proper message in a a guzzle response
* this merges a text string with a json object
* need to harvest the ->Message property using the following
*/
if($e instanceof ClientException) { //postmark specific failure if($e instanceof ClientException) { //postmark specific failure
$response = $e->getResponse(); $response = $e->getResponse();
$message_body = json_decode($response->getBody()->getContents());
if(property_exists($message_body, 'Message')){
$message = $message_body->Message;
nlog($message);
}
nlog($response);
// $message = $response->Message;
} }
/* If the is an entity attached to the message send a failure mailer */
if($this->nmo->entity) if($this->nmo->entity)
$this->entityEmailFailed($message); $this->entityEmailFailed($message);
if(Ninja::isHosted() && (!$e instanceof ClientException)) // Don't send postmark failures to Sentry /* Don't send postmark failures to Sentry */
if(Ninja::isHosted() && (!$e instanceof ClientException))
app('sentry')->captureException($e); app('sentry')->captureException($e);
} }
} }

View File

@ -640,7 +640,8 @@ class Import implements ShouldQueue
$client->updated_at = Carbon::parse($modified['updated_at']); $client->updated_at = Carbon::parse($modified['updated_at']);
$client->save(['timestamps' => false]); $client->save(['timestamps' => false]);
$client->fresh();
$client->contacts()->forceDelete(); $client->contacts()->forceDelete();
if (array_key_exists('contacts', $resource)) { // need to remove after importing new migration.json if (array_key_exists('contacts', $resource)) { // need to remove after importing new migration.json
@ -650,7 +651,7 @@ class Import implements ShouldQueue
$modified_contacts[$key]['company_id'] = $this->company->id; $modified_contacts[$key]['company_id'] = $this->company->id;
$modified_contacts[$key]['user_id'] = $this->processUserId($resource); $modified_contacts[$key]['user_id'] = $this->processUserId($resource);
$modified_contacts[$key]['client_id'] = $client->id; $modified_contacts[$key]['client_id'] = $client->id;
$modified_contacts[$key]['password'] = 'mysuperpassword'; // @todo, and clean up the code.. $modified_contacts[$key]['password'] = Str::random(8);
unset($modified_contacts[$key]['id']); unset($modified_contacts[$key]['id']);
} }
@ -685,6 +686,8 @@ class Import implements ShouldQueue
'old' => $resource['id'], 'old' => $resource['id'],
'new' => $client->id, 'new' => $client->id,
]; ];
$client = null;
} }
Client::reguard(); Client::reguard();

View File

@ -88,7 +88,7 @@ class PaymentNotification implements ShouldQueue
$client = $payment->client; $client = $payment->client;
$amount = $payment->amount; $amount = $payment->amount;
if ($invoice) { if ($invoice && $invoice->line_items) {
$items = $invoice->line_items; $items = $invoice->line_items;
$item = end($items)->product_key; $item = end($items)->product_key;
$entity_number = $invoice->number; $entity_number = $invoice->number;

View File

@ -62,9 +62,10 @@ class SupportMessageSent extends Mailable
$company = auth()->user()->company(); $company = auth()->user()->company();
$user = auth()->user(); $user = auth()->user();
$db = str_replace("db-ninja-", "", $company->db); $db = str_replace("db-ninja-", "", $company->db);
$is_large = $company->is_large ? "L" : "";
if(Ninja::isHosted()) if(Ninja::isHosted())
$subject = "{$priority}Hosted-{$db}-[{$company->is_large}] :: {$plan} :: ".date('M jS, g:ia'); $subject = "{$priority}Hosted-{$db}{$is_large} :: {$plan} :: ".date('M jS, g:ia');
else else
$subject = "{$priority}Self Hosted :: {$plan} :: ".date('M jS, g:ia'); $subject = "{$priority}Self Hosted :: {$plan} :: ".date('M jS, g:ia');

View File

@ -126,7 +126,11 @@ class TemplateEmail extends Mailable
if($this->invitation->invoice && $settings->ubl_email_attachment && $this->company->account->hasFeature(Account::FEATURE_DOCUMENTS)){ if($this->invitation->invoice && $settings->ubl_email_attachment && $this->company->account->hasFeature(Account::FEATURE_DOCUMENTS)){
$ubl_string = CreateUbl::dispatchNow($this->invitation->invoice); $ubl_string = CreateUbl::dispatchNow($this->invitation->invoice);
$this->attachData($ubl_string, $this->invitation->invoice->getFileName('xml'));
nlog($ubl_string);
if($ubl_string)
$this->attachData($ubl_string, $this->invitation->invoice->getFileName('xml'));
} }

View File

@ -90,7 +90,7 @@ class Client extends BaseModel implements HasLocalePreference
'contacts.company', 'contacts.company',
// 'currency', // 'currency',
// 'primary_contact', // 'primary_contact',
// 'country', 'country',
// 'contacts', // 'contacts',
// 'shipping_country', // 'shipping_country',
// 'company', // 'company',
@ -218,7 +218,7 @@ class Client extends BaseModel implements HasLocalePreference
public function assigned_user() public function assigned_user()
{ {
return $this->belongsTo(User::class, 'assigned_user_id', 'id'); return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
} }
public function country() public function country()

View File

@ -92,7 +92,7 @@ class ClientContact extends Authenticatable implements HasLocalePreference
'custom_value4', 'custom_value4',
'email', 'email',
'is_primary', 'is_primary',
'client_id', // 'client_id',
]; ];
/** /**

View File

@ -13,10 +13,12 @@ namespace App\Models;
use App\Utils\Traits\MakesDates; use App\Utils\Traits\MakesDates;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class ClientGatewayToken extends BaseModel class ClientGatewayToken extends BaseModel
{ {
use MakesDates; use MakesDates;
use SoftDeletes;
protected $casts = [ protected $casts = [
'meta' => 'object', 'meta' => 'object',

View File

@ -36,7 +36,7 @@ class CompanyLedger extends Model
public function user() public function user()
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class)->withTrashed();
} }
public function company() public function company()

View File

@ -23,6 +23,8 @@ class CompanyToken extends BaseModel
]; ];
protected $with = [ protected $with = [
'company',
'user'
]; ];
protected $touches = []; protected $touches = [];

View File

@ -78,7 +78,7 @@ class CompanyUser extends Pivot
public function user() public function user()
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class)->withTrashed();
} }
public function company() public function company()

View File

@ -120,7 +120,7 @@ class Credit extends BaseModel
public function assigned_user() public function assigned_user()
{ {
return $this->belongsTo(User::class, 'assigned_user_id', 'id'); return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
} }
public function history() public function history()

View File

@ -84,7 +84,7 @@ class Expense extends BaseModel
public function assigned_user() public function assigned_user()
{ {
return $this->belongsTo(User::class, 'assigned_user_id', 'id'); return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
} }
public function company() public function company()

View File

@ -52,7 +52,7 @@ class GroupSetting extends StaticModel
public function user() public function user()
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class)->withTrashed();
} }
public function clients() public function clients()

View File

@ -45,6 +45,11 @@ class Proposal extends BaseModel
return $this->morphMany(Document::class, 'documentable'); return $this->morphMany(Document::class, 'documentable');
} }
public function user()
{
return $this->belongsTo(User::class)->withTrashed();
}
public function assigned_user() public function assigned_user()
{ {
return $this->belongsTo(User::class, 'assigned_user_id', 'id'); return $this->belongsTo(User::class, 'assigned_user_id', 'id');

View File

@ -76,7 +76,7 @@ class Subscription extends BaseModel
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class)->withTrashed();
} }
public function nextDateByInterval($date, $frequency_id) public function nextDateByInterval($date, $frequency_id)

View File

@ -66,7 +66,7 @@ class Task extends BaseModel
public function user() public function user()
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class)->withTrashed();
} }
public function client() public function client()

View File

@ -82,7 +82,7 @@ class Vendor extends BaseModel
public function assigned_user() public function assigned_user()
{ {
return $this->belongsTo(User::class, 'assigned_user_id', 'id'); return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
} }
public function contacts() public function contacts()

View File

@ -87,7 +87,7 @@ class Webhook extends BaseModel
public function user() public function user()
{ {
return $this->belongsTo(User::class); return $this->belongsTo(User::class)->withTrashed();
} }
public function company() public function company()

View File

@ -11,6 +11,8 @@
namespace App\Notifications; namespace App\Notifications;
use App\Jobs\Invoice\CreateUbl;
use App\Models\Invoice;
use App\Utils\TempFile; use App\Utils\TempFile;
use App\Utils\Traits\MakesInvoiceHtml; use App\Utils\Traits\MakesInvoiceHtml;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;

View File

@ -46,7 +46,7 @@ class InvoiceObserver
* @return void * @return void
*/ */
public function updated(Invoice $invoice) public function updated(Invoice $invoice)
{nlog("updated"); {
$subscriptions = Webhook::where('company_id', $invoice->company->id) $subscriptions = Webhook::where('company_id', $invoice->company->id)
->where('event_id', Webhook::EVENT_UPDATE_INVOICE) ->where('event_id', Webhook::EVENT_UPDATE_INVOICE)
->exists(); ->exists();

View File

@ -205,7 +205,6 @@ class BaseDriver extends AbstractPaymentDriver
$invoices->each(function ($invoice) use ($payment) { $invoices->each(function ($invoice) use ($payment) {
event(new InvoiceWasPaid($invoice, $payment, $payment->company, Ninja::eventVars())); event(new InvoiceWasPaid($invoice, $payment, $payment->company, Ninja::eventVars()));
$invoice->service()->workFlow();
}); });
return $payment->service()->applyNumber()->save(); return $payment->service()->applyNumber()->save();

View File

@ -362,9 +362,14 @@ class StripePaymentDriver extends BaseDriver
$response = null; $response = null;
try { try {
$response = $this->stripe // $response = $this->stripe
->refunds // ->refunds
->create(['charge' => $payment->transaction_reference, 'amount' => $this->convertToStripeAmount($amount, $this->client->currency()->precision, $this->client->currency())], $meta); // ->create(['charge' => $payment->transaction_reference, 'amount' => $this->convertToStripeAmount($amount, $this->client->currency()->precision, $this->client->currency())], $meta);
$response = \Stripe\Refund::create([
'charge' => $payment->transaction_reference,
'amount' => $this->convertToStripeAmount($amount, $this->client->currency()->precision, $this->client->currency())
], $meta);
if ($response->status == $response::STATUS_SUCCEEDED) { if ($response->status == $response::STATUS_SUCCEEDED) {
SystemLogger::dispatch(['server_response' => $response, 'data' => request()->all(),], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->client, $this->client->company); SystemLogger::dispatch(['server_response' => $response, 'data' => request()->all(),], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->client, $this->client->company);

View File

@ -60,12 +60,18 @@ use WePayCommon;
'method' => '1', 'method' => '1',
*/ */
$response = $this->wepay_payment_driver->wepay->request('credit_card/authorize', array( try {
'client_id' => config('ninja.wepay.client_id'),
'client_secret' => config('ninja.wepay.client_secret'), $response = $this->wepay_payment_driver->wepay->request('credit_card/authorize', array(
'credit_card_id' => (int)$data['credit_card_id'], 'client_id' => config('ninja.wepay.client_id'),
)); 'client_secret' => config('ninja.wepay.client_secret'),
'credit_card_id' => (int)$data['credit_card_id'],
));
}
catch(\Exception $e){
return $this->wepay_payment_driver->processInternallyFailedPayment($this->wepay_payment_driver, $e);
}
// display the response // display the response
// nlog($response); // nlog($response);
@ -116,11 +122,16 @@ use WePayCommon;
{ {
nlog("authorize the card first!"); nlog("authorize the card first!");
$response = $this->wepay_payment_driver->wepay->request('credit_card/authorize', array( try {
'client_id' => config('ninja.wepay.client_id'), $response = $this->wepay_payment_driver->wepay->request('credit_card/authorize', array(
'client_secret' => config('ninja.wepay.client_secret'), 'client_id' => config('ninja.wepay.client_id'),
'credit_card_id' => (int)$request->input('credit_card_id'), 'client_secret' => config('ninja.wepay.client_secret'),
)); 'credit_card_id' => (int)$request->input('credit_card_id'),
));
}
catch(\Exception $e){
return $this->wepay_payment_driver->processInternallyFailedPayment($this->wepay_payment_driver, $e);
}
$credit_card_id = (int)$response->credit_card_id; $credit_card_id = (int)$response->credit_card_id;

View File

@ -56,8 +56,10 @@ class ClientContactRepository extends BaseRepository
if (! $update_contact) { if (! $update_contact) {
$update_contact = ClientContactFactory::create($client->company_id, $client->user_id); $update_contact = ClientContactFactory::create($client->company_id, $client->user_id);
$update_contact->client_id = $client->id;
} }
//10-09-2021 - enforce the client->id and remove client_id from fillables
$update_contact->client_id = $client->id;
/* We need to set NULL email addresses to blank strings to pass authentication*/ /* We need to set NULL email addresses to blank strings to pass authentication*/
if(array_key_exists('email', $contact) && is_null($contact['email'])) if(array_key_exists('email', $contact) && is_null($contact['email']))
@ -88,5 +90,7 @@ class ClientContactRepository extends BaseRepository
$new_contact->email = ' '; $new_contact->email = ' ';
$new_contact->save(); $new_contact->save();
} }
$client = null;
} }
} }

View File

@ -63,8 +63,8 @@ class TriggeredActions extends AbstractService
private function sendEmail() private function sendEmail()
{ {
//$reminder_template = $this->invoice->calculateTemplate('invoice'); $reminder_template = $this->invoice->calculateTemplate('invoice');
$reminder_template = 'payment'; //$reminder_template = 'payment';
$this->invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) use ($reminder_template) { $this->invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) use ($reminder_template) {
EmailEntity::dispatch($invitation, $this->invoice->company, $reminder_template); EmailEntity::dispatch($invitation, $this->invoice->company, $reminder_template);

View File

@ -83,6 +83,7 @@ class UpdateInvoicePayment
->updatePaidToDate($paid_amount) ->updatePaidToDate($paid_amount)
->updateStatus() ->updateStatus()
->deletePdf() ->deletePdf()
->workFlow()
->save(); ->save();
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));

View File

@ -38,6 +38,7 @@ use App\Utils\Traits\MakesHash;
use App\Utils\Traits\SubscriptionHooker; use App\Utils\Traits\SubscriptionHooker;
use Carbon\Carbon; use Carbon\Carbon;
use GuzzleHttp\RequestOptions; use GuzzleHttp\RequestOptions;
use Illuminate\Contracts\Container\BindingResolutionException;
class SubscriptionService class SubscriptionService
{ {
@ -950,7 +951,12 @@ class SubscriptionService
return redirect($default_redirect); return redirect($default_redirect);
} }
public function planPaid($invoice) /**
* @param Invoice $invoice
* @return true
* @throws BindingResolutionException
*/
public function planPaid(Invoice $invoice)
{ {
$recurring_invoice_hashed_id = $invoice->recurring_invoice()->exists() ? $invoice->recurring_invoice->hashed_id : null; $recurring_invoice_hashed_id = $invoice->recurring_invoice()->exists() ? $invoice->recurring_invoice->hashed_id : null;
@ -959,12 +965,14 @@ class SubscriptionService
'subscription' => $this->subscription->hashed_id, 'subscription' => $this->subscription->hashed_id,
'recurring_invoice' => $recurring_invoice_hashed_id, 'recurring_invoice' => $recurring_invoice_hashed_id,
'client' => $invoice->client->hashed_id, 'client' => $invoice->client->hashed_id,
'contact' => $invoice->client->primary_contact()->first() ? $invoice->client->contacts->first() : false, 'contact' => $invoice->client->primary_contact()->first() ? $invoice->client->primary_contact()->first(): $invoice->client->contacts->first(),
'invoice' => $invoice->hashed_id, 'invoice' => $invoice->hashed_id,
]; ];
$response = $this->triggerWebhook($context); $response = $this->triggerWebhook($context);
nlog($response);
return true; return true;
} }
} }

View File

@ -14,8 +14,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true), 'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => '5.3.8', 'app_version' => '5.3.9',
'app_tag' => '5.3.8', 'app_tag' => '5.3.9',
'minimum_client_version' => '5.0.16', 'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1', 'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', ''), 'api_secret' => env('API_SECRET', ''),

View File

@ -3,12 +3,12 @@ const MANIFEST = 'flutter-app-manifest';
const TEMP = 'flutter-temp-cache'; const TEMP = 'flutter-temp-cache';
const CACHE_NAME = 'flutter-app-cache'; const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = { const RESOURCES = {
"main.dart.js": "a4ce90340b3e610ee073d2f40c0377c1", "main.dart.js": "0124649b1dd42c7fd93b9489eaf99b1e",
"version.json": "46d4015fc9abcefe5371cafcf2084173", "version.json": "9ec5e3813adc4bfd8713556c5059e97d",
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40", "manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35", "icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed", "icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
"/": "7fb4e233bcd97d5af44e8e4ed2d9784b", "/": "debe3f3301b29dcbdc324fb3f330965a",
"assets/NOTICES": "9eb7e2eb2888ea5bae5f536720db37cd", "assets/NOTICES": "9eb7e2eb2888ea5bae5f536720db37cd",
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1", "assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
"assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5", "assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5",

172461
public/main.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

171966
public/main.foss.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

175855
public/main.wasm.dart.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"app_name":"invoiceninja_flutter","version":"5.0.58","build_number":"58"} {"app_name":"invoiceninja_flutter","version":"5.0.59","build_number":"59"}

View File

@ -36,7 +36,8 @@
} }
.company-logo { .company-logo {
max-width: 55%; height: 100%;
padding-right: 120px;
} }
#company-details, #company-details,
@ -251,6 +252,10 @@
[data-ref*=".line_total-td"] { [data-ref*=".line_total-td"] {
white-space: nowrap; white-space: nowrap;
} }
.logo-container {
max-height: 160px;
}
/** Useful snippets, uncomment to enable. **/ /** Useful snippets, uncomment to enable. **/
@ -288,7 +293,9 @@
<tr> <tr>
<td> <td>
<div class="header-wrapper" id="header"> <div class="header-wrapper" id="header">
<img class="company-logo" src="$company.logo" alt="$company.name logo"/> <div class="logo-container">
<img class="company-logo" src="$company.logo" alt="$company.name logo"/>
</div>
<div id="company-details"></div> <div id="company-details"></div>
<div id="company-address"></div> <div id="company-address"></div>
</div> </div>

View File

@ -208,6 +208,7 @@ trait MockAccountData
$this->cu = CompanyUserFactory::create($user->id, $this->company->id, $this->account->id); $this->cu = CompanyUserFactory::create($user->id, $this->company->id, $this->account->id);
$this->cu->is_owner = true; $this->cu->is_owner = true;
$this->cu->is_admin = true; $this->cu->is_admin = true;
$this->cu->is_locked = false;
$this->cu->save(); $this->cu->save();
$this->token = \Illuminate\Support\Str::random(64); $this->token = \Illuminate\Support\Str::random(64);