Invoice Deletion - Ledger (#3590)

* Fixes when implementing

* php_cs

* Clean up

* Clean up

* Working on adjusting ledger when an invoice is deleted
This commit is contained in:
David Bomba 2020-04-04 21:32:42 +11:00 committed by GitHub
parent a87ae37ce1
commit 6d7b7ca9a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 304 additions and 287 deletions

View File

@ -157,8 +157,7 @@ class Designer
} elseif ($this->entity_string == 'quote') {
//$this->exported_variables['$entity_labels'] = $this->processLabels($this->input_variables['quote_details'], $this->quoteDetails($company));
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['quote_details'], $this->quoteDetails($company));
}
else {
} else {
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['invoice_details'], $this->quoteDetails($company));
}
@ -268,7 +267,6 @@ class Designer
private function invoiceDetails(Company $company)
{
$data = [
'$invoice.number' => '<span class="flex justify-between items-center"><span>$invoice.number_label:</span><span> $invoice.number</span></span>',
'$invoice.po_number' => '<span class="flex justify-between items-center"><span>$invoice.po_number_label:</span><span> $invoice.po_number</span></span>',

View File

@ -55,31 +55,24 @@ class Handler extends ExceptionHandler
*/
public function report(Exception $exception)
{
if (app()->bound('sentry') && $this->shouldReport($exception)) {
app('sentry')->configureScope(function (Scope $scope): void {
if(auth()->guard('contact')->user() && auth()->guard('contact')->user()->company->account->report_errors) {
if (auth()->guard('contact')->user() && auth()->guard('contact')->user()->company->account->report_errors) {
$scope->setUser([
'id' => auth()->guard('contact')->user()->company->account->key,
'email' => "anonymous@example.com",
'name' => "Anonymous User",
]);
}
else if (auth()->guard('user')->user() && auth()->user()->company()->account->report_errors) {
} elseif (auth()->guard('user')->user() && auth()->user()->company()->account->report_errors) {
$scope->setUser([
'id' => auth()->user()->account->key,
'email' => "anonymous@example.com",
'name' => "Anonymous User",
]);
}
});
app('sentry')->captureException($exception);
}
parent::report($exception);

View File

@ -158,48 +158,4 @@ class AccountController extends BaseController
return $this->listResponse($ct);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@ -176,7 +176,6 @@ class LoginController extends BaseController
$ct = CompanyUser::whereUserId($user->id);
return $this->listResponse($ct);
} else {
$this->incrementLoginAttempts($request);

View File

@ -81,8 +81,6 @@ class BaseController extends Controller
$include = implode(",", $this->forced_includes);
}
\Log::error(print_r($include,1));
$this->manager->parseIncludes($include);
$this->serializer = request()->input('serializer') ?: EntityTransformer::API_SERIALIZER_ARRAY;
@ -105,14 +103,24 @@ class BaseController extends Controller
->header('X-APP-VERSION', config('ninja.app_version'));
}
/**
* 404 for the client portal
* @return Response 404 response
*/
public function notFoundClient()
{
return abort(404);
}
protected function errorResponse($response, $httpErrorCode = 400)
/**
* API Error response
* @param string $message The return error message
* @param integer $httpErrorCode 404/401/403 etc
* @return Response The JSON response
*/
protected function errorResponse($message, $httpErrorCode = 400)
{
$error['error'] = $response;
$error['error'] = $message;
$error = json_encode($error, JSON_PRETTY_PRINT);
@ -134,15 +142,7 @@ class BaseController extends Controller
$query->with($includes);
if (!auth()->user()->hasPermission('view_'.lcfirst(class_basename($this->entity_type)))) {
// if ($this->entity_type == Company::class || $this->entity_type == Design::class) {
// //no user keys exist on the company table, so we need to skip
// } elseif ($this->entity_type == User::class) {
// //$query->where('id', '=', auth()->user()->id); @todo why?
// } else {
$query->where('user_id', '=', auth()->user()->id);
// }
$query->where('user_id', '=', auth()->user()->id);
}
if (request()->has('updated_at') && request()->input('updated_at') > 0) {

View File

@ -92,7 +92,6 @@ class InvoiceController extends Controller
*/
public function bulk(ProcessInvoicesInBulkRequest $request)
{
$transformed_ids = $this->transformKeys($request->invoices);
if ($request->input('action') == 'payment') {

View File

@ -75,12 +75,12 @@ class EmailController extends BaseController
* property="entity_id",
* description="The entity_id",
* type="string",
* ),
* ),
* @OA\Property(
* property="template",
* description="The template required",
* type="string",
* ),
* ),
* )
* )
* ),
@ -113,16 +113,12 @@ class EmailController extends BaseController
$body = $request->input('body');
$entity_string = strtolower(class_basename($entity_obj));
$entity_obj->invitations->each(function ($invitation) use($subject, $body, $entity_string, $entity_obj) {
$entity_obj->invitations->each(function ($invitation) use ($subject, $body, $entity_string, $entity_obj) {
if ($invitation->contact->send_email && $invitation->contact->email) {
$when = now()->addSeconds(1);
$invitation->contact->notify((new SendGenericNotification($invitation, $entity_string, $subject, $body))->delay($when));
}
});
if ($this instanceof Invoice) {
@ -143,7 +139,5 @@ class EmailController extends BaseController
$entity_obj->service()->markSent()->save();
return $this->itemResponse($entity_obj);
}
}

View File

@ -687,7 +687,6 @@ class InvoiceController extends BaseController
});
if ($invoice->invitations->count() > 0) {
event(new InvoiceWasEmailed($invoice->invitations->first()));
}

