Refactor to use generate parent/child ids
This commit is contained in:
parent
8d23ba14d4
commit
c7e79fe673
|
|
@ -18,6 +18,7 @@ use Illuminate\Validation\Rule;
|
|||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Http\ValidationRules\Project\ValidProjectForClient;
|
||||
use App\Http\ValidationRules\Invoice\CanGenerateModificationInvoice;
|
||||
use App\Http\ValidationRules\Invoice\VerifactuAmountCheck;
|
||||
|
||||
class StoreInvoiceRequest extends Request
|
||||
{
|
||||
|
|
@ -45,7 +46,7 @@ class StoreInvoiceRequest extends Request
|
|||
|
||||
$rules = [];
|
||||
|
||||
$rules['client_id'] = ['required', 'bail', Rule::exists('clients', 'id')->where('company_id', $user->company()->id)->where('is_deleted', 0)];
|
||||
$rules['client_id'] = ['required', 'bail', new VerifactuAmountCheck($this->all()) , Rule::exists('clients', 'id')->where('company_id', $user->company()->id)->where('is_deleted', 0)];
|
||||
|
||||
if ($this->file('documents') && is_array($this->file('documents'))) {
|
||||
$rules['documents.*'] = $this->fileValidation();
|
||||
|
|
@ -72,7 +73,7 @@ class StoreInvoiceRequest extends Request
|
|||
$rules['date'] = 'bail|sometimes|date:Y-m-d';
|
||||
$rules['due_date'] = ['bail', 'sometimes', 'nullable', 'after:partial_due_date', Rule::requiredIf(fn () => strlen($this->partial_due_date ?? '') > 1), 'date'];
|
||||
|
||||
$rules['line_items'] = 'array';
|
||||
$rules['line_items'] = ['bail', 'array'];
|
||||
$rules['discount'] = 'sometimes|numeric|max:99999999999999';
|
||||
$rules['tax_rate1'] = 'bail|sometimes|numeric';
|
||||
$rules['tax_rate2'] = 'bail|sometimes|numeric';
|
||||
|
|
|
|||
|
|
@ -61,6 +61,18 @@ class HandleCancellation extends AbstractService
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* verifactuCancellation
|
||||
* @todo we must ensure that if there have been previous credit notes attached to the invoice,
|
||||
* that the credit notes are not exceeded by the cancellation amount.
|
||||
* This is because the credit notes are not linked to the invoice, but are linked to the
|
||||
* invoice's backup.
|
||||
* So we need to check the backup for the credit notes and ensure that the cancellation amount
|
||||
* does not exceed the credit notes.
|
||||
* If it does, we need to create a new credit note with the remaining amount.
|
||||
* This is because the credit notes are not linked to the invoice, but are linked to the
|
||||
* @return Invoice
|
||||
*/
|
||||
private function verifactuCancellation(): Invoice
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,305 @@ class VerifactuApiTest extends TestCase
|
|||
|
||||
}
|
||||
|
||||
public function test_credits_never_exceed_original_invoice7()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
$this->assertEquals(121, $invoice->amount);
|
||||
|
||||
|
||||
$data = $invoice->toArray();
|
||||
unset($data['client']);
|
||||
unset($data['invitations']);
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
$data['verifactu_modified'] = true;
|
||||
$data['modified_invoice_id'] = $invoice->hashed_id;
|
||||
$data['number'] = null;
|
||||
$data['discount'] = 120;
|
||||
$data['is_amount_discount'] = true;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function test_credits_never_exceed_original_invoice6()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
$this->assertEquals(121, $invoice->amount);
|
||||
|
||||
$invoice->line_items = [[
|
||||
'quantity' => -1,
|
||||
'cost' => 10,
|
||||
'discount' => 0,
|
||||
'tax_rate1' => 21,
|
||||
'tax_name1' => 'IVA',
|
||||
]];
|
||||
|
||||
$invoice->discount = 0;
|
||||
$invoice->is_amount_discount = false;
|
||||
|
||||
$data = $invoice->toArray();
|
||||
unset($data['client']);
|
||||
unset($data['invitations']);
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
$data['verifactu_modified'] = true;
|
||||
$data['modified_invoice_id'] = $invoice->hashed_id;
|
||||
$data['number'] = null;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function test_credits_never_exceed_original_invoice5()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
$this->assertEquals(121, $invoice->amount);
|
||||
|
||||
$invoice->line_items = [[
|
||||
'quantity' => -5,
|
||||
'cost' => 100,
|
||||
'discount' => 0,
|
||||
'tax_rate1' => 21,
|
||||
'tax_name1' => 'IVA',
|
||||
]];
|
||||
|
||||
$invoice->discount = 0;
|
||||
$invoice->is_amount_discount = false;
|
||||
|
||||
$data = $invoice->toArray();
|
||||
unset($data['client']);
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
$data['verifactu_modified'] = true;
|
||||
$data['modified_invoice_id'] = $invoice->hashed_id;
|
||||
$data['number'] = null;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
|
||||
$response->assertStatus(422);
|
||||
}
|
||||
|
||||
public function test_credits_never_exceed_original_invoice4()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
$this->assertEquals(121, $invoice->amount);
|
||||
|
||||
$data = $invoice->toArray();
|
||||
|
||||
unset($data['client']);
|
||||
unset($data['company']);
|
||||
unset($data['invitations']);
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
$data['verifactu_modified'] = true;
|
||||
$data['modified_invoice_id'] = $invoice->hashed_id;
|
||||
$data['number'] = null;
|
||||
$data['line_items'] = [[
|
||||
'quantity' => -1,
|
||||
'cost' => 100,
|
||||
'discount' => 0,
|
||||
'tax_rate1' => 21,
|
||||
'tax_name1' => 'IVA',
|
||||
]];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
|
||||
public function test_credits_never_exceed_original_invoice3()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
$invoice->line_items = [];
|
||||
$invoice->discount = 500;
|
||||
$invoice->is_amount_discount = false;
|
||||
|
||||
$data = $invoice->toArray();
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
$data['verifactu_modified'] = true;
|
||||
$data['modified_invoice_id'] = $invoice->hashed_id;
|
||||
$data['number'] = null;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(422);
|
||||
}
|
||||
|
||||
public function test_credits_never_exceed_original_invoice2()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
$invoice->line_items = [];
|
||||
|
||||
$invoice->discount = 500;
|
||||
$invoice->is_amount_discount = false;
|
||||
|
||||
$data = $invoice->toArray();
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
$data['verifactu_modified'] = true;
|
||||
$data['modified_invoice_id'] = $invoice->hashed_id;
|
||||
$data['number'] = null;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(422);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function test_credits_never_exceed_original_invoice()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
// $invoice->line_items = [];
|
||||
$invoice->discount = 5;
|
||||
$invoice->is_amount_discount = false;
|
||||
|
||||
$data = $invoice->toArray();
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
$data['verifactu_modified'] = true;
|
||||
$data['modified_invoice_id'] = $invoice->hashed_id;
|
||||
$data['number'] = null;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function test_verifactu_amount_check()
|
||||
{
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->e_invoice_type = 'verifactu';
|
||||
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$invoice = $this->buildData();
|
||||
$invoice->line_items = [];
|
||||
$invoice->discount = 500;
|
||||
$invoice->is_amount_discount = false;
|
||||
|
||||
$data = $invoice->toArray();
|
||||
$data['client_id'] = $this->client->hashed_id;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/invoices', $data);
|
||||
|
||||
$response->assertStatus(422);
|
||||
|
||||
}
|
||||
|
||||
public function test_create_modification_invoice()
|
||||
{
|
||||
|
||||
|
|
@ -281,14 +580,12 @@ class VerifactuApiTest extends TestCase
|
|||
$response->assertStatus(200);
|
||||
|
||||
$arr = $response->json();
|
||||
// nlog($arr);
|
||||
|
||||
$this->assertEquals($arr['data'][0]['status_id'], Invoice::STATUS_CANCELLED);
|
||||
$this->assertEquals($arr['data'][0]['balance'], 121);
|
||||
$this->assertEquals($arr['data'][0]['amount'], 121);
|
||||
$this->assertNotNull($arr['data'][0]['backup']['child_invoice_ids'][0]);
|
||||
|
||||
|
||||
$credit_invoice = Invoice::find($this->decodePrimaryKey($arr['data'][0]['backup']['child_invoice_ids'][0]));
|
||||
|
||||
$this->assertNotNull($credit_invoice);
|
||||
|
|
|
|||
Loading…
Reference in New Issue