mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Add document list view
This commit is contained in:
parent
cf0e086d2a
commit
b4bf6cc760
92
app/Filters/DocumentFilters.php
Normal file
92
app/Filters/DocumentFilters.php
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DocumentFilters.
|
||||||
|
*/
|
||||||
|
class DocumentFilters extends QueryFilters
|
||||||
|
{
|
||||||
|
public function type_id(int $type_id) :Builder
|
||||||
|
{
|
||||||
|
return $this->builder->where('type_id', $type_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function category_id(int $category_id) :Builder
|
||||||
|
{
|
||||||
|
return $this->builder->where('category_id', $category_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function event_id(int $event_id) :Builder
|
||||||
|
{
|
||||||
|
return $this->builder->where('event_id', $event_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function client_id(int $client_id) :Builder
|
||||||
|
{
|
||||||
|
return $this->builder->where('client_id', $client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter based on search text.
|
||||||
|
*
|
||||||
|
* @param string query filter
|
||||||
|
* @return Builder
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public function filter(string $filter = '') : Builder
|
||||||
|
{
|
||||||
|
if (strlen($filter) == 0) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the list based on $sort.
|
||||||
|
*
|
||||||
|
* @param string sort formatted as column|asc
|
||||||
|
* @return Builder
|
||||||
|
*/
|
||||||
|
public function sort(string $sort) : Builder
|
||||||
|
{
|
||||||
|
$sort_col = explode('|', $sort);
|
||||||
|
|
||||||
|
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base query.
|
||||||
|
*
|
||||||
|
* @param int company_id
|
||||||
|
* @param User $user
|
||||||
|
* @return Builder
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public function baseQuery(int $company_id, User $user) : Builder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the query by the users company ID.
|
||||||
|
*
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
|
public function entityFilter()
|
||||||
|
{
|
||||||
|
return $this->builder->company();
|
||||||
|
}
|
||||||
|
}
|
@ -65,7 +65,6 @@ class BaseController extends Controller
|
|||||||
'company.task_statuses',
|
'company.task_statuses',
|
||||||
'company.expense_categories',
|
'company.expense_categories',
|
||||||
'company.documents',
|
'company.documents',
|
||||||
//'company.users',
|
|
||||||
'company.users.company_user',
|
'company.users.company_user',
|
||||||
'company.clients.contacts.company',
|
'company.clients.contacts.company',
|
||||||
'company.clients.gateway_tokens',
|
'company.clients.gateway_tokens',
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Filters\DocumentFilters;
|
||||||
use App\Http\Requests\Document\DestroyDocumentRequest;
|
use App\Http\Requests\Document\DestroyDocumentRequest;
|
||||||
use App\Http\Requests\Document\ShowDocumentRequest;
|
use App\Http\Requests\Document\ShowDocumentRequest;
|
||||||
use App\Http\Requests\Document\StoreDocumentRequest;
|
use App\Http\Requests\Document\StoreDocumentRequest;
|
||||||
@ -26,10 +27,6 @@ class DocumentController extends BaseController
|
|||||||
*/
|
*/
|
||||||
protected $document_repo;
|
protected $document_repo;
|
||||||
|
|
||||||
/**
|
|
||||||
* DocumentController constructor.
|
|
||||||
* @param DocumentRepository $document_repo
|
|
||||||
*/
|
|
||||||
public function __construct(DocumentRepository $document_repo)
|
public function __construct(DocumentRepository $document_repo)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
@ -40,13 +37,46 @@ class DocumentController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* @OA\Get(
|
||||||
*
|
* path="/api/v1/documents",
|
||||||
* @return void
|
* operationId="getDocuments",
|
||||||
|
* tags={"documents"},
|
||||||
|
* summary="Gets a list of documents",
|
||||||
|
* description="Lists documents, search and filters allow fine grained lists to be generated.
|
||||||
|
|
||||||
|
Query parameters can be added to performed more fine grained filtering of the documents, these are handled by the DocumentsFilters 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\Parameter(ref="#/components/parameters/index"),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="A list of documents",
|
||||||
|
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Document"),
|
||||||
|
* ),
|
||||||
|
* @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"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
* @param DocumentsFilters $filters
|
||||||
|
* @return Response|mixed
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(DocumentFilters $filters)
|
||||||
{
|
{
|
||||||
//
|
$documents = Document::filter($filters);
|
||||||
|
|
||||||
|
return $this->listResponse($documents);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,6 +57,27 @@ class PaymentEmailEngine extends BaseEmailEngine
|
|||||||
|
|
||||||
/* Use default translations if a custom message has not been set*/
|
/* Use default translations if a custom message has not been set*/
|
||||||
if (iconv_strlen($body_template) == 0) {
|
if (iconv_strlen($body_template) == 0) {
|
||||||
|
|
||||||
|
if ($payment->invoices()->exists())
|
||||||
|
{
|
||||||
|
$invoice_texts = ctrans('texts.invoice_number_short');
|
||||||
|
|
||||||
|
foreach ($this->payment->invoices as $invoice) {
|
||||||
|
$invoice_texts .= $invoice->number.',';
|
||||||
|
}
|
||||||
|
|
||||||
|
$invoice_texts = substr($invoice_texts, 0, -1);
|
||||||
|
|
||||||
|
$body_template = trans(
|
||||||
|
'texts.payment_message_extended',
|
||||||
|
['amount' => $payment->amount, 'company' => $payment->company->present()->name(), 'invoice' => $invoice_texts],
|
||||||
|
null,
|
||||||
|
$this->client->locale()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
$body_template = trans(
|
$body_template = trans(
|
||||||
'texts.payment_message',
|
'texts.payment_message',
|
||||||
['amount' => $payment->amount, 'company' => $payment->company->present()->name()],
|
['amount' => $payment->amount, 'company' => $payment->company->present()->name()],
|
||||||
@ -65,6 +86,8 @@ class PaymentEmailEngine extends BaseEmailEngine
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
||||||
$subject_template = $this->template_data['subject'];
|
$subject_template = $this->template_data['subject'];
|
||||||
} elseif (strlen($this->client->getSetting('email_subject_payment')) > 0) {
|
} elseif (strlen($this->client->getSetting('email_subject_payment')) > 0) {
|
||||||
|
@ -11,12 +11,14 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\Filterable;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class Document extends BaseModel
|
class Document extends BaseModel
|
||||||
{
|
{
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
use Filterable;
|
||||||
|
|
||||||
const DOCUMENT_PREVIEW_SIZE = 300; // pixels
|
const DOCUMENT_PREVIEW_SIZE = 300; // pixels
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ class AuthorizeCreditCard
|
|||||||
$payment_record = [];
|
$payment_record = [];
|
||||||
$payment_record['amount'] = $amount;
|
$payment_record['amount'] = $amount;
|
||||||
$payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER;
|
$payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER;
|
||||||
|
$payment_record['gateway_type_id'] = GatewayType::CREDIT_CARD;
|
||||||
$payment_record['transaction_reference'] = $response->getTransactionResponse()->getTransId();
|
$payment_record['transaction_reference'] = $response->getTransactionResponse()->getTransId();
|
||||||
|
|
||||||
$payment = $this->authorize->createPayment($payment_record);
|
$payment = $this->authorize->createPayment($payment_record);
|
||||||
@ -165,21 +165,6 @@ class AuthorizeCreditCard
|
|||||||
return $payment;
|
return $payment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createPaymentRecord($data, $amount) :?Payment
|
|
||||||
{
|
|
||||||
$response = $data['response'];
|
|
||||||
//create a payment record
|
|
||||||
|
|
||||||
$payment = $this->authorize->createPayment($data['response']);
|
|
||||||
$payment->gateway_type_id = GatewayType::CREDIT_CARD;
|
|
||||||
$payment->type_id = PaymentType::CREDIT_CARD_OTHER;
|
|
||||||
$payment->transaction_reference = $response->getTransactionResponse()->getTransId();
|
|
||||||
$payment->amount = $amount;
|
|
||||||
$payment->save();
|
|
||||||
|
|
||||||
return $payment;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function processSuccessfulResponse($data, $request)
|
private function processSuccessfulResponse($data, $request)
|
||||||
{
|
{
|
||||||
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->input('payment_hash')])->firstOrFail();
|
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->input('payment_hash')])->firstOrFail();
|
||||||
|
@ -209,6 +209,8 @@ class BaseDriver extends AbstractPaymentDriver
|
|||||||
$payment->currency_id = $this->client->getSetting('currency_id');
|
$payment->currency_id = $this->client->getSetting('currency_id');
|
||||||
$payment->date = Carbon::now();
|
$payment->date = Carbon::now();
|
||||||
|
|
||||||
|
//$payment->gateway_type_id = $data['gateway_type_id'];
|
||||||
|
|
||||||
$client_contact = $this->getContact();
|
$client_contact = $this->getContact();
|
||||||
$client_contact_id = $client_contact ? $client_contact->id : null;
|
$client_contact_id = $client_contact ? $client_contact->id : null;
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ class PayPalExpressPaymentDriver extends BaseDriver
|
|||||||
'payment_type' => PaymentType::PAYPAL,
|
'payment_type' => PaymentType::PAYPAL,
|
||||||
'amount' => $this->payment_hash->data->amount,
|
'amount' => $this->payment_hash->data->amount,
|
||||||
'transaction_reference' => $response->getTransactionReference(),
|
'transaction_reference' => $response->getTransactionReference(),
|
||||||
|
'gateway_type_id' => GatewayType::PAYPAL,
|
||||||
];
|
];
|
||||||
|
|
||||||
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
$payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED);
|
||||||
|
@ -157,6 +157,7 @@ class ACH
|
|||||||
'payment_type' => PaymentType::ACH,
|
'payment_type' => PaymentType::ACH,
|
||||||
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->amount, $this->stripe->client->currency()->precision),
|
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->amount, $this->stripe->client->currency()->precision),
|
||||||
'transaction_reference' => $state['charge']->id,
|
'transaction_reference' => $state['charge']->id,
|
||||||
|
'gateway_type_id' => GatewayType::BANK_TRANSFER,
|
||||||
];
|
];
|
||||||
|
|
||||||
$payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING);
|
$payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING);
|
||||||
|
@ -76,6 +76,8 @@ class Alipay
|
|||||||
'payment_type' => PaymentType::ALIPAY,
|
'payment_type' => PaymentType::ALIPAY,
|
||||||
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision),
|
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision),
|
||||||
'transaction_reference' => $source,
|
'transaction_reference' => $source,
|
||||||
|
'gateway_type_id' => GatewayType::ALIPAY,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING);
|
$payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING);
|
||||||
|
@ -172,23 +172,18 @@ class Charge
|
|||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'gateway_type_id' => $cgt->gateway_type_id,
|
'gateway_type_id' => $cgt->gateway_type_id,
|
||||||
'type_id' => $this->transformPaymentTypeToConstant($payment_method_type),
|
'payment_type' => $this->transformPaymentTypeToConstant($payment_method_type),
|
||||||
'transaction_reference' => $response->charges->data[0]->id,
|
'transaction_reference' => $response->charges->data[0]->id,
|
||||||
|
'amount' => $amount,
|
||||||
];
|
];
|
||||||
|
|
||||||
$payment = $this->stripe->createPaymentRecord($data, $amount);
|
$payment = $this->stripe->createPayment($data);
|
||||||
$payment->meta = $cgt->meta;
|
$payment->meta = $cgt->meta;
|
||||||
$payment->save();
|
$payment->save();
|
||||||
|
|
||||||
$payment_hash->payment_id = $payment->id;
|
$payment_hash->payment_id = $payment->id;
|
||||||
$payment_hash->save();
|
$payment_hash->save();
|
||||||
|
|
||||||
$this->stripe->attachInvoices($payment, $payment_hash);
|
|
||||||
|
|
||||||
$payment->service()->updateInvoicePayment($payment_hash);
|
|
||||||
|
|
||||||
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
|
|
||||||
|
|
||||||
return $payment;
|
return $payment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,7 @@ class CreditCard
|
|||||||
'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)),
|
'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)),
|
||||||
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->server_response->amount, $this->stripe->client->currency()->precision),
|
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->server_response->amount, $this->stripe->client->currency()->precision),
|
||||||
'transaction_reference' => optional($this->stripe->payment_hash->data->payment_intent->charges->data[0])->id,
|
'transaction_reference' => optional($this->stripe->payment_hash->data->payment_intent->charges->data[0])->id,
|
||||||
|
'gateway_type_id' => GatewayType::CREDIT_CARD,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ class SOFORT
|
|||||||
'payment_type' => PaymentType::SOFORT,
|
'payment_type' => PaymentType::SOFORT,
|
||||||
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision),
|
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->stripe_amount, $this->stripe->client->currency()->precision),
|
||||||
'transaction_reference' => $source,
|
'transaction_reference' => $source,
|
||||||
|
'gateway_type_id' => GatewayType::SOFORT,
|
||||||
];
|
];
|
||||||
|
|
||||||
$payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING);
|
$payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING);
|
||||||
|
@ -177,6 +177,8 @@ class StripePaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
public function processPaymentResponse($request) //We never have to worry about unsuccessful payments as failures are handled at the front end for this driver.
|
public function processPaymentResponse($request) //We never have to worry about unsuccessful payments as failures are handled at the front end for this driver.
|
||||||
{
|
{
|
||||||
|
$this->setPaymentHash($request->payment_hash);
|
||||||
|
|
||||||
return $this->payment_method->paymentResponse($request);
|
return $this->payment_method->paymentResponse($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,34 +324,11 @@ class StripePaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
||||||
{
|
{
|
||||||
|
$this->setPaymentHash($payment_hash);
|
||||||
|
|
||||||
return (new Charge($this))->tokenBilling($cgt, $payment_hash);
|
return (new Charge($this))->tokenBilling($cgt, $payment_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a payment record for the given
|
|
||||||
* data array.
|
|
||||||
*
|
|
||||||
* @param array $data An array of payment attributes
|
|
||||||
* @param float $amount The amount of the payment
|
|
||||||
* @return Payment The payment object
|
|
||||||
*/
|
|
||||||
public function createPaymentRecord($data, $amount): ?Payment
|
|
||||||
{
|
|
||||||
$payment = PaymentFactory::create($this->client->company_id, $this->client->user_id);
|
|
||||||
$payment->client_id = $this->client->id;
|
|
||||||
$payment->company_gateway_id = $this->company_gateway->id;
|
|
||||||
$payment->status_id = Payment::STATUS_COMPLETED;
|
|
||||||
$payment->gateway_type_id = $data['gateway_type_id'];
|
|
||||||
$payment->type_id = $data['type_id'];
|
|
||||||
$payment->currency_id = $this->client->getSetting('currency_id');
|
|
||||||
$payment->date = Carbon::now();
|
|
||||||
$payment->transaction_reference = $data['transaction_reference'];
|
|
||||||
$payment->amount = $amount;
|
|
||||||
$payment->save();
|
|
||||||
|
|
||||||
return $payment->service()->applyNumber()->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach Stripe payment method to Stripe client.
|
* Attach Stripe payment method to Stripe client.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user