View File

@ -47,8 +47,9 @@ class SetupController extends Controller
$mail_driver = $request->input('mail_driver');
if(!$this->failsafeMailCheck($request))
if (!$this->failsafeMailCheck($request)) {
$mail_driver = 'log';
}
$_ENV['APP_KEY'] = config('app.key');
$_ENV['APP_URL'] = $request->input('url');
@ -162,14 +163,13 @@ class SetupController extends Controller
private function failsafeMailCheck($request)
{
$response_array = SystemHealth::testMailServer($request);
if($response_array instanceof Response)
if ($response_array instanceof Response) {
return true;
}
return false;
}
}

View File

@ -30,16 +30,14 @@ trait VerifiesUserEmail
public function confirm()
{
if ($user = User::whereRaw("BINARY `confirmation_code`= ?", request()->route('confirmation_code'))->first()) {
$user->email_verified_at = now();
$user->confirmation_code = null;
$user->save();
return response()->json(['message' => ctrans('texts.security_confirmation')]);
//return redirect()->route('dashboard.index')->with('message', ctrans('texts.security_confirmation'));
}
return response()->json(['message' => ctrans('texts.wrong_confirmation')]);
//return redirect()->route('login')->with('message', ctrans('texts.wrong_confirmation'));
}
}

View File

@ -47,11 +47,10 @@ class QueryLogging
$count = count($queries);
$timeEnd = microtime(true);
$time = $timeEnd - $timeStart;
// Log::info($request->method() . ' - ' . $request->url() . ": $count queries - " . $time);
// Log::info($request->method() . ' - ' . $request->url() . ": $count queries - " . $time);
// if($count > 50)
// Log::info($queries);
}
}

View File

@ -56,5 +56,4 @@ class UpdateCompanyRequest extends Request
protected function prepareForValidation()
{
}
}

View File

