1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00

Merge pull request #4206 from turbo124/v5-stable

Fix for date localization
This commit is contained in:
David Bomba 2020-10-24 14:40:30 +11:00 committed by GitHub
commit 70fe9e0d2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 152 additions and 122 deletions

View File

@ -112,6 +112,7 @@ class CreateSingleAccount extends Command
$company = Company::factory()->create([
'account_id' => $account->id,
'slack_webhook_url' => config('ninja.notification.slack'),
'use_credits_payment' => 'always',
]);
$account->default_company_id = $company->id;

View File

@ -207,7 +207,7 @@ class BaseController extends Controller
$query->whereNotNull('updated_at')->with('documents');
},
'company.clients' => function ($query) use ($updated_at) {
$query->where('clients.updated_at', '>=', $updated_at)->with('contacts.company', 'gateway_tokens','documents','company');
$query->where('clients.updated_at', '>=', $updated_at)->with('contacts.company', 'gateway_tokens','documents');
},
'company.company_gateways' => function ($query) {
$query->whereNotNull('updated_at');

View File

@ -52,7 +52,7 @@ class Kernel extends HttpKernel
],
'api' => [
'throttle:60,1',
'throttle:300,1',
'bindings',
'query_logging',
\App\Http\Middleware\Cors::class,
@ -74,7 +74,7 @@ class Kernel extends HttpKernel
\App\Http\Middleware\QueryLogging::class,
],
'shop' => [
'throttle:60,1',
'throttle:120,1',
'bindings',
'query_logging',
],

View File

@ -54,6 +54,7 @@ class QueryLogging
// if($count > 50)
// Log::info($queries);
}
}

View File

@ -46,16 +46,7 @@ class UpdateExpenseRequest extends Request
$rules['number'] = 'unique:expenses,number,'.$this->id.',id,company_id,'.$this->expense->company_id;
}
$contacts = request('contacts');
if (is_array($contacts)) {
// for ($i = 0; $i < count($contacts); $i++) {
// // $rules['contacts.' . $i . '.email'] = 'nullable|email|unique:client_contacts,email,' . isset($contacts[$i]['id'].',company_id,'.$this->company_id);
// //$rules['contacts.' . $i . '.email'] = 'nullable|email';
// }
}
return $rules;
return $this->globalRules($rules);
}
public function messages()
@ -72,6 +63,8 @@ class UpdateExpenseRequest extends Request
{
$input = $this->all();
$input = $this->decodePrimaryKeys($input);
$this->replace($input);
}
}

View File

@ -34,7 +34,6 @@ class StoreProjectRequest extends Request
{
$rules = [];
//$rules['name'] ='required|unique:projects,name,null,null,company_id,'.auth()->user()->companyId();
$rules['name'] = 'required';
$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
@ -48,7 +47,6 @@ class StoreProjectRequest extends Request
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
}
$this->replace($input);
}

View File

@ -38,6 +38,10 @@ class UpdateProjectRequest extends Request
{
$input = $this->all();
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
unset($input['client_id']);
}
$this->replace($input);
}
}

View File

@ -63,7 +63,7 @@ class Request extends FormRequest
private function vendor_id($rules)
{
$rules['vendor_id'] = 'bail|sometimes|exists:vendors,id,company_id,'.auth()->user()->company()->id;
$rules['vendor_id'] = 'bail|nullable|sometimes|exists:vendors,id,company_id,'.auth()->user()->company()->id;
return $rules;
}

View File

@ -82,7 +82,7 @@ class BaseMailerJob implements ShouldQueue
public function failed($exception = null)
{
info('the job failed');
// info('the job failed');
$job_failure = new EmailFailure();
$job_failure->string_metric5 = get_parent_class($this);

View File

@ -240,7 +240,6 @@ class Client extends BaseModel implements HasLocalePreference
return $item->id == $this->getSetting('date_format_id');
})->first()->format;
//return DateFormat::find($this->getSetting('date_format_id'))->format;
}
public function currency()

View File

