mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 21:22:58 +01:00
commit
3e1b983955
@ -834,7 +834,6 @@ class CompanySettings extends BaseSettings
|
||||
'$client.address1',
|
||||
'$client.address2',
|
||||
'$client.city_state_postal',
|
||||
'$client.postal_city',
|
||||
'$client.country',
|
||||
'$client.phone',
|
||||
'$contact.email',
|
||||
@ -846,7 +845,6 @@ class CompanySettings extends BaseSettings
|
||||
'$vendor.address1',
|
||||
'$vendor.address2',
|
||||
'$vendor.city_state_postal',
|
||||
'$vendor.postal_city',
|
||||
'$vendor.country',
|
||||
'$vendor.phone',
|
||||
'$contact.email',
|
||||
@ -871,7 +869,6 @@ class CompanySettings extends BaseSettings
|
||||
'$company.address1',
|
||||
'$company.address2',
|
||||
'$company.city_state_postal',
|
||||
'$company.postal_city',
|
||||
'$company.country',
|
||||
],
|
||||
'invoice_details' => [
|
||||
|
@ -195,4 +195,56 @@ class Request extends FormRequest
|
||||
public function prepareForValidation()
|
||||
{
|
||||
}
|
||||
|
||||
public function checkTimeLog(array $log): bool
|
||||
{
|
||||
if(count($log) == 0)
|
||||
return true;
|
||||
|
||||
/*Get first value of all arrays*/
|
||||
$result = array_column($log, 0);
|
||||
|
||||
/*Sort the array in ascending order*/
|
||||
asort($result);
|
||||
|
||||
$new_array = [];
|
||||
|
||||
/*Rebuild the array in order*/
|
||||
foreach($result as $key => $value)
|
||||
$new_array[] = $log[$key];
|
||||
|
||||
/*Iterate through the array and perform checks*/
|
||||
foreach($new_array as $key => $array)
|
||||
{
|
||||
/*Flag which helps us know if there is a NEXT timelog*/
|
||||
$next = false;
|
||||
/* If there are more than 1 time log in the array, ensure the last timestamp is not zero*/
|
||||
if(count($new_array) >1 && $array[1] == 0)
|
||||
return false;
|
||||
|
||||
/* Check if the start time is greater than the end time */
|
||||
/* Ignore the last value for now, we'll do a separate check for this */
|
||||
if($array[0] > $array[1] && $array[1] != 0)
|
||||
return false;
|
||||
|
||||
/* Find the next time log value - if it exists */
|
||||
if(array_key_exists($key+1, $new_array))
|
||||
$next = $new_array[$key+1];
|
||||
|
||||
/* check the next time log and ensure the start time is GREATER than the end time of the previous record */
|
||||
if($next && $next[0] < $array[1])
|
||||
return false;
|
||||
|
||||
/* Get the last row of the timelog*/
|
||||
$last_row = end($new_array);
|
||||
|
||||
/*If the last value is NOT zero, ensure start time is not GREATER than the endtime */
|
||||
if($last_row[1] != 0 && $last_row[0] > $last_row[1])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,6 +53,9 @@ class StoreTaskRequest extends Request
|
||||
$fail('The '.$attribute.' - '.print_r($k,1).' is invalid. Unix timestamps only.');
|
||||
}
|
||||
|
||||
if(!$this->checkTimeLog($values))
|
||||
$fail('Please correct overlapping values');
|
||||
|
||||
}];
|
||||
|
||||
|
||||
|
@ -59,6 +59,9 @@ class UpdateTaskRequest extends Request
|
||||
$fail('The '.$attribute.' - '.print_r($k,1).' is invalid. Unix timestamps only.');
|
||||
}
|
||||
|
||||
if(!$this->checkTimeLog($values))
|
||||
$fail('Please correct overlapping values');
|
||||
|
||||
}];
|
||||
|
||||
return $this->globalRules($rules);
|
||||
|
@ -39,6 +39,8 @@ class StoreWebhookRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(!isset($input['rest_method']))
|
||||
$input['rest_method'] = 'post';
|
||||
// if(isset($input['headers']) && count($input['headers']) == 0)
|
||||
// $input['headers'] = null;
|
||||
|
||||
|
@ -44,6 +44,9 @@ class UpdateWebhookRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(!isset($input['rest_method']))
|
||||
$input['rest_method'] = 'post';
|
||||
|
||||
// if(isset($input['headers']) && count($input['headers']) == 0)
|
||||
// $input['headers'] = null;
|
||||
|
||||
|
@ -18,7 +18,6 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
class BankTransactionRule extends BaseModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
use MakesHash;
|
||||
use Filterable;
|
||||
|
||||
protected $fillable = [
|
||||
@ -66,6 +65,37 @@ class BankTransactionRule extends BaseModel
|
||||
|
||||
private array $search_results = [];
|
||||
|
||||
public function getEntityType()
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function vendor()
|
||||
{
|
||||
return $this->belongsTo(Vendor::class);
|
||||
}
|
||||
|
||||
public function client()
|
||||
{
|
||||
return $this->belongsTo(Client::class);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function expense_category()
|
||||
{
|
||||
return $this->belongsTo(ExpenseCategory::class, 'category_id')->withTrashed();
|
||||
}
|
||||
|
||||
|
||||
// rule object looks like this:
|
||||
//[
|
||||
// {
|
||||
@ -138,34 +168,5 @@ class BankTransactionRule extends BaseModel
|
||||
// }
|
||||
// }
|
||||
|
||||
public function getEntityType()
|
||||
{
|
||||
return self::class;
|
||||
}
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function vendor()
|
||||
{
|
||||
return $this->belongsTo(Vendor::class);
|
||||
}
|
||||
|
||||
public function client()
|
||||
{
|
||||
return $this->belongsTo(Client::class);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function expense_category()
|
||||
{
|
||||
return $this->belongsTo(ExpenseCategory::class, 'category_id', 'id')->withTrashed();
|
||||
}
|
||||
|
||||
}
|
@ -206,12 +206,22 @@ class BaseModel extends Model
|
||||
return ctrans('texts.item');
|
||||
}
|
||||
|
||||
public function sendEvent($event_id, $additional_data=""){
|
||||
/**
|
||||
* Model helper to send events for webhooks
|
||||
*
|
||||
* @param int $event_id
|
||||
* @param string $additional_data optional includes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sendEvent(int $event_id, string $additional_data = ""): void
|
||||
{
|
||||
$subscriptions = Webhook::where('company_id', $this->company_id)
|
||||
->where('event_id', $event_id)
|
||||
->exists();
|
||||
->where('event_id', $event_id)
|
||||
->exists();
|
||||
|
||||
if ($subscriptions) {
|
||||
WebhookHandler::dispatch($event_id, $this, $this->company, $additional_data)->delay(0);
|
||||
WebhookHandler::dispatch($event_id, $this, $this->company, $additional_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ class ClientObserver
|
||||
->exists();
|
||||
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch($event, $client, $client->company)->delay(0);
|
||||
WebhookHandler::dispatch($event, $client, $client->company, 'client')->delay(0);
|
||||
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class InvoiceObserver
|
||||
->exists();
|
||||
|
||||
if ($subscriptions)
|
||||
WebhookHandler::dispatch($event, $invoice, $invoice->company)->delay(0);
|
||||
WebhookHandler::dispatch($event, $invoice, $invoice->company, 'client')->delay(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,10 +13,13 @@ namespace App\Transformers;
|
||||
|
||||
use App\Models\BankTransaction;
|
||||
use App\Models\BankTransactionRule;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Transformers\VendorTransformer;
|
||||
use App\Models\Vendor;
|
||||
use App\Transformers\ExpenseCategoryTransformer;
|
||||
use App\Transformers\ExpenseCateogryTransformer;
|
||||
use App\Transformers\VendorTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
/**
|
||||
@ -74,31 +77,34 @@ class BankTransactionRuleTransformer extends EntityTransformer
|
||||
|
||||
public function includeClient(BankTransactionRule $bank_transaction_rule)
|
||||
{
|
||||
$transformer = new ClientTransformer($this->serializer);
|
||||
|
||||
if(!$bank_transaction_rule->client)
|
||||
return null;
|
||||
|
||||
return $this->includeItem($bank_transaction_rule->expense, $transformer, Client::class);
|
||||
$transformer = new ClientTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($bank_transaction_rule->client, $transformer, Client::class);
|
||||
}
|
||||
|
||||
public function includeVendor(BankTransactionRule $bank_transaction_rule)
|
||||
{
|
||||
$transformer = new VendorTransformer($this->serializer);
|
||||
|
||||
if(!$bank_transaction_rule->vendor)
|
||||
return null;
|
||||
|
||||
$transformer = new VendorTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($bank_transaction_rule->vendor, $transformer, Vendor::class);
|
||||
}
|
||||
|
||||
public function includeExpenseCategory(BankTransactionRule $bank_transaction_rule)
|
||||
{
|
||||
$transformer = new ExpenseCategoryTransformer($this->serializer);
|
||||
|
||||
if(!$bank_transaction_rule->expense_cateogry)
|
||||
if(!$bank_transaction_rule->expense_category)
|
||||
return null;
|
||||
|
||||
$transformer = new ExpenseCategoryTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($bank_transaction_rule->expense_category, $transformer, ExpenseCategory::class);
|
||||
}
|
||||
|
||||
|
@ -223,15 +223,15 @@ class Number
|
||||
|
||||
/* 08-01-2022 allow increased precision for unit price*/
|
||||
$v = rtrim(sprintf('%f', $value), '0');
|
||||
// $precision = strlen(substr(strrchr($v, $decimal), 1));
|
||||
|
||||
if ($v < 1) {
|
||||
/* 08-02-2023 special if block to render $0.5 to $0.50*/
|
||||
if ($v < 1 && strlen($v) == 3) {
|
||||
$precision = 2;
|
||||
}
|
||||
elseif ($v < 1) {
|
||||
$precision = strlen($v) - strrpos($v, '.') - 1;
|
||||
}
|
||||
|
||||
// if($precision == 1)
|
||||
// $precision = 2;
|
||||
|
||||
$value = number_format($v, $precision, $decimal, $thousand);
|
||||
$symbol = $currency->symbol;
|
||||
|
||||
|
@ -185,7 +185,7 @@ class BankTransactionRuleTest extends TestCase
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->putJson('/api/v1/bank_transaction_rules/'. $br->hashed_id, $data);
|
||||
])->putJson('/api/v1/bank_transaction_rules/'. $br->hashed_id. '?include=expense_category', $data);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||
@ -194,7 +194,7 @@ class BankTransactionRuleTest extends TestCase
|
||||
|
||||
if($response){
|
||||
$arr = $response->json();
|
||||
|
||||
nlog($arr);
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,198 @@ class TaskApiTest extends TestCase
|
||||
Model::reguard();
|
||||
}
|
||||
|
||||
private function checkTimeLog(array $log): bool
|
||||
{
|
||||
if(count($log) == 0)
|
||||
return true;
|
||||
|
||||
/*Get first value of all arrays*/
|
||||
$result = array_column($log, 0);
|
||||
|
||||
/*Sort the array in ascending order*/
|
||||
asort($result);
|
||||
|
||||
$new_array = [];
|
||||
|
||||
/*Rebuild the array in order*/
|
||||
foreach($result as $key => $value)
|
||||
$new_array[] = $log[$key];
|
||||
|
||||
/*Iterate through the array and perform checks*/
|
||||
foreach($new_array as $key => $array)
|
||||
{
|
||||
/*Flag which helps us know if there is a NEXT timelog*/
|
||||
$next = false;
|
||||
/* If there are more than 1 time log in the array, ensure the last timestamp is not zero*/
|
||||
if(count($new_array) >1 && $array[1] == 0)
|
||||
return false;
|
||||
|
||||
/* Check if the start time is greater than the end time */
|
||||
/* Ignore the last value for now, we'll do a separate check for this */
|
||||
if($array[0] > $array[1] && $array[1] != 0)
|
||||
return false;
|
||||
|
||||
/* Find the next time log value - if it exists */
|
||||
if(array_key_exists($key+1, $new_array))
|
||||
$next = $new_array[$key+1];
|
||||
|
||||
/* check the next time log and ensure the start time is GREATER than the end time of the previous record */
|
||||
if($next && $next[0] < $array[1])
|
||||
return false;
|
||||
|
||||
/* Get the last row of the timelog*/
|
||||
$last_row = end($new_array);
|
||||
|
||||
/*If the last value is NOT zero, ensure start time is not GREATER than the endtime */
|
||||
if($last_row[1] != 0 && $last_row[0] > $last_row[1])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testTimeLogChecker1()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[50,0]
|
||||
];
|
||||
|
||||
$this->assertTrue($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
public function testTimeLogChecker2()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[4,5],
|
||||
[5,1]
|
||||
];
|
||||
|
||||
|
||||
$this->assertFalse($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testTimeLogChecker3()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[4,5],
|
||||
[3,50]
|
||||
];
|
||||
|
||||
|
||||
$this->assertFalse($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testTimeLogChecker4()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[4,5],
|
||||
[3,0]
|
||||
];
|
||||
|
||||
|
||||
$this->assertFalse($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
public function testTimeLogChecker5()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[4,5],
|
||||
[3,1]
|
||||
];
|
||||
|
||||
|
||||
$this->assertFalse($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
public function testTimeLogChecker6()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[4,5],
|
||||
[1,3],
|
||||
];
|
||||
|
||||
|
||||
$this->assertTrue($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
public function testTimeLogChecker7()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[1,3],
|
||||
[4,5]
|
||||
];
|
||||
|
||||
|
||||
$this->assertTrue($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
public function testTimeLogChecker8()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[1,3],
|
||||
[50,0]
|
||||
];
|
||||
|
||||
$this->assertTrue($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
public function testTimeLogChecker9()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[4,5,'bb'],
|
||||
[50,0,'aa'],
|
||||
];
|
||||
|
||||
$this->assertTrue($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testTimeLogChecker10()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[4,5,'5'],
|
||||
[50,0,'3'],
|
||||
];
|
||||
|
||||
$this->assertTrue($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testTimeLogChecker11()
|
||||
{
|
||||
|
||||
$log = [
|
||||
[1,2,'a'],
|
||||
[3,4,'d'],
|
||||
];
|
||||
|
||||
$this->assertTrue($this->checkTimeLog($log));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testTaskListClientStatus()
|
||||
|
@ -49,33 +49,6 @@ class WebhookAPITest extends TestCase
|
||||
$this->withoutExceptionHandling();
|
||||
}
|
||||
|
||||
// public function testClientWebhooks()
|
||||
// {
|
||||
// // client archived = 37
|
||||
// $data = [
|
||||
// 'target_url' => 'http://hook.com',
|
||||
// 'event_id' => 37,
|
||||
// 'rest_method' => 'post',
|
||||
// 'format' => 'JSON',
|
||||
// ];
|
||||
|
||||
// $response = $this->withHeaders([
|
||||
// 'X-API-SECRET' => config('ninja.api_secret'),
|
||||
// 'X-API-TOKEN' => $this->token,
|
||||
// ])->post('/api/v1/webhooks', $data);
|
||||
|
||||
// $repo = new ClientRepository(new ClientContactRepository());
|
||||
|
||||
// $repo->archive($this->client);
|
||||
|
||||
// \Illuminate\Support\Facades\Queue::after(function (WebhookHandler $event) {
|
||||
// $this->assertTrue($event->job->isReleased());
|
||||
// });
|
||||
|
||||
// \Illuminate\Support\Facades\Queue::assertPushed(WebhookHandler::class);
|
||||
|
||||
// }
|
||||
|
||||
public function testWebhookGetFilter()
|
||||
{
|
||||
$response = $this->withHeaders([
|
||||
@ -98,6 +71,20 @@ class WebhookAPITest extends TestCase
|
||||
|
||||
public function testWebhookPostRoute()
|
||||
{
|
||||
|
||||
$data = [
|
||||
'target_url' => 'http://hook.com',
|
||||
'event_id' => 1,
|
||||
'format' => 'JSON',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/webhooks', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$data = [
|
||||
'target_url' => 'http://hook.com',
|
||||
'event_id' => 1,
|
||||
@ -116,6 +103,20 @@ class WebhookAPITest extends TestCase
|
||||
|
||||
$this->assertEquals(1, $arr['data']['event_id']);
|
||||
|
||||
$data = [
|
||||
'target_url' => 'http://hook.com',
|
||||
'event_id' => 2,
|
||||
'format' => 'JSON',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/webhooks/'.$arr['data']['id'], $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
$data = [
|
||||
'target_url' => 'http://hook.com',
|
||||
'event_id' => 2,
|
||||
|
Loading…
Reference in New Issue
Block a user