mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Ft quote services (#3310)
* Quote service * convert quote * Update Quote.php * Update Quote.php * Update MarkApproved.php
This commit is contained in:
parent
c6216fb128
commit
dee99b1a62
31
app/Events/Quote/QuoteWasMarkedApproved.php
Normal file
31
app/Events/Quote/QuoteWasMarkedApproved.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace App\Events\Quote;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Quote;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class InvoiceWasMarkedSent.
|
||||
*/
|
||||
class QuoteWasMarkedApproved
|
||||
{
|
||||
use SerializesModels;
|
||||
/**
|
||||
* @var Quote
|
||||
*/
|
||||
public $quote;
|
||||
|
||||
public $company;
|
||||
|
||||
/**
|
||||
* QuoteWasMarkedApproved constructor.
|
||||
* @param Quote $quote
|
||||
* @param Company $company
|
||||
*/
|
||||
public function __construct(Quote $quote, Company $company)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
$this->company = $company;
|
||||
}
|
||||
}
|
30
app/Events/Quote/QuoteWasMarkedSent.php
Normal file
30
app/Events/Quote/QuoteWasMarkedSent.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace App\Events\Quote;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Quote;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class InvoiceWasMarkedSent.
|
||||
*/
|
||||
class QuoteWasMarkedSent
|
||||
{
|
||||
use SerializesModels;
|
||||
/**
|
||||
* @var Invoice
|
||||
*/
|
||||
public $quote;
|
||||
public $company;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param Quote $quote
|
||||
*/
|
||||
public function __construct(Quote $quote, Company $company)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
$this->company = $company;
|
||||
}
|
||||
}
|
19
app/Factory/CloneQuoteToInvoiceFactory.php
Normal file
19
app/Factory/CloneQuoteToInvoiceFactory.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Quote;
|
||||
|
||||
class CloneQuoteToInvoiceFactory
|
||||
{
|
||||
public function create(Quote $quote, $user_id, $company_id) : ?Invoice
|
||||
{
|
||||
$invoice = new Invoice();
|
||||
$invoice->company_id = $company_id;
|
||||
$invoice->client_id = $quote->client_id;
|
||||
$invoice->user_id = $user_id;
|
||||
$invoice->po_number = $quote->po_number;
|
||||
$invoice->footer = $quote->footer;
|
||||
return $invoice;
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ namespace App\Models;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||
use App\Models\Filterable;
|
||||
use App\Services\Quote\QuoteService;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -23,7 +24,7 @@ class Quote extends BaseModel
|
||||
use MakesHash;
|
||||
use Filterable;
|
||||
use SoftDeletes;
|
||||
|
||||
|
||||
protected $fillable = [
|
||||
'number',
|
||||
'discount',
|
||||
@ -59,7 +60,7 @@ class Quote extends BaseModel
|
||||
'created_at' => 'timestamp',
|
||||
'deleted_at' => 'timestamp',
|
||||
];
|
||||
|
||||
|
||||
const STATUS_DRAFT = 1;
|
||||
const STATUS_SENT = 2;
|
||||
const STATUS_APPROVED = 3;
|
||||
@ -84,7 +85,7 @@ class Quote extends BaseModel
|
||||
{
|
||||
return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
|
||||
}
|
||||
|
||||
|
||||
public function invitations()
|
||||
{
|
||||
return $this->hasMany(QuoteInvitation::class);
|
||||
@ -112,4 +113,23 @@ class Quote extends BaseModel
|
||||
|
||||
return $quote_calc->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Invites to SENT
|
||||
*
|
||||
*/
|
||||
public function markInvitationsSent()
|
||||
{
|
||||
$this->invitations->each(function ($invitation) {
|
||||
if (!isset($invitation->sent_date)) {
|
||||
$invitation->sent_date = Carbon::now();
|
||||
$invitation->save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function service(): QuoteService
|
||||
{
|
||||
return new QuoteService($this);
|
||||
}
|
||||
}
|
||||
|
41
app/Services/Quote/ApplyNumber.php
Normal file
41
app/Services/Quote/ApplyNumber.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Models\Quote;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
|
||||
class ApplyNumber
|
||||
{
|
||||
use GeneratesCounter;
|
||||
|
||||
private $client;
|
||||
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function __invoke($quote)
|
||||
{
|
||||
|
||||
if ($quote->number != '')
|
||||
return $quote;
|
||||
|
||||
switch ($this->client->getSetting('counter_number_applied')) {
|
||||
case 'when_saved':
|
||||
$quote->number = $this->getNextQuoteNumber($this->client);
|
||||
break;
|
||||
case 'when_sent':
|
||||
if ($quote->status_id == Quote::STATUS_SENT) {
|
||||
$quote->number = $this->getNextQuoteNumber($this->client);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
|
||||
return $quote;
|
||||
}
|
||||
}
|
31
app/Services/Quote/ConvertQuote.php
Normal file
31
app/Services/Quote/ConvertQuote.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||
use App\Quote;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
|
||||
class ConvertQuote
|
||||
{
|
||||
private $client;
|
||||
private $invoice_repo;
|
||||
|
||||
public function __construct($client, InvoiceRepository $invoice_repo)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->invoice_repo = $invoice_repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $quote
|
||||
* @return mixed
|
||||
*/
|
||||
public function __invoke($quote)
|
||||
{
|
||||
$invoice = CloneQuoteToInvoiceFactory::create($quote, $quote->user_id, $quote->company_id);
|
||||
$this->invoice_repo->save([], $invoice);
|
||||
|
||||
// maybe should return invoice here
|
||||
return $quote;
|
||||
}
|
||||
}
|
37
app/Services/Quote/CreateInvitations.php
Normal file
37
app/Services/Quote/CreateInvitations.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Factory\QuoteInvitationFactory;
|
||||
use App\Models\QuoteInvitation;
|
||||
|
||||
class CreateInvitations
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function __invoke($quote)
|
||||
{
|
||||
|
||||
$contacts = $quote->client->contacts;
|
||||
|
||||
$contacts->each(function ($contact) use($quote){
|
||||
$invitation = QuoteInvitation::whereCompanyId($quote->company_id)
|
||||
->whereClientContactId($contact->id)
|
||||
->whereQuoteId($quote->id)
|
||||
->first();
|
||||
|
||||
if (!$invitation && $contact->send_quote) {
|
||||
$ii = QuoteInvitationFactory::create($quote->company_id, $quote->user_id);
|
||||
$ii->quote_id = $quote->id;
|
||||
$ii->client_contact_id = $contact->id;
|
||||
$ii->save();
|
||||
} elseif ($invitation && !$contact->send_quote) {
|
||||
$invitation->delete();
|
||||
}
|
||||
});
|
||||
|
||||
return $quote;
|
||||
}
|
||||
}
|
30
app/Services/Quote/MarkApproved.php
Normal file
30
app/Services/Quote/MarkApproved.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Events\Quote\QuoteWasMarkedApproved;
|
||||
use App\Models\Quote;
|
||||
|
||||
class MarkApproved
|
||||
{
|
||||
private $client;
|
||||
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function __invoke($quote)
|
||||
{
|
||||
/* Return immediately if status is not draft */
|
||||
if ($quote->status_id != Quote::STATUS_SENT) {
|
||||
return $quote;
|
||||
}
|
||||
|
||||
$quote->service()->setStatus(Quote::STATUS_APPROVED)->applyNumber()->save();
|
||||
|
||||
event(new QuoteWasMarkedApproved($quote, $quote->company));
|
||||
|
||||
return $quote;
|
||||
}
|
||||
}
|
34
app/Services/Quote/MarkSent.php
Normal file
34
app/Services/Quote/MarkSent.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Events\Quote\QuoteWasMarkedSent;
|
||||
use App\Models\Quote;
|
||||
|
||||
class MarkSent
|
||||
{
|
||||
private $client;
|
||||
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function __invoke($quote)
|
||||
{
|
||||
|
||||
/* Return immediately if status is not draft */
|
||||
if ($quote->status_id != Quote::STATUS_DRAFT) {
|
||||
return $quote;
|
||||
}
|
||||
|
||||
$quote->markInvitationsSent();
|
||||
|
||||
event(new QuoteWasMarkedSent($quote, $quote->company));
|
||||
|
||||
$quote->service()->setStatus(Quote::STATUS_SENT)->applyNumber()->save();
|
||||
|
||||
return $quote;
|
||||
|
||||
}
|
||||
}
|
76
app/Services/Quote/QuoteService.php
Normal file
76
app/Services/Quote/QuoteService.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace App\Services\Quote;
|
||||
|
||||
use App\Models\Quote;
|
||||
|
||||
class QuoteService
|
||||
{
|
||||
protected $quote;
|
||||
|
||||
public function __construct($quote)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
}
|
||||
|
||||
public function createInvitations()
|
||||
{
|
||||
$create_invitation = new CreateInvitations();
|
||||
|
||||
$this->quote = $create_invitation($this->quote);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function markApproved()
|
||||
{
|
||||
$mark_approved = new MarkApproved($this->quote->client);
|
||||
|
||||
$this->quote = $mark_approved($this->quote);
|
||||
|
||||
if($this->quote->client->getSetting('auto_convert_quote') === true) {
|
||||
$convert_quote = new ConvertQuote($this->quote->client);
|
||||
$this->quote = $convert_quote($this->quote);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the invoice number
|
||||
* @return $this InvoiceService object
|
||||
*/
|
||||
public function applyNumber()
|
||||
{
|
||||
$apply_number = new ApplyNumber($this->quote->client);
|
||||
|
||||
$this->quote = $apply_number($this->quote);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function markSent()
|
||||
{
|
||||
$mark_sent = new MarkSent($this->quote->client);
|
||||
|
||||
$this->quote = $mark_sent($this->quote);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStatus($status)
|
||||
{
|
||||
$this->quote->status_id = $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the quote
|
||||
* @return Quote|null
|
||||
*/
|
||||
public function save() : ?Quote
|
||||
{
|
||||
$this->quote->save();
|
||||
return $this->quote;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user