mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-11 05:32:39 +01:00
commit
7eb5b37eef
2
.github/workflows/phpunit.yml
vendored
2
.github/workflows/phpunit.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: ['ubuntu-20.04', 'ubuntu-22.04']
|
operating-system: ['ubuntu-20.04', 'ubuntu-22.04']
|
||||||
php-versions: ['8.1.11']
|
php-versions: ['8.1']
|
||||||
phpunit-versions: ['latest']
|
phpunit-versions: ['latest']
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
@ -1 +1 @@
|
|||||||
5.5.46
|
5.5.47
|
@ -152,7 +152,22 @@ class BankTransactionFilters extends QueryFilters
|
|||||||
public function sort(string $sort) : Builder
|
public function sort(string $sort) : Builder
|
||||||
{
|
{
|
||||||
$sort_col = explode('|', $sort);
|
$sort_col = explode('|', $sort);
|
||||||
|
|
||||||
|
if(!is_array($sort_col))
|
||||||
|
return $this->builder;
|
||||||
|
|
||||||
|
if($sort_col[0] == 'deposit')
|
||||||
|
return $this->builder->where('base_type', 'CREDIT')->orderBy('amount', $sort_col[1]);
|
||||||
|
|
||||||
|
if($sort_col[0] == 'withdrawal')
|
||||||
|
return $this->builder->where('base_type', 'DEBIT')->orderBy('amount', $sort_col[1]);
|
||||||
|
|
||||||
|
if($sort_col[0] == 'status')
|
||||||
|
$sort_col[0] = 'status_id';
|
||||||
|
|
||||||
|
if(in_array($sort_col[0],['invoices','expense']))
|
||||||
|
return $this->builder;
|
||||||
|
|
||||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Livewire;
|
namespace App\Http\Livewire;
|
||||||
|
|
||||||
|
use App\DataMapper\ClientSettings;
|
||||||
use App\Factory\ClientFactory;
|
use App\Factory\ClientFactory;
|
||||||
use App\Jobs\Mail\NinjaMailerJob;
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
use App\Jobs\Mail\NinjaMailerObject;
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
@ -19,15 +20,17 @@ use App\Mail\ContactPasswordlessLogin;
|
|||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
use App\Models\Subscription;
|
use App\Models\Subscription;
|
||||||
use App\Repositories\ClientContactRepository;
|
use App\Repositories\ClientContactRepository;
|
||||||
use App\Repositories\ClientRepository;
|
use App\Repositories\ClientRepository;
|
||||||
|
use App\Utils\Number;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use App\DataMapper\ClientSettings;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class BillingPortalPurchasev2 extends Component
|
class BillingPortalPurchasev2 extends Component
|
||||||
@ -179,6 +182,13 @@ class BillingPortalPurchasev2 extends Component
|
|||||||
*/
|
*/
|
||||||
public $campaign;
|
public $campaign;
|
||||||
|
|
||||||
|
public $bundle;
|
||||||
|
public $recurring_products;
|
||||||
|
public $products;
|
||||||
|
public $optional_recurring_products;
|
||||||
|
public $optional_products;
|
||||||
|
public $total;
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
@ -196,46 +206,156 @@ class BillingPortalPurchasev2 extends Component
|
|||||||
elseif(strlen($this->subscription->promo_code) == 0 && $this->subscription->promo_discount > 0){
|
elseif(strlen($this->subscription->promo_code) == 0 && $this->subscription->promo_discount > 0){
|
||||||
$this->price = $this->subscription->promo_price;
|
$this->price = $this->subscription->promo_price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->recurring_products = $this->subscription->service()->recurring_products();
|
||||||
|
$this->products = $this->subscription->service()->products();
|
||||||
|
$this->optional_recurring_products = $this->subscription->service()->optional_recurring_products();
|
||||||
|
$this->optional_products = $this->subscription->service()->optional_products();
|
||||||
|
|
||||||
|
// $this->buildBundle();
|
||||||
|
$this->bundle = collect();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updatingData()
|
public function buildBundle()
|
||||||
{
|
{
|
||||||
nlog('updating');
|
$this->bundle = collect();
|
||||||
// nlog($this->data);
|
|
||||||
|
$data = $this->data;
|
||||||
|
|
||||||
|
foreach($this->recurring_products as $key => $p)
|
||||||
|
{
|
||||||
|
|
||||||
|
$qty = isset($data[$key]['recurring_qty']) ? $data[$key]['recurring_qty'] : 1;
|
||||||
|
$total = $p->price * $qty;
|
||||||
|
|
||||||
|
$this->bundle->push([
|
||||||
|
'product' => nl2br(substr($p->notes, 0, 50)),
|
||||||
|
'price' => Number::formatMoney($total, $this->subscription->company).' / '. RecurringInvoice::frequencyForKey($this->subscription->frequency_id),
|
||||||
|
'total' => $total,
|
||||||
|
'qty' => $qty,
|
||||||
|
'is_recurring' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($this->products as $key => $p)
|
||||||
|
{
|
||||||
|
|
||||||
|
$qty = 1;
|
||||||
|
$total = $p->price * $qty;
|
||||||
|
|
||||||
|
$this->bundle->push([
|
||||||
|
'product' => nl2br(substr($p->notes, 0, 50)),
|
||||||
|
'price' => Number::formatMoney($total, $this->subscription->company),
|
||||||
|
'total' => $total,
|
||||||
|
'qty' => $qty,
|
||||||
|
'is_recurring' => false
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($this->data as $key => $value)
|
||||||
|
{
|
||||||
|
if(isset($this->data[$key]['optional_recurring_qty']))
|
||||||
|
{
|
||||||
|
$p = $this->optional_recurring_products->first(function ($v,$k) use($key){
|
||||||
|
return $k == $key;
|
||||||
|
});
|
||||||
|
|
||||||
|
$qty = isset($this->data[$key]['optional_recurring_qty']) ? $this->data[$key]['optional_recurring_qty'] : 0;
|
||||||
|
$total = $p->price * $qty;
|
||||||
|
|
||||||
|
if($qty == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
$this->bundle->push([
|
||||||
|
'product' => nl2br(substr($p->notes, 0, 50)),
|
||||||
|
'price' => Number::formatMoney($total, $this->subscription->company).' / '. RecurringInvoice::frequencyForKey($this->subscription->frequency_id),
|
||||||
|
'total' => $total,
|
||||||
|
'qty' => $qty,
|
||||||
|
'is_recurring' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($this->data[$key]['optional_qty']))
|
||||||
|
{
|
||||||
|
$p = $this->optional_products->first(function ($v,$k) use($key){
|
||||||
|
return $k == $key;
|
||||||
|
});
|
||||||
|
|
||||||
|
$qty = isset($this->data[$key]['optional_qty']) ? $this->data[$key]['optional_qty'] : 0;
|
||||||
|
$total = $p->price * $qty;
|
||||||
|
|
||||||
|
if($qty == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->bundle->push([
|
||||||
|
'product' => nl2br(substr($p->notes, 0, 50)),
|
||||||
|
'price' => Number::formatMoney($total, $this->subscription->company),
|
||||||
|
'total' => $total,
|
||||||
|
'qty' => $qty,
|
||||||
|
'is_recurring' => false
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->total = Number::formatMoney($this->bundle->sum('total'), $this->subscription->company);
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updatedData()
|
public function updatedData()
|
||||||
{
|
{
|
||||||
nlog('updated');
|
}
|
||||||
nlog($this->data);
|
|
||||||
$validatedData = $this->validate();
|
public function updating($prop)
|
||||||
nlog( $validatedData );
|
{
|
||||||
|
// $this->resetValidation($prop);
|
||||||
|
// $this->resetErrorBag($prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updated($propertyName)
|
public function updated($propertyName)
|
||||||
{
|
{
|
||||||
nlog("validating {$propertyName}");
|
$x = $this->validateOnly($propertyName, $this->rules(), [], $this->attributes());
|
||||||
$this->errors = $this->validateOnly($propertyName);
|
|
||||||
|
|
||||||
nlog($this->errors);
|
// // $validatedData = $this->validate();
|
||||||
$validatedData = $this->validate();
|
$this->buildBundle();
|
||||||
nlog( $validatedData );
|
|
||||||
|
// $order_validator = Validator::make($this->all(), $this->rules(), [], $this->attributes());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
$rules = [
|
$rules = [
|
||||||
'email' => ['required', 'email'],
|
'data.*.recurring_qty' => 'numeric|between:0,1000',
|
||||||
'data' => ['required', 'array'],
|
'data.*.optional_recurring_qty' => 'numeric|between:0,1000',
|
||||||
'data.*.recurring_qty' => ['required', 'between:100,1000'],
|
'data.*.optional_qty' => 'numeric|between:0,1000',
|
||||||
'data.*.optional_recurring_qty' => ['required', 'between:100,1000'],
|
|
||||||
'data.*.optional_qty' => ['required', 'between:100,1000'],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function attributes()
|
||||||
|
{
|
||||||
|
$attributes = [
|
||||||
|
'data.*.recurring_qty' => 'recurring_qty',
|
||||||
|
'data.*.optional_recurring_qty' => 'optional_recurring_qty',
|
||||||
|
'data.*.optional_qty' => 'optional_qty',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle user authentication
|
* Handle user authentication
|
||||||
*
|
*
|
||||||
|
@ -389,6 +389,7 @@ class MatchBankTransactions implements ShouldQueue
|
|||||||
|
|
||||||
$this->bt->invoice_ids = collect($invoices)->pluck('hashed_id')->implode(',');
|
$this->bt->invoice_ids = collect($invoices)->pluck('hashed_id')->implode(',');
|
||||||
$this->bt->status_id = BankTransaction::STATUS_CONVERTED;
|
$this->bt->status_id = BankTransaction::STATUS_CONVERTED;
|
||||||
|
$this->bt->payment_id = $payment->id;
|
||||||
$this->bt->save();
|
$this->bt->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ class QuoteViewedActivity implements ShouldQueue
|
|||||||
$fields->user_id = $event->invitation->quote->user_id;
|
$fields->user_id = $event->invitation->quote->user_id;
|
||||||
$fields->company_id = $event->invitation->company_id;
|
$fields->company_id = $event->invitation->company_id;
|
||||||
$fields->activity_type_id = Activity::VIEW_QUOTE;
|
$fields->activity_type_id = Activity::VIEW_QUOTE;
|
||||||
$fields->client_id = $event->invitation->client_id;
|
$fields->client_id = $event->invitation->quote->client_id;
|
||||||
$fields->client_contact_id = $event->invitation->client_contact_id;
|
$fields->client_contact_id = $event->invitation->client_contact_id;
|
||||||
$fields->invitation_id = $event->invitation->id;
|
$fields->invitation_id = $event->invitation->id;
|
||||||
$fields->quote_id = $event->invitation->quote_id;
|
$fields->quote_id = $event->invitation->quote_id;
|
||||||
|
@ -126,6 +126,8 @@ class Company extends BaseModel
|
|||||||
'report_include_deleted',
|
'report_include_deleted',
|
||||||
'invoice_task_lock',
|
'invoice_task_lock',
|
||||||
'use_vendor_currency',
|
'use_vendor_currency',
|
||||||
|
'convert_payment_currency',
|
||||||
|
'convert_expense_currency',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
|
@ -154,31 +154,6 @@ class PaymentIntentWebhook implements ShouldQueue
|
|||||||
'card_details' => isset($charge['payment_method_details']['card']['brand']) ? $charge['payment_method_details']['card']['brand'] : PaymentType::CREDIT_CARD_OTHER
|
'card_details' => isset($charge['payment_method_details']['card']['brand']) ? $charge['payment_method_details']['card']['brand'] : PaymentType::CREDIT_CARD_OTHER
|
||||||
];
|
];
|
||||||
|
|
||||||
if(isset($pi['allowed_source_types']) && in_array('card', $pi['allowed_source_types']))
|
|
||||||
{
|
|
||||||
|
|
||||||
$invoice = Invoice::with('client')->find($payment_hash->fee_invoice_id);
|
|
||||||
$client = $invoice->client;
|
|
||||||
|
|
||||||
$this->updateCreditCardPayment($payment_hash, $client, $meta);
|
|
||||||
}
|
|
||||||
elseif(isset($pi['payment_method_types']) && in_array('card', $pi['payment_method_types']))
|
|
||||||
{
|
|
||||||
|
|
||||||
$invoice = Invoice::with('client')->find($payment_hash->fee_invoice_id);
|
|
||||||
$client = $invoice->client;
|
|
||||||
|
|
||||||
$this->updateCreditCardPayment($payment_hash, $client, $meta);
|
|
||||||
}
|
|
||||||
elseif(isset($pi['payment_method_types']) && in_array('us_bank_account', $pi['payment_method_types']))
|
|
||||||
{
|
|
||||||
|
|
||||||
$invoice = Invoice::with('client')->find($payment_hash->fee_invoice_id);
|
|
||||||
$client = $invoice->client;
|
|
||||||
|
|
||||||
$this->updateAchPayment($payment_hash, $client, $meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemLogger::dispatch(
|
SystemLogger::dispatch(
|
||||||
['response' => $this->stripe_request, 'data' => []],
|
['response' => $this->stripe_request, 'data' => []],
|
||||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
@ -188,6 +163,39 @@ class PaymentIntentWebhook implements ShouldQueue
|
|||||||
$company,
|
$company,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(isset($pi['allowed_source_types']) && in_array('card', $pi['allowed_source_types']))
|
||||||
|
{
|
||||||
|
|
||||||
|
$invoice = Invoice::with('client')->withTrashed()->find($payment_hash->fee_invoice_id);
|
||||||
|
$client = $invoice->client;
|
||||||
|
|
||||||
|
if($invoice->is_deleted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->updateCreditCardPayment($payment_hash, $client, $meta);
|
||||||
|
}
|
||||||
|
elseif(isset($pi['payment_method_types']) && in_array('card', $pi['payment_method_types']))
|
||||||
|
{
|
||||||
|
|
||||||
|
$invoice = Invoice::with('client')->withTrashed()->find($payment_hash->fee_invoice_id);
|
||||||
|
$client = $invoice->client;
|
||||||
|
|
||||||
|
if($invoice->is_deleted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->updateCreditCardPayment($payment_hash, $client, $meta);
|
||||||
|
}
|
||||||
|
elseif(isset($pi['payment_method_types']) && in_array('us_bank_account', $pi['payment_method_types']))
|
||||||
|
{
|
||||||
|
|
||||||
|
$invoice = Invoice::with('client')->withTrashed()->find($payment_hash->fee_invoice_id);
|
||||||
|
$client = $invoice->client;
|
||||||
|
|
||||||
|
if($invoice->is_deleted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$this->updateAchPayment($payment_hash, $client, $meta);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +190,8 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'report_include_deleted' => (bool) $company->report_include_deleted,
|
'report_include_deleted' => (bool) $company->report_include_deleted,
|
||||||
'invoice_task_lock' => (bool) $company->invoice_task_lock,
|
'invoice_task_lock' => (bool) $company->invoice_task_lock,
|
||||||
'use_vendor_currency' => (bool) $company->use_vendor_currency,
|
'use_vendor_currency' => (bool) $company->use_vendor_currency,
|
||||||
|
'convert_payment_currency' => (bool) $company->convert_payment_currency,
|
||||||
|
'convert_expense_currency' => (bool) $company->convert_expense_currency,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ trait GeneratesCounter
|
|||||||
|
|
||||||
$counter_entity = $client;
|
$counter_entity = $client;
|
||||||
} elseif ((strpos($pattern, 'groupCounter') !== false) || (strpos($pattern, 'group_counter') !== false)) {
|
} elseif ((strpos($pattern, 'groupCounter') !== false) || (strpos($pattern, 'group_counter') !== false)) {
|
||||||
if (property_exists($client->group_settings, $counter_string)) {
|
if (property_exists($client, 'group_settings') && property_exists($client->group_settings, $counter_string)) {
|
||||||
$counter = $client->group_settings->{$counter_string};
|
$counter = $client->group_settings->{$counter_string};
|
||||||
} else {
|
} else {
|
||||||
$counter = 1;
|
$counter = 1;
|
||||||
@ -751,7 +751,7 @@ trait GeneratesCounter
|
|||||||
$replace[] = $client->number;
|
$replace[] = $client->number;
|
||||||
|
|
||||||
$search[] = '{$client_id_number}';
|
$search[] = '{$client_id_number}';
|
||||||
$replace[] = $client->id_number;
|
$replace[] = $client->id_number ?: $client->number;
|
||||||
|
|
||||||
$search[] = '{$clientIdNumber}';
|
$search[] = '{$clientIdNumber}';
|
||||||
$replace[] = $client->id_number ?: $client->number;
|
$replace[] = $client->id_number ?: $client->number;
|
||||||
|
@ -14,8 +14,8 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||||
'app_version' => '5.5.46',
|
'app_version' => '5.5.47',
|
||||||
'app_tag' => '5.5.46',
|
'app_tag' => '5.5.47',
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', ''),
|
'api_secret' => env('API_SECRET', ''),
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('companies', function (Blueprint $table) {
|
||||||
|
$table->boolean('convert_payment_currency')->default(false);
|
||||||
|
$table->boolean('convert_expense_currency')->default(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
@ -7,10 +7,12 @@
|
|||||||
{{ $subscription->name }}
|
{{ $subscription->name }}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<form wire:submit.prevent="submit">
|
||||||
|
|
||||||
<!-- Recurring Plan Products-->
|
<!-- Recurring Plan Products-->
|
||||||
<ul role="list" class="-my-6 divide-y divide-gray-200">
|
<ul role="list" class="-my-6 divide-y divide-gray-200">
|
||||||
@if(!empty($subscription->recurring_product_ids))
|
@if(!empty($subscription->recurring_product_ids))
|
||||||
@foreach($subscription->service()->recurring_products() as $index => $product)
|
@foreach($recurring_products as $index => $product)
|
||||||
<li class="flex py-6">
|
<li class="flex py-6">
|
||||||
@if(false)
|
@if(false)
|
||||||
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200">
|
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200">
|
||||||
@ -32,18 +34,11 @@
|
|||||||
<p class="text-gray-500 w-full"></p>
|
<p class="text-gray-500 w-full"></p>
|
||||||
<div class="flex place-content-end">
|
<div class="flex place-content-end">
|
||||||
<p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p>
|
<p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p>
|
||||||
<input wire:model="data.{{ $index }}.recurring_qty" type="text" class="w-1/4 rounded-md border-gray-300 shadow-sm sm:text-sm text-center" placeholder="0"/>
|
<input wire:model.debounce.300ms="data.{{ $index }}.recurring_qty" type="text" class="w-1/4 rounded-md border-gray-300 shadow-sm sm:text-sm text-center" placeholder="0"/>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
{{ isset($data[$index]['recurring_qty']) ? $data[$index]['recurring_qty'] : 'merp' }}
|
@error("data.{$index}.recurring_qty")
|
||||||
|
|
||||||
@if($errors)
|
|
||||||
@foreach($errors as $error)
|
|
||||||
{{ $error }}
|
|
||||||
@endforeach
|
|
||||||
@endif
|
|
||||||
@error('data.{{$index}}.recurring_qty')
|
|
||||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
|
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
|
||||||
<span class="block sm:inline">{{ $message }} </span>
|
<span class="block sm:inline">{{ $message }} </span>
|
||||||
<span class="absolute top-0 bottom-0 right-0 px-4 py-3">
|
<span class="absolute top-0 bottom-0 right-0 px-4 py-3">
|
||||||
@ -55,7 +50,7 @@
|
|||||||
@endif
|
@endif
|
||||||
<!-- One Time Plan Products-->
|
<!-- One Time Plan Products-->
|
||||||
@if(!empty($subscription->product_ids))
|
@if(!empty($subscription->product_ids))
|
||||||
@foreach($subscription->service()->products() as $product)
|
@foreach($products as $product)
|
||||||
<li class="flex py-6">
|
<li class="flex py-6">
|
||||||
@if(false)
|
@if(false)
|
||||||
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200">
|
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200">
|
||||||
@ -93,7 +88,7 @@
|
|||||||
<!-- Optional Recurring Products-->
|
<!-- Optional Recurring Products-->
|
||||||
<ul role="list" class="-my-6 divide-y divide-gray-200">
|
<ul role="list" class="-my-6 divide-y divide-gray-200">
|
||||||
@if(!empty($subscription->optional_recurring_product_ids))
|
@if(!empty($subscription->optional_recurring_product_ids))
|
||||||
@foreach($subscription->service()->optional_recurring_products() as $index => $product)
|
@foreach($optional_recurring_products as $index => $product)
|
||||||
<li class="flex py-6">
|
<li class="flex py-6">
|
||||||
@if(false)
|
@if(false)
|
||||||
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200 mr-2">
|
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200 mr-2">
|
||||||
@ -104,7 +99,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between text-base font-medium text-gray-900">
|
<div class="flex justify-between text-base font-medium text-gray-900">
|
||||||
<h3>{!! nl2br($product->notes) !!}</h3>
|
<h3>{!! nl2br($product->notes) !!}</h3>
|
||||||
<p class="ml-0">{{ \App\Utils\Number::formatMoney($product->price, $subscription->company) }}</p>
|
<p class="ml-0">{{ \App\Utils\Number::formatMoney($product->price, $subscription->company) }} </p>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-1 text-sm text-gray-500"></p>
|
<p class="mt-1 text-sm text-gray-500"></p>
|
||||||
</div>
|
</div>
|
||||||
@ -112,21 +107,22 @@
|
|||||||
<p class="text-gray-500 w-full"></p>
|
<p class="text-gray-500 w-full"></p>
|
||||||
<div class="flex place-content-end">
|
<div class="flex place-content-end">
|
||||||
<p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p>
|
<p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p>
|
||||||
<input wire:model="data.{{ $index }}.optional_recurring_qty" type="text" class="w-1/4 rounded-md border-gray-300 shadow-sm sm:text-sm text-center" placeholder="0"/>
|
<input wire:model.debounce.300ms="data.{{ $index }}.optional_recurring_qty" type="text" class="w-1/4 rounded-md border-gray-300 shadow-sm sm:text-sm text-center" placeholder="0"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@error("data.{$index}.optional_recurring_qty")
|
||||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
|
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
|
||||||
<span class="block sm:inline">{{ isset($data[$index]['optional_recurring_qty']) ? $data[$index]['optional_recurring_qty'] : '' }}</span>
|
<span class="block sm:inline">{{ $message }} </span>
|
||||||
<span class="absolute top-0 bottom-0 right-0 px-4 py-3">
|
<span class="absolute top-0 bottom-0 right-0 px-4 py-3">
|
||||||
</div>
|
</div>
|
||||||
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
@endif
|
@endif
|
||||||
@if(!empty($subscription->optional_product_ids))
|
@if(!empty($subscription->optional_product_ids))
|
||||||
@foreach($subscription->service()->optional_products() as $index => $product)
|
@foreach($optional_products as $index => $product)
|
||||||
<li class="flex py-6">
|
<li class="flex py-6">
|
||||||
@if(false)
|
@if(false)
|
||||||
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200 mr-2">
|
<div class="h-24 w-24 flex-shrink-0 overflow-hidden rounded-md border border-gray-200 mr-2">
|
||||||
@ -145,13 +141,15 @@
|
|||||||
<p class="text-gray-500 w-full"></p>
|
<p class="text-gray-500 w-full"></p>
|
||||||
<div class="flex place-content-end">
|
<div class="flex place-content-end">
|
||||||
<p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p>
|
<p class="text-sm font-light text-gray-700 text-right mr-2 mt-2">{{ ctrans('texts.qty') }}</p>
|
||||||
<input type="text" wire:model="data.{{ $index }}.optional_qty" class="w-1/4 rounded-md border-gray-300 shadow-sm sm:text-sm text-center" placeholder="0">
|
<input type="text" wire:model.debounce.300ms="data.{{ $index }}.optional_qty" class="w-1/4 rounded-md border-gray-300 shadow-sm sm:text-sm text-center" placeholder="0">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@error("data.{$index}.optional_qty")
|
||||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
|
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
|
||||||
<span class="block sm:inline">{{ isset($data[$index]['optional_qty']) ? $data[$index]['optional_qty'] : '' }}</span>
|
<span class="block sm:inline">{{ $message }} </span>
|
||||||
<span class="absolute top-0 bottom-0 right-0 px-4 py-3">
|
<span class="absolute top-0 bottom-0 right-0 px-4 py-3">
|
||||||
</div>
|
</div>
|
||||||
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
@ -160,27 +158,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
<div class="col-span-4 bg-blue-500 flex flex-col item-center p-2 h-screen">
|
<div class="col-span-4 bg-blue-500 flex flex-col item-center p-2 h-screen" wire:init="buildBundle">
|
||||||
<div class="w-full p-4">
|
<div class="w-full p-4">
|
||||||
<div id="summary" class="px-4 text-white">
|
<div id="summary" class="px-4 text-white">
|
||||||
<h1 class="font-semibold text-2xl border-b-2 border-gray-200 border-opacity-50 pb-2 text-white">{{ ctrans('texts.order') }}</h1>
|
<h1 class="font-semibold text-2xl border-b-2 border-gray-200 border-opacity-50 pb-2 text-white">{{ ctrans('texts.order') }}</h1>
|
||||||
|
|
||||||
@foreach($subscription->service()->recurring_products() as $product)
|
@foreach($bundle as $item)
|
||||||
<div class="flex justify-between mt-1 mb-1">
|
<div class="flex justify-between mt-1 mb-1">
|
||||||
<span class="font-light text-sm uppercase">{!! nl2br(substr($product->notes, 0, 50)) !!}</span>
|
<span class="font-light text-sm uppercase">{{$item['product']}} x {{$item['qty']}}</span>
|
||||||
<span class="font-semibold text-sm">{{ \App\Utils\Number::formatMoney($product->price, $subscription->company) }}</span>
|
<span class="font-semibold text-sm">{{ $item['price'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
@foreach($subscription->service()->products() as $product)
|
|
||||||
<div class="flex justify-between mt-1 mb-1">
|
|
||||||
<span class="font-light text-sm uppercase">{!! nl2br(substr($product->notes, 0, 50)) !!}</span>
|
|
||||||
<span class="font-semibold text-sm">{{ \App\Utils\Number::formatMoney($product->price, $subscription->company) }}</span>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
|
|
||||||
@if(!empty($subscription->promo_code) && !$subscription->trial_enabled)
|
@if(!empty($subscription->promo_code) && !$subscription->trial_enabled)
|
||||||
<form wire:submit.prevent="handleCoupon" class="">
|
<form wire:submit.prevent="handleCoupon" class="">
|
||||||
@csrf
|
@csrf
|
||||||
@ -190,7 +181,7 @@
|
|||||||
<div class="relative flex flex-grow items-stretch focus-within:z-10">
|
<div class="relative flex flex-grow items-stretch focus-within:z-10">
|
||||||
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||||
</div>
|
</div>
|
||||||
<input type="text" wire:model.defer="coupon" class="block w-full rounded-none rounded-l-md border-gray-300 pl-10 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="">
|
<input type="text" wire:model.debounce.300ms="coupon" class="block w-full rounded-none rounded-l-md border-gray-300 pl-10 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="">
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="relative -ml-px inline-flex items-center space-x-2 rounded-r-md border border-gray-300 bg-gray-50 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
<button type="button" class="relative -ml-px inline-flex items-center space-x-2 rounded-r-md border border-gray-300 bg-gray-50 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
|
||||||
|
|
||||||
@ -204,7 +195,7 @@
|
|||||||
<div class="border-t-2 border-gray-200 border-opacity-50 mt-8">
|
<div class="border-t-2 border-gray-200 border-opacity-50 mt-8">
|
||||||
<div class="flex font-semibold justify-between py-6 text-sm uppercase">
|
<div class="flex font-semibold justify-between py-6 text-sm uppercase">
|
||||||
<span>{{ ctrans('texts.total') }}</span>
|
<span>{{ ctrans('texts.total') }}</span>
|
||||||
<span>{{ \App\Utils\Number::formatMoney($price, $subscription->company) }}</span>
|
<span>{{ $total }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="bg-white font-semibold hover:bg-gray-600 py-3 text-sm text-blue-500 uppercase w-full">Checkout</button>
|
<button class="bg-white font-semibold hover:bg-gray-600 py-3 text-sm text-blue-500 uppercase w-full">Checkout</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
<input type="checkbox" class="form-checkbox cursor-pointer" onchange="appendToElement('multiple-downloads', '{{ $document->hashed_id }}')" />
|
<input type="checkbox" class="form-checkbox cursor-pointer" onchange="appendToElement('multiple-downloads', '{{ $document->hashed_id }}')" />
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-nowrap text-sm leading-5 text-gray-500">
|
||||||
{{ Illuminate\Support\Str::limit($document->name, 20) }}
|
{{ Illuminate\Support\Str::limit($document->name, 40) }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm leading-5 text-gray-500">
|
<td class="px-6 py-4 whitespace-nowrap text-sm leading-5 text-gray-500">
|
||||||
|
Loading…
Reference in New Issue
Block a user