@ -50,11 +50,13 @@ class SendEmailRequest extends Request
$settings = auth()->user()->company()->settings;
if(empty($input['template']))
if (empty($input['template'])) {
$input['template'] = '';
}
if(!property_exists($settings, $input['template']))
if (!property_exists($settings, $input['template'])) {
unset($input['template']);
}
$input['entity_id'] = $this->decodePrimaryKey($input['entity_id']);
$input['entity'] = "App\Models\\". ucfirst($input['entity']);
@ -74,8 +76,7 @@ class SendEmailRequest extends Request
$input = $this->all();
/*Make sure we have all the require ingredients to send a template*/
if(array_key_exists('entity', $input) && array_key_exists('entity_id', $input) && is_string($input['entity']) && $input['entity_id']) {
if (array_key_exists('entity', $input) && array_key_exists('entity_id', $input) && is_string($input['entity']) && $input['entity_id']) {
$company = auth()->user()->company();
$entity = $input['entity'];
@ -84,9 +85,9 @@ class SendEmailRequest extends Request
$entity_obj = $entity::whereId($input['entity_id'])->company()->first();
/* Check object, check user and company id is same as users, and check user can edit the object */
if($entity_obj && ($company->id == $entity_obj->company_id) && auth()->user()->can('edit', $entity_obj))
if ($entity_obj && ($company->id == $entity_obj->company_id) && auth()->user()->can('edit', $entity_obj)) {
return true;
}
}
return false;

View File

@ -20,7 +20,6 @@ use Symfony\Component\HttpFoundation\Response;
class CreateAccount
{
use Dispatchable;
protected $request;
@ -32,27 +31,25 @@ class CreateAccount
public function handle()
{
if(config('ninja.environment') == 'selfhost' && Account::all()->count() == 0) {
if (config('ninja.environment') == 'selfhost' && Account::all()->count() == 0) {
return $this->create();
}elseif (config('ninja.environment') == 'selfhost' && Account::all()->count() > 1) {
return response()->json(array('message' => Ninja::selfHostedMessage()), 400);
} elseif (config('ninja.environment') == 'selfhost' && Account::all()->count() > 1) {
return response()->json(array('message' => Ninja::selfHostedMessage()), 400);
} elseif (!Ninja::boot()) {
return response()->json(array('message' => Ninja::parse()), 401);
return response()->json(array('message' => Ninja::parse()), 401);
}
return $this->create();
}
private function create()
{
$sp794f3f = Account::create($this->request);
$sp794f3f->referral_code = Str::random(32);
if(!$sp794f3f->key)
if (!$sp794f3f->key) {
$sp794f3f->key = Str::random(32);
}
$sp794f3f->save();
@ -80,7 +77,5 @@ class CreateAccount
$sp035a66->notification(new NewAccountCreated($spaa9f78, $sp035a66))->ninja();
return $sp794f3f;
}
}

View File

@ -65,7 +65,6 @@ class StartMigration implements ShouldQueue
*/
public function handle()
{
MultiDB::setDb($this->company->db);
auth()->login($this->user, false);
@ -80,7 +79,6 @@ class StartMigration implements ShouldQueue
$filename = pathinfo($this->filepath, PATHINFO_FILENAME);
try {
if (!$archive) {
throw new ProcessingMigrationArchiveFailed('Processing migration archive failed. Migration file is possibly corrupted.');
}
@ -103,10 +101,7 @@ class StartMigration implements ShouldQueue
$data = json_decode(file_get_contents($file), 1);
Import::dispatchNow($data, $this->company, $this->user);
} catch (NonExistingMigrationFile | ProcessingMigrationArchiveFailed | ResourceNotAvailableForMigration | MigrationValidatorFailed | ResourceDependencyMissing $e) {
$this->company->setMigration(false);
Mail::to($this->user)->send(new MigrationFailed($e, $e->getMessage()));
@ -115,11 +110,9 @@ class StartMigration implements ShouldQueue
info($e->getMessage());
}
}
}
public function failed($exception = null)
{
}
}

View File

@ -182,7 +182,6 @@ class MultiDB
public static function findAndSetDbByDomain($subdomain) :bool
{
foreach (self::$dbs as $db) {
if ($company = Company::on($db)->whereSubdomain($subdomain)->first()) {
self::setDb($company->db);

View File

@ -0,0 +1,53 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Invoice;
use App\Models\Activity;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Repositories\ActivityRepository;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
class DeleteInvoiceActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @return void
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
$fields = new \stdClass;
$fields->invoice_id = $event->invoice->id;
$fields->user_id = $event->invoice->user_id;
$fields->company_id = $event->invoice->company_id;
$fields->activity_type_id = Activity::DELETE_INVOICE;
$this->activity_repo->save($fields, $event->invoice);
}
}

View File

@ -44,15 +44,14 @@ class PaymentNotification implements ShouldQueue
$payment = $event->payment;
foreach ($payment->company->company_users as $company_user) {
$user = $company_user->user;
$notification = new NewPaymentNotification($payment, $payment->company);
$notification->method = $this->findUserEntityNotificationType($payment, $company_user, ['all_notifications']);
if($user)
if ($user) {
$user->notify($notification);
}
}
if (isset($payment->company->slack_webhook_url)) {

View File

@ -47,14 +47,10 @@ class SendVerificationNotification implements ShouldQueue
MultiDB::setDB($event->company->db);
try {
$event->user->notify(new VerifyUser($event->user));
Ninja::registerNinjaUser($event->user);
}
catch(\Exception $e){
} catch (\Exception $e) {
}
}
}

View File

