1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00

Merge pull request #5346 from turbo124/v5-stable

v5.1.35
This commit is contained in:
David Bomba 2021-04-06 19:07:59 +10:00 committed by GitHub
commit 7ed78f2f2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 240454 additions and 239696 deletions

View File

@ -13,7 +13,7 @@ jobs:
strategy:
matrix:
operating-system: ['ubuntu-18.04', 'ubuntu-20.04']
php-versions: ['7.4']
php-versions: ['7.3','7.4','8.0']
phpunit-versions: ['latest']
env:

View File

@ -1 +1 @@
5.1.34
5.1.35

View File

@ -600,6 +600,7 @@ class CompanySettings extends BaseSettings
'$client.city_state_postal',
'$client.country',
'$contact.email',
'$client.phone',
],
'company_details' => [
'$company.name',

View File

@ -23,7 +23,9 @@ class WebhookFactory
$webhook->target_url = '';
$webhook->event_id = 1;
$webhook->format = 'JSON';
$webhook->rest_method = 'post';
$webhook->headers = [];
return $webhook;
}
}

View File

@ -795,7 +795,7 @@ class InvoiceController extends BaseController
$file_path = $invoice->service()->getInvoicePdf($contact);
nlog($file_path);
nlog($file_path);
return response()->download($file_path, basename($file_path));
}

View File

