Merge pull request #7884 from turbo124/preview

Preview
This commit is contained in:
David Bomba 2022-10-23 11:41:59 +11:00 committed by GitHub
commit e1b2afd871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 10438 additions and 10384 deletions

View File

@ -36,6 +36,10 @@ class ExpenseMap
17 => 'expense.tax_rate3', 17 => 'expense.tax_rate3',
18 => 'expense.uses_inclusive_taxes', 18 => 'expense.uses_inclusive_taxes',
19 => 'expense.payment_date', 19 => 'expense.payment_date',
20 => 'expense.custom_value1',
21 => 'expense.custom_value2',
22 => 'expense.custom_value3',
23 => 'expense.custom_value4',
]; ];
} }
@ -63,6 +67,10 @@ class ExpenseMap
17 => 'texts.tax_rate3', 17 => 'texts.tax_rate3',
18 => 'texts.uses_inclusive_taxes', 18 => 'texts.uses_inclusive_taxes',
19 => 'texts.payment_date', 19 => 'texts.payment_date',
20 => 'texts.custom_value1',
21 => 'texts.custom_value2',
22 => 'texts.custom_value3',
23 => 'texts.custom_value4',
]; ];
} }

View File

@ -86,7 +86,7 @@ class CreateAccount
$sp794f3f->hosted_company_count = config('ninja.quotas.free.max_companies'); $sp794f3f->hosted_company_count = config('ninja.quotas.free.max_companies');
$sp794f3f->account_sms_verified = true; $sp794f3f->account_sms_verified = true;
if(in_array($this->getDomain($this->request['email']), ['gmail.com', 'hotmail.com', 'outlook.com', 'yahoo.com', 'aol.com', 'mail.ru'])){ if(in_array($this->getDomain($this->request['email']), ['yopmail.com','gmail.com', 'hotmail.com', 'outlook.com', 'yahoo.com', 'aol.com', 'mail.ru'])){
$sp794f3f->account_sms_verified = false; $sp794f3f->account_sms_verified = false;
} }

View File

@ -515,8 +515,8 @@ class CompanyExport implements ShouldQueue
$path = 'backups'; $path = 'backups';
if(!Storage::disk(config('filesystems.default'))->exists($path)) // if(!Storage::disk(config('filesystems.default'))->exists($path))
Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775); // Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775);
$zip_path = public_path('storage/backups/'.$file_name); $zip_path = public_path('storage/backups/'.$file_name);
$zip = new \ZipArchive(); $zip = new \ZipArchive();

View File

@ -213,11 +213,13 @@ class CreateEntityPdf implements ShouldQueue
if ($pdf) { if ($pdf) {
try { try {
if (! Storage::disk($this->disk)->exists($path)) { // if (! Storage::disk($this->disk)->exists($path)) {
Storage::disk($this->disk)->makeDirectory($path, 0775); // Storage::disk($this->disk)->makeDirectory($path, 0775);
} // }
Storage::disk($this->disk)->put($file_path, $pdf, 'public'); Storage::disk($this->disk)->put($file_path, $pdf, 'public');
//r2 Storage::disk($this->disk)->put($file_path, $pdf);
} catch (\Exception $e) { } catch (\Exception $e) {
throw new FilePermissionsFailure($e->getMessage()); throw new FilePermissionsFailure($e->getMessage());
} }

View File

@ -83,9 +83,23 @@ class UpdateOrCreateProduct implements ShouldQueue
$product = Product::withTrashed()->firstOrNew(['product_key' => $item->product_key, 'company_id' => $this->invoice->company->id]); $product = Product::withTrashed()->firstOrNew(['product_key' => $item->product_key, 'company_id' => $this->invoice->company->id]);
/* If a user is using placeholders in their descriptions, do not update the products */
$string_hit = false;
foreach ( [':MONTH',':YEAR',':QUARTER',':WEEK'] as $string )
{
if(stripos($product->notes, $string) !== FALSE) {
$string_hit = true;
}
}
if($string_hit)
continue;
$product->product_key = $item->product_key; $product->product_key = $item->product_key;
$product->notes = isset($item->notes) ? $item->notes : ''; $product->notes = isset($item->notes) ? $item->notes : '';
//$product->cost = isset($item->cost) ? $item->cost : 0; //this value shouldn't be updated.
$product->price = isset($item->cost) ? $item->cost : 0; $product->price = isset($item->cost) ? $item->cost : 0;
if (! $product->id) { if (! $product->id) {

View File

@ -100,11 +100,13 @@ class CreatePurchaseOrderPdf implements ShouldQueue
try{ try{
if(!Storage::disk($this->disk)->exists($this->path)) // if(!Storage::disk($this->disk)->exists($this->path))
Storage::disk($this->disk)->makeDirectory($this->path, 0775); // Storage::disk($this->disk)->makeDirectory($this->path, 0775);
Storage::disk($this->disk)->put($this->file_path, $pdf, 'public'); Storage::disk($this->disk)->put($this->file_path, $pdf, 'public');
//r2 Storage::disk($this->disk)->put($this->file_path, $pdf);
} }
catch(\Exception $e) catch(\Exception $e)
{ {

View File

@ -146,10 +146,17 @@ class TemplateEmail extends Mailable
} }
//22-10-2022 - Performance - To improve the performance/reliability of sending emails, attaching as Data is much better, stubs in place
foreach ($this->build_email->getAttachments() as $file) { foreach ($this->build_email->getAttachments() as $file) {
if (is_string($file)) { if (is_string($file)) {
// nlog($file);
// $file_data = file_get_contents($file);
// $this->attachData($file_data, basename($file));
$this->attach($file); $this->attach($file);
} elseif (is_array($file)) { } elseif (is_array($file)) {
// nlog($file['path']);
// $file_data = file_get_contents($file['path']);
// $this->attachData($file_data, $file['name']);
$this->attach($file['path'], ['as' => $file['name'], 'mime' => null]); $this->attach($file['path'], ['as' => $file['name'], 'mime' => null]);
} }
} }

View File

@ -36,15 +36,15 @@ class Backup extends BaseModel
$filename = now()->format('Y_m_d').'_'.md5(time()).'.html'; $filename = now()->format('Y_m_d').'_'.md5(time()).'.html';
$file_path = $path.$filename; $file_path = $path.$filename;
Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775); // Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775);
Storage::disk(config('filesystems.default'))->put($file_path, $html); Storage::disk(config('filesystems.default'))->put($file_path, $html);
if (Storage::disk(config('filesystems.default'))->exists($file_path)) { // if (Storage::disk(config('filesystems.default'))->exists($file_path)) {
$this->html_backup = ''; $this->html_backup = '';
$this->filename = $file_path; $this->filename = $file_path;
$this->save(); $this->save();
} // }
} }
public function deleteFile() public function deleteFile()

View File

@ -602,11 +602,11 @@ class BaseDriver extends AbstractPaymentDriver
} }
} }
if ($this->company_gateway->require_contact_email) { // if ($this->company_gateway->require_contact_email) {
if ($this->checkRequiredResource($this->email)) { // if ($this->checkRequiredResource($this->email)) {
$this->required_fields[] = 'contact_email'; // $this->required_fields[] = 'contact_email';
} // }
} // }
// if ($this->company_gateway->require_contact_name) { // if ($this->company_gateway->require_contact_name) {
// if ($this->checkRequiredResource($this->first_name)) { // if ($this->checkRequiredResource($this->first_name)) {

