Merge pull request #6647 from turbo124/v5-develop

v5.3.12
This commit is contained in:
David Bomba 2021-09-15 19:52:04 +10:00 committed by GitHub
commit 4b5fb94474
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 198 additions and 8 deletions

View File

@ -1 +1 @@
5.3.10
5.3.12

View File

@ -654,6 +654,7 @@ class CompanySettings extends BaseSettings
'$product.discount',
'$product.tax',
'$product.line_total',
'$product.gross_line_total',
],
'task_columns' =>[
'$task.service',
@ -663,9 +664,11 @@ class CompanySettings extends BaseSettings
'$task.discount',
'$task.tax',
'$task.line_total',
'$task.gross_line_total',
],
'total_columns' => [
'$net_subtotal',
'$gross_subtotal',
'$subtotal',
'$discount',
'$custom_surcharge1',

View File

@ -43,6 +43,8 @@ class InvoiceItem
public $line_total = 0;
public $gross_line_total = 0;
public $date = '';
public $custom_value1 = '';
@ -72,6 +74,7 @@ class InvoiceItem
'tax_rate3' => 'float',
'sort_id' => 'string',
'line_total' => 'float',
'gross_line_total' => 'float',
'date' => 'string',
'custom_value1' => 'string',
'custom_value2' => 'string',

View File

@ -35,6 +35,7 @@ class InvoiceItemFactory
$item->tax_rate3 = 0;
$item->sort_id = 0;
$item->line_total = 0;
$item->gross_line_total = 0;
$item->custom_value1 = '';
$item->custom_value2 = '';
$item->custom_value3 = '';

View File

@ -28,6 +28,8 @@ class InvoiceItemSum
private $line_total;
private $gross_line_total;
private $currency;
private $total_taxes;
@ -38,6 +40,8 @@ class InvoiceItemSum
private $sub_total;
private $gross_sub_total;
private $total_discount;
private $tax_collection;
@ -83,6 +87,8 @@ class InvoiceItemSum
{
$this->sub_total += $this->getLineTotal();
$this->gross_sub_total += $this->getGrossLineTotal();
$this->line_items[] = $this->item;
return $this;
@ -144,10 +150,11 @@ class InvoiceItemSum
if($item_tax_rate3_total != 0)
$this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
$this->setTotalTaxes($this->formatValue($item_tax, $this->currency->precision));
$this->item->gross_line_total = $this->getLineTotal() + $item_tax;
return $this;
}
@ -186,6 +193,11 @@ class InvoiceItemSum
return $this->item->line_total;
}
public function getGrossLineTotal()
{
return $this->item->gross_line_total;
}
public function getLineItems()
{
return $this->line_items;
@ -208,6 +220,11 @@ class InvoiceItemSum
return $this->sub_total;
}
public function getGrossSubTotal()
{
return $this->gross_sub_total;
}
public function setSubTotal($value)
{
$this->sub_total = $value;
@ -263,6 +280,7 @@ class InvoiceItemSum
if ($item_tax_rate3_total != 0) {
$this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
}
}
$this->setTotalTaxes($item_tax);

View File

