mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-11 05:32:39 +01:00
Merge pull request #6991 from turbo124/v5-develop
Negative Credits/Payments for eurozone.
This commit is contained in:
commit
0734e9ad93
@ -524,6 +524,11 @@ class CreditController extends BaseController
|
|||||||
{
|
{
|
||||||
/*If we are using bulk actions, we don't want to return anything */
|
/*If we are using bulk actions, we don't want to return anything */
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
|
case 'mark_paid':
|
||||||
|
$credit->service()->markPaid()->save();
|
||||||
|
return $this->itemResponse($credit);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'clone_to_credit':
|
case 'clone_to_credit':
|
||||||
$credit = CloneCreditFactory::create($credit, auth()->user()->id);
|
$credit = CloneCreditFactory::create($credit, auth()->user()->id);
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class ContactAccount
|
|||||||
if(!Ninja::isHosted()) {
|
if(!Ninja::isHosted()) {
|
||||||
|
|
||||||
$account_id = Account::first()->id;
|
$account_id = Account::first()->id;
|
||||||
$request->attributes->add(['account_id' => $account_id]);
|
$request->request->add(['account_id' => $account_id]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class SetDomainNameDb
|
|||||||
];
|
];
|
||||||
|
|
||||||
if($company = MultiDB::findAndSetDbByDomain($query)){
|
if($company = MultiDB::findAndSetDbByDomain($query)){
|
||||||
$request->attributes->add(['account_id' => $company->account_id]);
|
$request->request->add(['account_id' => $company->account_id]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -71,7 +71,7 @@ class SetDomainNameDb
|
|||||||
];
|
];
|
||||||
|
|
||||||
if($company = MultiDB::findAndSetDbByDomain($query)){
|
if($company = MultiDB::findAndSetDbByDomain($query)){
|
||||||
$request->attributes->add(['account_id' => $company->account_id]);
|
$request->request->add(['account_id' => $company->account_id]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -56,6 +56,7 @@ class StoreCreditRequest extends Request
|
|||||||
|
|
||||||
// $rules['number'] = new UniqueCreditNumberRule($this->all());
|
// $rules['number'] = new UniqueCreditNumberRule($this->all());
|
||||||
$rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)];
|
$rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)];
|
||||||
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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['number'] = Rule::unique('credits')->where('company_id', auth()->user()->company()->id)->ignore($this->credit->id);
|
||||||
|
|
||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ class StoreInvoiceRequest extends Request
|
|||||||
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
|
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
|
||||||
|
|
||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
@ -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['number'] = Rule::unique('invoices')->where('company_id', auth()->user()->company()->id)->ignore($this->invoice->id);
|
||||||
|
|
||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
if($this->input('status_id') != Invoice::STATUS_DRAFT)
|
if($this->input('status_id') != Invoice::STATUS_DRAFT)
|
||||||
$rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all());
|
$rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all());
|
||||||
|
@ -50,6 +50,7 @@ class StoreQuoteRequest extends Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
$rules['number'] = ['nullable',Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)];
|
$rules['number'] = ['nullable',Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)];
|
||||||
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
// $rules['number'] = new UniqueQuoteNumberRule($this->all());
|
// $rules['number'] = new UniqueQuoteNumberRule($this->all());
|
||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
|
@ -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['number'] = Rule::unique('quotes')->where('company_id', auth()->user()->company()->id)->ignore($this->quote->id);
|
||||||
|
|
||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ class MolliePaymentDriver extends BaseDriver
|
|||||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
SystemLog::TYPE_MOLLIE,
|
SystemLog::TYPE_MOLLIE,
|
||||||
$this->client,
|
$this->client,
|
||||||
$this->client->companyk
|
$this->client->company
|
||||||
);
|
);
|
||||||
|
|
||||||
nlog($e->getMessage());
|
nlog($e->getMessage());
|
||||||
@ -239,7 +239,8 @@ class MolliePaymentDriver extends BaseDriver
|
|||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
SystemLog::EVENT_GATEWAY_SUCCESS,
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
SystemLog::TYPE_MOLLIE,
|
SystemLog::TYPE_MOLLIE,
|
||||||
$this->client
|
$this->client,
|
||||||
|
$this->client->company
|
||||||
);
|
);
|
||||||
|
|
||||||
return $payment;
|
return $payment;
|
||||||
@ -259,7 +260,8 @@ class MolliePaymentDriver extends BaseDriver
|
|||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
SystemLog::TYPE_CHECKOUT,
|
SystemLog::TYPE_CHECKOUT,
|
||||||
$this->client
|
$this->client,
|
||||||
|
$this->client->company
|
||||||
);
|
);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -310,7 +312,7 @@ class MolliePaymentDriver extends BaseDriver
|
|||||||
$client = $record->client;
|
$client = $record->client;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$client = Client::withTrashed()->find($this->decodePrimaryKey($payment['metadata']->client_id));
|
$client = Client::withTrashed()->find($this->decodePrimaryKey($payment->metadata->client_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
$message = [
|
$message = [
|
||||||
@ -331,7 +333,8 @@ class MolliePaymentDriver extends BaseDriver
|
|||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
$response,
|
$response,
|
||||||
SystemLog::TYPE_MOLLIE,
|
SystemLog::TYPE_MOLLIE,
|
||||||
$client
|
$client,
|
||||||
|
$client->company
|
||||||
);
|
);
|
||||||
|
|
||||||
return response()->json([], 200);
|
return response()->json([], 200);
|
||||||
|
@ -185,13 +185,13 @@ class PaymentRepository extends BaseRepository {
|
|||||||
* @param $payment
|
* @param $payment
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private function processExchangeRates($data, $payment)
|
public function processExchangeRates($data, $payment)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(array_key_exists('exchange_rate', $data) && isset($data['exchange_rate']))
|
if(array_key_exists('exchange_rate', $data) && isset($data['exchange_rate']))
|
||||||
return $payment;
|
return $payment;
|
||||||
|
|
||||||
$client = Client::find($data['client_id']);
|
$client = Client::withTrashed()->find($data['client_id']);
|
||||||
|
|
||||||
$client_currency = $client->getSetting('currency_id');
|
$client_currency = $client->getSetting('currency_id');
|
||||||
$company_currency = $client->company->settings->currency_id;
|
$company_currency = $client->company->settings->currency_id;
|
||||||
|
@ -11,8 +11,13 @@
|
|||||||
|
|
||||||
namespace App\Services\Credit;
|
namespace App\Services\Credit;
|
||||||
|
|
||||||
|
use App\Factory\PaymentFactory;
|
||||||
use App\Jobs\Util\UnlinkFile;
|
use App\Jobs\Util\UnlinkFile;
|
||||||
use App\Models\Credit;
|
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\CreateInvitations;
|
||||||
use App\Services\Credit\TriggeredActions;
|
use App\Services\Credit\TriggeredActions;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
@ -79,6 +84,61 @@ class CreditService
|
|||||||
return $this;
|
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()
|
public function markSent()
|
||||||
{
|
{
|
||||||
$this->credit = (new MarkSent($this->credit->client, $this->credit))->run();
|
$this->credit = (new MarkSent($this->credit->client, $this->credit))->run();
|
||||||
|
@ -130,7 +130,7 @@ class AutoBillInvoice extends AbstractService
|
|||||||
info("Auto Bill payment captured for ".$this->invoice->number);
|
info("Auto Bill payment captured for ".$this->invoice->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->invoice;
|
return $this->invoice->fresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +33,7 @@ class CreateInvitations extends AbstractService
|
|||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
|
|
||||||
$contacts = $this->invoice->client->contacts;
|
$contacts = $this->invoice->client->contacts()->where('send_email', true)->get();
|
||||||
|
|
||||||
if($contacts->count() == 0){
|
if($contacts->count() == 0){
|
||||||
$this->createBlankContact();
|
$this->createBlankContact();
|
||||||
|
@ -139,8 +139,13 @@ class DeletePayment
|
|||||||
if ($this->payment->credits()->exists()) {
|
if ($this->payment->credits()->exists()) {
|
||||||
$this->payment->credits()->each(function ($paymentable_credit) {
|
$this->payment->credits()->each(function ($paymentable_credit) {
|
||||||
|
|
||||||
|
$multiplier = 1;
|
||||||
|
|
||||||
|
if($paymentable_credit->pivot->amount < 0)
|
||||||
|
$multiplier = -1;
|
||||||
|
|
||||||
$paymentable_credit->service()
|
$paymentable_credit->service()
|
||||||
->updateBalance($paymentable_credit->pivot->amount)
|
->updateBalance($paymentable_credit->pivot->amount*$multiplier)
|
||||||
->updatePaidToDate($paymentable_credit->pivot->amount*-1)
|
->updatePaidToDate($paymentable_credit->pivot->amount*-1)
|
||||||
->setStatus(Credit::STATUS_SENT)
|
->setStatus(Credit::STATUS_SENT)
|
||||||
->save();
|
->save();
|
||||||
|
@ -717,8 +717,9 @@ class SubscriptionService
|
|||||||
*/
|
*/
|
||||||
public function convertInvoiceToRecurring($client_id) :RecurringInvoice
|
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();
|
$subscription_repo = new SubscriptionRepository();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user