View File

@ -14,9 +14,11 @@ namespace App\PaymentDrivers\CheckoutCom;
use App\Exceptions\PaymentFailed; use App\Exceptions\PaymentFailed;
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
use App\Jobs\Util\SystemLogger;
use App\Models\ClientGatewayToken; use App\Models\ClientGatewayToken;
use App\Models\GatewayType; use App\Models\GatewayType;
use App\Models\Payment; use App\Models\Payment;
use App\Models\SystemLog;
use App\PaymentDrivers\CheckoutComPaymentDriver; use App\PaymentDrivers\CheckoutComPaymentDriver;
use App\PaymentDrivers\Common\MethodInterface; use App\PaymentDrivers\Common\MethodInterface;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
@ -242,6 +244,16 @@ class CreditCard implements MethodInterface
if ($response['status'] == 'Declined') { if ($response['status'] == 'Declined') {
$this->checkout->unWindGatewayFees($this->checkout->payment_hash); $this->checkout->unWindGatewayFees($this->checkout->payment_hash);
//18-10-2022
SystemLogger::dispatch(
$response,
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_ERROR,
SystemLog::TYPE_CHECKOUT,
$this->checkout->client,
$this->checkout->client->company,
);
return $this->processUnsuccessfulPayment($response); return $this->processUnsuccessfulPayment($response);
} }
} catch (CheckoutApiException $e) { } catch (CheckoutApiException $e) {

View File

@ -49,8 +49,8 @@ class EntityPolicy
return ($user->isAdmin() && $entity->company_id == $user->companyId()) return ($user->isAdmin() && $entity->company_id == $user->companyId())
|| ($user->hasPermission('edit_'.strtolower(\Illuminate\Support\Str::snake(class_basename($entity)))) && $entity->company_id == $user->companyId()) || ($user->hasPermission('edit_'.strtolower(\Illuminate\Support\Str::snake(class_basename($entity)))) && $entity->company_id == $user->companyId())
|| ($user->hasPermission('edit_all') && $entity->company_id == $user->companyId()) || ($user->hasPermission('edit_all') && $entity->company_id == $user->companyId())
|| $user->owns($entity) || ($user->owns($entity) && $entity->company_id == $user->companyId())
|| $user->assigned($entity); || ($user->assigned($entity) && $entity->company_id == $user->companyId());
} }
/** /**
@ -66,7 +66,7 @@ class EntityPolicy
return ($user->isAdmin() && $entity->company_id == $user->companyId()) return ($user->isAdmin() && $entity->company_id == $user->companyId())
|| ($user->hasPermission('view_'.strtolower(\Illuminate\Support\Str::snake(class_basename($entity)))) && $entity->company_id == $user->companyId()) || ($user->hasPermission('view_'.strtolower(\Illuminate\Support\Str::snake(class_basename($entity)))) && $entity->company_id == $user->companyId())
|| ($user->hasPermission('view_all') && $entity->company_id == $user->companyId()) || ($user->hasPermission('view_all') && $entity->company_id == $user->companyId())
|| $user->owns($entity) || ($user->owns($entity) && $entity->company_id == $user->companyId())
|| $user->assigned($entity); || ($user->assigned($entity) && $entity->company_id == $user->companyId());
} }
} }

View File

@ -59,7 +59,8 @@ class ActivityRepository extends BaseRepository
$activity->save(); $activity->save();
$this->createBackup($entity, $activity); //rate limiter
// $this->createBackup($entity, $activity);
} }
/** /**
@ -82,7 +83,8 @@ class ActivityRepository extends BaseRepository
$backup = new Backup(); $backup = new Backup();
$entity->load('client'); $entity->load('client');
$contact = $entity->client->primary_contact()->first(); $contact = $entity->client->primary_contact()->first();
$backup->html_backup = $this->generateHtml($entity); $backup->html_backup = '';
// $backup->html_backup = $this->generateHtml($entity);
$backup->amount = $entity->amount; $backup->amount = $entity->amount;
$backup->activity_id = $activity->id; $backup->activity_id = $activity->id;
$backup->json_backup = ''; $backup->json_backup = '';

View File

@ -19,9 +19,11 @@ use App\Models\Credit;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Quote; use App\Models\Quote;
use App\Models\RecurringInvoice; use App\Models\RecurringInvoice;
use App\Utils\Helpers;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use App\Utils\Traits\SavesDocuments; use App\Utils\Traits\SavesDocuments;
use Google\Service\Vision\Property;
use ReflectionClass; use ReflectionClass;
class BaseRepository class BaseRepository
@ -108,32 +110,6 @@ class BaseRepository
} }
} }
/**
* @param $ids
* @param $action
*
* @return int
* @deprecated - this doesn't appear to be used anywhere?
*/
// public function bulk($ids, $action)
// {
// if (! $ids) {
// return 0;
// }
// $ids = $this->transformKeys($ids);
// $entities = $this->findByPublicIdsWithTrashed($ids);
// foreach ($entities as $entity) {
// if (auth()->user()->can('edit', $entity)) {
// $this->$action($entity);
// }
// }
// return count($entities);
// }
/* Returns an invoice if defined as a key in the $resource array*/ /* Returns an invoice if defined as a key in the $resource array*/
public function getInvitation($invitation, $resource) public function getInvitation($invitation, $resource)
{ {
@ -171,7 +147,7 @@ class BaseRepository
* @throws \ReflectionException * @throws \ReflectionException
*/ */
protected function alternativeSave($data, $model) protected function alternativeSave($data, $model)
{ { //$start = microtime(true);
//forces the client_id if it doesn't exist //forces the client_id if it doesn't exist
if(array_key_exists('client_id', $data)) if(array_key_exists('client_id', $data))
$model->client_id = $data['client_id']; $model->client_id = $data['client_id'];
@ -208,9 +184,21 @@ class BaseRepository
$model->custom_surcharge_tax3 = $client->company->custom_surcharge_taxes3; $model->custom_surcharge_tax3 = $client->company->custom_surcharge_taxes3;
$model->custom_surcharge_tax4 = $client->company->custom_surcharge_taxes4; $model->custom_surcharge_tax4 = $client->company->custom_surcharge_taxes4;
if(!$model->id) if(!$model->id){
$this->new_model = true; $this->new_model = true;
if(is_array($model->line_items))
{
$model->line_items = (collect($model->line_items))->map(function ($item) use($model,$client) {
$item->notes = Helpers::processReservedKeywords($item->notes, $client);
return $item;
});
}
}
$model->saveQuietly(); $model->saveQuietly();
/* Model now persisted, now lets do some child tasks */ /* Model now persisted, now lets do some child tasks */
@ -378,6 +366,8 @@ class BaseRepository
$model->save(); $model->save();
// nlog("save time = ". microtime(true) - $start);
return $model->fresh(); return $model->fresh();
} }
} }

