Fixes for credits

This commit is contained in:
David Bomba 2024-06-17 13:45:24 +10:00
parent 742b49c75a
commit 11e082d443
19 changed files with 295 additions and 236 deletions

View File

@ -29,6 +29,7 @@ class InvoiceItemSum
use Discounter; use Discounter;
use Taxer; use Taxer;
//@phpstan-ignore-next-line
private array $eu_tax_jurisdictions = [ private array $eu_tax_jurisdictions = [
'AT', // Austria 'AT', // Austria
'BE', // Belgium 'BE', // Belgium
@ -170,7 +171,7 @@ class InvoiceItemSum
private function shouldCalculateTax(): self private function shouldCalculateTax(): self
{ {
if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) { if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) { //@phpstan-ignore-line
$this->calc_tax = false; $this->calc_tax = false;
return $this; return $this;
} }

View File

@ -27,7 +27,7 @@ class InvoiceItemSumInclusive
use Discounter; use Discounter;
use Taxer; use Taxer;
//@phpstan-ignore-next-line
private array $eu_tax_jurisdictions = [ private array $eu_tax_jurisdictions = [
'AT', // Austria 'AT', // Austria
'BE', // Belgium 'BE', // Belgium
@ -98,6 +98,7 @@ class InvoiceItemSumInclusive
private $total_taxes; private $total_taxes;
/** @phpstan-ignore-next-line */
private $item; private $item;
private $line_items; private $line_items;
@ -399,7 +400,7 @@ class InvoiceItemSumInclusive
private function shouldCalculateTax(): self private function shouldCalculateTax(): self
{ {
if (!$this->invoice->company->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) { if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {//@phpstan-ignore-line
$this->calc_tax = false; $this->calc_tax = false;
return $this; return $this;
} }

View File

@ -280,18 +280,6 @@ class MigrationController extends BaseController
} }
} }
if (app()->environment() === 'local') {
}
try {
return response()->json([
'_id' => Str::uuid(),
'method' => config('queue.default'),
'started_at' => now(),
], 200);
} finally {
// Controller logic here
foreach ($companies as $company) { foreach ($companies as $company) {
if (! is_array($company)) { if (! is_array($company)) {
continue; continue;
@ -460,6 +448,4 @@ class MigrationController extends BaseController
], 200); ], 200);
} }
}
} }

View File

