mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 13:12:50 +01:00
Merge pull request #8473 from turbo124/v5-develop
FIxes for show_credits_tables
This commit is contained in:
commit
e1eeabe700
@ -1 +1 @@
|
||||
5.5.107
|
||||
5.5.108
|
@ -235,7 +235,7 @@ class BaseRule implements RuleInterface
|
||||
return $this;
|
||||
} elseif($this->isTaxableRegion()) { //other regions outside of US
|
||||
|
||||
match($item->tax_id) {
|
||||
match(intval($item->tax_id)) {
|
||||
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt(),
|
||||
Product::PRODUCT_TYPE_REDUCED_TAX => $this->taxReduced(),
|
||||
Product::PRODUCT_TYPE_OVERRIDE_TAX => $this->override(),
|
||||
|
@ -66,7 +66,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
return $this->taxExempt();
|
||||
}
|
||||
|
||||
match($product_tax_type){
|
||||
match(intval($product_tax_type)){
|
||||
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt(),
|
||||
Product::PRODUCT_TYPE_DIGITAL => $this->taxDigital(),
|
||||
Product::PRODUCT_TYPE_SERVICE => $this->taxService(),
|
||||
|
@ -57,7 +57,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
public function taxByType($product_tax_type): self
|
||||
{
|
||||
|
||||
match($product_tax_type) {
|
||||
match(intval($product_tax_type)) {
|
||||
Product::PRODUCT_TYPE_EXEMPT => $this->taxExempt(),
|
||||
Product::PRODUCT_TYPE_DIGITAL => $this->taxDigital(),
|
||||
Product::PRODUCT_TYPE_SERVICE => $this->taxService(),
|
||||
@ -103,7 +103,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
*/
|
||||
public function taxService(): self
|
||||
{
|
||||
if($this->tax_data->txbService == 'Y') {
|
||||
if($this->tax_data?->txbService == 'Y') {
|
||||
$this->default();
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ class Rule extends BaseRule implements RuleInterface
|
||||
*/
|
||||
public function taxShipping(): self
|
||||
{
|
||||
if($this->tax_data->txbFreight == 'Y') {
|
||||
if($this->tax_data?->txbFreight == 'Y') {
|
||||
$this->default();
|
||||
}
|
||||
|
||||
|
@ -668,7 +668,7 @@ class BaseController extends Controller
|
||||
* Passes back the miniloaded data response
|
||||
*
|
||||
* @param Builder $query
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
protected function timeConstrainedResponse($query)
|
||||
{
|
||||
|
@ -64,7 +64,6 @@ class ChartController extends BaseController
|
||||
* ),
|
||||
* )
|
||||
* @param Request $request
|
||||
* @return Response|mixed
|
||||
*/
|
||||
public function totals(ShowChartRequest $request)
|
||||
{
|
||||
|
@ -574,7 +574,7 @@ class ClientController extends BaseController
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param UploadClientRequest $request
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
*
|
||||
@ -644,7 +644,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @param string $mergeable client hashed_id
|
||||
* @param string $mergeable_client
|
||||
* @return Response
|
||||
*
|
||||
*
|
||||
|
@ -46,20 +46,15 @@ class ClientGatewayTokenController extends BaseController
|
||||
|
||||
protected $entity_transformer = ClientGatewayTokenTransformer::class;
|
||||
|
||||
/**
|
||||
* @var ClientGatewayTokenRepository
|
||||
*/
|
||||
protected $client_gateway_token_gateway_token_repo;
|
||||
|
||||
/**
|
||||
* ClientGatewayTokenController constructor.
|
||||
* @param ClientGatewayTokenRepository $client_gateway_token_gateway_token_repo
|
||||
* @param ClientGatewayTokenRepository $client_gateway_token_repo
|
||||
*/
|
||||
public function __construct(ClientGatewayTokenRepository $client_gateway_token_gateway_token_repo)
|
||||
public function __construct(protected ClientGatewayTokenRepository $client_gateway_token_repo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->client_gateway_token_repo = $client_gateway_token_gateway_token_repo;
|
||||
$this->client_gateway_token_repo = $client_gateway_token_repo;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,8 +64,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* tags={"client_gateway_tokens"},
|
||||
* summary="Gets a list of client_gateway_tokens",
|
||||
* description="Lists client_gateway_tokens, search and filters allow fine grained lists to be generated.
|
||||
|
||||
Query parameters can be added to performed more fine grained filtering of the client_gateway_tokens, these are handled by the ClientGatewayTokenFilters class which defines the methods available",
|
||||
* Query parameters can be added to performed more fine grained filtering of the client_gateway_tokens, these are handled by the ClientGatewayTokenFilters class which defines the methods available",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
@ -94,7 +88,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
* @param ClientGatewayTokenFilters $filters
|
||||
* @param ListClientGatewayTokenRequest $request
|
||||
* @return Response|mixed
|
||||
*/
|
||||
public function index(ListClientGatewayTokenRequest $request)
|
||||
|
@ -11,17 +11,18 @@
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\ViewComposers\PortalComposer;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Auth;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use App\Http\ViewComposers\PortalComposer;
|
||||
|
||||
class ContactHashLoginController extends Controller
|
||||
{
|
||||
/**
|
||||
* Logs a user into the client portal using their contact_key
|
||||
* @param string $contact_key The contact key
|
||||
* @return Auth|Redirect
|
||||
* @return Redirect
|
||||
*/
|
||||
public function login(string $contact_key)
|
||||
{
|
||||
|
@ -187,7 +187,6 @@ class InvoiceController extends Controller
|
||||
*
|
||||
* @param array $ids
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function downloadInvoicePDF(array $ids)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ class StatementController extends Controller
|
||||
public function raw(ShowStatementRequest $request)
|
||||
{
|
||||
$pdf = $request->client()->service()->statement(
|
||||
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table', 'status'])
|
||||
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table', 'show_credits_table', 'status'])
|
||||
);
|
||||
|
||||
if ($pdf && $request->query('download')) {
|
||||
|
@ -24,7 +24,7 @@ class SubscriptionPlanSwitchController extends Controller
|
||||
*
|
||||
* @param ShowPlanSwitchRequest $request
|
||||
* @param RecurringInvoice $recurring_invoice
|
||||
* @param string $target
|
||||
* @param Subscription $target
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function index(ShowPlanSwitchRequest $request, RecurringInvoice $recurring_invoice, Subscription $target)
|
||||
|
@ -11,16 +11,17 @@
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class TempRouteController extends Controller
|
||||
{
|
||||
/**
|
||||
* Logs a user into the client portal using their contact_key
|
||||
* @param string $contact_key The contact key
|
||||
* @return Auth|Redirect
|
||||
* @param string $hash The hash
|
||||
* @return Redirect
|
||||
*/
|
||||
public function index(string $hash)
|
||||
{
|
||||
|
@ -11,9 +11,10 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Statements\CreateStatementRequest;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use App\Http\Requests\Statements\CreateStatementRequest;
|
||||
|
||||
class ClientStatementController extends BaseController
|
||||
{
|
||||
@ -32,71 +33,6 @@ class ClientStatementController extends BaseController
|
||||
*
|
||||
* @param CreateStatementRequest $request
|
||||
* @return Response
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/client_statement",
|
||||
* operationId="clientStatement",
|
||||
* tags={"clients"},
|
||||
* summary="Return a PDF of the client statement",
|
||||
* description="Return a PDF of the client statement",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\RequestBody(
|
||||
* description="Statment Options",
|
||||
* required=true,
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="start_date",
|
||||
* description="The start date of the statement period - format Y-m-d",
|
||||
* type="string",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="end_date",
|
||||
* description="The start date of the statement period - format Y-m-d",
|
||||
* type="string",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="client_id",
|
||||
* description="The hashed ID of the client",
|
||||
* type="string",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="show_payments_table",
|
||||
* description="Flag which determines if the payments table is shown",
|
||||
* type="boolean",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="show_aging_table",
|
||||
* description="Flag which determines if the aging table is shown",
|
||||
* type="boolean",
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the client object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/Client"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function statement(CreateStatementRequest $request)
|
||||
{
|
||||
|
@ -603,7 +603,7 @@ class CompanyController extends BaseController
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param UploadCompanyRequest $request
|
||||
* @param Company $client
|
||||
* @param Company $company
|
||||
* @return Response
|
||||
*
|
||||
*
|
||||
|
@ -39,6 +39,7 @@ class ShowStatementRequest extends FormRequest
|
||||
$this->merge([
|
||||
'show_payments_table' => $this->has('show_payments_table') ? \boolval($this->show_payments_table) : false,
|
||||
'show_aging_table' => $this->has('show_aging_table') ? \boolval($this->show_aging_table) : false,
|
||||
'show_credits_table' => $this->has('show_credits_table') ? \boolval($this->show_credits_table) : false,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ class CreateStatementRequest extends Request
|
||||
$this->merge([
|
||||
'show_payments_table' => $this->has('show_payments_table') ? \boolval($this->show_payments_table) : false,
|
||||
'show_aging_table' => $this->has('show_aging_table') ? \boolval($this->show_aging_table) : false,
|
||||
'show_credits_table' => $this->has('show_credits_table') ? \boolval($this->show_credits_table) : false,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ class CreateAccountActivity implements ShouldQueue
|
||||
/**
|
||||
* Create the event listener.
|
||||
*
|
||||
* @param ActivityRepository $activity_repo
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -4,7 +4,6 @@ namespace App\Listeners\Document;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Document;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DeleteCompanyDocuments
|
||||
@ -31,10 +30,6 @@ class DeleteCompanyDocuments
|
||||
|
||||
$path = sprintf('%s/%s', public_path('storage'), $event->company->company_key);
|
||||
|
||||
// Remove all files & folders, under company's path.
|
||||
// This will delete directory itself, as well.
|
||||
// In case we want to remove the content of folder, we should use $fs->cleanDirectory();
|
||||
//$filesystem = new Filesystem();
|
||||
Storage::deleteDirectory($event->company->company_key);
|
||||
|
||||
Document::whereCompanyId($event->company->id)->delete();
|
||||
|
@ -310,7 +310,6 @@ use Laracasts\Presenter\PresentableTrait;
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\SystemLog> $system_logs
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Task> $tasks
|
||||
* @property int $has_valid_vat_number
|
||||
* @property string $leitweg_id
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Activity> $activities
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\CompanyLedger> $company_ledger
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ClientContact> $contacts
|
||||
|
@ -18,7 +18,6 @@ use App\Utils\Ninja;
|
||||
use App\Utils\Traits\AppSetup;
|
||||
use App\Utils\Traits\CompanySettingsSaver;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\ThrottlesEmail;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Notifications\Notification;
|
||||
@ -785,7 +784,6 @@ class Company extends BaseModel
|
||||
use PresentableTrait;
|
||||
use MakesHash;
|
||||
use CompanySettingsSaver;
|
||||
use ThrottlesEmail;
|
||||
use AppSetup;
|
||||
use \Awobaz\Compoships\Compoships;
|
||||
|
||||
|
@ -66,8 +66,9 @@ class EmailStatementService
|
||||
return [
|
||||
'start_date' =>$start_end[0],
|
||||
'end_date' =>$start_end[1],
|
||||
'show_payments_table' => $this->scheduler->parameters['show_payments_table'],
|
||||
'show_aging_table' => $this->scheduler->parameters['show_aging_table'],
|
||||
'show_payments_table' => $this->scheduler->parameters['show_payments_table'] ?? true,
|
||||
'show_aging_table' => $this->scheduler->parameters['show_aging_table'] ?? true,
|
||||
'show_credits_table' => $this->scheduler->parameters['show_credits_table'] ?? true,
|
||||
'status' => $this->scheduler->parameters['status']
|
||||
];
|
||||
}
|
||||
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Utils\Traits;
|
||||
|
||||
use App\Models\Company;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
/**
|
||||
* Class ThrottlesEmail.
|
||||
*/
|
||||
trait ThrottlesEmail
|
||||
{
|
||||
public function getDailyEmailLimit(Company $company)
|
||||
{
|
||||
$limit = config('ninja.daily_email_limit');
|
||||
|
||||
$limit += $company->created_at->diffInMonths() * 100;
|
||||
|
||||
return min($limit, 5000);
|
||||
}
|
||||
|
||||
public function isThrottled(Company $company)
|
||||
{
|
||||
$key = $company->company_key;
|
||||
|
||||
// http://stackoverflow.com/questions/1375501/how-do-i-throttle-my-sites-api-users
|
||||
$day = 60 * 60 * 24;
|
||||
$day_limit = $this->getDailyEmailLimit($company);
|
||||
$day_throttle = Cache::get("email_day_throttle:{$key}", null);
|
||||
$last_api_request = Cache::get("last_email_request:{$key}", 0);
|
||||
$last_api_diff = time() - $last_api_request;
|
||||
|
||||
if (is_null($day_throttle)) {
|
||||
$new_day_throttle = 0;
|
||||
} else {
|
||||
$new_day_throttle = $day_throttle - $last_api_diff;
|
||||
$new_day_throttle = $new_day_throttle < 0 ? 0 : $new_day_throttle;
|
||||
$new_day_throttle += $day / $day_limit;
|
||||
$day_hits_remaining = floor(($day - $new_day_throttle) * $day_limit / $day);
|
||||
$day_hits_remaining = $day_hits_remaining >= 0 ? $day_hits_remaining : 0;
|
||||
}
|
||||
|
||||
Cache::put("email_day_throttle:{$key}", $new_day_throttle, 60);
|
||||
Cache::put("last_email_request:{$key}", time(), 60);
|
||||
|
||||
if ($new_day_throttle > $day) {
|
||||
$error_email = config('ninja.error_email');
|
||||
if ($error_email && ! Cache::get("throttle_notified:{$key}")) {
|
||||
Mail::raw('Account Throttle: '.$company->company_key, function ($message) use ($error_email, $company) {
|
||||
$message->to($error_email)
|
||||
->from(config('ninja.contact.email'))
|
||||
->subject('Email throttle triggered for company '.$company->id);
|
||||
});
|
||||
}
|
||||
Cache::put("throttle_notified:{$key}", true, 60 * 24);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -108,6 +108,7 @@
|
||||
"laravel/dusk": "^6.15",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^6.1",
|
||||
"nunomaduro/larastan": "^2.0",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^9.5.10",
|
||||
"spatie/laravel-ignition": "^1.0",
|
||||
|
185
composer.lock
generated
185
composer.lock
generated
@ -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": "7482363bb2c3f9f8fb07bbd3d517597b",
|
||||
"content-hash": "8c21eb3ea2c2baeecb223d5fdbc8423c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adrienrn/php-mimetyper",
|
||||
@ -15445,6 +15445,102 @@
|
||||
],
|
||||
"time": "2023-01-03T12:54:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/larastan",
|
||||
"version": "v2.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nunomaduro/larastan.git",
|
||||
"reference": "ccac5b25949576807862cf32ba1fce1769c06c42"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nunomaduro/larastan/zipball/ccac5b25949576807862cf32ba1fce1769c06c42",
|
||||
"reference": "ccac5b25949576807862cf32ba1fce1769c06c42",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/console": "^9.47.0 || ^10.0.0",
|
||||
"illuminate/container": "^9.47.0 || ^10.0.0",
|
||||
"illuminate/contracts": "^9.47.0 || ^10.0.0",
|
||||
"illuminate/database": "^9.47.0 || ^10.0.0",
|
||||
"illuminate/http": "^9.47.0 || ^10.0.0",
|
||||
"illuminate/pipeline": "^9.47.0 || ^10.0.0",
|
||||
"illuminate/support": "^9.47.0 || ^10.0.0",
|
||||
"php": "^8.0.2",
|
||||
"phpmyadmin/sql-parser": "^5.6.0",
|
||||
"phpstan/phpstan": "~1.10.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"nikic/php-parser": "^4.15.2",
|
||||
"orchestra/testbench": "^7.19.0 || ^8.0.0",
|
||||
"phpunit/phpunit": "^9.5.27"
|
||||
},
|
||||
"suggest": {
|
||||
"orchestra/testbench": "Using Larastan for analysing a package needs Testbench"
|
||||
},
|
||||
"type": "phpstan-extension",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"NunoMaduro\\Larastan\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nuno Maduro",
|
||||
"email": "enunomaduro@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel",
|
||||
"keywords": [
|
||||
"PHPStan",
|
||||
"code analyse",
|
||||
"code analysis",
|
||||
"larastan",
|
||||
"laravel",
|
||||
"package",
|
||||
"php",
|
||||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nunomaduro/larastan/issues",
|
||||
"source": "https://github.com/nunomaduro/larastan/tree/v2.6.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/paypalme/enunomaduro",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/canvural",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nunomaduro",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/nunomaduro",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-20T12:40:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "openlss/lib-array2xml",
|
||||
"version": "1.0.0",
|
||||
@ -15843,6 +15939,93 @@
|
||||
},
|
||||
"time": "2023-03-27T19:02:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpmyadmin/sql-parser",
|
||||
"version": "5.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpmyadmin/sql-parser.git",
|
||||
"reference": "0f5895aab2b6002d00b6831b60983523dea30bff"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/0f5895aab2b6002d00b6831b60983523dea30bff",
|
||||
"reference": "0f5895aab2b6002d00b6831b60983523dea30bff",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"conflict": {
|
||||
"phpmyadmin/motranslator": "<3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpbench/phpbench": "^1.1",
|
||||
"phpmyadmin/coding-standard": "^3.0",
|
||||
"phpmyadmin/motranslator": "^4.0 || ^5.0",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan": "^1.9.12",
|
||||
"phpstan/phpstan-phpunit": "^1.3.3",
|
||||
"phpunit/php-code-coverage": "*",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"psalm/plugin-phpunit": "^0.16.1",
|
||||
"vimeo/psalm": "^4.11",
|
||||
"zumba/json-serializer": "^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance",
|
||||
"phpmyadmin/motranslator": "Translate messages to your favorite locale"
|
||||
},
|
||||
"bin": [
|
||||
"bin/highlight-query",
|
||||
"bin/lint-query",
|
||||
"bin/tokenize-query"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpMyAdmin\\SqlParser\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-2.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The phpMyAdmin Team",
|
||||
"email": "developers@phpmyadmin.net",
|
||||
"homepage": "https://www.phpmyadmin.net/team/"
|
||||
}
|
||||
],
|
||||
"description": "A validating SQL lexer and parser with a focus on MySQL dialect.",
|
||||
"homepage": "https://github.com/phpmyadmin/sql-parser",
|
||||
"keywords": [
|
||||
"analysis",
|
||||
"lexer",
|
||||
"parser",
|
||||
"query linter",
|
||||
"sql",
|
||||
"sql lexer",
|
||||
"sql linter",
|
||||
"sql parser",
|
||||
"sql syntax highlighter",
|
||||
"sql tokenizer"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpmyadmin/sql-parser/issues",
|
||||
"source": "https://github.com/phpmyadmin/sql-parser"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.phpmyadmin.net/donate/",
|
||||
"type": "other"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-25T10:43:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.10.13",
|
||||
|
@ -15,8 +15,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.5.107',
|
||||
'app_tag' => '5.5.107',
|
||||
'app_version' => '5.5.108',
|
||||
'app_tag' => '5.5.108',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
|
@ -1,4 +1,9 @@
|
||||
includes:
|
||||
- ./vendor/nunomaduro/larastan/extension.neon
|
||||
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
- '#Call to an undefined method .*badMethod\(\)#'
|
||||
level: 2
|
||||
paths:
|
||||
- app
|
||||
|
@ -147,6 +147,77 @@ class UsTaxTest extends TestCase
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
public function testSameSubregionAndExemptProduct()
|
||||
{
|
||||
|
||||
$settings = CompanySettings::defaults();
|
||||
$settings->country_id = '840'; // germany
|
||||
|
||||
$tax_data = new TaxModel();
|
||||
$tax_data->seller_subregion = 'CA';
|
||||
$tax_data->regions->US->has_sales_above_threshold = true;
|
||||
$tax_data->regions->US->tax_all_subregions = true;
|
||||
$tax_data->regions->EU->has_sales_above_threshold = true;
|
||||
$tax_data->regions->EU->tax_all_subregions = true;
|
||||
$tax_data->regions->EU->subregions->DE->tax_rate = 21;
|
||||
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $this->account->id,
|
||||
'settings' => $settings,
|
||||
'tax_data' => $tax_data,
|
||||
'calculate_taxes' => true,
|
||||
]);
|
||||
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $company->id,
|
||||
'country_id' => 840,
|
||||
'postal_code' => '90210',
|
||||
'shipping_country_id' => 840,
|
||||
'shipping_postal_code' => '90210',
|
||||
'has_valid_vat_number' => false,
|
||||
'postal_code' => 'xx',
|
||||
'is_tax_exempt' => false,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'status_id' => 1,
|
||||
'user_id' => $this->user->id,
|
||||
'uses_inclusive_taxes' => false,
|
||||
'discount' => 0,
|
||||
'line_items' => [
|
||||
[
|
||||
'product_key' => 'Test',
|
||||
'notes' => 'Test',
|
||||
'cost' => 100,
|
||||
'quantity' => 1,
|
||||
'tax_name1' => '',
|
||||
'tax_rate1' => 0,
|
||||
'tax_name2' => '',
|
||||
'tax_rate2' => 0,
|
||||
'tax_name3' => '',
|
||||
'tax_rate3' => 0,
|
||||
'type_id' => '1',
|
||||
'tax_id' => Product::PRODUCT_TYPE_EXEMPT,
|
||||
],
|
||||
],
|
||||
'tax_rate1' => 0,
|
||||
'tax_rate2' => 0,
|
||||
'tax_rate3' => 0,
|
||||
'tax_name1' => '',
|
||||
'tax_name2' => '',
|
||||
'tax_name3' => '',
|
||||
'tax_data' => new Response($this->mock_response),
|
||||
]);
|
||||
|
||||
$invoice = $invoice->calc()->getInvoice()->service()->markSent()->save();
|
||||
|
||||
$this->assertEquals(100, $invoice->amount);
|
||||
|
||||
}
|
||||
|
||||
public function testForeignTaxesEnabledWithExemptProduct()
|
||||
{
|
||||
$settings = CompanySettings::defaults();
|
||||
@ -174,6 +245,7 @@ class UsTaxTest extends TestCase
|
||||
'shipping_country_id' => 276,
|
||||
'has_valid_vat_number' => false,
|
||||
'postal_code' => 'xx',
|
||||
'is_tax_exempt' => false,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
|
Loading…
Reference in New Issue
Block a user