View File

@ -105,11 +105,14 @@ class GenerateDeliveryNote
info($maker->getCompiledHTML()); info($maker->getCompiledHTML());
} }
if (! Storage::disk($this->disk)->exists($this->invoice->client->invoice_filepath($invitation))) { // if (! Storage::disk($this->disk)->exists($this->invoice->client->invoice_filepath($invitation))) {
Storage::disk($this->disk)->makeDirectory($this->invoice->client->invoice_filepath($invitation), 0775); // Storage::disk($this->disk)->makeDirectory($this->invoice->client->invoice_filepath($invitation), 0775);
} // }
Storage::disk($this->disk)->put($file_path, $pdf, 'public'); Storage::disk($this->disk)->put($file_path, $pdf, 'public');
//r2 Storage::disk($this->disk)->put($file_path, $pdf);
return $file_path; return $file_path;
} }
} }

View File

@ -218,6 +218,7 @@ class InvoiceService
public function markDeleted() public function markDeleted()
{ {
$this->removeUnpaidGatewayFees(); $this->removeUnpaidGatewayFees();
$this->deletePdf();
$this->invoice = (new MarkInvoiceDeleted($this->invoice))->run(); $this->invoice = (new MarkInvoiceDeleted($this->invoice))->run();
@ -298,6 +299,9 @@ class InvoiceService
} elseif ($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount) { } elseif ($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount) {
$this->setStatus(Invoice::STATUS_PARTIAL); $this->setStatus(Invoice::STATUS_PARTIAL);
} }
elseif($this->invoice->balance < 0) {
$this->setStatus(Invoice::STATUS_PARTIAL);
}
return $this; return $this;
} }

View File

