Merge branch 'v5-develop' of https://github.com/turbo124/invoiceninja into v5-develop

This commit is contained in:
David Bomba 2021-12-07 22:14:49 +11:00
commit 47d6715fb8
35 changed files with 371492 additions and 370254 deletions

View File

@ -36,7 +36,7 @@ class ExpenseFilters extends QueryFilters
}
return $this->builder->where(function ($query) use ($filter) {
$query->where('expenses.name', 'like', '%'.$filter.'%')
$query->where('expenses.public_notes', 'like', '%'.$filter.'%')
->orWhere('expenses.id_number', 'like', '%'.$filter.'%')
->orWhere('expenses.custom_value1', 'like', '%'.$filter.'%')
->orWhere('expenses.custom_value2', 'like', '%'.$filter.'%')
@ -94,7 +94,10 @@ class ExpenseFilters extends QueryFilters
{
$sort_col = explode('|', $sort);
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
if(is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4']))
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
return $this->builder;
}
/**

View File

@ -60,8 +60,15 @@ class ContactForgotPasswordController extends Controller
{
$account_id = $request->has('account_id') ? $request->get('account_id') : 1;
$account = Account::find($account_id);
$company = $account->companies->first();
if($request->has('company_key'))
$company = Company::where('company_key', $request->input('company_key'))->first();
else
$company = $account->companies->first();
if(!$account)
$account = Account::first();
return $this->render('auth.passwords.request', [
'title' => 'Client Password Reset',
'passwordEmailRoute' => 'client.password.email',
@ -90,7 +97,9 @@ class ContactForgotPasswordController extends Controller
// $user = MultiDB::hasContact($request->input('email'));
$company = Company::where('company_key', $request->input('company_key'))->first();
$contact = MultiDB::findContact(['company_id' => $company->id, 'email' => $request->input('email')]);
//$contact = MultiDB::findContact(['company_id' => $company->id, 'email' => $request->input('email')]);
nlog(['company_id' => $company->id, 'email' => $request->input('email')]);
$contact = ClientContact::where(['company_id' => $company->id, 'email' => $request->input('email')])->first();
$response = false;

View File

@ -71,6 +71,8 @@ class InvitationController extends Controller
if(!in_array($entity, ['invoice', 'credit', 'quote', 'recurring_invoice']))
return response()->json(['message' => 'Invalid resource request']);
$is_silent = 'false';
$key = $entity.'_id';
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
@ -111,8 +113,16 @@ class InvitationController extends Controller
$this->fireEntityViewedEvent($invitation, $entity);
}
else{
$is_silent = 'true';
return redirect()->route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key}), 'silent' => $is_silent]);
}
return redirect()->route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key})]);
}
private function fireEntityViewedEvent($invitation, $entity_string)

View File

@ -48,6 +48,7 @@ class QuotesTable extends Component
->where('company_id', $this->company->id)
->where('client_id', auth('contact')->user()->client->id)
->where('status_id', '<>', Quote::STATUS_DRAFT)
->where('is_deleted', 0)
->withTrashed()
->paginate($this->per_page);

View File

@ -50,7 +50,7 @@ class SetDomainNameDb
];
if($company = MultiDB::findAndSetDbByDomain($query)){
$request->request->add(['account_id' => $company->account_id]);
$request->request->add(['account_id' => $company->account_id, 'company_key' => $company->company_key]);
}
else
{
@ -72,7 +72,7 @@ class SetDomainNameDb
];
if($company = MultiDB::findAndSetDbByDomain($query)){
$request->request->add(['account_id' => $company->account_id]);
$request->request->add(['account_id' => $company->account_id, 'company_key' => $company->company_key]);
}
else
{

View File

@ -62,20 +62,30 @@ class BaseTransformer
public function getClient($client_name, $client_email) {
$clients = $this->maps['company']->clients;
$clients = $clients->where( 'id_number', $client_name );
$client_id_search = $clients->where( 'id_number', $client_name );
if ( $clients->count() >= 1 ) {
return $clients->first()->id;
if ( $client_id_search->count() >= 1 ) {
return $client_id_search->first()->id;
nlog("found via id number");
}
$client_name_search = $clients->where( 'name', $client_name );
if ( $client_name_search->count() >= 1 ) {
return $client_name_search->first()->id;
nlog("found via name");
}
if ( ! empty( $client_email ) ) {
$contacts = ClientContact::where( 'company_id', $this->maps['company']->id )
->where( 'email', $client_email );
if ( $contacts->count() >= 1 ) {
return $contacts->first()->client_id;
nlog("found via contact");
}
}
nlog("did not find client");
return null;
}

View File

@ -49,7 +49,7 @@ class InvoiceTransformer extends BaseTransformer {
'due_date' => isset( $invoice_data['invoice.due_date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['invoice.due_date'] ) ) : null,
'terms' => $this->getString( $invoice_data, 'invoice.terms' ),
'public_notes' => $this->getString( $invoice_data, 'invoice.public_notes' ),
'is_sent' => $this->getString( $invoice_data, 'invoice.is_sent' ),
// 'is_sent' => $this->getString( $invoice_data, 'invoice.is_sent' ),
'private_notes' => $this->getString( $invoice_data, 'invoice.private_notes' ),
'tax_name1' => $this->getString( $invoice_data, 'invoice.tax_name1' ),
'tax_rate1' => $this->getFloat( $invoice_data, 'invoice.tax_rate1' ),

View File

@ -53,7 +53,7 @@ class AutoBill
nlog("autobill {$this->invoice->id}");
$this->invoice->service()->autoBill()->save();
$this->invoice->service()->autoBill();
}
catch(\Exception $e) {

View File

@ -145,7 +145,7 @@ class SendRecurring implements ShouldQueue
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) {
nlog("attempting to autobill {$invoice->number}");
$invoice->service()->autoBill()->save();
$invoice->service()->autoBill();
}
elseif($invoice->client->getSetting('auto_bill_date') == 'on_due_date' && $invoice->auto_bill_enabled) {
@ -153,7 +153,7 @@ class SendRecurring implements ShouldQueue
if($invoice->due_date && Carbon::parse($invoice->due_date)->startOfDay()->lte(now()->startOfDay())) {
nlog("attempting to autobill {$invoice->number}");
$invoice->service()->autoBill()->save();
$invoice->service()->autoBill();
}

View File

@ -75,6 +75,7 @@ class Quote extends BaseModel
'assigned_user_id',
'exchange_rate',
'subscription_id',
'uses_inclusive_taxes',
];
protected $casts = [

View File

@ -30,6 +30,7 @@ use App\Models\GatewayType;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\Services\Subscription\SubscriptionService;
use App\Utils\Ninja;
@ -262,12 +263,18 @@ class BaseDriver extends AbstractPaymentDriver
event('eloquent.created: App\Models\Payment', $payment);
if ($this->client->getSetting('client_online_payment_notification'))
if ($this->client->getSetting('client_online_payment_notification') && in_array($status, [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING
]))
$payment->service()->sendEmail();
//todo
//catch any payment failures here also and fire a subsequent failure email if necessary? note only need for delayed payment forms
//perhaps this type of functionality should be handled higher up to provide better context?
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
if (property_exists($this->payment_hash->data, 'billing_context')) {
if (property_exists($this->payment_hash->data, 'billing_context') && $status == Payment::STATUS_COMPLETED) {
$billing_subscription = \App\Models\Subscription::find($this->payment_hash->data->billing_context->subscription_id);
// To access campaign hash => $this->payment_hash->data->billing_context->campaign;

View File

@ -161,7 +161,8 @@ class PayPal
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_BRAINTREE,
$this->braintree->client
$this->braintree->client,
$this->braintree->client->company
);
throw new PaymentFailed($response->message, 0);

View File

@ -319,24 +319,23 @@ class MolliePaymentDriver extends BaseDriver
// we may not have a payment record - in these cases we need to re-construct the payment
// record from the meta data in the payment hash.
if($payment && $payment->metadata->payment_hash){
if($payment && property_exists($payment->metadata, 'payment_hash') && $payment->metadata->payment_hash){
/* Harvest Payment Hash*/
$payment_hash = PaymentHash::where('hash', $payment->metadata->hash)->first();
$data = [
'gateway_type_id' => $payment->metadata->gateway_type_id,
'amount' => $amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total,
'payment_type' => $payment->metadata->payment_type_id,
'transaction_reference' => $payment->id,
];
$record = $this->createPayment(
$data,
$codes[$payment->status]
);
}
}

View File

@ -56,7 +56,6 @@ class Charge
if($cgt->gateway_type_id == GatewayType::BANK_TRANSFER)
return (new ACH($this->stripe))->tokenBilling($cgt, $payment_hash);
nlog(" DB = ".$this->stripe->client->company->db);
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
@ -119,7 +118,6 @@ class Charge
$data['message'] = $e->getMessage();
break;
}
$this->stripe->processInternallyFailedPayment($this->stripe, $e);

