mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 21:22:58 +01:00
commit
eaa73dd224
@ -1 +1 @@
|
|||||||
5.3.77
|
5.3.78
|
@ -86,8 +86,6 @@ class HostedMigrations extends Command
|
|||||||
|
|
||||||
$path = public_path('storage/migrations/import');
|
$path = public_path('storage/migrations/import');
|
||||||
|
|
||||||
nlog(public_path('storage/migrations/import'));
|
|
||||||
|
|
||||||
$directory = new DirectoryIterator($path);
|
$directory = new DirectoryIterator($path);
|
||||||
|
|
||||||
foreach ($directory as $file) {
|
foreach ($directory as $file) {
|
||||||
|
@ -80,8 +80,6 @@ class ImportMigrations extends Command
|
|||||||
|
|
||||||
$path = $this->option('path') ?? public_path('storage/migrations/import');
|
$path = $this->option('path') ?? public_path('storage/migrations/import');
|
||||||
|
|
||||||
nlog(public_path('storage/migrations/import'));
|
|
||||||
|
|
||||||
$directory = new DirectoryIterator($path);
|
$directory = new DirectoryIterator($path);
|
||||||
|
|
||||||
foreach ($directory as $file) {
|
foreach ($directory as $file) {
|
||||||
|
@ -46,7 +46,6 @@ class BaseSettings
|
|||||||
return is_null($value) ? '' : (string) $value;
|
return is_null($value) ? '' : (string) $value;
|
||||||
case 'bool':
|
case 'bool':
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
nlog($value);
|
|
||||||
return boolval($value);
|
return boolval($value);
|
||||||
case 'object':
|
case 'object':
|
||||||
return json_decode($value);
|
return json_decode($value);
|
||||||
|
@ -124,7 +124,7 @@ class Handler extends ExceptionHandler
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($this->validException($exception) && auth()->guard('contact')->user()->company->account->report_errors) {
|
if ($this->validException($exception)) {
|
||||||
app('sentry')->captureException($exception);
|
app('sentry')->captureException($exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,7 @@ class ProRata
|
|||||||
{
|
{
|
||||||
$days = $from_date->copy()->diffInDays($to_date);
|
$days = $from_date->copy()->diffInDays($to_date);
|
||||||
$days_in_frequency = $this->getDaysInFrequency($frequency);
|
$days_in_frequency = $this->getDaysInFrequency($frequency);
|
||||||
nlog($from_date->format('Y-m-d'));
|
|
||||||
nlog($days);
|
|
||||||
nlog($days_in_frequency);
|
|
||||||
nlog($amount);
|
|
||||||
return round( (($days/$days_in_frequency) * $amount),2);
|
return round( (($days/$days_in_frequency) * $amount),2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,6 +276,7 @@ class RecurringExpenseController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$recurring_expense = $this->recurring_expense_repo->save($request->all(), $recurring_expense);
|
$recurring_expense = $this->recurring_expense_repo->save($request->all(), $recurring_expense);
|
||||||
|
$recurring_expense->service()->triggeredActions($request)->save();
|
||||||
|
|
||||||
$this->uploadLogo($request->file('company_logo'), $recurring_expense->company, $recurring_expense);
|
$this->uploadLogo($request->file('company_logo'), $recurring_expense->company, $recurring_expense);
|
||||||
|
|
||||||
@ -372,6 +373,7 @@ class RecurringExpenseController extends BaseController
|
|||||||
public function store(StoreRecurringExpenseRequest $request)
|
public function store(StoreRecurringExpenseRequest $request)
|
||||||
{
|
{
|
||||||
$recurring_expense = $this->recurring_expense_repo->save($request->all(), RecurringExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
$recurring_expense = $this->recurring_expense_repo->save($request->all(), RecurringExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||||
|
$recurring_expense->service()->triggeredActions($request)->save();
|
||||||
|
|
||||||
event(new RecurringExpenseWasCreated($recurring_expense, $recurring_expense->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new RecurringExpenseWasCreated($recurring_expense, $recurring_expense->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
|
@ -388,7 +388,10 @@ class RecurringInvoiceController extends BaseController
|
|||||||
|
|
||||||
$recurring_invoice = $this->recurring_invoice_repo->save($request->all(), $recurring_invoice);
|
$recurring_invoice = $this->recurring_invoice_repo->save($request->all(), $recurring_invoice);
|
||||||
|
|
||||||
$recurring_invoice->service()->deletePdf()->save();
|
$recurring_invoice->service()
|
||||||
|
->triggeredActions($request)
|
||||||
|
->deletePdf()
|
||||||
|
->save();
|
||||||
|
|
||||||
event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
|
@ -280,6 +280,7 @@ class TaskController extends BaseController
|
|||||||
$old_task = json_decode(json_encode($task));
|
$old_task = json_decode(json_encode($task));
|
||||||
|
|
||||||
$task = $this->task_repo->save($request->all(), $task);
|
$task = $this->task_repo->save($request->all(), $task);
|
||||||
|
$task = $this->task_repo->triggeredActions($request, $task);
|
||||||
|
|
||||||
if($task->status_order != $old_task->status_order)
|
if($task->status_order != $old_task->status_order)
|
||||||
$this->task_repo->sortStatuses($old_task, $task);
|
$this->task_repo->sortStatuses($old_task, $task);
|
||||||
@ -377,6 +378,7 @@ class TaskController extends BaseController
|
|||||||
public function store(StoreTaskRequest $request)
|
public function store(StoreTaskRequest $request)
|
||||||
{
|
{
|
||||||
$task = $this->task_repo->save($request->all(), TaskFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
$task = $this->task_repo->save($request->all(), TaskFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||||
|
$task = $this->task_repo->triggeredActions($request, $task);
|
||||||
|
|
||||||
event(new TaskWasCreated($task, $task->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new TaskWasCreated($task, $task->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
|
@ -238,6 +238,7 @@ class BillingPortalPurchase extends Component
|
|||||||
{
|
{
|
||||||
$company = $this->subscription->company;
|
$company = $this->subscription->company;
|
||||||
$user = $this->subscription->user;
|
$user = $this->subscription->user;
|
||||||
|
$user->setCompany($company);
|
||||||
|
|
||||||
$client_repo = new ClientRepository(new ClientContactRepository());
|
$client_repo = new ClientRepository(new ClientContactRepository());
|
||||||
|
|
||||||
|
@ -75,12 +75,6 @@ class PaymentAmountsBalanceRule implements Rule
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nlog(request()->input('invoices'));
|
|
||||||
// nlog($payment_amounts);
|
|
||||||
// nlog($invoice_amounts);
|
|
||||||
// nlog(request()->all());
|
|
||||||
nlog($payment_amounts ." >= " . $invoice_amounts);
|
|
||||||
|
|
||||||
return round($payment_amounts,2) >= round($invoice_amounts,2);
|
return round($payment_amounts,2) >= round($invoice_amounts,2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,6 @@ class BaseTransformer
|
|||||||
->where('id_number', $client_name);
|
->where('id_number', $client_name);
|
||||||
|
|
||||||
if ($client_id_search->count() >= 1) {
|
if ($client_id_search->count() >= 1) {
|
||||||
// nlog("found via id number => {$client_id_search->first()->id}");
|
|
||||||
return $client_id_search->first()->id;
|
return $client_id_search->first()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +82,6 @@ class BaseTransformer
|
|||||||
->where('name', $client_name);
|
->where('name', $client_name);
|
||||||
|
|
||||||
if ($client_name_search->count() >= 1) {
|
if ($client_name_search->count() >= 1) {
|
||||||
// nlog("found via name {$client_name_search->first()->id}");
|
|
||||||
return $client_name_search->first()->id;
|
return $client_name_search->first()->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,13 +92,10 @@ class BaseTransformer
|
|||||||
)->where('email', $client_email);
|
)->where('email', $client_email);
|
||||||
|
|
||||||
if ($contacts->count() >= 1) {
|
if ($contacts->count() >= 1) {
|
||||||
// nlog("found via contact {$contacts->first()->client_id}");
|
|
||||||
return $contacts->first()->client_id;
|
return $contacts->first()->client_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nlog("did not find client");
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,14 +66,12 @@ class BaseTransformer
|
|||||||
|
|
||||||
if ( $client_id_search->count() >= 1 ) {
|
if ( $client_id_search->count() >= 1 ) {
|
||||||
return $client_id_search->first()->id;
|
return $client_id_search->first()->id;
|
||||||
nlog("found via id number");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$client_name_search = $clients->where( 'name', $client_name );
|
$client_name_search = $clients->where( 'name', $client_name );
|
||||||
|
|
||||||
if ( $client_name_search->count() >= 1 ) {
|
if ( $client_name_search->count() >= 1 ) {
|
||||||
return $client_name_search->first()->id;
|
return $client_name_search->first()->id;
|
||||||
nlog("found via name");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $client_email ) ) {
|
if ( ! empty( $client_email ) ) {
|
||||||
@ -82,10 +80,8 @@ class BaseTransformer
|
|||||||
|
|
||||||
if ( $contacts->count() >= 1 ) {
|
if ( $contacts->count() >= 1 ) {
|
||||||
return $contacts->first()->client_id;
|
return $contacts->first()->client_id;
|
||||||
nlog("found via contact");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// nlog("did not find client");
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -483,8 +483,6 @@ class CompanyImport implements ShouldQueue
|
|||||||
$tmp_company->db = config('database.default');
|
$tmp_company->db = config('database.default');
|
||||||
$tmp_company->account_id = $this->account->id;
|
$tmp_company->account_id = $this->account->id;
|
||||||
|
|
||||||
nlog($tmp_company);
|
|
||||||
|
|
||||||
if(Ninja::isHosted())
|
if(Ninja::isHosted())
|
||||||
$tmp_company->subdomain = MultiDB::randomSubdomainGenerator();
|
$tmp_company->subdomain = MultiDB::randomSubdomainGenerator();
|
||||||
else
|
else
|
||||||
|
@ -46,7 +46,7 @@ class SupportMessageSent extends Mailable
|
|||||||
$log_file->seek(PHP_INT_MAX);
|
$log_file->seek(PHP_INT_MAX);
|
||||||
$last_line = $log_file->key();
|
$last_line = $log_file->key();
|
||||||
|
|
||||||
$lines = new LimitIterator($log_file, $last_line - 100, $last_line);
|
$lines = new LimitIterator($log_file, max(0,$last_line - 100), $last_line);
|
||||||
$log_lines = iterator_to_array($lines);
|
$log_lines = iterator_to_array($lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ class SupportMessageSent extends Mailable
|
|||||||
->replyTo($user->email, $user->present()->name())
|
->replyTo($user->email, $user->present()->name())
|
||||||
->subject($subject)
|
->subject($subject)
|
||||||
->view('email.support.message', [
|
->view('email.support.message', [
|
||||||
'support_message' => $this->data['message'],
|
'support_message' => nl2br($this->data['message']),
|
||||||
'system_info' => $system_info,
|
'system_info' => $system_info,
|
||||||
'laravel_log' => $log_lines,
|
'laravel_log' => $log_lines,
|
||||||
'logo' => $company->present()->logo(),
|
'logo' => $company->present()->logo(),
|
||||||
|
@ -99,6 +99,7 @@ class Company extends BaseModel
|
|||||||
'report_include_drafts',
|
'report_include_drafts',
|
||||||
'client_registration_fields',
|
'client_registration_fields',
|
||||||
'convert_rate_to_client',
|
'convert_rate_to_client',
|
||||||
|
'markdown_email_enabled',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
|
@ -255,9 +255,6 @@ class CreditCard
|
|||||||
|
|
||||||
$response = $this->eway_driver->init()->eway->createTransaction(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
|
$response = $this->eway_driver->init()->eway->createTransaction(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
|
||||||
|
|
||||||
nlog('eway');
|
|
||||||
nlog($response);
|
|
||||||
|
|
||||||
$response_status = ErrorCode::getStatus($response->ResponseMessage);
|
$response_status = ErrorCode::getStatus($response->ResponseMessage);
|
||||||
|
|
||||||
if(!$response_status['success']){
|
if(!$response_status['success']){
|
||||||
|
@ -151,8 +151,6 @@ class PayFastPaymentDriver extends BaseDriver
|
|||||||
if($this->company_gateway->getConfigField('passphrase'))
|
if($this->company_gateway->getConfigField('passphrase'))
|
||||||
$fields['passphrase'] = $this->company_gateway->getConfigField('passphrase');
|
$fields['passphrase'] = $this->company_gateway->getConfigField('passphrase');
|
||||||
|
|
||||||
nlog(http_build_query($fields));
|
|
||||||
|
|
||||||
return md5(http_build_query($fields));
|
return md5(http_build_query($fields));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace App\Repositories;
|
|||||||
|
|
||||||
use App\Factory\ClientFactory;
|
use App\Factory\ClientFactory;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
|
use App\Models\Company;
|
||||||
use App\Utils\Traits\GeneratesCounter;
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
use App\Utils\Traits\SavesDocuments;
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
|
||||||
@ -60,9 +61,9 @@ class ClientRepository extends BaseRepository
|
|||||||
|
|
||||||
$client->fill($data);
|
$client->fill($data);
|
||||||
|
|
||||||
|
if(!$client->country_id){
|
||||||
if(auth()->user() && !$client->country_id){
|
$company = Company::find($client->company_id);
|
||||||
$client->country_id = auth()->user()->company()->settings->country_id;
|
$client->country_id = $company->settings->country_id;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ class TaskRepository extends BaseRepository
|
|||||||
|
|
||||||
$last = end($log);
|
$last = end($log);
|
||||||
|
|
||||||
if($last[1] !== 0){
|
if(is_array($last) && $last[1] !== 0){
|
||||||
|
|
||||||
$new = [time(), 0];
|
$new = [time(), 0];
|
||||||
$log = array_merge($log, [$new]);
|
$log = array_merge($log, [$new]);
|
||||||
@ -212,6 +212,7 @@ class TaskRepository extends BaseRepository
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stop(Task $task)
|
public function stop(Task $task)
|
||||||
@ -220,7 +221,7 @@ class TaskRepository extends BaseRepository
|
|||||||
|
|
||||||
$last = end($log);
|
$last = end($log);
|
||||||
|
|
||||||
if($last[1] === 0){
|
if(is_array($last) && $last[1] === 0){
|
||||||
|
|
||||||
$last[1] = time();
|
$last[1] = time();
|
||||||
|
|
||||||
@ -231,5 +232,21 @@ class TaskRepository extends BaseRepository
|
|||||||
$task->save();
|
$task->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $task;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function triggeredActions($request, $task)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($request->has('start') && $request->input('start') == 'true') {
|
||||||
|
$task = $this->start($task);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('stop') && $request->input('stop') == 'true') {
|
||||||
|
$task = $this->stop($task);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,70 +41,15 @@ class HandleRestore extends AbstractService
|
|||||||
|
|
||||||
foreach ($this->invoice->payments as $payment) {
|
foreach ($this->invoice->payments as $payment) {
|
||||||
//restore the payment record
|
//restore the payment record
|
||||||
// $payment->restore();
|
|
||||||
$this->invoice->restore();
|
$this->invoice->restore();
|
||||||
|
|
||||||
// //determine the paymentable amount before paymentable restoration
|
|
||||||
// $pre_restore_amount = $payment->paymentables()
|
|
||||||
// ->where('paymentable_type', '=', 'invoices')
|
|
||||||
// ->sum(\DB::raw('amount'));
|
|
||||||
|
|
||||||
// nlog("first pre restore amount = {$pre_restore_amount}");
|
|
||||||
|
|
||||||
// $pre_restore_amount -= $payment->paymentables()
|
|
||||||
// ->where('paymentable_type', '=', 'invoices')
|
|
||||||
// ->sum(\DB::raw('refunded'));
|
|
||||||
|
|
||||||
// nlog("second pre restore amount = {$pre_restore_amount}");
|
|
||||||
|
|
||||||
|
|
||||||
//restore the paymentables
|
|
||||||
// $payment->paymentables()
|
|
||||||
// ->where('paymentable_type', '=', 'invoices')
|
|
||||||
// ->where('paymentable_id', $this->invoice->id)
|
|
||||||
// ->restore();
|
|
||||||
|
|
||||||
//determine the post restore paymentable amount (we need to increment the payment amount by the difference between pre and post)
|
|
||||||
// $payment_amount = $payment->paymentables()
|
|
||||||
// ->where('paymentable_type', '=', 'invoices')
|
|
||||||
// ->sum(\DB::raw('amount'));
|
|
||||||
|
|
||||||
// nlog("first payment_amount = {$payment_amount}");
|
|
||||||
|
|
||||||
// $payment_amount -= $payment->paymentables()
|
|
||||||
// ->where('paymentable_type', '=', 'invoices')
|
|
||||||
// ->sum(\DB::raw('refunded'));
|
|
||||||
|
|
||||||
// nlog("second payment_amount = {$payment_amount}");
|
|
||||||
|
|
||||||
// nlog($payment->amount . " == " . $payment_amount);
|
|
||||||
|
|
||||||
// if ($payment->amount == $payment_amount) {
|
|
||||||
// $payment->is_deleted = false;
|
|
||||||
// $payment->save();
|
|
||||||
|
|
||||||
// $this->payment_total += $payment_amount;
|
|
||||||
// } else {
|
|
||||||
// $payment->is_deleted = false;
|
|
||||||
// $payment->amount += ($payment_amount - $pre_restore_amount);
|
|
||||||
// $payment->applied += ($payment_amount - $pre_restore_amount);
|
|
||||||
// $payment->save();
|
|
||||||
|
|
||||||
// $this->payment_total += ($payment_amount - $pre_restore_amount);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//adjust ledger balance
|
//adjust ledger balance
|
||||||
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance, "Restored invoice {$this->invoice->number}")->save();
|
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance, "Restored invoice {$this->invoice->number}")->save();
|
||||||
|
|
||||||
//adjust paid to dates
|
|
||||||
// $this->invoice->client->service()->updatePaidToDate($this->payment_total)->save();
|
|
||||||
|
|
||||||
$this->invoice->client->service()->updateBalance($this->invoice->balance)->save();
|
$this->invoice->client->service()->updateBalance($this->invoice->balance)->save();
|
||||||
|
|
||||||
// you only need to touch the ledger ONCE per transaction.
|
|
||||||
// $this->invoice->ledger()->updatePaymentBalance($this->payment_total*-1, "Restored payment for invoice {$this->invoice->number}")->save();
|
|
||||||
|
|
||||||
$this->windBackInvoiceNumber();
|
$this->windBackInvoiceNumber();
|
||||||
|
|
||||||
$this->invoice->is_deleted = false;
|
$this->invoice->is_deleted = false;
|
||||||
|
@ -96,10 +96,10 @@ class MarkPaid extends AbstractService
|
|||||||
$payment->ledger()
|
$payment->ledger()
|
||||||
->updatePaymentBalance($payment->amount * -1);
|
->updatePaymentBalance($payment->amount * -1);
|
||||||
|
|
||||||
$client = $this->invoice->client->fresh();
|
$this->invoice->client->fresh();
|
||||||
$client->paid_to_date += $payment->amount;
|
$this->invoice->client->paid_to_date += $payment->amount;
|
||||||
$client->balance += $payment->amount * -1;
|
$this->invoice->client->balance += $payment->amount * -1;
|
||||||
$client->save();
|
$this->invoice->client->push();
|
||||||
|
|
||||||
$this->invoice = $this->invoice
|
$this->invoice = $this->invoice
|
||||||
->service()
|
->service()
|
||||||
|
@ -47,12 +47,6 @@ class MarkSent extends AbstractService
|
|||||||
->updateBalance($adjustment, true)
|
->updateBalance($adjustment, true)
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
/*Adjust client balance*/
|
|
||||||
$this->client
|
|
||||||
->service()
|
|
||||||
->updateBalance($adjustment)
|
|
||||||
->save();
|
|
||||||
|
|
||||||
/*Update ledger*/
|
/*Update ledger*/
|
||||||
$this->invoice
|
$this->invoice
|
||||||
->ledger()
|
->ledger()
|
||||||
@ -68,6 +62,12 @@ class MarkSent extends AbstractService
|
|||||||
->setReminder()
|
->setReminder()
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
|
/*Adjust client balance*/
|
||||||
|
$this->client->fresh();
|
||||||
|
$this->client->balance += $adjustment;
|
||||||
|
$this->client->save();
|
||||||
|
|
||||||
|
|
||||||
$this->invoice->markInvitationsSent();
|
$this->invoice->markInvitationsSent();
|
||||||
|
|
||||||
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
@ -57,6 +57,9 @@ class TriggeredActions extends AbstractService
|
|||||||
$this->invoice = $this->invoice->service()->markSent()->save();
|
$this->invoice = $this->invoice->service()->markSent()->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->request->has('cancel') && $this->request->input('cancel') == 'true') {
|
||||||
|
$this->invoice = $this->invoice->service()->handleCancellation()->save();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->invoice;
|
return $this->invoice;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ class Design extends BaseDesign
|
|||||||
|
|
||||||
$elements = [
|
$elements = [
|
||||||
['element' => 'div', 'properties' => ['style' => 'display: flex; flex-direction: column;'], 'elements' => [
|
['element' => 'div', 'properties' => ['style' => 'display: flex; flex-direction: column;'], 'elements' => [
|
||||||
['element' => 'p', 'content' => strtr(str_replace("labels", "", $_variables['values']['$entity.public_notes']), $_variables), 'properties' => ['data-ref' => 'total_table-public_notes', 'style' => 'text-align: left;']],
|
['element' => 'p', 'content' => strtr(str_replace(["labels","values"], ["",""], $_variables['values']['$entity.public_notes']), $_variables), 'properties' => ['data-ref' => 'total_table-public_notes', 'style' => 'text-align: left;']],
|
||||||
['element' => 'p', 'content' => '', 'properties' => ['style' => 'text-align: left; display: flex; flex-direction: column; page-break-inside: auto;'], 'elements' => [
|
['element' => 'p', 'content' => '', 'properties' => ['style' => 'text-align: left; display: flex; flex-direction: column; page-break-inside: auto;'], 'elements' => [
|
||||||
['element' => 'span', 'content' => '$entity.terms_label: ', 'properties' => ['hidden' => $this->entityVariableCheck('$entity.terms'), 'data-ref' => 'total_table-terms-label', 'style' => 'font-weight: bold; text-align: left; margin-top: 1rem;']],
|
['element' => 'span', 'content' => '$entity.terms_label: ', 'properties' => ['hidden' => $this->entityVariableCheck('$entity.terms'), 'data-ref' => 'total_table-terms-label', 'style' => 'font-weight: bold; text-align: left; margin-top: 1rem;']],
|
||||||
['element' => 'span', 'content' => strtr(str_replace("labels", "", $_variables['values']['$entity.terms']), $_variables['labels']), 'properties' => ['data-ref' => 'total_table-terms', 'style' => 'text-align: left;']],
|
['element' => 'span', 'content' => strtr(str_replace("labels", "", $_variables['values']['$entity.terms']), $_variables['labels']), 'properties' => ['data-ref' => 'total_table-terms', 'style' => 'text-align: left;']],
|
||||||
|
@ -50,6 +50,10 @@ class TriggeredActions extends AbstractService
|
|||||||
$this->quote = $this->quote->service()->convert()->save();
|
$this->quote = $this->quote->service()->convert()->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->request->has('approve') && $this->request->input('approve') == 'true' && in_array($this->quote->status_id, [Quote::STATUS_SENT, Quote::STATUS_DRAFT])) {
|
||||||
|
$this->quote = $this->quote->service()->convert()->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $this->quote;
|
return $this->quote;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'report_include_drafts' => (bool) $company->report_include_drafts,
|
'report_include_drafts' => (bool) $company->report_include_drafts,
|
||||||
'client_registration_fields' => (array) $company->client_registration_fields,
|
'client_registration_fields' => (array) $company->client_registration_fields,
|
||||||
'convert_rate_to_client' => (bool) $company->convert_rate_to_client,
|
'convert_rate_to_client' => (bool) $company->convert_rate_to_client,
|
||||||
|
'markdown_email_enabled' => (bool) $company->markdown_email_enabled,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||||
'app_version' => '5.3.77',
|
'app_version' => '5.3.78',
|
||||||
'app_tag' => '5.3.77',
|
'app_tag' => '5.3.78',
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', ''),
|
'api_secret' => env('API_SECRET', ''),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
use App\Models\Gateway;
|
use App\Models\Gateway;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
@ -27,6 +28,10 @@ class ReverseAppleDomainForHosted extends Migration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Company::cursor()->each(function ($company){
|
||||||
|
$company->update(['markdown_email_enabled' => true]);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
@component('email.template.admin', ['settings' => $settings, 'logo' => $logo ?? 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
|
@component('email.template.admin', ['settings' => $settings, 'logo' => $logo ?? 'https://www.invoiceninja.com/wp-content/uploads/2015/10/logo-white-horizontal-1.png'])
|
||||||
{{-- Body --}}
|
{{-- Body --}}
|
||||||
{{ $support_message }}
|
{!! $support_message !!}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
{!! str_replace('\n', '<br>', $system_info) !!}
|
{!! str_replace('\n', '<br>', $system_info) !!}
|
||||||
|
|
||||||
|
@ -211,5 +211,76 @@ class RecurringExpenseApiTest extends TestCase
|
|||||||
$this->assertEquals(RecurringInvoice::STATUS_PAUSED, $arr['data'][0]['status_id']);
|
$this->assertEquals(RecurringInvoice::STATUS_PAUSED, $arr['data'][0]['status_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRecurringExpenseStartedWithTriggeredAction()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'ids' => [$this->encodePrimaryKey($this->recurring_expense->id)],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->put('/api/v1/recurring_expenses/'.$this->recurring_expense->hashed_id.'?start=true', []);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_ACTIVE, $arr['data']['status_id']);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->put('/api/v1/recurring_expenses/'.$this->recurring_expense->hashed_id.'?stop=true', []);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_PAUSED, $arr['data']['status_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRecurringExpensePostWithStartAction()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'amount' => 10,
|
||||||
|
'client_id' => $this->client->hashed_id,
|
||||||
|
'number' => '123321',
|
||||||
|
'frequency_id' => 5,
|
||||||
|
'remaining_cycles' =>5
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/recurring_expenses?start=true', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_ACTIVE, $arr['data']['status_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testRecurringExpensePostWithStopAction()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'amount' => 10,
|
||||||
|
'client_id' => $this->client->hashed_id,
|
||||||
|
'number' => '1233x21',
|
||||||
|
'frequency_id' => 5,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/recurring_expenses?stop=true', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_PAUSED, $arr['data']['status_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,79 @@ class RecurringInvoiceTest extends TestCase
|
|||||||
$this->makeTestData();
|
$this->makeTestData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPostRecurringInvoice()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'frequency_id' => 1,
|
||||||
|
'status_id' => 1,
|
||||||
|
'discount' => 0,
|
||||||
|
'is_amount_discount' => 1,
|
||||||
|
'po_number' => '3434343',
|
||||||
|
'public_notes' => 'notes',
|
||||||
|
'is_deleted' => 0,
|
||||||
|
'custom_value1' => 0,
|
||||||
|
'custom_value2' => 0,
|
||||||
|
'custom_value3' => 0,
|
||||||
|
'custom_value4' => 0,
|
||||||
|
'status' => 1,
|
||||||
|
'client_id' => $this->encodePrimaryKey($this->client->id),
|
||||||
|
'line_items' => $this->buildLineItems(),
|
||||||
|
'remaining_cycles' => -1,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/recurring_invoices/', $data)
|
||||||
|
->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_DRAFT, $arr['data']['status_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPostRecurringInvoiceWithStartAndStop()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'frequency_id' => 1,
|
||||||
|
'status_id' => 1,
|
||||||
|
'discount' => 0,
|
||||||
|
'is_amount_discount' => 1,
|
||||||
|
'po_number' => '3434343',
|
||||||
|
'public_notes' => 'notes',
|
||||||
|
'is_deleted' => 0,
|
||||||
|
'custom_value1' => 0,
|
||||||
|
'custom_value2' => 0,
|
||||||
|
'custom_value3' => 0,
|
||||||
|
'custom_value4' => 0,
|
||||||
|
'status' => 1,
|
||||||
|
'client_id' => $this->encodePrimaryKey($this->client->id),
|
||||||
|
'line_items' => $this->buildLineItems(),
|
||||||
|
'remaining_cycles' => -1,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/recurring_invoices?start=true', $data)
|
||||||
|
->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_ACTIVE, $arr['data']['status_id']);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->put('/api/v1/recurring_invoices/'.$arr['data']['id'].'?stop=true', $data)
|
||||||
|
->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$this->assertEquals(RecurringInvoice::STATUS_PAUSED, $arr['data']['status_id']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testRecurringInvoiceList()
|
public function testRecurringInvoiceList()
|
||||||
{
|
{
|
||||||
Client::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) {
|
Client::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) {
|
||||||
|
@ -90,7 +90,7 @@ class TaskApiTest extends TestCase
|
|||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
|
|
||||||
$this->assertEquals('taskynumber', $arr['data']['number']);
|
$this->assertEquals('taskynumber', $arr['data']['number']);
|
||||||
|
$this->assertLessThan(5, strlen($arr['data']['time_log']));
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
'X-API-SECRET' => config('ninja.api_secret'),
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
@ -113,6 +113,23 @@ class TaskApiTest extends TestCase
|
|||||||
$this->assertNotEmpty($arr['data']['number']);
|
$this->assertNotEmpty($arr['data']['number']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTaskPostNoDefinedTaskNumber()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'description' => $this->faker->firstName,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$this->assertNotEmpty($arr['data']['number']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testTaskPostWithActionStart()
|
public function testTaskPostWithActionStart()
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
@ -224,4 +241,46 @@ class TaskApiTest extends TestCase
|
|||||||
|
|
||||||
$this->assertTrue($arr['data'][0]['is_deleted']);
|
$this->assertTrue($arr['data'][0]['is_deleted']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testTaskPostWithStartAction()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'description' => $this->faker->firstName,
|
||||||
|
'number' => 'taskynumber2'
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks?start=true', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$this->assertEquals('taskynumber2', $arr['data']['number']);
|
||||||
|
$this->assertGreaterThan(5, strlen($arr['data']['time_log']));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTaskPostWithStopAction()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'description' => $this->faker->firstName,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks?stop=true', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$this->assertLessThan(5, strlen($arr['data']['time_log']));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,8 @@ class CompanyLedgerTest extends TestCase
|
|||||||
//client->balance should = 10
|
//client->balance should = 10
|
||||||
$invoice->service()->markSent()->save();
|
$invoice->service()->markSent()->save();
|
||||||
|
|
||||||
$this->assertEquals($invoice->client->balance, 10);
|
$this->client = Client::find($this->client->id);
|
||||||
|
$this->assertEquals($this->client->balance, 10);
|
||||||
|
|
||||||
$invoice_ledger = $invoice->company_ledger->sortByDesc('id')->first();
|
$invoice_ledger = $invoice->company_ledger->sortByDesc('id')->first();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user