$total_tax_labels
$line_tax_labels
diff --git a/app/Factory/CompanyFactory.php b/app/Factory/CompanyFactory.php
index 03b84ac41b49..0dfe4f4ed20e 100644
--- a/app/Factory/CompanyFactory.php
+++ b/app/Factory/CompanyFactory.php
@@ -31,7 +31,8 @@ class CompanyFactory
$company->company_key = $this->createHash();
$company->settings = CompanySettings::defaults();
$company->db = config('database.default');
- $company->custom_fields = (object) ['custom1' => '1', 'custom2' => '2', 'custom3'=>'3'];
+ //$company->custom_fields = (object) ['invoice1' => '1', 'invoice2' => '2', 'client1'=>'3'];
+ $company->custom_fields = (object) [];
$company->subdomain = '';
return $company;
diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php
index 17ee43a6c82f..f32a609adc59 100644
--- a/app/Http/Controllers/BaseController.php
+++ b/app/Http/Controllers/BaseController.php
@@ -56,32 +56,35 @@ class BaseController extends Controller
public function __construct()
{
+
$this->manager = new Manager();
$this->forced_includes = [];
$this->forced_index = 'data';
+
}
private function buildManager()
{
+
$include = '';
if(request()->has('first_load') && request()->input('first_load') == 'true') {
- $include = $this->getRequestIncludes([]);
- $include = array_merge($this->forced_includes, $include);
+ $include = implode("," , array_merge($this->forced_includes, $this->getRequestIncludes([])));
- $include = implode(",", $include);
}
else if (request()->input('include') !== null) {
- $request_include = explode(",", request()->input('include'));
- $include = array_merge($this->forced_includes, $request_include);
+ $include = array_merge($this->forced_includes, explode(",", request()->input('include')));
$include = implode(",", $include);
+
} elseif (count($this->forced_includes) >= 1) {
+
$include = implode(",", $this->forced_includes);
+
}
$this->manager->parseIncludes($include);
@@ -89,10 +92,15 @@ class BaseController extends Controller
$this->serializer = request()->input('serializer') ?: EntityTransformer::API_SERIALIZER_ARRAY;
if ($this->serializer === EntityTransformer::API_SERIALIZER_JSON) {
+
$this->manager->setSerializer(new JsonApiSerializer());
+
} else {
+
$this->manager->setSerializer(new ArraySerializer());
+
}
+
}
/**
@@ -101,27 +109,36 @@ class BaseController extends Controller
*/
public function notFound()
{
+
return response()->json(['message' => '404 | Nothing to see here!'], 404)
->header('X-API-VERSION', config('ninja.api_version'))
->header('X-APP-VERSION', config('ninja.app_version'));
+
}
public function notFoundClient()
{
+
return abort(404);
+
}
protected function errorResponse($response, $httpErrorCode = 400)
{
+
$error['error'] = $response;
+
$error = json_encode($error, JSON_PRETTY_PRINT);
+
$headers = self::getApiHeaders();
return response()->make($error, $httpErrorCode, $headers);
+
}
protected function listResponse($query)
{
+
$this->buildManager();
$transformer = new $this->entity_transformer(Input::get('serializer'));
@@ -145,32 +162,40 @@ class BaseController extends Controller
$data = $this->createCollection($query, $transformer, $this->entity_type);
return $this->response($data);
+
}
protected function createCollection($query, $transformer, $entity_type)
{
+
$this->buildManager();
- if ($this->serializer && $this->serializer != EntityTransformer::API_SERIALIZER_JSON) {
+ if ($this->serializer && $this->serializer != EntityTransformer::API_SERIALIZER_JSON)
$entity_type = null;
- }
+
if (is_a($query, "Illuminate\Database\Eloquent\Builder")) {
+
$limit = Input::get('per_page', 20);
$paginator = $query->paginate($limit);
$query = $paginator->getCollection();
$resource = new Collection($query, $transformer, $entity_type);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
+
} else {
+
$resource = new Collection($query, $transformer, $entity_type);
+
}
return $this->manager->createData($resource)->toArray();
+
}
protected function response($response)
{
+
$index = request()->input('index') ?: $this->forced_index;
if ($index == 'none') {
@@ -194,55 +219,50 @@ class BaseController extends Controller
ksort($response);
$response = json_encode($response, JSON_PRETTY_PRINT);
+
$headers = self::getApiHeaders();
-
return response()->make($response, 200, $headers);
+
}
protected function itemResponse($item)
{
+
$this->buildManager();
$transformer = new $this->entity_transformer(Input::get('serializer'));
$data = $this->createItem($item, $transformer, $this->entity_type);
- if (request()->include_static) {
+ if (request()->include_static)
$data['static'] = Statics::company(auth()->user()->getCompany()->getLocale());
- }
-
return $this->response($data);
+
}
protected function createItem($data, $transformer, $entity_type)
{
- if ($this->serializer && $this->serializer != EntityTransformer::API_SERIALIZER_JSON) {
- $entity_type = null;
- }
-
+ if ($this->serializer && $this->serializer != EntityTransformer::API_SERIALIZER_JSON)
+ $entity_type = null;
+
$resource = new Item($data, $transformer, $entity_type);
return $this->manager->createData($resource)->toArray();
+
}
public static function getApiHeaders($count = 0)
{
+
return [
'Content-Type' => 'application/json',
- //'Access-Control-Allow-Origin' => '*',
- //'Access-Control-Allow-Methods' => 'GET',
- //'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
- //'Access-Control-Allow-Credentials' => 'true',
- //'X-Total-Count' => $count,
'X-Api-Version' => config('ninja.api_version'),
'X-App-Version' => config('ninja.app_version'),
- //'X-Rate-Limit-Limit' - The number of allowed requests in the current period
- //'X-Rate-Limit-Remaining' - The number of remaining requests in the current period
- //'X-Rate-Limit-Reset' - The number of seconds left in the current period,
];
+
}
@@ -279,7 +299,9 @@ class BaseController extends Controller
'company.groups',
];
-
+ /**
+ * Thresholds for displaying large account on first load
+ */
if (request()->has('first_load') && request()->input('first_load') == 'true')
{
@@ -315,4 +337,5 @@ class BaseController extends Controller
return $data;
}
+
}
diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index fdb423150a5c..50319d2ca668 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -24,640 +24,636 @@ use App\Http\Requests\Invoice\EditInvoiceRequest;
use App\Http\Requests\Invoice\ShowInvoiceRequest;
use App\Http\Requests\Invoice\StoreInvoiceRequest;
use App\Http\Requests\Invoice\UpdateInvoiceRequest;
-use App\Jobs\Entity\ActionEntity;
+
use App\Jobs\Invoice\EmailInvoice;
-use App\Jobs\Invoice\MarkInvoicePaid;
+
use App\Jobs\Invoice\StoreInvoice;
use App\Models\Invoice;
-use App\Repositories\BaseRepository;
+
use App\Repositories\InvoiceRepository;
use App\Transformers\InvoiceTransformer;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
/**
* Class InvoiceController
* @package App\Http\Controllers\InvoiceController
*/
-class InvoiceController extends BaseController
-{
- use MakesHash;
+class InvoiceController extends BaseController {
+ use MakesHash;
- protected $entity_type = Invoice::class;
+ protected $entity_type = Invoice::class ;
- protected $entity_transformer = InvoiceTransformer::class;
+ protected $entity_transformer = InvoiceTransformer::class ;
- /**
- * @var InvoiceRepository
- */
- protected $invoice_repo;
+ /**
+ * @var InvoiceRepository
+ */
+ protected $invoice_repo;
- /**
- * InvoiceController constructor.
- *
- * @param \App\Repositories\InvoiceRepository $invoice_repo The invoice repo
- */
- public function __construct(InvoiceRepository $invoice_repo)
- {
- parent::__construct();
+ /**
+ * InvoiceController constructor.
+ *
+ * @param \App\Repositories\InvoiceRepository $invoice_repo The invoice repo
+ */
+ public function __construct(InvoiceRepository $invoice_repo) {
+ parent::__construct();
- $this->invoice_repo = $invoice_repo;
- }
+ $this->invoice_repo = $invoice_repo;
+ }
- /**
- * Show the list of Invoices
- *
- * @param \App\Filters\InvoiceFilters $filters The filters
- *
- * @return \Illuminate\Http\Response
- *
- * @OA\Get(
- * path="/api/v1/invoices",
- * operationId="getInvoices",
- * tags={"invoices"},
- * summary="Gets a list of invoices",
- * description="Lists invoices, search and filters allow fine grained lists to be generated.
+ /**
+ * Show the list of Invoices
+ *
+ * @param \App\Filters\InvoiceFilters $filters The filters
+ *
+ * @return \Illuminate\Http\Response
+ *
+ * @OA\Get(
+ * path="/api/v1/invoices",
+ * operationId="getInvoices",
+ * tags={"invoices"},
+ * summary="Gets a list of invoices",
+ * description="Lists invoices, search and filters allow fine grained lists to be generated.
- Query parameters can be added to performed more fine grained filtering of the invoices, these are handled by the InvoiceFilters class which defines the methods available",
- * @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(ref="#/components/parameters/include"),
- * @OA\Response(
- * response=200,
- * description="A list of invoices",
- * @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\JsonContent(ref="#/components/schemas/Invoice"),
- * ),
- * @OA\Response(
- * response=422,
- * description="Validation error",
- * @OA\JsonContent(ref="#/components/schemas/ValidationError"),
+ Query parameters can be added to performed more fine grained filtering of the invoices, these are handled by the InvoiceFilters class which defines the methods available",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Response(
+ * response=200,
+ * description="A list of invoices",
+ * @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\JsonContent(ref="#/components/schemas/Invoice"),
+ * ),
+ * @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 index(InvoiceFilters $filters)
- {
- $invoices = Invoice::filter($filters);
-
- return $this->listResponse($invoices);
- }
+ * ),
+ * @OA\Response(
+ * response="default",
+ * description="Unexpected Error",
+ * @OA\JsonContent(ref="#/components/schemas/Error"),
+ * ),
+ * )
+ *
+ */
+ public function index(InvoiceFilters $filters) {
+ $invoices = Invoice::filter($filters);
- /**
- * Show the form for creating a new resource.
- *
- * @param \App\Http\Requests\Invoice\CreateInvoiceRequest $request The request
- *
- * @return \Illuminate\Http\Response
- *
- *
- * @OA\Get(
- * path="/api/v1/invoices/create",
- * operationId="getInvoicesCreate",
- * tags={"invoices"},
- * summary="Gets a new blank invoice object",
- * description="Returns a blank object with default values",
- * @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(ref="#/components/parameters/include"),
- * @OA\Response(
- * response=200,
- * description="A blank invoice object",
- * @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\JsonContent(ref="#/components/schemas/Invoice"),
- * ),
- * @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 create(CreateInvoiceRequest $request)
- {
- $invoice = InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id);
+ return $this->listResponse($invoices);
+ }
- return $this->itemResponse($invoice);
- }
+ /**
+ * Show the form for creating a new resource.
+ *
+ * @param \App\Http\Requests\Invoice\CreateInvoiceRequest $request The request
+ *
+ * @return \Illuminate\Http\Response
+ *
+ *
+ * @OA\Get(
+ * path="/api/v1/invoices/create",
+ * operationId="getInvoicesCreate",
+ * tags={"invoices"},
+ * summary="Gets a new blank invoice object",
+ * description="Returns a blank object with default values",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Response(
+ * response=200,
+ * description="A blank invoice object",
+ * @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\JsonContent(ref="#/components/schemas/Invoice"),
+ * ),
+ * @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 create(CreateInvoiceRequest $request) {
+ $invoice = InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id);
+ return $this->itemResponse($invoice);
+ }
- /**
- * Store a newly created resource in storage.
- *
- * @param \App\Http\Requests\Invoice\StoreInvoiceRequest $request The request
- *
- * @return \Illuminate\Http\Response
- *
- *
- * @OA\Post(
- * path="/api/v1/invoices",
- * operationId="storeInvoice",
- * tags={"invoices"},
- * summary="Adds a invoice",
- * description="Adds an invoice to the system",
- * @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(ref="#/components/parameters/include"),
- * @OA\Response(
- * response=200,
- * description="Returns the saved invoice object",
- * @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\JsonContent(ref="#/components/schemas/Invoice"),
- * ),
- * @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 store(StoreInvoiceRequest $request)
- {
- $invoice = $this->invoice_repo->save($request->all(), InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id));
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @param \App\Http\Requests\Invoice\StoreInvoiceRequest $request The request
+ *
+ * @return \Illuminate\Http\Response
+ *
+ *
+ * @OA\Post(
+ * path="/api/v1/invoices",
+ * operationId="storeInvoice",
+ * tags={"invoices"},
+ * summary="Adds a invoice",
+ * description="Adds an invoice to the system",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Response(
+ * response=200,
+ * description="Returns the saved invoice object",
+ * @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\JsonContent(ref="#/components/schemas/Invoice"),
+ * ),
+ * @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 store(StoreInvoiceRequest $request) {
+ $invoice = $this->invoice_repo->save($request->all(), InvoiceFactory::create(auth()->user()->company()->id, auth()->user()->id));
- $invoice = StoreInvoice::dispatchNow($invoice, $request->all(), $invoice->company); //todo potentially this may return mixed ie PDF/$invoice... need to revisit when we implement UI
+ $invoice = StoreInvoice::dispatchNow($invoice, $request->all(), $invoice->company);//todo potentially this may return mixed ie PDF/$invoice... need to revisit when we implement UI
- event(new InvoiceWasCreated($invoice, $invoice->company));
+ event(new InvoiceWasCreated($invoice, $invoice->company));
- return $this->itemResponse($invoice);
- }
+ return $this->itemResponse($invoice);
+ }
- /**
- * Display the specified resource.
- *
- * @param \App\Http\Requests\Invoice\ShowInvoiceRequest $request The request
- * @param \App\Models\Invoice $invoice The invoice
- *
- * @return \Illuminate\Http\Response
- *
- *
- * @OA\Get(
- * path="/api/v1/invoices/{id}",
- * operationId="showInvoice",
- * tags={"invoices"},
- * summary="Shows an invoice",
- * description="Displays an invoice by id",
- * @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(ref="#/components/parameters/include"),
- * @OA\Parameter(
- * name="id",
- * in="path",
- * description="The Invoice Hashed ID",
- * example="D2J234DFA",
- * required=true,
- * @OA\Schema(
- * type="string",
- * format="string",
- * ),
- * ),
- * @OA\Response(
- * response=200,
- * description="Returns the invoice object",
- * @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\JsonContent(ref="#/components/schemas/Invoice"),
- * ),
- * @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 show(ShowInvoiceRequest $request, Invoice $invoice)
- {
- return $this->itemResponse($invoice);
- }
+ /**
+ * Display the specified resource.
+ *
+ * @param \App\Http\Requests\Invoice\ShowInvoiceRequest $request The request
+ * @param \App\Models\Invoice $invoice The invoice
+ *
+ * @return \Illuminate\Http\Response
+ *
+ *
+ * @OA\Get(
+ * path="/api/v1/invoices/{id}",
+ * operationId="showInvoice",
+ * tags={"invoices"},
+ * summary="Shows an invoice",
+ * description="Displays an invoice by id",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Parameter(
+ * name="id",
+ * in="path",
+ * description="The Invoice Hashed ID",
+ * example="D2J234DFA",
+ * required=true,
+ * @OA\Schema(
+ * type="string",
+ * format="string",
+ * ),
+ * ),
+ * @OA\Response(
+ * response=200,
+ * description="Returns the invoice object",
+ * @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\JsonContent(ref="#/components/schemas/Invoice"),
+ * ),
+ * @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 show(ShowInvoiceRequest $request, Invoice $invoice) {
+ return $this->itemResponse($invoice);
+ }
- /**
- * Show the form for editing the specified resource.
- *
- * @param \App\Http\Requests\Invoice\EditInvoiceRequest $request The request
- * @param \App\Models\Invoice $invoice The invoice
- *
- * @return \Illuminate\Http\Response
- *
- * @OA\Get(
- * path="/api/v1/invoices/{id}/edit",
- * operationId="editInvoice",
- * tags={"invoices"},
- * summary="Shows an invoice for editting",
- * description="Displays an invoice by id",
- * @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(ref="#/components/parameters/include"),
- * @OA\Parameter(
- * name="id",
- * in="path",
- * description="The Invoice Hashed ID",
- * example="D2J234DFA",
- * required=true,
- * @OA\Schema(
- * type="string",
- * format="string",
- * ),
- * ),
- * @OA\Response(
- * response=200,
- * description="Returns the invoice object",
- * @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\JsonContent(ref="#/components/schemas/Invoice"),
- * ),
- * @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 edit(EditInvoiceRequest $request, Invoice $invoice)
- {
- return $this->itemResponse($invoice);
- }
-
- /**
- * Update the specified resource in storage.
- *
- * @param \App\Http\Requests\Invoice\UpdateInvoiceRequest $request The request
- * @param \App\Models\Invoice $invoice The invoice
- *
- * @return \Illuminate\Http\Response
- *
- *
- * @OA\Put(
- * path="/api/v1/invoices/{id}",
- * operationId="updateInvoice",
- * tags={"invoices"},
- * summary="Updates an invoice",
- * description="Handles the updating of an invoice by id",
- * @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(ref="#/components/parameters/include"),
- * @OA\Parameter(
- * name="id",
- * in="path",
- * description="The Invoice Hashed ID",
- * example="D2J234DFA",
- * required=true,
- * @OA\Schema(
- * type="string",
- * format="string",
- * ),
- * ),
- * @OA\Response(
- * response=200,
- * description="Returns the invoice object",
- * @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\JsonContent(ref="#/components/schemas/Invoice"),
- * ),
- * @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 update(UpdateInvoiceRequest $request, Invoice $invoice)
- {
- if($request->entityIsDeleted($invoice))
- return $request->disallowUpdate();
+ /**
+ * Show the form for editing the specified resource.
+ *
+ * @param \App\Http\Requests\Invoice\EditInvoiceRequest $request The request
+ * @param \App\Models\Invoice $invoice The invoice
+ *
+ * @return \Illuminate\Http\Response
+ *
+ * @OA\Get(
+ * path="/api/v1/invoices/{id}/edit",
+ * operationId="editInvoice",
+ * tags={"invoices"},
+ * summary="Shows an invoice for editting",
+ * description="Displays an invoice by id",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Parameter(
+ * name="id",
+ * in="path",
+ * description="The Invoice Hashed ID",
+ * example="D2J234DFA",
+ * required=true,
+ * @OA\Schema(
+ * type="string",
+ * format="string",
+ * ),
+ * ),
+ * @OA\Response(
+ * response=200,
+ * description="Returns the invoice object",
+ * @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\JsonContent(ref="#/components/schemas/Invoice"),
+ * ),
+ * @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 edit(EditInvoiceRequest $request, Invoice $invoice) {
+ return $this->itemResponse($invoice);
+ }
- $invoice = $this->invoice_repo->save($request->all(), $invoice);
+ /**
+ * Update the specified resource in storage.
+ *
+ * @param \App\Http\Requests\Invoice\UpdateInvoiceRequest $request The request
+ * @param \App\Models\Invoice $invoice The invoice
+ *
+ * @return \Illuminate\Http\Response
+ *
+ *
+ * @OA\Put(
+ * path="/api/v1/invoices/{id}",
+ * operationId="updateInvoice",
+ * tags={"invoices"},
+ * summary="Updates an invoice",
+ * description="Handles the updating of an invoice by id",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Parameter(
+ * name="id",
+ * in="path",
+ * description="The Invoice Hashed ID",
+ * example="D2J234DFA",
+ * required=true,
+ * @OA\Schema(
+ * type="string",
+ * format="string",
+ * ),
+ * ),
+ * @OA\Response(
+ * response=200,
+ * description="Returns the invoice object",
+ * @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\JsonContent(ref="#/components/schemas/Invoice"),
+ * ),
+ * @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 update(UpdateInvoiceRequest $request, Invoice $invoice) {
+ if ($request->entityIsDeleted($invoice)) {
+ return $request->disallowUpdate();
+ }
- event(new InvoiceWasUpdated($invoice, $invoice->company));
+ $invoice = $this->invoice_repo->save($request->all(), $invoice);
- return $this->itemResponse($invoice);
- }
+ event(new InvoiceWasUpdated($invoice, $invoice->company));
- /**
- * Remove the specified resource from storage.
- *
- * @param \App\Http\Requests\Invoice\DestroyInvoiceRequest $request
- * @param \App\Models\Invoice $invoice
- *
- * @return \Illuminate\Http\Response
- *
- * @OA\Delete(
- * path="/api/v1/invoices/{id}",
- * operationId="deleteInvoice",
- * tags={"invoices"},
- * summary="Deletes a invoice",
- * description="Handles the deletion of an invoice by id",
- * @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(ref="#/components/parameters/include"),
- * @OA\Parameter(
- * name="id",
- * in="path",
- * description="The Invoice Hashed ID",
- * example="D2J234DFA",
- * required=true,
- * @OA\Schema(
- * type="string",
- * format="string",
- * ),
- * ),
- * @OA\Response(
- * response=200,
- * description="Returns a HTTP status",
- * @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 destroy(DestroyInvoiceRequest $request, Invoice $invoice)
- {
- $invoice->delete();
+ return $this->itemResponse($invoice);
+ }
- return response()->json([], 200);
- }
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param \App\Http\Requests\Invoice\DestroyInvoiceRequest $request
+ * @param \App\Models\Invoice $invoice
+ *
+ * @return \Illuminate\Http\Response
+ *
+ * @OA\Delete(
+ * path="/api/v1/invoices/{id}",
+ * operationId="deleteInvoice",
+ * tags={"invoices"},
+ * summary="Deletes a invoice",
+ * description="Handles the deletion of an invoice by id",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Parameter(
+ * name="id",
+ * in="path",
+ * description="The Invoice Hashed ID",
+ * example="D2J234DFA",
+ * required=true,
+ * @OA\Schema(
+ * type="string",
+ * format="string",
+ * ),
+ * ),
+ * @OA\Response(
+ * response=200,
+ * description="Returns a HTTP status",
+ * @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 destroy(DestroyInvoiceRequest $request, Invoice $invoice) {
+ $invoice->delete();
- /**
- * Perform bulk actions on the list view
- *
- * @return Collection
- *
- * @OA\Post(
- * path="/api/v1/invoices/bulk",
- * operationId="bulkInvoices",
- * tags={"invoices"},
- * summary="Performs bulk actions on an array of invoices",
- * description="",
- * @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(ref="#/components/parameters/index"),
- * @OA\RequestBody(
- * description="User credentials",
- * required=true,
- * @OA\MediaType(
- * mediaType="application/json",
- * @OA\Schema(
- * type="array",
- * @OA\Items(
- * type="integer",
- * description="Array of hashed IDs to be bulk 'actioned",
- * example="[0,1,2,3]",
- * ),
- * )
- * )
- * ),
- * @OA\Response(
- * response=200,
- * description="The Company User response",
- * @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\JsonContent(ref="#/components/schemas/CompanyUser"),
- * ),
- * @OA\Response(
- * response=422,
- * description="Validation error",
- * @OA\JsonContent(ref="#/components/schemas/ValidationError"),
+ return response()->json([], 200);
+ }
- * ),
- * @OA\Response(
- * response="default",
- * description="Unexpected Error",
- * @OA\JsonContent(ref="#/components/schemas/Error"),
- * ),
- * )
- *
- */
- public function bulk()
- {
- $action = request()->input('action');
-
- $ids = request()->input('ids');
+ /**
+ * Perform bulk actions on the list view
+ *
+ * @return Collection
+ *
+ * @OA\Post(
+ * path="/api/v1/invoices/bulk",
+ * operationId="bulkInvoices",
+ * tags={"invoices"},
+ * summary="Performs bulk actions on an array of invoices",
+ * description="",
+ * @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(ref="#/components/parameters/index"),
+ * @OA\RequestBody(
+ * description="User credentials",
+ * required=true,
+ * @OA\MediaType(
+ * mediaType="application/json",
+ * @OA\Schema(
+ * type="array",
+ * @OA\Items(
+ * type="integer",
+ * description="Array of hashed IDs to be bulk 'actioned",
+ * example="[0,1,2,3]",
+ * ),
+ * )
+ * )
+ * ),
+ * @OA\Response(
+ * response=200,
+ * description="The Company User response",
+ * @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\JsonContent(ref="#/components/schemas/CompanyUser"),
+ * ),
+ * @OA\Response(
+ * response=422,
+ * description="Validation error",
+ * @OA\JsonContent(ref="#/components/schemas/ValidationError"),
- $invoices = Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids));
+ * ),
+ * @OA\Response(
+ * response="default",
+ * description="Unexpected Error",
+ * @OA\JsonContent(ref="#/components/schemas/Error"),
+ * ),
+ * )
+ *
+ */
+ public function bulk() {
+ $action = request()->input('action');
- if (!$invoices) {
- return response()->json(['message'=>'No Invoices Found']);
- }
+ $ids = request()->input('ids');
- $invoices->each(function ($invoice, $key) use ($action) {
+ $invoices = Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids));
-// $this->invoice_repo->{$action}($invoice);
+ if (!$invoices) {
+ return response()->json(['message' => 'No Invoices Found']);
+ }
- if (auth()->user()->can('edit', $invoice)) {
- $this->performAction($invoice, $action, true);
- }
- });
+ $invoices->each(function ($invoice, $key) use ($action) {
- return $this->listResponse(Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids)));
- }
+ // $this->invoice_repo->{$action}($invoice);
- /**
- *
- * @OA\Get(
- * path="/api/v1/invoices/{id}/{action}",
- * operationId="actionInvoice",
- * tags={"invoices"},
- * summary="Performs a custom action on an invoice",
- * description="Performs a custom action on an invoice.
+ if (auth()->user()->can('edit', $invoice)) {
+ $this->performAction($invoice, $action, true);
+ }
+ });
- The current range of actions are as follows
- - clone_to_invoice
- - clone_to_quote
- - history
- - delivery_note
- - mark_paid
- - download
- - archive
- - delete
- - email",
- * @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(ref="#/components/parameters/include"),
- * @OA\Parameter(
- * name="id",
- * in="path",
- * description="The Invoice Hashed ID",
- * example="D2J234DFA",
- * required=true,
- * @OA\Schema(
- * type="string",
- * format="string",
- * ),
- * ),
- * @OA\Parameter(
- * name="action",
- * in="path",
- * description="The action string to be performed",
- * example="clone_to_quote",
- * required=true,
- * @OA\Schema(
- * type="string",
- * format="string",
- * ),
- * ),
- * @OA\Response(
- * response=200,
- * description="Returns the invoice object",
- * @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\JsonContent(ref="#/components/schemas/Invoice"),
- * ),
- * @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 action(ActionInvoiceRequest $request, Invoice $invoice, $action)
- {
- return $this->performAction($invoice, $action);
- }
-
- private function performAction(Invoice $invoice, $action, $bulk = false)
- {
- /*If we are using bulk actions, we don't want to return anything */
- switch ($action) {
- case 'clone_to_invoice':
- $invoice = CloneInvoiceFactory::create($invoice, auth()->user()->id);
- return $this->itemResponse($invoice);
- break;
- case 'clone_to_quote':
- $quote = CloneInvoiceToQuoteFactory::create($invoice, auth()->user()->id);
- // todo build the quote transformer and return response here
- break;
- case 'history':
- # code...
- break;
- case 'delivery_note':
- # code...
- break;
- case 'mark_paid':
- if ($invoice->balance < 0 || $invoice->status_id == Invoice::STATUS_PAID || $invoice->is_deleted === true) {
- return $this->errorResponse(['message' => 'Invoice cannot be marked as paid'], 400);
- }
+ return $this->listResponse(Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids)));
+ }
- $invoice = $invoice->service()->markPaid();
+ /**
+ *
+ * @OA\Get(
+ * path="/api/v1/invoices/{id}/{action}",
+ * operationId="actionInvoice",
+ * tags={"invoices"},
+ * summary="Performs a custom action on an invoice",
+ * description="Performs a custom action on an invoice.
- if (!$bulk) {
- return $this->itemResponse($invoice);
- }
- break;
- case 'mark_sent':
- $invoice->service()->markSent()->save();
+ The current range of actions are as follows
+ - clone_to_invoice
+ - clone_to_quote
+ - history
+ - delivery_note
+ - mark_paid
+ - download
+ - archive
+ - delete
+ - email",
+ * @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(ref="#/components/parameters/include"),
+ * @OA\Parameter(
+ * name="id",
+ * in="path",
+ * description="The Invoice Hashed ID",
+ * example="D2J234DFA",
+ * required=true,
+ * @OA\Schema(
+ * type="string",
+ * format="string",
+ * ),
+ * ),
+ * @OA\Parameter(
+ * name="action",
+ * in="path",
+ * description="The action string to be performed",
+ * example="clone_to_quote",
+ * required=true,
+ * @OA\Schema(
+ * type="string",
+ * format="string",
+ * ),
+ * ),
+ * @OA\Response(
+ * response=200,
+ * description="Returns the invoice object",
+ * @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\JsonContent(ref="#/components/schemas/Invoice"),
+ * ),
+ * @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 action(ActionInvoiceRequest $request, Invoice $invoice, $action) {
+ return $this->performAction($invoice, $action);
+ }
- if (!$bulk) {
- return $this->itemResponse($invoice);
- }
- break;
- case 'download':
- return response()->download(public_path($invoice->pdf_file_path()));
- break;
- case 'archive':
- $this->invoice_repo->archive($invoice);
+ private function performAction(Invoice $invoice, $action, $bulk = false) {
+ /*If we are using bulk actions, we don't want to return anything */
+ switch ($action) {
+ case 'clone_to_invoice':
+ $invoice = CloneInvoiceFactory::create($invoice, auth()->user()->id);
+ return $this->itemResponse($invoice);
+ break;
+ case 'clone_to_quote':
+ $quote = CloneInvoiceToQuoteFactory::create($invoice, auth()->user()->id);
+ // todo build the quote transformer and return response here
+ break;
+ case 'history':
+ # code...
+ break;
+ case 'delivery_note':
+ # code...
+ break;
+ case 'mark_paid':
+ if ($invoice->balance < 0 || $invoice->status_id == Invoice::STATUS_PAID || $invoice->is_deleted === true) {
+ return $this->errorResponse(['message' => 'Invoice cannot be marked as paid'], 400);
+ }
- if (!$bulk) {
- return $this->listResponse($invoice);
- }
- break;
- case 'delete':
- $this->invoice_repo->delete($invoice);
+ $invoice = $invoice->service()->markPaid();
- if (!$bulk) {
- return $this->listResponse($invoice);
- }
- break;
- case 'email':
- EmailInvoice::dispatch($invoice, $invoice->company);
- if (!$bulk) {
- return response()->json(['message'=>'email sent'], 200);
- }
- break;
+ if (!$bulk) {
+ return $this->itemResponse($invoice);
+ }
+ break;
+ case 'mark_sent':
+ $invoice->service()->markSent()->save();
- default:
- return response()->json(['message' => "The requested action `{$action}` is not available."], 400);
- break;
- }
- }
+ if (!$bulk) {
+ return $this->itemResponse($invoice);
+ }
+ break;
+ case 'download':
+ return response()->download(public_path($invoice->pdf_file_path()));
+ break;
+ case 'archive':
+ $this->invoice_repo->archive($invoice);
+
+ if (!$bulk) {
+ return $this->listResponse($invoice);
+ }
+ break;
+ case 'delete':
+ $this->invoice_repo->delete($invoice);
+
+ if (!$bulk) {
+ return $this->listResponse($invoice);
+ }
+ break;
+ case 'email':
+ EmailInvoice::dispatch($invoice, $invoice->company);
+ if (!$bulk) {
+ return response()->json(['message' => 'email sent'], 200);
+ }
+ break;
+
+ default:
+ return response()->json(['message' => "The requested action `{$action}` is not available."], 400);
+ break;
+ }
+ }
+
+ public function downloadPdf($invitation_key) {
+
+ $invitation = InvoiceInvitation::whereKey($invitation_key)->company()->first();
+ $contact = $invitation->contact;
+ $invoice = $invitation->invoice;
+
+ return response()->json($invitation_key);
+ }
}
diff --git a/app/Http/Controllers/SelfUpdateController.php b/app/Http/Controllers/SelfUpdateController.php
index 24bca36f1713..e8cccd980e33 100644
--- a/app/Http/Controllers/SelfUpdateController.php
+++ b/app/Http/Controllers/SelfUpdateController.php
@@ -11,6 +11,9 @@
namespace App\Http\Controllers;
+use Codedge\Updater\UpdaterManager;
+use Illuminate\Foundation\Bus\DispatchesJobs;
+
class SelfUpdateController extends BaseController
{
use DispatchesJobs;
@@ -20,8 +23,10 @@ class SelfUpdateController extends BaseController
}
- public function update()
+ public function update(UpdaterManager $updater)
{
+
+ $updater->update();
}
}
diff --git a/app/Http/Controllers/TemplateController.php b/app/Http/Controllers/TemplateController.php
index f5945a24d537..a979f92e13bd 100644
--- a/app/Http/Controllers/TemplateController.php
+++ b/app/Http/Controllers/TemplateController.php
@@ -103,8 +103,8 @@ class TemplateController extends BaseController
$entity_obj = $class::whereId(request()->input('entity_id'))->company()->first();
}
- $subject = request()->input('subject');
- $body = request()->input('body');
+ $subject = request()->input('subject') ?: '';
+ $body = request()->input('body') ?: '';
$converter = new CommonMarkConverter([
'html_input' => 'strip',
diff --git a/app/Jobs/Invoice/CreateInvoicePdf.php b/app/Jobs/Invoice/CreateInvoicePdf.php
index e178402e4cde..4891f64aacd7 100644
--- a/app/Jobs/Invoice/CreateInvoicePdf.php
+++ b/app/Jobs/Invoice/CreateInvoicePdf.php
@@ -14,11 +14,10 @@ namespace App\Jobs\Invoice;
use App\Designs\Designer;
use App\Designs\Modern;
use App\Libraries\MultiDB;
+use App\Models\ClientContact;
use App\Models\Company;
use App\Models\Invoice;
-use App\Models\Payment;
-use App\Models\PaymentTerm;
-use App\Repositories\InvoiceRepository;
+
use App\Utils\Traits\MakesInvoiceHtml;
use App\Utils\Traits\NumberFormatter;
use Illuminate\Bus\Queueable;
@@ -26,142 +25,78 @@ 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\Log;
+
+use Illuminate\Support\Facades\App;
+
use Illuminate\Support\Facades\Storage;
use Spatie\Browsershot\Browsershot;
-use Symfony\Component\Debug\Exception\FatalThrowableError;
-class CreateInvoicePdf implements ShouldQueue
-{
- use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml;
+class CreateInvoicePdf implements ShouldQueue {
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml;
- public $invoice;
+ public $invoice;
- public $company;
- /**
- * Create a new job instance.
- *
- * @return void
- */
- public function __construct(Invoice $invoice, Company $company)
- {
- $this->invoice = $invoice;
+ public $company;
- $this->company = $company;
- }
+ public $contact;
+ /**
+ * Create a new job instance.
+ *
+ * @return void
+ */
+ public function __construct(Invoice $invoice, Company $company, ClientContact $contact) {
+ $this->invoice = $invoice;
- public function handle()
- {
- MultiDB::setDB($this->company->db);
+ $this->company = $company;
+ $this->contact = $contact;
+ }
- $input_variables = [
- 'client_details' => [
- 'name',
- 'id_number',
- 'vat_number',
- 'address1',
- 'address2',
- 'city_state_postal',
- 'postal_city_state',
- 'country',
- 'email',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
- ],
- 'company_details' => [
- 'company_name',
- 'id_number',
- 'vat_number',
- 'website',
- 'email',
- 'phone',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
- ],
- 'company_address' => [
- 'address1',
- 'address2',
- 'city_state_postal',
- 'postal_city_state',
- 'country',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
- ],
- 'invoice_details' => [
- 'invoice_number',
- 'po_number',
- 'date',
- 'due_date',
- 'balance_due',
- 'invoice_total',
- 'partial_due',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
- ],
- 'table_columns' => [
- 'product_key',
- 'notes',
- 'cost',
- 'quantity',
- 'discount',
- 'tax_name1',
- 'line_total'
- ],
- ];
+ public function handle() {
+ MultiDB::setDB($this->company->db);
+ App::setLocale($this->contact->preferredLocale());
+ $this->invoice->load('client');
+ $path = 'public/'.$this->invoice->client->client_hash.'/invoices/';
+ $file_path = $path.$this->invoice->number.'.pdf';
+ $modern = new Modern();
+ $designer = new Designer($modern, $this->invoice->client->getSetting('invoice_variables'));
+ //get invoice design
+ $html = $this->generateInvoiceHtml($designer->build($this->invoice)->getHtml(), $this->invoice, $this->contact);
- $this->invoice->load('client');
- $path = 'public/' . $this->invoice->client->client_hash . '/invoices/';
- $file_path = $path . $this->invoice->number . '.pdf';
+ //todo - move this to the client creation stage so we don't keep hitting this unnecessarily
+ Storage::makeDirectory($path, 0755);
- $modern = new Modern();
- $designer = new Designer($modern, $input_variables);
+ //\Log::error($html);
+ //create pdf
+ $pdf = $this->makePdf(null, null, $html);
- //get invoice design
- $html = $this->generateInvoiceHtml($designer->build($this->invoice)->getHtml(), $this->invoice);
+ $path = Storage::put($file_path, $pdf);
- //todo - move this to the client creation stage so we don't keep hitting this unnecessarily
- Storage::makeDirectory($path, 0755);
+ return $path;
+ }
-\Log::error($html);
- //create pdf
- $pdf = $this->makePdf(null, null, $html);
-
- $path = Storage::put($file_path, $pdf);
- }
-
- /**
- * Returns a PDF stream
- *
- * @param string $header Header to be included in PDF
- * @param string $footer Footer to be included in PDF
- * @param string $html The HTML object to be converted into PDF
- *
- * @return string The PDF string
- */
- private function makePdf($header, $footer, $html)
- {
- return Browsershot::html($html)
- //->showBrowserHeaderAndFooter()
- //->headerHtml($header)
- //->footerHtml($footer)
- ->deviceScaleFactor(1)
- ->showBackground()
- ->waitUntilNetworkIdle(false)->pdf();
- //->margins(10,10,10,10)
- //->savePdf('test.pdf');
- }
+ /**
+ * Returns a PDF stream
+ *
+ * @param string $header Header to be included in PDF
+ * @param string $footer Footer to be included in PDF
+ * @param string $html The HTML object to be converted into PDF
+ *
+ * @return string The PDF string
+ */
+ private function makePdf($header, $footer, $html) {
+ return Browsershot::html($html)
+ //->showBrowserHeaderAndFooter()
+ //->headerHtml($header)
+ //->footerHtml($footer)
+ ->deviceScaleFactor(1)
+ ->showBackground()
+ ->waitUntilNetworkIdle(true) ->pdf();
+ //->margins(10,10,10,10)
+ //->savePdf('test.pdf');
+ }
}
diff --git a/app/Listeners/Invoice/CreateInvoicePdf.php b/app/Listeners/Invoice/CreateInvoicePdf.php
index af88e7c575a0..6a382c057165 100644
--- a/app/Listeners/Invoice/CreateInvoicePdf.php
+++ b/app/Listeners/Invoice/CreateInvoicePdf.php
@@ -35,6 +35,6 @@ class CreateInvoicePdf implements ShouldQueue
*/
public function handle($event)
{
- PdfCreator::dispatch($event->invoice, $event->company);
+ PdfCreator::dispatch($event->invoice, $event->company, $event->invoice->client->primary_contact()->first());
}
}
diff --git a/app/Models/Client.php b/app/Models/Client.php
index cdec1f1f1767..8dfecab7a40a 100644
--- a/app/Models/Client.php
+++ b/app/Models/Client.php
@@ -32,13 +32,14 @@ use App\Utils\Traits\GeneratesCounter;
use App\Utils\Traits\MakesDates;
use App\Utils\Traits\MakesHash;
use Hashids\Hashids;
+use Illuminate\Contracts\Translation\HasLocalePreference;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\URL;
use Laracasts\Presenter\PresentableTrait;
-class Client extends BaseModel
+class Client extends BaseModel implements HasLocalePreference
{
use PresentableTrait;
use MakesHash;
@@ -424,4 +425,18 @@ class Client extends BaseModel
return $payment_urls;
}
+
+ public function preferredLocale()
+ {
+ $languages = Cache::get('languages');
+
+ return $languages->filter(function ($item) {
+ return $item->id == $this->client->getSetting('language_id');
+ })->first()->locale;
+
+ //$lang = Language::find($this->client->getSetting('language_id'));
+
+ //return $lang->locale;
+ }
+
}
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index ea6536f44518..dce27036dcc9 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -33,7 +33,6 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\File;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Laracasts\Presenter\PresentableTrait;
@@ -349,7 +348,7 @@ class Invoice extends BaseModel
if (!Storage::exists($storage_path)) {
event(new InvoiceWasUpdated($this, $this->company));
- CreateInvoicePdf::dispatch($this, $this->company);
+ CreateInvoicePdf::dispatch($this, $this->company, $this->client->primary_contact()->first());
}
return $public_path;
@@ -360,7 +359,7 @@ class Invoice extends BaseModel
$storage_path = 'storage/' . $this->client->client_hash . '/invoices/'. $this->number . '.pdf';
if (!Storage::exists($storage_path)) {
- CreateInvoicePdf::dispatchNow($this, $this->company);
+ CreateInvoicePdf::dispatchNow($this, $this->company, $this->client->primary_contact()->first());
}
return $storage_path;
diff --git a/app/Models/InvoiceInvitation.php b/app/Models/InvoiceInvitation.php
index beba5722eaa6..c23e35318fa7 100644
--- a/app/Models/InvoiceInvitation.php
+++ b/app/Models/InvoiceInvitation.php
@@ -14,79 +14,70 @@ namespace App\Models;
use App\Models\Invoice;
use App\Utils\Traits\Inviteable;
use App\Utils\Traits\MakesDates;
-use Illuminate\Database\Eloquent\Model;
+
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
-class InvoiceInvitation extends BaseModel
-{
- use MakesDates;
- use SoftDeletes;
- use Inviteable;
+class InvoiceInvitation extends BaseModel {
+ use MakesDates;
+ use SoftDeletes;
+ use Inviteable;
- protected $fillable = [
- 'id',
- 'client_contact_id',
- ];
+ protected $fillable = [
+ //'id',
+ //'client_contact_id',
+ ];
- protected $with = [
- // 'company',
- ];
+ protected $with = [
+ // 'company',
+ ];
- public function entityType()
- {
- return Invoice::class;
- }
+ public function entityType() {
+ return Invoice::class ;
+ }
- /**
- * @return mixed
- */
- public function invoice()
- {
- return $this->belongsTo(Invoice::class)->withTrashed();
- }
+ /**
+ * @return mixed
+ */
+ public function invoice() {
+ return $this->belongsTo(Invoice::class )->withTrashed();
+ }
- /**
- * @return mixed
- */
- public function contact()
- {
- return $this->belongsTo(ClientContact::class, 'client_contact_id', 'id')->withTrashed();
- }
+ /**
+ * @return mixed
+ */
+ public function contact() {
+ return $this->belongsTo(ClientContact::class , 'client_contact_id', 'id')->withTrashed();
+ }
- /**
- * @return mixed
- */
- public function user()
- {
- return $this->belongsTo(User::class)->withTrashed();
- }
+ /**
+ * @return mixed
+ */
+ public function user() {
+ return $this->belongsTo(User::class )->withTrashed();
+ }
- /**
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
- public function company()
- {
- return $this->belongsTo(Company::class);
- }
+ /**
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function company() {
+ return $this->belongsTo(Company::class );
+ }
- public function signatureDiv()
- {
- if (! $this->signature_base64) {
- return false;
- }
+ public function signatureDiv() {
+ if (!$this->signature_base64) {
+ return false;
+ }
- return sprintf('

%s: %s', $this->signature_base64, ctrans('texts.signed'), $this->createClientDate($this->signature_date, $this->contact->client->timezone()->name));
- }
+ return sprintf('

%s: %s', $this->signature_base64, ctrans('texts.signed'), $this->createClientDate($this->signature_date, $this->contact->client->timezone()->name));
+ }
- public function getName()
- {
- return $this->key;
- }
+ public function getName() {
+ return $this->key;
+ }
- public function markViewed()
- {
- $this->viewed_date = Carbon::now();
- $this->save();
- }
+ public function markViewed() {
+ $this->viewed_date = Carbon::now();
+ $this->save();
+ }
}
diff --git a/app/Repositories/InvoiceRepository.php b/app/Repositories/InvoiceRepository.php
index ee7079651a61..867119cc7b02 100644
--- a/app/Repositories/InvoiceRepository.php
+++ b/app/Repositories/InvoiceRepository.php
@@ -11,126 +11,119 @@
namespace App\Repositories;
-use App\Events\Invoice\InvoiceWasCreated;
-use App\Events\Invoice\InvoiceWasUpdated;
use App\Factory\InvoiceInvitationFactory;
-use App\Helpers\Invoice\InvoiceSum;
+
use App\Jobs\Company\UpdateCompanyLedgerWithInvoice;
use App\Jobs\Product\UpdateOrCreateProduct;
-use App\Listeners\Invoice\CreateInvoiceInvitation;
+
use App\Models\ClientContact;
use App\Models\Invoice;
use App\Models\InvoiceInvitation;
use App\Utils\Traits\MakesHash;
-use Illuminate\Http\Request;
-use Illuminate\Support\Carbon;
/**
* InvoiceRepository
*/
-class InvoiceRepository extends BaseRepository
-{
- use MakesHash;
-
- /**
- * Gets the class name.
- *
- * @return string The class name.
- */
- public function getClassName()
- {
- return Invoice::class;
- }
-
- /**
- * Saves the invoices
- *
- * @param array. $data The invoice data
- * @param InvoiceSum|\App\Models\Invoice $invoice The invoice
- *
- * @return Invoice|InvoiceSum|\App\Models\Invoice|null Returns the invoice object
- */
- public function save($data, Invoice $invoice) : ?Invoice
- {
- /* Always carry forward the initial invoice amount this is important for tracking client balance changes later......*/
- $starting_amount = $invoice->amount;
+class InvoiceRepository extends BaseRepository {
+ use MakesHash;
- $invoice->fill($data);
+ /**
+ * Gets the class name.
+ *
+ * @return string The class name.
+ */
+ public function getClassName() {
+ return Invoice::class ;
+ }
- $invoice->save();
+ /**
+ * Saves the invoices
+ *
+ * @param array. $data The invoice data
+ * @param InvoiceSum|\App\Models\Invoice $invoice The invoice
+ *
+ * @return Invoice|InvoiceSum|\App\Models\Invoice|null Returns the invoice object
+ */
+ public function save($data, Invoice $invoice):?Invoice {
- if (isset($data['client_contacts'])) {
- foreach ($data['client_contacts'] as $contact) {
- if ($contact['send_invoice'] == 1) {
- $client_contact = ClientContact::find($this->decodePrimaryKey($contact['id']));
- $client_contact->send_invoice = true;
- $client_contact->save();
- }
- }
- }
+ /* Always carry forward the initial invoice amount this is important for tracking client balance changes later......*/
+ $starting_amount = $invoice->amount;
- if (isset($data['invitations'])) {
- $invitations = collect($data['invitations']);
+ $invoice->fill($data);
- /* Get array of Keyss which have been removed from the invitations array and soft delete each invitation */
- collect($invoice->invitations->pluck('key'))->diff($invitations->pluck('key'))->each(function ($invitation) {
- InvoiceInvitation::destroy($invitation);
- });
+ $invoice->save();
- foreach ($data['invitations'] as $invitation) {
- $inv = false;
+ if (isset($data['client_contacts'])) {
+ foreach ($data['client_contacts'] as $contact) {
+ if ($contact['send_invoice'] == 1) {
+ $client_contact = ClientContact::find($this->decodePrimaryKey($contact['id']));
+ $client_contact->send_invoice = true;
+ $client_contact->save();
+ }
+ }
+ }
- if (array_key_exists('key', $invitation)) {
- $inv = InvoiceInvitation::whereKey($invitation['key'])->first();
- }
+ if (isset($data['invitations'])) {
+ $invitations = collect($data['invitations']);
- if (!$inv) {
+ /* Get array of Keyss which have been removed from the invitations array and soft delete each invitation */
+ collect($invoice->invitations->pluck('key'))->diff($invitations->pluck('key'))->each(function ($invitation) {
+ InvoiceInvitation::destroy($invitation);
+ });
- $new_invitation = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
- $new_invitation->fill($invitation);
- $new_invitation->invoice_id = $invoice->id;
- $new_invitation->client_contact_id = $this->decodePrimaryKey($invitation['client_contact_id']);
- $new_invitation->save();
-
- }
- }
- }
+ foreach ($data['invitations'] as $invitation) {
+ $inv = false;
- /* If no invitations have been created, this is our fail safe to maintain state*/
- if ($invoice->invitations->count() == 0) {
- $invoice->service()->createInvitations();
- }
+ if (array_key_exists('key', $invitation)) {
+ $inv = InvoiceInvitation::whereKey($invitation['key'])->first();
+ }
- $invoice = $invoice->calc()->getInvoice();
-
- $invoice->save();
+ if (!$inv) {
- $finished_amount = $invoice->amount;
+ $new_invitation = InvoiceInvitationFactory::create($invoice->company_id, $invoice->user_id);
+ $new_invitation->fill($invitation);
+ $new_invitation->invoice_id = $invoice->id;
+ $new_invitation->client_contact_id = $this->decodePrimaryKey($invitation['client_contact_id']);
+ $new_invitation->save();
- /**/
- if (($finished_amount != $starting_amount) && ($invoice->status_id != Invoice::STATUS_DRAFT)) {
- UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, ($finished_amount - $starting_amount), $invoice->company);
- }
+ }
+ }
+ }
- $invoice = $invoice->service()->applyNumber()->save();
+ /* If no invitations have been created, this is our fail safe to maintain state*/
+ if ($invoice->invitations->count() == 0) {
+ $invoice->service()->createInvitations();
+ }
- if ($invoice->company->update_products !== false) {
- UpdateOrCreateProduct::dispatch($invoice->line_items, $invoice, $invoice->company);
- }
+ $invoice = $invoice->calc()->getInvoice();
- return $invoice->fresh();
- }
+ $invoice->save();
- /**
- * Mark the invoice as sent.
- *
- * @param \App\Models\Invoice $invoice The invoice
- *
- * @return Invoice|\App\Models\Invoice|null Return the invoice object
- */
- public function markSent(Invoice $invoice) : ?Invoice
- {
- return $invoice->service()->markSent()->save();
- }
+ $finished_amount = $invoice->amount;
+
+ /**/
+ if (($finished_amount != $starting_amount) && ($invoice->status_id != Invoice::STATUS_DRAFT)) {
+ UpdateCompanyLedgerWithInvoice::dispatchNow($invoice, ($finished_amount-$starting_amount), $invoice->company);
+ }
+
+ $invoice = $invoice->service()->applyNumber()->save();
+
+ if ($invoice->company->update_products !== false) {
+ UpdateOrCreateProduct::dispatch($invoice->line_items, $invoice, $invoice->company);
+ }
+
+ return $invoice->fresh();
+ }
+
+ /**
+ * Mark the invoice as sent.
+ *
+ * @param \App\Models\Invoice $invoice The invoice
+ *
+ * @return Invoice|\App\Models\Invoice|null Return the invoice object
+ */
+ public function markSent(Invoice $invoice):?Invoice {
+ return $invoice->service()->markSent()->save();
+ }
}
diff --git a/app/Utils/Traits/MakesInvoiceHtml.php b/app/Utils/Traits/MakesInvoiceHtml.php
index 7b121c3748eb..83ee61b63a49 100644
--- a/app/Utils/Traits/MakesInvoiceHtml.php
+++ b/app/Utils/Traits/MakesInvoiceHtml.php
@@ -11,6 +11,7 @@
namespace App\Utils\Traits;
+use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Blade;
use Symfony\Component\Debug\Exception\FatalThrowableError;
@@ -29,11 +30,20 @@ trait MakesInvoiceHtml
*
* @return string The invoice string in HTML format
*/
- public function generateInvoiceHtml($design, $invoice) :string
+ public function generateInvoiceHtml($design, $invoice, $contact = null) :string
{
- $variables = array_merge($invoice->makeLabels(), $invoice->makeValues());
+ //$variables = array_merge($invoice->makeLabels(), $invoice->makeValues());
+ //$design = str_replace(array_keys($variables), array_values($variables), $design);
+ if(!$contact)
+ $contact = $invoice->client->primary_contact()->first();
- $design = str_replace(array_keys($variables), array_values($variables), $design);
+ App::setLocale($contact->preferredLocale());
+
+ $labels = $invoice->makeLabels();
+ $values = $invoice->makeValues($contact);
+
+ $design = str_replace(array_keys($labels), array_values($labels), $design);
+ $design = str_replace(array_keys($values), array_values($values), $design);
$data['invoice'] = $invoice;
diff --git a/app/Utils/Traits/MakesInvoiceValues.php b/app/Utils/Traits/MakesInvoiceValues.php
index 6f315c691bfc..e81ddcc59e50 100644
--- a/app/Utils/Traits/MakesInvoiceValues.php
+++ b/app/Utils/Traits/MakesInvoiceValues.php
@@ -119,10 +119,10 @@ trait MakesInvoiceValues
'service',
'product_key',
'unit_cost',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
+ // 'custom_value1',
+ // 'custom_value2',
+ // 'custom_value3',
+ // 'custom_value4',
'delivery_note',
'date',
'method',
@@ -130,6 +130,49 @@ trait MakesInvoiceValues
'reference',
'amount',
'amount_paid',
+ 'invoice1',
+ 'invoice2',
+ 'invoice3',
+ 'invoice4',
+ 'surcharge1',
+ 'surcharge2',
+ 'surcharge3',
+ 'surcharge4',
+ 'client1',
+ 'client2',
+ 'client3',
+ 'client4',
+ 'contact1',
+ 'contact2',
+ 'contact3',
+ 'contact4',
+ 'company1',
+ 'company2',
+ 'company3',
+ 'company4',
+ ];
+
+ private static $custom_label_fields = [
+ 'invoice1',
+ 'invoice2',
+ 'invoice3',
+ 'invoice4',
+ 'surcharge1',
+ 'surcharge2',
+ 'surcharge3',
+ 'surcharge4',
+ 'client1',
+ 'client2',
+ 'client3',
+ 'client4',
+ 'contact1',
+ 'contact2',
+ 'contact3',
+ 'contact4',
+ 'company1',
+ 'company2',
+ 'company3',
+ 'company4',
];
/**
@@ -150,8 +193,49 @@ trait MakesInvoiceValues
$data['$'.$label . '_label'] = ctrans('texts.'.$label);
}
- if($custom_fields && property_exists($custom_fields,'invoice_text1'))
- $data['$invoice_text1'] = $custom_fields->invoice_text1;
+ if($custom_fields)
+ {
+
+ foreach($custom_fields as $key => $value)
+ {
+
+ if(strpos($value, '|') !== false)
+ {
+ $value = explode("|", $value);
+ $value = $value[0];
+ }
+
+ $data['$'.$key.'_label'] = $value;
+ }
+
+ }
+
+
+ /*
+ Don't forget pipe | strings for dropdowns needs to be filtered
+ */
+
+ /*
+ invoice1
+ invoice2
+ invoice3
+ invoice4
+ surcharge1
+ surcharge2
+ surcharge3
+ surcharge4
+ client1
+ client2
+ client3
+ client4
+ contact1
+ contact2
+ contact3
+ contact4
+ */
+
+ $arrKeysLength = array_map('strlen', array_keys($data));
+ array_multisort($arrKeysLength, SORT_DESC, $data);
return $data;
}
@@ -179,18 +263,18 @@ trait MakesInvoiceValues
$data['$line_tax_labels'] = $this->lineTaxLabels();
$data['$line_tax_values'] = $this->lineTaxValues();
- $data['$date'] = $this->date;
+ $data['$date'] = $this->date ?: ' ';
$data['$invoice.date'] = &$data['$date'];
- $data['$due_date'] = $this->due_date;
+ $data['$due_date'] = $this->due_date ?: ' ';
$data['$invoice.due_date'] = &$data['$due_date'];
- $data['$number'] = $this->number;
+ $data['$number'] = $this->number ?: ' ';
$data['$invoice.number'] = &$data['$number'];
$data['$invoice_number'] = &$data['$number'];
- $data['$po_number'] = $this->po_number;
+ $data['$po_number'] = $this->po_number ?: ' ';
$data['$invoice.po_number'] = &$data['$po_number'];
- $data['$line_taxes'] = $this->makeLineTaxes();
+ $data['$line_taxes'] = $this->makeLineTaxes() ?: ' ';
$data['$invoice.line_taxes'] = &$data['$line_taxes'];
- $data['$total_taxes'] = $this->makeTotalTaxes();
+ $data['$total_taxes'] = $this->makeTotalTaxes() ?: ' ';
$data['$invoice.total_taxes'] = &$data['$total_taxes'];
// $data['$tax'] = ;
// $data['$item'] = ;
@@ -199,31 +283,31 @@ trait MakesInvoiceValues
// $data['$quantity'] = ;
// $data['$line_total'] = ;
// $data['$paid_to_date'] = ;
- $data['$discount'] = Number::formatMoney($this->calc()->getTotalDiscount(), $this->client);
+ $data['$discount'] = Number::formatMoney($this->calc()->getTotalDiscount(), $this->client) ?: ' ';
$data['$invoice.discount'] = &$data['$discount'];
- $data['$subtotal'] = Number::formatMoney($this->calc()->getSubTotal(), $this->client);
+ $data['$subtotal'] = Number::formatMoney($this->calc()->getSubTotal(), $this->client) ?: ' ';
$data['$invoice.subtotal'] = &$data['$subtotal'];
- $data['$balance_due'] = Number::formatMoney($this->balance, $this->client);
+ $data['$balance_due'] = Number::formatMoney($this->balance, $this->client) ?: ' ';
$data['$invoice.balance_due'] = &$data['$balance_due'];
- $data['$partial_due'] = Number::formatMoney($this->partial, $this->client);
+ $data['$partial_due'] = Number::formatMoney($this->partial, $this->client) ?: ' ';
$data['$invoice.partial_due'] = &$data['$partial_due'];
- $data['$total'] = Number::formatMoney($this->calc()->getTotal(), $this->client);
+ $data['$total'] = Number::formatMoney($this->calc()->getTotal(), $this->client) ?: ' ';
$data['$invoice.total'] = &$data['$total'];
$data['$amount'] = &$data['$total'];
$data['$invoice_total'] = &$data['$total'];
$data['$invoice.amount'] = &$data['$total'];
- $data['$balance'] = Number::formatMoney($this->calc()->getBalance(), $this->client);
+ $data['$balance'] = Number::formatMoney($this->calc()->getBalance(), $this->client) ?: ' ';
$data['$invoice.balance'] = &$data['$balance'];
- $data['$taxes'] = Number::formatMoney($this->calc()->getItemTotalTaxes(), $this->client);
+ $data['$taxes'] = Number::formatMoney($this->calc()->getItemTotalTaxes(), $this->client) ?: ' ';
$data['$invoice.taxes'] = &$data['$taxes'];
- $data['$terms'] = $this->terms;
+ $data['$terms'] = $this->terms ?: ' ';
$data['$invoice.terms'] = &$data['$terms'];
- $data['$invoice.custom_value1'] = $this->custom_value1;
- $data['$invoice.custom_value2'] = $this->custom_value2;
- $data['$invoice.custom_value3'] = $this->custom_value3;
- $data['$invoice.custom_value4'] = $this->custom_value4;
- $data['$invoice.public_notes'] = $this->public_notes;
+ $data['$invoice1'] = $this->custom_value1 ?: ' ';
+ $data['$invoice2'] = $this->custom_value2 ?: ' ';
+ $data['$invoice3'] = $this->custom_value3 ?: ' ';
+ $data['$invoice4'] = $this->custom_value4 ?: ' ';
+ $data['$invoice.public_notes'] = $this->public_notes ?: ' ';
// $data['$your_invoice'] = ;
// $data['$quote'] = ;
// $data['$your_quote'] = ;
@@ -238,74 +322,74 @@ trait MakesInvoiceValues
// $data['$invoice_to'] = ;
// $data['$quote_to'] = ;
// $data['$details'] = ;
- $data['$invoice_no'] = $this->number;
+ $data['$invoice_no'] = $this->number ?: ' ';
$data['$invoice.invoice_no'] = &$data['$invoice_no'];
// $data['$quote_no'] = ;
// $data['$valid_until'] = ;
- $data['$client_name'] = $this->present()->clientName();
+ $data['$client1'] = $this->client->custom_value1 ?: ' ';
+ $data['$client2'] = $this->client->custom_value2 ?: ' ';
+ $data['$client3'] = $this->client->custom_value3 ?: ' ';
+ $data['$client4'] = $this->client->custom_value4 ?: ' ';
+ $data['$client_name'] = $this->present()->clientName() ?: ' ';
$data['$client.name'] = &$data['$client_name'];
- $data['$client_address'] = $this->present()->address();
- $data['$client.address'] = &$data['$client_address'];
- $data['$address1'] = $this->client->address1;
- $data['$client.address1'] = &$data['$address1'];
- $data['$address2'] = $this->client->address2;
+ $data['$address1'] = $this->client->address1 ?: ' ';
+ $data['$address2'] = $this->client->address2 ?: ' ';
$data['$client.address2'] = &$data['$address2'];
- $data['$id_number'] = $this->client->id_number;
+ $data['$client.address1'] = &$data['$address1'];
+ $data['$client.address'] = &$data['$client_address'];
+ $data['$client_address'] = $this->present()->address() ?: ' ';
+ $data['$id_number'] = $this->client->id_number ?: ' ';
$data['$client.id_number'] = &$data['$id_number'];
- $data['$vat_number'] = $this->client->vat_number;
+ $data['$vat_number'] = $this->client->vat_number ?: ' ';
$data['$client.vat_number'] = &$data['$vat_number'];
- $data['$website'] = $this->client->present()->website();
+ $data['$website'] = $this->client->present()->website() ?: ' ';
$data['$client.website'] = &$data['$website'];
- $data['$phone'] = $this->client->present()->phone();
+ $data['$phone'] = $this->client->present()->phone() ?: ' ';
$data['$client.phone'] = &$data['$phone'];
- $data['$city_state_postal'] = $this->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, false);
+ $data['$city_state_postal'] = $this->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, false) ?: ' ';
$data['$client.city_state_postal'] = &$data['$city_state_postal'];
- $data['$postal_city_state'] = $this->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, true);
+ $data['$postal_city_state'] = $this->present()->cityStateZip($this->client->city, $this->client->state, $this->client->postal_code, true) ?: ' ';
$data['$client.postal_city_state'] = &$data['$postal_city_state'];
- $data['$country'] = isset($this->client->country->name) ?: 'No Country Set';
+ $data['$country'] = isset($this->client->country->name) ? $this->client->country->name : 'No Country Set';
$data['$client.country'] = &$data['$country'];
- $data['$email'] = isset($this->client->primary_contact()->first()->email) ?: 'no contact email on record';
+ $data['$email'] = isset($this->client->primary_contact()->first()->email) ? $this->client->primary_contact()->first()->email : 'no contact email on record';
$data['$client.email'] = &$data['$email'];
- $data['$client.custom_value1'] = $this->client->custom_value1;
- $data['$client.custom_value2'] = $this->client->custom_value2;
- $data['$client.custom_value3'] = $this->client->custom_value3;
- $data['$client.custom_value4'] = $this->client->custom_value4;
if(!$contact)
$contact = $this->client->primary_contact()->first();
$data['$contact_name'] = isset($contact) ? $contact->present()->name() : 'no contact name on record';
$data['$contact.name'] = &$data['$contact_name'];
- $data['$contact.custom_value1'] = isset($contact) ? $contact->custom_value1 : '';
- $data['$contact.custom_value2'] = isset($contact) ? $contact->custom_value2 : '';
- $data['$contact.custom_value3'] = isset($contact) ? $contact->custom_value3 : '';
- $data['$contact.custom_value4'] = isset($contact) ? $contact->custom_value4 : '';
+ $data['$contact1'] = isset($contact) ? $contact->custom_value1 : ' ';
+ $data['$contact2'] = isset($contact) ? $contact->custom_value2 : ' ';
+ $data['$contact3'] = isset($contact) ? $contact->custom_value3 : ' ';
+ $data['$contact4'] = isset($contact) ? $contact->custom_value4 : ' ';
- $data['$company.city_state_postal'] = $this->company->present()->cityStateZip($settings->city, $settings->state, $settings->postal_code, false);
- $data['$company.postal_city_state'] = $this->company->present()->cityStateZip($settings->city, $settings->state, $settings->postal_code, true);
- $data['$company.name'] = $this->company->present()->name();
+ $data['$company.city_state_postal'] = $this->company->present()->cityStateZip($settings->city, $settings->state, $settings->postal_code, false) ?: ' ';
+ $data['$company.postal_city_state'] = $this->company->present()->cityStateZip($settings->city, $settings->state, $settings->postal_code, true) ?: ' ';
+ $data['$company.name'] = $this->company->present()->name() ?: ' ';
$data['$company.company_name'] = &$data['$company.name'];
- $data['$company.address1'] = $settings->address1;
- $data['$company.address2'] = $settings->address2;
- $data['$company.city'] = $settings->city;
- $data['$company.state'] = $settings->state;
- $data['$company.postal_code'] = $settings->postal_code;
- $data['$company.country'] = Country::find($settings->country_id)->first()->name;
- $data['$company.phone'] = $settings->phone;
- $data['$company.email'] = $settings->email;
- $data['$company.vat_number'] = $settings->vat_number;
- $data['$company.id_number'] = $settings->id_number;
- $data['$company.website'] = $settings->website;
- $data['$company.address'] = $this->company->present()->address($settings);
+ $data['$company.address1'] = $settings->address1 ?: ' ';
+ $data['$company.address2'] = $settings->address2 ?: ' ';
+ $data['$company.city'] = $settings->city ?: ' ';
+ $data['$company.state'] = $settings->state ?: ' ';
+ $data['$company.postal_code'] = $settings->postal_code ?: ' ';
+ $data['$company.country'] = Country::find($settings->country_id)->first()->name ?: ' ';
+ $data['$company.phone'] = $settings->phone ?: ' ';
+ $data['$company.email'] = $settings->email ?: ' ';
+ $data['$company.vat_number'] = $settings->vat_number ?: ' ';
+ $data['$company.id_number'] = $settings->id_number ?: ' ';
+ $data['$company.website'] = $settings->website ?: ' ';
+ $data['$company.address'] = $this->company->present()->address($settings) ?: ' ';
$logo = $this->company->present()->logo($settings);
- $data['$company.logo'] = "