@ -15,6 +15,7 @@ use App\Factory\ClientFactory;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
use App\Mail\ContactPasswordlessLogin;
use App\Models\Client;
use App\Models\Subscription;
use App\Models\ClientContact;
use App\Models\Invoice;
@ -220,6 +221,16 @@ class BillingPortalPurchase extends Component
'settings' => [],
];
foreach ($this->request_data as $field => $value) {
if (in_array($field, Client::$subscriptions_fillable)) {
$data[$field] = $value;
}
if (in_array($field, ClientContact::$subscription_fillable)) {
$data['contacts'][0][$field] = $value;
}
}
if (array_key_exists('locale', $this->request_data)) {
$request = $this->request_data;
@ -391,6 +402,10 @@ class BillingPortalPurchase extends Component
public function render()
{
if (array_key_exists('email', $this->request_data)) {
$this->email = $this->request_data['email'];
}
if ($this->contact instanceof ClientContact) {
$this->getPaymentMethods($this->contact);
}

View File

@ -34,7 +34,7 @@ class StoreSubscriptionRequest extends Request
*/
public function rules()
{
return [
$rules = [
'product_id' => ['sometimes'],
'assigned_user_id' => ['sometimes'],
'is_recurring' => ['sometimes'],
@ -55,12 +55,17 @@ class StoreSubscriptionRequest extends Request
'webhook_configuration' => ['array'],
'name' => ['required', Rule::unique('subscriptions')->where('company_id', auth()->user()->company()->id)]
];
return $this->globalRules($rules);
}
protected function prepareForValidation()
{
$input = $this->all();
$input = $this->decodePrimaryKeys($input);
$this->replace($input);
}
}

View File

@ -35,8 +35,20 @@ class UpdateSubscriptionRequest extends Request
*/
public function rules()
{
return [
$rules = [
//
];
return $this->globalRules($rules);
}
protected function prepareForValidation()
{
$input = $this->all();
$input = $this->decodePrimaryKeys($input);
$this->replace($input);
}
}

View File

@ -34,6 +34,7 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\App;
/*Multi Mailer implemented*/
@ -104,6 +105,9 @@ class EmailEntity implements ShouldQueue
/* Set DB */
MultiDB::setDB($this->company->db);
App::setLocale($this->invitation->contact->preferredLocale());
$nmo = new NinjaMailerObject;
$nmo->mailable = new TemplateEmail($this->email_entity_builder,$this->invitation->contact, $this->invitation);
$nmo->company = $this->company;

View File

@ -11,12 +11,12 @@
namespace App\Jobs\Mail;
use App\Jobs\Mail\NinjaMailer;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
use App\Libraries\MultiDB;
use App\Mail\Admin\EntityNotificationMailer;
use App\Mail\Admin\PaymentFailureObject;
use App\Mail\NinjaMailer;
use App\Models\User;
use App\Utils\Traits\Notifications\UserNotifies;
use Illuminate\Bus\Queueable;
@ -38,7 +38,7 @@ class PaymentFailureMailer implements ShouldQueue
public $company;
public $payment_hash;
public $amount;
public $settings;
@ -50,7 +50,7 @@ class PaymentFailureMailer implements ShouldQueue
* @param $company
* @param $amount
*/
public function __construct($client, $error, $company, $payment_hash)
public function __construct($client, $error, $company, $amount)
{
$this->company = $company;
@ -58,7 +58,7 @@ class PaymentFailureMailer implements ShouldQueue
$this->client = $client;
$this->payment_hash = $payment_hash;
$this->amount = $amount;
$this->company = $company;
@ -86,7 +86,7 @@ class PaymentFailureMailer implements ShouldQueue
if (($key = array_search('mail', $methods)) !== false) {
unset($methods[$key]);
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $this->payment_hash))->build();
$mail_obj = (new PaymentFailureObject($this->client, $this->error, $this->company, $this->amount))->build();
$nmo = new NinjaMailerObject;
$nmo->mailable = new NinjaMailer($mail_obj);

View File

@ -55,6 +55,9 @@ class UpdateOrCreateProduct implements ShouldQueue
{
MultiDB::setDB($this->company->db);
if(strval($this->invoice->client->getSetting('currency_id')) != strval($this->company->settings->currency_id))
return;
/*
* If the invoice was generated from a Task or Expense then
* we do NOT update the product details this short block we

View File

@ -227,6 +227,8 @@ class Import implements ShouldQueue
CompanySizeCheck::dispatch();
info('Completed🚀🚀🚀🚀🚀 at '.now());
unlink($this->file_path);
}
private function setInitialCompanyLedgerBalances()

View File

@ -41,6 +41,8 @@ class InvoiceArchivedActivity implements ShouldQueue
{
MultiDB::setDb($event->company->db);
$event->invoice->service()->deletePdf();
$fields = new stdClass;
$fields->invoice_id = $event->invoice->id;

View File

@ -26,9 +26,9 @@ class PaymentFailureObject
public $company;
public $payment_hash;
public $amount;
private $invoices;
// private $invoices;
/**
* Create a new job instance.
@ -38,7 +38,7 @@ class PaymentFailureObject
* @param $company
* @param $amount
*/
public function __construct($client, $error, $company, $payment_hash)
public function __construct($client, $error, $company, $amount)
{
$this->client = $client;
@ -46,7 +46,7 @@ class PaymentFailureObject
$this->company = $company;
$this->payment_hash = $payment_hash;
$this->amount = $amount;
$this->company = $company;
@ -55,7 +55,7 @@ class PaymentFailureObject
public function build()
{
$this->invoices = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->get();
// $this->invoices = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->get();
$mail_obj = new stdClass;
$mail_obj->amount = $this->getAmount();
@ -70,7 +70,7 @@ class PaymentFailureObject
private function getAmount()
{
return array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
return $this->amount;
}

View File

@ -53,6 +53,7 @@ class Account extends BaseModel
'deleted_at',
'promo_expires',
'discount_expires',
'trial_started',
];
const PLAN_FREE = 'free';
@ -238,14 +239,19 @@ class Account extends BaseModel
}
$trial_active = false;
if ($trial_plan && $include_trial) {
$trial_started = DateTime::createFromFormat('Y-m-d', $this->trial_started);
$trial_expires = clone $trial_started;
$trial_expires->modify('+2 weeks');
if ($trial_expires >= date_create()) {
if ($trial_plan && $include_trial) {
$trial_started = $this->trial_started;
$trial_expires = $this->trial_started->addSeconds($this->trial_duration);
// $trial_expires->modify('+2 weeks');
if($trial_expires->greaterThan(now())){
$trial_active = true;
}
}
// if ($trial_expires >= date_create()) {
// $trial_active = true;
// }
}
$plan_active = false;
@ -265,6 +271,7 @@ class Account extends BaseModel
return null;
}
// Should we show plan details or trial details?
if (($plan && ! $trial_plan) || ! $include_trial) {
$use_plan = true;

View File

@ -99,6 +99,36 @@ class Client extends BaseModel implements HasLocalePreference
protected $touches = [];
/**
* Whitelisted fields for using from query parameters on subscriptions request.
*
* @var string[]
*/
public static $subscriptions_fillable = [
'assigned_user_id',
'address1',
'address2',
'city',
'state',
'postal_code',
'country_id',
'custom_value1',
'custom_value2',
'custom_value3',
'custom_value4',
'shipping_address1',
'shipping_address2',
'shipping_city',
'shipping_state',
'shipping_postal_code',
'shipping_country_id',
'payment_terms',
'vat_number',
'id_number',
'public_notes',
'phone',
];
public function getEntityType()
{
return self::class;
@ -614,7 +644,7 @@ class Client extends BaseModel implements HasLocalePreference
public function recurring_invoice_filepath()
{
return $this->company->company_key.'/'.$this->client_hash.'/recurring_invoices/';
return $this->company->company_key.'/'.$this->client_hash.'/recurring_invoices/';
}
public function company_filepath()

View File

@ -95,6 +95,21 @@ class ClientContact extends Authenticatable implements HasLocalePreference
'client_id',
];
/**
* Whitelisted fields for using from query parameters on subscriptions request.
*
* @var string[]
*/
public static $subscription_fillable = [
'first_name',
'last_name',
'phone',
'custom_value1',
'custom_value2',
'custom_value3',
'custom_value4',
'email',
];
/*
V2 type of scope

View File

@ -20,6 +20,16 @@ class Subscription extends BaseModel
{
use HasFactory, SoftDeletes;
protected $hidden = [
'id',
'user_id',
'assigned_user_id',
'company_id',
'product_ids',
'recurring_product_ids',
'group_id',
];
protected $fillable = [
'assigned_user_id',
'product_ids',

View File

@ -57,6 +57,15 @@ class Webhook extends BaseModel
'target_url',
'format',
'event_id',
'rest_method',
'headers',
];
protected $casts = [
'headers' => 'array',
'updated_at' => 'timestamp',
'created_at' => 'timestamp',
'deleted_at' => 'timestamp',
];
public function user()

View File

@ -17,7 +17,9 @@ use App\Models\Design;
use App\Models\Invoice;
use App\Services\PdfMaker\Design as PdfMakerDesign;
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
use App\Utils\HostedPDF\NinjaPdf;
use App\Utils\HtmlEngine;
use App\Utils\PhantomJS\Phantom;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\Pdf\PdfMaker;
use Illuminate\Support\Facades\Storage;
@ -58,6 +60,10 @@ class GenerateDeliveryNote
$file_path = sprintf('%s%s_delivery_note.pdf', $this->invoice->client->invoice_filepath(), $this->invoice->number);
if (config('ninja.phantomjs_pdf_generation')) {
return (new Phantom)->generate($this->invoice->invitations->first());
}
$design = Design::find($design_id);
$html = new HtmlEngine($this->invoice->invitations->first());
@ -86,7 +92,12 @@ class GenerateDeliveryNote
// Storage::makeDirectory($this->invoice->client->invoice_filepath(), 0775);
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML());
if(config('ninja.invoiceninja_hosted_pdf_generation')){
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
}
else {
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML());
}
if (config('ninja.log_pdf_html')) {
info($maker->getCompiledHTML());

View File

@ -263,7 +263,7 @@ class InvoiceService
{
if ((int)$this->invoice->balance == 0) {
InvoiceWorkflowSettings::dispatch($this->invoice);
InvoiceWorkflowSettings::dispatchNow($this->invoice);
$this->setStatus(Invoice::STATUS_PAID);
}

View File

@ -12,6 +12,7 @@
namespace App\Services\Payment;
use App\Events\Invoice\InvoiceWasUpdated;
use App\Jobs\Invoice\InvoiceWorkflowSettings;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\PaymentHash;
@ -81,8 +82,11 @@ class UpdateInvoicePayment
->updateBalance($paid_amount * -1)
->updatePaidToDate($paid_amount)
->updateStatus()
->deletePdf()
->save();
InvoiceWorkflowSettings::dispatchNow($invoice);
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars()));
});

View File

@ -251,7 +251,7 @@ class Design extends BaseDesign
public function productTable(): array
{
$product_items = collect($this->entity->line_items)->filter(function ($item) {
return $item->type_id == 1;
return $item->type_id == 1 || $item->type_id == 6;
});
if (count($product_items) == 0) {
@ -412,11 +412,9 @@ class Design extends BaseDesign
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => 'product_table-product.tax2-td']];
} elseif ($cell == '$product.tax_rate3') {
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => 'product_table-product.tax3-td']];
}
else if($cell == '$product.unit_cost' || $cell == '$task.rate') {
} else if ($cell == '$product.unit_cost' || $cell == '$task.rate') {
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['style' => 'white-space: nowrap;', 'data-ref' => "{$_type}_table-" . substr($cell, 1) . '-td']];
}
else {
} else {
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => "{$_type}_table-" . substr($cell, 1) . '-td']];
}
}
@ -456,7 +454,7 @@ class Design extends BaseDesign
['element' => 'div', 'properties' => ['class' => 'totals-table-right-side'], 'elements' => []],
];
foreach (['discount', 'custom_surcharge1', 'custom_surcharge2', 'custom_surcharge3', 'custom_surcharge4'] as $property) {
foreach (['discount'] as $property) {
$variable = sprintf('%s%s', '$', $property);
if (
@ -499,6 +497,14 @@ class Design extends BaseDesign
['element' => 'span', 'content', 'content' => Number::formatMoney($tax['total'], $this->context['client']), 'properties' => ['data-ref' => 'totals-table-line_tax_' . $i]],
]];
}
} elseif (Str::startsWith($variable, '$custom')) {
$field = explode('_', $variable);
$visible = property_exists($this->client->company->custom_fields, $field[1]) && !empty($this->client->company->custom_fields->{$field[1]});
$elements[1]['elements'][] = ['element' => 'div', 'elements' => [
['element' => 'span', 'content' => $variable . '_label', 'properties' => ['hidden' => !$visible, 'data-ref' => 'totals_table-' . substr($variable, 1) . '-label']],
['element' => 'span', 'content' => $variable, 'properties' => ['hidden' => !$visible, 'data-ref' => 'totals_table-' . substr($variable, 1)]],
]];
} else {
$elements[1]['elements'][] = ['element' => 'div', 'elements' => [
['element' => 'span', 'content' => $variable . '_label', 'properties' => ['data-ref' => 'totals_table-' . substr($variable, 1) . '-label']],
@ -507,13 +513,6 @@ class Design extends BaseDesign
}
}
if (!is_null($this->entity->partial) && $this->entity->partial > 0) {
$elements[1]['elements'][] = ['element' => 'div', 'elements' => [
['element' => 'span', 'content' => '$partial_due_label', 'properties' => ['data-ref' => 'totals_table-partial_due-label']],
['element' => 'span', 'content' => '$partial_due'],
]];
}
$elements[1]['elements'][] = ['element' => 'div', 'elements' => [
['element' => 'span', 'content' => '',],
['element' => 'span', 'content' => ''],

View File

@ -15,7 +15,9 @@ use App\DataMapper\InvoiceItem;
use App\Factory\InvoiceFactory;
use App\Factory\InvoiceToRecurringInvoiceFactory;
use App\Factory\RecurringInvoiceFactory;
use App\Jobs\Util\SubscriptionWebhookHandler;
use App\Jobs\Util\SystemLogger;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\ClientSubscription;
use App\Models\Invoice;
@ -27,6 +29,7 @@ use App\Models\SystemLog;
use App\Repositories\InvoiceRepository;
use App\Repositories\RecurringInvoiceRepository;
use App\Repositories\SubscriptionRepository;
use App\Utils\Ninja;
use App\Utils\Traits\CleanLineItems;
use App\Utils\Traits\MakesHash;
use GuzzleHttp\RequestOptions;
@ -70,7 +73,16 @@ class SubscriptionService
->save();
//execute any webhooks
$this->triggerWebhook();
$context = [
'context' => 'recurring_purchase',
'recurring_invoice' => $recurring_invoice->hashed_id,
'invoice' => $this->encodePrimaryKey($payment_hash->fee_invoice_id),
'client' => $recurring_invoice->client->hashed_id,
'subscription' => $this->subscription->hashed_id,
];
$this->triggerWebhook($context);
if(array_key_exists('post_purchase_url', $this->subscription->webhook_configuration) && strlen($this->subscription->webhook_configuration['post_purchase_url']) >=1)
return redirect($this->subscription->webhook_configuration['post_purchase_url']);
@ -79,9 +91,17 @@ class SubscriptionService
}
else
{
$invoice = Invoice::find($payment_hash->fee_invoice_id);
$context = [
'context' => 'single_purchase',
'invoice' => $this->encodePrimaryKey($payment_hash->fee_invoice_id),
'client' => $invoice->client->hashed_id,
'subscription' => $this->subscription->hashed_id,
];
//execute any webhooks
$this->triggerWebhook();
$this->triggerWebhook($context);
if(array_key_exists('post_purchase_url', $this->subscription->webhook_configuration) && strlen($this->subscription->webhook_configuration['post_purchase_url']) >=1)
return redirect($this->subscription->webhook_configuration['post_purchase_url']);
@ -91,11 +111,27 @@ class SubscriptionService
}
}
/**
'email' => $this->email ?? $this->contact->email,
'quantity' => $this->quantity,
'contact_id' => $this->contact->id,
*/
/* Hits the client endpoint to determine whether the user is able to access this subscription */
public function isEligible($contact)
{
$context = [
'context' => 'is_eligible',
'subscription' => $this->subscription->hashed_id,
'contact' => $contact->hashed_id,
'contact_email' => $contact->email
];
$response = $this->triggerWebhook($context);
}
/* Starts the process to create a trial
- we create a recurring invoice, which is has its next_send_date as now() + trial_duration
- we then hit the client API end point to advise the trial payload
- we then return the user to either a predefined user endpoint, OR we return the user to the recurring invoice page.
*/
public function startTrial(array $data)
{
// Redirects from here work just fine. Livewire will respect it.
@ -124,11 +160,19 @@ class SubscriptionService
->start()
->save();
//execute any webhooks
$this->triggerWebhook();
$context = [
'context' => 'trial',
'recurring_invoice' => $recurring_invoice->hashed_id,
'client' => $recurring_invoice->client->hashed_id,
'subscription' => $this->subscription->hashed_id,
];
if(array_key_exists('post_purchase_url', $this->subscription->webhook_configuration) && strlen($this->subscription->webhook_configuration['post_purchase_url']) >=1)
return redirect($this->subscription->webhook_configuration['post_purchase_url']);
//execute any webhooks
$response = $this->triggerWebhook($context);
if(array_key_exists('return_url', $this->subscription->webhook_configuration) && strlen($this->subscription->webhook_configuration['return_url']) >=1){
return redirect($this->subscription->webhook_configuration['return_url']);
}
return redirect('/client/recurring_invoices/'.$recurring_invoice->hashed_id);
}
@ -171,67 +215,62 @@ class SubscriptionService
return $recurring_invoice;
}
// @deprecated due to change in architecture
// public function createClientSubscription($payment_hash)
// {
// //is this a recurring or one off subscription.
// $cs = new ClientSubscription();
// $cs->subscription_id = $this->subscription->id;
// $cs->company_id = $this->subscription->company_id;
// $cs->invoice_id = $payment_hash->billing_context->invoice_id;
// $cs->client_id = $payment_hash->billing_context->client_id;
// $cs->quantity = $payment_hash->billing_context->quantity;
// //if is_recurring
// //create recurring invoice from invoice
// if($this->subscription->is_recurring)
// {
// $recurring_invoice = $this->convertInvoiceToRecurring($payment_hash);
// $recurring_invoice->frequency_id = $this->subscription->frequency_id;
// $recurring_invoice->next_send_date = $recurring_invoice->nextDateByFrequency(now()->format('Y-m-d'));
// $recurring_invoice->save();
// $cs->recurring_invoice_id = $recurring_invoice->id;
// //?set the recurring invoice as active - set the date here also based on the frequency?
// $recurring_invoice->service()->start();
// }
// $cs->save();
// $this->client_subscription = $cs;
// }
//@todo - need refactor
public function triggerWebhook()
public function triggerWebhook($context)
{
//hit the webhook to after a successful onboarding
/* If no webhooks have been set, then just return gracefully */
if(!array_key_exists('post_purchase_url', $this->subscription->webhook_configuration) || !array_key_exists('post_purchase_rest_method', $this->subscription->webhook_configuration)) {
return true;
}
// $body = [
// 'subscription' => $this->subscription,
// 'client_subscription' => $this->client_subscription,
// 'client' => $this->client_subscription->client->toArray(),
// ];
$response = false;
$body = array_merge($context, [
'company_key' => $this->subscription->company->company_key,
'account_key' => $this->subscription->company->account->key,
'db' => $this->subscription->company->db,
]);
$headers = [
'Content-Type' => 'application/json',
'X-Requested-With' => 'XMLHttpRequest',
];
// $client = new \GuzzleHttp\Client(['headers' => $this->subscription->webhook_configuration->post_purchase_headers]);
$client = new \GuzzleHttp\Client(
[
'headers' => $headers,
]);
// $response = $client->{$this->subscription->webhook_configuration->post_purchase_rest_method}($this->subscription->post_purchase_url,[
// RequestOptions::JSON => ['body' => $body]
// ]);
try {
$response = $client->{$this->subscription->webhook_configuration['post_purchase_rest_method']}($this->subscription->webhook_configuration['post_purchase_url'],[
RequestOptions::JSON => ['body' => $body], RequestOptions::ALLOW_REDIRECTS => false
]);
}
catch(\Exception $e)
{
$body = array_merge($body, ['exception' => $e->getMessage()]);
}
// SystemLogger::dispatch(
// $body,
// SystemLog::CATEGORY_WEBHOOK,
// SystemLog::EVENT_WEBHOOK_RESPONSE,
// SystemLog::TYPE_WEBHOOK_RESPONSE,
// $this->client_subscription->client,
// );
/* Append the response to the system logger body */
if($response) {
$status = $response->getStatusCode();
$response_body = $response->getBody();
$body = array_merge($body, ['status' => $status, 'response_body' => $response_body]);
}
$client = \App\Models\Client::find($this->decodePrimaryKey($body['client']));
SystemLogger::dispatch(
$body,
SystemLog::CATEGORY_WEBHOOK,
SystemLog::EVENT_WEBHOOK_RESPONSE,
SystemLog::TYPE_WEBHOOK_RESPONSE,
$client,
);
return $response;
}

View File

@ -65,6 +65,7 @@ class SubscriptionTransformer extends EntityTransformer
'created_at' => (int)$subscription->created_at,
'updated_at' => (int)$subscription->updated_at,
'archived_at' => (int)$subscription->deleted_at,
'plan_map' => '', //@deprecated 03/04/2021
];
}

View File

@ -34,6 +34,8 @@ class WebhookTransformer extends EntityTransformer
'target_url' => $webhook->target_url ? (string) $webhook->target_url : '',
'event_id' => (string) $webhook->event_id,
'format' => (string) $webhook->format,
'rest_method' => (string) $webhook->rest_method ?: '',
'headers' => $webhook->headers ?: [],
];
}
}

