mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-02 22:57:33 -05:00 
			
		
		
		
	
						commit
						5c81a40461
					
				
							
								
								
									
										37
									
								
								app/Events/Credit/CreditWasViewed.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Events/Credit/CreditWasViewed.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					<?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\Events\Credit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Company;
 | 
				
			||||||
 | 
					use App\Models\CreditWasViewed;
 | 
				
			||||||
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class CreditWasViewed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class CreditWasViewed
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $invitation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $event_vars;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct(CreditInvitation $invitation, Company $company, array $event_vars)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->invitation = $invitation;
 | 
				
			||||||
 | 
					        $this->company = $company;
 | 
				
			||||||
 | 
					        $this->event_vars = $event_vars;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -126,7 +126,7 @@ class Handler extends ExceptionHandler
 | 
				
			|||||||
            return response()->json(['message' => $exception->getMessage()], 400);
 | 
					            return response()->json(['message' => $exception->getMessage()], 400);
 | 
				
			||||||
        } elseif ($exception instanceof GenericPaymentDriverFailure) {
 | 
					        } elseif ($exception instanceof GenericPaymentDriverFailure) {
 | 
				
			||||||
            $data['message'] = $exception->getMessage();
 | 
					            $data['message'] = $exception->getMessage();
 | 
				
			||||||
            dd($data);
 | 
					            //dd($data);
 | 
				
			||||||
           // return view('errors.layout', $data);
 | 
					           // return view('errors.layout', $data);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,12 +11,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
 | 
				
			||||||
use App\Models\Activity;
 | 
					use App\Models\Activity;
 | 
				
			||||||
use App\Transformers\ActivityTransformer;
 | 
					use App\Transformers\ActivityTransformer;
 | 
				
			||||||
 | 
					use App\Utils\Traits\Pdf\PdfMaker;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ActivityController extends BaseController
 | 
					class ActivityController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    use PdfMaker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $entity_type = Activity::class;
 | 
					    protected $entity_type = Activity::class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $entity_transformer = ActivityTransformer::class;
 | 
					    protected $entity_transformer = ActivityTransformer::class;
 | 
				
			||||||
@ -78,7 +82,70 @@ class ActivityController extends BaseController
 | 
				
			|||||||
        $activities = Activity::orderBy('created_at', 'DESC')->company()
 | 
					        $activities = Activity::orderBy('created_at', 'DESC')->company()
 | 
				
			||||||
                                ->take($default_activities);
 | 
					                                ->take($default_activities);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->listResponse($activities);
 | 
					        return $this->listResponse($activities);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *      @OA\Get(
 | 
				
			||||||
 | 
					     *      path="/api/v1/actvities/download_entity/{activity_id}",
 | 
				
			||||||
 | 
					     *      operationId="getActivityHistoricalEntityPdf",
 | 
				
			||||||
 | 
					     *      tags={"actvities"},
 | 
				
			||||||
 | 
					     *      summary="Gets a PDF for the given activity",
 | 
				
			||||||
 | 
					     *      description="Gets a PDF for the given activity",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(
 | 
				
			||||||
 | 
					     *          name="activity_id",
 | 
				
			||||||
 | 
					     *          in="path",
 | 
				
			||||||
 | 
					     *          description="The Activity Hashed ID",
 | 
				
			||||||
 | 
					     *          example="D2J234DFA",
 | 
				
			||||||
 | 
					     *          required=true,
 | 
				
			||||||
 | 
					     *          @OA\Schema(
 | 
				
			||||||
 | 
					     *              type="string",
 | 
				
			||||||
 | 
					     *              format="string",
 | 
				
			||||||
 | 
					     *          ),
 | 
				
			||||||
 | 
					     *      ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="PDF File",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=404,
 | 
				
			||||||
 | 
					     *          description="No file exists for the given record",
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function downloadHistoricalEntity(DownloadHistoricalEntityRequest $request, Activity $activity)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $backup = $activity->backup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!$backup || !$backup->html_backup)
 | 
				
			||||||
 | 
					            return response()->json(['message'=> 'No backup exists for this activity', 'errors' => new \stdClass], 404);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $pdf = $this->makePdf(null, null, $backup->html_backup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(isset($activity->invoice_id))
 | 
				
			||||||
 | 
					            $filename = $activity->invoice->number . ".pdf";
 | 
				
			||||||
 | 
					        elseif(isset($activity->quote_id))
 | 
				
			||||||
 | 
					            $filename = $activity->quote->number . ".pdf";
 | 
				
			||||||
 | 
					        elseif(isset($activity->credit_id))
 | 
				
			||||||
 | 
					            $filename = $activity->credit->number . ".pdf";
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            $filename = "backup.pdf";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return response()->streamDownload(function () use($pdf) {
 | 
				
			||||||
 | 
					            echo $pdf;
 | 
				
			||||||
 | 
					        }, $filename);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -68,6 +68,7 @@ class BaseController extends Controller
 | 
				
			|||||||
          'company.groups',
 | 
					          'company.groups',
 | 
				
			||||||
          'company.company_gateways.gateway',
 | 
					          'company.company_gateways.gateway',
 | 
				
			||||||
          'company.clients.contacts',
 | 
					          'company.clients.contacts',
 | 
				
			||||||
 | 
					          'company.clients.gateway_tokens',
 | 
				
			||||||
          'company.products',
 | 
					          'company.products',
 | 
				
			||||||
          'company.invoices.invitations.contact',
 | 
					          'company.invoices.invitations.contact',
 | 
				
			||||||
          'company.invoices.invitations.company',
 | 
					          'company.invoices.invitations.company',
 | 
				
			||||||
 | 
				
			|||||||
@ -49,7 +49,7 @@ class DocumentController extends Controller
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $contact = auth()->user();
 | 
					        $contact = auth()->user();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        Storage::makeDirectory('public/' . $contact->client->client_hash, 0755);
 | 
					        Storage::makeDirectory('public/' . $contact->client->client_hash, 0775);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $path = Storage::putFile('public/' . $contact->client->client_hash, $request->file('file'));
 | 
					        $path = Storage::putFile('public/' . $contact->client->client_hash, $request->file('file'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -11,8 +11,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\ClientPortal;
 | 
					namespace App\Http\Controllers\ClientPortal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Events\Credit\CreditWasViewed;
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasViewed;
 | 
					use App\Events\Invoice\InvoiceWasViewed;
 | 
				
			||||||
use App\Events\Misc\InvitationWasViewed;
 | 
					use App\Events\Misc\InvitationWasViewed;
 | 
				
			||||||
 | 
					use App\Events\Quote\QuoteWasViewed;
 | 
				
			||||||
use App\Http\Controllers\Controller;
 | 
					use App\Http\Controllers\Controller;
 | 
				
			||||||
use App\Models\InvoiceInvitation;
 | 
					use App\Models\InvoiceInvitation;
 | 
				
			||||||
use App\Utils\Ninja;
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
@ -70,7 +72,12 @@ class InvitationController extends Controller
 | 
				
			|||||||
            case 'invoice':
 | 
					            case 'invoice':
 | 
				
			||||||
                event(new InvoiceWasViewed($invitation, $invitation->company, Ninja::eventVars()));
 | 
					                event(new InvoiceWasViewed($invitation, $invitation->company, Ninja::eventVars()));
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            
 | 
					            case 'quote':
 | 
				
			||||||
 | 
					                event(new QuoteWasViewed($invitation, $invitation->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'credit':
 | 
				
			||||||
 | 
					                event(new CreditWasViewed($invitation, $invitation->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					                break;              
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                # code...
 | 
					                # code...
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
				
			|||||||
@ -495,8 +495,82 @@ class CompanyController extends BaseController
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//        ob_flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return response()->json(['message' => 'success'], 200);
 | 
					        return response()->json(['message' => 'success'], 200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Purge Company
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @OA\Post(
 | 
				
			||||||
 | 
					     *      path="/api/v1/companies/purge/{company}",
 | 
				
			||||||
 | 
					     *      operationId="postCompanyPurge",
 | 
				
			||||||
 | 
					     *      tags={"companies"},
 | 
				
			||||||
 | 
					     *      summary="Attempts to purge a company record and all its child records",
 | 
				
			||||||
 | 
					     *      description="Attempts to purge a company record and all its child records",
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
 | 
				
			||||||
 | 
					     *      @OA\Parameter(
 | 
				
			||||||
 | 
					     *          name="company",
 | 
				
			||||||
 | 
					     *          in="path",
 | 
				
			||||||
 | 
					     *          description="The Company Hashed ID",
 | 
				
			||||||
 | 
					     *          example="D2J234DFA",
 | 
				
			||||||
 | 
					     *          required=true,
 | 
				
			||||||
 | 
					     *          @OA\Schema(
 | 
				
			||||||
 | 
					     *              type="string",
 | 
				
			||||||
 | 
					     *              format="string",
 | 
				
			||||||
 | 
					     *          ),
 | 
				
			||||||
 | 
					     *      ),
 | 
				
			||||||
 | 
					     *      @OA\Response(
 | 
				
			||||||
 | 
					     *          response=200,
 | 
				
			||||||
 | 
					     *          description="Returns a refresh object",
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
 | 
				
			||||||
 | 
					     *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/CompanyUser"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *          response=422,
 | 
				
			||||||
 | 
					     *          description="Validation error",
 | 
				
			||||||
 | 
					     *          @OA\JsonContent(ref="#/components/schemas/ValidationError"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *       @OA\Response(
 | 
				
			||||||
 | 
					     *           response="default",
 | 
				
			||||||
 | 
					     *           description="Unexpected Error",
 | 
				
			||||||
 | 
					     *           @OA\JsonContent(ref="#/components/schemas/Error"),
 | 
				
			||||||
 | 
					     *       ),
 | 
				
			||||||
 | 
					     *     )
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function purgeCompany(Company $company)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $account = $company->account;
 | 
				
			||||||
 | 
					        $company_id = $company->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $company->delete();
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					        /*Set New Company*/
 | 
				
			||||||
 | 
					        if($account->companies->count() >= 1)
 | 
				
			||||||
 | 
					            auth()->user()->setCompany($account->companies->first());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*Update the new default company if necessary*/
 | 
				
			||||||
 | 
					        if($company_id == $account->default_company_id){
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $new_default_company = $account->companies->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($new_default_company){
 | 
				
			||||||
 | 
					                $account->default_company_id = $new_default_company->id;
 | 
				
			||||||
 | 
					                $account->save();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*Prep response*/
 | 
				
			||||||
 | 
					        $this->entity_type = CompanyUser::class;
 | 
				
			||||||
 | 
					        $this->entity_transformer = CompanyUserTransformer::class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $company_user = $account->company_users->where('user_id', auth()->user()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->refreshResponse($company_user);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -725,10 +725,6 @@ class InvoiceController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if ($invoice->invitations->count() > 0) {
 | 
					 | 
				
			||||||
                    event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars()));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!$bulk) {
 | 
					                if (!$bulk) {
 | 
				
			||||||
                    return response()->json(['message' => 'email sent'], 200);
 | 
					                    return response()->json(['message' => 'email sent'], 200);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -77,18 +77,7 @@ class MigrationController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function purgeCompany(Company $company)
 | 
					    public function purgeCompany(Company $company)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // $account = $company->account;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // if($account->default_company_id == $company->id)
 | 
					 | 
				
			||||||
        // {
 | 
					 | 
				
			||||||
        //     $companies = $account->companies;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //     if($companies->count() > 1)
 | 
					 | 
				
			||||||
        //     {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //     }
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
        $company->delete();
 | 
					        $company->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json(['message' => 'Company purged'], 200);
 | 
					        return response()->json(['message' => 'Company purged'], 200);
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					<?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\Http\Requests\Activity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DownloadHistoricalEntityRequest extends Request
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Determine if the user is authorized to make this request.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function authorize() : bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return auth()->user()->can('view', $this->activity);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -54,6 +54,9 @@ class UpdateInvoiceRequest extends Request
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $rules['id'] = new LockedInvoiceRule($this->invoice);
 | 
					        $rules['id'] = new LockedInvoiceRule($this->invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($this->input('number'))
 | 
				
			||||||
 | 
					            $rules['number'] = 'unique:invoices,number,' . $this->id . ',id,company_id,' . $this->invoice->company_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $rules;
 | 
					        return $rules;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -60,7 +60,7 @@ class UniqueInvoiceNumberRule implements Rule
 | 
				
			|||||||
        $invoice = Invoice::where('client_id', $this->input['client_id'])
 | 
					        $invoice = Invoice::where('client_id', $this->input['client_id'])
 | 
				
			||||||
                        ->where('number', $this->input['number'])
 | 
					                        ->where('number', $this->input['number'])
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->first();
 | 
					                        ->exists();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($invoice)
 | 
					        if($invoice)
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
				
			|||||||
@ -87,7 +87,7 @@ class CreateCreditPdf implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $html = (new HtmlEngine($designer, $this->invitation, 'credit'))->build();
 | 
					        $html = (new HtmlEngine($designer, $this->invitation, 'credit'))->build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Storage::makeDirectory($path, 0755);
 | 
					        Storage::makeDirectory($path, 0775);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $pdf       = $this->makePdf(null, null, $html);
 | 
					        $pdf       = $this->makePdf(null, null, $html);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,7 @@ class CreateInvoicePdf implements ShouldQueue
 | 
				
			|||||||
        $html = (new HtmlEngine($designer, $this->invitation, 'invoice'))->build();
 | 
					        $html = (new HtmlEngine($designer, $this->invitation, 'invoice'))->build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //todo - move this to the client creation stage so we don't keep hitting this unnecessarily
 | 
					        //todo - move this to the client creation stage so we don't keep hitting this unnecessarily
 | 
				
			||||||
        Storage::makeDirectory($path, 0755);
 | 
					        Storage::makeDirectory($path, 0775);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $pdf       = $this->makePdf(null, null, $html);
 | 
					        $pdf       = $this->makePdf(null, null, $html);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,6 +22,7 @@ use App\Models\Company;
 | 
				
			|||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Models\InvoiceInvitation;
 | 
					use App\Models\InvoiceInvitation;
 | 
				
			||||||
use App\Models\SystemLog;
 | 
					use App\Models\SystemLog;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use Illuminate\Bus\Queueable;
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
					use Illuminate\Foundation\Bus\Dispatchable;
 | 
				
			||||||
@ -75,6 +76,8 @@ class EmailInvoice extends BaseMailerJob implements ShouldQueue
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        $this->setMailDriver();
 | 
					        $this->setMailDriver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Mail::to($this->invoice_invitation->contact->email, $this->invoice_invitation->contact->present()->name())
 | 
					            Mail::to($this->invoice_invitation->contact->email, $this->invoice_invitation->contact->present()->name())
 | 
				
			||||||
                ->send(
 | 
					                ->send(
 | 
				
			||||||
                    new TemplateEmail(
 | 
					                    new TemplateEmail(
 | 
				
			||||||
@ -84,9 +87,19 @@ class EmailInvoice extends BaseMailerJob implements ShouldQueue
 | 
				
			|||||||
                    )
 | 
					                    )
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch (\Swift_TransportException $e) {
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            event(new InvoiceWasEmailedAndFailed($this->invoice_invitation->invoice, $this->company, $e->getMessage(), Ninja::eventVars()));
 | 
				
			||||||
 | 
					        } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count(Mail::failures()) > 0) {
 | 
					        if (count(Mail::failures()) > 0) {
 | 
				
			||||||
            return $this->logMailError(Mail::failures(), $this->invoice->client);
 | 
					            return $this->logMailError(Mail::failures(), $this->invoice->client);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        else{
 | 
				
			||||||
 | 
					            event(new InvoiceWasEmailed($this->invoice_invitation, $this->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -84,7 +84,7 @@ class CreateQuotePdf implements ShouldQueue
 | 
				
			|||||||
        $designer   = new Designer($this->quote, $design, $this->quote->client->getSetting('pdf_variables'), 'quote');
 | 
					        $designer   = new Designer($this->quote, $design, $this->quote->client->getSetting('pdf_variables'), 'quote');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //todo - move this to the client creation stage so we don't keep hitting this unnecessarily
 | 
					        //todo - move this to the client creation stage so we don't keep hitting this unnecessarily
 | 
				
			||||||
        Storage::makeDirectory($path, 0755);
 | 
					        Storage::makeDirectory($path, 0775);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $html = (new HtmlEngine($designer, $this->invitation, 'quote'))->build();
 | 
					        $html = (new HtmlEngine($designer, $this->invitation, 'quote'))->build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ class UploadAvatar implements ShouldQueue
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //make dir
 | 
					        //make dir
 | 
				
			||||||
        Storage::makeDirectory('public/' . $this->directory, 0755);
 | 
					        Storage::makeDirectory('public/' . $this->directory, 0775);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $tmp_file = sha1(time()).".png";
 | 
					        $tmp_file = sha1(time()).".png";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -55,13 +55,14 @@ class PaymentCreatedActivity implements ShouldQueue
 | 
				
			|||||||
        $fields->company_id = $payment->company_id;
 | 
					        $fields->company_id = $payment->company_id;
 | 
				
			||||||
        $fields->activity_type_id = Activity::CREATE_PAYMENT;
 | 
					        $fields->activity_type_id = Activity::CREATE_PAYMENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($invoices as $invoice) { //todo we may need to add additional logic if in the future we apply payments to other entity Types, not just invoices
 | 
					        /*todo tests fail for this for some reason?*/
 | 
				
			||||||
            $fields->invoice_id = $invoice->id;
 | 
					        // foreach ($invoices as $invoice) { //todo we may need to add additional logic if in the future we apply payments to other entity Types, not just invoices
 | 
				
			||||||
 | 
					        //     $fields->invoice_id = $invoice->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            InvoiceWorkflowSettings::dispatchNow($invoice);
 | 
					        //     InvoiceWorkflowSettings::dispatchNow($invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $this->activity_repo->save($fields, $invoice, $event->event_vars);
 | 
					        //     $this->activity_repo->save($fields, $invoice, $event->event_vars);
 | 
				
			||||||
        }
 | 
					        // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($invoices) == 0) {
 | 
					        if (count($invoices) == 0) {
 | 
				
			||||||
            $this->activity_repo->save($fields, $payment, $event->event_vars);
 | 
					            $this->activity_repo->save($fields, $payment, $event->event_vars);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										59
									
								
								app/Listeners/Credit/CreditViewedActivity.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								app/Listeners/Credit/CreditViewedActivity.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Credit Ninja (https://creditninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/creditninja/creditninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2020. Credit Ninja LLC (https://creditninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://opensource.org/licenses/AAL
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Listeners\Credit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					use App\Models\ClientContact;
 | 
				
			||||||
 | 
					use App\Models\CreditInvitation;
 | 
				
			||||||
 | 
					use App\Repositories\ActivityRepository;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
 | 
					use Illuminate\Queue\InteractsWithQueue;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreditViewedActivity 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)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MultiDB::setDb($event->company->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fields = new \stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fields->user_id = $event->invitation->user_id;
 | 
				
			||||||
 | 
					        $fields->company_id = $event->invitation->company_id;
 | 
				
			||||||
 | 
					        $fields->activity_type_id = Activity::VIEW_CREDIT;
 | 
				
			||||||
 | 
					        $fields->client_id = $event->invitation->credit->client_id;
 | 
				
			||||||
 | 
					        $fields->client_contact_id = $event->invitation->client_contact_id;
 | 
				
			||||||
 | 
					        $fields->invitation_id = $event->invitation->id;
 | 
				
			||||||
 | 
					        $fields->credit_id = $event->invitation->credit_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->activity_repo->save($fields, $event->invitation->credit, $event->event_vars);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -51,6 +51,7 @@ class InvoiceEmailFailedActivity implements ShouldQueue
 | 
				
			|||||||
        $fields->user_id = $event->invoice->user_id;
 | 
					        $fields->user_id = $event->invoice->user_id;
 | 
				
			||||||
        $fields->company_id = $event->invoice->company_id;
 | 
					        $fields->company_id = $event->invoice->company_id;
 | 
				
			||||||
        $fields->activity_type_id = Activity::EMAIL_INVOICE_FAILED;
 | 
					        $fields->activity_type_id = Activity::EMAIL_INVOICE_FAILED;
 | 
				
			||||||
 | 
					        $fields->notes = $event->errors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
					        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -13,11 +13,15 @@ namespace App\Listeners\Invoice;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use App\Libraries\MultiDB;
 | 
					use App\Libraries\MultiDB;
 | 
				
			||||||
use App\Models\Activity;
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					use App\Models\ClientContact;
 | 
				
			||||||
 | 
					use App\Models\InvoiceInvitation;
 | 
				
			||||||
use App\Repositories\ActivityRepository;
 | 
					use App\Repositories\ActivityRepository;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
use Illuminate\Queue\InteractsWithQueue;
 | 
					use Illuminate\Queue\InteractsWithQueue;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CreateInvoiceHtmlBackup implements ShouldQueue
 | 
					class InvoicePaidActivity implements ShouldQueue
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $activity_repo;
 | 
					    protected $activity_repo;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -38,15 +42,14 @@ class CreateInvoiceHtmlBackup implements ShouldQueue
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function handle($event)
 | 
					    public function handle($event)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDB($event->company->db);
 | 
					        MultiDB::setDb($event->company->db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $fields = new \stdClass;
 | 
					        $fields = new \stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $fields->invoice_id = $event->invoice->id;
 | 
					        $fields->invoice_id = $event->invoice->id;
 | 
				
			||||||
              $fields->client_id = $event->invoice->client_id;
 | 
					 | 
				
			||||||
        $fields->user_id = $event->invoice->user_id;
 | 
					        $fields->user_id = $event->invoice->user_id;
 | 
				
			||||||
        $fields->company_id = $event->invoice->company_id;
 | 
					        $fields->company_id = $event->invoice->company_id;
 | 
				
			||||||
        $fields->activity_type_id = Activity::MARK_SENT_INVOICE;
 | 
					        $fields->activity_type_id = Activity::PAID_INVOICE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
					        $this->activity_repo->save($fields, $event->invoice, $event->event_vars);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -11,10 +11,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Models;
 | 
					namespace App\Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Model;
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Activity extends StaticModel
 | 
					class Activity extends StaticModel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    const CREATE_CLIENT=1; //
 | 
					    const CREATE_CLIENT=1; //
 | 
				
			||||||
    const ARCHIVE_CLIENT=2; //
 | 
					    const ARCHIVE_CLIENT=2; //
 | 
				
			||||||
    const DELETE_CLIENT=3; //
 | 
					    const DELETE_CLIENT=3; //
 | 
				
			||||||
@ -52,8 +56,9 @@ class Activity extends StaticModel
 | 
				
			|||||||
    const ARCHIVE_EXPENSE=35;
 | 
					    const ARCHIVE_EXPENSE=35;
 | 
				
			||||||
    const DELETE_EXPENSE=36;
 | 
					    const DELETE_EXPENSE=36;
 | 
				
			||||||
    const RESTORE_EXPENSE=37;
 | 
					    const RESTORE_EXPENSE=37;
 | 
				
			||||||
    const VOIDED_PAYMENT=39;
 | 
					
 | 
				
			||||||
    const REFUNDED_PAYMENT=40;
 | 
					    const VOIDED_PAYMENT=39; //
 | 
				
			||||||
 | 
					    const REFUNDED_PAYMENT=40; //
 | 
				
			||||||
    const FAILED_PAYMENT=41;
 | 
					    const FAILED_PAYMENT=41;
 | 
				
			||||||
    const CREATE_TASK=42;
 | 
					    const CREATE_TASK=42;
 | 
				
			||||||
    const UPDATE_TASK=43;
 | 
					    const UPDATE_TASK=43;
 | 
				
			||||||
@ -61,16 +66,18 @@ class Activity extends StaticModel
 | 
				
			|||||||
    const DELETE_TASK=45;
 | 
					    const DELETE_TASK=45;
 | 
				
			||||||
    const RESTORE_TASK=46;
 | 
					    const RESTORE_TASK=46;
 | 
				
			||||||
    const UPDATE_EXPENSE=47;
 | 
					    const UPDATE_EXPENSE=47;
 | 
				
			||||||
    const CREATE_USER=48;
 | 
					
 | 
				
			||||||
    const UPDATE_USER=49;
 | 
					    const CREATE_USER=48; // only used in CreateUser::job
 | 
				
			||||||
    const ARCHIVE_USER=50;
 | 
					    const UPDATE_USER=49; // not needed?
 | 
				
			||||||
    const DELETE_USER=51;
 | 
					    const ARCHIVE_USER=50; // not needed?
 | 
				
			||||||
    const RESTORE_USER=52;
 | 
					    const DELETE_USER=51; // not needed?
 | 
				
			||||||
    const MARK_SENT_INVOICE=53;
 | 
					    const RESTORE_USER=52; // not needed?
 | 
				
			||||||
    const PAID_INVOICE=54;
 | 
					    const MARK_SENT_INVOICE=53; // not needed?
 | 
				
			||||||
 | 
					    const PAID_INVOICE=54; //
 | 
				
			||||||
    const EMAIL_INVOICE_FAILED=57;
 | 
					    const EMAIL_INVOICE_FAILED=57;
 | 
				
			||||||
    const REVERSED_INVOICE=58;
 | 
					    const REVERSED_INVOICE=58; //
 | 
				
			||||||
    const CANCELLED_INVOICE=59;
 | 
					    const CANCELLED_INVOICE=59; //
 | 
				
			||||||
 | 
					    const VIEW_CREDIT=60; //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $casts = [
 | 
					    protected $casts = [
 | 
				
			||||||
        'is_system' => 'boolean',
 | 
					        'is_system' => 'boolean',
 | 
				
			||||||
@ -144,4 +151,16 @@ class Activity extends StaticModel
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->belongsTo(Company::class);
 | 
					        return $this->belongsTo(Company::class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function resolveRouteBinding($value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (is_numeric($value)) {
 | 
				
			||||||
 | 
					            throw new ModelNotFoundException("Record with value {$value} not found");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this
 | 
				
			||||||
 | 
					            //->withTrashed()
 | 
				
			||||||
 | 
					            ->where('id', $this->decodePrimaryKey($value))->firstOrFail();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -194,7 +194,8 @@ class AuthorizeCreditCard
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function processFailedResponse($data, $request)
 | 
					    private function processFailedResponse($data, $request)
 | 
				
			||||||
    {   dd($data);
 | 
					    {   
 | 
				
			||||||
 | 
					        //dd($data);
 | 
				
			||||||
        info(print_r($data,1));
 | 
					        info(print_r($data,1));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,12 +12,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\PaymentDrivers;
 | 
					namespace App\PaymentDrivers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceWasPaid;
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Models\ClientGatewayToken;
 | 
					use App\Models\ClientGatewayToken;
 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					use App\Models\CompanyGateway;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Models\Payment;
 | 
					use App\Models\Payment;
 | 
				
			||||||
use App\PaymentDrivers\AbstractPaymentDriver;
 | 
					use App\PaymentDrivers\AbstractPaymentDriver;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use App\Utils\Traits\SystemLogTrait;
 | 
					use App\Utils\Traits\SystemLogTrait;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -119,6 +121,10 @@ class BaseDriver extends AbstractPaymentDriver
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $payment->service()->applyNumber()->save();
 | 
					        $payment->service()->applyNumber()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoices->each(function ($invoice) use($payment){
 | 
				
			||||||
 | 
					            event(new InvoiceWasPaid($invoice, $payment->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $payment;
 | 
					        return $payment;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,7 @@ use App\Events\Credit\CreditWasEmailedAndFailed;
 | 
				
			|||||||
use App\Events\Credit\CreditWasMarkedSent;
 | 
					use App\Events\Credit\CreditWasMarkedSent;
 | 
				
			||||||
use App\Events\Credit\CreditWasRestored;
 | 
					use App\Events\Credit\CreditWasRestored;
 | 
				
			||||||
use App\Events\Credit\CreditWasUpdated;
 | 
					use App\Events\Credit\CreditWasUpdated;
 | 
				
			||||||
 | 
					use App\Events\Credit\CreditWasViewed;
 | 
				
			||||||
use App\Events\Design\DesignWasArchived;
 | 
					use App\Events\Design\DesignWasArchived;
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasArchived;
 | 
					use App\Events\Invoice\InvoiceWasArchived;
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasCancelled;
 | 
					use App\Events\Invoice\InvoiceWasCancelled;
 | 
				
			||||||
@ -76,17 +77,21 @@ use App\Listeners\Activity\RestoreClientActivity;
 | 
				
			|||||||
use App\Listeners\Activity\UpdatedCreditActivity;
 | 
					use App\Listeners\Activity\UpdatedCreditActivity;
 | 
				
			||||||
use App\Listeners\Contact\UpdateContactLastLogin;
 | 
					use App\Listeners\Contact\UpdateContactLastLogin;
 | 
				
			||||||
use App\Listeners\Credit\CreditRestoredActivity;
 | 
					use App\Listeners\Credit\CreditRestoredActivity;
 | 
				
			||||||
 | 
					use App\Listeners\Credit\CreditViewedActivity;
 | 
				
			||||||
use App\Listeners\Document\DeleteCompanyDocuments;
 | 
					use App\Listeners\Document\DeleteCompanyDocuments;
 | 
				
			||||||
use App\Listeners\Invoice\CreateInvoiceActivity;
 | 
					use App\Listeners\Invoice\CreateInvoiceActivity;
 | 
				
			||||||
use App\Listeners\Invoice\CreateInvoiceHtmlBackup;
 | 
					use App\Listeners\Invoice\CreateInvoiceHtmlBackup;
 | 
				
			||||||
use App\Listeners\Invoice\CreateInvoiceInvitation;
 | 
					use App\Listeners\Invoice\CreateInvoiceInvitation;
 | 
				
			||||||
use App\Listeners\Invoice\CreateInvoicePdf;
 | 
					use App\Listeners\Invoice\CreateInvoicePdf;
 | 
				
			||||||
use App\Listeners\Invoice\InvoiceArchivedActivity;
 | 
					use App\Listeners\Invoice\InvoiceArchivedActivity;
 | 
				
			||||||
 | 
					use App\Listeners\Invoice\InvoiceCancelledActivity;
 | 
				
			||||||
use App\Listeners\Invoice\InvoiceDeletedActivity;
 | 
					use App\Listeners\Invoice\InvoiceDeletedActivity;
 | 
				
			||||||
use App\Listeners\Invoice\InvoiceEmailActivity;
 | 
					use App\Listeners\Invoice\InvoiceEmailActivity;
 | 
				
			||||||
use App\Listeners\Invoice\InvoiceEmailFailedActivity;
 | 
					use App\Listeners\Invoice\InvoiceEmailFailedActivity;
 | 
				
			||||||
use App\Listeners\Invoice\InvoiceEmailedNotification;
 | 
					use App\Listeners\Invoice\InvoiceEmailedNotification;
 | 
				
			||||||
 | 
					use App\Listeners\Invoice\InvoicePaidActivity;
 | 
				
			||||||
use App\Listeners\Invoice\InvoiceRestoredActivity;
 | 
					use App\Listeners\Invoice\InvoiceRestoredActivity;
 | 
				
			||||||
 | 
					use App\Listeners\Invoice\InvoiceReversedActivity;
 | 
				
			||||||
use App\Listeners\Invoice\InvoiceViewedActivity;
 | 
					use App\Listeners\Invoice\InvoiceViewedActivity;
 | 
				
			||||||
use App\Listeners\Invoice\UpdateInvoiceActivity;
 | 
					use App\Listeners\Invoice\UpdateInvoiceActivity;
 | 
				
			||||||
use App\Listeners\Invoice\UpdateInvoiceInvitations;
 | 
					use App\Listeners\Invoice\UpdateInvoiceInvitations;
 | 
				
			||||||
@ -194,6 +199,9 @@ class EventServiceProvider extends ServiceProvider
 | 
				
			|||||||
        CreditWasRestored::class => [
 | 
					        CreditWasRestored::class => [
 | 
				
			||||||
            CreditRestoredActivity::class,
 | 
					            CreditRestoredActivity::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
					        CreditWasViewed::class => [
 | 
				
			||||||
 | 
					            CreditViewedActivity::class
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
        //Designs
 | 
					        //Designs
 | 
				
			||||||
        DesignWasArchived::class => [
 | 
					        DesignWasArchived::class => [
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
@ -216,7 +224,7 @@ class EventServiceProvider extends ServiceProvider
 | 
				
			|||||||
        //    CreateInvoicePdf::class,
 | 
					        //    CreateInvoicePdf::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        InvoiceWasPaid::class => [
 | 
					        InvoiceWasPaid::class => [
 | 
				
			||||||
       //    CreateInvoiceHtmlBackup::class,
 | 
					           InvoicePaidActivity::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        InvoiceWasViewed::class => [
 | 
					        InvoiceWasViewed::class => [
 | 
				
			||||||
            InvoiceViewedActivity::class,
 | 
					            InvoiceViewedActivity::class,
 | 
				
			||||||
@ -238,8 +246,10 @@ class EventServiceProvider extends ServiceProvider
 | 
				
			|||||||
            InvoiceRestoredActivity::class,
 | 
					            InvoiceRestoredActivity::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        InvoiceWasReversed::class => [
 | 
					        InvoiceWasReversed::class => [
 | 
				
			||||||
 | 
					            InvoiceReversedActivity::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        InvoiceWasCancelled::class => [
 | 
					        InvoiceWasCancelled::class => [
 | 
				
			||||||
 | 
					            InvoiceCancelledActivity::class,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        InvitationWasViewed::class => [
 | 
					        InvitationWasViewed::class => [
 | 
				
			||||||
            InvitationViewedListener::class
 | 
					            InvitationViewedListener::class
 | 
				
			||||||
 | 
				
			|||||||
@ -66,8 +66,10 @@ class ActivityRepository extends BaseRepository
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $backup = new Backup();
 | 
					        $backup = new Backup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (get_class($entity) == Invoice::class || get_class($entity) == Quote::class || get_class($entity) == Credit::class)
 | 
					        if (get_class($entity) == Invoice::class || get_class($entity) == Quote::class || get_class($entity) == Credit::class){
 | 
				
			||||||
            $backup->html_backup = $this->generateEntityHtml($entity->getEntityDesigner(), $entity);
 | 
					            $contact = $entity->client->primary_contact()->first();
 | 
				
			||||||
 | 
					            $backup->html_backup = $this->generateEntityHtml($entity->getEntityDesigner(), $entity, $contact);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $backup->activity_id = $activity->id;
 | 
					        $backup->activity_id = $activity->id;
 | 
				
			||||||
        $backup->json_backup = '';
 | 
					        $backup->json_backup = '';
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Services\Invoice;
 | 
					namespace App\Services\Invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceWasPaid;
 | 
				
			||||||
use App\Events\Payment\PaymentWasCreated;
 | 
					use App\Events\Payment\PaymentWasCreated;
 | 
				
			||||||
use App\Factory\PaymentFactory;
 | 
					use App\Factory\PaymentFactory;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
@ -72,6 +73,7 @@ class MarkPaid extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        /* Update Invoice balance */
 | 
					        /* Update Invoice balance */
 | 
				
			||||||
        event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
 | 
					        event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					        event(new InvoiceWasPaid($this->invoice, $payment->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $payment->ledger()
 | 
					        $payment->ledger()
 | 
				
			||||||
                ->updatePaymentBalance($payment->amount*-1);
 | 
					                ->updatePaymentBalance($payment->amount*-1);
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Services\Invoice;
 | 
					namespace App\Services\Invoice;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasMarkedSent;
 | 
					use App\Events\Invoice\InvoiceWasUpdated;
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use App\Services\AbstractService;
 | 
					use App\Services\AbstractService;
 | 
				
			||||||
@ -41,8 +41,6 @@ class MarkSent extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->invoice->setReminder();
 | 
					        $this->invoice->setReminder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event(new InvoiceWasMarkedSent($this->invoice, $this->invoice->company, Ninja::eventVars()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->invoice
 | 
					        $this->invoice
 | 
				
			||||||
             ->service()
 | 
					             ->service()
 | 
				
			||||||
             ->setStatus(Invoice::STATUS_SENT)
 | 
					             ->setStatus(Invoice::STATUS_SENT)
 | 
				
			||||||
@ -54,6 +52,8 @@ class MarkSent extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance);
 | 
					        $this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars()));
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        return $this->invoice->fresh();
 | 
					        return $this->invoice->fresh();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -96,4 +96,11 @@ class PaymentService
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function save()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->payment->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->payment->fresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -63,7 +63,7 @@ class Phantom
 | 
				
			|||||||
		$phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$url}%22,renderType:%22pdf%22%7D";
 | 
							$phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$url}%22,renderType:%22pdf%22%7D";
 | 
				
			||||||
        $pdf = \App\Utils\CurlUtils::get($phantom_url);
 | 
					        $pdf = \App\Utils\CurlUtils::get($phantom_url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Storage::makeDirectory($path, 0755);
 | 
					        Storage::makeDirectory($path, 0775);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $instance = Storage::disk(config('filesystems.default'))->put($file_path, $pdf);
 | 
					        $instance = Storage::disk(config('filesystems.default'))->put($file_path, $pdf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,7 @@ trait MakesInvoiceHtml
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function generateEntityHtml(Designer $designer, $entity, $contact = null) :string
 | 
					    public function generateEntityHtml(Designer $designer, $entity, $contact = null) :string
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $entity->load('client');
 | 
					        $entity->load('client');
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $client = $entity->client;
 | 
					        $client = $entity->client;
 | 
				
			||||||
 | 
				
			|||||||
@ -46,6 +46,16 @@ return [
 | 
				
			|||||||
        'local' => [
 | 
					        'local' => [
 | 
				
			||||||
            'driver' => 'local',
 | 
					            'driver' => 'local',
 | 
				
			||||||
            'root' => storage_path('app'),
 | 
					            'root' => storage_path('app'),
 | 
				
			||||||
 | 
					            'permissions' => [
 | 
				
			||||||
 | 
					                'file' => [
 | 
				
			||||||
 | 
					                    'public' => 0664,
 | 
				
			||||||
 | 
					                    'private' => 0600,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                'dir' => [
 | 
				
			||||||
 | 
					                    'public' => 0775,
 | 
				
			||||||
 | 
					                    'private' => 0700,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        'public' => [
 | 
					        'public' => [
 | 
				
			||||||
@ -53,6 +63,16 @@ return [
 | 
				
			|||||||
            'root' => storage_path('app/public'),
 | 
					            'root' => storage_path('app/public'),
 | 
				
			||||||
            'url' => env('APP_URL').'/storage',
 | 
					            'url' => env('APP_URL').'/storage',
 | 
				
			||||||
            'visibility' => 'public',
 | 
					            'visibility' => 'public',
 | 
				
			||||||
 | 
					            'permissions' => [
 | 
				
			||||||
 | 
					                'file' => [
 | 
				
			||||||
 | 
					                    'public' => 0664,
 | 
				
			||||||
 | 
					                    'private' => 0600,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                'dir' => [
 | 
				
			||||||
 | 
					                    'public' => 0775,
 | 
				
			||||||
 | 
					                    'private' => 0700,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        's3' => [
 | 
					        's3' => [
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,6 @@
 | 
				
			|||||||
use App\DataMapper\ClientSettings;
 | 
					use App\DataMapper\ClientSettings;
 | 
				
			||||||
use App\DataMapper\CompanySettings;
 | 
					use App\DataMapper\CompanySettings;
 | 
				
			||||||
use App\DataMapper\DefaultSettings;
 | 
					use App\DataMapper\DefaultSettings;
 | 
				
			||||||
use App\Events\Invoice\InvoiceWasMarkedSent;
 | 
					 | 
				
			||||||
use App\Events\Invoice\InvoiceWasUpdated;
 | 
					use App\Events\Invoice\InvoiceWasUpdated;
 | 
				
			||||||
use App\Events\Payment\PaymentWasCreated;
 | 
					use App\Events\Payment\PaymentWasCreated;
 | 
				
			||||||
use App\Helpers\Invoice\InvoiceSum;
 | 
					use App\Helpers\Invoice\InvoiceSum;
 | 
				
			||||||
@ -200,8 +199,6 @@ class RandomDataSeeder extends Seeder
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
            $invoice->ledger()->updateInvoiceBalance($invoice->balance);
 | 
					            $invoice->ledger()->updateInvoiceBalance($invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            event(new InvoiceWasMarkedSent($invoice, $company, Ninja::eventVars()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (rand(0, 1)) {
 | 
					            if (rand(0, 1)) {
 | 
				
			||||||
                $payment = App\Models\Payment::create([
 | 
					                $payment = App\Models\Payment::create([
 | 
				
			||||||
                    'date' => now(),
 | 
					                    'date' => now(),
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,9 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a
 | 
				
			|||||||
    Route::get('ping', 'PingController@index')->name('ping');
 | 
					    Route::get('ping', 'PingController@index')->name('ping');
 | 
				
			||||||
    Route::get('health_check', 'PingController@health')->name('health_check');
 | 
					    Route::get('health_check', 'PingController@health')->name('health_check');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Route::resource('activities', 'ActivityController');// name = (clients. index / create / show / update / destroy / edit
 | 
					    Route::get('activities', 'ActivityController@index');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Route::get('activities/download_entity/{activity}', 'ActivityController@downloadHistoricalEntity');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Route::resource('clients', 'ClientController');// name = (clients. index / create / show / update / destroy / edit
 | 
					    Route::resource('clients', 'ClientController');// name = (clients. index / create / show / update / destroy / edit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -145,4 +145,76 @@ class InvoiceTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testUniqueNumberValidation()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* stub a invoice in the DB that we will use to test against later */
 | 
				
			||||||
 | 
					        $invoice = factory(\App\Models\Invoice::class)->create([
 | 
				
			||||||
 | 
					            'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					            'client_id' => $this->client->id,
 | 
				
			||||||
 | 
					            'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					            'number' => 'test',
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Test fire new invoice */
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'client_id' => $this->client->hashed_id,
 | 
				
			||||||
 | 
					            'number' => 'dude'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					        ])->post('/api/v1/invoices/', $data)
 | 
				
			||||||
 | 
					        ->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $arr = $response->json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals('dude', $arr['data']['number']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*test validation fires*/
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'client_id' => $this->client->hashed_id,
 | 
				
			||||||
 | 
					            'number' => 'test'
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try{
 | 
				
			||||||
 | 
					            $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->put('/api/v1/invoices/' . $arr['data']['id'], $data)
 | 
				
			||||||
 | 
					            ->assertStatus(302);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } catch (ValidationException $e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $message = json_decode($e->validator->getMessageBag(), 1);
 | 
				
			||||||
 | 
					            info("inside update invoice validator");
 | 
				
			||||||
 | 
					            info($message);
 | 
				
			||||||
 | 
					            $this->assertNotNull($message);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $data = [
 | 
				
			||||||
 | 
					                'client_id' => $this->client->hashed_id,
 | 
				
			||||||
 | 
					                'number' => 'style'
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* test number passed validation*/
 | 
				
			||||||
 | 
					            $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->put('/api/v1/invoices/' . $arr['data']['id'], $data)
 | 
				
			||||||
 | 
					            ->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $data = [
 | 
				
			||||||
 | 
					                'client_id' => $this->client->hashed_id,
 | 
				
			||||||
 | 
					                'number' => 'style'
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Make sure we can UPDATE using the same number*/
 | 
				
			||||||
 | 
					            $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->put('/api/v1/invoices/' . $arr['data']['id'], $data)
 | 
				
			||||||
 | 
					            ->assertStatus(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -156,6 +156,15 @@ class RefundTest extends TestCase
 | 
				
			|||||||
        $this->invoice = $this->invoice_calc->getInvoice();
 | 
					        $this->invoice = $this->invoice_calc->getInvoice();
 | 
				
			||||||
        $this->invoice->save();
 | 
					        $this->invoice->save();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        $this->invoice->setRelation('client', $this->client);
 | 
				
			||||||
 | 
					        $this->invoice->setRelation('company', $this->company);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->invoice->service()->createInvitations()->markSent()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertNotNull($this->invoice->invitations);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $this->assertNotNull($this->invoice->invitations->first()->contact);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'amount' => 50,
 | 
					            'amount' => 50,
 | 
				
			||||||
            'client_id' => $client->hashed_id,
 | 
					            'client_id' => $client->hashed_id,
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,8 @@ class DesignTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->invoice->uses_inclusive_taxes = false;
 | 
					        $this->invoice->uses_inclusive_taxes = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoice->service()->createInvitations()->markSent()->save();
 | 
					        $this->invoice->service()->createInvitations()->markSent()->applyNumber()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->invoice->fresh();
 | 
					        $this->invoice->fresh();
 | 
				
			||||||
        $this->invoice->load('invitations');
 | 
					        $this->invoice->load('invitations');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										85
									
								
								tests/Integration/DownloadHistoricalInvoiceTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								tests/Integration/DownloadHistoricalInvoiceTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,85 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Tests\Integration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Events\Invoice\InvoiceWasUpdated;
 | 
				
			||||||
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					use App\Repositories\ActivityRepository;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Testing\Concerns\InteractsWithDatabase;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Testing\DatabaseTransactions;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Cache;
 | 
				
			||||||
 | 
					use Tests\MockAccountData;
 | 
				
			||||||
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @test
 | 
				
			||||||
 | 
					 * @covers App\Http\Controllers\ActivityController
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class DownloadHistoricalInvoiceTest extends TestCase
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MockAccountData;
 | 
				
			||||||
 | 
					    use DatabaseTransactions;
 | 
				
			||||||
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function setUp() :void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::setUp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->makeTestData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function mockActivity()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $activity_repo = new ActivityRepository();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $obj = new \stdClass;
 | 
				
			||||||
 | 
					        $obj->invoice_id = $this->invoice->id;
 | 
				
			||||||
 | 
					        $obj->user_id = $this->invoice->user_id;
 | 
				
			||||||
 | 
					        $obj->company_id = $this->company->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $activity_repo->save($obj, $this->invoice, Ninja::eventVars());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function testActivityAccessible()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->mockActivity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertNotNull($this->invoice->activities);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testBackupExists()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->mockActivity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertNotNull($this->invoice->activities->first()->backup->html_backup);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testBackupDownload()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->mockActivity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token
 | 
				
			||||||
 | 
					            ])->get('/api/v1/activities/download_entity/'.$this->encodePrimaryKey($this->invoice->activities->first()->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testBackupCheckPriorToDownloadWorks()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->mockActivity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $backup = $this->invoice->activities->first()->backup;
 | 
				
			||||||
 | 
					        $backup->forceDelete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token
 | 
				
			||||||
 | 
					            ])->get('/api/v1/activities/download_entity/'.$this->encodePrimaryKey($this->invoice->activities->first()->id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response->assertStatus(404);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -25,6 +25,7 @@ use App\Factory\InvoiceItemFactory;
 | 
				
			|||||||
use App\Factory\InvoiceToRecurringInvoiceFactory;
 | 
					use App\Factory\InvoiceToRecurringInvoiceFactory;
 | 
				
			||||||
use App\Helpers\Invoice\InvoiceSum;
 | 
					use App\Helpers\Invoice\InvoiceSum;
 | 
				
			||||||
use App\Models\Client;
 | 
					use App\Models\Client;
 | 
				
			||||||
 | 
					use App\Models\ClientContact;
 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					use App\Models\CompanyGateway;
 | 
				
			||||||
use App\Models\CompanyToken;
 | 
					use App\Models\CompanyToken;
 | 
				
			||||||
use App\Models\Credit;
 | 
					use App\Models\Credit;
 | 
				
			||||||
@ -153,7 +154,7 @@ trait MockAccountData
 | 
				
			|||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        factory(\App\Models\ClientContact::class, 1)->create([
 | 
					        $contact = factory(\App\Models\ClientContact::class, 1)->create([
 | 
				
			||||||
                'user_id' => $this->user->id,
 | 
					                'user_id' => $this->user->id,
 | 
				
			||||||
                'client_id' => $this->client->id,
 | 
					                'client_id' => $this->client->id,
 | 
				
			||||||
                'company_id' => $this->company->id,
 | 
					                'company_id' => $this->company->id,
 | 
				
			||||||
@ -161,13 +162,17 @@ trait MockAccountData
 | 
				
			|||||||
                'send_email' => true,
 | 
					                'send_email' => true,
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        factory(\App\Models\ClientContact::class, 1)->create([
 | 
					        $contact2 = factory(\App\Models\ClientContact::class, 1)->create([
 | 
				
			||||||
                'user_id' => $this->user->id,
 | 
					                'user_id' => $this->user->id,
 | 
				
			||||||
                'client_id' => $this->client->id,
 | 
					                'client_id' => $this->client->id,
 | 
				
			||||||
                'company_id' => $this->company->id,
 | 
					                'company_id' => $this->company->id,
 | 
				
			||||||
                'send_email' => true
 | 
					                'send_email' => true
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         // $rels = collect($contact, $contact2);
 | 
				
			||||||
 | 
					         // $this->client->setRelation('contacts', $rels);
 | 
				
			||||||
 | 
					         // $this->client->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $gs = new GroupSetting;
 | 
					        $gs = new GroupSetting;
 | 
				
			||||||
        $gs->name = 'Test';
 | 
					        $gs->name = 'Test';
 | 
				
			||||||
        $gs->company_id = $this->client->company_id;
 | 
					        $gs->company_id = $this->client->company_id;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user