1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00

Merge pull request #6991 from turbo124/v5-develop

Negative Credits/Payments for eurozone.
This commit is contained in:
David Bomba 2021-11-23 07:06:58 +11:00 committed by GitHub
commit 0734e9ad93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 96 additions and 16 deletions

View File

@ -524,6 +524,11 @@ class CreditController extends BaseController
{
/*If we are using bulk actions, we don't want to return anything */
switch ($action) {
case 'mark_paid':
$credit->service()->markPaid()->save();
return $this->itemResponse($credit);
break;
case 'clone_to_credit':
$credit = CloneCreditFactory::create($credit, auth()->user()->id);

View File

@ -32,7 +32,7 @@ class ContactAccount
if(!Ninja::isHosted()) {
$account_id = Account::first()->id;
$request->attributes->add(['account_id' => $account_id]);
$request->request->add(['account_id' => $account_id]);
}

View File

@ -49,7 +49,7 @@ class SetDomainNameDb
];
if($company = MultiDB::findAndSetDbByDomain($query)){
$request->attributes->add(['account_id' => $company->account_id]);
$request->request->add(['account_id' => $company->account_id]);
}
else
{
@ -71,7 +71,7 @@ class SetDomainNameDb
];
if($company = MultiDB::findAndSetDbByDomain($query)){
$request->attributes->add(['account_id' => $company->account_id]);
$request->request->add(['account_id' => $company->account_id]);
}
else
{

View File

@ -56,6 +56,7 @@ class StoreCreditRequest extends Request
// $rules['number'] = new UniqueCreditNumberRule($this->all());
$rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)];
$rules['discount'] = 'sometimes|numeric';

View File

@ -57,6 +57,7 @@ class UpdateCreditRequest extends Request
$rules['number'] = Rule::unique('credits')->where('company_id', auth()->user()->company()->id)->ignore($this->credit->id);
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';
return $rules;
}

View File

@ -56,6 +56,7 @@ class StoreInvoiceRequest extends Request
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';
return $rules;
}

View File

@ -56,6 +56,7 @@ class UpdateInvoiceRequest extends Request
$rules['number'] = Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)->ignore($this->invoice->id);
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';
if($this->input('status_id') != Invoice::STATUS_DRAFT)
$rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all());

View File

@ -50,6 +50,7 @@ class StoreQuoteRequest extends Request
}
$rules['number'] = ['nullable',Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)];
$rules['discount'] = 'sometimes|numeric';
// $rules['number'] = new UniqueQuoteNumberRule($this->all());
$rules['line_items'] = 'array';

View File

@ -51,6 +51,7 @@ class UpdateQuoteRequest extends Request
$rules['number'] = Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)->ignore($this->quote->id);
$rules['line_items'] = 'array';
$rules['discount'] = 'sometimes|numeric';
return $rules;
}

View File

@ -176,7 +176,7 @@ class MolliePaymentDriver extends BaseDriver
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_MOLLIE,
$this->client,
$this->client->companyk
$this->client->company
);
nlog($e->getMessage());
@ -239,7 +239,8 @@ class MolliePaymentDriver extends BaseDriver
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_SUCCESS,
SystemLog::TYPE_MOLLIE,
$this->client
$this->client,
$this->client->company
);
return $payment;
@ -259,7 +260,8 @@ class MolliePaymentDriver extends BaseDriver
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_CHECKOUT,
$this->client
$this->client,
$this->client->company
);
return false;
@ -310,7 +312,7 @@ class MolliePaymentDriver extends BaseDriver
$client = $record->client;
}
else{
$client = Client::withTrashed()->find($this->decodePrimaryKey($payment['metadata']->client_id));
$client = Client::withTrashed()->find($this->decodePrimaryKey($payment->metadata->client_id));
}
$message = [
@ -331,7 +333,8 @@ class MolliePaymentDriver extends BaseDriver
SystemLog::CATEGORY_GATEWAY_RESPONSE,
$response,
SystemLog::TYPE_MOLLIE,
$client
$client,
$client->company
);
return response()->json([], 200);

View File

