Wiring up verifactu sending
This commit is contained in:
parent
3d3b5f6938
commit
c5c9c4325e
|
|
@ -39,13 +39,13 @@ class VerifactuAmountCheck implements ValidationRule
|
|||
|
||||
$company = $user->company();
|
||||
|
||||
if ($company->verifactuEnabled()) {
|
||||
if ($company->verifactuEnabled()) { // Company level check if Verifactu is enabled
|
||||
|
||||
$client = Client::withTrashed()->find($this->input['client_id']);
|
||||
|
||||
if($client->country->iso_3166_2 !== 'ES') {
|
||||
if($client->country->iso_3166_2 !== 'ES') { // Client level check if client is in Spain
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$invoice = false;
|
||||
$child_invoices = false;
|
||||
|
|
|
|||
|
|
@ -278,6 +278,14 @@ class Activity extends StaticModel
|
|||
public const E_EXPENSE_CREATED = 148;
|
||||
|
||||
public const EMAIL_CREDIT = 149;
|
||||
|
||||
public const VERIFACTU_INVOICE_SENT = 150;
|
||||
|
||||
public const VERIFACTU_INVOICE_SENT_FAILURE = 151;
|
||||
|
||||
public const VERIFACTU_CANCELLATION_SENT = 152;
|
||||
|
||||
public const VERIFACTU_CANCELLATION_SENT_FAILURE = 153;
|
||||
|
||||
protected $casts = [
|
||||
'is_system' => 'boolean',
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ class SystemLog extends Model
|
|||
|
||||
public const CATEGORY_LOG = 6;
|
||||
|
||||
public const CATEGORY_VERIFACTU = 7;
|
||||
|
||||
/* Event IDs*/
|
||||
public const EVENT_PAYMENT_RECONCILIATION_FAILURE = 10;
|
||||
|
||||
|
|
@ -115,6 +117,10 @@ class SystemLog extends Model
|
|||
|
||||
public const EVENT_INBOUND_MAIL_BLOCKED = 62;
|
||||
|
||||
public const EVENT_VERIFACTU_FAILURE = 70;
|
||||
|
||||
public const EVENT_VERIFACTU_SUCCESS = 71;
|
||||
|
||||
/*Type IDs*/
|
||||
public const TYPE_PAYPAL = 300;
|
||||
|
||||
|
|
@ -180,6 +186,12 @@ class SystemLog extends Model
|
|||
|
||||
public const TYPE_GENERIC = 900;
|
||||
|
||||
public const TYPE_VERIFACTU_CANCELLATION = 1000;
|
||||
|
||||
public const TYPE_VERIFACTU_INVOICE = 1001;
|
||||
|
||||
public const TYPE_VERIFACTU_RECTIFICATION = 1002;
|
||||
|
||||
protected $fillable = [
|
||||
'client_id',
|
||||
'company_id',
|
||||
|
|
|
|||
|
|
@ -15,12 +15,16 @@ use Mail;
|
|||
use App\Utils\Ninja;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Activity;
|
||||
use App\Models\SystemLog;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Repositories\ActivityRepository;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
|
@ -63,16 +67,13 @@ class SendToAeat implements ShouldQueue
|
|||
return [5, 30, 240, 3600, 7200];
|
||||
}
|
||||
|
||||
public function handle()
|
||||
public function handle(ActivityRepository $activity_repository)
|
||||
{
|
||||
MultiDB::setDB($this->company->db);
|
||||
|
||||
$invoice = Invoice::withTrashed()->find($this->invoice_id);
|
||||
|
||||
switch($this->action) {
|
||||
case 'modify':
|
||||
$this->modifyInvoice($invoice);
|
||||
break;
|
||||
case 'create':
|
||||
$this->createInvoice($invoice);
|
||||
break;
|
||||
|
|
@ -92,27 +93,7 @@ class SendToAeat implements ShouldQueue
|
|||
* @param Invoice $invoice
|
||||
* @return void
|
||||
*/
|
||||
public function modifyInvoice(Invoice $invoice)
|
||||
{
|
||||
|
||||
$verifactu = new Verifactu($invoice);
|
||||
$verifactu->run();
|
||||
|
||||
$envelope = $verifactu->getEnvelope();
|
||||
|
||||
$response = $verifactu->send($envelope);
|
||||
|
||||
nlog($response);
|
||||
|
||||
// if($invoice->amount >= 0) {
|
||||
// $document = (new RegistroAlta($invoice))->run()->getInvoice();
|
||||
// }
|
||||
// else {
|
||||
// $document = (new RegistroRectificacion($invoice))->run()->getInvoice();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function createInvoice(Invoice $invoice)
|
||||
{
|
||||
$verifactu = new Verifactu($invoice);
|
||||
|
|
@ -124,6 +105,9 @@ class SendToAeat implements ShouldQueue
|
|||
|
||||
nlog($response);
|
||||
|
||||
$this->writeActivity($invoice, $response['success'] ? Activity::VERIFACTU_INVOICE_SENT : Activity::VERIFACTU_INVOICE_SENT_FAILURE, $response['message']);
|
||||
$this->systemLog($invoice, $response, $response['success'] ? SystemLog::EVENT_VERIFACTU_SUCCESS : SystemLog::EVENT_VERIFACTU_FAILURE, SystemLog::TYPE_VERIFACTU_INVOICE);
|
||||
|
||||
}
|
||||
|
||||
public function cancelInvoice(Invoice $invoice)
|
||||
|
|
@ -153,12 +137,15 @@ class SendToAeat implements ShouldQueue
|
|||
$parent->saveQuietly();
|
||||
}
|
||||
}
|
||||
|
||||
//@todo - verifactu logging
|
||||
$this->writeActivity($invoice, $response['success'] ? Activity::VERIFACTU_CANCELLATION_SENT : Activity::VERIFACTU_CANCELLATION_SENT_FAILURE, $response['message']);
|
||||
$this->systemLog($invoice, $response, $response['success'] ? SystemLog::EVENT_VERIFACTU_SUCCESS : SystemLog::EVENT_VERIFACTU_FAILURE, SystemLog::TYPE_VERIFACTU_CANCELLATION);
|
||||
}
|
||||
|
||||
public function middleware()
|
||||
{
|
||||
return [new WithoutOverlapping("send_to_aeat_{$this->company->company_key}")];
|
||||
return [(new WithoutOverlapping("send_to_aeat_{$this->company->company_key}"))->releaseAfter(30)->expireAfter(30)];
|
||||
}
|
||||
|
||||
public function failed($exception = null)
|
||||
|
|
@ -166,7 +153,34 @@ class SendToAeat implements ShouldQueue
|
|||
nlog($exception);
|
||||
}
|
||||
|
||||
private function writeActivity(Invoice $invoice, int $activity_id, string $notes = ''): void
|
||||
{
|
||||
$activity = new Activity();
|
||||
$activity->user_id = $invoice->user_id;
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->company_id = $invoice->company_id;
|
||||
$activity->account_id = $invoice->company->account_id;
|
||||
$activity->activity_type_id = $activity_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->notes = str_replace('"', '', $notes);
|
||||
$activity->is_system = true;
|
||||
|
||||
$activity->save();
|
||||
|
||||
}
|
||||
|
||||
private function systemLog(Invoice $invoice, array $data, int $event_id, int $type_id): void
|
||||
{
|
||||
(new SystemLogger(
|
||||
$data,
|
||||
SystemLog::CATEGORY_VERIFACTU,
|
||||
$event_id,
|
||||
$type_id,
|
||||
$invoice->client,
|
||||
$invoice->company
|
||||
)
|
||||
)->handle();
|
||||
}
|
||||
|
||||
/**
|
||||
* cancellationHash
|
||||
|
|
|
|||
|
|
@ -76,39 +76,56 @@ class HandleCancellation extends AbstractService
|
|||
private function verifactuCancellation(): Invoice
|
||||
{
|
||||
|
||||
$replicated_invoice = $this->invoice->replicate();
|
||||
|
||||
$this->invoice = $this->invoice->service()->setStatus(Invoice::STATUS_CANCELLED)->save();
|
||||
$this->invoice->service()->workFlow()->save();
|
||||
|
||||
$replicated_invoice->status_id = Invoice::STATUS_DRAFT;
|
||||
$replicated_invoice->date = now()->format('Y-m-d');
|
||||
$replicated_invoice->due_date = null;
|
||||
$replicated_invoice->partial = 0;
|
||||
$replicated_invoice->partial_due_date = null;
|
||||
$replicated_invoice->number = null;
|
||||
$replicated_invoice->amount = 0;
|
||||
$replicated_invoice->balance = 0;
|
||||
$replicated_invoice->paid_to_date = 0;
|
||||
// R2 Cancellation - do not create a separate document
|
||||
if($this->invoice->backup->document_type === 'R2'){
|
||||
|
||||
$items = $replicated_invoice->line_items;
|
||||
$parent = Invoice::withTrashed()->find($this->decodePrimaryKey($this->invoice->backup->parent_invoice_id));
|
||||
|
||||
foreach($items as &$item) {
|
||||
$item->quantity = $item->quantity * -1;
|
||||
if(!$parent) {
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
$parent->backup->adjustable_amount -= $this->invoice->amount;
|
||||
$parent->backup->child_invoice_ids->reject(fn($id) => $id === $this->invoice->hashed_id);
|
||||
$parent->save();
|
||||
|
||||
$this->invoice->service()->cancelVerifactu();
|
||||
}
|
||||
else {
|
||||
$replicated_invoice = $this->invoice->replicate();
|
||||
$replicated_invoice->status_id = Invoice::STATUS_DRAFT;
|
||||
$replicated_invoice->date = now()->format('Y-m-d');
|
||||
$replicated_invoice->due_date = null;
|
||||
$replicated_invoice->partial = 0;
|
||||
$replicated_invoice->partial_due_date = null;
|
||||
$replicated_invoice->number = null;
|
||||
$replicated_invoice->amount = 0;
|
||||
$replicated_invoice->balance = 0;
|
||||
$replicated_invoice->paid_to_date = 0;
|
||||
|
||||
$items = $replicated_invoice->line_items;
|
||||
|
||||
foreach($items as &$item) {
|
||||
$item->quantity = $item->quantity * -1;
|
||||
}
|
||||
|
||||
$replicated_invoice->line_items = $items;
|
||||
$replicated_invoice->backup->parent_invoice_id = $this->invoice->hashed_id;
|
||||
$replicated_invoice->backup->parent_invoice_number = $this->invoice->number;
|
||||
$replicated_invoice->backup->document_type = 'R2'; // Full Credit Note Generated for the invoice
|
||||
|
||||
$invoice_repository = new InvoiceRepository();
|
||||
$replicated_invoice = $invoice_repository->save([], $replicated_invoice);
|
||||
$replicated_invoice->service()->markSent()->sendVerifactu()->save();
|
||||
|
||||
$this->invoice->backup->child_invoice_ids->push($replicated_invoice->hashed_id);
|
||||
|
||||
$this->invoice->saveQuietly();
|
||||
}
|
||||
|
||||
$replicated_invoice->line_items = $items;
|
||||
$replicated_invoice->backup->parent_invoice_id = $this->invoice->hashed_id;
|
||||
$replicated_invoice->backup->parent_invoice_number = $this->invoice->number;
|
||||
$replicated_invoice->backup->document_type = 'R2'; // Full Credit Note Generated for the invoice
|
||||
|
||||
$invoice_repository = new InvoiceRepository();
|
||||
$replicated_invoice = $invoice_repository->save([], $replicated_invoice);
|
||||
$replicated_invoice->service()->markSent()->sendVerifactu()->save();
|
||||
|
||||
$this->invoice->backup->child_invoice_ids->push($replicated_invoice->hashed_id);
|
||||
|
||||
$this->invoice->saveQuietly();
|
||||
$this->invoice->fresh();
|
||||
|
||||
event(new InvoiceWasCancelled($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use Illuminate\Support\Facades\Storage;
|
|||
use App\Events\Invoice\InvoiceWasArchived;
|
||||
use App\Jobs\Inventory\AdjustProductInventory;
|
||||
use App\Libraries\Currency\Conversion\CurrencyApi;
|
||||
use App\Services\EDocument\Standards\Verifactu\SendToAeat;
|
||||
|
||||
class InvoiceService
|
||||
{
|
||||
|
|
@ -248,7 +249,7 @@ class InvoiceService
|
|||
$this->invoice = (new MarkInvoiceDeleted($this->invoice))->run();
|
||||
|
||||
if($this->invoice->company->verifactuEnabled()) {
|
||||
$this->deleteVerifactu();
|
||||
$this->cancelVerifactu();
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
@ -680,31 +681,24 @@ class InvoiceService
|
|||
|
||||
/**
|
||||
* sendVerifactu
|
||||
* @todo - send the invoice to AEAT
|
||||
* ONLY send when the transaction is ES => ES
|
||||
* Ensure we run all sending syncronously to ensure chronology
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function sendVerifactu(): self
|
||||
{
|
||||
// if($this->invoice->company->verifactuEnabled()) {
|
||||
// (new SendVerifactu($this->invoice))->handle();
|
||||
// }
|
||||
|
||||
SendToAeat::dispatch($this->invoice->id, $this->invoice->company, 'create');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* deleteVerifactu
|
||||
* @todo - handle "cancelling" the invoice in AEAT
|
||||
* cancelVerifactu
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function deleteVerifactu(): self
|
||||
public function cancelVerifactu(): self
|
||||
{
|
||||
// if($this->invoice->company->verifactuEnabled()) {
|
||||
// (new DeleteVerifactu($this->invoice))->handle();
|
||||
// }
|
||||
SendToAeat::dispatch($this->invoice->id, $this->invoice->company, 'cancel');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5576,6 +5576,10 @@ $lang = array(
|
|||
'restore_disabled_verifactu' => 'You cannot restore an invoice once it has been deleted',
|
||||
'delete_disabled_verifactu' => 'You cannot delete an invoice once it has been cancelled or modified',
|
||||
'rectify' => 'Rectificar',
|
||||
'verifactu_invoice_send_success' => 'Invoice :invoice for :client sent to AEAT successfully',
|
||||
'verifactu_invoice_sent_failure' => 'Invoice :invoice for :client failed to send to AEAT :notes',
|
||||
'verifactu_cancellation_send_success' => 'Invoice cancellation for :invoice sent to AEAT successfully',
|
||||
'verifactu_cancellation_send_failure' => 'Invoice cancellation for :invoice failed to send to AEAT :notes',
|
||||
);
|
||||
|
||||
return $lang;
|
||||
|
|
|
|||
Loading…
Reference in New Issue