View File

@ -220,14 +220,14 @@ trait CompanySettingsSaver
switch ($key) {
case 'int':
case 'integer':
return ctype_digit(strval(abs($value)));
return ctype_digit(strval(abs((int)$value)));
// return is_int($value) || ctype_digit(strval(abs($value)));
case 'real':
case 'float':
case 'double':
return is_float($value) || is_numeric(strval($value));
case 'string':
return method_exists($value, '__toString') || is_null($value) || is_string($value);
return (is_string($value) && method_exists($value, '__toString')) || is_null($value) || is_string($value);
//return is_null($value) || is_string($value);
case 'bool':
case 'boolean':

View File

@ -273,7 +273,7 @@ trait MakesInvoiceValues
foreach ($items as $key => $item) {
if ($table_type == '$product' && $item->type_id != 1) {
if ($item->type_id != 4) {
if ($item->type_id != 4 && $item->type_id != 6) {
continue;
}
}

View File

@ -26,7 +26,7 @@
],
"type": "project",
"require": {
"php": "^7.3|^7.4",
"php": "^7.3|^7.4|^8.0",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
@ -38,7 +38,7 @@
"coconutcraig/laravel-postmark": "^2.10",
"composer/composer": "^2",
"czproject/git-php": "^3.17",
"dacastro4/laravel-gmail": "^5.1",
"turbo124/laravel-gmail": "^5",
"doctrine/dbal": "^2.10",
"fideloper/proxy": "^4.2",
"fzaninotto/faker": "^1.4",
@ -71,7 +71,7 @@
"wildbit/swiftmailer-postmark": "^3.3"
},
"require-dev": {
"php": "^7.3|^7.4",
"php": "^7.3|^7.4|^8.0",
"anahkiasen/former": "^4.2",
"barryvdh/laravel-debugbar": "^3.4",
"brianium/paratest": "^6.1",

255
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2307a2f3214da0d1cc772cc1a1405682",
"content-hash": "feb70f976b798dde6550a7b5439bb191",
"packages": [
{
"name": "authorizenet/authorizenet",
@ -51,16 +51,16 @@
},
{
"name": "aws/aws-sdk-php",
"version": "3.176.5",
"version": "3.176.8",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "45d69a8da4f55879f8a24b0b659a5bc7ad077725"
"reference": "776b944988167fa3d563d2cbc5fcb6763424a9f0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/45d69a8da4f55879f8a24b0b659a5bc7ad077725",
"reference": "45d69a8da4f55879f8a24b0b659a5bc7ad077725",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/776b944988167fa3d563d2cbc5fcb6763424a9f0",
"reference": "776b944988167fa3d563d2cbc5fcb6763424a9f0",
"shasum": ""
},
"require": {
@ -135,9 +135,9 @@
"support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.176.5"
"source": "https://github.com/aws/aws-sdk-php/tree/3.176.8"
},
"time": "2021-03-31T18:15:22+00:00"
"time": "2021-04-05T18:16:29+00:00"
},
{
"name": "bacon/bacon-qr-code",
@ -641,16 +641,16 @@
},
{
"name": "composer/composer",
"version": "2.0.11",
"version": "2.0.12",
"source": {
"type": "git",
"url": "https://github.com/composer/composer.git",
"reference": "a5a5632da0b1c2d6fa9a3b65f1f4e90d1f04abb9"
"reference": "6c12ce263da71641903e399c3ce8ecb08fd375fb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/composer/zipball/a5a5632da0b1c2d6fa9a3b65f1f4e90d1f04abb9",
"reference": "a5a5632da0b1c2d6fa9a3b65f1f4e90d1f04abb9",
"url": "https://api.github.com/repos/composer/composer/zipball/6c12ce263da71641903e399c3ce8ecb08fd375fb",
"reference": "6c12ce263da71641903e399c3ce8ecb08fd375fb",
"shasum": ""
},
"require": {
@ -718,7 +718,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/composer/issues",
"source": "https://github.com/composer/composer/tree/2.0.11"
"source": "https://github.com/composer/composer/tree/2.0.12"
},
"funding": [
{
@ -734,7 +734,7 @@
"type": "tidelift"
}
],
"time": "2021-02-24T13:57:23+00:00"
"time": "2021-04-01T08:14:59+00:00"
},
{
"name": "composer/semver",
@ -1006,76 +1006,6 @@
},
"time": "2021-02-15T11:41:33+00:00"
},
{
"name": "dacastro4/laravel-gmail",
"version": "v5.1",
"source": {
"type": "git",
"url": "https://github.com/dacastro4/laravel-gmail.git",
"reference": "6d4cabe04f8cdd02b25ef73a1a489099b5e790bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dacastro4/laravel-gmail/zipball/6d4cabe04f8cdd02b25ef73a1a489099b5e790bd",
"reference": "6d4cabe04f8cdd02b25ef73a1a489099b5e790bd",
"shasum": ""
},
"require": {
"google/apiclient": "^2.5",
"illuminate/auth": "~5.8|^6.0|^7.0|^8.0",
"illuminate/config": "~5.8|^6.0|^7.0|^8.0",
"illuminate/database": "~5.8|^6.0|^7.0|^8.0",
"illuminate/routing": "~5.8|^6.0|^7.0|^8.0",
"illuminate/session": "~5.8|^6.0|^7.0|^8.0",
"illuminate/support": "~5.8|^6.0|^7.0|^8.0",
"php": "^7.2",
"swiftmailer/swiftmailer": "~5.8|^6.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.0",
"phpunit/phpunit": "^8.5",
"squizlabs/php_codesniffer": "~3.4"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Dacastro4\\LaravelGmail\\LaravelGmailServiceProvider"
],
"aliases": {
"LaravelGmail": "Dacastro4\\LaravelGmail\\Facade\\LaravelGmail"
}
}
},
"autoload": {
"psr-4": {
"Dacastro4\\LaravelGmail\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniel Castro",
"email": "danielcastro04@gmail.com",
"homepage": "https://danielcastro.me"
}
],
"description": "Gmail API package for Laravel",
"keywords": [
"api",
"gmail",
"laravel"
],
"support": {
"issues": "https://github.com/dacastro4/laravel-gmail/issues",
"source": "https://github.com/dacastro4/laravel-gmail/tree/v5.1"
},
"time": "2020-12-13T19:17:07+00:00"
},
{
"name": "dasprid/enum",
"version": "1.0.3",
@ -1921,26 +1851,27 @@
},
{
"name": "fzaninotto/faker",
"version": "v1.9.2",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/fzaninotto/Faker.git",
"reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e"
"reference": "5ffe7db6c80f441f150fc88008d64e64af66634b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
"reference": "848d8125239d7dbf8ab25cb7f054f1a630e68c2e",
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/5ffe7db6c80f441f150fc88008d64e64af66634b",
"reference": "5ffe7db6c80f441f150fc88008d64e64af66634b",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0"
"php": "^5.3.3 || ^7.0 || ^8.0"
},
"require-dev": {
"ext-intl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7",
"squizlabs/php_codesniffer": "^2.9.2"
},
"default-branch": true,
"type": "library",
"extra": {
"branch-alias": {
@ -1969,10 +1900,10 @@
],
"support": {
"issues": "https://github.com/fzaninotto/Faker/issues",
"source": "https://github.com/fzaninotto/Faker/tree/v1.9.2"
"source": "https://github.com/fzaninotto/Faker/tree/master"
},
"abandoned": true,
"time": "2020-12-11T09:56:16+00:00"
"time": "2020-12-11T09:59:14+00:00"
},
{
"name": "google/apiclient",
@ -2045,7 +1976,7 @@
},
{
"name": "google/apiclient-services",
"version": "v0.166.0",
"version": "v0.167.0",
"source": {
"type": "git",
"url": "https://github.com/googleapis/google-api-php-client-services.git",
@ -2080,7 +2011,7 @@
],
"support": {
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.166.0"
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.167.0"
},
"time": "2021-03-22T11:26:04+00:00"
},
@ -3824,27 +3755,28 @@
},
{
"name": "league/omnipay",
"version": "v3.1.0",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay.git",
"reference": "1ba7c8a3312cf2342458b99c9e5b86eaae44aed2"
"reference": "e9439db0633ba988e6f6cdd029fad38aad73f9f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay/zipball/1ba7c8a3312cf2342458b99c9e5b86eaae44aed2",
"reference": "1ba7c8a3312cf2342458b99c9e5b86eaae44aed2",
"url": "https://api.github.com/repos/thephpleague/omnipay/zipball/e9439db0633ba988e6f6cdd029fad38aad73f9f6",
"reference": "e9439db0633ba988e6f6cdd029fad38aad73f9f6",
"shasum": ""
},
"require": {
"omnipay/common": "^3",
"php": "^7.2",
"php": "^7.2|^8.0",
"php-http/discovery": "^1.12",
"php-http/guzzle7-adapter": "^0.1"
},
"require-dev": {
"omnipay/tests": "^3"
},
"default-branch": true,
"type": "metapackage",
"extra": {
"branch-alias": {
@ -3875,22 +3807,22 @@
],
"support": {
"issues": "https://github.com/thephpleague/omnipay/issues",
"source": "https://github.com/thephpleague/omnipay/tree/v3.1.0"
"source": "https://github.com/thephpleague/omnipay/tree/master"
},
"time": "2020-09-22T14:02:17+00:00"
"time": "2021-03-12T09:17:59+00:00"
},
{
"name": "livewire/livewire",
"version": "v2.4.1",
"version": "v2.4.2",
"source": {
"type": "git",
"url": "https://github.com/livewire/livewire.git",
"reference": "b0cb782674673a67ddfd5910d2fcb5308bb32857"
"reference": "2495387841a3eb03ac62b2c984ccd2574303285b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/livewire/livewire/zipball/b0cb782674673a67ddfd5910d2fcb5308bb32857",
"reference": "b0cb782674673a67ddfd5910d2fcb5308bb32857",
"url": "https://api.github.com/repos/livewire/livewire/zipball/2495387841a3eb03ac62b2c984ccd2574303285b",
"reference": "2495387841a3eb03ac62b2c984ccd2574303285b",
"shasum": ""
},
"require": {
@ -3941,7 +3873,7 @@
"description": "A front-end framework for Laravel.",
"support": {
"issues": "https://github.com/livewire/livewire/issues",
"source": "https://github.com/livewire/livewire/tree/v2.4.1"
"source": "https://github.com/livewire/livewire/tree/v2.4.2"
},
"funding": [
{
@ -3949,7 +3881,7 @@
"type": "github"
}
],
"time": "2021-03-22T14:03:36+00:00"
"time": "2021-04-04T15:46:50+00:00"
},
{
"name": "maennchen/zipstream-php",
@ -4628,21 +4560,21 @@
},
{
"name": "omnipay/common",
"version": "v3.0.5",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-common.git",
"reference": "0d1f4486c1c873537ac030d37c7ce2986c4de1d2"
"reference": "e1ebc22615f14219d31cefdf62d7036feb228b1c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-common/zipball/0d1f4486c1c873537ac030d37c7ce2986c4de1d2",
"reference": "0d1f4486c1c873537ac030d37c7ce2986c4de1d2",
"url": "https://api.github.com/repos/thephpleague/omnipay-common/zipball/e1ebc22615f14219d31cefdf62d7036feb228b1c",
"reference": "e1ebc22615f14219d31cefdf62d7036feb228b1c",
"shasum": ""
},
"require": {
"moneyphp/money": "^3.1",
"php": "^5.6|^7",
"php": "^5.6|^7|^8",
"php-http/client-implementation": "^1",
"php-http/discovery": "^1.2.1",
"php-http/message": "^1.5",
@ -4657,6 +4589,7 @@
"suggest": {
"league/omnipay": "The default Omnipay package provides a default HTTP Adapter."
},
"default-branch": true,
"type": "library",
"extra": {
"branch-alias": {
@ -4708,9 +4641,9 @@
],
"support": {
"issues": "https://github.com/thephpleague/omnipay-common/issues",
"source": "https://github.com/thephpleague/omnipay-common/tree/v3.0.5"
"source": "https://github.com/thephpleague/omnipay-common/tree/master"
},
"time": "2020-08-20T18:22:12+00:00"
"time": "2020-12-13T12:53:48+00:00"
},
{
"name": "omnipay/paypal",
@ -5645,23 +5578,22 @@
},
{
"name": "predis/predis",
"version": "v1.1.6",
"version": "v1.1.7",
"source": {
"type": "git",
"url": "https://github.com/predis/predis.git",
"reference": "9930e933c67446962997b05201c69c2319bf26de"
"reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/predis/predis/zipball/9930e933c67446962997b05201c69c2319bf26de",
"reference": "9930e933c67446962997b05201c69c2319bf26de",
"url": "https://api.github.com/repos/predis/predis/zipball/b240daa106d4e02f0c5b7079b41e31ddf66fddf8",
"reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
"cweagans/composer-patches": "^1.6",
"phpunit/phpunit": "~4.8"
},
"suggest": {
@ -5669,18 +5601,6 @@
"ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
},
"type": "library",
"extra": {
"composer-exit-on-patch-failure": true,
"patches": {
"phpunit/phpunit-mock-objects": {
"Fix PHP 7 and 8 compatibility": "./tests/phpunit_mock_objects.patch"
},
"phpunit/phpunit": {
"Fix PHP 7 compatibility": "./tests/phpunit_php7.patch",
"Fix PHP 8 compatibility": "./tests/phpunit_php8.patch"
}
}
},
"autoload": {
"psr-4": {
"Predis\\": "src/"
@ -5712,7 +5632,7 @@
],
"support": {
"issues": "https://github.com/predis/predis/issues",
"source": "https://github.com/predis/predis/tree/v1.1.6"
"source": "https://github.com/predis/predis/tree/v1.1.7"
},
"funding": [
{
@ -5720,7 +5640,7 @@
"type": "github"
}
],
"time": "2020-09-11T19:18:05+00:00"
"time": "2021-04-04T19:34:46+00:00"
},
{
"name": "psr/cache",
@ -9761,6 +9681,75 @@
},
"time": "2021-03-23T09:54:29+00:00"
},
{
"name": "turbo124/laravel-gmail",
"version": "v5.0.1",
"source": {
"type": "git",
"url": "https://github.com/turbo124/laravel-gmail.git",
"reference": "55ca0271a54a568ebaa26febbe0790b2ce5ac966"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/turbo124/laravel-gmail/zipball/55ca0271a54a568ebaa26febbe0790b2ce5ac966",
"reference": "55ca0271a54a568ebaa26febbe0790b2ce5ac966",
"shasum": ""
},
"require": {
"google/apiclient": "^2.5",
"illuminate/auth": "~5.8|^6.0|^7.0|^8.0",
"illuminate/config": "~5.8|^6.0|^7.0|^8.0",
"illuminate/database": "~5.8|^6.0|^7.0|^8.0",
"illuminate/routing": "~5.8|^6.0|^7.0|^8.0",
"illuminate/session": "~5.8|^6.0|^7.0|^8.0",
"illuminate/support": "~5.8|^6.0|^7.0|^8.0",
"php": "^7.3|^7.4|^8.0",
"swiftmailer/swiftmailer": "~5.8|^6.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.0",
"phpunit/phpunit": "^8.5",
"squizlabs/php_codesniffer": "~3.4"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Dacastro4\\LaravelGmail\\LaravelGmailServiceProvider"
],
"aliases": {
"LaravelGmail": "Dacastro4\\LaravelGmail\\Facade\\LaravelGmail"
}
}
},
"autoload": {
"psr-4": {
"Dacastro4\\LaravelGmail\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Daniel Castro",
"email": "danielcastro04@gmail.com",
"homepage": "https://danielcastro.me"
}
],
"description": "Gmail API package for Laravel",
"keywords": [
"api",
"gmail",
"laravel"
],
"support": {
"source": "https://github.com/turbo124/laravel-gmail/tree/v5.0.1"
},
"time": "2021-04-06T00:53:48+00:00"
},
{
"name": "vlucas/phpdotenv",
"version": "v5.3.0",
@ -14133,13 +14122,13 @@
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^7.3|^7.4",
"php": "^7.3|^7.4|^8.0",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*"
},
"platform-dev": {
"php": "^7.3|^7.4"
"php": "^7.3|^7.4|^8.0"
},
"plugin-api-version": "2.0.0"
}