@ -22,8 +22,6 @@ use Illuminate\Support\Str;
class OneTimeTokenController extends BaseController class OneTimeTokenController extends BaseController
{ {
private $contexts = [
];
public function __construct() public function __construct()
{ {

View File

@ -19,7 +19,6 @@ use Illuminate\Http\Request;
*/ */
class PostMarkController extends BaseController class PostMarkController extends BaseController
{ {
private $invitation;
public function __construct() public function __construct()
{ {

View File

@ -234,24 +234,6 @@ class SetupController extends Controller
} }
} }
private function testPhantom()
{
try {
$key = config('ninja.phantomjs_key');
$url = 'https://www.invoiceninja.org/';
$phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$url}%22,renderType:%22pdf%22%7D";
$pdf = CurlUtils::get($phantom_url);
Storage::disk(config('filesystems.default'))->put('test.pdf', $pdf);
Storage::disk('local')->put('test.pdf', $pdf);
return response(['url' => Storage::disk('local')->url('test.pdf')], 200);
} catch (Exception $e) {
return response([], 500);
}
}
public function clearCompiledCache() public function clearCompiledCache()
{ {
$cacheCompiled = base_path('bootstrap/cache/compiled.php'); $cacheCompiled = base_path('bootstrap/cache/compiled.php');

View File

@ -277,7 +277,7 @@ class InvoiceTransformer extends BaseTransformer
if($key == 0) { if($key == 0) {
continue; continue;
} }
/** @var array $row */
if(is_array($row[5])) { if(is_array($row[5])) {
$csv = str_getcsv($row[5][0], ";"); $csv = str_getcsv($row[5][0], ";");
$row[5] = array_combine(explode(",", $csv[0]), explode(",", $csv[1])); $row[5] = array_combine(explode(",", $csv[0]), explode(",", $csv[1]));

View File

@ -40,7 +40,7 @@ class CreateRawPdf
public Invoice | Credit | Quote | RecurringInvoice | PurchaseOrder $entity; public Invoice | Credit | Quote | RecurringInvoice | PurchaseOrder $entity;
public $company; public \App\Models\Company $company;
public $contact; public $contact;
@ -55,6 +55,7 @@ class CreateRawPdf
{ {
$this->invitation = $invitation; $this->invitation = $invitation;
$this->company = $invitation->company;
if ($invitation instanceof InvoiceInvitation) { if ($invitation instanceof InvoiceInvitation) {
$this->entity = $invitation->invoice; $this->entity = $invitation->invoice;
@ -116,6 +117,13 @@ class CreateRawPdf
if ($this->entity_string == "invoice" && $this->entity->client->getSetting("merge_e_invoice_to_pdf")) { if ($this->entity_string == "invoice" && $this->entity->client->getSetting("merge_e_invoice_to_pdf")) {
$pdf = (new MergeEDocument($this->entity, $pdf))->handle(); $pdf = (new MergeEDocument($this->entity, $pdf))->handle();
} }
$merge_docs = $this->entity->client ? $this->entity->client->getSetting('embed_documents') : $this->company->getSetting('embed_documents');
if($merge_docs && ($this->entity->documents()->where('is_public', true)->count() > 0 || $this->company->documents()->where('is_public', true)->count() > 0)) {
$pdf = $this->entity->documentMerge($pdf);
}
return $pdf; return $pdf;
} }

View File

@ -192,7 +192,7 @@ class CreateUbl implements ShouldQueue
/** /**
* @param $item * @param $item
* @param $invoice_total * @param $invoice_total
* @return float|int * @return float
*/ */
private function getItemTaxable($item, $invoice_total) private function getItemTaxable($item, $invoice_total)
{ {

View File

@ -60,7 +60,7 @@ use Laracasts\Presenter\PresentableTrait;
* @property bool $is_deleted * @property bool $is_deleted
* @property string|null $last_login * @property string|null $last_login
* @property string|null $signature * @property string|null $signature
* @property string $password * @property string|null $password
* @property string $language_id * @property string $language_id
* @property string|null $remember_token * @property string|null $remember_token
* @property string|null $custom_value1 * @property string|null $custom_value1

View File

@ -53,7 +53,7 @@ class CreditCard
* Credit card payment page. * Credit card payment page.
* *
* @param array $data * @param array $data
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View * @return array
*/ */
private function threeDParameters(array $data) private function threeDParameters(array $data)

View File

@ -307,7 +307,7 @@ class PayPalWebhook implements ShouldQueue
}); });
return $gateway ?? false; return $gateway ?? null;
} }
//--------------------------------------------------------------------------------------// //--------------------------------------------------------------------------------------//

View File

@ -284,6 +284,10 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver
$r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order); $r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order);
if(!isset($r->json()['id'])) {
$this->handleProcessingFailure($r->json());
}
$this->payment_hash->withData("orderID", $r->json()['id']); $this->payment_hash->withData("orderID", $r->json()['id']);
return $r->json()['id']; return $r->json()['id'];

View File

@ -59,7 +59,7 @@ class PaymentRepository extends BaseRepository
* @param Payment $payment The $payment entity * @param Payment $payment The $payment entity
* @return Payment The updated/created payment object * @return Payment The updated/created payment object
*/ */
private function applyPayment(array $data, Payment $payment): ?Payment private function applyPayment(array $data, Payment $payment): Payment
{ {
$is_existing_payment = true; $is_existing_payment = true;
$client = false; $client = false;

View File

@ -219,27 +219,6 @@ class CreditService
public function deletePdf() public function deletePdf()
{ {
$this->credit->invitations->each(function ($invitation) {
// (new UnlinkFile(config('filesystems.default'), $this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf'))->handle();
//30-06-2023
try {
// if (Storage::disk(config('filesystems.default'))->exists($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'.pdf')) {
Storage::disk(config('filesystems.default'))->delete($this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf');
// }
// if (Ninja::isHosted() && Storage::disk('public')->exists($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'.pdf')) {
if (Ninja::isHosted()) {
Storage::disk('public')->delete($this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf');
}
} catch (\Exception $e) {
nlog($e->getMessage());
}
});
return $this; return $this;
} }
@ -273,9 +252,12 @@ class CreditService
public function deleteCredit() public function deleteCredit()
{ {
$paid_to_date = $this->credit->invoice_id ? $this->credit->balance : 0;
$this->credit $this->credit
->client ->client
->service() ->service()
->updatePaidToDate($paid_to_date)
->adjustCreditBalance($this->credit->balance * -1) ->adjustCreditBalance($this->credit->balance * -1)
->save(); ->save();
@ -285,9 +267,13 @@ class CreditService
public function restoreCredit() public function restoreCredit()
{ {
$paid_to_date = $this->credit->invoice_id ? $this->credit->balance : 0;
$this->credit $this->credit
->client ->client
->service() ->service()
->updatePaidToDate($paid_to_date * -1)
->adjustCreditBalance($this->credit->balance) ->adjustCreditBalance($this->credit->balance)
->save(); ->save();

View File

@ -405,7 +405,7 @@ class RoEInvoice extends AbstractService
/** /**
* @param $item * @param $item
* @param $invoice_total * @param $invoice_total
* @return float|int * @return float
*/ */
private function getItemTaxable($item, $invoice_total) private function getItemTaxable($item, $invoice_total)
{ {

View File

@ -406,7 +406,7 @@ class EmailDefaults
* @param string $markdown The body to convert * @param string $markdown The body to convert
* @return string The parsed markdown response * @return string The parsed markdown response
*/ */
private function parseMarkdownToHtml(string $markdown): ?string private function parseMarkdownToHtml(string $markdown): string
{ {
$converter = new CommonMarkConverter([ $converter = new CommonMarkConverter([
'allow_unsafe_links' => false, 'allow_unsafe_links' => false,

View File

@ -110,8 +110,6 @@ trait CleanLineItems
$total += ($item['cost'] * $item['quantity']); $total += ($item['cost'] * $item['quantity']);
} }
nlog($total);
return $total; return $total;
} }
} }

View File

@ -43,6 +43,102 @@ class CreditTest extends TestCase
$this->makeTestData(); $this->makeTestData();
} }
public function testPaidToDateAdjustments()
{
$c = Client::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'balance' => 0,
]);
$ii = new InvoiceItem();
$ii->cost = 100;
$ii->quantity = 1;
$ii->product_key = 'xx';
$ii->notes = 'yy';
$i = \App\Models\Invoice::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'client_id' => $c->id,
'tax_name1' => '',
'tax_name2' => '',
'tax_name3' => '',
'tax_rate1' => 0,
'tax_rate2' => 0,
'tax_rate3' => 0,
'discount' => 0,
'line_items' => [
$ii
],
'status_id' => 1,
]);
$i = $i->calc()->getInvoice();
$this->assertEquals(0, $i->balance);
$this->assertEquals(100, $i->amount);
$i->service()->markSent()->save();
$this->assertEquals(100, $i->balance);
$i->service()->markPaid()->save();
$i = $i->fresh();
$c = $c->fresh();
$this->assertEquals(0, $i->balance);
$this->assertEquals(0, $c->balance);
$this->assertEquals(100, $c->paid_to_date);
$i->service()->handleReversal()->save();
$data = $i->toArray();
$data['invoice_id'] = $i->hashed_id;
$data['user_id'] = $this->encodePrimaryKey($i->user_id);
$data['client_id'] = $this->encodePrimaryKey($i->client_id);
$data['status_id'] = 1;
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson("/api/v1/credits?mark_sent=true", $data);
$response->assertStatus(200);
$arr = $response->json();
$cr_id = $arr['data']['id'];
$i = $i->fresh();
$c = $c->fresh();
$credit = $i->credits()->first();
$this->assertNotNull($credit);
$this->assertEquals(0, $i->balance);
$this->assertEquals(100, $c->credit_balance);
$this->assertEquals(0, $c->paid_to_date);
$credit->service()->deleteCredit()->save();
$c = $c->fresh();
$this->assertEquals(100, $c->paid_to_date);
$this->assertEquals(0, $c->credit_balance);
$credit->service()->restoreCredit()->save();
$c = $c->fresh();
$this->assertEquals(0, $c->paid_to_date);
$this->assertEquals(100, $c->credit_balance);
}
public function testCreditPaymentsPaidToDates() public function testCreditPaymentsPaidToDates()
{ {
$c = Client::factory()->create([ $c = Client::factory()->create([