@ -11,7 +11,7 @@ use Laracasts\Presenter\PresentableTrait;
*/
class Project extends BaseModel
{
// Expense Categories
use SoftDeletes;
use PresentableTrait;
use Filterable;

View File

@ -201,7 +201,7 @@ class AuthorizeCreditCard
private function processFailedResponse($data, $request)
{
//dd($data);
info(print_r($data, 1));
// info(print_r($data, 1));
}
private function formatGatewayResponse($data, $vars)

View File

@ -55,6 +55,19 @@ class CreditService
return $this;
}
public function setCalculatedStatus()
{
if((int)$this->credit->balance == 0)
$this->credit->status_id = Credit::STATUS_APPLIED;
elseif((string)$this->credit->amount == (string)$this->credit->balance)
$this->credit->status_id = Credit::STATUS_SENT;
elseif($this->credit->balance > 0)
$this->credit->status_id = Credit::STATUS_PARTIAL;
return $this;
}
public function markSent()
{
$this->credit = (new MarkSent($this->credit->client, $this->credit))->run();
@ -69,6 +82,13 @@ class CreditService
return $this;
}
public function adjustBalance($adjustment)
{
$this->credit->balance += $adjustment;
return $this;
}
/**
* Saves the credit.
* @return Credit object

View File

@ -56,7 +56,7 @@ class AutoBillInvoice extends AbstractService
//if the credits cover the payments, we stop here, build the payment with credits and exit early
if($this->invoice->company->use_credits_payment == 'always' || $this->invoice->company->use_credits_payment == 'option')
if($this->invoice->company->use_credits_payment != 'off')
$this->applyCreditPayment();
info("partial = {$this->invoice->partial}");
@ -68,7 +68,7 @@ class AutoBillInvoice extends AbstractService
elseif($this->invoice->balance > 0)
$amount = $this->invoice->balance;
else
return $this->finalizePaymentUsingCredits();
return $this->invoice;
info("balance remains to be paid!!");
@ -127,8 +127,11 @@ class AutoBillInvoice extends AbstractService
$current_credit = Credit::find($credit['credit_id']);
$payment->credits()->attach($current_credit->id, ['amount' => $credit['amount']]);
info("adjusting credit balance {$current_credit->balance} by this amount ". $credit['amount']);
$current_credit->balance -= $credit['amount'];
$current_credit->save();
$current_credit->service()->setCalculatedStatus()->save();
// $this->applyPaymentToCredit($current_credit, $credit['amount']);
}
@ -147,9 +150,9 @@ class AutoBillInvoice extends AbstractService
->updateCreditBalance($amount * -1, 'Credits used to pay down Invoice ' . $this->invoice->number)
->save();
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
return $this->invoice->service()->setStatus(Invoice::STATUS_PAID)->save();
return $this->invoice->service()->setCalculatedStatus()->save();
}
/**
@ -169,6 +172,8 @@ class AutoBillInvoice extends AbstractService
$available_credit_balance = $available_credits->sum('balance');
info("available credit balance = {$available_credit_balance}");
if((int)$available_credit_balance == 0)
return;
@ -217,7 +222,7 @@ class AutoBillInvoice extends AbstractService
}
}
$this->finalizePaymentUsingCredits();
return $this;
}

View File

@ -210,6 +210,16 @@ class InvoiceService
return $this;
}
public function setCalculatedStatus()
{
if((int)$this->invoice->balance == 0)
$this->setStatus(Invoice::STATUS_PAID);
elseif($this->invoice->balance > 0 && $this->invoice->balance < $this->invoice->amount)
$this->setStatus(Invoice::STATUS_PARTIAL);
return $this;
}
public function updateStatus()
{
info("invoice balance = {$this->invoice->balance}");

View File

@ -241,6 +241,7 @@ class RefundPayment
$adjustment_amount += $refunded_invoice['amount'];
$client->balance += $refunded_invoice['amount'];
//$client->paid_to_date -= $refunded_invoice['amount'];//todo refund balancing
$client->save();
//todo adjust ledger balance here? or after and reference the credit and its total
@ -251,7 +252,8 @@ class RefundPayment
// $this->credit_note->ledger()->updateCreditBalance($adjustment_amount, $ledger_string);
$client = $this->payment->client->fresh();
$client->service()->updatePaidToDate(-1 * $this->total_refund)->save();
//$client->service()->updatePaidToDate(-1 * $this->total_refund)->save();
$client->service()->updatePaidToDate(-1 * $refunded_invoice['amount'])->save();
}
return $this;

View File

@ -293,7 +293,7 @@ trait PdfMakerUtilities
$this->document->getElementById('repeat-content')->appendChild($clone);
}
info($this->data['options']);
// info($this->data['options']);
if (
$header = $this->document->getElementById('header') &&

View File

@ -144,6 +144,9 @@ class CompanyTransformer extends EntityTransformer
'enable_shop_api' => (bool) $company->enable_shop_api,
'mark_expenses_invoiceable'=> (bool) $company->mark_expenses_invoiceable,
'mark_expenses_paid' => (bool) $company->mark_expenses_paid,
'invoice_expense_documents' => (bool) $company->invoice_expense_documents,
'invoice_task_timelog' => (bool) $company->invoice_task_timelog,
'auto_start_tasks' => (bool) $company->auto_start_tasks,
'use_credits_payment' => (string) $company->use_credits_payment,
];
}

View File

@ -15,10 +15,13 @@ namespace App\Utils;
use App\Designs\Designer;
use App\Models\Country;
use App\Utils\Number;
use App\Utils\Traits\MakesDates;
use Illuminate\Support\Facades\App;
class HtmlEngine
{
use MakesDates;
public $entity;
public $invitation;
@ -172,10 +175,10 @@ class HtmlEngine
$data['$taxes'] = ['value' => Number::formatMoney($this->entity_calc->getItemTotalTaxes(), $this->client) ?: '&nbsp;', 'label' => ctrans('texts.taxes')];
$data['$invoice.taxes'] = &$data['$taxes'];
$data['$invoice.custom1'] = ['value' => $this->entity->custom_value1 ?: '&nbsp;', 'label' => $this->makeCustomField('invoice1')];
$data['$invoice.custom2'] = ['value' => $this->entity->custom_value2 ?: '&nbsp;', 'label' => $this->makeCustomField('invoice2')];
$data['$invoice.custom3'] = ['value' => $this->entity->custom_value3 ?: '&nbsp;', 'label' => $this->makeCustomField('invoice3')];
$data['$invoice.custom4'] = ['value' => $this->entity->custom_value4 ?: '&nbsp;', 'label' => $this->makeCustomField('invoice4')];
$data['$invoice.custom1'] = ['value' => $this->formatCustomFieldValue('invoice1', $this->entity->custom_value1) ?: '&nbsp;', 'label' => $this->makeCustomField('invoice1')];
$data['$invoice.custom2'] = ['value' => $this->formatCustomFieldValue('invoice2', $this->entity->custom_value2) ?: '&nbsp;', 'label' => $this->makeCustomField('invoice2')];
$data['$invoice.custom3'] = ['value' => $this->formatCustomFieldValue('invoice3', $this->entity->custom_value3) ?: '&nbsp;', 'label' => $this->makeCustomField('invoice3')];
$data['$invoice.custom4'] = ['value' => $this->formatCustomFieldValue('invoice4', $this->entity->custom_value4) ?: '&nbsp;', 'label' => $this->makeCustomField('invoice4')];
$data['$invoice.public_notes'] = ['value' => $this->entity->public_notes ?: '&nbsp;', 'label' => ctrans('texts.public_notes')];
$data['$entity.public_notes'] = &$data['$invoice.public_notes'];
@ -481,6 +484,7 @@ class HtmlEngine
if ($custom_fields && property_exists($custom_fields, $field)) {
$custom_field = $custom_fields->{$field};
$custom_field_parts = explode('|', $custom_field);
return $custom_field_parts[0];
@ -489,6 +493,28 @@ class HtmlEngine
return '';
}
private function formatCustomFieldValue($field, $value) :string
{
$custom_fields = $this->company->custom_fields;
$custom_field = '';
if ($custom_fields && property_exists($custom_fields, $field)) {
$custom_field = $custom_fields->{$field};
$custom_field_parts = explode('|', $custom_field);
$custom_field = $custom_field_parts[1];
}
switch ($custom_field) {
case 'date':
return $this->formatDate($value, $this->client->date_format());
break;
default:
return $value;
break;
}
}
private function makeTotalTaxes() :string
{
$data = '';

View File

@ -59,7 +59,6 @@
"spatie/browsershot": "^3.37",
"staudenmeir/eloquent-has-many-deep": "^1.11",
"stripe/stripe-php": "^7.50",
"swooletw/laravel-swoole": "^2.6",
"turbo124/beacon": "^1",
"turbo124/laravel-gmail": "^5.0",
"webpatser/laravel-countries": "dev-master#75992ad"

91
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "08ae0ebd522fae2599454303710f08b1",
"content-hash": "152c174ecc48f87a2c7fd00335c6fc86",
"packages": [
{
"name": "asgrim/ofxparser",
@ -3879,16 +3879,16 @@
},
{
"name": "nesbot/carbon",
"version": "2.41.3",
"version": "2.41.4",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "e148788eeae9b9b7b87996520358b86faad37b52"
"reference": "6571aec754a648ef476a8d8f57993f7bc965afe4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e148788eeae9b9b7b87996520358b86faad37b52",
"reference": "e148788eeae9b9b7b87996520358b86faad37b52",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/6571aec754a648ef476a8d8f57993f7bc965afe4",
"reference": "6571aec754a648ef476a8d8f57993f7bc965afe4",
"shasum": ""
},
"require": {
@ -3964,7 +3964,7 @@
"type": "tidelift"
}
],
"time": "2020-10-12T20:36:09+00:00"
"time": "2020-10-22T07:28:05+00:00"
},
{
"name": "nikic/php-parser",
@ -6497,85 +6497,6 @@
],
"time": "2019-11-12T09:31:26+00:00"
},
{
"name": "swooletw/laravel-swoole",
"version": "v2.6.68",
"source": {
"type": "git",
"url": "https://github.com/swooletw/laravel-swoole.git",
"reference": "4167206bfbaea752264c814cac5c2172e72a400a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swooletw/laravel-swoole/zipball/4167206bfbaea752264c814cac5c2172e72a400a",
"reference": "4167206bfbaea752264c814cac5c2172e72a400a",
"shasum": ""
},
"require": {
"illuminate/console": "~5.4|~6.0|~7.0|~8.0",
"illuminate/contracts": "~5.4|~6.0|~7.0|~8.0",
"illuminate/http": "~5.4|~6.0|~7.0|~8.0",
"illuminate/support": "~5.4|~6.0|~7.0|~8.0",
"php": "^7.2",
"predis/predis": "^1.1"
},
"require-dev": {
"codedungeon/phpunit-result-printer": "^0.14.0",
"laravel/lumen-framework": "~5.4|~6.0|~7.0|~8.0",
"mockery/mockery": "~1.0",
"php-coveralls/php-coveralls": "^2.1",
"php-mock/php-mock": "^2.0",
"phpunit/php-code-coverage": "^6.1",
"phpunit/phpunit": "^7.5",
"swoole/ide-helper": "@dev"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"SwooleTW\\Http\\LaravelServiceProvider"
],
"aliases": {
"Server": "SwooleTW\\Http\\Server\\Facades\\Server",
"Table": "SwooleTW\\Http\\Server\\Facades\\Table",
"Room": "SwooleTW\\Http\\Websocket\\Facades\\Room",
"Websocket": "SwooleTW\\Http\\Websocket\\Facades\\Websocket"
}
}
},
"autoload": {
"files": [
"src/Server/helpers.php"
],
"psr-4": {
"SwooleTW\\Http\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Albert Chen",
"email": "albert@unisharp.com"
},
{
"name": "Huang Yi",
"email": "coodeer@163.com"
}
],
"description": "High performance HTTP server based on Swoole. Speed up your Laravel and Lumen applications.",
"keywords": [
"http",
"laravel",
"lumen",
"performance",
"server",
"swoole"
],
"time": "2020-09-21T10:06:50+00:00"
},
{
"name": "symfony/console",
"version": "v5.1.7",

View File

@ -181,7 +181,6 @@ return [
App\Providers\MultiDBProvider::class,
App\Providers\ClientPortalServiceProvider::class,
App\Providers\NinjaTranslationServiceProvider::class,
SwooleTW\Http\LaravelServiceProvider::class,
],

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CompanyTableFields extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('companies', function(Blueprint $table){
$table->boolean('invoice_task_timelog')->default(true);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View File

@ -14,6 +14,7 @@ use Faker\Factory;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\MockAccountData;
use Tests\TestCase;
use Illuminate\Routing\Middleware\ThrottleRequests;
/**
* @test
@ -31,6 +32,11 @@ class ActivityApiTest extends TestCase
$this->makeTestData();
$this->withoutMiddleware(
ThrottleRequests::class
);
}
public function testActivityGet()

View File

@ -516,7 +516,8 @@ class ClientTest extends TestCase
$response->assertStatus(200);
$arr = $response->json();
info($arr);
$this->client = Client::find($this->decodePrimaryKey($arr['data']['id']));
$this->client->fresh();

View File

@ -172,6 +172,6 @@ class CompanyGatewayResolutionTest extends TestCase
$this->assertEquals(4, count($this->cg->driver($this->client)->gatewayTypes()));
info(print_r($this->client->getPaymentMethods(10),1));
// info(print_r($this->client->getPaymentMethods(10),1));
}
}

View File

@ -29,6 +29,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Tests\MockAccountData;
use Tests\TestCase;
use Illuminate\Routing\Middleware\ThrottleRequests;
/**
* @test
@ -51,6 +52,11 @@ class PaymentTermsApiTest extends TestCase
$this->faker = \Faker\Factory::create();
Model::reguard();
$this->withoutMiddleware(
ThrottleRequests::class
);
}
public function testPaymentTermsGet()

View File

@ -1295,7 +1295,7 @@ $contact = ClientContact::factory()->create([
$payment = Payment::find($this->decodePrimaryKey($payment_id))->first();
info($payment);
// info($payment);
$this->assertNotNull($payment);
$this->assertNotNull($payment->invoices());

View File

@ -13,6 +13,7 @@ namespace Tests\Feature;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\MockAccountData;
use Tests\TestCase;
use Illuminate\Routing\Middleware\ThrottleRequests;
/**
* @test
@ -28,6 +29,11 @@ class PingTest extends TestCase
parent::setUp();
$this->makeTestData();
$this->withoutMiddleware(
ThrottleRequests::class
);
}
public function testPingEndPoint()