diff --git a/app/Http/Livewire/BillingPortalPurchasev2.php b/app/Http/Livewire/BillingPortalPurchasev2.php index cd4e255b43..92da5b55b0 100644 --- a/app/Http/Livewire/BillingPortalPurchasev2.php +++ b/app/Http/Livewire/BillingPortalPurchasev2.php @@ -196,6 +196,7 @@ class BillingPortalPurchasev2 extends Component public $float_amount_total; public $payment_started = false; public $valid_coupon = false; + public $payable_invoices = []; public function mount() { @@ -310,12 +311,13 @@ class BillingPortalPurchasev2 extends Component { if($this->coupon == $this->subscription->promo_code) { - $this->buildBundle(); $this->valid_coupon = true; + $this->buildBundle(); } else{ $this->discount = 0; $this->valid_coupon = false; + $this->buildBundle(); } } @@ -378,24 +380,24 @@ class BillingPortalPurchasev2 extends Component return $k == $key; }); - $qty = isset($this->data[$key]['optional_recurring_qty']) ? $this->data[$key]['optional_recurring_qty'] : 0; + $qty = isset($this->data[$key]['optional_recurring_qty']) ? $this->data[$key]['optional_recurring_qty'] : false; $total = $p->price * $qty; - if($qty == 0) - return; + if($qty) + { + $this->bundle->push([ + 'description' => $p->notes, + 'product_key' => $p->product_key, + 'unit_cost' => $p->price, + '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 + ]); - $this->bundle->push([ - 'description' => $p->notes, - 'product_key' => $p->product_key, - 'unit_cost' => $p->price, - '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 - ]); - + } } /* Optional products can have a variable quantity */ @@ -405,23 +407,23 @@ class BillingPortalPurchasev2 extends Component return $k == $key; }); - $qty = isset($this->data[$key]['optional_qty']) ? $this->data[$key]['optional_qty'] : 0; + $qty = isset($this->data[$key]['optional_qty']) ? $this->data[$key]['optional_qty'] : false; $total = $p->price * $qty; - if($qty == 0) - return; - - $this->bundle->push([ - 'description' => $p->notes, - 'product_key' => $p->product_key, - 'unit_cost' => $p->price, - 'product' => nl2br(substr($p->notes, 0, 50)), - 'price' => Number::formatMoney($total, $this->subscription->company), - 'total' => $total, - 'qty' => $qty, - 'is_recurring' => false - ]); - + if($qty) + { + $this->bundle->push([ + 'description' => $p->notes, + 'product_key' => $p->product_key, + 'unit_cost' => $p->price, + 'product' => nl2br(substr($p->notes, 0, 50)), + 'price' => Number::formatMoney($total, $this->subscription->company), + 'total' => $total, + 'qty' => $qty, + 'is_recurring' => false + ]); + } + } } @@ -429,7 +431,7 @@ class BillingPortalPurchasev2 extends Component $this->sub_total = Number::formatMoney($this->bundle->sum('total'), $this->subscription->company); $this->total = $this->sub_total; - if($this->coupon == $this->subscription->promo_code) + if($this->valid_coupon) { if($this->subscription->is_amount_discount) @@ -443,6 +445,11 @@ class BillingPortalPurchasev2 extends Component $this->float_amount_total = ($this->bundle->sum('total') - $discount); } + else { + $this->float_amount_total = $this->bundle->sum('total'); + $this->total = Number::formatMoney($this->float_amount_total, $this->subscription->company); + + } return $this; @@ -490,7 +497,6 @@ class BillingPortalPurchasev2 extends Component */ protected function getPaymentMethods(): self { - $this->methods = $this->contact->client->service()->getPaymentMethods($this->float_amount_total); return $this; @@ -505,6 +511,7 @@ class BillingPortalPurchasev2 extends Component */ public function handleMethodSelectingEvent($company_gateway_id, $gateway_type_id) { + $this->company_gateway_id = $company_gateway_id; $this->payment_method_id = $gateway_type_id; @@ -546,19 +553,20 @@ class BillingPortalPurchasev2 extends Component ->service() ->createInvoiceV2($this->bundle, $this->contact->client_id, $this->valid_coupon) ->service() - // ->markSent() + ->markSent() ->fillDefaults() ->adjustInventory() ->save(); - // Cache::put($this->hash, [ - // 'subscription_id' => $this->subscription->id, - // 'email' => $this->email ?? $this->contact->email, - // 'client_id' => $this->contact->client->id, - // 'invoice_id' => $this->invoice->id, - // 'context' => 'purchase', - // 'campaign' => $this->campaign, - // ], now()->addMinutes(60)); + Cache::put($this->hash, [ + 'subscription_id' => $this->subscription->id, + 'email' => $this->email ?? $this->contact->email, + 'client_id' => $this->contact->client->id, + 'invoice_id' => $this->invoice->id, + 'context' => 'purchase', + 'campaign' => $this->campaign, + 'bundle' => $this->bundle, + ], now()->addMinutes(60)); $this->emit('beforePaymentEventsCompleted'); } diff --git a/app/Jobs/Product/UpdateOrCreateProduct.php b/app/Jobs/Product/UpdateOrCreateProduct.php index eff3edd8ff..a614820441 100644 --- a/app/Jobs/Product/UpdateOrCreateProduct.php +++ b/app/Jobs/Product/UpdateOrCreateProduct.php @@ -112,10 +112,19 @@ class UpdateOrCreateProduct implements ShouldQueue $product->tax_rate2 = isset($item->tax_rate2) ? $item->tax_rate2 : 0; $product->tax_name3 = isset($item->tax_name3) ? $item->tax_name3 : ''; $product->tax_rate3 = isset($item->tax_rate3) ? $item->tax_rate3 : 0; - $product->custom_value1 = isset($item->custom_value1) ? $item->custom_value1 : ''; - $product->custom_value2 = isset($item->custom_value2) ? $item->custom_value2 : ''; - $product->custom_value3 = isset($item->custom_value3) ? $item->custom_value3 : ''; - $product->custom_value4 = isset($item->custom_value4) ? $item->custom_value4 : ''; + + if(isset($item->custom_value1) && strlen($item->custom_value1) >=1) + $product->custom_value1 = $item->custom_value1; + + if(isset($item->custom_value2) && strlen($item->custom_value1) >=1) + $product->custom_value2 = $item->custom_value2; + + if(isset($item->custom_value3) && strlen($item->custom_value1) >=1) + $product->custom_value3 = $item->custom_value3; + + if(isset($item->custom_value4) && strlen($item->custom_value1) >=1) + $product->custom_value4 = $item->custom_value4; + $product->user_id = $this->invoice->user_id; $product->company_id = $this->invoice->company_id; $product->project_id = $this->invoice->project_id; diff --git a/app/Repositories/SubscriptionRepository.php b/app/Repositories/SubscriptionRepository.php index ed0a9d1138..8e1995b72d 100644 --- a/app/Repositories/SubscriptionRepository.php +++ b/app/Repositories/SubscriptionRepository.php @@ -118,6 +118,36 @@ class SubscriptionRepository extends BaseRepository return $line_items; } + public function generateBundleLineItems($bundle, $is_recurring = false, $is_credit = false) + { + $multiplier = $is_credit ? -1 : 1; + + $line_items = []; + + $line_items = collect($bundle)->filter(function ($item){ + + return $item->is_recurring; + + })->map(function ($item){ + + $line_item = new InvoiceItem; + $line_item->product_key = $item->product_key; + $line_item->quantity = (float)$item->qty; + $line_item->cost = (float)$item->unit_cost; + $line_item->notes = $item->description; + + return $line_item; + + + })->toArray(); + + + $line_items = $this->cleanItems($line_items); + + return $line_items; + } + + private function makeLineItem($product, $multiplier) { $item = new InvoiceItem; diff --git a/app/Services/Subscription/SubscriptionService.php b/app/Services/Subscription/SubscriptionService.php index fbcef3d595..db3dd6f5ac 100644 --- a/app/Services/Subscription/SubscriptionService.php +++ b/app/Services/Subscription/SubscriptionService.php @@ -79,7 +79,11 @@ class SubscriptionService // if we have a recurring product - then generate a recurring invoice if(strlen($this->subscription->recurring_product_ids) >=1){ - $recurring_invoice = $this->convertInvoiceToRecurring($payment_hash->payment->client_id); + if(isset($payment_hash->data->billing_context->bundle)) + $recurring_invoice = $this->convertInvoiceToRecurringBundle($payment_hash->payment->client_id, $payment_hash->data->billing_context->bundle); + else + $recurring_invoice = $this->convertInvoiceToRecurring($payment_hash->payment->client_id); + $recurring_invoice_repo = new RecurringInvoiceRepository(); $recurring_invoice = $recurring_invoice_repo->save([], $recurring_invoice); @@ -718,18 +722,16 @@ class SubscriptionService $line_item = new InvoiceItem; $line_item->product_key = $item['product_key']; - $line_item->quantity = $item['qty']; - $line_item->cost = $item['unit_cost']; + $line_item->quantity = (float)$item['qty']; + $line_item->cost = (float)$item['unit_cost']; $line_item->notes = $item['description']; return $line_item; })->toArray(); -nlog($line_items); - $invoice->line_items = $line_items; - + if($valid_coupon){ $invoice->discount = $this->subscription->promo_discount; $invoice->is_amount_discount = $this->subscription->is_amount_discount; @@ -803,6 +805,41 @@ nlog($line_items); return $recurring_invoice; } + + /** + * Generates a recurring invoice based on + * the specifications of the subscription USING BUNDLE + * + * @param int $client_id The Client Id + * @return RecurringInvoice + */ + public function convertInvoiceToRecurringBundle($client_id, $bundle) :RecurringInvoice + { + MultiDB::setDb($this->subscription->company->db); + + $client = Client::withTrashed()->find($client_id); + + $subscription_repo = new SubscriptionRepository(); + + $recurring_invoice = RecurringInvoiceFactory::create($this->subscription->company_id, $this->subscription->user_id); + $recurring_invoice->client_id = $client_id; + $recurring_invoice->line_items = $subscription_repo->generateBundleLineItems($bundle, true, false); + $recurring_invoice->subscription_id = $this->subscription->id; + $recurring_invoice->frequency_id = $this->subscription->frequency_id ?: RecurringInvoice::FREQUENCY_MONTHLY; + $recurring_invoice->date = now(); + $recurring_invoice->remaining_cycles = -1; + $recurring_invoice->auto_bill = $client->getSetting('auto_bill'); + $recurring_invoice->auto_bill_enabled = $this->setAutoBillFlag($recurring_invoice->auto_bill); + $recurring_invoice->due_date_days = 'terms'; + $recurring_invoice->next_send_date = now()->format('Y-m-d'); + $recurring_invoice->next_send_date_client = now()->format('Y-m-d'); + $recurring_invoice->next_send_date = $recurring_invoice->nextSendDate(); + $recurring_invoice->next_send_date_client = $recurring_invoice->nextSendDateClient(); + + return $recurring_invoice; + } + + private function setAutoBillFlag($auto_bill) { if ($auto_bill == 'always' || $auto_bill == 'optout') { diff --git a/lang/en/texts.php b/lang/en/texts.php index 537a539db9..e64bc61fab 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -4902,7 +4902,11 @@ $LANG = array( 'delete_tax_rate' => 'Delete Tax Rate', 'restore_tax_rate' => 'Restore Tax Rate', 'company_backup_file' => 'Select company backup file', - 'company_backup_file_help' => 'Please upload the .zip file used to create this backup.' + 'company_backup_file_help' => 'Please upload the .zip file used to create this backup.', + 'backup_restore' => 'Backup | Restore', + 'export_company' => 'Create company backup', + 'backup' => 'Backup', + ); return $LANG; diff --git a/resources/views/portal/ninja2020/components/livewire/billing-portal-purchasev2.blade.php b/resources/views/portal/ninja2020/components/livewire/billing-portal-purchasev2.blade.php index 2c0aae8c4c..251829679d 100644 --- a/resources/views/portal/ninja2020/components/livewire/billing-portal-purchasev2.blade.php +++ b/resources/views/portal/ninja2020/components/livewire/billing-portal-purchasev2.blade.php @@ -25,8 +25,8 @@ @endif - - + + @endif @@ -261,7 +261,7 @@ {{ session('message') }} @endcomponent @endif - @if(count($methods) > 0 && !$payment_started) + @if(count($methods) > 0)