";
+ $data['$company.logo'] = "

" ?: ' ';
$data['$company_logo'] = &$data['$company.logo'];
- $data['$company.custom_value1'] = $this->company->custom_value1;
- $data['$company.custom_value2'] = $this->company->custom_value2;
- $data['$company.custom_value3'] = $this->company->custom_value3;
- $data['$company.custom_value4'] = $this->company->custom_value4;
+ $data['$company1'] = $settings->custom_value1 ?: ' ';
+ $data['$company2'] = $settings->custom_value2 ?: ' ';
+ $data['$company3'] = $settings->custom_value3 ?: ' ';
+ $data['$company4'] = $settings->custom_value4 ?: ' ';
//$data['$blank'] = ;
//$data['$surcharge'] = ;
/*
@@ -340,6 +424,12 @@ trait MakesInvoiceValues
$data['$amount'] = ;
$data['$amount_paid'] =;
*/
+
+ $arrKeysLength = array_map('strlen', array_keys($data));
+ array_multisort($arrKeysLength, SORT_DESC, $data);
+ // \Log::error('woop');
+ //\Log::error(print_r($data,1));
+
return $data;
}
@@ -499,6 +589,26 @@ trait MakesInvoiceValues
$item->discount = $item->discount . '%';
}
}
+ else
+ $item->discount = '';
+
+ if(isset($item->tax_rate1) && $item->tax_rate1 > 0)
+ $item->tax_rate1 = $item->tax_rate1."%";
+
+ if(isset($item->tax_rate2) && $item->tax_rate2 > 0)
+ $item->tax_rate2 = $item->tax_rate2."%";
+
+ if(isset($item->tax_rate2) && $item->tax_rate2 > 0)
+ $item->tax_rate2 = $item->tax_rate2."%";
+
+ if(isset($item->tax_rate1) && $item->tax_rate1 == 0)
+ $item->tax_rate1 = '';
+
+ if(isset($item->tax_rate2) && $item->tax_rate2 == 0)
+ $item->tax_rate2 = '';
+
+ if(isset($item->tax_rate2) && $item->tax_rate2 == 0)
+ $item->tax_rate2 = '';
}
diff --git a/config/self-update.php b/config/self-update.php
index 05571ac6a20f..04d04c54b62f 100644
--- a/config/self-update.php
+++ b/config/self-update.php
@@ -2,124 +2,126 @@
return [
- /*
- |--------------------------------------------------------------------------
- | Default source repository type
- |--------------------------------------------------------------------------
- |
- | The default source repository type you want to pull your updates from.
- |
- */
+ /*
+ |--------------------------------------------------------------------------
+ | Default source repository type
+ |--------------------------------------------------------------------------
+ |
+ | The default source repository type you want to pull your updates from.
+ |
+ */
- 'default' => env('SELF_UPDATER_SOURCE', 'github'),
+ 'default' => env('SELF_UPDATER_SOURCE', 'github'),
- /*
- |--------------------------------------------------------------------------
- | Version installed
- |--------------------------------------------------------------------------
- |
- | Set this to the version of your software installed on your system.
- |
- */
+ /*
+ |--------------------------------------------------------------------------
+ | Version installed
+ |--------------------------------------------------------------------------
+ |
+ | Set this to the version of your software installed on your system.
+ |
+ */
- 'version_installed' => env('SELF_UPDATER_VERSION_INSTALLED', ''),
+ 'version_installed' => env('SELF_UPDATER_VERSION_INSTALLED', ''),
- /*
- |--------------------------------------------------------------------------
- | Repository types
- |--------------------------------------------------------------------------
- |
- | A repository can be of different types, which can be specified here.
- | Current options:
- | - github
- | - http
- |
- */
+ /*
+ |--------------------------------------------------------------------------
+ | Repository types
+ |--------------------------------------------------------------------------
+ |
+ | A repository can be of different types, which can be specified here.
+ | Current options:
+ | - github
+ | - http
+ |
+ */
- 'repository_types' => [
- 'github' => [
- 'type' => 'github',
- 'repository_vendor' => env('SELF_UPDATER_REPO_VENDOR', ''),
- 'repository_name' => env('SELF_UPDATER_REPO_NAME', ''),
- 'repository_url' => '',
- 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'),
- 'private_access_token' => env('SELF_UPDATER_GITHUB_PRIVATE_ACCESS_TOKEN', ''),
- ],
- 'http' => [
- 'type' => 'http',
- 'repository_url' => env('SELF_UPDATER_REPO_URL', ''),
- 'pkg_filename_format' => env('SELF_UPDATER_PKG_FILENAME_FORMAT', 'v_VERSION_'),
- 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'),
- 'private_access_token' => env('SELF_UPDATER_HTTP_PRIVATE_ACCESS_TOKEN', ''),
- ],
- ],
+ 'repository_types' => [
+ 'github' => [
+ 'type' => 'github',
+ 'repository_vendor' => env('SELF_UPDATER_REPO_VENDOR', ''),
+ 'repository_name' => env('SELF_UPDATER_REPO_NAME', ''),
+ 'repository_url' => '',
+ 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'),
+ 'private_access_token' => env('SELF_UPDATER_GITHUB_PRIVATE_ACCESS_TOKEN', ''),
+ 'use_branch' => env('SELF_UPDATER_BRANCH_NAME', 'v2'),
- /*
- |--------------------------------------------------------------------------
- | Exclude folders from update
- |--------------------------------------------------------------------------
- |
- | Specifiy folders which should not be updated and will be skipped during the
- | update process.
- |
- | Here's already a list of good examples to skip. You may want to keep those.
- |
- */
+ ],
+ 'http' => [
+ 'type' => 'http',
+ 'repository_url' => env('SELF_UPDATER_REPO_URL', ''),
+ 'pkg_filename_format' => env('SELF_UPDATER_PKG_FILENAME_FORMAT', 'v_VERSION_'),
+ 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'),
+ 'private_access_token' => env('SELF_UPDATER_HTTP_PRIVATE_ACCESS_TOKEN', ''),
+ ],
+ ],
- 'exclude_folders' => [
- 'node_modules',
- 'bootstrap/cache',
- 'bower',
- 'storage/app',
- 'storage/framework',
- 'storage/logs',
- 'storage/self-update',
- 'vendor',
- ],
+ /*
+ |--------------------------------------------------------------------------
+ | Exclude folders from update
+ |--------------------------------------------------------------------------
+ |
+ | Specifiy folders which should not be updated and will be skipped during the
+ | update process.
+ |
+ | Here's already a list of good examples to skip. You may want to keep those.
+ |
+ */
- /*
- |--------------------------------------------------------------------------
- | Event Logging
- |--------------------------------------------------------------------------
- |
- | Configure if fired events should be logged
- |
- */
+ 'exclude_folders' => [
+ 'node_modules',
+ 'bootstrap/cache',
+ 'bower',
+ 'storage/app',
+ 'storage/framework',
+ 'storage/logs',
+ 'storage/self-update',
+ 'vendor',
+ ],
- 'log_events' => env('SELF_UPDATER_LOG_EVENTS', false),
+ /*
+ |--------------------------------------------------------------------------
+ | Event Logging
+ |--------------------------------------------------------------------------
+ |
+ | Configure if fired events should be logged
+ |
+ */
- /*
- |--------------------------------------------------------------------------
- | Mail To Settings
- |--------------------------------------------------------------------------
- |
- | Configure if fired events should be logged
- |
- */
+ 'log_events' => env('SELF_UPDATER_LOG_EVENTS', false),
- 'mail_to' => [
- 'address' => env('SELF_UPDATER_MAILTO_ADDRESS', ''),
- 'name' => env('SELF_UPDATER_MAILTO_NAME', ''),
- 'subject_update_available' => env('SELF_UPDATER_MAILTO_UPDATE_AVAILABLE_SUBJECT', 'Update available'),
- 'subject_update_succeeded' => env('SELF_UPDATER_MAILTO_UPDATE_SUCCEEDED_SUBJECT', 'Update succeeded'),
- ],
+ /*
+ |--------------------------------------------------------------------------
+ | Mail To Settings
+ |--------------------------------------------------------------------------
+ |
+ | Configure if fired events should be logged
+ |
+ */
- /*
- |---------------------------------------------------------------------------
- | Register custom artisan commands
- |---------------------------------------------------------------------------
- */
+ 'mail_to' => [
+ 'address' => env('SELF_UPDATER_MAILTO_ADDRESS', ''),
+ 'name' => env('SELF_UPDATER_MAILTO_NAME', ''),
+ 'subject_update_available' => env('SELF_UPDATER_MAILTO_UPDATE_AVAILABLE_SUBJECT', 'Update available'),
+ 'subject_update_succeeded' => env('SELF_UPDATER_MAILTO_UPDATE_SUCCEEDED_SUBJECT', 'Update succeeded'),
+ ],
- 'artisan_commands' => [
- 'pre_update' => [
- //'command:signature' => [
- // 'class' => Command class
- // 'params' => []
- //]
- ],
- 'post_update' => [
+ /*
+ |---------------------------------------------------------------------------
+ | Register custom artisan commands
+ |---------------------------------------------------------------------------
+ */
- ],
- ],
+ 'artisan_commands' => [
+ 'pre_update' => [
+ //'command:signature' => [
+ // 'class' => Command class
+ // 'params' => []
+ //]
+ ],
+ 'post_update' => [
+
+ ],
+ ],
];
diff --git a/database/factories/CompanyFactory.php b/database/factories/CompanyFactory.php
index f5ddfb9e3a80..f96054f399f3 100644
--- a/database/factories/CompanyFactory.php
+++ b/database/factories/CompanyFactory.php
@@ -10,7 +10,7 @@ $factory->define(App\Models\Company::class, function (Faker $faker) {
'ip' => $faker->ipv4,
'db' => config('database.default'),
'settings' => CompanySettings::defaults(),
- 'custom_fields' => (object) ['custom1' => '1', 'custom2' => '2', 'custom3'=>'3'],
+ 'custom_fields' => (object) ['invoice1' => '1', 'invoice2' => '2', 'client1'=>'3'],
// 'address1' => $faker->secondaryAddress,
// 'address2' => $faker->address,
diff --git a/routes/api.php b/routes/api.php
index f9eab0ad1423..f2e9cd74481c 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -1,7 +1,5 @@
get('/user', function (Request $request) {
- return $request->user();
+return $request->user();
});
-*/
+ */
-Route::group(['middleware' => ['api_secret_check']], function () {
+Route::group(['middleware' => ['api_secret_check']],
+ function () {
- Route::post('api/v1/signup', 'AccountController@store')->name('signup.submit');
- Route::post('api/v1/oauth_login', 'Auth\LoginController@oauthApiLogin');
+ Route::post('api/v1/signup', 'AccountController@store')->name('signup.submit');
+ Route::post('api/v1/oauth_login', 'Auth\LoginController@oauthApiLogin');
-});
+ });
Route::group(['api_secret_check', 'email_db'], function () {
- Route::post('api/v1/login', 'Auth\LoginController@apiLogin')->name('login.submit');
- Route::post('api/v1/reset_password', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.reset');
+ Route::post('api/v1/login', 'Auth\LoginController@apiLogin')->name('login.submit');
+ Route::post('api/v1/reset_password', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.reset');
-});
+ });
Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
- Route::resource('activities', 'ActivityController'); // name = (clients. index / create / show / update / destroy / edit
+ Route::resource('activities', 'ActivityController');// name = (clients. index / create / show / update / destroy / edit
- Route::resource('clients', 'ClientController'); // name = (clients. index / create / show / update / destroy / edit
+ Route::resource('clients', 'ClientController');// name = (clients. index / create / show / update / destroy / edit
- Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk');
+ Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk');
- Route::resource('invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit
-
- Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action');
-
- Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk');
+ Route::resource('invoices', 'InvoiceController');// name = (invoices. index / create / show / update / destroy / edit
- Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
+ Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action');
- Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action');
+ Route::get('invoice/{invitation_key}/download', 'InvoiceController@downloadPdf')->name('invoices.downloadPdf');
- Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
+ Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk');
- Route::resource('products', 'ProductController'); // name = (products. index / create / show / update / destroy / edit
+ Route::resource('credits', 'CreditController');// name = (credits. index / create / show / update / destroy / edit
- Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk');
+ Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action');
- Route::resource('quotes', 'QuoteController'); // name = (quotes. index / create / show / update / destroy / edit
+ Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
- Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk');
+ Route::resource('products', 'ProductController');// name = (products. index / create / show / update / destroy / edit
- Route::resource('recurring_invoices', 'RecurringInvoiceController'); // name = (recurring_invoices. index / create / show / update / destroy / edit
+ Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk');
- Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk');
+ Route::resource('quotes', 'QuoteController');// name = (quotes. index / create / show / update / destroy / edit
- Route::resource('recurring_quotes', 'RecurringQuoteController'); // name = (recurring_invoices. index / create / show / update / destroy / edit
+ Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk');
- Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
+ Route::resource('recurring_invoices', 'RecurringInvoiceController');// name = (recurring_invoices. index / create / show / update / destroy / edit
- Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit
+ Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk');
- Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
+ Route::resource('recurring_quotes', 'RecurringQuoteController');// name = (recurring_invoices. index / create / show / update / destroy / edit
- Route::resource('vendors', 'VendorController'); // name = (vendors. index / create / show / update / destroy / edit
+ Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
- Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk');
+ Route::resource('expenses', 'ExpenseController');// name = (expenses. index / create / show / update / destroy / edit
- Route::resource('client_statement', 'ClientStatementController@statement'); // name = (client_statement. index / create / show / update / destroy / edit
+ Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
- Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit
+ Route::resource('vendors', 'VendorController');// name = (vendors. index / create / show / update / destroy / edit
- Route::post('payments/refund', 'PaymentController@refund')->name('payments.refund');
+ Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk');
- Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk');
+ Route::resource('client_statement', 'ClientStatementController@statement');// name = (client_statement. index / create / show / update / destroy / edit
- Route::post('migrate', 'Migration\MigrateController@index')->name('migrate.start');
+ Route::resource('payments', 'PaymentController');// name = (payments. index / create / show / update / destroy / edit
-// Route::resource('users', 'UserController')->middleware('password_protected'); // name = (users. index / create / show / update / destroy / edit
- Route::get('users', 'UserController@index');
- Route::put('users/{user}', 'UserController@update')->middleware('password_protected');
- Route::post('users', 'UserController@store')->middleware('password_protected');
- Route::post('users/{user}/attach_to_company', 'UserController@attach')->middleware('password_protected');
- Route::delete('users/{user}/detach_from_company', 'UserController@detach')->middleware('password_protected');
+ Route::post('payments/refund', 'PaymentController@refund')->name('payments.refund');
+
+ Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk');
+
+ Route::post('migrate', 'Migration\MigrateController@index')->name('migrate.start');
+
+ // Route::resource('users', 'UserController')->middleware('password_protected'); // name = (users. index / create / show / update / destroy / edit
+ Route::get('users', 'UserController@index');
+ Route::put('users/{user}', 'UserController@update')->middleware('password_protected');
+ Route::post('users', 'UserController@store')->middleware('password_protected');
+ Route::post('users/{user}/attach_to_company', 'UserController@attach')->middleware('password_protected');
+ Route::delete('users/{user}/detach_from_company', 'UserController@detach')->middleware('password_protected');
+
+ Route::post('users/bulk', 'UserController@bulk')->name('users.bulk')->middleware('password_protected');
+
+ Route::post('migration/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected');
+ Route::post('migration/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected');
+ Route::post('migration/start', 'MigrationController@startMigration')->middleware('password_protected');
+
+ Route::resource('companies', 'CompanyController');// name = (companies. index / create / show / update / destroy / edit
+
+ Route::resource('company_gateways', 'CompanyGatewayController');
+
+ Route::resource('group_settings', 'GroupSettingController');
+
+ Route::resource('tax_rates', 'TaxRateController');// name = (tasks. index / create / show / update / destroy / edit
+
+ Route::post('refresh', 'Auth\LoginController@refresh');
+
+ Route::post('templates', 'TemplateController@show')->name('templates.show');
+
+ Route::post('self-update', 'SelfUpdateController@update');
+
+ /*
+ Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit
+
+ Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
- Route::post('users/bulk', 'UserController@bulk')->name('users.bulk')->middleware('password_protected');
+ Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
- Route::post('migration/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected');
- Route::post('migration/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected');
- Route::post('migration/start', 'MigrationController@startMigration')->middleware('password_protected');
-
- Route::resource('companies', 'CompanyController'); // name = (companies. index / create / show / update / destroy / edit
-
- Route::resource('company_gateways', 'CompanyGatewayController');
-
- Route::resource('group_settings', 'GroupSettingController');
-
- Route::resource('tax_rates', 'TaxRateController'); // name = (tasks. index / create / show / update / destroy / edit
-
- Route::post('refresh', 'Auth\LoginController@refresh');
-
- Route::post('templates', 'TemplateController@show')->name('templates.show');
-
- /*
- Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit
-
- Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
-
-
- Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
-
- Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
+ Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
- Route::get('settings', 'SettingsController@index')->name('user.settings');
- */
- Route::post('support/messages/send', 'Support\Messages\SendingController');
-});
+ Route::get('settings', 'SettingsController@index')->name('user.settings');
+ */
+ Route::post('support/messages/send', 'Support\Messages\SendingController');
+ });
Route::fallback('BaseController@notFound');
diff --git a/tests/Feature/PaymentTest.php b/tests/Feature/PaymentTest.php
index f68e9362a78a..65b99e877727 100644
--- a/tests/Feature/PaymentTest.php
+++ b/tests/Feature/PaymentTest.php
@@ -281,6 +281,14 @@ class PaymentTest extends TestCase
$client = ClientFactory::create($this->company->id, $this->user->id);
$client->save();
+ factory(\App\Models\ClientContact::class)->create([
+ 'user_id' => $this->user->id,
+ 'client_id' => $client->id,
+ 'company_id' =>$this->company->id,
+ 'is_primary' => true,
+ ]);
+
+
$this->invoice = InvoiceFactory::create($this->company->id,$this->user->id);//stub the company and user_id
$this->invoice->client_id = $client->id;
diff --git a/tests/Integration/InvoiceDesignTest.php b/tests/Integration/InvoiceDesignTest.php
index 9c1a83c3e880..41d9a4e2cec3 100644
--- a/tests/Integration/InvoiceDesignTest.php
+++ b/tests/Integration/InvoiceDesignTest.php
@@ -39,10 +39,14 @@ class InvoiceDesignTest extends TestCase
'postal_city_state',
'country',
'email',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
+ 'client1',
+ 'client2',
+ 'client3',
+ 'client4',
+ 'contact1',
+ 'contact2',
+ 'contact3',
+ 'contact4',
],
'company_details' => [
'company_name',
@@ -51,10 +55,10 @@ class InvoiceDesignTest extends TestCase
'website',
'email',
'phone',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
+ 'company1',
+ 'company2',
+ 'company3',
+ 'company4',
],
'company_address' => [
'address1',
@@ -62,10 +66,10 @@ class InvoiceDesignTest extends TestCase
'city_state_postal',
'postal_city_state',
'country',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
+ 'company1',
+ 'company2',
+ 'company3',
+ 'company4',
],
'invoice_details' => [
'invoice_number',
@@ -75,10 +79,14 @@ class InvoiceDesignTest extends TestCase
'balance_due',
'invoice_total',
'partial_due',
- 'custom_value1',
- 'custom_value2',
- 'custom_value3',
- 'custom_value4',
+ 'invoice1',
+ 'invoice2',
+ 'invoice3',
+ 'invoice4',
+ 'surcharge1',
+ 'surcharge2',
+ 'surcharge3',
+ 'surcharge4',
],
'table_columns' => [
'product_key',
@@ -99,7 +107,7 @@ class InvoiceDesignTest extends TestCase
//\Log::error($html);
- CreateInvoicePdf::dispatchNow($this->invoice, $this->invoice->company);
+ CreateInvoicePdf::dispatchNow($this->invoice, $this->invoice->company, $this->invoice->client->primary_contact()->first());
}