@ -177,6 +177,11 @@ class InvoiceItemSumInclusive
return $this->item->line_total;
}
public function getGrossLineTotal()
{
return $this->item->line_total;
}
public function getLineItems()
{
return $this->line_items;
@ -199,6 +204,11 @@ class InvoiceItemSumInclusive
return $this->sub_total;
}
public function getGrossSubTotal()
{
return $this->sub_total;
}
public function setSubTotal($value)
{
$this->sub_total = $value;

View File

@ -42,6 +42,8 @@ class InvoiceSum
private $sub_total;
private $gross_sub_total;
/**
* Constructs the object with Invoice and Settings object.
*
@ -75,7 +77,8 @@ class InvoiceSum
$this->invoice->line_items = $this->invoice_items->getLineItems();
$this->total = $this->invoice_items->getSubTotal();
$this->setSubTotal($this->invoice_items->getSubTotal());
$this->setGrossSubTotal($this->invoice_items->getGrossSubTotal());
return $this;
}
@ -266,6 +269,18 @@ class InvoiceSum
return $this;
}
public function getGrossSubTotal()
{
return $this->gross_sub_total;
}
public function setGrossSubTotal($value)
{
$this->gross_sub_total = $value;
return $this;
}
public function getTotalDiscount()
{
return $this->total_discount;

View File

@ -259,6 +259,11 @@ class InvoiceSumInclusive
return $this->sub_total;
}
public function getGrossSubTotal()
{
return $this->sub_total;
}
public function setSubTotal($value)
{
$this->sub_total = $value;

View File

@ -738,6 +738,7 @@ class BaseController extends Controller
//pass referral code to front end
$data['rc'] = request()->has('rc') ? request()->input('rc') : '';
$data['build'] = request()->has('build') ? request()->input('build') : '';
$data['user_agent'] = request()->server('HTTP_USER_AGENT');
$data['path'] = $this->setBuild();

View File

@ -512,6 +512,9 @@ class ClientController extends BaseController
$ids = request()->input('ids');
$clients = Client::withTrashed()->whereIn('id', $this->transformKeys($ids))->cursor();
if(!in_array($action, ['restore','archive','delete']))
return response()->json(['message' => 'That action is not available.'], 400);
$clients->each(function ($client, $key) use ($action) {
if (auth()->user()->can('edit', $client)) {
$this->client_repo->{$action}($client);

View File

@ -210,7 +210,10 @@ class QuoteController extends BaseController
$quote = $this->quote_repo->save($request->all(), QuoteFactory::create(auth()->user()->company()->id, auth()->user()->id));
$quote = $quote->service()->fillDefaults()->save();
$quote = $quote->service()
->fillDefaults()
->triggeredActions($request)
->save();
event(new QuoteWasCreated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));

View File

@ -75,7 +75,6 @@ class Client extends BaseModel implements HasLocalePreference
'shipping_postal_code',
'shipping_country_id',
'settings',
'payment_terms',
'vat_number',
'id_number',
'group_settings_id',

View File

@ -42,6 +42,7 @@ class SOFORT
$data['return_url'] = $this->buildReturnUrl();
$data['stripe_amount'] = $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency());
$data['client'] = $this->stripe->client;
$data['customer'] = $this->stripe->findOrCreateCustomer()->id;
$data['country'] = $this->stripe->client->country->iso_3166_2;
$this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, ['stripe_amount' => $data['stripe_amount']]);

View File

@ -16,6 +16,7 @@ use App\Jobs\Util\UnlinkFile;
use App\Models\Invoice;
use App\Models\Quote;
use App\Repositories\QuoteRepository;
use App\Services\Quote\TriggeredActions;
use App\Utils\Ninja;
use App\Utils\Traits\MakesHash;
@ -177,6 +178,13 @@ class QuoteService
return $this;
}
public function triggeredActions($request)
{
$this->quote = (new TriggeredActions($this->quote, $request))->run();
return $this;
}
public function deletePdf()
{
$this->quote->invitations->each(function ($invitation){

View File

@ -0,0 +1,66 @@
<?php
/**
* Quote Ninja (https://quoteninja.com).
*
* @link https://github.com/quoteninja/quoteninja source repository
*
* @copyright Copyright (c) 2021. Quote Ninja LLC (https://quoteninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Services\Quote;
use App\Events\Quote\QuoteWasEmailed;
use App\Jobs\Entity\EmailEntity;
use App\Models\Quote;
use App\Services\AbstractService;
use App\Utils\Ninja;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Http\Request;
class TriggeredActions extends AbstractService
{
use GeneratesCounter;
private $request;
private $quote;
public function __construct(Quote $quote, Request $request)
{
$this->request = $request;
$this->quote = $quote;
}
public function run()
{
if ($this->request->has('send_email') && $this->request->input('send_email') == 'true') {
$this->sendEmail();
}
if ($this->request->has('mark_sent') && $this->request->input('mark_sent') == 'true') {
$this->quote = $this->quote->service()->markSent()->save();
}
return $this->quote;
}
private function sendEmail()
{
$reminder_template = $this->quote->calculateTemplate('quote');
//$reminder_template = 'payment';
$this->quote->invitations->load('contact.client.country', 'quote.client.country', 'quote.company')->each(function ($invitation) use ($reminder_template) {
EmailEntity::dispatch($invitation, $this->quote->company, $reminder_template);
});
if ($this->quote->invitations->count() > 0) {
event(new QuoteWasEmailed($this->quote->invitations->first(), $this->quote->company, Ninja::eventVars(), 'quote'));
}
}
}

View File

@ -175,6 +175,7 @@ class HtmlEngine
$data['$invoice.discount'] = ['value' => Number::formatMoney($this->entity_calc->getTotalDiscount(), $this->client) ?: '&nbsp;', 'label' => ctrans('texts.discount')];
$data['$discount'] = &$data['$invoice.discount'];
$data['$subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getSubTotal(), $this->client) ?: '&nbsp;', 'label' => ctrans('texts.subtotal')];
$data['$gross_subtotal'] = ['value' => Number::formatMoney($this->entity_calc->getGrossSubTotal(), $this->client) ?: '&nbsp;', 'label' => ctrans('texts.subtotal')];
if($this->entity->uses_inclusive_taxes)
$data['$net_subtotal'] = ['value' => Number::formatMoney(($this->entity_calc->getSubTotal() - $this->entity->total_taxes), $this->client) ?: '&nbsp;', 'label' => ctrans('texts.net_subtotal')];
@ -380,6 +381,7 @@ class HtmlEngine
$data['$product.tax_name2'] = ['value' => '', 'label' => ctrans('texts.tax')];
$data['$product.tax_name3'] = ['value' => '', 'label' => ctrans('texts.tax')];
$data['$product.line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
$data['$product.gross_line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
$data['$product.description'] = ['value' => '', 'label' => ctrans('texts.description')];
$data['$product.unit_cost'] = ['value' => '', 'label' => ctrans('texts.unit_cost')];
$data['$product.product1'] = ['value' => '', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'product1')];
@ -399,6 +401,7 @@ class HtmlEngine
$data['$task.tax_name2'] = ['value' => '', 'label' => ctrans('texts.tax')];
$data['$task.tax_name3'] = ['value' => '', 'label' => ctrans('texts.tax')];
$data['$task.line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
$data['$task.gross_line_total'] = ['value' => '', 'label' => ctrans('texts.line_total')];
$data['$task.service'] = ['value' => '', 'label' => ctrans('texts.service')];
$data['$task.task1'] = ['value' => '', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'task1')];
$data['$task.task2'] = ['value' => '', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'task2')];

View File

@ -311,6 +311,7 @@ trait MakesInvoiceValues
$data[$key][$table_type.'.cost'] = Number::formatMoney($item->cost, $this->client);
$data[$key][$table_type.'.line_total'] = Number::formatMoney($item->line_total, $this->client);
$data[$key][$table_type.'.gross_line_total'] = Number::formatMoney($item->gross_line_total, $this->client);
if (isset($item->discount) && $item->discount > 0) {
if ($item->is_amount_discount) {

View File

@ -14,8 +14,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => '5.3.10',
'app_tag' => '5.3.10',
'app_version' => '5.3.12',
'app_tag' => '5.3.12',
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', ''),

View File

@ -27,6 +27,7 @@ class ProcessSOFORT {
handle = () => {
let data = {
type: 'sofort',
customer: document.querySelector('meta[name="customer"]').content,
amount: document.querySelector('meta[name="amount"]').content,
currency: 'eur',
redirect: {

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html data-report-errors="{{ $report_errors }}" data-rc="{{ $rc }}" data-build="{{ $build }}">
<html data-report-errors="{{ $report_errors }}" data-rc="{{ $rc }}" data-build="{{ $build }}" user-agent="{{ $user_agent }}">
<head>
<!-- Source: https://github.com/invoiceninja/invoiceninja -->
<!-- Version: {{ config('ninja.app_version') }} -->

View File

@ -6,6 +6,7 @@
<meta name="return-url" content="{{ $return_url }}">
<meta name="amount" content="{{ $stripe_amount }}">
<meta name="country" content="{{ $country }}">
<meta name="customer" content="{{ $customer }}">
@endsection
@section('gateway_content')

View File

@ -51,6 +51,29 @@ class InvoiceItemTest extends TestCase
$this->assertEquals($item_calc->getLineTotal(), 10);
}
public function testInvoiceItemTotalSimpleWithGrossTaxes()
{
$item = InvoiceItemFactory::create();
$item->quantity = 1;
$item->cost = 10;
$item->is_amount_discount = true;
$item->tax_rate1 = 10;
$settings = new \stdClass;
$settings->inclusive_taxes = false;
$settings->precision = 2;
$this->invoice->line_items = [$item];
$item_calc = new InvoiceItemSum($this->invoice, $settings);
$item_calc->process();
$this->assertEquals($item_calc->getLineTotal(), 10);
$this->assertEquals($item_calc->getGrossLineTotal(), 11);
}
public function testInvoiceItemTotalSimpleWithDiscount()
{
$item = InvoiceItemFactory::create();
@ -71,6 +94,29 @@ class InvoiceItemTest extends TestCase
$this->assertEquals($item_calc->getLineTotal(), 8);
}
public function testInvoiceItemTotalSimpleWithDiscountAndGrossLineTotal()
{
$item = InvoiceItemFactory::create();
$item->quantity = 1;
$item->cost = 10;
$item->is_amount_discount = true;
$item->discount = 2;
$item->tax_rate1 = 10;
$this->invoice->line_items = [$item];
$settings = new \stdClass;
$settings->inclusive_taxes = false;
$settings->precision = 2;
$item_calc = new InvoiceItemSum($this->invoice, $settings);
$item_calc->process();
$this->assertEquals($item_calc->getLineTotal(), 8);
$this->assertEquals($item_calc->getGrossLineTotal(), 8.8);
}
public function testInvoiceItemTotalSimpleWithDiscountWithPrecision()
{
$item = InvoiceItemFactory::create();

View File

@ -123,6 +123,7 @@ class InvoiceTest extends TestCase
$this->invoice_calc->build();
$this->assertEquals($this->invoice_calc->getSubTotal(), 20);
// $this->assertEquals($this->invoice_calc->getGrossSubTotal(), 22);
//$this->assertEquals($this->invoice_calc->getTotal(), 21.5);
//$this->assertEquals($this->invoice_calc->getBalance(), 21.5);
//$this->assertEquals($this->invoice_calc->getTotalTaxes(), 1.5);
@ -216,6 +217,7 @@ class InvoiceTest extends TestCase
$this->invoice_calc->build();
$this->assertEquals($this->invoice_calc->getSubTotal(), 20);
$this->assertEquals($this->invoice_calc->getGrossSubTotal(), 22);
//$this->assertEquals($this->invoice_calc->getTotal(), 26);
//$this->assertEquals($this->invoice_calc->getBalance(), 26);
//$this->assertEquals($this->invoice_calc->getTotalTaxes(), 4);