mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge branch 'v5-develop' of https://github.com/turbo124/invoiceninja into v5-develop
This commit is contained in:
commit
3884f0bc78
40
app/Factory/CloneQuoteToProjectFactory.php
Normal file
40
app/Factory/CloneQuoteToProjectFactory.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Project Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Project Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Factory;
|
||||||
|
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Models\Quote;
|
||||||
|
|
||||||
|
class CloneQuoteToProjectFactory
|
||||||
|
{
|
||||||
|
public static function create(Quote $quote, $user_id) : ?Project
|
||||||
|
{
|
||||||
|
$project = new Project();
|
||||||
|
|
||||||
|
$project->company_id = $quote->company_id;
|
||||||
|
$project->user_id = $user_id;
|
||||||
|
$project->client_id = $quote->client_id;
|
||||||
|
|
||||||
|
$project->public_notes = $quote->public_notes;
|
||||||
|
$project->private_notes = $quote->private_notes;
|
||||||
|
$project->budgeted_hours = 0;
|
||||||
|
$project->task_rate = 0;
|
||||||
|
$project->name = ctrans('texts.quote_number_short') . " " . $quote->number;
|
||||||
|
$project->custom_value1 = '';
|
||||||
|
$project->custom_value2 = '';
|
||||||
|
$project->custom_value3 = '';
|
||||||
|
$project->custom_value4 = '';
|
||||||
|
$project->is_deleted = 0;
|
||||||
|
|
||||||
|
return $project;
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ use App\Events\Quote\QuoteWasCreated;
|
|||||||
use App\Events\Quote\QuoteWasUpdated;
|
use App\Events\Quote\QuoteWasUpdated;
|
||||||
use App\Factory\CloneQuoteFactory;
|
use App\Factory\CloneQuoteFactory;
|
||||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||||
|
use App\Factory\CloneQuoteToProjectFactory;
|
||||||
use App\Factory\QuoteFactory;
|
use App\Factory\QuoteFactory;
|
||||||
use App\Filters\QuoteFilters;
|
use App\Filters\QuoteFilters;
|
||||||
use App\Http\Requests\Quote\ActionQuoteRequest;
|
use App\Http\Requests\Quote\ActionQuoteRequest;
|
||||||
@ -31,12 +32,15 @@ use App\Jobs\Quote\ZipQuotes;
|
|||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Repositories\QuoteRepository;
|
use App\Repositories\QuoteRepository;
|
||||||
use App\Transformers\InvoiceTransformer;
|
use App\Transformers\InvoiceTransformer;
|
||||||
|
use App\Transformers\ProjectTransformer;
|
||||||
use App\Transformers\QuoteTransformer;
|
use App\Transformers\QuoteTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\TempFile;
|
use App\Utils\TempFile;
|
||||||
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Utils\Traits\SavesDocuments;
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@ -50,6 +54,7 @@ class QuoteController extends BaseController
|
|||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
use SavesDocuments;
|
use SavesDocuments;
|
||||||
|
use GeneratesCounter;
|
||||||
|
|
||||||
protected $entity_type = Quote::class;
|
protected $entity_type = Quote::class;
|
||||||
|
|
||||||
@ -556,6 +561,28 @@ class QuoteController extends BaseController
|
|||||||
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($action == 'convert_to_project')
|
||||||
|
{
|
||||||
|
|
||||||
|
$quotes->each(function ($quote, $key) use ($action) {
|
||||||
|
if (auth()->user()->can('edit', $quote))
|
||||||
|
{
|
||||||
|
$project = CloneQuoteToProjectFactory::create($quote, auth()->user()->id);
|
||||||
|
|
||||||
|
if (empty($project->number)) {
|
||||||
|
$project->number = $this->getNextProjectNumber($project);
|
||||||
|
|
||||||
|
}
|
||||||
|
$project->save();
|
||||||
|
$quote->project_id = $project->id;
|
||||||
|
$quote->save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the other actions to the switch
|
* Send the other actions to the switch
|
||||||
*/
|
*/
|
||||||
@ -661,6 +688,7 @@ class QuoteController extends BaseController
|
|||||||
return $this->itemResponse($quote->service()->convertToInvoice());
|
return $this->itemResponse($quote->service()->convertToInvoice());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'clone_to_invoice':
|
case 'clone_to_invoice':
|
||||||
|
|
||||||
$this->entity_type = Invoice::class;
|
$this->entity_type = Invoice::class;
|
||||||
|
@ -265,6 +265,9 @@ class BillingPortalPurchase extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nlog($this->subscription->group_settings->settings);
|
||||||
|
// nlog($this->subscription->group_settings->settings->currency_id);
|
||||||
|
|
||||||
if(array_key_exists('currency_id', $this->request_data)) {
|
if(array_key_exists('currency_id', $this->request_data)) {
|
||||||
|
|
||||||
$currency = Cache::get('currencies')->filter(function ($item){
|
$currency = Cache::get('currencies')->filter(function ($item){
|
||||||
@ -274,6 +277,16 @@ class BillingPortalPurchase extends Component
|
|||||||
if($currency)
|
if($currency)
|
||||||
$data['settings']->currency_id = $currency->id;
|
$data['settings']->currency_id = $currency->id;
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif($this->subscription->group_settings && property_exists($this->subscription->group_settings->settings, 'currency_id')) {
|
||||||
|
|
||||||
|
$currency = Cache::get('currencies')->filter(function ($item){
|
||||||
|
return $item->id == $this->subscription->group_settings->settings->currency_id;
|
||||||
|
})->first();
|
||||||
|
|
||||||
|
if($currency)
|
||||||
|
$data['settings']->currency_id = $currency->id;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('locale', $this->request_data)) {
|
if (array_key_exists('locale', $this->request_data)) {
|
||||||
|
@ -83,6 +83,11 @@ class Subscription extends BaseModel
|
|||||||
return $this->belongsTo(User::class)->withTrashed();
|
return $this->belongsTo(User::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function group_settings()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(GroupSetting::class, 'group_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
public function nextDateByInterval($date, $frequency_id)
|
public function nextDateByInterval($date, $frequency_id)
|
||||||
{
|
{
|
||||||
switch ($frequency_id) {
|
switch ($frequency_id) {
|
||||||
|
@ -47,14 +47,6 @@ class CreditCard
|
|||||||
return render('gateways.paytrace.authorize', $data);
|
return render('gateways.paytrace.authorize', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// +"success": true
|
|
||||||
// +"response_code": 160
|
|
||||||
// +"status_message": "The customer profile for PLS5U60OoLUfQXzcmtJYNefPA0gTthzT/11 was successfully created."
|
|
||||||
// +"customer_id": "PLS5U60OoLUfQXzcmtJYNefPA0gTthzT"
|
|
||||||
|
|
||||||
//if(!$response->success)
|
|
||||||
//handle failure
|
|
||||||
|
|
||||||
public function authorizeResponse($request)
|
public function authorizeResponse($request)
|
||||||
{
|
{
|
||||||
$data = $request->all();
|
$data = $request->all();
|
||||||
@ -64,27 +56,6 @@ class CreditCard
|
|||||||
return redirect()->route('client.payment_methods.index');
|
return redirect()->route('client.payment_methods.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
// "_token" => "Vl1xHflBYQt9YFSaNCPTJKlY5x3rwcFE9kvkw71I"
|
|
||||||
// "company_gateway_id" => "1"
|
|
||||||
// "HPF_Token" => "e484a92c-90ed-4468-ac4d-da66824c75de"
|
|
||||||
// "enc_key" => "zqz6HMHCXALWdX5hyBqrIbSwU7TBZ0FTjjLB3Cp0FQY="
|
|
||||||
// "amount" => "Amount"
|
|
||||||
// "q" => "/client/payment_methods"
|
|
||||||
// "method" => "1"
|
|
||||||
// ]
|
|
||||||
|
|
||||||
// "customer_id":"customer789",
|
|
||||||
// "hpf_token":"e369847e-3027-4174-9161-fa0d4e98d318",
|
|
||||||
// "enc_key":"lI785yOBMet4Rt9o4NLXEyV84WBU3tdStExcsfoaOoo=",
|
|
||||||
// "integrator_id":"xxxxxxxxxx",
|
|
||||||
// "billing_address":{
|
|
||||||
// "name":"Mark Smith",
|
|
||||||
// "street_address":"8320 E. West St.",
|
|
||||||
// "city":"Spokane",
|
|
||||||
// "state":"WA",
|
|
||||||
// "zip":"85284"
|
|
||||||
// }
|
|
||||||
|
|
||||||
private function createCustomer($data)
|
private function createCustomer($data)
|
||||||
{
|
{
|
||||||
$post_data = [
|
$post_data = [
|
||||||
@ -193,8 +164,6 @@ class CreditCard
|
|||||||
'invoice_id' => $this->harvestInvoiceId(),
|
'invoice_id' => $this->harvestInvoiceId(),
|
||||||
];
|
];
|
||||||
|
|
||||||
nlog($data);
|
|
||||||
|
|
||||||
$response = $this->paytrace->gatewayRequest('/v1/transactions/sale/pt_protect', $data);
|
$response = $this->paytrace->gatewayRequest('/v1/transactions/sale/pt_protect', $data);
|
||||||
|
|
||||||
if ($response->success) {
|
if ($response->success) {
|
||||||
|
@ -13,6 +13,7 @@ namespace Tests\Feature;
|
|||||||
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@ -49,6 +50,26 @@ class QuoteTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function testQuoteConvertToProject()
|
||||||
|
{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/quotes/bulk',['action' => 'convert_to_project', 'ids' => [$this->quote->hashed_id]]);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$res = $response->json();
|
||||||
|
|
||||||
|
$this->assertNotNull($res['data'][0]['project_id']);
|
||||||
|
|
||||||
|
$project = Project::find($this->decodePrimaryKey($res['data'][0]['project_id']));
|
||||||
|
|
||||||
|
$this->assertEquals($project->name, ctrans('texts.quote_number_short') . " " . $this->quote->number);
|
||||||
|
}
|
||||||
|
|
||||||
public function testQuoteList()
|
public function testQuoteList()
|
||||||
{
|
{
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
@ -139,4 +160,5 @@ class QuoteTest extends TestCase
|
|||||||
|
|
||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user