mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 01:47:32 -05:00 
			
		
		
		
	Fixes for tests (#3082)
* Update client paid to date job: * Backup Invoice HTML when invoice is marked as sent and paid * Store HTML of invoice when invoice was paid * Fix foreign keys in db schema * V2 Endpoints for Company Migrations * Fixes for tests
This commit is contained in:
		
							parent
							
								
									6d225b7fe7
								
							
						
					
					
						commit
						f59585dd62
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -21,3 +21,4 @@ yarn-error.log
 | 
			
		||||
.env.dusk.local
 | 
			
		||||
/public/vendors/*
 | 
			
		||||
public/mix-manifest.json
 | 
			
		||||
*.log
 | 
			
		||||
@ -119,8 +119,10 @@ class CreateTestData extends Command
 | 
			
		||||
 | 
			
		||||
    private function createClient($company, $user)
 | 
			
		||||
    {
 | 
			
		||||
        $client = ClientFactory::create($company->id, $user->id);
 | 
			
		||||
        $client->save();
 | 
			
		||||
        $client = factory(\App\Models\Client::class)->create([
 | 
			
		||||
            'user_id' => $user->id,
 | 
			
		||||
            'company_id' => $company->id
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            factory(\App\Models\ClientContact::class,1)->create([
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										38
									
								
								app/Events/Invoice/InvoiceWasPaid.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/Events/Invoice/InvoiceWasPaid.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Events\Invoice;
 | 
			
		||||
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class InvoiceWasPaid.
 | 
			
		||||
 */
 | 
			
		||||
class InvoiceWasPaid 
 | 
			
		||||
{
 | 
			
		||||
    use SerializesModels;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var Invoice
 | 
			
		||||
     */
 | 
			
		||||
    public $invoice;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new event instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @param Invoice $invoice
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(Invoice $invoice)
 | 
			
		||||
    {
 | 
			
		||||
        $this->invoice = $invoice;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										144
									
								
								app/Http/Controllers/MigrationController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								app/Http/Controllers/MigrationController.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,144 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Http\Controllers;
 | 
			
		||||
 | 
			
		||||
use App\Http\Requests\Account\CreateAccountRequest;
 | 
			
		||||
use App\Jobs\Account\CreateAccount;
 | 
			
		||||
use App\Models\Account;
 | 
			
		||||
use App\Models\Company;
 | 
			
		||||
use App\Models\CompanyUser;
 | 
			
		||||
use App\Transformers\AccountTransformer;
 | 
			
		||||
use App\Transformers\CompanyUserTransformer;
 | 
			
		||||
use Illuminate\Foundation\Bus\DispatchesJobs;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
class MigrationController extends BaseController
 | 
			
		||||
{
 | 
			
		||||
    use DispatchesJobs;
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * Purge Company
 | 
			
		||||
     * 
 | 
			
		||||
     * @OA\Post(
 | 
			
		||||
     *      path="/api/v1/migration/purge/{company}",
 | 
			
		||||
     *      operationId="postPurgeCompany",
 | 
			
		||||
     *      tags={"migration"},
 | 
			
		||||
     *      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="Success",
 | 
			
		||||
     *          @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-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=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)
 | 
			
		||||
    {
 | 
			
		||||
       
 | 
			
		||||
       $company->delete();
 | 
			
		||||
 | 
			
		||||
            return response()->json(['message'=>'Company purged'], 200);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * Purge Company but save settings
 | 
			
		||||
     * 
 | 
			
		||||
     * @OA\Post(
 | 
			
		||||
     *      path="/api/v1/migration/purge_save_settings/{company}",
 | 
			
		||||
     *      operationId="postPurgeCompanySaveSettings",
 | 
			
		||||
     *      tags={"migration"},
 | 
			
		||||
     *      summary="Attempts to purge a companies child records but save the company record and its settings",
 | 
			
		||||
     *      description="Attempts to purge a companies child records but save the company record and its settings",
 | 
			
		||||
     *      @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="Success",
 | 
			
		||||
     *          @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-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=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 purgeCompanySaveSettings(Company $company)
 | 
			
		||||
    {
 | 
			
		||||
        $company->client->delete()
 | 
			
		||||
        $company->save()
 | 
			
		||||
 | 
			
		||||
            return response()->json(['message'=>'Setting preserved'], 200);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								app/Jobs/Client/UpdateClientPaidToDate.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								app/Jobs/Client/UpdateClientPaidToDate.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Jobs\Client;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
 | 
			
		||||
class UpdateClientPaidToDate
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable;
 | 
			
		||||
 | 
			
		||||
    protected $amount;
 | 
			
		||||
 | 
			
		||||
    protected $client;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public function __construct(Client $client, $amount)
 | 
			
		||||
    {
 | 
			
		||||
        $this->amount = $amount;
 | 
			
		||||
        $this->client = $client;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute the job.
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function handle() 
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $this->client->paid_to_date += $this->amount;
 | 
			
		||||
        $this->client->save();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -11,6 +11,7 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Jobs\Invoice;
 | 
			
		||||
 | 
			
		||||
use App\Events\Invoice\InvoiceWasPaid;
 | 
			
		||||
use App\Jobs\Invoice\ApplyInvoiceNumber;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Models\Payment;
 | 
			
		||||
@ -95,8 +96,11 @@ class ApplyPaymentToInvoice implements ShouldQueue
 | 
			
		||||
        $this->invoice->balance = $this->invoice->balance + $adjustment;
 | 
			
		||||
 | 
			
		||||
        /* Update Invoice Status */
 | 
			
		||||
        if($this->invoice->balance == 0)
 | 
			
		||||
        if($this->invoice->balance == 0){
 | 
			
		||||
            $this->invoice->status_id = Invoice::STATUS_PAID;
 | 
			
		||||
            $this->invoice->save();
 | 
			
		||||
            event(new InvoiceWasPaid($this->invoice));
 | 
			
		||||
        }
 | 
			
		||||
        elseif($this->payment->amount > 0 && $this->invoice->balance > 0)
 | 
			
		||||
            $this->invoice->status_id = Invoice::STATUS_PARTIAL;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -16,13 +16,13 @@ use App\Models\Payment;
 | 
			
		||||
use App\Models\PaymentTerm;
 | 
			
		||||
use App\Repositories\InvoiceRepository;
 | 
			
		||||
use App\Utils\Traits\NumberFormatter;
 | 
			
		||||
use App\Utils\Traits\MakesInvoiceHtml;
 | 
			
		||||
use Illuminate\Bus\Queueable;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use Illuminate\Support\Carbon;
 | 
			
		||||
use Illuminate\Support\Facades\Blade;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
use Illuminate\Support\Facades\Storage;
 | 
			
		||||
use Spatie\Browsershot\Browsershot;
 | 
			
		||||
@ -30,7 +30,7 @@ use Symfony\Component\Debug\Exception\FatalThrowableError;
 | 
			
		||||
 | 
			
		||||
class CreateInvoicePdf implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter;
 | 
			
		||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml;
 | 
			
		||||
 | 
			
		||||
    public $invoice;
 | 
			
		||||
 | 
			
		||||
@ -89,67 +89,5 @@ class CreateInvoicePdf implements ShouldQueue
 | 
			
		||||
            //->savePdf('test.pdf');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generate the HTML invoice parsing variables 
 | 
			
		||||
     * and generating the final invoice HTML
 | 
			
		||||
     *     
 | 
			
		||||
     * @param  string $design either the path to the design template, OR the full design template string
 | 
			
		||||
     * @param  Collection $invoice  The invoice object
 | 
			
		||||
     * 
 | 
			
		||||
     * @return string           The invoice string in HTML format
 | 
			
		||||
     */
 | 
			
		||||
    private function generateInvoiceHtml($design, $invoice) :string
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $variables = array_merge($invoice->makeLabels(), $invoice->makeValues());
 | 
			
		||||
        $design = str_replace(array_keys($variables), array_values($variables), $design);
 | 
			
		||||
 | 
			
		||||
        $data['invoice'] = $invoice;
 | 
			
		||||
 | 
			
		||||
        return $this->renderView($design, $data);
 | 
			
		||||
 | 
			
		||||
        //return view($design, $data)->render();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses the blade file string and processes the template variables
 | 
			
		||||
     * 
 | 
			
		||||
     * @param  string $string The Blade file string
 | 
			
		||||
     * @param  array $data   The array of template variables
 | 
			
		||||
     * @return string         The return HTML string
 | 
			
		||||
     * 
 | 
			
		||||
     */
 | 
			
		||||
    private function renderView($string, $data) :string
 | 
			
		||||
    {
 | 
			
		||||
        if (!$data) {
 | 
			
		||||
        $data = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $data['__env'] = app(\Illuminate\View\Factory::class);
 | 
			
		||||
 | 
			
		||||
        $php = Blade::compileString($string);
 | 
			
		||||
 | 
			
		||||
        $obLevel = ob_get_level();
 | 
			
		||||
        ob_start();
 | 
			
		||||
        extract($data, EXTR_SKIP);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            eval('?' . '>' . $php);
 | 
			
		||||
        } catch (\Exception $e) {
 | 
			
		||||
            while (ob_get_level() > $obLevel) {
 | 
			
		||||
                ob_end_clean();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw $e;
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            while (ob_get_level() > $obLevel) {
 | 
			
		||||
                ob_end_clean();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw new FatalThrowableError($e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ob_get_clean();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -72,8 +72,8 @@ class MarkInvoicePaid implements ShouldQueue
 | 
			
		||||
        event(new PaymentWasCreated($payment));
 | 
			
		||||
 | 
			
		||||
        UpdateCompanyLedgerWithPayment::dispatchNow($payment, ($payment->amount*-1));
 | 
			
		||||
        UpdateClientBalance::dispatchNow($payment->client, $this->payment->amount*-1);
 | 
			
		||||
        UpdateClientPaidToDate::dispatchNow($payment->client, $this->payment->amount);
 | 
			
		||||
        UpdateClientBalance::dispatchNow($payment->client, $payment->amount*-1);
 | 
			
		||||
        UpdateClientPaidToDate::dispatchNow($payment->client, $payment->amount);
 | 
			
		||||
 | 
			
		||||
        return $this->invoice;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										50
									
								
								app/Listeners/Invoice/CreateInvoiceHtmlBackup.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								app/Listeners/Invoice/CreateInvoiceHtmlBackup.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Listeners\Invoice;
 | 
			
		||||
 | 
			
		||||
use App\Models\Activity;
 | 
			
		||||
use App\Repositories\ActivityRepository;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
 | 
			
		||||
class CreateInvoiceHtmlBackup 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::MARK_SENT_INVOICE;
 | 
			
		||||
 | 
			
		||||
        $this->activity_repo->save($fields, $event->invoice);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -45,8 +45,6 @@ class UpdateInvoiceInvitations implements ShouldQueue
 | 
			
		||||
		*/
 | 
			
		||||
		$invoices->each(function ($invoice) use($payment) {
 | 
			
		||||
 | 
			
		||||
			$invoice->status_id = Invoice::STATUS_PAID;
 | 
			
		||||
			$invoice->save();
 | 
			
		||||
			$invoice->invitations()->update(['transaction_reference' => $payment->transaction_reference]);
 | 
			
		||||
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
@ -67,6 +67,8 @@ class Activity extends StaticModel
 | 
			
		||||
    const ARCHIVE_USER=50;
 | 
			
		||||
    const DELETE_USER=51;
 | 
			
		||||
    const RESTORE_USER=52;
 | 
			
		||||
    const MARK_SENT_INVOICE=53;
 | 
			
		||||
    const PAID_INVOICE=54;
 | 
			
		||||
    
 | 
			
		||||
    protected $casts = [
 | 
			
		||||
        'is_system' => 'boolean',
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,6 @@ class CompanyUser extends Pivot
 | 
			
		||||
     * @var array
 | 
			
		||||
     */
 | 
			
		||||
    protected $casts = [
 | 
			
		||||
        'settings' => 'object',
 | 
			
		||||
        'permissions' => 'object',
 | 
			
		||||
        'updated_at' => 'timestamp',
 | 
			
		||||
        'created_at' => 'timestamp',
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,8 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Models;
 | 
			
		||||
 | 
			
		||||
use App\Events\Invoice\InvoiceWasMarkedSent;
 | 
			
		||||
use App\Events\Invoice\InvoiceWasPaid;
 | 
			
		||||
use App\Events\Invoice\InvoiceWasUpdated;
 | 
			
		||||
use App\Helpers\Invoice\InvoiceSum;
 | 
			
		||||
use App\Helpers\Invoice\InvoiceSumInclusive;
 | 
			
		||||
@ -370,8 +372,13 @@ class Invoice extends BaseModel
 | 
			
		||||
        
 | 
			
		||||
        $this->balance = $this->balance + $balance_adjustment;
 | 
			
		||||
 | 
			
		||||
        if($this->balance == 0)
 | 
			
		||||
        if($this->balance == 0) {
 | 
			
		||||
            $this->status_id = self::STATUS_PAID;
 | 
			
		||||
            $this->save();
 | 
			
		||||
            event(new InvoiceWasPaid($this));
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->save();
 | 
			
		||||
    }
 | 
			
		||||
@ -399,6 +406,8 @@ class Invoice extends BaseModel
 | 
			
		||||
 | 
			
		||||
        $this->markInvitationsSent();
 | 
			
		||||
 | 
			
		||||
        event(new InvoiceWasMarkedSent($this));
 | 
			
		||||
 | 
			
		||||
        UpdateClientBalance::dispatchNow($this->client, $this->balance);
 | 
			
		||||
        
 | 
			
		||||
        $this->save();
 | 
			
		||||
 | 
			
		||||
@ -327,7 +327,11 @@ class User extends Authenticatable implements MustVerifyEmail
 | 
			
		||||
    public function hasPermission($permission) : bool
 | 
			
		||||
    { 
 | 
			
		||||
 | 
			
		||||
        return $this->permissionsFlat()->contains($permission);
 | 
			
		||||
 | 
			
		||||
        return (stripos($this->user_company()->permissions, $permission) !== false);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
       // return $this->permissionsFlat()->contains($permission);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ use App\Events\Client\ClientWasCreated;
 | 
			
		||||
use App\Events\Contact\ContactLoggedIn;
 | 
			
		||||
use App\Events\Invoice\InvoiceWasCreated;
 | 
			
		||||
use App\Events\Invoice\InvoiceWasMarkedSent;
 | 
			
		||||
use App\Events\Invoice\InvoiceWasPaid;
 | 
			
		||||
use App\Events\Invoice\InvoiceWasUpdated;
 | 
			
		||||
use App\Events\Payment\PaymentWasCreated;
 | 
			
		||||
use App\Events\Payment\PaymentWasDeleted;
 | 
			
		||||
@ -25,6 +26,7 @@ use App\Listeners\Activity\PaymentCreatedActivity;
 | 
			
		||||
use App\Listeners\Activity\PaymentDeletedActivity;
 | 
			
		||||
use App\Listeners\Contact\UpdateContactLastLogin;
 | 
			
		||||
use App\Listeners\Invoice\CreateInvoiceActivity;
 | 
			
		||||
use App\Listeners\Invoice\CreateInvoiceHtmlBackup;
 | 
			
		||||
use App\Listeners\Invoice\CreateInvoiceInvitation;
 | 
			
		||||
use App\Listeners\Invoice\CreateInvoicePdf;
 | 
			
		||||
use App\Listeners\Invoice\UpdateInvoiceActivity;
 | 
			
		||||
@ -59,10 +61,10 @@ class EventServiceProvider extends ServiceProvider
 | 
			
		||||
        PaymentWasCreated::class => [
 | 
			
		||||
            PaymentCreatedActivity::class,
 | 
			
		||||
            //UpdateInvoicePayment::class,
 | 
			
		||||
            UpdateInvoiceInvitations::class,
 | 
			
		||||
            //UpdateInvoiceInvitations::class,
 | 
			
		||||
        ],
 | 
			
		||||
        PaymentWasDeleted::class => [
 | 
			
		||||
            PaymentDeletedActivity::class
 | 
			
		||||
            PaymentDeletedActivity::class,
 | 
			
		||||
        ],
 | 
			
		||||
        'App\Events\ClientWasArchived' => [
 | 
			
		||||
            'App\Listeners\ActivityListener@archivedClient',
 | 
			
		||||
@ -82,7 +84,7 @@ class EventServiceProvider extends ServiceProvider
 | 
			
		||||
        //Invoices
 | 
			
		||||
        
 | 
			
		||||
        InvoiceWasMarkedSent::class => [
 | 
			
		||||
            CreateInvoiceInvitation::class,
 | 
			
		||||
            CreateInvoiceHtmlBackup::class,
 | 
			
		||||
        ],
 | 
			
		||||
        InvoiceWasUpdated::class => [
 | 
			
		||||
            UpdateInvoiceActivity::class,
 | 
			
		||||
@ -92,6 +94,9 @@ class EventServiceProvider extends ServiceProvider
 | 
			
		||||
            CreateInvoiceActivity::class,
 | 
			
		||||
            CreateInvoicePdf::class,
 | 
			
		||||
        ],
 | 
			
		||||
        InvoiceWasPaid::class => [
 | 
			
		||||
            CreateInvoiceHtmlBackup::class,
 | 
			
		||||
        ]
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,8 @@ namespace App\Repositories;
 | 
			
		||||
use App\Models\Activity;
 | 
			
		||||
use App\Models\Backup;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Utils\Traits\MakesInvoiceHtml;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -21,7 +23,7 @@ use Illuminate\Support\Facades\Log;
 | 
			
		||||
 */
 | 
			
		||||
class ActivityRepository extends BaseRepository
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	use MakesInvoiceHtml;
 | 
			
		||||
	/**
 | 
			
		||||
	 * Save the Activity
 | 
			
		||||
	 *
 | 
			
		||||
@ -66,6 +68,11 @@ class ActivityRepository extends BaseRepository
 | 
			
		||||
		else
 | 
			
		||||
			$entity->load('company','client');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if(get_class($entity) == Invoice::class && ($activity->activity_type_id == Activity::MARK_SENT_INVOICE || $activity->activity_type_id == Activity::PAID_INVOICE))
 | 
			
		||||
			$backup->html_backup = $this->generateInvoiceHtml($entity->design(), $entity);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		$backup->activity_id = $activity->id;
 | 
			
		||||
		$backup->json_backup = $entity->toJson();
 | 
			
		||||
		$backup->save();
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,6 @@ use App\Models\Quote;
 | 
			
		||||
use App\Models\RecurringInvoice;
 | 
			
		||||
use App\Models\Timezone;
 | 
			
		||||
use Illuminate\Support\Carbon;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class GeneratesCounter
 | 
			
		||||
@ -43,7 +42,6 @@ trait GeneratesCounter
 | 
			
		||||
 | 
			
		||||
		//todo handle if we have specific client patterns in the future
 | 
			
		||||
		$pattern = $client->getSetting('invoice_number_pattern');
 | 
			
		||||
 | 
			
		||||
		//Determine if we are using client_counters
 | 
			
		||||
		if(strpos($pattern, 'clientCounter'))
 | 
			
		||||
		{
 | 
			
		||||
@ -65,10 +63,12 @@ trait GeneratesCounter
 | 
			
		||||
		$pattern = $client->getSetting('invoice_number_pattern');
 | 
			
		||||
		$prefix = $client->getSetting('invoice_number_prefix');
 | 
			
		||||
		$padding = $client->getSetting('counter_padding');
 | 
			
		||||
		
 | 
			
		||||
		$invoice_number = $this->checkEntityNumber(Invoice::class, $client, $counter, $padding, $prefix, $pattern);
 | 
			
		||||
 | 
			
		||||
		$this->incrementCounter($counter_entity, 'invoice_number_counter');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		return $invoice_number;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -173,7 +173,7 @@ trait GeneratesCounter
 | 
			
		||||
	public function hasSharedCounter(Client $client) : bool
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		return $client->getSettingsByKey('shared_invoice_quote_counter') === TRUE;
 | 
			
		||||
		return $client->getSetting('shared_invoice_quote_counter') === TRUE;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -213,6 +213,7 @@ trait GeneratesCounter
 | 
			
		||||
 | 
			
		||||
		} while ($check);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return $number;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -235,6 +236,7 @@ trait GeneratesCounter
 | 
			
		||||
 | 
			
		||||
	private function prefixCounter($counter, $prefix) : string
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		if(strlen($prefix) == 0)
 | 
			
		||||
			return $counter;
 | 
			
		||||
 | 
			
		||||
@ -330,6 +332,7 @@ trait GeneratesCounter
 | 
			
		||||
     */
 | 
			
		||||
    private function applyNumberPattern(Client $client, string $counter, $pattern) :string
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    	if(!$pattern)
 | 
			
		||||
			return $counter;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								app/Utils/Traits/MakesInvoiceHtml.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/Utils/Traits/MakesInvoiceHtml.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://opensource.org/licenses/AAL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Utils\Traits;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Support\Facades\Blade;
 | 
			
		||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class MakesInvoiceHtml.
 | 
			
		||||
 */
 | 
			
		||||
trait MakesInvoiceHtml
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generate the HTML invoice parsing variables 
 | 
			
		||||
     * and generating the final invoice HTML
 | 
			
		||||
     *     
 | 
			
		||||
     * @param  string $design either the path to the design template, OR the full design template string
 | 
			
		||||
     * @param  Collection $invoice  The invoice object
 | 
			
		||||
     * 
 | 
			
		||||
     * @return string           The invoice string in HTML format
 | 
			
		||||
     */
 | 
			
		||||
    public function generateInvoiceHtml($design, $invoice) :string
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $variables = array_merge($invoice->makeLabels(), $invoice->makeValues());
 | 
			
		||||
        $design = str_replace(array_keys($variables), array_values($variables), $design);
 | 
			
		||||
 | 
			
		||||
        $data['invoice'] = $invoice;
 | 
			
		||||
 | 
			
		||||
        return $this->renderView($design, $data);
 | 
			
		||||
 | 
			
		||||
        //return view($design, $data)->render();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parses the blade file string and processes the template variables
 | 
			
		||||
     * 
 | 
			
		||||
     * @param  string $string The Blade file string
 | 
			
		||||
     * @param  array $data   The array of template variables
 | 
			
		||||
     * @return string         The return HTML string
 | 
			
		||||
     * 
 | 
			
		||||
     */
 | 
			
		||||
    public function renderView($string, $data) :string
 | 
			
		||||
    {
 | 
			
		||||
        if (!$data) {
 | 
			
		||||
        $data = [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $data['__env'] = app(\Illuminate\View\Factory::class);
 | 
			
		||||
 | 
			
		||||
        $php = Blade::compileString($string);
 | 
			
		||||
 | 
			
		||||
        $obLevel = ob_get_level();
 | 
			
		||||
        ob_start();
 | 
			
		||||
        extract($data, EXTR_SKIP);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            eval('?' . '>' . $php);
 | 
			
		||||
        } catch (\Exception $e) {
 | 
			
		||||
            while (ob_get_level() > $obLevel) {
 | 
			
		||||
                ob_end_clean();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw $e;
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            while (ob_get_level() > $obLevel) {
 | 
			
		||||
                ob_end_clean();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw new FatalThrowableError($e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ob_get_clean();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -41,11 +41,11 @@ return [
 | 
			
		||||
            'username'  => env('DB_USERNAME1', 'forge'),
 | 
			
		||||
            'password'  => env('DB_PASSWORD1', ''),
 | 
			
		||||
            'port'      => env('DB_PORT1', '3306'),
 | 
			
		||||
            'charset'   => 'utf8',
 | 
			
		||||
            'collation' => 'utf8_unicode_ci',
 | 
			
		||||
            'charset'   => 'utf8mb4',
 | 
			
		||||
            'collation' => 'utf8mb4_unicode_ci',
 | 
			
		||||
            'prefix'    => '',
 | 
			
		||||
            'strict'    => env('DB_STRICT', false),
 | 
			
		||||
            'engine'    => 'InnoDB',
 | 
			
		||||
            'engine'    => 'InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8',
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        'sqlite' => [
 | 
			
		||||
@ -92,7 +92,7 @@ return [
 | 
			
		||||
            'prefix'         => '',
 | 
			
		||||
            'prefix_indexes' => true,
 | 
			
		||||
            'strict'         => env('DB_STRICT', false),
 | 
			
		||||
            'engine'         => 'InnoDB',
 | 
			
		||||
            'engine'    => 'InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8',
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        'db-ninja-02' => [
 | 
			
		||||
@ -107,7 +107,7 @@ return [
 | 
			
		||||
            'prefix'         => '',
 | 
			
		||||
            'prefix_indexes' => true,
 | 
			
		||||
            'strict'         => env('DB_STRICT', false),
 | 
			
		||||
            'engine'         => 'InnoDB',
 | 
			
		||||
            'engine'    => 'InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8',
 | 
			
		||||
        ],
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,9 @@ class CreateUsersTable extends Migration
 | 
			
		||||
    public function up()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    DB::raw("SET GLOBAL innodb_file_per_table=1;");
 | 
			
		||||
    DB::raw("SET GLOBAL innodb_file_format=Barracuda;");
 | 
			
		||||
 | 
			
		||||
        Schema::create('languages', function ($table) {
 | 
			
		||||
            $table->increments('id');
 | 
			
		||||
            $table->string('name');
 | 
			
		||||
@ -179,7 +182,7 @@ class CreateUsersTable extends Migration
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        DB::statement('ALTER table companies key_block_size=8 row_format=compressed');
 | 
			
		||||
        //DB::statement('ALTER table companies key_block_size=8 row_format=compressed');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        Schema::create('company_user', function (Blueprint $table) {
 | 
			
		||||
@ -195,6 +198,7 @@ class CreateUsersTable extends Migration
 | 
			
		||||
 | 
			
		||||
            $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
 | 
			
		||||
            $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
 | 
			
		||||
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
 | 
			
		||||
 | 
			
		||||
            $table->index(['account_id', 'company_id']);
 | 
			
		||||
 | 
			
		||||
@ -255,8 +259,7 @@ class CreateUsersTable extends Migration
 | 
			
		||||
 | 
			
		||||
            $table->unique(['oauth_user_id', 'oauth_provider_id']);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
           // $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
 | 
			
		||||
            $table->foreign('user_id')->references('user_id')->on('company_users')->onDelete('cascade');
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@ -364,7 +367,6 @@ class CreateUsersTable extends Migration
 | 
			
		||||
            $table->timestamps(6);
 | 
			
		||||
            $table->softDeletes('deleted_at', 6);
 | 
			
		||||
 | 
			
		||||
            $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
 | 
			
		||||
            $table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
 | 
			
		||||
            //$table->unique(['company_id', 'email']);
 | 
			
		||||
        });
 | 
			
		||||
@ -755,7 +757,7 @@ class CreateUsersTable extends Migration
 | 
			
		||||
            $t->foreign('client_contact_id')->references('id')->on('client_contacts')->onDelete('cascade');
 | 
			
		||||
            $t->foreign('company_gateway_id')->references('id')->on('company_gateways')->onDelete('cascade');
 | 
			
		||||
            $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
 | 
			
		||||
            ;
 | 
			
		||||
            
 | 
			
		||||
            $t->foreign('payment_type_id')->references('id')->on('payment_types');
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
@ -766,6 +768,9 @@ class CreateUsersTable extends Migration
 | 
			
		||||
            $table->unsignedInteger('paymentable_id');
 | 
			
		||||
            $table->decimal('amount', 16, 4)->default(0);
 | 
			
		||||
            $table->string('paymentable_type');
 | 
			
		||||
 | 
			
		||||
            $table->foreign('payment_id')->references('id')->on('payments')->onDelete('cascade');
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Schema::create('payment_libraries', function ($t) {
 | 
			
		||||
@ -896,7 +901,8 @@ class CreateUsersTable extends Migration
 | 
			
		||||
        Schema::create('backups', function ($table) {
 | 
			
		||||
            $table->increments('id');
 | 
			
		||||
            $table->unsignedInteger('activity_id');
 | 
			
		||||
            $table->mediumText('json_backup')->nullable();
 | 
			
		||||
            $table->longText('json_backup')->nullable();
 | 
			
		||||
            $table->longText('html_backup')->nullable();
 | 
			
		||||
            $table->timestamps(6);
 | 
			
		||||
 | 
			
		||||
            $table->foreign('activity_id')->references('id')->on('activities')->onDelete('cascade');
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,9 @@ Route::group(['middleware' => ['api_db','api_secret_check','token_auth'], 'prefi
 | 
			
		||||
 | 
			
		||||
  Route::post('users/bulk', 'UserController@bulk')->name('users.bulk')->middleware('password_protected');
 | 
			
		||||
 | 
			
		||||
  Route::post('migration/purge/{company}', 'MigrationController@purgeCompany');
 | 
			
		||||
  Route::post('migration/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings');
 | 
			
		||||
 | 
			
		||||
  Route::resource('companies', 'CompanyController'); // name = (companies. index / create / show / update / destroy / edit
 | 
			
		||||
 | 
			
		||||
  Route::resource('company_gateways', 'CompanyGatewayController');
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										96
									
								
								tests/Feature/MigrationTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								tests/Feature/MigrationTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,96 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Feature;
 | 
			
		||||
 | 
			
		||||
use App\Jobs\Account\CreateAccount;
 | 
			
		||||
use App\Models\Account;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\Company;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
use App\Utils\Traits\UserSessionAttributes;
 | 
			
		||||
use Faker\Factory;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
 | 
			
		||||
use Illuminate\Foundation\Testing\RefreshDatabase;
 | 
			
		||||
use Illuminate\Foundation\Testing\WithFaker;
 | 
			
		||||
use Illuminate\Http\Request;
 | 
			
		||||
use Illuminate\Support\Facades\DB;
 | 
			
		||||
use Illuminate\Support\Facades\Session;
 | 
			
		||||
use Tests\MockAccountData;
 | 
			
		||||
use Tests\TestCase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @test
 | 
			
		||||
 * @covers App\Http\Controllers\MigrationController
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class MigrationTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    use DatabaseTransactions;
 | 
			
		||||
    use MockAccountData;
 | 
			
		||||
 | 
			
		||||
    public function setUp() :void
 | 
			
		||||
    {
 | 
			
		||||
        parent::setUp();
 | 
			
		||||
 | 
			
		||||
        Session::start();
 | 
			
		||||
 | 
			
		||||
        $this->faker = \Faker\Factory::create();
 | 
			
		||||
 | 
			
		||||
        Model::reguard();
 | 
			
		||||
    
 | 
			
		||||
        $this->makeTestData();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function testCompanyExists()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    	$co = Company::find($this->company->id);
 | 
			
		||||
 | 
			
		||||
    	// $this->assertNull($this->company);
 | 
			
		||||
    	$this->assertNotNull($co);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testThatCompanyDeletesCompletely()
 | 
			
		||||
    {
 | 
			
		||||
    	$company_id = $this->company->id;
 | 
			
		||||
 | 
			
		||||
    	$this->company->delete();
 | 
			
		||||
    	$this->company->fresh();
 | 
			
		||||
 | 
			
		||||
    	$co = Company::find($company_id);
 | 
			
		||||
 | 
			
		||||
    	// $this->assertNull($this->company);
 | 
			
		||||
    	$this->assertNull($co);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testCompanyChildDeletes()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        $this->makeTestData();
 | 
			
		||||
 | 
			
		||||
        $this->assertNotNull($this->company);
 | 
			
		||||
 | 
			
		||||
    	$co = Client::whereCompanyId($this->company->id)->get();
 | 
			
		||||
    	$inv = Invoice::whereCompanyId($this->company->id)->get();
 | 
			
		||||
 | 
			
		||||
    	$this->assertEquals($co->count(),1);
 | 
			
		||||
    	$this->assertEquals($inv->count(),1);
 | 
			
		||||
 | 
			
		||||
		DB::statement( 'DELETE FROM `clients` WHERE `company_id`=:company_id', array('company_id' => $this->company->id) );
 | 
			
		||||
 | 
			
		||||
    	$co = Client::whereCompanyId($this->company->id)->get();
 | 
			
		||||
    	$inv = Invoice::whereCompanyId($this->company->id)->get();
 | 
			
		||||
 | 
			
		||||
    	$this->assertEquals($co->count(),0);
 | 
			
		||||
    	$this->assertEquals($inv->count(),0);
 | 
			
		||||
 | 
			
		||||
    	$this->assertNotNull($this->company);
 | 
			
		||||
    	$this->assertNotNull($this->company->settings);
 | 
			
		||||
    	$this->assertNotNull($this->company->settings->timezone_id);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -28,6 +28,7 @@ use App\Models\GroupSetting;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Models\Quote;
 | 
			
		||||
use App\Models\RecurringInvoice;
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
use App\Utils\Traits\GeneratesCounter;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
use Illuminate\Support\Carbon;
 | 
			
		||||
@ -93,10 +94,14 @@ trait MockAccountData
 | 
			
		||||
        $this->account->default_company_id = $this->company->id;
 | 
			
		||||
        $this->account->save();
 | 
			
		||||
 | 
			
		||||
        $this->user = factory(\App\Models\User::class)->create([
 | 
			
		||||
        //    'account_id' => $account->id,
 | 
			
		||||
            'confirmation_code' => $this->createDbHash(config('database.default'))
 | 
			
		||||
        ]);
 | 
			
		||||
        $this->user = User::whereEmail('user@example.com')->first();
 | 
			
		||||
 | 
			
		||||
        if(!$this->user){
 | 
			
		||||
            $this->user = factory(\App\Models\User::class)->create([
 | 
			
		||||
            //    'account_id' => $account->id,
 | 
			
		||||
                'confirmation_code' => $this->createDbHash(config('database.default'))
 | 
			
		||||
            ]);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $this->token = \Illuminate\Support\Str::random(64);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,10 +9,12 @@ use App\Factory\InvoiceFactory;
 | 
			
		||||
use App\Factory\ProductFactory;
 | 
			
		||||
use App\Factory\UserFactory;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
 | 
			
		||||
use Illuminate\Support\Facades\Session;
 | 
			
		||||
use Tests\MockAccountData;
 | 
			
		||||
use Tests\TestCase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -22,6 +24,7 @@ class FactoryCreationTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    use MakesHash;
 | 
			
		||||
    use DatabaseTransactions;
 | 
			
		||||
    use MockAccountData;
 | 
			
		||||
 | 
			
		||||
    public function setUp() :void
 | 
			
		||||
    {
 | 
			
		||||
@ -34,21 +37,8 @@ class FactoryCreationTest extends TestCase
 | 
			
		||||
 | 
			
		||||
        Model::reguard();
 | 
			
		||||
 | 
			
		||||
        $this->makeTestData();
 | 
			
		||||
        
 | 
			
		||||
        $this->account = factory(\App\Models\Account::class)->create();
 | 
			
		||||
                $this->company = factory(\App\Models\Company::class)->create([
 | 
			
		||||
                    'account_id' => $this->account->id,
 | 
			
		||||
                                'domain' => 'ninja.test',
 | 
			
		||||
 | 
			
		||||
                ]);
 | 
			
		||||
 | 
			
		||||
        $this->account->default_company_id = $this->company->id;
 | 
			
		||||
        $this->account->save();
 | 
			
		||||
 | 
			
		||||
        $this->user = factory(\App\Models\User::class)->create([
 | 
			
		||||
        //    'account_id' => $account->id,
 | 
			
		||||
            'confirmation_code' => $this->createDbHash(config('database.default'))
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -120,13 +110,13 @@ class FactoryCreationTest extends TestCase
 | 
			
		||||
     */
 | 
			
		||||
    public function testClientCreate()
 | 
			
		||||
    {
 | 
			
		||||
        $client = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
 | 
			
		||||
        $client->save();
 | 
			
		||||
        $cliz->save();
 | 
			
		||||
 | 
			
		||||
        $this->assertNotNull($client);
 | 
			
		||||
        $this->assertNotNull($cliz);
 | 
			
		||||
 | 
			
		||||
        $this->assertInternalType("int", $client->id);
 | 
			
		||||
        $this->assertInternalType("int", $cliz->id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -136,33 +126,13 @@ class FactoryCreationTest extends TestCase
 | 
			
		||||
    public function testClientContactCreate()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    factory(\App\Models\Client::class)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c){
 | 
			
		||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
 | 
			
		||||
            factory(\App\Models\ClientContact::class,1)->create([
 | 
			
		||||
                'user_id' => $this->user->id,
 | 
			
		||||
                'client_id' => $c->id,
 | 
			
		||||
                'company_id' => $this->company->id,
 | 
			
		||||
                'is_primary' => 1
 | 
			
		||||
            ]);
 | 
			
		||||
        $cliz->save();
 | 
			
		||||
 | 
			
		||||
            factory(\App\Models\ClientContact::class,2)->create([
 | 
			
		||||
                'user_id' => $this->user->id,
 | 
			
		||||
                'client_id' => $c->id,
 | 
			
		||||
                'company_id' => $this->company->id
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $client = Client::whereUserId($this->user->id)->whereCompanyId($this->company->id)->first();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        $contact = ClientContactFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        $contact->client_id = $client->id;
 | 
			
		||||
        $contact->save();
 | 
			
		||||
 | 
			
		||||
        $this->assertNotNull($contact);
 | 
			
		||||
 | 
			
		||||
        $this->assertInternalType("int", $contact->id);
 | 
			
		||||
        $this->assertNotNull($cliz->contacts);
 | 
			
		||||
        $this->assertEquals(1, $cliz->contacts->count());
 | 
			
		||||
        $this->assertInternalType("int", $cliz->contacts->first()->id);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,15 @@
 | 
			
		||||
 | 
			
		||||
namespace Tests\Unit;
 | 
			
		||||
 | 
			
		||||
use App\DataMapper\ClientSettings;
 | 
			
		||||
use App\DataMapper\DefaultSettings;
 | 
			
		||||
use App\Factory\ClientFactory;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\Company;
 | 
			
		||||
use App\Models\Credit;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Models\RecurringInvoice;
 | 
			
		||||
use App\Models\User;
 | 
			
		||||
use App\Utils\Traits\GeneratesCounter;
 | 
			
		||||
use App\Utils\Traits\GeneratesNumberCounter;
 | 
			
		||||
use App\Utils\Traits\MakesHash;
 | 
			
		||||
@ -15,6 +18,7 @@ use Illuminate\Database\Eloquent\Model;
 | 
			
		||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
 | 
			
		||||
use Illuminate\Support\Facades\Log;
 | 
			
		||||
use Illuminate\Support\Facades\Session;
 | 
			
		||||
use Tests\MockAccountData;
 | 
			
		||||
use Tests\TestCase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -26,7 +30,7 @@ class GeneratesCounterTest extends TestCase
 | 
			
		||||
	use GeneratesCounter;
 | 
			
		||||
    use DatabaseTransactions;
 | 
			
		||||
    use MakesHash;
 | 
			
		||||
    //use MockAccountData;
 | 
			
		||||
    use MockAccountData;
 | 
			
		||||
 | 
			
		||||
    public function setUp() :void
 | 
			
		||||
    {
 | 
			
		||||
@ -36,49 +40,8 @@ class GeneratesCounterTest extends TestCase
 | 
			
		||||
        Session::start();
 | 
			
		||||
        $this->faker = \Faker\Factory::create();
 | 
			
		||||
        Model::reguard();
 | 
			
		||||
                $account = factory(\App\Models\Account::class)->create();
 | 
			
		||||
        $company = factory(\App\Models\Company::class)->create([
 | 
			
		||||
            'account_id' => $account->id,
 | 
			
		||||
                        'domain' => 'ninja.test',
 | 
			
		||||
 | 
			
		||||
        ]);
 | 
			
		||||
        $account->default_company_id = $company->id;
 | 
			
		||||
        $account->save();
 | 
			
		||||
        $user = factory(\App\Models\User::class)->create([
 | 
			
		||||
        //    'account_id' => $account->id,
 | 
			
		||||
            'confirmation_code' => $this->createDbHash(config('database.default'))
 | 
			
		||||
        ]);
 | 
			
		||||
        $userPermissions = collect([
 | 
			
		||||
                                    'view_invoice',
 | 
			
		||||
                                    'view_client',
 | 
			
		||||
                                    'edit_client',
 | 
			
		||||
                                    'edit_invoice',
 | 
			
		||||
                                    'create_invoice',
 | 
			
		||||
                                    'create_client'
 | 
			
		||||
                                ]);
 | 
			
		||||
        $userSettings = DefaultSettings::userSettings();
 | 
			
		||||
        $user->companies()->attach($company->id, [
 | 
			
		||||
            'account_id' => $account->id,
 | 
			
		||||
            'is_owner' => 1,
 | 
			
		||||
            'is_admin' => 1,
 | 
			
		||||
            'permissions' => $userPermissions->toJson(),
 | 
			
		||||
            'settings' => json_encode($userSettings),
 | 
			
		||||
            'is_locked' => 0,
 | 
			
		||||
        ]);
 | 
			
		||||
        factory(\App\Models\Client::class)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
 | 
			
		||||
            factory(\App\Models\ClientContact::class,1)->create([
 | 
			
		||||
                'user_id' => $user->id,
 | 
			
		||||
                'client_id' => $c->id,
 | 
			
		||||
                'company_id' => $company->id,
 | 
			
		||||
                'is_primary' => 1
 | 
			
		||||
            ]);
 | 
			
		||||
            factory(\App\Models\ClientContact::class,2)->create([
 | 
			
		||||
                'user_id' => $user->id,
 | 
			
		||||
                'client_id' => $c->id,
 | 
			
		||||
                'company_id' => $company->id
 | 
			
		||||
            ]);
 | 
			
		||||
        });
 | 
			
		||||
        $this->client = Client::whereUserId($user->id)->whereCompanyId($company->id)->first();
 | 
			
		||||
        $this->makeTestData();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -92,11 +55,11 @@ class GeneratesCounterTest extends TestCase
 | 
			
		||||
 | 
			
		||||
    	$invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($invoice_number, 1);
 | 
			
		||||
        $this->assertEquals($invoice_number, 0007);
 | 
			
		||||
 | 
			
		||||
    	$invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($invoice_number, 2);
 | 
			
		||||
        $this->assertEquals($invoice_number, '0008');
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -110,6 +73,10 @@ class GeneratesCounterTest extends TestCase
 | 
			
		||||
        $this->client->company->settings = $settings;
 | 
			
		||||
        $this->client->company->save();
 | 
			
		||||
 | 
			
		||||
        $this->client->settings = $settings;
 | 
			
		||||
        $this->client->save();
 | 
			
		||||
        $this->client->fresh();
 | 
			
		||||
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
        $invoice_number2 = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
 | 
			
		||||
@ -121,70 +88,86 @@ class GeneratesCounterTest extends TestCase
 | 
			
		||||
 | 
			
		||||
    public function testInvoiceClientNumberPattern()
 | 
			
		||||
    {
 | 
			
		||||
        $settings = $this->client->company->settings;
 | 
			
		||||
        $settings = $this->company->settings;
 | 
			
		||||
        $settings->client_number_prefix = '';
 | 
			
		||||
        $settings->client_number_pattern = '{$year}-{$clientCounter}';
 | 
			
		||||
        $settings->client_number_counter = 10;
 | 
			
		||||
 | 
			
		||||
        $settings->invoice_number_prefix = '';
 | 
			
		||||
        $settings->invoice_number_pattern = '{$year}-{$clientCounter}';
 | 
			
		||||
        $this->client->company->settings = $settings;
 | 
			
		||||
        $this->client->company->save();
 | 
			
		||||
        $this->company->settings = $settings;
 | 
			
		||||
        $this->company->save();
 | 
			
		||||
 | 
			
		||||
        $settings = $this->client->settings;
 | 
			
		||||
        $settings->invoice_number_counter = 10;
 | 
			
		||||
        $settings->client_number_pattern = '{$year}-{$clientCounter}';
 | 
			
		||||
        $settings->client_number_counter = 10;
 | 
			
		||||
        $this->client->settings = $settings;
 | 
			
		||||
        $this->client->save();
 | 
			
		||||
        $this->client->fresh();
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($this->client->settings->invoice_number_counter,10);
 | 
			
		||||
        $this->assertEquals($this->client->settings->client_number_counter,10);
 | 
			
		||||
        $this->assertEquals($this->client->getSetting('client_number_pattern'), '{$year}-{$clientCounter}');
 | 
			
		||||
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
        $invoice_number = $this->getNextClientNumber($this->client);
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($invoice_number, '2019-0010');
 | 
			
		||||
        $this->assertEquals($invoice_number, '2019-0001');
 | 
			
		||||
        
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
		$this->assertEquals($invoice_number, '2019-0011');
 | 
			
		||||
        $invoice_number = $this->getNextClientNumber($this->client);
 | 
			
		||||
		$this->assertEquals($invoice_number, '2019-0002');
 | 
			
		||||
        
 | 
			
		||||
       
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testInvoicePadding()
 | 
			
		||||
    {
 | 
			
		||||
        $settings = $this->client->company->settings;
 | 
			
		||||
        $settings = $this->company->settings;
 | 
			
		||||
        $settings->counter_padding = 5;
 | 
			
		||||
        $this->client->company->settings = $settings;
 | 
			
		||||
        $this->client->push();
 | 
			
		||||
        $settings->invoice_number_counter = 7;
 | 
			
		||||
        //$this->client->settings = $settings;
 | 
			
		||||
        $this->company->settings = $settings;
 | 
			
		||||
        $this->company->save();
 | 
			
		||||
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        $cliz->settings = ClientSettings::defaults();
 | 
			
		||||
        $cliz->save();
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($this->client->company->settings->counter_padding, 5);
 | 
			
		||||
        $this->assertEquals($cliz->getSetting('counter_padding'), 5);
 | 
			
		||||
        $this->assertEquals($invoice_number, '00007');
 | 
			
		||||
        $this->assertEquals(strlen($invoice_number), 5);
 | 
			
		||||
        $this->assertEquals($invoice_number, '00001');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        $settings = $this->client->company->settings;
 | 
			
		||||
        $settings = $this->company->settings;
 | 
			
		||||
        $settings->counter_padding = 10;
 | 
			
		||||
        $this->client->company->settings = $settings;
 | 
			
		||||
        $this->client->push();
 | 
			
		||||
        $this->company->settings = $settings;
 | 
			
		||||
        $this->company->save();
 | 
			
		||||
        
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        $cliz->settings = ClientSettings::defaults();
 | 
			
		||||
        $cliz->save();
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($this->client->company->settings->counter_padding, 10);
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($cliz->getSetting('counter_padding'), 10);
 | 
			
		||||
        $this->assertEquals(strlen($invoice_number), 10);
 | 
			
		||||
        $this->assertEquals($invoice_number, '0000000002');
 | 
			
		||||
        $this->assertEquals($invoice_number, '0000000007');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testInvoicePrefix()
 | 
			
		||||
    {
 | 
			
		||||
        $settings = $this->client->company->settings;
 | 
			
		||||
        $settings = $this->company->settings;
 | 
			
		||||
        $settings->invoice_number_prefix = 'X';
 | 
			
		||||
        $this->client->company->settings = $settings;
 | 
			
		||||
        $this->client->company->save();    
 | 
			
		||||
        $this->company->settings = $settings;
 | 
			
		||||
        $this->company->save();    
 | 
			
		||||
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        $cliz->settings = ClientSettings::defaults();
 | 
			
		||||
        $cliz->save();
 | 
			
		||||
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
			
		||||
    
 | 
			
		||||
        $this->assertEquals($invoice_number, 'X0001');
 | 
			
		||||
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($this->client);
 | 
			
		||||
        $invoice_number = $this->getNextInvoiceNumber($cliz);
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($invoice_number, 'X0002');
 | 
			
		||||
 | 
			
		||||
@ -206,16 +189,20 @@ class GeneratesCounterTest extends TestCase
 | 
			
		||||
 | 
			
		||||
    public function testClientNumberPrefix()
 | 
			
		||||
    {
 | 
			
		||||
        $settings = $this->client->company->settings;
 | 
			
		||||
        $settings = $this->company->settings;
 | 
			
		||||
        $settings->client_number_prefix = 'C';
 | 
			
		||||
        $this->client->company->settings = $settings;
 | 
			
		||||
        $this->client->company->save();    
 | 
			
		||||
        $this->company->settings = $settings;
 | 
			
		||||
        $this->company->save();    
 | 
			
		||||
 | 
			
		||||
        $client_number = $this->getNextClientNumber($this->client);
 | 
			
		||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        $cliz->settings = ClientSettings::defaults();
 | 
			
		||||
        $cliz->save();
 | 
			
		||||
 | 
			
		||||
        $client_number = $this->getNextClientNumber($cliz);
 | 
			
		||||
    
 | 
			
		||||
        $this->assertEquals($client_number, 'C0001');
 | 
			
		||||
 | 
			
		||||
        $client_number = $this->getNextClientNumber($this->client);
 | 
			
		||||
        $client_number = $this->getNextClientNumber($cliz);
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($client_number, 'C0002');
 | 
			
		||||
 | 
			
		||||
@ -224,21 +211,23 @@ class GeneratesCounterTest extends TestCase
 | 
			
		||||
 | 
			
		||||
    public function testClientNumberPattern()
 | 
			
		||||
    {
 | 
			
		||||
        $settings = $this->client->company->settings;
 | 
			
		||||
        $settings = $this->company->settings;
 | 
			
		||||
        $settings->client_number_prefix = '';
 | 
			
		||||
        $settings->client_number_pattern = '{$year}-{$user_id}-{$counter}';
 | 
			
		||||
        $this->client->company->settings = $settings;
 | 
			
		||||
        $this->client->company->save();  
 | 
			
		||||
        $this->client->save();
 | 
			
		||||
        $this->client->fresh();  
 | 
			
		||||
        $this->company->settings = $settings;
 | 
			
		||||
        $this->company->save();  
 | 
			
		||||
 | 
			
		||||
        $client_number = $this->getNextClientNumber($this->client);
 | 
			
		||||
        $cliz = ClientFactory::create($this->company->id, $this->user->id);
 | 
			
		||||
        $cliz->settings = ClientSettings::defaults();
 | 
			
		||||
        $cliz->save();
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($client_number, date('Y') . '-' . $this->client->user_id . '-0001');
 | 
			
		||||
        $client_number = $this->getNextClientNumber($cliz);
 | 
			
		||||
    
 | 
			
		||||
        $client_number = $this->getNextClientNumber($this->client);
 | 
			
		||||
        $this->assertEquals($client_number, date('Y') . '-' . str_pad($this->client->user_id, 2, '0', STR_PAD_LEFT) . '-0001');
 | 
			
		||||
 | 
			
		||||
        $this->assertEquals($client_number, date('Y') . '-' . $this->client->user_id . '-0002');
 | 
			
		||||
        $client_number = $this->getNextClientNumber($cliz);
 | 
			
		||||
    
 | 
			
		||||
        $this->assertEquals($client_number, date('Y') . '-' . str_pad($this->client->user_id, 2, '0', STR_PAD_LEFT) . '-0002');
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user