1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-15 23:52:33 +01:00
invoiceninja/app/Repositories/SubscriptionRepository.php

227 lines
7.1 KiB
PHP
Raw Normal View History

<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
2024-04-12 06:15:41 +02:00
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
*
2021-06-16 08:58:16 +02:00
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Repositories;
2021-06-24 13:26:14 +02:00
use App\DataMapper\ClientSettings;
use App\DataMapper\InvoiceItem;
2021-03-26 21:28:56 +01:00
use App\Factory\InvoiceFactory;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Models\Subscription;
2021-03-26 21:28:56 +01:00
use App\Utils\Traits\CleanLineItems;
use Illuminate\Support\Facades\DB;
2024-01-14 02:34:40 +01:00
use Illuminate\Support\Str;
class SubscriptionRepository extends BaseRepository
{
2021-03-26 21:28:56 +01:00
use CleanLineItems;
2022-07-06 09:12:29 +02:00
public int $quantity = 1;
public function save($data, Subscription $subscription): ?Subscription
{
2021-03-26 21:28:56 +01:00
$subscription->fill($data);
2021-03-27 04:22:19 +01:00
$calculated_prices = $this->calculatePrice($subscription);
$subscription->price = $calculated_prices['price'];
$subscription->promo_price = $calculated_prices['promo_price'];
2021-03-26 21:28:56 +01:00
$subscription->save();
return $subscription;
}
2021-03-26 21:28:56 +01:00
2024-01-14 05:05:00 +01:00
private function calculatePrice($subscription): array
2021-03-26 21:28:56 +01:00
{
// DB::beginTransaction();
DB::connection(config('database.default'))->beginTransaction();
$data = [];
2021-03-26 21:28:56 +01:00
2023-08-03 00:24:30 +02:00
/** @var \App\Models\Client $client **/
2021-03-26 21:28:56 +01:00
$client = Client::factory()->create([
'user_id' => $subscription->user_id,
'company_id' => $subscription->company_id,
'group_settings_id' => $subscription->group_id,
'country_id' => $subscription->company->settings->country_id,
'settings' => ClientSettings::defaults(),
]);
2021-03-26 21:28:56 +01:00
2023-08-03 00:24:30 +02:00
/** @var \App\Models\ClientContact $contact **/
2021-03-26 21:28:56 +01:00
$contact = ClientContact::factory()->create([
'user_id' => $subscription->user_id,
'company_id' => $subscription->company_id,
'client_id' => $client->id,
'is_primary' => 1,
'send_email' => true,
]);
2021-03-26 21:28:56 +01:00
$invoice = InvoiceFactory::create($subscription->company_id, $subscription->user_id);
2021-03-27 04:22:19 +01:00
$invoice->client_id = $client->id;
$invoice->save();
2021-03-26 21:28:56 +01:00
$invitation = InvoiceInvitation::factory()->create([
'user_id' => $subscription->user_id,
'company_id' => $subscription->company_id,
'invoice_id' => $invoice->id,
'client_contact_id' => $contact->id,
2021-03-26 21:28:56 +01:00
]);
$invoice->setRelation('invitations', $invitation);
$invoice->setRelation('client', $client);
$invoice->setRelation('company', $subscription->company);
$invoice->load('client');
$invoice->line_items = $this->generateLineItems($subscription);
2021-03-27 04:22:19 +01:00
2021-03-26 21:28:56 +01:00
$data['price'] = $invoice->calc()->getTotal();
2021-03-26 21:28:56 +01:00
$invoice->discount = $subscription->promo_discount;
$invoice->is_amount_discount = $subscription->is_amount_discount;
$data['promo_price'] = $invoice->calc()->getTotal();
// DB::rollBack();
DB::connection(config('database.default'))->rollBack();
2021-03-26 21:28:56 +01:00
return $data;
}
2021-06-27 13:55:15 +02:00
public function generateLineItems($subscription, $is_recurring = false, $is_credit = false)
2021-03-26 21:28:56 +01:00
{
2021-06-27 13:55:15 +02:00
$multiplier = $is_credit ? -1 : 1;
2021-03-26 21:28:56 +01:00
$line_items = [];
2021-03-26 21:28:56 +01:00
if (! $is_recurring) {
foreach ($subscription->service()->products() as $product) {
$line_items[] = (array) $this->makeLineItem($product, $multiplier);
2021-03-29 04:14:55 +02:00
}
}
foreach ($subscription->service()->recurring_products() as $product) {
$line_items[] = (array) $this->makeLineItem($product, $multiplier);
}
$line_items = $this->cleanItems($line_items);
2021-03-26 21:28:56 +01:00
return $line_items;
2021-03-26 21:28:56 +01:00
}
/**
* 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;
}
2021-03-26 21:28:56 +01:00
2022-12-15 02:16:50 +01:00
public function generateBundleLineItems($bundle, $is_recurring = false, $is_credit = false)
{
if(isset($bundle->recurring_products))
$bundle = $this->convertV3Bundle($bundle);
2022-12-15 02:16:50 +01:00
$multiplier = $is_credit ? -1 : 1;
$line_items = [];
2023-02-16 02:36:09 +01:00
$line_items = collect($bundle)->filter(function ($item) {
2024-02-20 23:13:40 +01:00
return $item->is_recurring ?? false;
2023-02-16 02:36:09 +01:00
})->map(function ($item) {
2024-01-14 05:05:00 +01:00
$line_item = new InvoiceItem();
2023-02-16 02:36:09 +01:00
$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;
2022-12-15 02:16:50 +01:00
})->toArray();
$line_items = $this->cleanItems($line_items);
return $line_items;
}
2021-06-27 13:55:15 +02:00
private function makeLineItem($product, $multiplier)
{
2024-01-14 05:05:00 +01:00
$item = new InvoiceItem();
2022-07-06 09:12:29 +02:00
$item->quantity = $this->quantity;
$item->product_key = $product->product_key;
$item->notes = $product->notes;
$item->cost = $product->price * $multiplier;
$item->tax_rate1 = $product->tax_rate1 ?: 0;
$item->tax_name1 = $product->tax_name1 ?: '';
$item->tax_rate2 = $product->tax_rate2 ?: 0;
$item->tax_name2 = $product->tax_name2 ?: '';
$item->tax_rate3 = $product->tax_rate3 ?: 0;
$item->tax_name3 = $product->tax_name3 ?: '';
$item->custom_value1 = $product->custom_value1 ?: '';
$item->custom_value2 = $product->custom_value2 ?: '';
$item->custom_value3 = $product->custom_value3 ?: '';
$item->custom_value4 = $product->custom_value4 ?: '';
return $item;
}
2024-01-14 02:34:40 +01:00
public function assign_invoice(Subscription $subscription, $request)
{
$class = "\\App\\Models\\".ucfirst(Str::camel($request->entity));
$entity = $class::withTrashed()->find($request->entity_id);
2024-01-14 05:05:00 +01:00
if($entity) {
2024-01-14 02:34:40 +01:00
$entity->subscription_id = $subscription->id;
$entity->save();
}
2024-01-14 05:05:00 +01:00
2024-01-14 02:34:40 +01:00
return $subscription;
}
}