1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00

Merge remote-tracking branch 'upstream/v5-develop' into v5-paypal-refactor

This commit is contained in:
Benjamin Beganović 2020-11-28 01:01:18 +01:00
commit 4284870c4e
32 changed files with 114454 additions and 114134 deletions

View File

@ -52,8 +52,9 @@ TRUSTED_PROXIES=
NINJA_ENVIRONMENT=selfhost
PHANTOMJS_PDF_GENERATION=true
PHANTOMJS_KEY='a-demo-key-with-low-quota-per-ip-address'
PHANTOMJS_SECRET=
PHANTOMJS_SECRET=secret
COMPOSER_AUTH='{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}'
SENTRY_LARAVEL_DSN=https://cc7e8e2c678041689e53e409b7dba236@sentry.invoicing.co/5

View File

@ -1 +1 @@
5.0.25
5.0.27

View File

@ -155,19 +155,19 @@ class InvoiceSum
{
$this->total += $this->total_taxes;
if (is_numeric($this->invoice->custom_value1) && $this->invoice->custom_value1 > 0) {
if (is_numeric($this->invoice->custom_value1)) {
$this->total += $this->invoice->custom_value1;
}
if (is_numeric($this->invoice->custom_value2) && $this->invoice->custom_value2 > 0) {
if (is_numeric($this->invoice->custom_value2)) {
$this->total += $this->invoice->custom_value2;
}
if (is_numeric($this->invoice->custom_value3) && $this->invoice->custom_value3 > 0) {
if (is_numeric($this->invoice->custom_value3)) {
$this->total += $this->invoice->custom_value3;
}
if (is_numeric($this->invoice->custom_value4) && $this->invoice->custom_value4 > 0) {
if (is_numeric($this->invoice->custom_value4)) {
$this->total += $this->invoice->custom_value4;
}

View File

@ -166,19 +166,19 @@ class InvoiceSumInclusive
{
//$this->total += $this->total_taxes;
if (is_numeric($this->invoice->custom_value1) && $this->invoice->custom_value1 > 0) {
if (is_numeric($this->invoice->custom_value1)) {
$this->total += $this->invoice->custom_value1;
}
if (is_numeric($this->invoice->custom_value2) && $this->invoice->custom_value2 > 0) {
if (is_numeric($this->invoice->custom_value2)) {
$this->total += $this->invoice->custom_value2;
}
if (is_numeric($this->invoice->custom_value3) && $this->invoice->custom_value3 > 0) {
if (is_numeric($this->invoice->custom_value3)) {
$this->total += $this->invoice->custom_value3;
}
if (is_numeric($this->invoice->custom_value4) && $this->invoice->custom_value4 > 0) {
if (is_numeric($this->invoice->custom_value4)) {
$this->total += $this->invoice->custom_value4;
}

View File

@ -65,6 +65,7 @@ class BaseController extends Controller
'company.task_statuses',
'company.expense_categories',
'company.documents',
'company.users',
//'company.users.company_user',
'company.clients.contacts.company',
'company.clients.gateway_tokens',

View File

@ -0,0 +1,33 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Controllers\ClientPortal;
use App\Http\Controllers\Controller;
use Auth;
use Illuminate\Support\Facades\Cache;
class TempRouteController extends Controller
{
/**
* Logs a user into the client portal using their contact_key
* @param string $contact_key The contact key
* @return Auth|Redirect
*/
public function index(string $hash)
{
$data = [];
$data['html'] = Cache::get($hash);
return view('pdf.html', $data);
}
}

View File

@ -20,6 +20,7 @@ use App\Models\InvoiceInvitation;
use App\Services\PdfMaker\Design;
use App\Services\PdfMaker\PdfMaker;
use App\Utils\HtmlEngine;
use App\Utils\PhantomJS\Phantom;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceHtml;
use Illuminate\Support\Facades\DB;
@ -121,6 +122,12 @@ class PreviewController extends BaseController
->design($design)
->build();
//if phantom js...... inject here..
if (config('ninja.phantomjs_pdf_generation')) {
return (new Phantom)->convertHtmlToPdf($maker->getCompiledHTML(true));
}
//else
$file_path = PreviewPdf::dispatchNow($maker->getCompiledHTML(true), auth()->user()->company());
return response()->download($file_path)->deleteFileAfterSend(true);
@ -192,6 +199,10 @@ class PreviewController extends BaseController
->design($design)
->build();
if (config('ninja.phantomjs_pdf_generation')) {
return (new Phantom)->convertHtmlToPdf($maker->getCompiledHTML(true));
}
$file_path = PreviewPdf::dispatchNow($maker->getCompiledHTML(true), auth()->user()->company());
DB::rollBack();

View File

@ -10,12 +10,14 @@ class NameWebsiteLogo extends Component
public $name;
public $website;
public $phone;
public $saved;
public $rules = [
'name' => ['required', 'min:3'],
'website' => ['required', 'url'],
'phone' => ['required', 'string', 'max:255'],
];
public function mount()
@ -24,6 +26,7 @@ class NameWebsiteLogo extends Component
'profile' => auth()->user('contact')->client,
'name' => auth()->user('contact')->client->present()->name,
'website' => auth()->user('contact')->client->present()->website,
'phone' => auth()->user('contact')->client->present()->phone,
'saved' => ctrans('texts.save'),
]);
}
@ -37,9 +40,11 @@ class NameWebsiteLogo extends Component
{
$data = $this->validate($this->rules);
$this->profile
->fill($data)
->save();
$this->profile->name = $data['name'];
$this->profile->website = $data['website'];
$this->profile->phone = $data['phone'];
$this->profile->save();
$this->saved = ctrans('texts.saved_at', ['time' => now()->toTimeString()]);
}

View File

@ -87,7 +87,7 @@ class CreateEntityPdf implements ShouldQueue
public function handle()
{
if (config('ninja.phantomjs_key')) {
if (config('ninja.phantomjs_pdf_generation')) {
return (new Phantom)->generate($this->invitation);
}

View File

@ -55,6 +55,11 @@ class CompanyUser extends Pivot
return self::class;
}
public function tax_rates()
{
return $this->hasMany(TaxRate::class, 'company_id', 'company_id');
}
public function account()
{
return $this->belongsTo(Account::class);

View File

@ -11,15 +11,24 @@
namespace App\PaymentDrivers;
use App\Models\ClientGatewayToken;
use App\Models\Payment;
use App\Models\PaymentHash;
use Illuminate\Http\Request;
abstract class AbstractPaymentDriver
{
abstract public function authorize($payment_method);
abstract public function authorizeView(array $data);
abstract public function purchase($amount, $return_client_response = false);
abstract public function authorizeResponse(Request $request);
abstract public function processPaymentView(array $data);
abstract public function processPaymentResponse(Request $request);
abstract public function refund(Payment $payment, $refund_amount, $return_client_response = false);
abstract public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash);
abstract public function setPaymentMethod($payment_method_id);
}

View File

@ -95,18 +95,31 @@ class AuthorizeCreditCard
$data = (new ChargePaymentProfile($this->authorize))->chargeCustomerProfile($cgt->gateway_customer_reference, $cgt->token, $amount);
/*Refactor and push to BaseDriver*/
if ($data['response'] != null && $data['response']->getMessages()->getResultCode() == 'Ok') {
$payment = $this->createPaymentRecord($data, $amount);
$payment->meta = $cgt->meta;
$payment->save();
// $response = $data['response'];
// $payment_record = [];
// $payment_record['amount'] = $amount;
// $payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER;;
// $payment_record['transaction_reference'] = $response->getTransactionResponse()->getTransId();
// $this->authorize->createPayment($payment_record);
$payment_hash->payment_id = $payment->id;
$payment_hash->save();
$this->storePayment($payment_hash, $data);
// $payment = $this->createPaymentRecord($data, $amount);
// $payment->meta = $cgt->meta;
// $payment->save();
// $payment_hash->payment_id = $payment->id;
// $payment_hash->save();
$this->authorize->attachInvoices($payment, $payment_hash);
$payment->service()->updateInvoicePayment($payment_hash);
// $this->authorize->attachInvoices($payment, $payment_hash);
// $payment->service()->updateInvoicePayment($payment_hash);
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
// event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
$vars = [
'hashed_ids' => $invoice->hashed_id,
@ -126,6 +139,12 @@ class AuthorizeCreditCard
}
}
private function handleResponse($data, $request)
{
$response = $data['response'];
@ -143,16 +162,15 @@ class AuthorizeCreditCard
{
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
$payment = $this->createPaymentRecord($data, $amount);
$payment_hash->payment_id = $payment->id;
$payment_hash->save();
$response = $data['response'];
$this->authorize->attachInvoices($payment, $payment_hash);
$payment_record = [];
$payment_record['amount'] = $amount;
$payment_record['payment_type'] = PaymentType::CREDIT_CARD_OTHER;
;
$payment_record['transaction_reference'] = $response->getTransactionResponse()->getTransId();
$payment->service()->updateInvoicePayment($payment_hash);
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
$payment = $this->authorize->createPayment($payment_record);
return $payment;
}

View File

@ -13,7 +13,6 @@
namespace App\PaymentDrivers\Authorize;
use App\Exceptions\GenericPaymentDriverFailure;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use App\PaymentDrivers\AuthorizePaymentDriver;
use net\authorize\api\contract\v1\CreateCustomerPaymentProfileRequest;
@ -35,34 +34,34 @@ class AuthorizePaymentMethod
public $payment_method;
private $payment_method_id;
public function __construct(AuthorizePaymentDriver $authorize)
{
$this->authorize = $authorize;
}
public function authorizeView($payment_method)
public function authorizeView()
{
$this->payment_method = $payment_method;
if ($this->authorize->payment_method instanceof AuthorizeCreditCard) {
$this->payment_method_id = GatewayType::CREDIT_CARD;
switch ($payment_method) {
case GatewayType::CREDIT_CARD:
return $this->authorizeCreditCard();
break;
case GatewayType::BANK_TRANSFER:
return $this->authorizeBankTransfer();
break;
default:
// code...
break;
return $this->authorizeCreditCard();
}
// case GatewayType::BANK_TRANSFER:
// return $this->authorizeBankTransfer();
// break;
}
public function authorizeResponseView($data)
public function authorizeResponseView($request)
{
$this->payment_method = $data['payment_method_id'];
$data = $request->all();
$this->payment_method_id = $data['method'];
switch ($this->payment_method) {
switch ($this->payment_method_id) {
case GatewayType::CREDIT_CARD:
return $this->authorizeCreditCardResponse($data);
break;
@ -111,19 +110,16 @@ class AuthorizePaymentMethod
public function createClientGatewayToken($payment_profile, $gateway_customer_reference)
{
// info(print_r($payment_profile,1));
$data = [];
$additonal = [];
$client_gateway_token = new ClientGatewayToken();
$client_gateway_token->company_id = $this->authorize->client->company_id;
$client_gateway_token->client_id = $this->authorize->client->id;
$client_gateway_token->token = $payment_profile->getPaymentProfile()->getCustomerPaymentProfileId();
$client_gateway_token->company_gateway_id = $this->authorize->company_gateway->id;
$client_gateway_token->gateway_type_id = $this->payment_method;
$client_gateway_token->gateway_customer_reference = $gateway_customer_reference;
$client_gateway_token->meta = $this->buildPaymentMethod($payment_profile);
$client_gateway_token->save();
$data['token'] = $payment_profile->getPaymentProfile()->getCustomerPaymentProfileId();
$data['payment_method_id'] = $this->payment_method_id;
$data['payment_meta'] = $this->buildPaymentMethod($payment_profile);
return $client_gateway_token;
$additional['gateway_customer_reference'] = $gateway_customer_reference;
$this->authorize->storeGatewayToken($data, $additional);
}
public function buildPaymentMethod($payment_profile)

View File

@ -63,6 +63,38 @@ class AuthorizePaymentDriver extends BaseDriver
return $types;
}
public function authorizeView($payment_method)
{
return (new AuthorizePaymentMethod($this))->authorizeView();
}
public function authorizeResponse($request)
{
return (new AuthorizePaymentMethod($this))->authorizeResponseView($request);
}
public function processPaymentView($data)
{
return $this->payment_method->processPaymentView($data);
}
public function processPaymentResponse($request)
{
return $this->payment_method->processPaymentResponse($request);
}
public function refund(Payment $payment, $refund_amount, $return_client_response = false)
{
return (new RefundTransaction($this))->refundTransaction($payment, $refund_amount);
}
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
$this->setPaymentMethod($cgt->gateway_type_id);
return $this->payment_method->tokenBilling($cgt, $payment_hash);
}
public function init()
{
error_reporting(E_ALL & ~E_DEPRECATED);
@ -94,59 +126,6 @@ class AuthorizePaymentDriver extends BaseDriver
return $env = ANetEnvironment::PRODUCTION;
}
public function authorizeView($payment_method)
{
if (count($this->required_fields) > 0) {
return redirect()
->route('client.profile.edit', ['client_contact' => auth()->user()->hashed_id])
->with('missing_required_fields', $this->required_fields);
}
return (new AuthorizePaymentMethod($this))->authorizeView($payment_method);
}
public function authorizeResponseView(array $data)
{
return (new AuthorizePaymentMethod($this))->authorizeResponseView($data);
}
public function authorize($payment_method)
{
return $this->authorizeView($payment_method);
}
public function processPaymentView($data)
{
if (count($this->required_fields) > 0) {
return redirect()
->route('client.profile.edit', ['client_contact' => auth()->user()->hashed_id])
->with('missing_required_fields', $this->required_fields);
}
return $this->payment_method->processPaymentView($data);
}
public function processPaymentResponse($request)
{
if (count($this->required_fields) > 0) {
return redirect()
->route('client.profile.edit', ['client_contact' => auth()->user()->hashed_id])
->with('missing_required_fields', $this->required_fields);
}
return $this->payment_method->processPaymentResponse($request);
}
public function purchase($amount, $return_client_response = false)
{
return false;
}
public function refund(Payment $payment, $refund_amount, $return_client_response = false)
{
return (new RefundTransaction($this))->refundTransaction($payment, $refund_amount);
}
public function findClientGatewayRecord() :?ClientGatewayToken
{
return ClientGatewayToken::where('client_id', $this->client->id)
@ -154,12 +133,6 @@ class AuthorizePaymentDriver extends BaseDriver
->first();
}
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
$this->setPaymentMethod($cgt->gateway_type_id);
return $this->payment_method->tokenBilling($cgt, $payment_hash);
}
/**
* Detach payment method from Authorize.net.

View File

@ -31,8 +31,8 @@ use App\Utils\Traits\MakesHash;
use App\Utils\Traits\SystemLogTrait;
use Checkout\Library\Exceptions\CheckoutHttpException;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
/**
* Class BaseDriver.
@ -60,14 +60,13 @@ class BaseDriver extends AbstractPaymentDriver
/* The client */
public $client;
/* The initiated gateway driver class*/
/* The initialized gateway driver class*/
public $payment_method;
/**
* @var PaymentHash
*/
/* PaymentHash */
public $payment_hash;
/* Array of payment methods */
public static $methods = [];
/** @var array */
@ -76,9 +75,7 @@ class BaseDriver extends AbstractPaymentDriver
public function __construct(CompanyGateway $company_gateway, Client $client = null, $invitation = false)
{
$this->company_gateway = $company_gateway;
$this->invitation = $invitation;
$this->client = $client;
}
@ -86,21 +83,41 @@ class BaseDriver extends AbstractPaymentDriver
* Authorize a payment method.
*
* Returns a reusable token for storage for future payments
* @param const $payment_method The GatewayType::constant
* @return void Return a view for collecting payment method information
*
* @param array $data
* @return mixed Return a view for collecting payment method information
*/
public function authorize($payment_method)
public function authorizeView(array $data)
{
}
/**
* Executes purchase attempt for a given amount.
* The payment authorization response
*
* @param float $amount The amount to be collected
* @param bool $return_client_response Whether the method needs to return a response (otherwise we assume an unattended payment)
* @return mixed
* @param Request $request
* @return mixed Return a response for collecting payment method information
*/
public function purchase($amount, $return_client_response = false)
public function authorizeResponse(Request $request)
{
}
/**
* Process a payment
*
* @param array $data
* @return mixed Return a view for the payment
*/
public function processPaymentView(array $data)
{
}
/**
* Process payment response
*
* @param Request $request
* @return mixed Return a response for the payment
*/
public function processPaymentResponse(Request $request)
{
}
@ -116,6 +133,17 @@ class BaseDriver extends AbstractPaymentDriver
{
}
/**
* Process an unattended payment.
*
* @param ClientGatewayToken $cgt The client gateway token object
* @param PaymentHash $payment_hash The Payment hash containing the payment meta data
* @return void The payment response
*/
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
}
/**
* Set the inbound request payment method type for access.
*
@ -125,10 +153,12 @@ class BaseDriver extends AbstractPaymentDriver
{
}
/************************** Helper methods *************************************/
public function setPaymentHash(PaymentHash $payment_hash)
{
$this->payment_hash = $payment_hash;
return $this;
}
@ -189,17 +219,6 @@ class BaseDriver extends AbstractPaymentDriver
return $payment->service()->applyNumber()->save();
}
/**
* Process an unattended payment.
*
* @param ClientGatewayToken $cgt The client gateway token object
* @param PaymentHash $payment_hash The Payment hash containing the payment meta data
* @return void The payment response
*/
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
}
/**
* When a successful payment is made, we need to append the gateway fee
* to an invoice.
@ -215,7 +234,7 @@ class BaseDriver extends AbstractPaymentDriver
/*Payment invoices*/
$payment_invoices = $payment_hash->invoices();
// /*Fee charged at gateway*/
/*Fee charged at gateway*/
$fee_total = $payment_hash->fee_total;
// Sum of invoice amounts
@ -265,7 +284,6 @@ class BaseDriver extends AbstractPaymentDriver
}
}
/**
* Store payment method as company gateway token.
*

View File

@ -0,0 +1,72 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\PaymentDrivers;
use App\Utils\Traits\MakesHash;
class YourGatewayPaymentDriver extends BaseDriver
{
use MakesHash;
public $refundable = true; //does this gateway support refunds?
public $token_billing = true; //does this gateway support token billing?
public $can_authorise_credit_card = true; //does this gateway support authorizations?
public $gateway; //initialized gateway
public $payment_method; //initialized payment method
public static $methods = [
GatewayType::CREDIT_CARD => CreditCard::class, //maps GatewayType => Implementation class
];
const SYSTEM_LOG_TYPE = SystemLog::TYPE_STRIPE;
public function setPaymentMethod($payment_method_id)
{
$class = self::$methods[$payment_method_id];
$this->payment_method = new $class($this);
return $this;
}
public function authorizeView(array $data)
{
return $this->payment_method->authorizeView($data); //this is your custom implementation from here
}
public function authorizeResponse($request)
{
return $this->payment_method->authorizeResponse($request); //this is your custom implementation from here
}
public function processPaymentView(array $data)
{
return $this->payment_method->paymentView($data); //this is your custom implementation from here
}
public function processPaymentResponse($request)
{
return $this->payment_method->paymentResponse($request); //this is your custom implementation from here
}
public function refund(Payment $payment, $amount, $return_client_response = false)
{
return $this->payment_method->yourRefundImplementationHere(); //this is your custom implementation from here
}
public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
{
return $this->payment_method->yourTokenBillingImplmentation(); //this is your custom implementation from here
}
}

View File

@ -22,6 +22,8 @@ use App\Utils\CurlUtils;
use App\Utils\HtmlEngine;
use App\Utils\Traits\MakesHash;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
@ -82,12 +84,28 @@ class Phantom
return $file_path;
}
public function convertHtmlToPdf($html)
{
$hash = Str::random(32);
Cache::put($hash, $html, 300);
$url = route('tmp_pdf', ['hash' => $hash]);
info($url);
$key = config('ninja.phantomjs_key');
$phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$url}%22,renderType:%22pdf%22%7D";
$pdf = CurlUtils::get($phantom_url);
$response = Response::make($pdf, 200);
$response->header('Content-Type', 'application/pdf');
return $response;
}
public function displayInvitation(string $entity, string $invitation_key)
{
$key = $entity.'_id';
$invitation_instance = 'App\Models\\'.Str::camel(ucfirst($entity)).'Invitation';
$invitation_instance = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
$invitation = $invitation_instance::whereRaw('BINARY `key`= ?', [$invitation_key])->first();
$entity_obj = $invitation->{$entity};
@ -113,9 +131,9 @@ class Phantom
$state = [
'template' => $template->elements([
'client' => $this->entity->client,
'entity' => $this->entity,
'pdf_variables' => (array) $this->entity->company->settings->pdf_variables,
'client' => $entity_obj->client,
'entity' => $entity_obj,
'pdf_variables' => (array) $entity_obj->company->settings->pdf_variables,
'$product' => $design->design->product,
]),
'variables' => $html->generateLabelsAndValues(),

View File

@ -78,9 +78,20 @@ class SystemHealth
'simple_db_check' => (bool) self::simpleDbCheck(),
'npm_status' => self::checkNpm(),
'node_status' => self::checkNode(),
'cache_enabled' => self::checkConfigCache(),
'phantom_enabled' => (bool) config('ninja.phantomjs_pdf_generation'),
];
}
public static function checkConfigCache()
{
if (env('APP_URL')) {
return false;
}
return true;
}
public static function checkNode()
{
try {

View File

@ -60,7 +60,8 @@ return [
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'root' => 'storage/',
// 'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
'permissions' => [

View File

@ -12,7 +12,7 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/').'/',
'app_domain' => env('APP_DOMAIN', ''),
'app_version' => '5.0.25',
'app_version' => '5.0.27',
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false),
@ -29,6 +29,7 @@ return [
'enabled_modules' => 32767,
'phantomjs_key' => env('PHANTOMJS_KEY', false),
'phantomjs_secret' => env('PHANTOMJS_SECRET', false),
'phantomjs_pdf_generation' => env('PHANTOMJS_PDF_GENERATION', true),
'trusted_proxies' => env('TRUSTED_PROXIES', false),
'sentry_dsn' => env('SENTRY_LARAVEL_DSN', 'https://9b4e15e575214354a7d666489783904a@sentry.invoicing.co/6'),

1288
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,34 +3,34 @@ const MANIFEST = 'flutter-app-manifest';
const TEMP = 'flutter-temp-cache';
const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {
"favicon.ico": "51636d3a390451561744c42188ccd628",
"version.json": "399f70d54a0cf071e6e83bb5382fcdf5",
"favicon.ico": "51636d3a390451561744c42188ccd628",
"main.dart.js": "abbefac6e42c6ac8c46c784c474498bc",
"/": "23224b5e03519aaa87594403d54412cf",
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
"assets/assets/images/logo.png": "090f69e23311a4b6d851b3880ae52541",
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
"assets/assets/images/google-icon.png": "0f118259ce403274f407f5e982e681c3",
"assets/AssetManifest.json": "ea09ed4b9b8b6c83d6896248aac7c527",
"assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac",
"assets/NOTICES": "86034c34fd4330a5f028df4c6dafd6cf",
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "c1242726c7eac4eb5e843d826f78fb1b",
"assets/AssetManifest.json": "ea09ed4b9b8b6c83d6896248aac7c527",
"assets/assets/images/logo.png": "090f69e23311a4b6d851b3880ae52541",
"assets/assets/images/google-icon.png": "0f118259ce403274f407f5e982e681c3",
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
"assets/NOTICES": "02aa30cfaaab572341a87cc774e7ef24",
"manifest.json": "77215c1737c7639764e64a192be2f7b8",
"main.dart.js": "7c5eabcd4c179bc7d4fd0918f27ad7fb",
"version.json": "399f70d54a0cf071e6e83bb5382fcdf5",
"/": "23224b5e03519aaa87594403d54412cf",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35"
};

226739
public/main.dart.js vendored

File diff suppressed because one or more lines are too long

View File

@ -45,7 +45,9 @@ if(!isset($design)) $design = 'light';
{{ $greeting }}
@endisset
{{ $slot }}
<div class="break-all">
{{ $slot}}
</div>
@isset($signature)
{{ $signature }}

View File

@ -17,7 +17,8 @@
@endpush
@section('body')
<form action="{{ route('client.payment_methods.store') }}" method="post" id="server_response">
<form action="{{ route('client.payment_methods.store', ['method' => App\Models\GatewayType::CREDIT_CARD]) }}" method="post" id="server_response">
@csrf
<input type="hidden" name="company_gateway_id" value="{{ $gateway->id }}">
<input type="hidden" name="payment_method_id" value="1">

View File

@ -24,6 +24,15 @@
</div>
@enderror
</div>
<div class="col-span-6 sm:col-span-3">
<label for="street" class="input-label">{{ ctrans('texts.phone') }}</label>
<input id="phone" class="input w-full {{ in_array('phone', (array) session('missing_required_fields')) ? 'border border-red-400' : '' }}" name="phone" wire:model.defer="phone" />
@error('phone')
<div class="validation validation-fail">
{{ $message }}
</div>
@enderror
</div>
<div class="col-span-6 sm:col-span-3">
<label for="website" class="input-label">{{ ctrans('texts.website') }}</label>
<input id="website" class="input w-full" name="website" wire:model.defer="website" />

View File

@ -34,7 +34,7 @@
@enderror
</div>
<div class="mt-5">
<button class="button button-primary button-block">{{ ctrans('texts.update') }}</button>
<button class="button button-primary button-block bg-blue-600">{{ ctrans('texts.update') }}</button>
</div>
</form>
</div>

View File

@ -8,7 +8,7 @@
<img src="{{ asset('images/invoiceninja-black-logo-2.png') }}" class="border-b border-gray-100 h-18 pb-4" alt="Invoice Ninja logo">
<h1 class="text-center text-3xl mt-10">{{ ctrans('texts.confirmation') }}</h1>
<p class="text-center opacity-75">{{ $message }}</p>
<a class="button button-primary text-center mt-8" href="{{ url('/') }}">{{ ctrans('texts.return_to_login') }}</a>
<a class="button button-primary text-blue-600 text-center mt-8" href="{{ url('/') }}">{{ ctrans('texts.return_to_login') }}</a>
</div>
</div>
</div>

View File

@ -28,7 +28,7 @@
@enderror
</div>
<div class="mt-5">
<button class="button button-primary button-block">{{ ctrans('texts.next_step') }}</button>
<button class="button button-primary button-block bg-blue-600">{{ ctrans('texts.next_step') }}</button>
</div>
</form>
</div>

View File

@ -23,11 +23,11 @@
</section>
<div class="flex items-center">
@if($entity instanceof App\Models\Invoice)
<button class="button button-primary">{{ ctrans('texts.pay_now') }}</button>
<button class="button button-primary bg-blue-600">{{ ctrans('texts.pay_now') }}</button>
@elseif($$entity instanceof App\Models\Quote)
<button class="button button-primary">{{ ctrans('texts.approve') }}</button>
<button class="button button-primary bg-blue-600">{{ ctrans('texts.approve') }}</button>
@endif
<button class="button button-primary ml-2">{{ ctrans('texts.download') }}</button>
<button class="button button-primary bg-blue-600 ml-2">{{ ctrans('texts.download') }}</button>
<div x-data="{ open: false }" @keydown.escape="open = false" @click.away="open = false" class="relative inline-block text-left ml-2">
<div>
<button @click="open = !open" class="flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:text-gray-600">

View File

@ -22,7 +22,7 @@
@endif
</div>
<div class="mt-5">
<button class="button button-primary button-block">{{ ctrans('texts.continue') }}</button>
<button class="button button-primary button-block bg-blue-600">{{ ctrans('texts.continue') }}</button>
</div>
</form>
</div>

View File

@ -19,6 +19,8 @@ Route::get('view/{entity_type}/{invitation_key}', 'ClientPortal\EntityViewContro
Route::get('view/{entity_type}/{invitation_key}/password', 'ClientPortal\EntityViewController@password')->name('client.entity_view.password');
Route::post('view/{entity_type}/{invitation_key}/password', 'ClientPortal\EntityViewController@handlePassword');
Route::get('tmp_pdf/{hash}', 'ClientPortal\TempRouteController@index')->name('tmp_pdf');
Route::get('client/key_login/{contact_key}', 'ClientPortal\ContactHashLoginController@login')->name('client.contact_login')->middleware(['contact_key_login']);
//todo implement domain DB