@ -71,10 +71,6 @@ class MarkInvoiceDeleted extends AbstractService
private function adjustPaidToDateAndBalance() private function adjustPaidToDateAndBalance()
{ {
// $client = $this->invoice->client->fresh();
// $client->paid_to_date += $this->adjustment_amount * -1;
// $client->balance += $this->balance_adjustment * -1;
// $client->save();
// 06-09-2022 // 06-09-2022
$this->invoice $this->invoice

View File

@ -128,7 +128,7 @@ class Helpers
if(!$string_hit) if(!$string_hit)
return $value; return $value;
// 04-10-2022 Return Early if no reserved keywords are present, this is a very expenseive process // 04-10-2022 Return Early if no reserved keywords are present, this is a very expensive process
Carbon::setLocale($entity->locale()); Carbon::setLocale($entity->locale());
@ -296,8 +296,7 @@ class Helpers
} }
return $value; return $value;
// $x = str_replace(["\n", "<br>"], ["\r", "<br>"], $value);
// return $x;
} }
/** /**

View File

@ -54,17 +54,33 @@ class Number
* Formats a given value based on the clients currency. * Formats a given value based on the clients currency.
* *
* @param float $value The number to be formatted * @param float $value The number to be formatted
* @param object $currency The client currency object
* *
* @return string The formatted value * @return string The formatted value
*/ */
public static function formatValueNoTrailingZeroes($value, $currency) :string public static function formatValueNoTrailingZeroes($value, $entity) :string
{ {
$value = floatval($value); $value = floatval($value);
$currency = $entity->currency();
$thousand = $currency->thousand_separator; $thousand = $currency->thousand_separator;
$decimal = $currency->decimal_separator; $decimal = $currency->decimal_separator;
$precision = $currency->precision; // $precision = $currency->precision;
if ($entity instanceof Company) {
$country = $entity->country();
} else {
$country = $entity->country;
}
/* Country settings override client settings */
if (isset($country->thousand_separator) && strlen($country->thousand_separator) >= 1) {
$thousand = $country->thousand_separator;
}
if (isset($country->decimal_separator) && strlen($country->decimal_separator) >= 1) {
$decimal = $country->decimal_separator;
}
$precision = 10; $precision = 10;

View File

@ -65,7 +65,17 @@ trait ClientGroupSettingsSaver
} }
$entity->settings = $entity_settings; $entity->settings = $entity_settings;
$entity->save();
try{
$entity->save();
}
catch(\Exception $e){
nlog("client settings failure");
nlog($entity_settings);
nlog($e->getMessage());
}
return $entity_settings; return $entity_settings;
} }

View File