View File

@ -43,7 +43,7 @@ return [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'connection' => env('REDIS_BROADCAST_CONNECTION', 'default'),
],
'log' => [

View File

@ -74,7 +74,7 @@ return [
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
'connection' => env('REDIS_CACHE_CONNECTION', 'cache'),
],
'dynamodb' => [

View File

@ -153,6 +153,42 @@ return [
'database' => env('REDIS_CACHE_DB', 1),
],
'sentinel-default' => array_merge(
array_map(
function ($a, $b) {
return ["host" => $a,"port" => $b];
},
explode(',', env('REDIS_HOST', 'localhost')),
explode(',', env('REDIS_PORT', 26379))
),
['options' => [
'replication' => 'sentinel',
'service' => env('REDIS_SENTINEL_SERVICE', 'mymaster'),
'parameters' => [
'password' => env('REDIS_PASSWORD', null),
'database' => env('REDIS_DB', 0),
],
]]
),
'sentinel-cache' => array_merge(
array_map(
function ($a, $b) {
return ["host" => $a,"port" => $b];
},
explode(',', env('REDIS_HOST', 'localhost')),
explode(',', env('REDIS_PORT', 26379))
),
['options' => [
'replication' => 'sentinel',
'service' => env('REDIS_SENTINEL_SERVICE', 'mymaster'),
'parameters' => [
'password' => env('REDIS_PASSWORD', null),
'database' => env('REDIS_CACHE_DB', 1),
],
]]
),
],
];