View File

@ -123,7 +123,7 @@ class CreditCard
$data = [
'payment_method' => $this->stripe->payment_hash->data->server_response->payment_method,
'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)),
'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)) ?: PaymentType::CREDIT_CARD_OTHER,
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->server_response->amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()),
'transaction_reference' => optional($this->stripe->payment_hash->data->payment_intent->charges->data[0])->id,
'gateway_type_id' => GatewayType::CREDIT_CARD,

View File

@ -436,7 +436,7 @@ class StripePaymentDriver extends BaseDriver
//Else create a new record
$data['name'] = $this->client->present()->name();
$data['phone'] = $this->client->present()->phone();
$data['phone'] = substr($this->client->present()->phone(), 0 , 20);
if (filter_var($this->client->present()->email(), FILTER_VALIDATE_EMAIL)) {
$data['email'] = $this->client->present()->email();

View File

@ -54,6 +54,37 @@ class TaskRepository extends BaseRepository
$task->status_order = $data['status_order'];
}
/*V4 override*/
if (! empty($data['time_details'])) {
$timeLog = [];
foreach ($data['time_details'] as $detail) {
$startTime = strtotime($detail['start_datetime']);
$endTime = false;
if (! empty($detail['end_datetime'])) {
$endTime = strtotime($detail['end_datetime']);
} else {
$duration = 0;
if (! empty($detail['duration_seconds'])) {
$duration += $detail['duration_seconds'];
}
if (! empty($detail['duration_minutes'])) {
$duration += $detail['duration_minutes'] * 60;
}
if (! empty($detail['duration_hours'])) {
$duration += $detail['duration_hours'] * 60 * 60;
}
if ($duration) {
$endTime = $startTime + $duration;
}
}
$timeLog[] = [$startTime, $endTime];
if (! $endTime) {
$data['is_running'] = true;
}
}
$data['time_log'] = json_encode($timeLog);
}
if (isset($data['time_log'])) {
$time_log = json_decode($data['time_log']);
} elseif ($task->time_log) {

View File

@ -36,17 +36,6 @@ class TriggeredActions extends AbstractService
public function run()
{
// if ($this->request->has('auto_bill') && $this->request->input('auto_bill') == 'true') {
// $this->credit = $this->credit->service()->autoBill()->save();
// }
// if ($this->request->has('paid') && $this->request->input('paid') == 'true') {
// $this->credit = $this->credit->service()->markPaid()->save();
// }
// if ($this->request->has('amount_paid') && is_numeric($this->request->input('amount_paid')) ) {
// $this->credit = $this->credit->service()->applyPaymentAmount($this->request->input('amount_paid'))->save();
// }
if ($this->request->has('send_email') && $this->request->input('send_email') == 'true') {
$this->sendEmail();

View File

@ -105,7 +105,7 @@ class AddGatewayFee extends AbstractService
$invoice_item->quantity = 1;
$invoice_item->cost = $gateway_fee;
if ($fees_and_limits = $this->company_gateway->getFeesAndLimits()) {
if ($fees_and_limits = $this->company_gateway->getFeesAndLimits($this->gateway_type_id)) {
$invoice_item->tax_rate1 = $fees_and_limits->fee_tax_rate1;
$invoice_item->tax_rate2 = $fees_and_limits->fee_tax_rate2;
$invoice_item->tax_rate3 = $fees_and_limits->fee_tax_rate3;

View File

@ -130,7 +130,7 @@ class AutoBillInvoice extends AbstractService
info("Auto Bill payment captured for ".$this->invoice->number);
}
return $this->invoice->fresh();
// return $this->invoice->fresh();
}
/**

View File

@ -139,6 +139,7 @@ class InvoiceService
// $this->invoice = (new UpdateBalance($this->invoice, $balance_adjustment, $is_draft))->run();
if ((bool)$this->invoice->is_deleted !== false) {
nlog($this->invoice->number . " is deleted returning");
return $this;
}
@ -245,7 +246,7 @@ class InvoiceService
public function autoBill()
{
$this->invoice = (new AutoBillInvoice($this->invoice, $this->invoice->company->db))->run();
(new AutoBillInvoice($this->invoice, $this->invoice->company->db))->run();
return $this;
}

View File

@ -37,7 +37,7 @@ class TriggeredActions extends AbstractService
public function run()
{
if ($this->request->has('auto_bill') && $this->request->input('auto_bill') == 'true') {
$this->invoice = $this->invoice->service()->autoBill()->save();
$this->invoice->service()->autoBill();
}
if ($this->request->has('paid') && $this->request->input('paid') == 'true') {

126
composer.lock generated
View File

@ -323,16 +323,16 @@
},
{
"name": "aws/aws-sdk-php",
"version": "3.207.0",
"version": "3.208.0",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "c5252787784bf41b678b03cb3292d413fe281319"
"reference": "fef9c7a9b0d65014a40cc7451da9e420e6f0eaa0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c5252787784bf41b678b03cb3292d413fe281319",
"reference": "c5252787784bf41b678b03cb3292d413fe281319",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/fef9c7a9b0d65014a40cc7451da9e420e6f0eaa0",
"reference": "fef9c7a9b0d65014a40cc7451da9e420e6f0eaa0",
"shasum": ""
},
"require": {
@ -408,9 +408,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.207.0"
"source": "https://github.com/aws/aws-sdk-php/tree/3.208.0"
},
"time": "2021-11-30T23:44:55+00:00"
"time": "2021-12-02T19:14:25+00:00"
},
{
"name": "bacon/bacon-qr-code",
@ -2651,16 +2651,16 @@
},
{
"name": "google/apiclient",
"version": "v2.11.0",
"version": "v2.12.1",
"source": {
"type": "git",
"url": "https://github.com/googleapis/google-api-php-client.git",
"reference": "7db9eb40c8ba887e81c0fe84f2888a967396cdfb"
"reference": "1530583a711f4414407112c4068464bcbace1c71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/7db9eb40c8ba887e81c0fe84f2888a967396cdfb",
"reference": "7db9eb40c8ba887e81c0fe84f2888a967396cdfb",
"url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/1530583a711f4414407112c4068464bcbace1c71",
"reference": "1530583a711f4414407112c4068464bcbace1c71",
"shasum": ""
},
"require": {
@ -2691,7 +2691,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
"dev-main": "2.x-dev"
}
},
"autoload": {
@ -2716,9 +2716,9 @@
],
"support": {
"issues": "https://github.com/googleapis/google-api-php-client/issues",
"source": "https://github.com/googleapis/google-api-php-client/tree/v2.11.0"
"source": "https://github.com/googleapis/google-api-php-client/tree/v2.12.1"
},
"time": "2021-09-20T21:15:55+00:00"
"time": "2021-12-02T03:34:25+00:00"
},
{
"name": "google/apiclient-services",
@ -5053,16 +5053,16 @@
},
{
"name": "livewire/livewire",
"version": "v2.8.0",
"version": "v2.8.1",
"source": {
"type": "git",
"url": "https://github.com/livewire/livewire.git",
"reference": "fc8c315babf8d42c2a25f207b3931b1bc8eb5e70"
"reference": "0f846a93369109e445f0e5009741b1e19e6fa6f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/livewire/livewire/zipball/fc8c315babf8d42c2a25f207b3931b1bc8eb5e70",
"reference": "fc8c315babf8d42c2a25f207b3931b1bc8eb5e70",
"url": "https://api.github.com/repos/livewire/livewire/zipball/0f846a93369109e445f0e5009741b1e19e6fa6f6",
"reference": "0f846a93369109e445f0e5009741b1e19e6fa6f6",
"shasum": ""
},
"require": {
@ -5113,7 +5113,7 @@
"description": "A front-end framework for Laravel.",
"support": {
"issues": "https://github.com/livewire/livewire/issues",
"source": "https://github.com/livewire/livewire/tree/v2.8.0"
"source": "https://github.com/livewire/livewire/tree/v2.8.1"
},
"funding": [
{
@ -5121,7 +5121,7 @@
"type": "github"
}
],
"time": "2021-11-24T04:33:15+00:00"
"time": "2021-12-02T01:31:26+00:00"
},
{
"name": "maennchen/zipstream-php",
@ -8602,16 +8602,16 @@
},
{
"name": "stripe/stripe-php",
"version": "v7.103.0",
"version": "v7.104.0",
"source": {
"type": "git",
"url": "https://github.com/stripe/stripe-php.git",
"reference": "3a029598395bb4c7cfafa64707a553f4b01a9a12"
"reference": "6bfd895eaa3f6ebb49c10f9ab9ccc9e5baadded5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/3a029598395bb4c7cfafa64707a553f4b01a9a12",
"reference": "3a029598395bb4c7cfafa64707a553f4b01a9a12",
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/6bfd895eaa3f6ebb49c10f9ab9ccc9e5baadded5",
"reference": "6bfd895eaa3f6ebb49c10f9ab9ccc9e5baadded5",
"shasum": ""
},
"require": {
@ -8621,11 +8621,10 @@
"php": ">=5.6.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "2.17.1",
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^3.3",
"symfony/process": "~3.4"
"friendsofphp/php-cs-fixer": "3.2.1",
"phpstan/phpstan": "^1.2",
"phpunit/phpunit": "^5.7 || ^9.0",
"squizlabs/php_codesniffer": "^3.3"
},
"type": "library",
"extra": {
@ -8657,9 +8656,9 @@
],
"support": {
"issues": "https://github.com/stripe/stripe-php/issues",
"source": "https://github.com/stripe/stripe-php/tree/v7.103.0"
"source": "https://github.com/stripe/stripe-php/tree/v7.104.0"
},
"time": "2021-11-20T00:36:07+00:00"
"time": "2021-12-01T22:24:54+00:00"
},
{
"name": "swiftmailer/swiftmailer",
@ -9127,20 +9126,20 @@
},
{
"name": "symfony/event-dispatcher-contracts",
"version": "v3.0.0",
"version": "v2.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
"reference": "aa5422287b75594b90ee9cd807caf8f0df491385"
"reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385",
"reference": "aa5422287b75594b90ee9cd807caf8f0df491385",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a",
"reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a",
"shasum": ""
},
"require": {
"php": ">=8.0.2",
"php": ">=7.2.5",
"psr/event-dispatcher": "^1"
},
"suggest": {
@ -9149,7 +9148,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.0-dev"
"dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
@ -9186,7 +9185,7 @@
"standards"
],
"support": {
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0"
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0"
},
"funding": [
{
@ -9202,7 +9201,7 @@
"type": "tidelift"
}
],
"time": "2021-07-15T12:33:35+00:00"
"time": "2021-07-12T14:48:14+00:00"
},
{
"name": "symfony/filesystem",
@ -11045,33 +11044,34 @@
},
{
"name": "symfony/string",
"version": "v6.0.0",
"version": "v5.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "ba727797426af0f587f4800566300bdc0cda0777"
"reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/ba727797426af0f587f4800566300bdc0cda0777",
"reference": "ba727797426af0f587f4800566300bdc0cda0777",
"url": "https://api.github.com/repos/symfony/string/zipball/9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d",
"reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d",
"shasum": ""
},
"require": {
"php": ">=8.0.2",
"php": ">=7.2.5",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
"symfony/polyfill-mbstring": "~1.0"
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "~1.15"
},
"conflict": {
"symfony/translation-contracts": "<2.0"
"symfony/translation-contracts": ">=3.0"
},
"require-dev": {
"symfony/error-handler": "^5.4|^6.0",
"symfony/http-client": "^5.4|^6.0",
"symfony/translation-contracts": "^2.0|^3.0",
"symfony/var-exporter": "^5.4|^6.0"
"symfony/error-handler": "^4.4|^5.0|^6.0",
"symfony/http-client": "^4.4|^5.0|^6.0",
"symfony/translation-contracts": "^1.1|^2",
"symfony/var-exporter": "^4.4|^5.0|^6.0"
},
"type": "library",
"autoload": {
@ -11110,7 +11110,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v6.0.0"
"source": "https://github.com/symfony/string/tree/v5.4.0"
},
"funding": [
{
@ -11126,7 +11126,7 @@
"type": "tidelift"
}
],
"time": "2021-10-29T07:35:21+00:00"
"time": "2021-11-24T10:02:00+00:00"
},
{
"name": "symfony/translation",
@ -12222,16 +12222,16 @@
},
{
"name": "brianium/paratest",
"version": "v6.4.0",
"version": "v6.4.1",
"source": {
"type": "git",
"url": "https://github.com/paratestphp/paratest.git",
"reference": "9bd410d395a0a972533dbb60b017ce58c91a1024"
"reference": "c32a5c4fc2ff339202437d25d19a5f496f880d61"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paratestphp/paratest/zipball/9bd410d395a0a972533dbb60b017ce58c91a1024",
"reference": "9bd410d395a0a972533dbb60b017ce58c91a1024",
"url": "https://api.github.com/repos/paratestphp/paratest/zipball/c32a5c4fc2ff339202437d25d19a5f496f880d61",
"reference": "c32a5c4fc2ff339202437d25d19a5f496f880d61",
"shasum": ""
},
"require": {
@ -12301,7 +12301,7 @@
],
"support": {
"issues": "https://github.com/paratestphp/paratest/issues",
"source": "https://github.com/paratestphp/paratest/tree/v6.4.0"
"source": "https://github.com/paratestphp/paratest/tree/v6.4.1"
},
"funding": [
{
@ -12313,7 +12313,7 @@
"type": "paypal"
}
],
"time": "2021-11-30T16:25:32+00:00"
"time": "2021-12-02T09:12:23+00:00"
},
{
"name": "darkaonline/l5-swagger",
@ -13854,16 +13854,16 @@
},
{
"name": "phpunit/php-file-iterator",
"version": "3.0.5",
"version": "3.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "aa4be8575f26070b100fccb67faabb28f21f66f8"
"reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8",
"reference": "aa4be8575f26070b100fccb67faabb28f21f66f8",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
"reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
"shasum": ""
},
"require": {
@ -13902,7 +13902,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5"
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
},
"funding": [
{
@ -13910,7 +13910,7 @@
"type": "github"
}
],
"time": "2020-09-28T05:57:25+00:00"
"time": "2021-12-02T12:48:52+00:00"
},
{
"name": "phpunit/php-invoker",

View File

@ -6543,6 +6543,34 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
--------------------------------------------------------------------------------
diacritic
Copyright (c) 2016, Agilord.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
double-conversion
icu

View File

@ -3,38 +3,38 @@ const MANIFEST = 'flutter-app-manifest';
const TEMP = 'flutter-temp-cache';
const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
"favicon.ico": "51636d3a390451561744c42188ccd628",
"version.json": "9c7b0edc83733da56c726678aacd9fd3",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
"main.dart.js": "cf5d5c23d2b786d951713c1167ed4304",
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
"favicon.ico": "51636d3a390451561744c42188ccd628",
"main.dart.js": "4479880bad7e1f303b572d806a9c4555",
"/": "87ed144dcf495d9b331539ceeff9c0d3",
"assets/NOTICES": "5a96be85b952e4fcd3a6965546c85b7f",
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "015400679694f1f51047e46da0e1dc98",
"assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5",
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
"/": "3f4fb5e405b74e982799377abb8b98aa",
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
"assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5",
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3"
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
"assets/NOTICES": "4aea723d13add566ca34288c8295b0a4",
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "015400679694f1f51047e46da0e1dc98"
};
// The application shell files that are downloaded before a service worker can

177575
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

192864
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

172573
public/main.html.dart.js vendored

File diff suppressed because one or more lines are too long

194826
public/main.next.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

@ -121,6 +121,17 @@ class ExpenseApiTest extends TestCase
$response->assertStatus(200);
}
public function testExpenseGetSort()
{
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get('/api/v1/expenses?sort=public_notes|desc');
$response->assertStatus(200);
}
public function testExpenseNotArchived()
{
$response = $this->withHeaders([

View File

@ -38,7 +38,7 @@ class AutoBillInvoiceTest extends TestCase
$this->assertEquals($this->client->paid_to_date, 0);
$this->assertEquals($this->client->credit_balance, 10);
$this->invoice->service()->markSent()->autoBill()->save();
$this->invoice->service()->markSent()->autoBill();
$this->assertNotNull($this->invoice->payments());
$this->assertEquals(10, $this->invoice->payments()->sum('payments.amount'));

View File

@ -94,13 +94,13 @@ class SubscriptionsCalcTest extends TestCase
$refund = $pro_rata->refund($invoice->amount, Carbon::parse('2021-01-01'), Carbon::parse('2021-01-06'), $subscription->frequency_id);
$this->assertEquals(1.67, $refund);
$this->assertEquals(1.61, $refund);
$pro_rata = new ProRata;
$upgrade = $pro_rata->charge($target->price, Carbon::parse('2021-01-01'), Carbon::parse('2021-01-06'), $subscription->frequency_id);
$this->assertEquals(3.33, $upgrade);
$this->assertEquals(3.23, $upgrade);
}
}