@ -185,13 +185,13 @@ class PaymentRepository extends BaseRepository {
* @param $payment
* @return
*/
private function processExchangeRates($data, $payment)
public function processExchangeRates($data, $payment)
{
if(array_key_exists('exchange_rate', $data) && isset($data['exchange_rate']))
return $payment;
$client = Client::find($data['client_id']);
$client = Client::withTrashed()->find($data['client_id']);
$client_currency = $client->getSetting('currency_id');
$company_currency = $client->company->settings->currency_id;

View File

@ -11,8 +11,13 @@
namespace App\Services\Credit;
use App\Factory\PaymentFactory;
use App\Jobs\Util\UnlinkFile;
use App\Models\Credit;
use App\Models\Payment;
use App\Models\PaymentType;
use App\Repositories\CreditRepository;
use App\Repositories\PaymentRepository;
use App\Services\Credit\CreateInvitations;
use App\Services\Credit\TriggeredActions;
use App\Utils\Traits\MakesHash;
@ -79,6 +84,61 @@ class CreditService
return $this;
}
/*
For euro users - we mark a credit as paid when
we need to document a refund of sorts.
Criteria: Credit must be a negative value
A negative payment for the balance will be generated
This amount will be reduced from the clients paid to date.
*/
public function markPaid()
{
if($this->credit->balance > 0)
return $this;
$payment_repo = new PaymentRepository(new CreditRepository());
//set credit balance to zero
$adjustment = $this->credit->balance;
$this->updateBalance($adjustment)
->updatePaidToDate($adjustment)
->save();
//create a negative payment of total $this->credit->balance
$payment = PaymentFactory::create($this->credit->company_id, $this->credit->user_id);
$payment->client_id = $this->credit->client_id;
$payment->amount = $adjustment;
$payment->applied = $adjustment;
$payment->refunded = 0;
$payment->status_id = Payment::STATUS_COMPLETED;
$payment->type_id = PaymentType::CREDIT;
$payment->is_manual = true;
$payment->date = now();
$payment->saveQuietly();
$payment->number = $payment->client->getNextPaymentNumber($payment->client, $payment);
$payment = $payment_repo->processExchangeRates(['client_id' => $this->credit->client_id], $payment);
$payment->saveQuietly();
$payment
->credits()
->attach($this->credit->id, ['amount' => $adjustment]);
//reduce client paid_to_date by $this->credit->balance amount
$this->credit
->client
->service()
->updatePaidToDate($adjustment)
->save();
event('eloquent.created: App\Models\Payment', $payment);
return $this;
}
public function markSent()
{
$this->credit = (new MarkSent($this->credit->client, $this->credit))->run();

View File

@ -130,7 +130,7 @@ class AutoBillInvoice extends AbstractService
info("Auto Bill payment captured for ".$this->invoice->number);
}
return $this->invoice;
return $this->invoice->fresh();
}
/**

View File

@ -33,7 +33,7 @@ class CreateInvitations extends AbstractService
public function run()
{
$contacts = $this->invoice->client->contacts;
$contacts = $this->invoice->client->contacts()->where('send_email', true)->get();
if($contacts->count() == 0){
$this->createBlankContact();

View File

@ -139,8 +139,13 @@ class DeletePayment
if ($this->payment->credits()->exists()) {
$this->payment->credits()->each(function ($paymentable_credit) {
$multiplier = 1;
if($paymentable_credit->pivot->amount < 0)
$multiplier = -1;
$paymentable_credit->service()
->updateBalance($paymentable_credit->pivot->amount)
->updateBalance($paymentable_credit->pivot->amount*$multiplier)
->updatePaidToDate($paymentable_credit->pivot->amount*-1)
->setStatus(Credit::STATUS_SENT)
->save();

View File

@ -717,8 +717,9 @@ class SubscriptionService
*/
public function convertInvoiceToRecurring($client_id) :RecurringInvoice
{
MultiDB::setDb($this->subscription->company->db);
$client = Client::find($client_id);
$client = Client::withTrashed()->find($client_id);
$subscription_repo = new SubscriptionRepository();