View File

@ -14,7 +14,7 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', ''),
'app_version' => '5.1.34',
'app_version' => '5.1.35',
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false),
@ -142,7 +142,7 @@ return [
'expanded_logging' => env('EXPANDED_LOGGING', false),
'snappdf_chromium_path' => env('SNAPPDF_CHROMIUM_PATH', false),
'v4_migration_version' => '4.5.35',
'flutter_canvas_kit' => env('FLUTTER_CANVAS_KIT', 'selfhosted-html'),
'flutter_renderer' => env('FLUTTER_RENDERER', 'selfhosted-html'),
'webcron_secret' => env('WEBCRON_SECRET', false),
'disable_auto_update' => env('DISABLE_AUTO_UPDATE', false),
'invoiceninja_hosted_pdf_generation' => env('NINJA_HOSTED_PDF', false),

View File

@ -61,7 +61,7 @@ return [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90000000,
'block_for' => null,

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddTrialDurationToAccountsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function (Blueprint $table) {
$table->unsignedInteger('trial_duration')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddRestFieldsToWebhooksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('webhooks', function (Blueprint $table) {
$table->text('rest_method')->nullable();
$table->text('headers')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('webhooks', function (Blueprint $table) {
//
});
}
}

View File

@ -31,7 +31,7 @@ const RESOURCES = {
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
"main.dart.js": "54ad5a5e961909b8be9d8dd395bb3628",
"main.dart.js": "23e852b45f0ac1c4cf3d45a272ec0c83",
"version.json": "e021a7a1750aa3e7d1d89b51ac9837e9"
};

158643
public/main.dart.js vendored

File diff suppressed because one or more lines are too long

160513
public/main.foss.dart.js vendored

File diff suppressed because one or more lines are too long

160109
public/main.wasm.dart.js vendored

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@
if(!isset($design)) {
$design = 'light';
}
$primary_color = isset($settings) ? $settings->primary_color : '#4caf50';
@endphp
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@ -16,11 +17,11 @@
<style type="text/css">
:root {
--primary-color: {{ isset($settings) ? $settings->primary_color : '#4caf50' }};
--primary-color: {{ $primary_color }};
}
.primary-color-bg {
background-color: {{ isset($settings) ? $settings->primary_color : '#4caf50' }};
background-color: {{ $primary_color }};
}
#email-content h1, h2, h3, h4 {
@ -38,7 +39,7 @@
}
.button {
background-color: {{ isset($settings) ? $settings->primary_color : '#4caf50' }};
background-color: {{ $primary_color }};
color: white;
padding: 10px 16px;
text-decoration: none;
@ -68,7 +69,7 @@
<table align="center" cellpadding="0" cellspacing="0" width="600"
style="box-shadow: 0 1px 3px 0 rgba(0,0,0,.1), 0 1px 2px 0 rgba(0,0,0,.06)">
<tr>
<td align="center" bgcolor="#4caf50" class="primary-color-bg" style="padding: 40px 0 30px 0;">
<td align="center" bgcolor="{{ $primary_color }}" class="primary-color-bg" style="padding: 40px 0 30px 0;">
{{ $header }}
</td>
</tr>

View File

@ -146,9 +146,9 @@
</script>
@if(config('ninja.flutter_canvas_kit') == 'hosted')
@if(config('ninja.flutter_renderer') == 'hosted')
<script defer src="main.dart.js?v={{ config('ninja.app_version') }}" type="application/javascript"></script>
@elseif(config('ninja.flutter_canvas_kit') == 'selfhosted-canvaskit')
@elseif(config('ninja.flutter_renderer') == 'selfhosted-canvaskit')
<script defer src="main.wasm.dart.js?v={{ config('ninja.app_version') }}" type="application/javascript"></script>
@else
<script defer src="main.foss.dart.js?v={{ config('ninja.app_version') }}" type="application/javascript"></script>

View File

@ -19,7 +19,10 @@
@foreach($subscription->service()->products() as $product)
<div class="flex items-center justify-between mb-4 bg-white rounded px-6 py-4 shadow-sm border">
<div class="text-sm">{{ $product->product_key }}</div>
<div>
<p class="text-sm text-xl">{{ $product->product_key }}</p>
<p class="text-sm text-gray-800">{{ $product->notes }}</p>
</div>
<div data-ref="price-and-quantity-container">
<span
data-ref="price">{{ \App\Utils\Number::formatMoney($product->price, $subscription->company) }}</span>
@ -57,8 +60,7 @@
<div class="relative flex justify-center text-sm leading-5">
<h1 class="text-2xl font-bold tracking-wide bg-gray-50 px-6 py-0">
{{ ctrans('texts.total') }}
: {{ \App\Utils\Number::formatMoney($price, $subscription->company) }}
{{ ctrans('texts.total') }}: {{ \App\Utils\Number::formatMoney($price, $subscription->company) }}
@if($steps['discount_applied'])
<small class="ml-1 line-through text-gray-500">{{ \App\Utils\Number::formatMoney($subscription->price, $subscription->company) }}</small>

View File

@ -3,7 +3,7 @@
@push('head')
<meta name="show-invoice-terms" content="{{ $settings->show_accept_invoice_terms ? true : false }}">
<meta name="require-invoice-signature" content="{{ $settings->require_invoice_signature ? true : false }}">
<meta name="require-invoice-signature" content="{{ $client->company->account->hasFeature(\App\Models\Account::FEATURE_INVOICE_SETTINGS) && $settings->require_invoice_signature }}">
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
@endpush

View File

@ -4,7 +4,7 @@
@push('head')
<meta name="pdf-url" content="{{ $invoice->pdf_file_path() }}">
<meta name="show-invoice-terms" content="{{ $settings->show_accept_invoice_terms ? true : false }}">
<meta name="require-invoice-signature" content="{{ $settings->require_invoice_signature ? true : false }}">
<meta name="require-invoice-signature" content="{{ $client->company->account->hasFeature(\App\Models\Account::FEATURE_INVOICE_SETTINGS) && $settings->require_invoice_signature }}">
<script src="{{ asset('js/vendor/pdf.js/pdf.min.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
@endpush

View File

@ -3,7 +3,7 @@
@push('head')
<meta name="show-quote-terms" content="{{ $settings->show_accept_quote_terms ? true : false }}">
<meta name="require-quote-signature" content="{{ $settings->require_quote_signature ? true : false }}">
<meta name="require-quote-signature" content="{{ $client->company->account->hasFeature(\App\Models\Account::FEATURE_INVOICE_SETTINGS) && $settings->require_quote_signature }}">
<script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
@endpush

View File

@ -0,0 +1,65 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace Tests\Feature\Ninja;
use App\Models\Account;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Session;
use Tests\MockAccountData;
use Tests\TestCase;
/**
* @test
*/
class PlanTest extends TestCase
{
use MakesHash;
use DatabaseTransactions;
use MockAccountData;
public function setUp() :void
{
parent::setUp();
$this->makeTestData();
Session::start();
$this->faker = \Faker\Factory::create();
Model::reguard();
}
public function testTrialFeatures()
{
config(['ninja.production' => true]);
$this->assertFalse($this->account->hasFeature(Account::FEATURE_USERS));
$this->account->trial_plan = 'enterprise';
$this->account->trial_started = now();
$this->account->trial_duration = 60*60*24*31;
$this->account->save();
$this->assertFalse($this->account->hasFeature(Account::FEATURE_USERS));
$this->account->trial_plan = 'pro';
$this->account->save();
$this->assertFalse($this->account->hasFeature(Account::FEATURE_USERS));
$this->assertTrue($this->account->hasFeature(Account::FEATURE_CUSTOM_URL));
}
}

View File

@ -55,4 +55,36 @@ class CompanySettingsTest extends TestCase
$this->assertEquals(1, count($diff));
}
public function testStringEquivalence()
{
$value = (strval(4) != strval(3));
$this->assertTrue($value);
$value = (strval(4) != strval(4));
$this->assertFalse($value);
$value = (strval('4') != strval(4));
$this->assertFalse($value);
$value = (strval('4') != strval('4'));
$this->assertFalse($value);
$value = (strval('4') != strval(3));
$this->assertTrue($value);
$value = (strval(4) != strval('3'));
$this->assertTrue($value);
$value = (strval('4') != strval('3'));
$this->assertTrue($value);
}
}