diff --git a/app/Factory/InvoiceToRecurringInvoiceFactory.php b/app/Factory/InvoiceToRecurringInvoiceFactory.php index a16cbeaf93a2..5b1927a1a60e 100644 --- a/app/Factory/InvoiceToRecurringInvoiceFactory.php +++ b/app/Factory/InvoiceToRecurringInvoiceFactory.php @@ -49,7 +49,6 @@ class InvoiceToRecurringInvoiceFactory $recurring_invoice->client_id = $invoice->client_id; $recurring_invoice->company_id = $invoice->company_id; $recurring_invoice->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY; - $recurring_invoice->start_date = null; $recurring_invoice->last_sent_date = null; $recurring_invoice->next_send_date = null; $recurring_invoice->remaining_cycles = 0; diff --git a/app/Factory/RecurringInvoiceFactory.php b/app/Factory/RecurringInvoiceFactory.php index 4219c73a3803..822e017afea6 100644 --- a/app/Factory/RecurringInvoiceFactory.php +++ b/app/Factory/RecurringInvoiceFactory.php @@ -48,7 +48,6 @@ class RecurringInvoiceFactory $invoice->user_id = $user_id; $invoice->company_id = $company_id; $invoice->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY; - $invoice->start_date = null; $invoice->last_sent_date = null; $invoice->next_send_date = null; $invoice->remaining_cycles = 0; diff --git a/app/Factory/RecurringQuoteFactory.php b/app/Factory/RecurringQuoteFactory.php index 4b3d303f3497..8a728fb58304 100644 --- a/app/Factory/RecurringQuoteFactory.php +++ b/app/Factory/RecurringQuoteFactory.php @@ -47,7 +47,6 @@ class RecurringQuoteFactory $quote->user_id = $user_id; $quote->company_id = $company_id; $quote->frequency_id = RecurringQuote::FREQUENCY_MONTHLY; - $quote->start_date = null; $quote->last_sent_date = null; $quote->next_send_date = null; $quote->remaining_cycles = 0; diff --git a/app/Http/Requests/Client/UpdateClientRequest.php b/app/Http/Requests/Client/UpdateClientRequest.php index 42a05dd6db6e..7d9e05f4966f 100644 --- a/app/Http/Requests/Client/UpdateClientRequest.php +++ b/app/Http/Requests/Client/UpdateClientRequest.php @@ -81,6 +81,9 @@ class UpdateClientRequest extends Request 'email' => ctrans('validation.email', ['attribute' => 'email']), 'name.required' => ctrans('validation.required', ['attribute' => 'name']), 'required' => ctrans('validation.required', ['attribute' => 'email']), + 'contacts.*.password.min' => ctrans('texts.password_strength'), + 'contacts.*.password.regex' => ctrans('texts.password_strength'), + 'contacts.*.password.string' => ctrans('texts.password_strength'), ]; } @@ -109,11 +112,12 @@ class UpdateClientRequest extends Request if (strlen($contact['password']) == 0) { $input['contacts'][$key]['password'] = ''; } else { - $contact['password'] = str_replace('*', '', $contact['password']); + $input['contacts'][$key]['password'] = str_replace('*', '', $contact['password']); if (strlen($contact['password']) == 0) { unset($input['contacts'][$key]['password']); } + } } } diff --git a/app/Http/Requests/RecurringInvoice/StoreRecurringInvoiceRequest.php b/app/Http/Requests/RecurringInvoice/StoreRecurringInvoiceRequest.php index 99413a9a991f..4988103f7924 100644 --- a/app/Http/Requests/RecurringInvoice/StoreRecurringInvoiceRequest.php +++ b/app/Http/Requests/RecurringInvoice/StoreRecurringInvoiceRequest.php @@ -101,5 +101,6 @@ class StoreRecurringInvoiceRequest extends Request public function messages() { + return []; } } diff --git a/app/Models/RecurringInvoice.php b/app/Models/RecurringInvoice.php index 88b6842ffa7d..128b704fda9a 100644 --- a/app/Models/RecurringInvoice.php +++ b/app/Models/RecurringInvoice.php @@ -11,6 +11,8 @@ namespace App\Models; +use App\Helpers\Invoice\InvoiceSum; +use App\Helpers\Invoice\InvoiceSumInclusive; use App\Models\Filterable; use App\Utils\Traits\MakesDates; use App\Utils\Traits\MakesHash; @@ -74,6 +76,7 @@ class RecurringInvoice extends BaseModel 'po_number', 'date', 'due_date', + 'due_date_days', 'line_items', 'settings', 'footer', @@ -93,7 +96,6 @@ class RecurringInvoice extends BaseModel 'amount', 'partial', 'frequency_id', - 'start_date', ]; protected $casts = [ @@ -176,7 +178,7 @@ class RecurringInvoice extends BaseModel public function getStatusAttribute() { - if ($this->status_id == self::STATUS_ACTIVE && $this->start_date > Carbon::now()) { //marked as active, but yet to fire first cycle + if ($this->status_id == self::STATUS_ACTIVE && $this->next_send_date > Carbon::now()) { //marked as active, but yet to fire first cycle return self::STATUS_PENDING; } elseif ($this->status_id == self::STATUS_ACTIVE && $this->next_send_date > Carbon::now()) { return self::STATUS_COMPLETED; @@ -215,11 +217,47 @@ class RecurringInvoice extends BaseModel } } + public function nextDateByFrequency($date) + { + + switch ($this->frequency_id) { + case self::FREQUENCY_WEEKLY: + return Carbon::parse($date->addWeek()); + case self::FREQUENCY_TWO_WEEKS: + return Carbon::parse($date->addWeeks(2)); + case self::FREQUENCY_FOUR_WEEKS: + return Carbon::parse($date->addWeeks(4)); + case self::FREQUENCY_MONTHLY: + return Carbon::parse($date->addMonthNoOverflow()); + case self::FREQUENCY_TWO_MONTHS: + return Carbon::parse($date->addMonthsNoOverflow(2)); + case self::FREQUENCY_THREE_MONTHS: + return Carbon::parse($date->addMonthsNoOverflow(3)); + case self::FREQUENCY_FOUR_MONTHS: + return Carbon::parse($date->addMonthsNoOverflow(4)); + case self::FREQUENCY_SIX_MONTHS: + return Carbon::parse($date->addMonthsNoOverflow(6)); + case self::FREQUENCY_ANNUALLY: + return Carbon::parse($date->addYear()); + case self::FREQUENCY_TWO_YEARS: + return Carbon::parse($date->addYears(2)); + case self::FREQUENCY_THREE_YEARS: + return Carbon::parse($date->addYears(3)); + default: + return null; + } + + } + public function remainingCycles() : int { if ($this->remaining_cycles == 0) { return 0; - } else { + } + else if($this->remaining_cycles == -1) { + return -1; + } + else { return $this->remaining_cycles - 1; } } @@ -295,8 +333,75 @@ class RecurringInvoice extends BaseModel } } + public function calc() + { + $invoice_calc = null; + + if ($this->uses_inclusive_taxes) { + $invoice_calc = new InvoiceSumInclusive($this); + } else { + $invoice_calc = new InvoiceSum($this); + } + + return $invoice_calc->build(); + } + + /* + * Important to note when playing with carbon dates - in order + * not to modify the original instance, always use a `->copy()` + * + */ public function recurringDates() { - //todo send back a list of the next send dates and due dates + info($this->next_send_date); + /* Return early if nothing to send back! */ + if( $this->status_id == self::STATUS_COMPLETED || + $this->status_id == self::STATUS_DRAFT || + $this->status_id == self::STATUS_CANCELLED || + $this->remaining_cycles == 0 || + !$this->next_send_date) { + + return []; + } + + /* Endless - lets send 10 back*/ + $iterations = $this->remaining_cycles; + + if($this->remaining_cycles == -1) + $iterations = 10; + + $data = []; + + $next_send_date = Carbon::parse($this->next_send_date)->copy(); + + for($x=0; $x<$iterations; $x++) + { + + $next_due_date = $next_send_date->copy()->addDays($this->due_date_days); + + $next_send_date = Carbon::parse($next_send_date); + $next_due_date = Carbon::parse($next_due_date); + + $data[] = [ + 'next_send_date' => $next_send_date->format('Y-m-d'), + 'due_date' => $next_due_date->format('Y-m-d'), + ]; + + $next_send_date = $this->nextDateByFrequency($next_send_date); + + } + + /*If no due date is set - unset the due_date value */ + if(!$this->due_date_days || $this->due_date_days == 0){ + + foreach($data as $key => $value) + $data[$key]['due_date'] = ''; + + } + + return $data; + } + + } diff --git a/app/Models/RecurringQuote.php b/app/Models/RecurringQuote.php index 22aab4d03f66..5414e5e8640c 100644 --- a/app/Models/RecurringQuote.php +++ b/app/Models/RecurringQuote.php @@ -77,7 +77,7 @@ class RecurringQuote extends BaseModel 'custom_value4', 'amount', 'frequency_id', - 'start_date', + 'due_date_days', ]; protected $touches = []; diff --git a/app/Repositories/ClientContactRepository.php b/app/Repositories/ClientContactRepository.php index 3267bb20f84b..79f0ce397dcd 100644 --- a/app/Repositories/ClientContactRepository.php +++ b/app/Repositories/ClientContactRepository.php @@ -58,12 +58,10 @@ class ClientContactRepository extends BaseRepository $update_contact->fill($contact); - if (array_key_exists('password', $contact)) { - if (strlen($contact['password']) == 0) { - $update_contact->password = ''; - } else { - $update_contact->password = Hash::make($contact['password']); - } + if (array_key_exists('password', $contact) && strlen($contact['password']) > 1) { + + $update_contact->password = Hash::make($contact['password']); + } $update_contact->save(); diff --git a/app/Transformers/RecurringInvoiceTransformer.php b/app/Transformers/RecurringInvoiceTransformer.php index 71e5586119eb..25e79646ef42 100644 --- a/app/Transformers/RecurringInvoiceTransformer.php +++ b/app/Transformers/RecurringInvoiceTransformer.php @@ -133,8 +133,8 @@ class RecurringInvoiceTransformer extends EntityTransformer 'line_items' => $invoice->line_items ?: (array) [], 'entity_type' => 'recurring_invoice', 'frequency_id' => (string) $invoice->frequency_id, - 'start_date' => $invoice->start_date ?: '', 'remaining_cycles' => (int) $invoice->remaining_cycles, + 'recurring_dates' => (array) $invoice->recurringDates(), ]; } } diff --git a/app/Transformers/RecurringQuoteTransformer.php b/app/Transformers/RecurringQuoteTransformer.php index 65fc7d3ef61d..32e6ffdf58c6 100644 --- a/app/Transformers/RecurringQuoteTransformer.php +++ b/app/Transformers/RecurringQuoteTransformer.php @@ -118,7 +118,6 @@ class RecurringQuoteTransformer extends EntityTransformer 'custom_text_value2' => $quote->custom_text_value2 ?: '', 'settings' => $quote->settings ?: '', 'frequency_id' => (int) $quote->frequency_id, - 'start_date' => $quote->start_date ?: '', 'last_sent_date' => $quote->last_sent_date ?: '', 'next_send_date' => $quote->next_send_date ?: '', 'remaining_cycles' => (int) $quote->remaining_cycles, diff --git a/composer.json b/composer.json index 43311bda6a68..4df67077406e 100644 --- a/composer.json +++ b/composer.json @@ -56,17 +56,14 @@ "stripe/stripe-php": "^7.50", "turbo124/beacon": "^1", "webpatser/laravel-countries": "dev-master#75992ad", - "laravel/ui": "^2.0", - "fruitcake/laravel-cors": "^2.0" + "laravel/ui": "^2.0" }, "require-dev": { - "laravelcollective/html": "^6", "wildbit/postmark-php": "^2.6", "anahkiasen/former": "^4.2", "barryvdh/laravel-debugbar": "^3.4", "darkaonline/l5-swagger": "^7.0", "filp/whoops": "^2.7", - "laravel/dusk": "^6.5", "mockery/mockery": "^1.3.1", "nunomaduro/collision": "^4.1", "phpunit/phpunit": "^8.5", diff --git a/composer.lock b/composer.lock index 267ae13c98ac..232885377011 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "1e9eef01abf64118b10e9fc2dff9c5e9", + "content-hash": "897c03f97efca6c6540700216fa6d789", "packages": [ { "name": "asgrim/ofxparser", @@ -63,58 +63,6 @@ "abandoned": true, "time": "2018-10-29T10:10:13+00:00" }, - { - "name": "asm89/stack-cors", - "version": "v2.0.1", - "source": { - "type": "git", - "url": "https://github.com/asm89/stack-cors.git", - "reference": "23f469e81c65e2fb7fc7bce371fbdc363fe32adf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/asm89/stack-cors/zipball/23f469e81c65e2fb7fc7bce371fbdc363fe32adf", - "reference": "23f469e81c65e2fb7fc7bce371fbdc363fe32adf", - "shasum": "" - }, - "require": { - "php": "^7.0", - "symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0", - "symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Asm89\\Stack\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alexander", - "email": "iam.asm89@gmail.com" - } - ], - "description": "Cross-origin resource sharing library and stack middleware", - "homepage": "https://github.com/asm89/stack-cors", - "keywords": [ - "cors", - "stack" - ], - "time": "2020-05-31T07:17:05+00:00" - }, { "name": "authorizenet/authorizenet", "version": "2.0.0", @@ -160,16 +108,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.153.0", + "version": "3.154.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "3045bc6c8f7d2521b3e0d4a7b407194af8725c8f" + "reference": "5651d8a92164d98869b70a15e4c06ce4c14c7c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3045bc6c8f7d2521b3e0d4a7b407194af8725c8f", - "reference": "3045bc6c8f7d2521b3e0d4a7b407194af8725c8f", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5651d8a92164d98869b70a15e4c06ce4c14c7c28", + "reference": "5651d8a92164d98869b70a15e4c06ce4c14c7c28", "shasum": "" }, "require": { @@ -241,7 +189,7 @@ "s3", "sdk" ], - "time": "2020-09-09T18:12:35+00:00" + "time": "2020-09-11T18:12:41+00:00" }, { "name": "brick/math", @@ -1771,79 +1719,6 @@ ], "time": "2020-03-25T18:49:23+00:00" }, - { - "name": "fruitcake/laravel-cors", - "version": "v2.0.2", - "source": { - "type": "git", - "url": "https://github.com/fruitcake/laravel-cors.git", - "reference": "4b19bfc3bd422948af37a42a62fad7f49025894a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/4b19bfc3bd422948af37a42a62fad7f49025894a", - "reference": "4b19bfc3bd422948af37a42a62fad7f49025894a", - "shasum": "" - }, - "require": { - "asm89/stack-cors": "^2.0.1", - "illuminate/contracts": "^6|^7|^8", - "illuminate/support": "^6|^7|^8", - "php": ">=7.2", - "symfony/http-foundation": "^4|^5", - "symfony/http-kernel": "^4.3.4|^5" - }, - "require-dev": { - "laravel/framework": "^6|^7|^8", - "orchestra/testbench-dusk": "^4|^5|^6", - "phpunit/phpunit": "^6|^7|^8", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - }, - "laravel": { - "providers": [ - "Fruitcake\\Cors\\CorsServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Fruitcake\\Cors\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fruitcake", - "homepage": "https://fruitcake.nl" - }, - { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" - } - ], - "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application", - "keywords": [ - "api", - "cors", - "crossdomain", - "laravel" - ], - "funding": [ - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2020-09-07T11:48:52+00:00" - }, { "name": "fzaninotto/faker", "version": "v1.9.1", @@ -2929,27 +2804,27 @@ }, { "name": "laravel/ui", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/laravel/ui.git", - "reference": "2ccaa3b821ea8ac7e05393b946d0578bdb46099b" + "reference": "f5398544a9cd4804a42d09ce51735e37cd51ea2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/ui/zipball/2ccaa3b821ea8ac7e05393b946d0578bdb46099b", - "reference": "2ccaa3b821ea8ac7e05393b946d0578bdb46099b", + "url": "https://api.github.com/repos/laravel/ui/zipball/f5398544a9cd4804a42d09ce51735e37cd51ea2d", + "reference": "f5398544a9cd4804a42d09ce51735e37cd51ea2d", "shasum": "" }, "require": { - "illuminate/console": "^7.0|^8.0", - "illuminate/filesystem": "^7.0|^8.0", - "illuminate/support": "^7.0|^8.0", + "illuminate/console": "^7.0", + "illuminate/filesystem": "^7.0", + "illuminate/support": "^7.0", "php": "^7.2.5" }, "require-dev": { "mockery/mockery": "^1.0", - "phpunit/phpunit": "^8.0|^9.0" + "phpunit/phpunit": "^8.0" }, "type": "library", "extra": { @@ -2980,7 +2855,7 @@ "laravel", "ui" ], - "time": "2020-09-09T12:07:59+00:00" + "time": "2020-09-11T15:31:52+00:00" }, { "name": "league/commonmark", @@ -3963,16 +3838,16 @@ }, { "name": "nesbot/carbon", - "version": "2.39.1", + "version": "2.39.2", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7af467873250583cc967a59ee9df29fabab193c1" + "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7af467873250583cc967a59ee9df29fabab193c1", - "reference": "7af467873250583cc967a59ee9df29fabab193c1", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/326efde1bc09077a26cb77f6e2e32e13f06c27f2", + "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2", "shasum": "" }, "require": { @@ -4048,7 +3923,7 @@ "type": "tidelift" } ], - "time": "2020-09-04T13:11:37+00:00" + "time": "2020-09-10T12:16:42+00:00" }, { "name": "nikic/php-parser", @@ -5085,16 +4960,16 @@ }, { "name": "predis/predis", - "version": "v1.1.4", + "version": "v1.1.6", "source": { "type": "git", "url": "https://github.com/predis/predis.git", - "reference": "8be2418f0116572f1937083daf5cceb1bddc9f0d" + "reference": "9930e933c67446962997b05201c69c2319bf26de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/predis/predis/zipball/8be2418f0116572f1937083daf5cceb1bddc9f0d", - "reference": "8be2418f0116572f1937083daf5cceb1bddc9f0d", + "url": "https://api.github.com/repos/predis/predis/zipball/9930e933c67446962997b05201c69c2319bf26de", + "reference": "9930e933c67446962997b05201c69c2319bf26de", "shasum": "" }, "require": { @@ -5156,7 +5031,7 @@ "type": "github" } ], - "time": "2020-08-29T22:15:08+00:00" + "time": "2020-09-11T19:18:05+00:00" }, { "name": "psr/cache", @@ -5659,16 +5534,16 @@ }, { "name": "ramsey/collection", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "044184884e3c803e4cbb6451386cb71562939b18" + "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/044184884e3c803e4cbb6451386cb71562939b18", - "reference": "044184884e3c803e4cbb6451386cb71562939b18", + "url": "https://api.github.com/repos/ramsey/collection/zipball/24d93aefb2cd786b7edd9f45b554aea20b28b9b1", + "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1", "shasum": "" }, "require": { @@ -5724,7 +5599,7 @@ "type": "github" } ], - "time": "2020-08-11T00:57:21+00:00" + "time": "2020-09-10T20:58:17+00:00" }, { "name": "ramsey/uuid", @@ -9975,142 +9850,6 @@ ], "time": "2020-07-09T08:09:16+00:00" }, - { - "name": "laravel/dusk", - "version": "v6.6.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/dusk.git", - "reference": "be00c525f9bde15bcfec1afc4857ab26afa6b369" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/dusk/zipball/be00c525f9bde15bcfec1afc4857ab26afa6b369", - "reference": "be00c525f9bde15bcfec1afc4857ab26afa6b369", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-zip": "*", - "illuminate/console": "^6.0|^7.0|^8.0", - "illuminate/support": "^6.0|^7.0|^8.0", - "nesbot/carbon": "^2.0", - "php": "^7.2", - "php-webdriver/webdriver": "^1.8.1", - "symfony/console": "^4.3|^5.0", - "symfony/finder": "^4.3|^5.0", - "symfony/process": "^4.3|^5.0", - "vlucas/phpdotenv": "^3.0|^4.0|^5.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^7.5.15|^8.4|^9.0" - }, - "suggest": { - "ext-pcntl": "Used to gracefully terminate Dusk when tests are running." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.x-dev" - }, - "laravel": { - "providers": [ - "Laravel\\Dusk\\DuskServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Dusk\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Laravel Dusk provides simple end-to-end testing and browser automation.", - "keywords": [ - "laravel", - "testing", - "webdriver" - ], - "time": "2020-09-08T16:09:25+00:00" - }, - { - "name": "laravelcollective/html", - "version": "v6.2.0", - "source": { - "type": "git", - "url": "https://github.com/LaravelCollective/html.git", - "reference": "3bb99be7502feb2129b375cd026ccb0fa4b66628" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/LaravelCollective/html/zipball/3bb99be7502feb2129b375cd026ccb0fa4b66628", - "reference": "3bb99be7502feb2129b375cd026ccb0fa4b66628", - "shasum": "" - }, - "require": { - "illuminate/http": "^6.0|^7.0|^8.0", - "illuminate/routing": "^6.0|^7.0|^8.0", - "illuminate/session": "^6.0|^7.0|^8.0", - "illuminate/support": "^6.0|^7.0|^8.0", - "illuminate/view": "^6.0|^7.0|^8.0", - "php": ">=7.2.5" - }, - "require-dev": { - "illuminate/database": "^6.0|^7.0|^8.0", - "mockery/mockery": "~1.0", - "phpunit/phpunit": "~7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.0-dev" - }, - "laravel": { - "providers": [ - "Collective\\Html\\HtmlServiceProvider" - ], - "aliases": { - "Form": "Collective\\Html\\FormFacade", - "Html": "Collective\\Html\\HtmlFacade" - } - } - }, - "autoload": { - "psr-4": { - "Collective\\Html\\": "src/" - }, - "files": [ - "src/helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Adam Engebretson", - "email": "adam@laravelcollective.com" - }, - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "HTML and Form Builders for the Laravel Framework", - "homepage": "https://laravelcollective.com", - "time": "2020-09-07T19:59:40+00:00" - }, { "name": "maximebf/debugbar", "version": "v1.16.3", @@ -10480,71 +10219,6 @@ "description": "Library for handling version information and constraints", "time": "2018-07-08T19:19:57+00:00" }, - { - "name": "php-webdriver/webdriver", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/php-webdriver/php-webdriver.git", - "reference": "3308a70be084d6d7fd1ee5787b4c2e6eb4b70aab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/3308a70be084d6d7fd1ee5787b4c2e6eb4b70aab", - "reference": "3308a70be084d6d7fd1ee5787b4c2e6eb4b70aab", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-zip": "*", - "php": "^5.6 || ~7.0", - "symfony/polyfill-mbstring": "^1.12", - "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.0", - "jakub-onderka/php-parallel-lint": "^1.0", - "php-coveralls/php-coveralls": "^2.0", - "php-mock/php-mock-phpunit": "^1.1", - "phpunit/phpunit": "^5.7", - "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0", - "sminnee/phpunit-mock-objects": "^3.4", - "squizlabs/php_codesniffer": "^3.5", - "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0" - }, - "suggest": { - "ext-SimpleXML": "For Firefox profile creation" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "psr-4": { - "Facebook\\WebDriver\\": "lib/" - }, - "files": [ - "lib/Exception/TimeoutException.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.", - "homepage": "https://github.com/php-webdriver/php-webdriver", - "keywords": [ - "Chromedriver", - "geckodriver", - "php", - "selenium", - "webdriver" - ], - "time": "2020-03-04T14:40:12+00:00" - }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -11792,16 +11466,16 @@ }, { "name": "swagger-api/swagger-ui", - "version": "v3.32.5", + "version": "v3.33.0", "source": { "type": "git", "url": "https://github.com/swagger-api/swagger-ui.git", - "reference": "57f39bd5724956d96af43a86439e2808b981fb18" + "reference": "829d87530030bb5bfa24a5093d098c672adfbb9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/57f39bd5724956d96af43a86439e2808b981fb18", - "reference": "57f39bd5724956d96af43a86439e2808b981fb18", + "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/829d87530030bb5bfa24a5093d098c672adfbb9b", + "reference": "829d87530030bb5bfa24a5093d098c672adfbb9b", "shasum": "" }, "type": "library", @@ -11845,7 +11519,7 @@ "swagger", "ui" ], - "time": "2020-08-27T20:11:06+00:00" + "time": "2020-09-10T23:20:14+00:00" }, { "name": "symfony/debug", diff --git a/database/factories/RecurringInvoiceFactory.php b/database/factories/RecurringInvoiceFactory.php index bbd8ef4b65d2..44b9410959dd 100644 --- a/database/factories/RecurringInvoiceFactory.php +++ b/database/factories/RecurringInvoiceFactory.php @@ -25,9 +25,8 @@ $factory->define(App\Models\RecurringInvoice::class, function (Faker $faker) { 'due_date' => $faker->date(), 'line_items' => false, 'frequency_id' => App\Models\RecurringInvoice::FREQUENCY_MONTHLY, - 'start_date' => $faker->date(), - 'last_sent_date' => $faker->date(), - 'next_send_date' => $faker->date(), + 'last_sent_date' => now()->subMonth(), + 'next_send_date' => now()->addMonthNoOverflow(), 'remaining_cycles' => $faker->numberBetween(1, 10), 'amount' => $faker->randomFloat(2, $min = 1, $max = 1000), // 48.8932 diff --git a/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php b/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php index 73e37c195f27..e7e86ec690fb 100644 --- a/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php +++ b/database/migrations/2020_08_18_140557_add_is_public_to_documents_table.php @@ -66,6 +66,13 @@ class AddIsPublicToDocumentsTable extends Migration Schema::table('companies', function ($table) { $table->enum('default_auto_bill', ['off', 'always', 'optin', 'optout'])->default('off'); }); + + Schema::table('recurring_invoices', function (Blueprint $table) { + $table->integer('remaining_cycles')->nullable()->change(); + $table->dropColumn('start_date'); + $table->integer('due_date_days')->nullable(); + $table->date('partial_due_date')->nullable(); + }); } /** diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 4323653b70aa..82e47e29f195 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -3269,4 +3269,5 @@ return [ 'payment_due' => 'Payment due', 'account_balance' => 'Account balance', + 'password_strength' => 'Password strength too weak', ]; diff --git a/tests/MockAccountData.php b/tests/MockAccountData.php index 12a65cc8e094..1ff41c5ccc75 100644 --- a/tests/MockAccountData.php +++ b/tests/MockAccountData.php @@ -317,7 +317,7 @@ trait MockAccountData $recurring_invoice->next_send_date = Carbon::now(); $recurring_invoice->status_id = RecurringInvoice::STATUS_ACTIVE; $recurring_invoice->remaining_cycles = 2; - $recurring_invoice->start_date = Carbon::now(); + $recurring_invoice->next_send_date = Carbon::now(); $recurring_invoice->save(); $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client); @@ -327,7 +327,7 @@ trait MockAccountData $recurring_invoice->next_send_date = Carbon::now()->addMinutes(2); $recurring_invoice->status_id = RecurringInvoice::STATUS_ACTIVE; $recurring_invoice->remaining_cycles = 2; - $recurring_invoice->start_date = Carbon::now(); + $recurring_invoice->next_send_date = Carbon::now(); $recurring_invoice->save(); $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client); @@ -337,7 +337,7 @@ trait MockAccountData $recurring_invoice->next_send_date = Carbon::now()->addMinutes(10); $recurring_invoice->status_id = RecurringInvoice::STATUS_ACTIVE; $recurring_invoice->remaining_cycles = 2; - $recurring_invoice->start_date = Carbon::now(); + $recurring_invoice->next_send_date = Carbon::now(); $recurring_invoice->save(); $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client); @@ -347,7 +347,7 @@ trait MockAccountData $recurring_invoice->next_send_date = Carbon::now()->addMinutes(15); $recurring_invoice->status_id = RecurringInvoice::STATUS_ACTIVE; $recurring_invoice->remaining_cycles = 2; - $recurring_invoice->start_date = Carbon::now(); + $recurring_invoice->next_send_date = Carbon::now(); $recurring_invoice->save(); $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client); @@ -357,7 +357,7 @@ trait MockAccountData $recurring_invoice->next_send_date = Carbon::now()->addMinutes(20); $recurring_invoice->status_id = RecurringInvoice::STATUS_ACTIVE; $recurring_invoice->remaining_cycles = 2; - $recurring_invoice->start_date = Carbon::now(); + $recurring_invoice->next_send_date = Carbon::now(); $recurring_invoice->save(); $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client); @@ -367,7 +367,7 @@ trait MockAccountData $recurring_invoice->next_send_date = Carbon::now()->addDays(10); $recurring_invoice->status_id = RecurringInvoice::STATUS_ACTIVE; $recurring_invoice->remaining_cycles = 2; - $recurring_invoice->start_date = Carbon::now(); + $recurring_invoice->next_send_date = Carbon::now(); $recurring_invoice->save(); $recurring_invoice->number = $this->getNextInvoiceNumber($this->invoice->client); diff --git a/tests/Unit/RecurringDatesTest.php b/tests/Unit/RecurringDatesTest.php new file mode 100644 index 000000000000..16ab02d51284 --- /dev/null +++ b/tests/Unit/RecurringDatesTest.php @@ -0,0 +1,87 @@ +makeTestData(); + } + + public function testRecurringDatesDraftInvoice() + { + + $recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice->line_items = $this->buildLineItems(); + $recurring_invoice->client_id = $this->client->id; + $recurring_invoice->save(); + + $recurring_invoice->calc()->getInvoice(); + + $this->assertEquals(0, count($recurring_invoice->recurringDates())); + + } + + public function testRecurringDatesPendingInvoice() + { + + $recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice->line_items = $this->buildLineItems(); + $recurring_invoice->client_id = $this->client->id; + + $recurring_invoice->status_id = RecurringInvoice::STATUS_PENDING; + $recurring_invoice->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY; + $recurring_invoice->remaining_cycles = 5; + $recurring_invoice->due_date_days = 5; + $recurring_invoice->next_send_date = now(); + + $recurring_invoice->save(); + + $recurring_invoice->calc()->getInvoice(); + + $this->assertEquals(5, count($recurring_invoice->recurringDates())); + + } + + + public function testRecurringDatesPendingInvoiceWithNoDueDate() + { + + $recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id); + $recurring_invoice->line_items = $this->buildLineItems(); + $recurring_invoice->client_id = $this->client->id; + + $recurring_invoice->status_id = RecurringInvoice::STATUS_PENDING; + $recurring_invoice->frequency_id = RecurringInvoice::FREQUENCY_MONTHLY; + $recurring_invoice->remaining_cycles = 5; + $recurring_invoice->due_date_days = null; + $recurring_invoice->next_send_date = now(); + + $recurring_invoice->save(); + + $recurring_invoice->calc()->getInvoice(); + + $this->assertEquals(5, count($recurring_invoice->recurringDates())); + + } +}