@ -306,7 +306,7 @@ trait MakesInvoiceValues
$data[$key][$table_type.".{$_table_type}4"] = strlen($item->custom_value4) >= 1 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}4", $item->custom_value4, $entity) : ''; $data[$key][$table_type.".{$_table_type}4"] = strlen($item->custom_value4) >= 1 ? $helpers->formatCustomFieldValue($this->company->custom_fields, "{$_table_type}4", $item->custom_value4, $entity) : '';
if ($item->quantity > 0 || $item->cost > 0) { if ($item->quantity > 0 || $item->cost > 0) {
$data[$key][$table_type.'.quantity'] = Number::formatValueNoTrailingZeroes($item->quantity, $entity_currency); $data[$key][$table_type.'.quantity'] = Number::formatValueNoTrailingZeroes($item->quantity, $entity);
$data[$key][$table_type.'.unit_cost'] = Number::formatMoneyNoRounding($item->cost, $entity); $data[$key][$table_type.'.unit_cost'] = Number::formatMoneyNoRounding($item->cost, $entity);

View File

@ -79,6 +79,19 @@ return [
'throw' => false, 'throw' => false,
], ],
'r2' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'visibility' => 'private',
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
],
'gcs' => [ 'gcs' => [
'driver' => 'gcs', 'driver' => 'gcs',
'project_id' => env('GOOGLE_CLOUD_PROJECT_ID', 'your-project-id'), 'project_id' => env('GOOGLE_CLOUD_PROJECT_ID', 'your-project-id'),

View File

@ -4,9 +4,9 @@ const TEMP = 'flutter-temp-cache';
const CACHE_NAME = 'flutter-app-cache'; const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = { const RESOURCES = {
"favicon.png": "dca91c54388f52eded692718d5a98b8b", "favicon.png": "dca91c54388f52eded692718d5a98b8b",
"main.dart.js": "221c5c0123d1312d9dd4625143c4e890", "main.dart.js": "da1ca4eca714583ff82c65cd3792029b",
"favicon.ico": "51636d3a390451561744c42188ccd628", "favicon.ico": "51636d3a390451561744c42188ccd628",
"/": "3bb8121d93d3f214ecd76dd2a5db3bad", "/": "384495013e69b7963a1f0883fc10f045",
"flutter.js": "f85e6fb278b0fd20c349186fb46ae36d", "flutter.js": "f85e6fb278b0fd20c349186fb46ae36d",
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40", "manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
"canvaskit/canvaskit.js": "2bc454a691c631b07a9307ac4ca47797", "canvaskit/canvaskit.js": "2bc454a691c631b07a9307ac4ca47797",
@ -299,7 +299,7 @@ const RESOURCES = {
"assets/assets/google_fonts/Roboto-Regular.ttf": "8a36205bd9b83e03af0591a004bc97f4", "assets/assets/google_fonts/Roboto-Regular.ttf": "8a36205bd9b83e03af0591a004bc97f4",
"assets/fonts/MaterialIcons-Regular.otf": "95db9098c58fd6db106f1116bae85a0b", "assets/fonts/MaterialIcons-Regular.otf": "95db9098c58fd6db106f1116bae85a0b",
"assets/NOTICES": "1a34e70168d56fad075adfb4bdbb20eb", "assets/NOTICES": "1a34e70168d56fad075adfb4bdbb20eb",
"version.json": "5e61b05ca3d51910bc4464df86bcda1a", "version.json": "ecddd9a09423be80c670ca3af19cf971",
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35", "icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed" "icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed"
}; };

13841
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

6445
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

View File

@ -61440,7 +61440,7 @@
if (B.JSString_methods.startsWith$1(url, "https://invoicing.co")) if (B.JSString_methods.startsWith$1(url, "https://invoicing.co"))
secret = ""; secret = "";
t1 = type$.legacy_String; t1 = type$.legacy_String;
headers = A.LinkedHashMap_LinkedHashMap$_literal(["X-CLIENT-VERSION", "5.0.98", "X-API-SECRET", secret, "X-Requested-With", "XMLHttpRequest", "Content-Type", "application/json; charset=utf-8"], t1, t1); headers = A.LinkedHashMap_LinkedHashMap$_literal(["X-CLIENT-VERSION", "5.0.99", "X-API-SECRET", secret, "X-Requested-With", "XMLHttpRequest", "Content-Type", "application/json; charset=utf-8"], t1, t1);
if (token.length !== 0) if (token.length !== 0)
headers.$indexSet(0, "X-API-Token", token); headers.$indexSet(0, "X-API-Token", token);
if ((idToken == null ? "" : idToken).length !== 0) if ((idToken == null ? "" : idToken).length !== 0)
@ -61463,9 +61463,9 @@
else if (serverVersion == null) else if (serverVersion == null)
throw A.wrapException("Error: please check that Invoice Ninja v5 is installed on the server"); throw A.wrapException("Error: please check that Invoice Ninja v5 is installed on the server");
else { else {
t2 = A.Version__compare(A.Version_parse("5.0.98"), A.Version_parse(minClientVersion)); t2 = A.Version__compare(A.Version_parse("5.0.99"), A.Version_parse(minClientVersion));
if (t2 < 0) if (t2 < 0)
throw A.wrapException("Error: client not supported, please update to the latest version [Current v5.0.98 < Minimum v" + A.S(minClientVersion) + "]"); throw A.wrapException("Error: client not supported, please update to the latest version [Current v5.0.99 < Minimum v" + A.S(minClientVersion) + "]");
else { else {
t2 = A.Version__compare(A.Version_parse(serverVersion), A.Version_parse("5.0.4")); t2 = A.Version__compare(A.Version_parse(serverVersion), A.Version_parse("5.0.4"));
if (t2 < 0) if (t2 < 0)
@ -92148,16 +92148,17 @@
UpgradeDialog: function UpgradeDialog(t0) { UpgradeDialog: function UpgradeDialog(t0) {
this.key = t0; this.key = t0;
}, },
_UpgradeDialogState: function _UpgradeDialogState(t0, t1, t2, t3) { _UpgradeDialogState: function _UpgradeDialogState(t0, t1, t2, t3, t4) {
var _ = this; var _ = this;
_._inAppPurchase = t0; _._upgrade_dialog$_scrollController = t0;
_._inAppPurchase = t1;
_._upgrade_dialog$_subscription = null; _._upgrade_dialog$_subscription = null;
_._upgrade_dialog$_products = t1; _._upgrade_dialog$_products = t2;
_._purchases = t2; _._purchases = t3;
_._purchasePending = _._isAvailable = false; _._purchasePending = _._isAvailable = false;
_._loading = true; _._loading = true;
_._widget = _._queryProductError = null; _._widget = _._queryProductError = null;
_._debugLifecycleState = t3; _._debugLifecycleState = t4;
_._framework$_element = null; _._framework$_element = null;
}, },
_UpgradeDialogState_initState_closure: function _UpgradeDialogState_initState_closure(t0) { _UpgradeDialogState_initState_closure: function _UpgradeDialogState_initState_closure(t0) {
@ -328474,6 +328475,7 @@
t1 = A.convertDateTimeToSqlDate(null); t1 = A.convertDateTimeToSqlDate(null);
b.get$_invoice_model$_$this()._date = t1; b.get$_invoice_model$_$this()._date = t1;
b.get$_invoice_model$_$this()._dueDate = ""; b.get$_invoice_model$_$this()._dueDate = "";
b.get$_invoice_model$_$this()._partialDueDate = "";
B.JSArray_methods.clear$0(b.get$documents().get$_safeList()); B.JSArray_methods.clear$0(b.get$documents().get$_safeList());
t1 = b.get$lineItems(); t1 = b.get$lineItems();
t2 = this.$this; t2 = this.$this;
@ -359702,7 +359704,7 @@
version = "v" + (t1 == null ? "" : t1); version = "v" + (t1 == null ? "" : t1);
if (version.length !== 0) if (version.length !== 0)
version += "-"; version += "-";
return B.JSString_methods.$add(version + A.getPlatformLetter(), B.JSArray_methods.get$last("5.0.98".split("."))); return B.JSString_methods.$add(version + A.getPlatformLetter(), B.JSArray_methods.get$last("5.0.99".split(".")));
}, },
get$historyList() { get$historyList() {
var _this = this, var _this = this,
@ -417336,8 +417338,9 @@
else else
isEnabled = false; isEnabled = false;
t6 = t2[t4].userCompany; t6 = t2[t4].userCompany;
if (t6.isOwner) if (t6.isOwner) {
if (t6.account.trialStarted.length === 0) { t6 = t6.account;
if (t6.trialStarted.length === 0 && t6.plan === "" && !A.isIOS()) {
t5.toString; t5.toString;
t6 = $.$get$LocalizationsProvider__localizedValues(); t6 = $.$get$LocalizationsProvider__localizedValues();
t7 = t5.localeCode; t7 = t5.localeCode;
@ -417354,7 +417357,7 @@
t8 = ""; t8 = "";
upgradeMessage = t8; upgradeMessage = t8;
} }
else { } else {
t5.toString; t5.toString;
t6 = $.$get$LocalizationsProvider__localizedValues(); t6 = $.$get$LocalizationsProvider__localizedValues();
t7 = t5.localeCode; t7 = t5.localeCode;
@ -423766,7 +423769,8 @@
t1 = A.StoreProvider_of(context, t1).__Store__state_A; t1 = A.StoreProvider_of(context, t1).__Store__state_A;
t1 === $ && A.throwUnnamedLateFieldNI(); t1 === $ && A.throwUnnamedLateFieldNI();
if (!t1.get$isPaidAccount()) if (!t1.get$isPaidAccount())
A.isApple(); if (A.isApple())
A.isIOS();
} }
t9.push(A.DrawerTile$(company, _null, A.getEntityIcon(B.EntityType_dashboard), _null, new A._MenuDrawerState_build_closure8(store), new A._MenuDrawerState_build_closure9(), t4.get$dashboard())); t9.push(A.DrawerTile$(company, _null, A.getEntityIcon(B.EntityType_dashboard), _null, new A._MenuDrawerState_build_closure8(store), new A._MenuDrawerState_build_closure9(), t4.get$dashboard()));
t1 = A.getEntityIcon(B.EntityType_client); t1 = A.getEntityIcon(B.EntityType_client);
@ -427203,7 +427207,7 @@
}; };
A.UpgradeDialog.prototype = { A.UpgradeDialog.prototype = {
createState$0() { createState$0() {
return new A._UpgradeDialogState(A.InAppPurchase__getOrCreateInstance(), A._setArrayType([], type$.JSArray_legacy_ProductDetails), A._setArrayType([], type$.JSArray_legacy_PurchaseDetails), B._StateLifecycle_0); return new A._UpgradeDialogState(A.ScrollController$(0, true), A.InAppPurchase__getOrCreateInstance(), A._setArrayType([], type$.JSArray_legacy_ProductDetails), A._setArrayType([], type$.JSArray_legacy_PurchaseDetails), B._StateLifecycle_0);
} }
}; };
A._UpgradeDialogState.prototype = { A._UpgradeDialogState.prototype = {
@ -427274,13 +427278,15 @@
return A._asyncStartSync($async$initStoreInfo$0, $async$completer); return A._asyncStartSync($async$initStoreInfo$0, $async$completer);
}, },
dispose$0() { dispose$0() {
var _this = this;
if ($.$get$Platform_isIOS()) { if ($.$get$Platform_isIOS()) {
this._inAppPurchase.toString; _this._inAppPurchase.toString;
type$.legacy_InAppPurchaseStoreKitPlatformAddition._as($.InAppPurchasePlatformAddition__instance).toString; type$.legacy_InAppPurchaseStoreKitPlatformAddition._as($.InAppPurchasePlatformAddition__instance).toString;
$.$get$SKPaymentQueueWrapper__singleton().setDelegate$1(null); $.$get$SKPaymentQueueWrapper__singleton().setDelegate$1(null);
} }
this._upgrade_dialog$_subscription.cancel$0(0); _this._upgrade_dialog$_subscription.cancel$0(0);
this.super$State$dispose(); _this._upgrade_dialog$_scrollController.dispose$0();
_this.super$State$dispose();
}, },
build$1(context) { build$1(context) {
var t4, t5, t6, _this = this, _null = null, var t4, t5, t6, _this = this, _null = null,
@ -427290,11 +427296,12 @@
stack = A._setArrayType([], t2), stack = A._setArrayType([], t2),
t3 = _this._queryProductError; t3 = _this._queryProductError;
if (t3 == null) { if (t3 == null) {
t3 = A._setArrayType([], t2); t3 = _this._upgrade_dialog$_scrollController;
t4 = A._setArrayType([], t2);
if ($.$get$Platform_isIOS()) if ($.$get$Platform_isIOS())
t3.push(new A.Padding(B.EdgeInsets_0_0_0_16, A.Text$("Payment will be charged to iTunes Account at confirmation of purchase. Subscription automatically renews unless auto-renew is turned off at least 24-hours before the end of the current period. Account will be charged for renewal within 24-hours prior to the end of the current period, and identify the cost of the renewal. Subscriptions may be managed by the user and auto-renewal may be turned off by going to the user's Account Settings after purchase.", _null, _null, _null, _null, _null, A.TextStyle$(_null, _null, B.MaterialColor_Map_HFpTk_4288585374, _null, _null, _null, _null, _null, _null, _null, _null, 12, _null, _null, _null, _null, _null, true, _null, _null, _null, _null, _null, _null, _null, _null), _null, _null, _null), _null)); t4.push(new A.Padding(B.EdgeInsets_0_0_0_16, A.Text$("Payment will be charged to iTunes Account at confirmation of purchase. Subscription automatically renews unless auto-renew is turned off at least 24-hours before the end of the current period. Account will be charged for renewal within 24-hours prior to the end of the current period, and identify the cost of the renewal. Subscriptions may be managed by the user and auto-renewal may be turned off by going to the user's Account Settings after purchase.", _null, _null, _null, _null, _null, A.TextStyle$(_null, _null, B.MaterialColor_Map_HFpTk_4288585374, _null, _null, _null, _null, _null, _null, _null, _null, 12, _null, _null, _null, _null, _null, true, _null, _null, _null, _null, _null, _null, _null, _null), _null, _null, _null), _null));
t3.push(_this._buildProductList$0()); t4.push(_this._buildProductList$0());
stack.push(A.ListView$(t3, _null, _null, _null, B.Axis_1, false)); stack.push(A.Scrollbar$(A.ListView$(t4, t3, _null, _null, B.Axis_1, false), t3, true));
} else } else
stack.push(A.Center$(A.Text$(t3, _null, _null, _null, _null, _null, _null, _null, _null, _null), _null, _null)); stack.push(A.Center$(A.Text$(t3, _null, _null, _null, _null, _null, _null, _null, _null, _null), _null, _null));
if (_this._purchasePending) if (_this._purchasePending)
@ -427601,26 +427608,24 @@
}; };
A._UpgradeDialogState__buildProductList_closure1.prototype = { A._UpgradeDialogState__buildProductList_closure1.prototype = {
call$1(productDetails) { call$1(productDetails) {
var t5, _null = null, var t4, t5, _null = null,
_s8_ = "activate", _s8_ = "activate",
t1 = productDetails.id, previousPurchase = this.purchases.$index(0, productDetails.id),
previousPurchase = this.purchases.$index(0, t1), t1 = A.Text$(productDetails.description, _null, _null, _null, _null, _null, _null, _null, _null, _null),
description = productDetails.description, t2 = A.TextButton_styleFrom(_null, _null, B.Color_4281236786, _null, _null, _null, _null, _null, _null, _null, _null, _null, _null, B.Color_4294967295, _null, _null, _null, _null, _null, _null),
t2 = A.Text$(description.length === 0 && t1 === "enterprise_plan_10" ? "One month of the Enterprise Plan (10 users)" : description, _null, _null, _null, _null, _null, _null, _null, _null, _null), t3 = this.$this;
t3 = A.TextButton_styleFrom(_null, _null, B.Color_4281236786, _null, _null, _null, _null, _null, _null, _null, _null, _null, _null, B.Color_4294967295, _null, _null, _null, _null, _null, _null),
t4 = this.$this;
if (previousPurchase != null) { if (previousPurchase != null) {
t1 = t4._framework$_element; t4 = t3._framework$_element;
t1.toString; t4.toString;
t1 = A.Localizations_of(t1, B.Type_AppLocalization_KyD, type$.legacy_AppLocalization); t4 = A.Localizations_of(t4, B.Type_AppLocalization_KyD, type$.legacy_AppLocalization);
t1.toString; t4.toString;
t5 = $.$get$LocalizationsProvider__localizedValues(); t5 = $.$get$LocalizationsProvider__localizedValues();
t1 = J.$index$asx(t5.$index(0, t1.localeCode), _s8_); t4 = J.$index$asx(t5.$index(0, t4.localeCode), _s8_);
if (t1 == null) if (t4 == null)
t1 = J.$index$asx(t5.$index(0, "en"), _s8_); t4 = J.$index$asx(t5.$index(0, "en"), _s8_);
} else } else
t1 = productDetails.price; t4 = productDetails.price;
return A.ListTile$(false, _null, _null, _null, true, _null, _null, false, _null, _null, _null, _null, false, _null, _null, A.Column$(A._setArrayType([A.TextButton$(false, A.Text$(t1, _null, _null, _null, _null, _null, _null, _null, _null, _null), _null, _null, new A._UpgradeDialogState__buildProductList__closure(t4, previousPurchase, productDetails, this.account), t3), new A.SizedBox(_null, 20, _null, _null)], type$.JSArray_legacy_Widget), B.CrossAxisAlignment_0, _null, B.MainAxisAlignment_0, B.MainAxisSize_1, B.VerticalDirection_1), _null, t2, _null, _null); return A.ListTile$(false, _null, _null, _null, true, _null, _null, false, _null, _null, _null, _null, false, _null, _null, A.Column$(A._setArrayType([A.TextButton$(false, A.Text$(t4, _null, _null, _null, _null, _null, _null, _null, _null, _null), _null, _null, new A._UpgradeDialogState__buildProductList__closure(t3, previousPurchase, productDetails, this.account), t2), new A.SizedBox(_null, 20, _null, _null)], type$.JSArray_legacy_Widget), B.CrossAxisAlignment_0, _null, B.MainAxisAlignment_0, B.MainAxisSize_1, B.VerticalDirection_1), _null, t1, _null, _null);
}, },
$signature: 2377 $signature: 2377
}; };
@ -465226,7 +465231,7 @@
else else
t7 = false; t7 = false;
if (t7) { if (t7) {
if (account.trialStarted.length === 0 && account.plan === "") { if (account.trialStarted.length === 0 && account.plan === "" && !A.isIOS()) {
t7 = J.$index$asx(t5.$index(0, t6), _s16_); t7 = J.$index$asx(t5.$index(0, t6), _s16_);
if (t7 == null) if (t7 == null)
t7 = J.$index$asx(t5.$index(0, _s2_), _s16_); t7 = J.$index$asx(t5.$index(0, _s2_), _s16_);

View File

@ -1 +1 @@
{"app_name":"invoiceninja_flutter","version":"5.0.98","build_number":"98","package_name":"invoiceninja_flutter"} {"app_name":"invoiceninja_flutter","version":"5.0.99","build_number":"99","package_name":"invoiceninja_flutter"}

View File

@ -12,6 +12,7 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Models\Country; use App\Models\Country;
use App\Utils\Number;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
@ -401,4 +402,89 @@ class ClientApiTest extends TestCase
$response->assertStatus(302); $response->assertStatus(302);
} }
public function testRoundingDecimalsTwo()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(0.05, $currency);
$this->assertEquals(0.05, $x);
}
public function testRoundingDecimalsThree()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(0.005, $currency);
$this->assertEquals(0.005, $x);
}
public function testRoundingDecimalsFour()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(0.0005, $currency);
$this->assertEquals(0.0005, $x);
}
public function testRoundingDecimalsFive()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(0.00005, $currency);
$this->assertEquals(0.00005, $x);
}
public function testRoundingDecimalsSix()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(0.000005, $currency);
$this->assertEquals(0.000005, $x);
}
public function testRoundingDecimalsSeven()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(0.0000005, $currency);
$this->assertEquals(0.0000005, $x);
}
public function testRoundingDecimalsEight()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(0.00000005, $currency);
$this->assertEquals(0.00000005, $x);
}
public function testRoundingPositive()
{
$currency = $this->company;
$x = Number::formatValueNoTrailingZeroes(1.5, $currency);
$this->assertEquals(1.5, $x);
$x = Number::formatValueNoTrailingZeroes(1.50, $currency);
$this->assertEquals(1.5, $x);
$x = Number::formatValueNoTrailingZeroes(1.500, $currency);
$this->assertEquals(1.5, $x);
$x = Number::formatValueNoTrailingZeroes(1.50005, $currency);
$this->assertEquals(1.50005, $x);
$x = Number::formatValueNoTrailingZeroes(1.50000005, $currency);
$this->assertEquals(1.50000005, $x);
}
} }

