mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 13:12:50 +01:00
commit
9c518bfff8
2
.github/workflows/react_release.yml
vendored
2
.github/workflows/react_release.yml
vendored
@ -38,8 +38,6 @@ jobs:
|
|||||||
sudo php artisan cache:clear
|
sudo php artisan cache:clear
|
||||||
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
|
sudo find ./vendor/bin/ -type f -exec chmod +x {} \;
|
||||||
sudo find ./ -type d -exec chmod 755 {} \;
|
sudo find ./ -type d -exec chmod 755 {} \;
|
||||||
sudo rm -f public/main.*
|
|
||||||
sudo rm -f public/flutter*
|
|
||||||
|
|
||||||
- name: Prepare React FrontEnd
|
- name: Prepare React FrontEnd
|
||||||
run: |
|
run: |
|
||||||
|
@ -1 +1 @@
|
|||||||
5.8.46
|
5.8.47
|
@ -27,10 +27,28 @@ trait CustomValuer
|
|||||||
|
|
||||||
public function valuerTax($custom_value, $has_custom_invoice_taxes)
|
public function valuerTax($custom_value, $has_custom_invoice_taxes)
|
||||||
{
|
{
|
||||||
if (isset($custom_value) && is_numeric($custom_value) && $has_custom_invoice_taxes) {
|
|
||||||
|
if (isset($custom_value) && is_numeric($custom_value) && $has_custom_invoice_taxes !== false) {
|
||||||
return round($custom_value * ($this->invoice->tax_rate1 / 100), 2) + round($custom_value * ($this->invoice->tax_rate2 / 100), 2) + round($custom_value * ($this->invoice->tax_rate3 / 100), 2);
|
return round($custom_value * ($this->invoice->tax_rate1 / 100), 2) + round($custom_value * ($this->invoice->tax_rate2 / 100), 2) + round($custom_value * ($this->invoice->tax_rate3 / 100), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function multiInclusiveTax($value, $has_custom_invoice_taxes) {
|
||||||
|
|
||||||
|
if (isset($custom_value) && is_numeric($custom_value) && $has_custom_invoice_taxes !== false) {
|
||||||
|
|
||||||
|
$tax = 0;
|
||||||
|
|
||||||
|
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate1 / 100))), 2);
|
||||||
|
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate2 / 100))), 2);
|
||||||
|
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate3 / 100))), 2);
|
||||||
|
|
||||||
|
return round($tax,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,18 +106,20 @@ class InvoiceSumInclusive
|
|||||||
|
|
||||||
private function calculateCustomValues()
|
private function calculateCustomValues()
|
||||||
{
|
{
|
||||||
$this->total_taxes += $this->valuerTax($this->invoice->custom_surcharge1, $this->invoice->custom_surcharge_tax1);
|
|
||||||
|
$this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge1, $this->invoice->custom_surcharge_tax1);
|
||||||
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge1);
|
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge1);
|
||||||
|
|
||||||
$this->total_taxes += $this->valuerTax($this->invoice->custom_surcharge2, $this->invoice->custom_surcharge_tax2);
|
$this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge2, $this->invoice->custom_surcharge_tax2);
|
||||||
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge2);
|
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge2);
|
||||||
|
|
||||||
$this->total_taxes += $this->valuerTax($this->invoice->custom_surcharge3, $this->invoice->custom_surcharge_tax3);
|
$this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge3, $this->invoice->custom_surcharge_tax3);
|
||||||
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge3);
|
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge3);
|
||||||
|
|
||||||
$this->total_taxes += $this->valuerTax($this->invoice->custom_surcharge4, $this->invoice->custom_surcharge_tax4);
|
$this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge4, $this->invoice->custom_surcharge_tax4);
|
||||||
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge4);
|
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge4);
|
||||||
|
|
||||||
|
|
||||||
$this->total += $this->total_custom_values;
|
$this->total += $this->total_custom_values;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -126,7 +128,7 @@ class InvoiceSumInclusive
|
|||||||
private function calculateInvoiceTaxes()
|
private function calculateInvoiceTaxes()
|
||||||
{
|
{
|
||||||
$amount = $this->total;
|
$amount = $this->total;
|
||||||
|
|
||||||
if ($this->invoice->discount > 0 && $this->invoice->is_amount_discount) {
|
if ($this->invoice->discount > 0 && $this->invoice->is_amount_discount) {
|
||||||
$amount = $this->formatValue(($this->sub_total - $this->invoice->discount), 2);
|
$amount = $this->formatValue(($this->sub_total - $this->invoice->discount), 2);
|
||||||
}
|
}
|
||||||
@ -135,6 +137,23 @@ class InvoiceSumInclusive
|
|||||||
$amount = $this->formatValue(($this->sub_total - ($this->sub_total * ($this->invoice->discount / 100))), 2);
|
$amount = $this->formatValue(($this->sub_total - ($this->sub_total * ($this->invoice->discount / 100))), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Handles cases where the surcharge is not taxed
|
||||||
|
if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && $this->invoice->custom_surcharge_tax1) {
|
||||||
|
$amount += $this->invoice->custom_surcharge1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && $this->invoice->custom_surcharge_tax2) {
|
||||||
|
$amount += $this->invoice->custom_surcharge2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && $this->invoice->custom_surcharge_tax3) {
|
||||||
|
$amount += $this->invoice->custom_surcharge3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && $this->invoice->custom_surcharge_tax4) {
|
||||||
|
$amount += $this->invoice->custom_surcharge4;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_string($this->invoice->tax_name1) && strlen($this->invoice->tax_name1) > 1) {
|
if (is_string($this->invoice->tax_name1) && strlen($this->invoice->tax_name1) > 1) {
|
||||||
$tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount);
|
$tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount);
|
||||||
$this->total_taxes += $tax;
|
$this->total_taxes += $tax;
|
||||||
@ -354,7 +373,7 @@ class InvoiceSumInclusive
|
|||||||
|
|
||||||
$this->total_taxes += $total_line_tax;
|
$this->total_taxes += $total_line_tax;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,11 @@ class Invoice extends BaseModel
|
|||||||
'is_deleted' => 'bool',
|
'is_deleted' => 'bool',
|
||||||
'is_amount_discount' => 'bool',
|
'is_amount_discount' => 'bool',
|
||||||
'tax_data' => 'object',
|
'tax_data' => 'object',
|
||||||
'partial_due_date' => 'date:Y-m-d'
|
'partial_due_date' => 'date:Y-m-d',
|
||||||
|
'custom_surcharge_tax1' => 'bool',
|
||||||
|
'custom_surcharge_tax2' => 'bool',
|
||||||
|
'custom_surcharge_tax3' => 'bool',
|
||||||
|
'custom_surcharge_tax4' => 'bool',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $with = [];
|
protected $with = [];
|
||||||
|
@ -685,7 +685,7 @@ class StripePaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
//payment_intent.succeeded - this will confirm or cancel the payment
|
//payment_intent.succeeded - this will confirm or cancel the payment
|
||||||
if ($request->type === 'payment_intent.succeeded') {
|
if ($request->type === 'payment_intent.succeeded') {
|
||||||
PaymentIntentWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(rand(5, 10)));
|
PaymentIntentWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(rand(10, 15)));
|
||||||
|
|
||||||
return response()->json([], 200);
|
return response()->json([], 200);
|
||||||
}
|
}
|
||||||
|
@ -19,37 +19,37 @@ use SimpleXMLElement;
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<FatturaElettronica versione="FPR12" xmlns="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2">
|
<FatturaElettronica versione="FPR12" xmlns="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2">
|
||||||
<FatturaElettronicaHeader>
|
<FatturaElettronicaHeader>
|
||||||
<DatiTrasmissione>
|
<DatiTrasmissione>// Transmission data
|
||||||
<IdTrasmittente>
|
<IdTrasmittente>// Transmitter ID
|
||||||
<IdPaese>IT</IdPaese>
|
<IdPaese>IT</IdPaese> //Country code
|
||||||
<IdCodice>01234567890</IdCodice>
|
<IdCodice>01234567890</IdCodice> //Taxpayer code
|
||||||
</IdTrasmittente>
|
</IdTrasmittente>
|
||||||
<ProgressivoInvio>00001</ProgressivoInvio>
|
<ProgressivoInvio>00001</ProgressivoInvio> // Transmission progress
|
||||||
<FormatoTrasmissione>FPR12</FormatoTrasmissione>
|
<FormatoTrasmissione>FPR12</FormatoTrasmissione>// Transmission format
|
||||||
<CodiceDestinatario>ABCDE1</CodiceDestinatario>
|
<CodiceDestinatario>ABCDE1</CodiceDestinatario>// Receiver code
|
||||||
</DatiTrasmissione>
|
</DatiTrasmissione>
|
||||||
<CedentePrestatore>
|
<CedentePrestatore>//Seller/Provider
|
||||||
<!-- Company information of the sender (seller/provider) -->
|
<!-- Company information of the sender (seller/provider) -->
|
||||||
</CedentePrestatore>
|
</CedentePrestatore>
|
||||||
<CessionarioCommittente>
|
<CessionarioCommittente>//Buyer/Recipient
|
||||||
<!-- Company information of the receiver (buyer) -->
|
<!-- Company information of the receiver (buyer) -->
|
||||||
</CessionarioCommittente>
|
</CessionarioCommittente>
|
||||||
</FatturaElettronicaHeader>
|
</FatturaElettronicaHeader>
|
||||||
<FatturaElettronicaBody>
|
<FatturaElettronicaBody>
|
||||||
<DatiGenerali>
|
<DatiGenerali>//General data
|
||||||
<DatiGeneraliDocumento>
|
<DatiGeneraliDocumento>// Document general data
|
||||||
<TipoDocumento>TD01</TipoDocumento>
|
<TipoDocumento>TD01</TipoDocumento>// Document type
|
||||||
<Divisa>EUR</Divisa>
|
<Divisa>EUR</Divisa>// Currency
|
||||||
<Data>2023-04-21</Data>
|
<Data>2023-04-21</Data>// Date
|
||||||
<Numero>1</Numero>
|
<Numero>1</Numero>// Number
|
||||||
<!-- Add other information as needed -->
|
<!-- Add other information as needed -->
|
||||||
</DatiGeneraliDocumento>
|
</DatiGeneraliDocumento>
|
||||||
<!-- Add other general data as needed -->
|
<!-- Add other general data as needed -->
|
||||||
</DatiGenerali>
|
</DatiGenerali>
|
||||||
<DatiBeniServizi>
|
<DatiBeniServizi>//Goods and services data
|
||||||
<!-- List of items or services -->
|
<!-- List of items or services -->
|
||||||
</DatiBeniServizi>
|
</DatiBeniServizi>
|
||||||
<DatiPagamento>
|
<DatiPagamento>//Payment data
|
||||||
<!-- Payment details -->
|
<!-- Payment details -->
|
||||||
</DatiPagamento>
|
</DatiPagamento>
|
||||||
</FatturaElettronicaBody>
|
</FatturaElettronicaBody>
|
||||||
@ -60,6 +60,20 @@ class FatturaPA extends AbstractService
|
|||||||
{
|
{
|
||||||
private $xml;
|
private $xml;
|
||||||
|
|
||||||
|
//urn:cen.eu:en16931:2017#compliant#urn:fatturapa.gov.it:CIUS-IT:2.0.0
|
||||||
|
//<cbc:EndpointID schemeID=" 0201 ">UFF001</cbc:EndpointID>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Types
|
||||||
|
*
|
||||||
|
* EI01 => FILE VUOTO
|
||||||
|
* EI02 => SERVIZIO NON DISPONIBILE
|
||||||
|
* EI03 => UTENTE NON ABILITATO
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Invoice $invoice
|
||||||
|
*/
|
||||||
public function __construct(public Invoice $invoice)
|
public function __construct(public Invoice $invoice)
|
||||||
{
|
{
|
||||||
$this->xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><FatturaElettronica></FatturaElettronica>');
|
$this->xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><FatturaElettronica></FatturaElettronica>');
|
||||||
|
@ -201,11 +201,12 @@ class SystemHealth
|
|||||||
|
|
||||||
private static function simpleDbCheck(): bool
|
private static function simpleDbCheck(): bool
|
||||||
{
|
{
|
||||||
$result = true;
|
$result = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$pdo = DB::connection()->getPdo();
|
$result = DB::connection()->getPdo();
|
||||||
$result = true;
|
$result = true;
|
||||||
|
$result = DB::connection()->getDatabaseName() && strlen(DB::connection()->getDatabaseName()) > 1;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$result = false;
|
$result = false;
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||||
'app_version' => env('APP_VERSION', '5.8.46'),
|
'app_version' => env('APP_VERSION', '5.8.47'),
|
||||||
'app_tag' => env('APP_TAG', '5.8.46'),
|
'app_tag' => env('APP_TAG', '5.8.47'),
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', false),
|
'api_secret' => env('API_SECRET', false),
|
||||||
|
@ -21,7 +21,7 @@ return new class extends Migration {
|
|||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
Schema::table('accounts', function (Blueprint $table) {
|
Schema::table('accounts', function (Blueprint $table) {
|
||||||
$table->boolean('set_react_as_default_ap')->default(0);
|
$table->boolean('set_react_as_default_ap')->default(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ CREATE TABLE `accounts` (
|
|||||||
`hosted_client_count` int(10) unsigned DEFAULT NULL,
|
`hosted_client_count` int(10) unsigned DEFAULT NULL,
|
||||||
`hosted_company_count` int(10) unsigned DEFAULT NULL,
|
`hosted_company_count` int(10) unsigned DEFAULT NULL,
|
||||||
`inapp_transaction_id` varchar(100) DEFAULT NULL,
|
`inapp_transaction_id` varchar(100) DEFAULT NULL,
|
||||||
`set_react_as_default_ap` tinyint(1) NOT NULL DEFAULT 0,
|
`set_react_as_default_ap` tinyint(1) NOT NULL DEFAULT 1,
|
||||||
`is_flagged` tinyint(1) NOT NULL DEFAULT 0,
|
`is_flagged` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
`is_verified_account` tinyint(1) NOT NULL DEFAULT 0,
|
`is_verified_account` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
`account_sms_verification_code` text DEFAULT NULL,
|
`account_sms_verification_code` text DEFAULT NULL,
|
||||||
|
9
public/build/assets/setup-66b6b3c0.js
vendored
Normal file
9
public/build/assets/setup-66b6b3c0.js
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import{A as a}from"./index-08e160a7.js";import"./_commonjsHelpers-725317a4.js";/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/class c{constructor(){this.checkDbButton=document.getElementById("test-db-connection"),this.checkDbAlert=document.getElementById("database-response")}handleDatabaseCheck(){let e=document.querySelector("meta[name=setup-db-check]").content,t={};document.querySelector('input[name="db_host"]')&&(t={db_host:document.querySelector('input[name="db_host"]').value,db_port:document.querySelector('input[name="db_port"]').value,db_database:document.querySelector('input[name="db_database"]').value,db_username:document.querySelector('input[name="db_username"]').value,db_password:document.querySelector('input[name="db_password"]').value}),this.checkDbButton.disabled=!0,a.post(e,t).then(s=>{this.handleSuccess(this.checkDbAlert,"account-wrapper"),this.handleSuccess(this.checkDbAlert,"submit-wrapper")}).catch(s=>this.handleFailure(this.checkDbAlert,s.response.data.message)).finally(()=>this.checkDbButton.disabled=!1)}handleSuccess(e,t=null){e.classList.remove("alert-failure"),e.innerText="Success!",e.classList.add("alert-success"),t&&(document.getElementById(t).classList.remove("hidden"),document.getElementById(t).scrollIntoView({behavior:"smooth",block:"center"}))}handleFailure(e,t=null){e.classList.remove("alert-success"),e.innerText=t||"Oops, looks like something isn't correct!",e.classList.add("alert-failure")}handle(){this.checkDbButton.addEventListener("click",()=>this.handleDatabaseCheck())}}new c().handle();
|
9
public/build/assets/setup-81f58464.js
vendored
9
public/build/assets/setup-81f58464.js
vendored
@ -1,9 +0,0 @@
|
|||||||
import{A as s}from"./index-08e160a7.js";import"./_commonjsHelpers-725317a4.js";/**
|
|
||||||
* Invoice Ninja (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @license https://www.elastic.co/licensing/elastic-license
|
|
||||||
*/class a{constructor(){this.checkDbButton=document.getElementById("test-db-connection"),this.checkDbAlert=document.getElementById("database-response"),this.checkSmtpButton=document.getElementById("test-smtp-connection"),this.checkSmtpAlert=document.getElementById("smtp-response"),this.checkPdfButton=document.getElementById("test-pdf"),this.checkPdfAlert=document.getElementById("test-pdf-response")}handleDatabaseCheck(){let t=document.querySelector("meta[name=setup-db-check]").content,e={};document.querySelector('input[name="db_host"]')&&(e={db_host:document.querySelector('input[name="db_host"]').value,db_port:document.querySelector('input[name="db_port"]').value,db_database:document.querySelector('input[name="db_database"]').value,db_username:document.querySelector('input[name="db_username"]').value,db_password:document.querySelector('input[name="db_password"]').value}),this.checkDbButton.disabled=!0,s.post(t,e).then(c=>this.handleSuccess(this.checkDbAlert,"mail-wrapper")).catch(c=>this.handleFailure(this.checkDbAlert,c.response.data.message)).finally(()=>this.checkDbButton.disabled=!1)}handleSmtpCheck(){let t=document.querySelector("meta[name=setup-email-check]").content,e={mail_driver:document.querySelector('select[name="mail_driver"]').value,mail_name:document.querySelector('input[name="mail_name"]').value,mail_address:document.querySelector('input[name="mail_address"]').value,mail_username:document.querySelector('input[name="mail_username"]').value,mail_host:document.querySelector('input[name="mail_host"]').value,mail_port:document.querySelector('input[name="mail_port"]').value,encryption:document.querySelector('select[name="encryption"]').value,mail_password:document.querySelector('input[name="mail_password"]').value};if(this.checkSmtpButton.disabled=!0,e.mail_driver==="log")return this.handleSuccess(this.checkSmtpAlert,"account-wrapper"),this.handleSuccess(this.checkSmtpAlert,"submit-wrapper"),this.checkSmtpButton.disabled=!1;s.post(t,e).then(c=>{this.handleSuccess(this.checkSmtpAlert,"account-wrapper"),this.handleSuccess(this.checkSmtpAlert,"submit-wrapper")}).catch(c=>this.handleFailure(this.checkSmtpAlert,c.response.data.message)).finally(()=>this.checkSmtpButton.disabled=!1)}handleTestPdfCheck(){let t=document.querySelector("meta[name=setup-pdf-check]").content;this.checkPdfButton.disabled=!0,s.post(t,{}).then(e=>{try{return this.handleSuccess(this.checkPdfAlert,"database-wrapper")}catch{this.handleSuccess(this.checkPdfAlert,"database-wrapper"),this.checkPdfAlert.textContent="Success! PDF was generated succesfully."}}).catch(e=>{console.log(e),this.handleFailure(this.checkPdfAlert)}).finally(()=>this.checkPdfButton.disabled=!1)}handleSuccess(t,e=null){t.classList.remove("alert-failure"),t.innerText="Success!",t.classList.add("alert-success"),e&&(document.getElementById(e).classList.remove("hidden"),document.getElementById(e).scrollIntoView({behavior:"smooth",block:"center"}))}handleFailure(t,e=null){t.classList.remove("alert-success"),t.innerText=e||"Oops, looks like something isn't correct!",t.classList.add("alert-failure")}handle(){this.checkDbButton.addEventListener("click",()=>this.handleDatabaseCheck()),this.checkSmtpButton.addEventListener("click",()=>this.handleSmtpCheck()),this.checkPdfButton.addEventListener("click",()=>this.handleTestPdfCheck())}}new a().handle();
|
|
@ -231,7 +231,7 @@
|
|||||||
"src": "resources/js/clients/statements/view.js"
|
"src": "resources/js/clients/statements/view.js"
|
||||||
},
|
},
|
||||||
"resources/js/setup/setup.js": {
|
"resources/js/setup/setup.js": {
|
||||||
"file": "assets/setup-81f58464.js",
|
"file": "assets/setup-66b6b3c0.js",
|
||||||
"imports": [
|
"imports": [
|
||||||
"_index-08e160a7.js",
|
"_index-08e160a7.js",
|
||||||
"__commonjsHelpers-725317a4.js"
|
"__commonjsHelpers-725317a4.js"
|
||||||
|
1
public/js/assets/admin-4ed993c7.js
vendored
Normal file
1
public/js/assets/admin-4ed993c7.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
1
public/js/assets/app-2d547327.css
vendored
Normal file
1
public/js/assets/app-2d547327.css
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
@tailwind base;@tailwind components;@tailwind utilities;.pagination{@apply flex items-center !important;}.pagination .page-link{@apply -mt-px border-t-2 border-transparent pt-4 px-4 inline-flex items-center text-sm leading-5 font-medium text-gray-500 transition ease-in-out duration-150 cursor-pointer !important;}.pagination .page-link:hover{@apply text-gray-700 border-gray-300 !important;}.pagination .page-link:focus{@apply outline-none text-gray-700 border-gray-400;}.pagination .active>span{@apply text-blue-600 border-blue-600 !important;}
|
84
resources/js/setup/setup.js
vendored
84
resources/js/setup/setup.js
vendored
@ -14,12 +14,6 @@ class Setup {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.checkDbButton = document.getElementById('test-db-connection');
|
this.checkDbButton = document.getElementById('test-db-connection');
|
||||||
this.checkDbAlert = document.getElementById('database-response');
|
this.checkDbAlert = document.getElementById('database-response');
|
||||||
|
|
||||||
this.checkSmtpButton = document.getElementById('test-smtp-connection');
|
|
||||||
this.checkSmtpAlert = document.getElementById('smtp-response');
|
|
||||||
|
|
||||||
this.checkPdfButton = document.getElementById('test-pdf');
|
|
||||||
this.checkPdfAlert = document.getElementById('test-pdf-response');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDatabaseCheck() {
|
handleDatabaseCheck() {
|
||||||
@ -42,78 +36,16 @@ class Setup {
|
|||||||
this.checkDbButton.disabled = true;
|
this.checkDbButton.disabled = true;
|
||||||
|
|
||||||
Axios.post(url, data)
|
Axios.post(url, data)
|
||||||
.then((response) =>
|
.then((response) =>{
|
||||||
this.handleSuccess(this.checkDbAlert, 'mail-wrapper')
|
this.handleSuccess(this.checkDbAlert, 'account-wrapper');
|
||||||
|
this.handleSuccess(this.checkDbAlert, 'submit-wrapper');
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.catch((e) =>
|
.catch((e) =>
|
||||||
this.handleFailure(this.checkDbAlert, e.response.data.message)
|
this.handleFailure(this.checkDbAlert, e.response.data.message)
|
||||||
).finally(() => this.checkDbButton.disabled = false);
|
).finally(() => this.checkDbButton.disabled = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSmtpCheck() {
|
|
||||||
let url = document.querySelector('meta[name=setup-email-check]').content;
|
|
||||||
|
|
||||||
let data = {
|
|
||||||
mail_driver: document.querySelector('select[name="mail_driver"]')
|
|
||||||
.value,
|
|
||||||
mail_name: document.querySelector('input[name="mail_name"]').value,
|
|
||||||
mail_address: document.querySelector('input[name="mail_address"]')
|
|
||||||
.value,
|
|
||||||
mail_username: document.querySelector('input[name="mail_username"]')
|
|
||||||
.value,
|
|
||||||
mail_host: document.querySelector('input[name="mail_host"]').value,
|
|
||||||
mail_port: document.querySelector('input[name="mail_port"]').value,
|
|
||||||
encryption: document.querySelector('select[name="encryption"]')
|
|
||||||
.value,
|
|
||||||
mail_password: document.querySelector('input[name="mail_password"]')
|
|
||||||
.value,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.checkSmtpButton.disabled = true;
|
|
||||||
|
|
||||||
if (data.mail_driver === 'log') {
|
|
||||||
this.handleSuccess(this.checkSmtpAlert, 'account-wrapper');
|
|
||||||
this.handleSuccess(this.checkSmtpAlert, 'submit-wrapper');
|
|
||||||
|
|
||||||
return (this.checkSmtpButton.disabled = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Axios.post(url, data)
|
|
||||||
.then((response) => {
|
|
||||||
this.handleSuccess(this.checkSmtpAlert, 'account-wrapper');
|
|
||||||
this.handleSuccess(this.checkSmtpAlert, 'submit-wrapper');
|
|
||||||
})
|
|
||||||
.catch((e) =>
|
|
||||||
this.handleFailure(this.checkSmtpAlert, e.response.data.message)
|
|
||||||
)
|
|
||||||
.finally(() => (this.checkSmtpButton.disabled = false));
|
|
||||||
}
|
|
||||||
|
|
||||||
handleTestPdfCheck() {
|
|
||||||
let url = document.querySelector('meta[name=setup-pdf-check]').content;
|
|
||||||
this.checkPdfButton.disabled = true;
|
|
||||||
|
|
||||||
Axios.post(url, {})
|
|
||||||
.then((response) => {
|
|
||||||
try {
|
|
||||||
//let win = window.open(response.data.url, '_blank');
|
|
||||||
//win.focus();
|
|
||||||
|
|
||||||
return this.handleSuccess(
|
|
||||||
this.checkPdfAlert,
|
|
||||||
'database-wrapper'
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
this.handleSuccess(this.checkPdfAlert, 'database-wrapper');
|
|
||||||
this.checkPdfAlert.textContent = `Success! PDF was generated succesfully.`;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
this.handleFailure(this.checkPdfAlert);
|
|
||||||
})
|
|
||||||
.finally(() => (this.checkPdfButton.disabled = false));
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSuccess(element, nextStep = null) {
|
handleSuccess(element, nextStep = null) {
|
||||||
element.classList.remove('alert-failure');
|
element.classList.remove('alert-failure');
|
||||||
@ -140,14 +72,6 @@ class Setup {
|
|||||||
this.checkDbButton.addEventListener('click', () =>
|
this.checkDbButton.addEventListener('click', () =>
|
||||||
this.handleDatabaseCheck()
|
this.handleDatabaseCheck()
|
||||||
);
|
);
|
||||||
|
|
||||||
this.checkSmtpButton.addEventListener('click', () =>
|
|
||||||
this.handleSmtpCheck()
|
|
||||||
);
|
|
||||||
|
|
||||||
this.checkPdfButton.addEventListener('click', () =>
|
|
||||||
this.handleTestPdfCheck()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,9 +96,7 @@
|
|||||||
@stack('head')
|
@stack('head')
|
||||||
|
|
||||||
@if(strpos(Request::url(),'setup'))
|
@if(strpos(Request::url(),'setup'))
|
||||||
<meta name="setup-pdf-check" content="{{ str_replace("setup", "", Request::url())}}setup/check_pdf">
|
|
||||||
<meta name="setup-db-check" content="{{ str_replace("setup", "", Request::url())}}setup/check_db">
|
<meta name="setup-db-check" content="{{ str_replace("setup", "", Request::url())}}setup/check_db">
|
||||||
<meta name="setup-email-check" content="{{ str_replace("setup", "", Request::url())}}setup/check_mail">
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{ asset('vendor/cookieconsent@3/cookieconsent.min.css') }}" />
|
<link rel="stylesheet" type="text/css" href="{{ asset('vendor/cookieconsent@3/cookieconsent.min.css') }}" />
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
<div class="bg-white shadow overflow-hidden rounded-lg mt-8">
|
|
||||||
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
|
|
||||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
|
||||||
{{ ctrans('texts.application_settings') }}
|
|
||||||
</h3>
|
|
||||||
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
|
|
||||||
{{ ctrans('texts.application_settings_label') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<dl>
|
|
||||||
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
|
|
||||||
<dt class="text-sm leading-5 font-medium text-gray-500">
|
|
||||||
{{ ctrans('texts.url') }}*
|
|
||||||
</dt>
|
|
||||||
<dd class="text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
|
||||||
<input
|
|
||||||
type="url" class="input w-full" name="url" placeholder="https://example.com"
|
|
||||||
pattern="https?://.*" size="45" value="{{ old('url', 'https://') }}" required>
|
|
||||||
<small>(including http:// or https://)</small>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
|
|
||||||
<dt class="text-sm leading-5 font-medium text-gray-500">
|
|
||||||
{{ ctrans('texts.https') }}
|
|
||||||
</dt>
|
|
||||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
|
||||||
<input type="checkbox" class="form-checkbox mr-1" name="https"
|
|
||||||
{{ old('https') ? 'checked': '' }} checked>
|
|
||||||
<span>{{ ctrans('texts.require') }}</span>
|
|
||||||
<span class="text-gray-600 text-xs ml-2">({{ ctrans('texts.recommended_in_production') }})</span>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
|
|
||||||
<dt class="text-sm leading-5 font-medium text-gray-500">
|
|
||||||
{{ ctrans('texts.reports') }}
|
|
||||||
</dt>
|
|
||||||
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
|
||||||
<input type="checkbox" class="form-checkbox mr-1"
|
|
||||||
name="send_logs" {{ old('send_logs' ? 'checked': '') }}>
|
|
||||||
<span>{{ ctrans('texts.send_fail_logs_to_our_server') }}</span>
|
|
||||||
<a class="button-link mt-1 block" target="_blank" href="https://www.invoiceninja.com/privacy-policy/">Read more
|
|
||||||
about how we use this.</a>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
|
|
||||||
<dt class="text-sm leading-5 font-medium text-gray-500">
|
|
||||||
<button type="button" class="button button-primary bg-blue-600 py-2 px-3 text-xs" id="test-pdf">
|
|
||||||
{{ ctrans('texts.test_pdf') }}
|
|
||||||
</button>
|
|
||||||
</dt>
|
|
||||||
<dd class="text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
|
||||||
<div class="alert py-2 bg-white" id="test-pdf-response"></div>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,4 +1,52 @@
|
|||||||
<div class="bg-white shadow overflow-hidden rounded-lg mt-6 hidden" id="database-wrapper">
|
<div class="bg-white shadow overflow-hidden rounded-lg mt-8">
|
||||||
|
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
|
||||||
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
|
{{ ctrans('texts.application_settings') }}
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
|
||||||
|
{{ ctrans('texts.application_settings_label') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<dl>
|
||||||
|
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
|
||||||
|
<dt class="text-sm leading-5 font-medium text-gray-500">
|
||||||
|
{{ ctrans('texts.url') }}*
|
||||||
|
</dt>
|
||||||
|
<dd class="text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||||
|
<input
|
||||||
|
type="url" class="input w-full" name="url" placeholder="https://example.com"
|
||||||
|
pattern="https?://.*" size="45" value="{{ old('url', 'https://') }}" required>
|
||||||
|
<small>(including http:// or https://)</small>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
|
||||||
|
<dt class="text-sm leading-5 font-medium text-gray-500">
|
||||||
|
{{ ctrans('texts.https') }}
|
||||||
|
</dt>
|
||||||
|
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||||
|
<input type="checkbox" class="form-checkbox mr-1" name="https"
|
||||||
|
{{ old('https') ? 'checked': '' }} checked>
|
||||||
|
<span>{{ ctrans('texts.require') }}</span>
|
||||||
|
<span class="text-gray-600 text-xs ml-2">({{ ctrans('texts.recommended_in_production') }})</span>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 sm:flex sm:items-center">
|
||||||
|
<dt class="text-sm leading-5 font-medium text-gray-500">
|
||||||
|
{{ ctrans('texts.reports') }}
|
||||||
|
</dt>
|
||||||
|
<dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
|
||||||
|
<input type="checkbox" class="form-checkbox mr-1"
|
||||||
|
name="send_logs" {{ old('send_logs' ? 'checked': '') }}>
|
||||||
|
<span>{{ ctrans('texts.send_fail_logs_to_our_server') }}</span>
|
||||||
|
<a class="button-link mt-1 block" target="_blank" href="https://www.invoiceninja.com/privacy-policy/">Read more
|
||||||
|
about how we use this.</a>
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white shadow overflow-hidden rounded-lg mt-6">
|
||||||
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
|
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">
|
||||||
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
{{ ctrans('texts.database_connection') }}
|
{{ ctrans('texts.database_connection') }}
|
||||||
|
@ -51,9 +51,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@include('setup._application')
|
|
||||||
@include('setup._database')
|
@include('setup._database')
|
||||||
@include('setup._mail')
|
|
||||||
@include('setup._account')
|
@include('setup._account')
|
||||||
|
|
||||||
<p class="mt-4 text-sm">{{ ctrans('texts.setup_steps_notice') }}</p>
|
<p class="mt-4 text-sm">{{ ctrans('texts.setup_steps_notice') }}</p>
|
||||||
|
@ -158,21 +158,31 @@ Route::get('.env', function () {
|
|||||||
|
|
||||||
Route::fallback(function () {
|
Route::fallback(function () {
|
||||||
|
|
||||||
if (Ninja::isSelfHost() && Account::first()?->set_react_as_default_ap) {
|
if (Ninja::isSelfHost()) {
|
||||||
|
|
||||||
|
$result = false;
|
||||||
|
try {
|
||||||
|
$result = DB::connection()->getPdo();
|
||||||
|
$result = DB::connection()->getDatabaseName();
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$result) {
|
||||||
|
return redirect('/setup');
|
||||||
|
}
|
||||||
|
|
||||||
$account = Account::first();
|
$account = Account::first();
|
||||||
|
|
||||||
return response()->view('react.index', [
|
return $account->set_react_as_default_ap ? response()->view('react.index', [
|
||||||
'rc' => request()->input('rc', ''),
|
'rc' => request()->input('rc', ''),
|
||||||
'login' => request()->input('login', ''),
|
'login' => request()->input('login', ''),
|
||||||
'signup' => request()->input('signup', ''),
|
'signup' => request()->input('signup', ''),
|
||||||
'report_errors' => $account->report_errors,
|
'report_errors' => $account->report_errors,
|
||||||
'user_agent' => request()->server('HTTP_USER_AGENT'),
|
'user_agent' => request()->server('HTTP_USER_AGENT'),
|
||||||
])->header('X-Frame-Options', 'SAMEORIGIN', false);
|
])->header('X-Frame-Options', 'SAMEORIGIN', false) : abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(404);
|
abort(404);
|
||||||
|
|
||||||
})->middleware('throttle:404');
|
})->middleware('throttle:404');
|
||||||
|
|
||||||
// Fix me: Move into invite_db middleware group.
|
|
@ -105,18 +105,18 @@ class InvoiceInclusiveTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->invoice->discount = 5;
|
$this->invoice->discount = 5;
|
||||||
$this->invoice->custom_surcharge1 = 5;
|
$this->invoice->custom_surcharge1 = 5;
|
||||||
|
$this->invoice->custom_surcharge_tax1 = false;
|
||||||
$this->invoice->tax_name1 = 'GST';
|
$this->invoice->tax_name1 = 'GST';
|
||||||
$this->invoice->tax_rate1 = 10;
|
$this->invoice->tax_rate1 = 10;
|
||||||
$this->invoice->is_amount_discount = true;
|
$this->invoice->is_amount_discount = true;
|
||||||
|
$this->invoice->line_items = $this->buildLineItems();
|
||||||
|
|
||||||
|
$calc = $this->invoice->calc();
|
||||||
$this->invoice_calc = new InvoiceSumInclusive($this->invoice);
|
|
||||||
$this->invoice_calc->build();
|
|
||||||
|
|
||||||
$this->assertEquals($this->invoice_calc->getSubTotal(), 20);
|
$this->assertEquals($calc->getSubTotal(), 20);
|
||||||
$this->assertEquals($this->invoice_calc->getTotalTaxes(), 1.36);
|
$this->assertEquals($calc->getTotalTaxes(), 1.36);
|
||||||
$this->assertEquals($this->invoice_calc->getTotal(), 20);
|
$this->assertEquals($calc->getTotal(), 20);
|
||||||
$this->assertEquals($this->invoice_calc->getBalance(), 20);
|
$this->assertEquals($calc->getBalance(), 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvoiceTotalsWithPercentDiscountWithSurchargeWithInclusiveTax()
|
public function testInvoiceTotalsWithPercentDiscountWithSurchargeWithInclusiveTax()
|
||||||
@ -297,7 +297,7 @@ class InvoiceInclusiveTest extends TestCase
|
|||||||
$this->invoice_calc->build();
|
$this->invoice_calc->build();
|
||||||
|
|
||||||
$line_items = $this->invoice_calc->invoice_items->getLineItems();
|
$line_items = $this->invoice_calc->invoice_items->getLineItems();
|
||||||
nlog($this->invoice_calc->getTaxMap());
|
// nlog($this->invoice_calc->getTaxMap());
|
||||||
|
|
||||||
$this->assertEquals(19, $this->invoice_calc->getSubTotal());
|
$this->assertEquals(19, $this->invoice_calc->getSubTotal());
|
||||||
$this->assertEquals(0.95, $this->invoice_calc->getTotalDiscount());
|
$this->assertEquals(0.95, $this->invoice_calc->getTotalDiscount());
|
||||||
|
Loading…
Reference in New Issue
Block a user