mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-30 22:54:32 -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\InvoiceSum;
|
||||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||||
use App\Models\Filterable;
|
use App\Models\Filterable;
|
||||||
|
use App\Services\Quote\QuoteService;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -23,7 +24,7 @@ class Quote extends BaseModel
|
|||||||
use MakesHash;
|
use MakesHash;
|
||||||
use Filterable;
|
use Filterable;
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'number',
|
'number',
|
||||||
'discount',
|
'discount',
|
||||||
@ -59,7 +60,7 @@ class Quote extends BaseModel
|
|||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
];
|
];
|
||||||
|
|
||||||
const STATUS_DRAFT = 1;
|
const STATUS_DRAFT = 1;
|
||||||
const STATUS_SENT = 2;
|
const STATUS_SENT = 2;
|
||||||
const STATUS_APPROVED = 3;
|
const STATUS_APPROVED = 3;
|
||||||
@ -84,7 +85,7 @@ class Quote extends BaseModel
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
|
return $this->belongsTo(User::class, 'assigned_user_id', 'id')->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function invitations()
|
public function invitations()
|
||||||
{
|
{
|
||||||
return $this->hasMany(QuoteInvitation::class);
|
return $this->hasMany(QuoteInvitation::class);
|
||||||
@ -112,4 +113,23 @@ class Quote extends BaseModel
|
|||||||
|
|
||||||
return $quote_calc->build();
|
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