@ -39,7 +39,7 @@ class UpdateUserLastLogin implements ShouldQueue
* @return void
*/
public function handle($event)
{
{
$user = $event->user;
$user->last_login = now();

View File

@ -332,16 +332,14 @@ class Client extends BaseModel implements HasLocalePreference
{
$company_gateways = $this->getSetting('company_gateway_ids');
info($company_gateways);
info($this->company->id);
info($company_gateways);
info($this->company->id);
if (strlen($company_gateways)>=1) {
$gateways = $this->company->company_gateways->whereIn('id', $payment_gateways);
} else {
$gateways = $this->company->company_gateways;
}
\Log::error($gateways);
foreach ($gateways as $gateway) {
if (in_array(GatewayType::CREDIT_CARD, $gateway->driver($this)->gatewayTypes())) {
return $gateway;

View File

@ -391,10 +391,9 @@ class Company extends BaseModel
public function setMigration($status)
{
$this->company_users->each(function ($cu) use($status){
$this->company_users->each(function ($cu) use ($status) {
$cu->is_migrating=$status;
$cu->save();
});
}
}

View File

@ -55,12 +55,12 @@ class CompanyUser extends Pivot
public function user_pivot()
{
return $this->hasOne(User::class)->withPivot('permissions', 'settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url','migrating');
return $this->hasOne(User::class)->withPivot('permissions', 'settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url', 'migrating');
}
public function company_pivot()
{
return $this->hasOne(Company::class)->withPivot('permissions', 'settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url','migrating');
return $this->hasOne(Company::class)->withPivot('permissions', 'settings', 'is_admin', 'is_owner', 'is_locked', 'slack_webhook_url', 'migrating');
}
public function user()

View File

@ -78,26 +78,29 @@ class Credit extends BaseModel
const STATUS_PARTIAL = 3;
const STATUS_APPLIED = 4;
public function getDateAttribute($value) {
public function getDateAttribute($value)
{
if (!empty($value)) {
//$value format 'Y:m:d H:i:s' to 'Y-m-d H:i'
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getDueDateAttribute($value) {
public function getDueDateAttribute($value)
{
if (!empty($value)) {
//$value format 'Y:m:d H:i:s' to 'Y-m-d H:i'
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getPartialDueDateAttribute($value) {
public function getPartialDueDateAttribute($value)
{
if (!empty($value)) {
//$value format 'Y:m:d H:i:s' to 'Y-m-d H:i'
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -33,30 +33,34 @@ class CreditInvitation extends BaseModel
// 'company',
];
public function getSignatureDateAttribute($value) {
public function getSignatureDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getSentDateAttribute($value) {
public function getSentDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getViewedDateAttribute($value) {
public function getViewedDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getOpenedDateAttribute($value) {
public function getOpenedDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -128,23 +128,26 @@ class Invoice extends BaseModel
const STATUS_UNPAID = -2;
const STATUS_REVERSED = -3;
public function getDateAttribute($value) {
public function getDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getDueDateAttribute($value) {
public function getDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getPartialDueDateAttribute($value) {
public function getPartialDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -34,30 +34,34 @@ class InvoiceInvitation extends BaseModel
];
public function getSignatureDateAttribute($value) {
public function getSignatureDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getSentDateAttribute($value) {
public function getSentDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getViewedDateAttribute($value) {
public function getViewedDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getOpenedDateAttribute($value) {
public function getOpenedDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -84,23 +84,26 @@ class Quote extends BaseModel
const STATUS_APPROVED = 3;
const STATUS_EXPIRED = -1;
public function getDateAttribute($value) {
public function getDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getDueDateAttribute($value) {
public function getDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getPartialDueDateAttribute($value) {
public function getPartialDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -27,30 +27,34 @@ class QuoteInvitation extends BaseModel
'client_contact_id',
];
public function getSignatureDateAttribute($value) {
public function getSignatureDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getSentDateAttribute($value) {
public function getSentDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getViewedDateAttribute($value) {
public function getViewedDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getOpenedDateAttribute($value) {
public function getOpenedDateAttribute($value)
{
if (!$value) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -111,23 +111,26 @@ class RecurringInvoice extends BaseModel
'status'
];
public function getDateAttribute($value) {
public function getDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getDueDateAttribute($value) {
public function getDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getPartialDueDateAttribute($value) {
public function getPartialDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -94,23 +94,26 @@ class RecurringQuote extends BaseModel
// 'company',
];
public function getDateAttribute($value) {
public function getDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getDueDateAttribute($value) {
public function getDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}
public function getPartialDueDateAttribute($value) {
public function getPartialDueDateAttribute($value)
{
if (!empty($value)) {
return (new Carbon($value))->format('Y-m-d');
return (new Carbon($value))->format('Y-m-d');
}
return $value;
}

View File

@ -289,8 +289,9 @@ class User extends Authenticatable implements MustVerifyEmail
$parts = explode("_", $permission);
$all_permission = '';
if(count($parts) > 1)
if (count($parts) > 1) {
$all_permission = $parts[0] . '_all';
}
return $this->isOwner() ||
$this->isAdmin() ||

View File

@ -89,7 +89,7 @@ class InvoiceViewedNotification extends Notification implements ShouldQueue
// if($this->settings->email_style == 'custom'){
// $subject =
// $subject =
// return (new MailMessage)
// ->subject($subject)

View File

@ -35,13 +35,11 @@ class NewPaymentNotification extends Notification implements ShouldQueue
public function __construct($payment, $company, $is_system = false, $settings = null)
{
$this->payment = $payment;
$this->company = $company;
$this->settings = $payment->client->getMergedSettings();
$this->is_system = $is_system;
$this->method = null;
}
/**

View File

@ -70,13 +70,12 @@ class SendGenericNotification extends Notification implements ShouldQueue
*/
public function toMail($notifiable)
{
$subject = $this->generateEmailEntityHtml($this->entity, $this->subject, $this->contact);
$body = $this->generateEmailEntityHtml($this->entity, $this->body, $this->contact);
$design_style = $this->settings->email_style;
if($design_style == 'custom') {
if ($design_style == 'custom') {
$email_style_custom = $this->settings->email_style_custom;
$body = str_replace("$body", $body, $email_style_custom);
}
@ -96,7 +95,6 @@ class SendGenericNotification extends Notification implements ShouldQueue
return (new MailMessage)
->subject($subject)
->markdown('email.admin.generic_email', $data);
}
/**
@ -114,7 +112,6 @@ class SendGenericNotification extends Notification implements ShouldQueue
public function toSlack($notifiable)
{
return '';
// $logo = $this->company->present()->logo();
// $amount = Number::formatMoney($this->invoice->amount, $this->invoice->client);

View File

@ -43,7 +43,6 @@ use Illuminate\Support\Facades\Queue;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Queue\Events\JobProcessing;
class AppServiceProvider extends ServiceProvider
{
/**
@ -89,7 +88,6 @@ class AppServiceProvider extends ServiceProvider
// \Log::error('Event Job '.$event->job->getJobId);
// // \Log::info('Event Job '.$event->job->payload());
// });
}
/**
@ -100,8 +98,6 @@ class AppServiceProvider extends ServiceProvider
public function register()
{
$this->loadHelpers();
}
protected function loadHelpers()

View File

@ -16,6 +16,7 @@ use App\Events\Company\CompanyWasDeleted;
use App\Events\Contact\ContactLoggedIn;
use App\Events\Credit\CreditWasMarkedSent;
use App\Events\Invoice\InvoiceWasCreated;
use App\Events\Invoice\InvoiceWasDeleted;
use App\Events\Invoice\InvoiceWasEmailed;
use App\Events\Invoice\InvoiceWasMarkedSent;
use App\Events\Invoice\InvoiceWasPaid;
@ -39,6 +40,7 @@ use App\Listeners\Invoice\CreateInvoiceActivity;
use App\Listeners\Invoice\CreateInvoiceHtmlBackup;
use App\Listeners\Invoice\CreateInvoiceInvitation;
use App\Listeners\Invoice\CreateInvoicePdf;
use App\Listeners\Invoice\DeleteInvoiceActivity;
use App\Listeners\Invoice\InvoiceEmailActivity;
use App\Listeners\Invoice\InvoiceEmailFailedActivity;
use App\Listeners\Invoice\InvoiceEmailedNotification;
@ -136,7 +138,9 @@ class EventServiceProvider extends ServiceProvider
InvoiceWasEmailedAndFailed::class => [
InvoiceEmailFailedActivity::class,
],
InvoiceWasDeleted::class => [
DeleteInvoiceActivity::class,
],
InvitationWasViewed::class => [
InvitationViewedListener::class
],
@ -166,7 +170,7 @@ class EventServiceProvider extends ServiceProvider
// }
public function boot()
{
parent::boot();
}
{
parent::boot();
}
}

View File

@ -32,13 +32,10 @@ class MultiDBProvider extends ServiceProvider
*/
public function register()
{
$this->app['events']->listen(
\Illuminate\Queue\Events\JobProcessing::class,
function ($event) {
if (isset($event->job->payload()['db'])) {
MultiDB::setDb($event->job->payload()['db']);
}
}
@ -48,6 +45,5 @@ class MultiDBProvider extends ServiceProvider
if ($this->app->runningInConsole()) {
return;
}
}
}

View File

@ -213,11 +213,13 @@ class BaseRepository
/* We need to unset some variable as we sometimes unguard the model */
if(isset($tmp_data['invitations']))
if (isset($tmp_data['invitations'])) {
unset($tmp_data['invitations']);
}
if(isset($tmp_data['client_contacts']))
if (isset($tmp_data['client_contacts'])) {
unset($tmp_data['client_contacts']);
}
$model->fill($tmp_data);

View File

@ -11,6 +11,7 @@
namespace App\Repositories;
use App\Events\Invoice\InvoiceWasDeleted;
use App\Factory\InvoiceInvitationFactory;
use App\Jobs\Product\UpdateOrCreateProduct;
use App\Models\Client;
@ -66,4 +67,20 @@ class InvoiceRepository extends BaseRepository
{
return InvoiceInvitation::whereRaw("BINARY `key`= ?", [$key])->first();
}
public function delete($invoice)
{
if ($invoice->is_deleted) {
return;
}
$invoice->is_deleted = true;
$invoice->save();
$invoice->delete();
if (class_exists($className)) {
event(new InvoiceWasDeleted($invoice));
}
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Services\Invoice;
use App\Events\Payment\PaymentWasCreated;
use App\Factory\PaymentFactory;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\AbstractService;
use App\Services\Client\ClientService;
use App\Services\Payment\PaymentService;
use App\Utils\Traits\GeneratesCounter;
class HandleDeletion extends AbstractService
{
use GeneratesCounter;
private $invoice;
public function __construct(Invoice $invoice)
{
$this->invoice = $invoice;
}
public function run()
{
$balance_remainig = $this->invoice->balance;
$total_paid = $this->invoice->amount - $this->invoice->balance;
//change invoice status
//set invoice balance to 0
//decrease client balance by $total_paid
//remove paymentables from payment
//decreate client paid_to_date by $total_paid
//generate credit for the $total paid
}
}

View File

@ -18,6 +18,7 @@ use App\Services\Invoice\ApplyNumber;
use App\Services\Invoice\ApplyPayment;
use App\Services\Invoice\CreateInvitations;
use App\Services\Invoice\GetInvoicePdf;
use App\Services\Invoice\HandleDeletion;
use App\Services\Invoice\MarkInvoicePaid;
use App\Services\Invoice\MarkSent;
use App\Services\Invoice\UpdateBalance;
@ -43,9 +44,7 @@ class InvoiceService
*/
public function markPaid()
{
$mark_invoice_paid = new MarkPaid($this->client_service, $this->invoice);
$this->invoice = $mark_invoice_paid->run();
$this->invoice = (new MarkPaid($this->client_service, $this->invoice))->run();
return $this;
}
@ -56,9 +55,7 @@ class InvoiceService
*/
public function applyNumber()
{
$apply_number = new ApplyNumber($this->invoice->client, $this->invoice);
$this->invoice = $apply_number->run();
$this->invoice = (new ApplyNumber($this->invoice->client, $this->invoice))->run();
return $this;
}
@ -71,9 +68,7 @@ class InvoiceService
*/
public function applyPayment(Payment $payment, float $payment_amount)
{
$apply_payment = new ApplyPayment($this->invoice, $payment, $payment_amount);
$this->invoice = $apply_payment->run();
$this->invoice = (new ApplyPayment($this->invoice, $payment, $payment_amount))->run();
return $this;
}
@ -87,29 +82,23 @@ class InvoiceService
*/
public function updateBalance($balance_adjustment)
{
$update_balance = new UpdateBalance($this->invoice, $balance_adjustment);
$this->invoice = $update_balance->run();
$this->invoice = (new UpdateBalance($this->invoice, $balance_adjustment))->run();
return $this;
}
public function createInvitations()
{
$create_invitation = new CreateInvitations($this->invoice);
$this->invoice = $create_invitation->run();
$this->invoice = (new CreateInvitations($this->invoice))->run();
return $this;
}
public function markSent()
{
$mark_sent = new MarkSent($this->invoice->client, $this->invoice);
$this->invoice = (new MarkSent($this->invoice->client, $this->invoice))->run();
$this->invoice = $mark_sent->run();
return $this;
return $this;
}
@ -127,6 +116,13 @@ class InvoiceService
return $send_email->run();
}
public function handleDeletion()
{
$this->invoice = (new HandleDeletion($this->invoice))->run();
return $this;
}
public function markViewed()
{
$this->invoice->last_viewed = Carbon::now()->format('Y-m-d H:i');
@ -166,14 +162,6 @@ class InvoiceService
/**
* Saves the invoice
* @return Invoice object

View File

@ -156,15 +156,14 @@ class TemplateEngine
$data['footer'] = '';
if ($email_style == 'custom') {
$wrapper = $this->settings_entity->getSetting('email_style_custom');
/*If no custom design exists, send back a blank!*/
if(strlen($wrapper) > 1)
if (strlen($wrapper) > 1) {
$wrapper = $this->renderView($wrapper, $data);
else
} else {
$wrapper = '';
}
} else {
$wrapper = $this->getTemplate();
$wrapper = view($this->getTemplatePath($email_style), $data)->render();

View File

@ -98,6 +98,4 @@ trait CompanyGatewayFeesAndLimitsSaver
return $new_arr;
}
}

View File

@ -45,7 +45,12 @@ trait GeneratesCounter
$pattern = $client->getSetting('invoice_number_pattern');
//Determine if we are using client_counters
if (strpos($pattern, 'clientCounter')) {
$counter = $client->settings->invoice_number_counter;
if (property_exists($client->settings, 'invoice_number_counter')) {
$counter = $client->settings->invoice_number_counter;
} else {
$counter = 1;
}
$counter_entity = $client;
} elseif (strpos($pattern, 'groupCounter')) {
$counter = $client->group_settings->invoice_number_counter;
@ -297,6 +302,10 @@ trait GeneratesCounter
{
$settings = $entity->settings;
if ($counter_name == 'invoice_number_counter' && !property_exists($entity->settings, 'invoice_number_counter')) {
$settings->invoice_number_counter = 0;
}
$settings->{$counter_name} = $settings->{$counter_name} + 1;
$entity->settings = $settings;

View File

@ -74,7 +74,6 @@ trait MakesInvoiceHtml
$values = $entity->makeValues($contact);
return $this->parseLabelsAndValues($labels, $values, $content);
}
private function parseLabelsAndValues($labels, $values, $section) :string

View File

@ -19,9 +19,9 @@ trait UserNotifies
{
public function findUserNotificationTypes($invitation, $company_user, $entity_name, $required_permissions) :array
{
if($this->migrationRunning($company_user))
if ($this->migrationRunning($company_user)) {
return [];
}
$notifiable_methods = [];
$notifications = $company_user->notifications;
@ -43,9 +43,9 @@ trait UserNotifies
public function findUserEntityNotificationType($entity, $company_user, $required_permissions) :array
{
if($this->migrationRunning($company_user))
if ($this->migrationRunning($company_user)) {
return [];
}
$notifiable_methods = [];
$notifications = $company_user->notifications;
@ -62,7 +62,6 @@ trait UserNotifies
// array_push($notifiable_methods, 'slack');
return $notifiable_methods;
}
private function migrationRunning($company_user)

View File

@ -11,7 +11,7 @@ return [
'app_env' => env('APP_ENV', 'local'),
'app_url' => env('APP_URL', ''),
'app_domain' => env('APP_DOMAIN', ''),
'app_version' => '0.0.1',
'app_version' => '0.0.2',
'api_version' => '0.0.1',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', ''),

View File

@ -3193,4 +3193,5 @@ return [
'oops_issues' => 'Oops, something doesn\'t look right!',
'open_in_new_tab' => 'Open in new tab',
'complete_your_payment' => 'Complete payment',
];

View File

@ -11,8 +11,7 @@
<div class="col-span-2 h-screen flex">
<div class="m-auto md:w-1/2 lg:w-1/4">
<div class="flex flex-col">
<h1 class="text-center text-3xl">{{ ctrans('texts.account_login') }}</h1>
<p class="text-center mt-1 text-gray-600">{{ ctrans('texts.account_login_text') }}</p>
<h1 class="text-center text-3xl">{{ ctrans('texts.client_portal') }}</h1>
<form action="{{ route('client.login') }}" method="post" class="mt-6">
@csrf
<div class="flex flex-col">
@ -48,9 +47,6 @@
</button>
</div>
</form>
<a href="#" class="uppercase text-sm mt-4 text-center text-grey-600 hover:text-blue-600 ease-in duration-100">
{{ trans('texts.login_create_an_account') }}
</a>
</div>
</div>
</div>

View File

@ -9,12 +9,7 @@
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
*/
*/
Route::get('/api/v1/ping', 'PingController@index')->name('ping');
Route::group(['middleware' => ['api_secret_check']], function () {
@ -86,13 +81,11 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
Route::resource('designs', 'DesignController');// name = (payments. index / create / show / update / destroy / edit
// Route::resource('users', 'UserController')->middleware('password_protected'); // name = (users. index / create / show / update / destroy / edit
Route::get('users', 'UserController@index');
Route::put('users/{user}', 'UserController@update')->middleware('password_protected');
Route::post('users', 'UserController@store')->middleware('password_protected');
Route::post('users/{user}/attach_to_company', 'UserController@attach')->middleware('password_protected');
Route::delete('users/{user}/detach_from_company', 'UserController@detach')->middleware('password_protected');
Route::post('users/bulk', 'UserController@bulk')->name('users.bulk')->middleware('password_protected');
Route::post('migration/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected');

View File

@ -42,7 +42,6 @@ class AccountTest extends TestCase
public function testApiAccountCreation()
{
$data = [
'first_name' => $this->faker->firstName,
'last_name' => $this->faker->lastName,
@ -60,5 +59,4 @@ class AccountTest extends TestCase
$response->assertStatus(200);
}
}

View File

@ -514,7 +514,6 @@ class ClientTest extends TestCase
])->put('/api/v1/clients/' . $client->hashed_id, $data);
} catch (ValidationException $e) {
$message = json_decode($e->validator->getMessageBag(), 1);
//\Log::error($message);
$this->assertNotNull($message);
}

View File

@ -125,22 +125,12 @@ class CompanyTest extends TestCase
$settings->quote_design_id = '1';
$company->settings = $settings;
// $this->withoutExceptionHandling();
// try{
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $token,
])->put('/api/v1/companies/'.$this->encodePrimaryKey($company->id), $company->toArray())
->assertStatus(200)->decodeResponseJson();
// }
// catch(ValidationException $e) {
// // \Log::error('in the validator');
// $message = json_decode($e->validator->getMessageBag(),1);
// \Log::error($message);
// $this->assertNotNull($message);
// }
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),

View File

@ -510,7 +510,6 @@ class PaymentTest extends TestCase
$this->assertTrue(array_key_exists('amount', $message));
}
}
@ -791,7 +790,6 @@ class PaymentTest extends TestCase
$this->assertTrue(array_key_exists('invoices', $message));
}
}

View File

@ -64,7 +64,6 @@ class PreviewTest extends TestCase
$response->assertStatus(200);
}
@ -84,6 +83,5 @@ class PreviewTest extends TestCase
$response->assertStatus(200);
}
}

View File

@ -119,7 +119,6 @@ class RefundTest extends TestCase
])->post('/api/v1/payments/refund', $data);
} catch (ValidationException $e) {
$message = json_decode($e->validator->getMessageBag(), 1);
}
$arr = $response->json();
@ -600,7 +599,6 @@ class RefundTest extends TestCase
$arr = $response->json();
$payment = Payment::find($this->decodePrimaryKey($arr['data']['id']));
}
/*Additional scenarios*/

View File

@ -189,7 +189,6 @@ class MultiDBUserTest extends TestCase
public function test_cross_db_user_linking_succeeds_appropriately()
{
$data = [
'first_name' => 'hey',
'last_name' => 'you',

View File

@ -50,7 +50,6 @@ class ImportTest extends TestCase
$status = class_exists('App\Jobs\Util\Import');
$this->assertTrue($status);
}
// public function testExceptionOnUnavailableResource()

View File

@ -23,6 +23,4 @@ class PdfVariablesTest extends TestCase
{
$this->assertTrue(is_array($this->settings->pdf_variables->client_details));
}
}

View File

@ -32,6 +32,5 @@ class SystemHealthTest extends TestCase
$this->assertTrue($results['extensions'][1]['gd']);
$this->assertTrue($results['extensions'][2]['curl']);
$this->assertTrue($results['extensions'][3]['zip']);
}
}