mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 20:22:42 +01:00
Fixes for wrong product types being used cost => price
This commit is contained in:
parent
42b111db58
commit
55d512b0a5
@ -23,7 +23,9 @@ class OptionalRecurringProducts extends Component
|
|||||||
|
|
||||||
public function quantity($id, $value): void
|
public function quantity($id, $value): void
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->dispatch('purchase.context', property: "bundle.optional_recurring_products.{$id}.quantity", value: $value);
|
$this->dispatch('purchase.context', property: "bundle.optional_recurring_products.{$id}.quantity", value: $value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(): \Illuminate\View\View
|
public function render(): \Illuminate\View\View
|
||||||
|
@ -73,8 +73,6 @@ class Methods extends Component
|
|||||||
? \App\Utils\Number::formatValue($invoice->partial, $invoice->client->currency())
|
? \App\Utils\Number::formatValue($invoice->partial, $invoice->client->currency())
|
||||||
: \App\Utils\Number::formatValue($invoice->balance, $invoice->client->currency());
|
: \App\Utils\Number::formatValue($invoice->balance, $invoice->client->currency());
|
||||||
|
|
||||||
nlog($invoice->toArray());
|
|
||||||
|
|
||||||
$this->dispatch('purchase.context', property: 'form.company_gateway_id', value: $company_gateway_id);
|
$this->dispatch('purchase.context', property: 'form.company_gateway_id', value: $company_gateway_id);
|
||||||
$this->dispatch('purchase.context', property: 'form.payment_method_id', value: $gateway_type_id);
|
$this->dispatch('purchase.context', property: 'form.payment_method_id', value: $gateway_type_id);
|
||||||
$this->dispatch('purchase.context', property: 'form.invoice_hashed_id', value: $invoice->hashed_id);
|
$this->dispatch('purchase.context', property: 'form.invoice_hashed_id', value: $invoice->hashed_id);
|
||||||
|
@ -161,6 +161,7 @@ class Purchase extends Component
|
|||||||
#[On('purchase.next')]
|
#[On('purchase.next')]
|
||||||
public function handleNext(): void
|
public function handleNext(): void
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($this->step < count($this->steps) - 1) {
|
if ($this->step < count($this->steps) - 1) {
|
||||||
$this->step++;
|
$this->step++;
|
||||||
}
|
}
|
||||||
|
@ -30,30 +30,34 @@ class RFF extends Component
|
|||||||
$validated = $this->validate([
|
$validated = $this->validate([
|
||||||
'contact_first_name' => ['required'],
|
'contact_first_name' => ['required'],
|
||||||
'contact_last_name' => ['required'],
|
'contact_last_name' => ['required'],
|
||||||
'contact_email' => ['required', 'email'],
|
// 'contact_email' => ['sometimes', 'email'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->contact = auth()->guard('contact')->user();
|
||||||
$this->contact->first_name = $validated['contact_first_name'];
|
$this->contact->first_name = $validated['contact_first_name'];
|
||||||
$this->contact->last_name = $validated['contact_last_name'];
|
$this->contact->last_name = $validated['contact_last_name'];
|
||||||
$this->contact->email = $validated['contact_email'];
|
|
||||||
$this->contact->save();
|
$this->contact->save();
|
||||||
|
|
||||||
|
$this->contact_first_name = $this->contact->first_name;
|
||||||
|
$this->contact_last_name = $this->contact->last_name;
|
||||||
|
$this->contact_email = $this->contact->email;
|
||||||
|
|
||||||
|
$this->dispatch('purchase.context', property: 'contact.first_name', value: $this->contact->first_name);
|
||||||
|
$this->dispatch('purchase.context', property: 'contact.last_name', value: $this->contact->last_name);
|
||||||
|
|
||||||
$this->dispatch('purchase.next');
|
$this->dispatch('purchase.next');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
if (auth()->guard('contact')->user()->showRff() === false) {
|
/** @var \App\Models\ClientContact $contact */
|
||||||
|
$contact = auth()->guard('contact')->user();
|
||||||
|
|
||||||
|
if ($contact->showRff() === false) {
|
||||||
$this->dispatch('purchase.next');
|
$this->dispatch('purchase.next');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->contact = auth()->guard('contact')->user();
|
|
||||||
|
|
||||||
$this->contact_first_name = $this->contact->first_name;
|
|
||||||
$this->contact_last_name = $this->contact->last_name;
|
|
||||||
$this->contact_email = $this->contact->email;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('billing-portal.v3.rff');
|
return view('billing-portal.v3.rff');
|
||||||
|
@ -40,6 +40,7 @@ class Summary extends Component
|
|||||||
'quantity' => $bundle['recurring_products'][$product->hashed_id]['quantity'] ?? 1,
|
'quantity' => $bundle['recurring_products'][$product->hashed_id]['quantity'] ?? 1,
|
||||||
'notes' => $product->markdownNotes(),
|
'notes' => $product->markdownNotes(),
|
||||||
];
|
];
|
||||||
|
$bundle['recurring_products'][$product->hashed_id]['product']['is_recurring'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->subscription->service()->products() as $key => $product) {
|
foreach ($this->subscription->service()->products() as $key => $product) {
|
||||||
@ -48,6 +49,7 @@ class Summary extends Component
|
|||||||
'quantity' => $bundle['one_time_products'][$product->hashed_id]['quantity'] ?? 1,
|
'quantity' => $bundle['one_time_products'][$product->hashed_id]['quantity'] ?? 1,
|
||||||
'notes' => $product->markdownNotes(),
|
'notes' => $product->markdownNotes(),
|
||||||
];
|
];
|
||||||
|
$bundle['one_time_products'][$product->hashed_id]['product']['is_recurring'] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->subscription->service()->optional_recurring_products() as $key => $product) {
|
foreach ($this->subscription->service()->optional_recurring_products() as $key => $product) {
|
||||||
@ -56,6 +58,7 @@ class Summary extends Component
|
|||||||
'quantity' => $bundle['optional_recurring_products'][$product->hashed_id]['quantity'] ?? 0,
|
'quantity' => $bundle['optional_recurring_products'][$product->hashed_id]['quantity'] ?? 0,
|
||||||
'notes' => $product->markdownNotes(),
|
'notes' => $product->markdownNotes(),
|
||||||
];
|
];
|
||||||
|
$bundle['optional_recurring_products'][$product->hashed_id]['product']['is_recurring'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->subscription->service()->optional_products() as $key => $product) {
|
foreach ($this->subscription->service()->optional_products() as $key => $product) {
|
||||||
@ -64,6 +67,7 @@ class Summary extends Component
|
|||||||
'quantity' => $bundle['optional_one_time_products'][$product->hashed_id]['quantity'] ?? 0,
|
'quantity' => $bundle['optional_one_time_products'][$product->hashed_id]['quantity'] ?? 0,
|
||||||
'notes' => $product->markdownNotes(),
|
'notes' => $product->markdownNotes(),
|
||||||
];
|
];
|
||||||
|
$bundle['optional_one_time_products'][$product->hashed_id]['product']['is_recurring'] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->dispatch('purchase.context', property: 'bundle', value: $bundle);
|
$this->dispatch('purchase.context', property: 'bundle', value: $bundle);
|
||||||
@ -76,11 +80,11 @@ class Summary extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$one_time = collect($this->context['bundle']['one_time_products'])->sum(function ($item) {
|
$one_time = collect($this->context['bundle']['one_time_products'])->sum(function ($item) {
|
||||||
return $item['product']['cost'] * $item['quantity'];
|
return $item['product']['price'] * $item['quantity'];
|
||||||
});
|
});
|
||||||
|
|
||||||
$one_time_optional = collect($this->context['bundle']['optional_one_time_products'])->sum(function ($item) {
|
$one_time_optional = collect($this->context['bundle']['optional_one_time_products'])->sum(function ($item) {
|
||||||
return $item['product']['cost'] * $item['quantity'];
|
return $item['product']['price'] * $item['quantity'];
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($raw) {
|
if ($raw) {
|
||||||
@ -98,11 +102,11 @@ class Summary extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$recurring = collect($this->context['bundle']['recurring_products'])->sum(function ($item) {
|
$recurring = collect($this->context['bundle']['recurring_products'])->sum(function ($item) {
|
||||||
return $item['product']['cost'] * $item['quantity'];
|
return $item['product']['price'] * $item['quantity'];
|
||||||
});
|
});
|
||||||
|
|
||||||
$recurring_optional = collect($this->context['bundle']['optional_recurring_products'])->sum(function ($item) {
|
$recurring_optional = collect($this->context['bundle']['optional_recurring_products'])->sum(function ($item) {
|
||||||
return $item['product']['cost'] * $item['quantity'];
|
return $item['product']['price'] * $item['quantity'];
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($raw) {
|
if ($raw) {
|
||||||
@ -140,8 +144,8 @@ class Summary extends Component
|
|||||||
$products[] = [
|
$products[] = [
|
||||||
'product_key' => $item['product']['product_key'],
|
'product_key' => $item['product']['product_key'],
|
||||||
'quantity' => $item['quantity'],
|
'quantity' => $item['quantity'],
|
||||||
'total_raw' => $item['product']['cost'] * $item['quantity'],
|
'total_raw' => $item['product']['price'] * $item['quantity'],
|
||||||
'total' => Number::formatMoney($item['product']['cost'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id),
|
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,8 +153,8 @@ class Summary extends Component
|
|||||||
$products[] = [
|
$products[] = [
|
||||||
'product_key' => $item['product']['product_key'],
|
'product_key' => $item['product']['product_key'],
|
||||||
'quantity' => $item['quantity'],
|
'quantity' => $item['quantity'],
|
||||||
'total_raw' => $item['product']['cost'] * $item['quantity'],
|
'total_raw' => $item['product']['price'] * $item['quantity'],
|
||||||
'total' => Number::formatMoney($item['product']['cost'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id),
|
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +162,8 @@ class Summary extends Component
|
|||||||
$products[] = [
|
$products[] = [
|
||||||
'product_key' => $item['product']['product_key'],
|
'product_key' => $item['product']['product_key'],
|
||||||
'quantity' => $item['quantity'],
|
'quantity' => $item['quantity'],
|
||||||
'total_raw' => $item['product']['cost'] * $item['quantity'],
|
'total_raw' => $item['product']['price'] * $item['quantity'],
|
||||||
'total' => Number::formatMoney($item['product']['cost'] * $item['quantity'], $this->subscription->company),
|
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,8 +171,8 @@ class Summary extends Component
|
|||||||
$products[] = [
|
$products[] = [
|
||||||
'product_key' => $item['product']['product_key'],
|
'product_key' => $item['product']['product_key'],
|
||||||
'quantity' => $item['quantity'],
|
'quantity' => $item['quantity'],
|
||||||
'total_raw' => $item['product']['cost'] * $item['quantity'],
|
'total_raw' => $item['product']['price'] * $item['quantity'],
|
||||||
'total' => Number::formatMoney($item['product']['cost'] * $item['quantity'], $this->subscription->company),
|
'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +118,54 @@ class SubscriptionRepository extends BaseRepository
|
|||||||
|
|
||||||
return $line_items;
|
return $line_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConvertV3Bundle
|
||||||
|
*
|
||||||
|
* Removing the nested keys of the items array
|
||||||
|
*
|
||||||
|
* @param array $bundle
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function convertV3Bundle($bundle): array
|
||||||
|
{
|
||||||
|
if(is_object($bundle))
|
||||||
|
$bundle = json_decode(json_encode($bundle),1);
|
||||||
|
|
||||||
|
$items = [];
|
||||||
|
|
||||||
|
foreach($bundle['recurring_products'] as $key => $value) {
|
||||||
|
|
||||||
|
$line_item = new \stdClass;
|
||||||
|
$line_item->product_key = $value['product']['product_key'];
|
||||||
|
$line_item->qty = (float) $value['quantity'];
|
||||||
|
$line_item->unit_cost = (float) $value['product']['price'];
|
||||||
|
$line_item->description = $value['product']['notes'];
|
||||||
|
$line_item->is_recurring = $value['product']['is_recurring'] ?? false;
|
||||||
|
$items[] = $line_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($bundle['recurring_products'] as $key => $value) {
|
||||||
|
|
||||||
|
$line_item = new \stdClass;
|
||||||
|
$line_item->product_key = $value['product']['product_key'];
|
||||||
|
$line_item->qty = (float) $value['quantity'];
|
||||||
|
$line_item->unit_cost = (float) $value['product']['price'];
|
||||||
|
$line_item->description = $value['product']['notes'];
|
||||||
|
$line_item->is_recurring = $value['product']['is_recurring'] ?? false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function generateBundleLineItems($bundle, $is_recurring = false, $is_credit = false)
|
public function generateBundleLineItems($bundle, $is_recurring = false, $is_credit = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(isset($bundle->recurring_products))
|
||||||
|
$bundle = $this->convertV3Bundle($bundle);
|
||||||
|
|
||||||
$multiplier = $is_credit ? -1 : 1;
|
$multiplier = $is_credit ? -1 : 1;
|
||||||
|
|
||||||
$line_items = [];
|
$line_items = [];
|
||||||
|
@ -71,21 +71,40 @@ class SubscriptionCalculator
|
|||||||
$recurring = array_merge(isset($bundle['recurring_products']) ? $bundle['recurring_products'] : [], isset($bundle['optional_recurring_products']) ? $bundle['optional_recurring_products'] : []);
|
$recurring = array_merge(isset($bundle['recurring_products']) ? $bundle['recurring_products'] : [], isset($bundle['optional_recurring_products']) ? $bundle['optional_recurring_products'] : []);
|
||||||
$one_time = array_merge(isset($bundle['one_time_products']) ? $bundle['one_time_products'] : [], isset($bundle['optional_one_time_products']) ? $bundle['optional_one_time_products'] : []);
|
$one_time = array_merge(isset($bundle['one_time_products']) ? $bundle['one_time_products'] : [], isset($bundle['optional_one_time_products']) ? $bundle['optional_one_time_products'] : []);
|
||||||
|
|
||||||
$items = array_filter(array_merge($recurring, $one_time), function ($product) {
|
$items = [];
|
||||||
return $product['quantity'] >= 1;
|
|
||||||
});
|
foreach($recurring as $item) {
|
||||||
|
|
||||||
|
if($item['quantity'] < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
return collect($items)->map(function ($item){
|
|
||||||
$line_item = new InvoiceItem();
|
$line_item = new InvoiceItem();
|
||||||
$line_item->product_key = $item['product']['product_key'];
|
$line_item->product_key = $item['product']['product_key'];
|
||||||
$line_item->quantity = (float) $item['quantity'];
|
$line_item->quantity = (float) $item['quantity'];
|
||||||
$line_item->cost = (float) $item['product']['price'];
|
$line_item->cost = (float) $item['product']['price'];
|
||||||
$line_item->notes = $item['product']['notes'];
|
$line_item->notes = $item['product']['notes'];
|
||||||
|
|
||||||
return $line_item;
|
$items[] = $line_item;
|
||||||
|
|
||||||
})->flatten()->toArray();
|
}
|
||||||
|
|
||||||
|
foreach($one_time as $item) {
|
||||||
|
|
||||||
|
if($item['quantity'] < 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$line_item = new InvoiceItem();
|
||||||
|
$line_item->product_key = $item['product']['product_key'];
|
||||||
|
$line_item->quantity = (float) $item['quantity'];
|
||||||
|
$line_item->cost = (float) $item['product']['price'];
|
||||||
|
$line_item->notes = $item['product']['notes'];
|
||||||
|
|
||||||
|
$items[] = $line_item;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div class="flex flex-col space-y-3 my-3">
|
<div class="flex flex-col space-y-3 my-3">
|
||||||
@foreach($methods as $method)
|
@foreach($methods as $method)
|
||||||
<button class="flex items-center justify-between mb-4 bg-white rounded px-6 py-4 shadow-sm border" wire:click="handleSelect('{{ $method['company_gateway_id'] }}', '{{ $method['gateway_type_id'] }}')">
|
<button class="flex items-center justify-between mb-4 bg-white rounded px-6 py-4 shadow-sm border" wire:click="handleSelect('{{ $method['company_gateway_id'] }}', '{{ $method['gateway_type_id'] }}'); $wire.$refresh();">
|
||||||
{{ $method['label'] }}
|
{{ $method['label'] }}
|
||||||
</button>
|
</button>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
Loading…
Reference in New Issue
Block a user