mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Subscriptions (#3682)
* Working on subscriptions * Implement return type in models * Subscription implementation * Improvements to handling importation of large accountS * Loggin imports * Activate collector * Improve memory usage of import script * Quote actions * Send Quotes * Fixes for seg faults! * Minor fixes * Fixes for client contact scopes
This commit is contained in:
parent
6e89affc93
commit
d9d2e21f93
@ -11,14 +11,14 @@
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Models\quote;
|
||||
use App\Models\Quote;
|
||||
|
||||
class CloneQuoteFactory
|
||||
{
|
||||
public static function create($quote, $user_id)
|
||||
{
|
||||
$clone_quote = $quote->replicate();
|
||||
$clone_quote->status_id = quote::STATUS_DRAFT;
|
||||
$clone_quote->status_id = Quote::STATUS_DRAFT;
|
||||
$clone_quote->number = null;
|
||||
$clone_quote->date = null;
|
||||
$clone_quote->due_date = null;
|
||||
|
@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Models\Invoice;
|
||||
@ -8,12 +18,25 @@ class CloneQuoteToInvoiceFactory
|
||||
{
|
||||
public static function create(Quote $quote, $user_id) : ?Invoice
|
||||
{
|
||||
$invoice = new Invoice();
|
||||
$invoice->user_id = $user_id;
|
||||
$invoice->po_number = $quote->po_number;
|
||||
$invoice->footer = $quote->footer;
|
||||
$invoice->line_items = $quote->line_items;
|
||||
|
||||
return $invoice;
|
||||
|
||||
$invoice = new Invoice();
|
||||
|
||||
$quote_array = $quote->toArray();
|
||||
|
||||
unset($quote_array['client']);
|
||||
unset($quote_array['company']);
|
||||
unset($quote_array['hashed_id']);
|
||||
unset($quote_array['id']);
|
||||
|
||||
foreach($quote_array as $key => $value)
|
||||
$invoice->{$key} = $value;
|
||||
|
||||
$invoice->due_date = null;
|
||||
$invoice->partial_due_date = null;
|
||||
$invoice->number = null;
|
||||
$invoice->status_id = null;
|
||||
|
||||
return $invoice;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use Turbo124\Collector\Facades\LightLogs;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
|
||||
class LoginController extends BaseController
|
||||
{
|
||||
|
@ -501,9 +501,7 @@ class QuoteController extends BaseController
|
||||
*/
|
||||
public function bulk()
|
||||
{
|
||||
/*
|
||||
* WIP!
|
||||
*/
|
||||
|
||||
$action = request()->input('action');
|
||||
|
||||
$ids = request()->input('ids');
|
||||
@ -511,14 +509,14 @@ class QuoteController extends BaseController
|
||||
$quotes = Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
||||
|
||||
if (!$quotes) {
|
||||
return response()->json(['message' => 'No Quotes Found']);
|
||||
return response()->json(['message' => 'No Quote/s Found']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Download Invoice/s
|
||||
*/
|
||||
|
||||
if ($action == 'download' && $quotes->count() > 1) {
|
||||
if ($action == 'download' && $quotes->count() >= 1) {
|
||||
$quotes->each(function ($quote) {
|
||||
if (auth()->user()->cannot('view', $quote)) {
|
||||
return response()->json(['message'=>'Insufficient privileges to access quote '. $quote->number]);
|
||||
@ -627,8 +625,8 @@ class QuoteController extends BaseController
|
||||
switch ($action) {
|
||||
case 'clone_to_invoice':
|
||||
|
||||
$this->entity_type = Quote::class;
|
||||
$this->entity_transformer = QuoteTransformer::class;
|
||||
$this->entity_type = Invoice::class;
|
||||
$this->entity_transformer = InvoiceTransformer::class;
|
||||
|
||||
$invoice = CloneQuoteToInvoiceFactory::create($quote, auth()->user()->id);
|
||||
return $this->itemResponse($invoice);
|
||||
@ -646,17 +644,16 @@ class QuoteController extends BaseController
|
||||
return $this->itemResponse($quote->service()->approve()->save());
|
||||
break;
|
||||
case 'convert':
|
||||
//convert quote to an invoice make sure we link the two entities!!!
|
||||
|
||||
$this->entity_type = Invoice::class;
|
||||
$this->entity_transformer = InvoiceTransformer::class;
|
||||
|
||||
return $this->itemResponse($quote->service()->convertToInvoice());
|
||||
|
||||
break;
|
||||
case 'history':
|
||||
# code...
|
||||
break;
|
||||
case 'delivery_note':
|
||||
# code...
|
||||
break;
|
||||
case 'mark_paid':
|
||||
# code...
|
||||
break;
|
||||
case 'download':
|
||||
return response()->download(TempFile::path($quote->pdf_file_path()), basename($quote->pdf_file_path()));
|
||||
break;
|
||||
@ -669,6 +666,7 @@ class QuoteController extends BaseController
|
||||
return $this->listResponse($quote);
|
||||
break;
|
||||
case 'email':
|
||||
$this->quote->service()->sendEmail();
|
||||
return response()->json(['message'=>'email sent'], 200);
|
||||
break;
|
||||
case 'mark_sent':
|
||||
|
@ -184,7 +184,7 @@ class PayPalExpressPaymentDriver extends BasePaymentDriver
|
||||
|
||||
private function buildReturnUrl($input) : string
|
||||
{
|
||||
$url = $this->client->company->domain() . "client/payments/process/response";
|
||||
$url = $this->client->company->domain() . "/client/payments/process/response";
|
||||
$url .= "?company_gateway_id={$this->company_gateway->id}&gateway_type_id=".GatewayType::PAYPAL;
|
||||
$url .= "&hashed_ids=" . implode(",", $input['hashed_ids']);
|
||||
$url .= "&amount=".$input['amount'];
|
||||
|
@ -1,4 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Services\Credit;
|
||||
|
||||
use App\Models\Credit;
|
||||
|
@ -103,12 +103,12 @@ class InvoiceService
|
||||
}
|
||||
|
||||
|
||||
public function getInvoicePdf($contact)
|
||||
public function getInvoicePdf($contact = null)
|
||||
{
|
||||
return (new GetInvoicePdf($this->invoice, $contact))->run();
|
||||
}
|
||||
|
||||
public function sendEmail($contact)
|
||||
public function sendEmail($contact = null)
|
||||
{
|
||||
$send_email = new SendEmail($this->invoice, null, $contact);
|
||||
|
||||
|
@ -22,6 +22,10 @@ class SendEmail extends AbstractService
|
||||
{
|
||||
protected $invoice;
|
||||
|
||||
protected $reminder_template;
|
||||
|
||||
protected $contact;
|
||||
|
||||
public function __construct(Invoice $invoice, $reminder_template = null, ClientContact $contact = null)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
|
@ -47,7 +47,7 @@ class PaymentService
|
||||
|
||||
public function sendEmail($contact = null)
|
||||
{
|
||||
return (new SendEmail($this->payment))->run(null, $contact);
|
||||
return (new SendEmail($this->payment, $contact))->run();
|
||||
}
|
||||
|
||||
public function reversePayment()
|
||||
|
@ -9,9 +9,13 @@ class SendEmail
|
||||
{
|
||||
public $payment;
|
||||
|
||||
public function __construct($payment)
|
||||
public $contact;
|
||||
|
||||
public function __construct($payment, $contact)
|
||||
{
|
||||
$this->payment = $payment;
|
||||
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -19,7 +23,7 @@ class SendEmail
|
||||
* @param string $reminder_template The template name ie reminder1
|
||||
* @return array
|
||||
*/
|
||||
public function run($contact = null): array
|
||||
public function run()
|
||||
{
|
||||
$email_builder = (new PaymentEmail())->build($this->payment, $contact);
|
||||
|
||||
|
@ -1,6 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Quote;
|
||||
use App\Repositories\QuoteRepository;
|
||||
@ -38,18 +49,18 @@ class QuoteService
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuotePdf($contact)
|
||||
public function getQuotePdf($contact = null)
|
||||
{
|
||||
$get_invoice_pdf = new GetQuotePdf();
|
||||
|
||||
return $get_invoice_pdf($this->quote, $contact);
|
||||
}
|
||||
|
||||
public function sendEmail($contact) :QuoteService
|
||||
public function sendEmail($contact = null) :QuoteService
|
||||
{
|
||||
$send_email = new SendEmail($this->quote);
|
||||
$send_email = new SendEmail($this->quote, null, $contact);
|
||||
|
||||
$send_email->run(null, $contact);
|
||||
$send_email->run();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -116,18 +127,17 @@ class QuoteService
|
||||
|
||||
public function convertToInvoice() :Invoice
|
||||
{
|
||||
Invoice::unguard();
|
||||
|
||||
$invoice = new Invoice((array) $this->quote);
|
||||
$invoice = CloneQuoteToInvoiceFactory::create($this->quote, $this->quote->user_id);
|
||||
$invoice->status_id = Invoice::STATUS_SENT;
|
||||
$invoice->due_date = null;
|
||||
$invoice->invitations = null;
|
||||
$invoice->number = null;
|
||||
$invoice->save();
|
||||
|
||||
Invoice::reguard();
|
||||
|
||||
$invoice->service()->markSent()->createInvitations()->save();
|
||||
$invoice->service()
|
||||
->markSent()
|
||||
->createInvitations()
|
||||
->save();
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
@ -4,31 +4,40 @@ namespace App\Services\Quote;
|
||||
|
||||
use App\Helpers\Email\QuoteEmail;
|
||||
use App\Jobs\Quote\EmailQuote;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Quote;
|
||||
|
||||
class SendEmail
|
||||
{
|
||||
public $quote;
|
||||
|
||||
public function __construct($quote)
|
||||
protected $reminder_template;
|
||||
|
||||
protected $contact;
|
||||
|
||||
public function __construct($quote, $reminder_template = null, ClientContact $contact = null)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
|
||||
$this->reminder_template = $reminder_template;
|
||||
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the correct template to send
|
||||
* @param string $reminder_template The template name ie reminder1
|
||||
* @param string $this->reminder_template The template name ie reminder1
|
||||
* @return array
|
||||
*/
|
||||
public function run($reminder_template = null, $contact = null): array
|
||||
public function run(): array
|
||||
{
|
||||
if (!$reminder_template) {
|
||||
$reminder_template = $this->quote->status_id == Quote::STATUS_DRAFT || Carbon::parse($this->quote->due_date) > now() ? 'invoice' : $this->quote->calculateTemplate();
|
||||
if (!$this->reminder_template) {
|
||||
$this->reminder_template = $this->quote->calculateTemplate();
|
||||
}
|
||||
|
||||
$this->quote->invitations->each(function ($invitation) {
|
||||
if ($invitation->contact->send_email && $invitation->contact->email) {
|
||||
$email_builder = (new QuoteEmail())->build($invitation, $reminder_template);
|
||||
$email_builder = (new QuoteEmail())->build($invitation, $this->reminder_template);
|
||||
|
||||
EmailQuote::dispatchNow($email_builder, $invitation);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@
|
||||
"staudenmeir/eloquent-has-many-deep": "^1.11",
|
||||
"stripe/stripe-php": "^7.0",
|
||||
"superbalist/laravel-google-cloud-storage": "^2.2",
|
||||
"turbo124/collector": "^0",
|
||||
"turbo124/beacon": "^0",
|
||||
"webpatser/laravel-countries": "dev-master#75992ad",
|
||||
"yajra/laravel-datatables-oracle": "~9.0"
|
||||
},
|
||||
|
@ -3,9 +3,9 @@
|
||||
return [
|
||||
|
||||
/**
|
||||
* Enable or disable the collector
|
||||
* Enable or disable the beacon
|
||||
*/
|
||||
'enabled' => false,
|
||||
'enabled' => true,
|
||||
|
||||
/**
|
||||
* The API endpoint for logs
|
||||
@ -15,7 +15,7 @@ return [
|
||||
/**
|
||||
* Your API key
|
||||
*/
|
||||
'api_key' => env('COLLECTOR_API_KEY',''),
|
||||
'api_key' => env('BEACON_API_KEY',''),
|
||||
|
||||
/**
|
||||
* Should batch requests
|
||||
@ -26,7 +26,7 @@ return [
|
||||
* The default key used to store
|
||||
* metrics for batching
|
||||
*/
|
||||
'cache_key' => 'collector',
|
||||
'cache_key' => 'beacon',
|
||||
|
||||
/**
|
||||
* Determines whether to log the
|
||||
@ -34,9 +34,9 @@ return [
|
||||
* the built in metrics.
|
||||
*/
|
||||
'system_logging' => [
|
||||
'Turbo124\Collector\Jobs\System\CpuMetric',
|
||||
'Turbo124\Collector\Jobs\System\HdMetric',
|
||||
'Turbo124\Collector\Jobs\System\MemMetric',
|
||||
'Turbo124\Beacon\Jobs\System\CpuMetric',
|
||||
'Turbo124\Beacon\Jobs\System\HdMetric',
|
||||
'Turbo124\Beacon\Jobs\System\MemMetric',
|
||||
],
|
||||
|
||||
];
|
223
package-lock.json
generated
223
package-lock.json
generated
@ -6188,6 +6188,54 @@
|
||||
"find-up": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"pkg-up": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
|
||||
"integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=",
|
||||
"requires": {
|
||||
"find-up": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"find-up": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
|
||||
"integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
|
||||
"requires": {
|
||||
"locate-path": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
|
||||
"integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
|
||||
"requires": {
|
||||
"p-locate": "^2.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
|
||||
"integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
|
||||
"requires": {
|
||||
"p-try": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
|
||||
"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
|
||||
"requires": {
|
||||
"p-limit": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
|
||||
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
|
||||
}
|
||||
}
|
||||
},
|
||||
"portfinder": {
|
||||
"version": "1.0.25",
|
||||
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz",
|
||||
@ -8219,13 +8267,16 @@
|
||||
}
|
||||
},
|
||||
"tailwindcss": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.2.0.tgz",
|
||||
"integrity": "sha512-CKvY0ytB3ze5qvynG7qv4XSpQtFNGPbu9pUn8qFdkqgD8Yo/vGss8mhzbqls44YCXTl4G62p3qVZBj45qrd6FQ==",
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.4.5.tgz",
|
||||
"integrity": "sha512-MJW96Rz3G3RrFDbDuQCU893y4bf5hMWeVbMgcCqUfLNPbO9wRogDibCEvdKitD6aX9Y90SDT2FOKD17+WmIFLQ==",
|
||||
"requires": {
|
||||
"@fullhuman/postcss-purgecss": "^2.1.2",
|
||||
"autoprefixer": "^9.4.5",
|
||||
"browserslist": "^4.12.0",
|
||||
"bytes": "^3.0.0",
|
||||
"chalk": "^3.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"color": "^3.1.2",
|
||||
"detective": "^5.2.0",
|
||||
"fs-extra": "^8.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
@ -8241,22 +8292,94 @@
|
||||
"resolve": "^1.14.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"@fullhuman/postcss-purgecss": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-2.2.0.tgz",
|
||||
"integrity": "sha512-q4zYAn8L9olA5uneaLhxkHRBoug9dnAqytbdX9R5dbzSORobhYr1yGR2JN3Q1UMd5RB0apm1NvJekHaymal/BQ==",
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
"postcss": "7.0.28",
|
||||
"purgecss": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"version": "7.0.28",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.28.tgz",
|
||||
"integrity": "sha512-YU6nVhyWIsVtlNlnAj1fHTsUKW5qxm3KEgzq2Jj6KTEFOTK8QWR12eIDvrlWhiSTK8WIBFTBhOJV4DY6dUuEbw==",
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"source-map": "^0.6.1",
|
||||
"supports-color": "^6.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
|
||||
"integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==",
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001043",
|
||||
"electron-to-chromium": "^1.3.413",
|
||||
"node-releases": "^1.1.53",
|
||||
"pkg-up": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001053",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001053.tgz",
|
||||
"integrity": "sha512-HtV4wwIZl6GA4Oznse8aR274XUOYGZnQLcf/P8vHgmlfqSNelwD+id8CyHOceqLqt9yfKmo7DUZTh1EuS9pukg=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
|
||||
"integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
@ -8272,6 +8395,16 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"commander": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
|
||||
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.430",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.430.tgz",
|
||||
"integrity": "sha512-HMDYkANGhx6vfbqpOf/hc6hWEmiOipOHGDeRDeUb3HLD3XIWpvKQxFgWf0tgHcr3aNv6I/8VPecplqmQsXoZSw=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
@ -8282,17 +8415,65 @@
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
"node-releases": {
|
||||
"version": "1.1.55",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.55.tgz",
|
||||
"integrity": "sha512-H3R3YR/8TjT5WPin/wOoHOUPHgvj8leuU/Keta/rwelEQN9pA/S2Dx8/se4pZ2LBxSd0nAGzsNzhqwa77v7F1w=="
|
||||
},
|
||||
"purgecss": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-2.2.1.tgz",
|
||||
"integrity": "sha512-wngRSLW1dpNr8kr3TL9nTJMyTFI5BiRiaUUEys5M1CA4zEHLF25fRHoshEeDqmhstaNTOddmpYM34zRrUtEGbQ==",
|
||||
"requires": {
|
||||
"commander": "^5.0.0",
|
||||
"glob": "^7.0.0",
|
||||
"postcss": "7.0.28",
|
||||
"postcss-selector-parser": "^6.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"version": "7.0.28",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.28.tgz",
|
||||
"integrity": "sha512-YU6nVhyWIsVtlNlnAj1fHTsUKW5qxm3KEgzq2Jj6KTEFOTK8QWR12eIDvrlWhiSTK8WIBFTBhOJV4DY6dUuEbw==",
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"source-map": "^0.6.1",
|
||||
"supports-color": "^6.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
|
||||
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,16 +156,18 @@ class DesignTest extends TestCase
|
||||
|
||||
public function testAllDesigns()
|
||||
{
|
||||
for ($x=1; $x<=10; $x++) {
|
||||
$settings = $this->invoice->client->settings;
|
||||
$settings->quote_design_id = (string)$this->encodePrimaryKey($x);
|
||||
$settings->all_pages_header = true;
|
||||
$settings->all_pages_footer = true;
|
||||
|
||||
$this->quote->client_id = $this->client->id;
|
||||
$this->quote->setRelation('client', $this->client);
|
||||
$this->quote->save();
|
||||
|
||||
|
||||
for ($x=1; $x<=10; $x++) {
|
||||
|
||||
$settings = $this->invoice->client->settings;
|
||||
$settings->quote_design_id = (string)$this->encodePrimaryKey($x);
|
||||
$settings->all_pages_header = true;
|
||||
$settings->all_pages_footer = true;
|
||||
$this->client->settings = $settings;
|
||||
$this->client->save();
|
||||
|
||||
@ -179,7 +181,9 @@ class DesignTest extends TestCase
|
||||
CreateQuotePdf::dispatchNow($invitation);
|
||||
|
||||
$this->quote->number = $this->getNextQuoteNumber($this->quote->client);
|
||||
$this->quote->save();
|
||||
|
||||
// $this->quote->save();
|
||||
|
||||
}
|
||||
|
||||
$this->assertTrue(true);
|
||||
|
49
tests/Unit/CloneQuoteToInvoiceFactoryTest.php
Normal file
49
tests/Unit/CloneQuoteToInvoiceFactoryTest.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\InvoiceItemFactory;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
class CloneQuoteToInvoiceFactoryTest extends TestCase
|
||||
{
|
||||
use MockAccountData;
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->makeTestData();
|
||||
|
||||
}
|
||||
|
||||
public function testCloneProperties()
|
||||
{
|
||||
|
||||
$invoice = CloneQuoteToInvoiceFactory::create($this->quote, $this->quote->user_id);
|
||||
|
||||
$this->assertNull($invoice->due_date);
|
||||
$this->assertNull($invoice->partial_due_date);
|
||||
$this->assertNull($invoice->number);
|
||||
|
||||
}
|
||||
|
||||
public function testQuoteToInvoiceConversionService()
|
||||
{
|
||||
$invoice = $this->quote->service()->convertToInvoice();
|
||||
|
||||
$this->assertTrue($invoice instanceof Invoice);
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user