View File

@ -166,11 +166,12 @@ class RecurringInvoiceTest extends TestCase
'company_id' => $this->company->id, 'company_id' => $this->company->id,
]); ]);
}); });
$client = Client::all()->first();
$client = Client::query()->orderBy('id', 'DESC')->first();
RecurringInvoice::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $this->client->id]); RecurringInvoice::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $this->client->id]);
$RecurringInvoice = RecurringInvoice::where('user_id', $this->user->id)->first(); $RecurringInvoice = RecurringInvoice::query()->where('user_id', $this->user->id)->orderBy('id', 'DESC')->first();
$RecurringInvoice->save(); $RecurringInvoice->save();
$response = $this->withHeaders([ $response = $this->withHeaders([

View File

@ -63,7 +63,7 @@ class RecurringQuoteTest extends TestCase
{ {
RecurringQuote::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $this->client->id]); RecurringQuote::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $this->client->id]);
$RecurringQuote = RecurringQuote::where('user_id', $this->user->id)->first(); $RecurringQuote = RecurringQuote::query()->where('user_id', $this->user->id)->orderBy('id','DESC')->first();
$RecurringQuote->save(); $RecurringQuote->save();
$response = $this->withHeaders([ $response = $this->withHeaders([

View File

@ -58,37 +58,5 @@ class DownloadHistoricalInvoiceTest extends TestCase
$this->assertNotNull($this->invoice->activities); $this->assertNotNull($this->invoice->activities);
} }
public function testBackupExists()
{
$this->mockActivity();
$this->assertNotNull($this->invoice->activities->first()->backup->html_backup);
}
public function testBackupDownload()
{
$this->mockActivity();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/activities/download_entity/'.$this->encodePrimaryKey($this->invoice->activities->first()->id));
$response->assertStatus(200);
}
public function testBackupCheckPriorToDownloadWorks()
{
$this->mockActivity();
$backup = $this->invoice->activities->first()->backup;
$backup->forceDelete();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/activities/download_entity/'.$this->encodePrimaryKey($this->invoice->activities->first()->id));
$response->assertStatus(404);
}
} }

View File

@ -89,18 +89,6 @@ class NumberTest extends TestCase
$this->assertEquals(2.15, $rounded); $this->assertEquals(2.15, $rounded);
} }
//this method proved an error! removing this method from production
// public function testImportFloatConversion()
// {
// $amount = '€7,99';
// $converted_amount = Number::parseStringFloat($amount);
// $this->assertEquals(799, $converted_amount);
// }
public function testParsingStringCurrency() public function testParsingStringCurrency()
{ {
$amount = '€7,99'; $amount = '€7,99';
@ -110,86 +98,4 @@ class NumberTest extends TestCase
$this->assertEquals(7.99, $converted_amount); $this->assertEquals(7.99, $converted_amount);
} }
public function testRoundingDecimalsTwo()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(0.05, $currency);
$this->assertEquals(0.05, $x);
}
public function testRoundingDecimalsThree()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(0.005, $currency);
$this->assertEquals(0.005, $x);
}
public function testRoundingDecimalsFour()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(0.0005, $currency);
$this->assertEquals(0.0005, $x);
}
public function testRoundingDecimalsFive()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(0.00005, $currency);
$this->assertEquals(0.00005, $x);
}
public function testRoundingDecimalsSix()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(0.000005, $currency);
$this->assertEquals(0.000005, $x);
}
public function testRoundingDecimalsSeven()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(0.0000005, $currency);
$this->assertEquals(0.0000005, $x);
}
public function testRoundingDecimalsEight()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(0.00000005, $currency);
$this->assertEquals(0.00000005, $x);
}
public function testRoundingPositive()
{
$currency = Currency::find(1);
$x = Number::formatValueNoTrailingZeroes(1.5, $currency);
$this->assertEquals(1.5, $x);
$x = Number::formatValueNoTrailingZeroes(1.50, $currency);
$this->assertEquals(1.5, $x);
$x = Number::formatValueNoTrailingZeroes(1.500, $currency);
$this->assertEquals(1.5, $x);
$x = Number::formatValueNoTrailingZeroes(1.50005, $currency);
$this->assertEquals(1.50005, $x);
$x = Number::formatValueNoTrailingZeroes(1.50000005, $currency);
$this->assertEquals(1.50000005, $x);
}
} }