mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-11 05:32:39 +01:00
commit
b9bcbe0015
@ -11,11 +11,12 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Backup;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Document;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\GroupSetting;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
@ -55,6 +56,9 @@ class BackupUpdate extends Command
|
||||
{
|
||||
//always return state to first DB
|
||||
|
||||
if(Ninja::isSelfHost())
|
||||
return;
|
||||
|
||||
$current_db = config('database.default');
|
||||
|
||||
if (! config('ninja.db.multi_db_enabled')) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\DataMapper\Tax;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Product;
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
|
||||
@ -117,6 +118,8 @@ class BaseRule implements RuleInterface
|
||||
|
||||
protected ?Response $tax_data;
|
||||
|
||||
public ?Invoice $invoice;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
@ -126,18 +129,29 @@ class BaseRule implements RuleInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setClient(Client $client): self
|
||||
public function setInvoice(Invoice $invoice): self
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->invoice = $invoice;
|
||||
|
||||
$this->configTaxData();
|
||||
|
||||
$this->client = $invoice->client;
|
||||
|
||||
$this->tax_data = new Response($this->invoice->tax_data);
|
||||
|
||||
$this->resolveRegions();
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTaxData(Response $tax_data): self
|
||||
private function configTaxData(): self
|
||||
{
|
||||
$this->tax_data = $tax_data;
|
||||
if($this->invoice->tax_data && $this->invoice->status_id > 1)
|
||||
return $this;
|
||||
|
||||
//determine if we are taxing locally or if we are taxing globally
|
||||
// $this->invoice->tax_data = $this->invoice->client->tax_data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -176,10 +190,10 @@ class BaseRule implements RuleInterface
|
||||
return $this;
|
||||
|
||||
}
|
||||
elseif($this->client_region == 'AU'){
|
||||
elseif($this->client_region == 'AU'){ //these are defaults and are only stubbed out for now, for AU we can actually remove these
|
||||
|
||||
$this->tax_rate1 = 10;
|
||||
$this->tax_name1 = 'GST';
|
||||
$this->tax_rate1 = $this->client->company->tax_data->regions->AU->subregions->AU->tax_rate;
|
||||
$this->tax_name1 = $this->client->company->tax_data->regions->AU->subregions->AU->tax_name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -14,19 +14,19 @@ namespace App\DataMapper\Tax;
|
||||
class TaxModel
|
||||
{
|
||||
|
||||
/** @var mixed $seller_subregion */
|
||||
/** @var string $seller_subregion */
|
||||
public string $seller_subregion = 'CA';
|
||||
|
||||
/** @var mixed $version */
|
||||
/** @var string $version */
|
||||
public string $version = 'alpha';
|
||||
|
||||
/** @var mixed $regions */
|
||||
/** @var object $regions */
|
||||
public object $regions;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param mixed $model
|
||||
* @param TaxModel $model
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(public ?TaxModel $model = null)
|
||||
@ -42,9 +42,9 @@ class TaxModel
|
||||
/**
|
||||
* Initializes the rules and builds any required data.
|
||||
*
|
||||
* @return void
|
||||
* @return object
|
||||
*/
|
||||
public function init()
|
||||
public function init(): object
|
||||
{
|
||||
$this->regions = new \stdClass();
|
||||
$this->regions->US = new \stdClass();
|
||||
|
@ -65,6 +65,7 @@ class Response
|
||||
public string $geoCounty = "";
|
||||
public string $geoState = "";
|
||||
public float $taxSales = 0;
|
||||
public string $taxName = "";
|
||||
public float $taxUse = 0;
|
||||
public string $txbService = ""; // N = No, Y = Yes
|
||||
public string $txbFreight = ""; // N = No, Y = Yes
|
||||
@ -73,6 +74,8 @@ class Response
|
||||
public float $citySalesTax = 0;
|
||||
public float $cityUseTax = 0;
|
||||
public string $cityTaxCode = "";
|
||||
|
||||
/* US SPECIFIC TAX CODES */
|
||||
public float $countySalesTax = 0;
|
||||
public float $countyUseTax = 0;
|
||||
public string $countyTaxCode = "";
|
||||
@ -93,7 +96,9 @@ class Response
|
||||
public string $district5Code = "";
|
||||
public float $district5SalesTax = 0;
|
||||
public float $district5UseTax = 0;
|
||||
public string $originDestination = "";
|
||||
/* US SPECIFIC TAX CODES */
|
||||
|
||||
public string $originDestination = ""; // defines if the client origin is the locale where the tax is remitted to
|
||||
|
||||
public function __construct($data)
|
||||
{
|
||||
|
@ -116,7 +116,7 @@ class RecurringInvoiceFilters extends QueryFilters
|
||||
/**
|
||||
* Filters the query by the users company ID.
|
||||
*
|
||||
* @return Illuminate\Database\Eloquent\Builder
|
||||
* @return Builder
|
||||
*/
|
||||
public function entityFilter(): Builder
|
||||
{
|
||||
@ -126,7 +126,7 @@ class RecurringInvoiceFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on line_items product_key
|
||||
*
|
||||
* @param string value Product keys
|
||||
* @param string $value Product keys
|
||||
* @return Builder
|
||||
*/
|
||||
public function product_key(string $value = ''): Builder
|
||||
|
@ -146,12 +146,9 @@ class InvoiceItemSum
|
||||
|
||||
$class = "App\DataMapper\Tax\\".$this->client->company->country()->iso_3166_2."\\Rule";
|
||||
|
||||
$tax_data = new Response($this->invoice?->tax_data);
|
||||
|
||||
$this->rule = new $class();
|
||||
$this->rule
|
||||
->setTaxData($tax_data)
|
||||
->setClient($this->client)
|
||||
->setInvoice($this->invoice)
|
||||
->init();
|
||||
|
||||
$this->calc_tax = true;
|
||||
|
@ -140,10 +140,6 @@ class EmailController extends BaseController
|
||||
$mo->cc[] = new Address($request->cc_email);
|
||||
}
|
||||
|
||||
// if ($entity == 'purchaseOrder' || $entity == 'purchase_order' || $template == 'purchase_order' || $entity == 'App\Models\PurchaseOrder') {
|
||||
// return $this->sendPurchaseOrder($entity_obj, $data, $template);
|
||||
// }
|
||||
|
||||
$entity_obj->invitations->each(function ($invitation) use ($data, $entity_obj, $template, $mo) {
|
||||
if (! $invitation->contact->trashed() && $invitation->contact->email) {
|
||||
$entity_obj->service()->markSent()->save();
|
||||
|
@ -162,6 +162,9 @@ class SelfUpdateController extends BaseController
|
||||
$this->deleteDirectory(base_path('vendor/beganovich/snappdf/versions/'.$file->getFileName()));
|
||||
}
|
||||
}
|
||||
|
||||
$iterator = null;
|
||||
|
||||
}
|
||||
|
||||
private function deleteDirectory($dir)
|
||||
@ -206,6 +209,8 @@ class SelfUpdateController extends BaseController
|
||||
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
|
||||
unlink(base_path('bootstrap/cache/').$file->getFileName());
|
||||
}
|
||||
|
||||
$directoryIterator = null;
|
||||
}
|
||||
|
||||
private function testWritable()
|
||||
@ -225,6 +230,8 @@ class SelfUpdateController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
$directoryIterator = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ class BlackListRule implements Rule
|
||||
'sharklasers.com',
|
||||
'100072641.help',
|
||||
'yandex.com',
|
||||
'bloheyz.com',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -136,7 +136,7 @@ class NinjaMailerJob implements ShouldQueue
|
||||
->send($this->nmo->mailable);
|
||||
|
||||
/* Count the amount of emails sent across all the users accounts */
|
||||
Cache::increment($this->company->account->key);
|
||||
Cache::increment("email_quota".$this->company->account->key);
|
||||
|
||||
LightLogs::create(new EmailSuccess($this->nmo->company->company_key))
|
||||
->send();
|
||||
@ -486,8 +486,13 @@ class NinjaMailerJob implements ShouldQueue
|
||||
*/
|
||||
private function preFlightChecksFail(): bool
|
||||
{
|
||||
/* Always send regardless */
|
||||
if($this->override) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If we are migrating data we don't want to fire any emails */
|
||||
if ($this->company->is_disabled && !$this->override) {
|
||||
if ($this->company->is_disabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ class Account extends BaseModel
|
||||
$limit += Carbon::createFromTimestamp($this->created_at)->diffInMonths() * 50;
|
||||
} else {
|
||||
$limit = $this->free_plan_email_quota;
|
||||
$limit += Carbon::createFromTimestamp($this->created_at)->diffInMonths() * 10;
|
||||
$limit += Carbon::createFromTimestamp($this->created_at)->diffInMonths() * 3;
|
||||
}
|
||||
|
||||
return min($limit, 5000);
|
||||
|
@ -190,7 +190,7 @@ class BaseRepository
|
||||
$this->new_model = true;
|
||||
|
||||
if (is_array($model->line_items) && !($model instanceof RecurringInvoice)) {
|
||||
$model->line_items = (collect($model->line_items))->map(function ($item) use ($model, $client) {
|
||||
$model->line_items = (collect($model->line_items))->map(function ($item) use ($client) {
|
||||
$item->notes = Helpers::processReservedKeywords($item->notes, $client);
|
||||
|
||||
return $item;
|
||||
|
@ -247,7 +247,7 @@ class Email implements ShouldQueue
|
||||
|
||||
$mailer->send($this->mailable);
|
||||
|
||||
Cache::increment($this->company->account->key);
|
||||
Cache::increment("email_quota".$this->company->account->key);
|
||||
|
||||
LightLogs::create(new EmailSuccess($this->company->company_key))
|
||||
->send();
|
||||
@ -329,8 +329,13 @@ class Email implements ShouldQueue
|
||||
*/
|
||||
public function preFlightChecksFail(): bool
|
||||
{
|
||||
/* Always send if disabled */
|
||||
if($this->override) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If we are migrating data we don't want to fire any emails */
|
||||
if ($this->company->is_disabled && !$this->override) {
|
||||
if ($this->company->is_disabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ class EmailMailer implements ShouldQueue
|
||||
|
||||
$mailer->send($this->email_mailable);
|
||||
|
||||
Cache::increment($this->email_service->company->account->key);
|
||||
Cache::increment("email_quota".$this->email_service->company->account->key);
|
||||
|
||||
LightLogs::create(new EmailSuccess($this->email_service->company->company_key))
|
||||
->send();
|
||||
|
140
app/Services/Invoice/EInvoice/FatturaPA.php
Normal file
140
app/Services/Invoice/EInvoice/FatturaPA.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?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\Services\Invoice\EInvoice;
|
||||
|
||||
use SimpleXMLElement;
|
||||
use App\Models\Invoice;
|
||||
use App\Services\AbstractService;
|
||||
/*
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FatturaElettronica versione="FPR12" xmlns="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2">
|
||||
<FatturaElettronicaHeader>
|
||||
<DatiTrasmissione>
|
||||
<IdTrasmittente>
|
||||
<IdPaese>IT</IdPaese>
|
||||
<IdCodice>01234567890</IdCodice>
|
||||
</IdTrasmittente>
|
||||
<ProgressivoInvio>00001</ProgressivoInvio>
|
||||
<FormatoTrasmissione>FPR12</FormatoTrasmissione>
|
||||
<CodiceDestinatario>ABCDE1</CodiceDestinatario>
|
||||
</DatiTrasmissione>
|
||||
<CedentePrestatore>
|
||||
<!-- Company information of the sender (seller/provider) -->
|
||||
</CedentePrestatore>
|
||||
<CessionarioCommittente>
|
||||
<!-- Company information of the receiver (buyer) -->
|
||||
</CessionarioCommittente>
|
||||
</FatturaElettronicaHeader>
|
||||
<FatturaElettronicaBody>
|
||||
<DatiGenerali>
|
||||
<DatiGeneraliDocumento>
|
||||
<TipoDocumento>TD01</TipoDocumento>
|
||||
<Divisa>EUR</Divisa>
|
||||
<Data>2023-04-21</Data>
|
||||
<Numero>1</Numero>
|
||||
<!-- Add other information as needed -->
|
||||
</DatiGeneraliDocumento>
|
||||
<!-- Add other general data as needed -->
|
||||
</DatiGenerali>
|
||||
<DatiBeniServizi>
|
||||
<!-- List of items or services -->
|
||||
</DatiBeniServizi>
|
||||
<DatiPagamento>
|
||||
<!-- Payment details -->
|
||||
</DatiPagamento>
|
||||
</FatturaElettronicaBody>
|
||||
</FatturaElettronica>
|
||||
*/
|
||||
|
||||
class FatturaPA extends AbstractService
|
||||
{
|
||||
private $xml;
|
||||
|
||||
public function __construct(public Invoice $invoice)
|
||||
{
|
||||
$this->xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><FatturaElettronica></FatturaElettronica>');
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
return $this->addHeader()->getXml();
|
||||
}
|
||||
|
||||
public function addHeader() {
|
||||
$this->xml->addChild('FatturaElettronicaHeader');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addTrasmissioneData($idPaese, $idCodice, $progressivoInvio, $formatoTrasmissione, $codiceDestinatario) {
|
||||
$datiTrasmissione = $this->xml->FatturaElettronicaHeader->addChild('DatiTrasmissione');
|
||||
$idTrasmittente = $datiTrasmissione->addChild('IdTrasmittente');
|
||||
$idTrasmittente->addChild('IdPaese', $idPaese);
|
||||
$idTrasmittente->addChild('IdCodice', $idCodice);
|
||||
$datiTrasmissione->addChild('ProgressivoInvio', $progressivoInvio);
|
||||
$datiTrasmissione->addChild('FormatoTrasmissione', $formatoTrasmissione);
|
||||
$datiTrasmissione->addChild('CodiceDestinatario', $codiceDestinatario);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addCedentePrestatore($data) {
|
||||
// Add CedentePrestatore data
|
||||
}
|
||||
|
||||
public function addCessionarioCommittente($data) {
|
||||
// Add CessionarioCommittente data
|
||||
}
|
||||
|
||||
public function addBody() {
|
||||
$this->xml->addChild('FatturaElettronicaBody');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addDatiGenerali($data) {
|
||||
// Add DatiGenerali data
|
||||
}
|
||||
|
||||
public function addLineItem($data) {
|
||||
if (!isset($this->xml->FatturaElettronicaBody->DatiBeniServizi)) {
|
||||
$this->xml->FatturaElettronicaBody->addChild('DatiBeniServizi');
|
||||
}
|
||||
$lineItem = $this->xml->FatturaElettronicaBody->DatiBeniServizi->addChild('DettaglioLinee');
|
||||
$lineItem->addChild('NumeroLinea', $data['NumeroLinea']);
|
||||
$lineItem->addChild('Descrizione', $data['notes']);
|
||||
$lineItem->addChild('Quantita', $data['quantity']);
|
||||
$lineItem->addChild('PrezzoUnitario', $data['cost']);
|
||||
$lineItem->addChild('PrezzoTotale', $data['line_total']);
|
||||
$lineItem->addChild('AliquotaIVA', $data['tax_rate1']);
|
||||
|
||||
if (isset($data['UnitaMisura'])) {
|
||||
$lineItem->addChild('UnitaMisura', $data['UnitaMisura']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addDatiPagamento($data) {
|
||||
// Add DatiPagamento data
|
||||
}
|
||||
|
||||
|
||||
public function getXml()
|
||||
{
|
||||
return $this->xml->asXML();
|
||||
}
|
||||
}
|
||||
|
||||
// $fattura = new FatturaPA();
|
||||
// $fattura
|
||||
// ->addHeader()
|
||||
// ->addTrasmissioneData('IT', '01234567890', '00001', 'FPR12', 'ABCDE1');
|
||||
|
||||
// echo $fattura->getXml();
|
@ -28,7 +28,7 @@ class EmailStats
|
||||
*/
|
||||
public static function inc($company_key)
|
||||
{
|
||||
Cache::increment(self::EMAIL.$company_key);
|
||||
Cache::increment("email_quota".self::EMAIL.$company_key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,7 +155,7 @@ class HtmlEngine
|
||||
$data['$exchange_rate'] = ['value' => $this->entity->exchange_rate ?: ' ', 'label' => ctrans('texts.exchange_rate')];
|
||||
|
||||
if ($this->entity_string == 'invoice' || $this->entity_string == 'recurring_invoice') {
|
||||
$data['$entity'] = ['value' => '', 'label' => ctrans('texts.invoice')];
|
||||
$data['$entity'] = ['value' => ctrans('texts.invoice'), 'label' => ctrans('texts.invoice')];
|
||||
$data['$number'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')];
|
||||
$data['$invoice'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number')];
|
||||
$data['$number_short'] = ['value' => $this->entity->number ?: ' ', 'label' => ctrans('texts.invoice_number_short')];
|
||||
@ -212,7 +212,7 @@ class HtmlEngine
|
||||
}
|
||||
|
||||
if ($this->entity_string == 'quote') {
|
||||
$data['$entity'] = ['value' => '', 'label' => ctrans('texts.quote')];
|
||||
$data['$entity'] = ['value' => ctrans('texts.quote'), 'label' => ctrans('texts.quote')];
|
||||
$data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number')];
|
||||
$data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number_short')];
|
||||
$data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms ?: ''), $this->client) ?: '', 'label' => ctrans('texts.quote_terms')];
|
||||
@ -256,7 +256,7 @@ class HtmlEngine
|
||||
}
|
||||
|
||||
if ($this->entity_string == 'credit') {
|
||||
$data['$entity'] = ['value' => '', 'label' => ctrans('texts.credit')];
|
||||
$data['$entity'] = ['value' => ctrans('texts.credit'), 'label' => ctrans('texts.credit')];
|
||||
$data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number')];
|
||||
$data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number_short')];
|
||||
$data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms ?: ''), $this->client) ?: '', 'label' => ctrans('texts.credit_terms')];
|
||||
|
@ -4379,7 +4379,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
|
||||
'imported_customers' => 'Se comenzó a importar clientes con éxito',
|
||||
'login_success' => 'Inicio de sesión correcto',
|
||||
'login_failure' => 'Inicio de sesión fallido',
|
||||
'exported_data' => 'Once the file is ready you\'ll receive an email with a download link',
|
||||
'exported_data' => 'Una vez que el archivo esté listo, recibirá un correo electrónico con un enlace de descarga.',
|
||||
'include_deleted_clients' => 'Incluir clientes eliminados',
|
||||
'include_deleted_clients_help' => 'Cargar registros pertenecientes a clientes eliminados',
|
||||
'step_1_sign_in' => 'Paso 1: Iniciar sesión',
|
||||
@ -4468,7 +4468,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
|
||||
'activity_123' => ':user eliminó el gasto recurrente :recurring_expense',
|
||||
'activity_124' => ':user restauró el gasto recurrente :recurring_expense',
|
||||
'fpx' => "FPX",
|
||||
'to_view_entity_set_password' => 'To view the :entity you need to set a password.',
|
||||
'to_view_entity_set_password' => 'Para ver el :entity necesita establecer una contraseña.',
|
||||
'unsubscribe' => 'Darse de baja',
|
||||
'unsubscribed' => 'Dado de baja',
|
||||
'unsubscribed_text' => 'Se le ha eliminado de las notificaciones de este documento',
|
||||
@ -4566,7 +4566,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
|
||||
'purchase_order_number' => 'Número de orden de compra',
|
||||
'purchase_order_number_short' => 'orden de compra n.°',
|
||||
'inventory_notification_subject' => 'Notificación de umbral de inventario para el producto: :product',
|
||||
'inventory_notification_body' => 'Threshold of :amount has been reached for product: :product',
|
||||
'inventory_notification_body' => 'Se ha alcanzado el umbral de:amount para el producto: :product',
|
||||
'activity_130' => ':user creó la orden de compra :purchase_order',
|
||||
'activity_131' => ':user actualizó la orden de compra :purchase_order',
|
||||
'activity_132' => ':user archivó la orden de compra :purchase_order',
|
||||
@ -4598,7 +4598,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
|
||||
'vendor_document_upload' => 'Carga de documentos de proveedores',
|
||||
'vendor_document_upload_help' => 'Permitir que los proveedores carguen documentos',
|
||||
'are_you_enjoying_the_app' => '¿Estás disfrutando de la aplicación?',
|
||||
'yes_its_great' => 'Yes, it\'s great!',
|
||||
'yes_its_great' => '¡Sí, es genial!',
|
||||
'not_so_much' => 'No tanto',
|
||||
'would_you_rate_it' => '¡Me alegro de oirlo! ¿Te gustaría calificarlo?',
|
||||
'would_you_tell_us_more' => '¡Siento escucharlo! ¿Te gustaría contarnos más?',
|
||||
@ -4969,9 +4969,9 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
|
||||
'white_label_body' => 'Gracias por comprar una licencia de marca blanca.<br><br> Su clave de licencia es:<br><br> :license_key',
|
||||
'payment_type_Klarna' => 'Klarna',
|
||||
'payment_type_Interac E Transfer' => 'Interac E Transfer',
|
||||
'xinvoice_payable' => 'Payable within :payeddue days net until :paydate',
|
||||
'xinvoice_no_buyers_reference' => "No buyer's reference given",
|
||||
'xinvoice_online_payment' => 'The invoice needs to be payed online via the provided link',
|
||||
'xinvoice_payable' => 'Pagadero dentro de :payeddue días de pago vencido neto hasta :paydate',
|
||||
'xinvoice_no_buyers_reference' => "No se da la referencia del comprador",
|
||||
'xinvoice_online_payment' => 'La factura debe pagarse en línea a través del enlace proporcionado.',
|
||||
'pre_payment' => 'Prepago',
|
||||
'number_of_payments' => 'Numero de pagos',
|
||||
'number_of_payments_helper' => 'El número de veces que se realizará este pago.',
|
||||
@ -5034,24 +5034,24 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
|
||||
'taxable_amount' => 'Base imponible',
|
||||
'tax_summary' => 'Resumen de impuestos',
|
||||
'oauth_mail' => 'OAuth / Mail',
|
||||
'preferences' => 'Preferences',
|
||||
'analytics' => 'Analytics',
|
||||
'reduced_rate' => 'Reduced Rate',
|
||||
'tax_all' => 'Tax All',
|
||||
'tax_selected' => 'Tax Selected',
|
||||
'version' => 'version',
|
||||
'seller_subregion' => 'Seller Subregion',
|
||||
'calculate_taxes' => 'Calculate Taxes',
|
||||
'calculate_taxes_help' => 'Automatically calculate taxes when saving invoices',
|
||||
'link_expenses' => 'Link Expenses',
|
||||
'converted_client_balance' => 'Converted Client Balance',
|
||||
'converted_payment_balance' => 'Converted Payment Balance',
|
||||
'total_hours' => 'Total Hours',
|
||||
'date_picker_hint' => 'Use +days to set the date in the future',
|
||||
'app_help_link' => 'More information ',
|
||||
'here' => 'here',
|
||||
'industry_Restaurant & Catering' => 'Restaurant & Catering',
|
||||
'show_credits_table' => 'Show Credits Table',
|
||||
'preferences' => 'Preferencias',
|
||||
'analytics' => 'Analítica',
|
||||
'reduced_rate' => 'Tarifa Reducida',
|
||||
'tax_all' => 'Impuestos Todos',
|
||||
'tax_selected' => 'Impuesto Seleccionado',
|
||||
'version' => 'versión',
|
||||
'seller_subregion' => 'Subregión del vendedor',
|
||||
'calculate_taxes' => 'Calcular impuestos',
|
||||
'calculate_taxes_help' => 'Calcular automáticamente los impuestos al guardar las facturas',
|
||||
'link_expenses' => 'Gastos de enlace',
|
||||
'converted_client_balance' => 'Saldo de cliente convertido',
|
||||
'converted_payment_balance' => 'Saldo de pago convertido',
|
||||
'total_hours' => 'Horas totales',
|
||||
'date_picker_hint' => 'Usa +días para establecer la fecha en el futuro',
|
||||
'app_help_link' => 'Más información',
|
||||
'here' => 'aquí',
|
||||
'industry_Restaurant & Catering' => 'Restaurante y Catering',
|
||||
'show_credits_table' => 'Mostrar tabla de créditos',
|
||||
);
|
||||
|
||||
|
||||
|
1186
lang/fr_CA/texts.php
1186
lang/fr_CA/texts.php
File diff suppressed because it is too large
Load Diff
2932
lang/it/texts.php
2932
lang/it/texts.php
File diff suppressed because it is too large
Load Diff
1550
lang/pt_PT/texts.php
1550
lang/pt_PT/texts.php
File diff suppressed because it is too large
Load Diff
@ -14,11 +14,11 @@
|
||||
|
||||
@if($invoice->isPayable() && $client->getSetting('custom_message_unpaid_invoice'))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{{ $client->getSetting('custom_message_unpaid_invoice') }}
|
||||
<pre>{{ $client->getSetting('custom_message_unpaid_invoice') }}</pre>
|
||||
@endcomponent
|
||||
@elseif($invoice->status_id === 4 && $client->getSetting('custom_message_paid_invoice'))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{{ $client->getSetting('custom_message_paid_invoice') }}
|
||||
<pre>{{ $client->getSetting('custom_message_paid_invoice') }}</pre>
|
||||
@endcomponent
|
||||
@endif
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
@if(!$quote->isApproved() && $client->getSetting('custom_message_unapproved_quote'))
|
||||
@component('portal.ninja2020.components.message')
|
||||
{{ $client->getSetting('custom_message_unapproved_quote') }}
|
||||
<pre>{{ $client->getSetting('custom_message_unapproved_quote') }}</pre>
|
||||
@endcomponent
|
||||
@endif
|
||||
|
||||
|
48
tests/Feature/EInvoice/FatturaPATest.php
Normal file
48
tests/Feature/EInvoice/FatturaPATest.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Services\Invoice\EInvoice\FatturaPA;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
class FatturaPATest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->makeTestData();
|
||||
|
||||
$this->withoutMiddleware(
|
||||
ThrottleRequests::class
|
||||
);
|
||||
}
|
||||
|
||||
public function testInvoiceBoot()
|
||||
{
|
||||
$fat = new FatturaPA($this->invoice);
|
||||
$xml = $fat->run();
|
||||
|
||||
// nlog($xml);
|
||||
|
||||
$this->assertnotNull($xml);
|
||||
}
|
||||
}
|
@ -579,7 +579,7 @@ class RecurringInvoiceTest extends TestCase
|
||||
'user_id' => $this->user->id,
|
||||
'cost' => 10,
|
||||
'price' => 10,
|
||||
'product_key' => $this->faker->word,
|
||||
'product_key' => $this->faker->unique()->word(),
|
||||
]);
|
||||
|
||||
$p2 = Product::factory()->create([
|
||||
@ -587,7 +587,7 @@ class RecurringInvoiceTest extends TestCase
|
||||
'user_id' => $this->user->id,
|
||||
'cost' => 20,
|
||||
'price' => 20,
|
||||
'product_key' => $this->faker->word,
|
||||
'product_key' => $this->faker->unique()->word(),
|
||||
]);
|
||||
|
||||
$recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id);
|
||||
@ -627,7 +627,7 @@ class RecurringInvoiceTest extends TestCase
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/recurring_invoices?product_key=' . $this->faker->word)
|
||||
])->get('/api/v1/recurring_invoices?product_key=' . $this->faker->unique()->word())
|
||||
->assertStatus(200);
|
||||
|
||||
$arr = $response->json();
|
||||
|
@ -11,18 +11,18 @@
|
||||
|
||||
namespace Tests\Unit\Tax;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\DataMapper\Tax\DE\Rule;
|
||||
use App\DataMapper\Tax\TaxModel;
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Product;
|
||||
use Tests\MockAccountData;
|
||||
use App\DataMapper\Tax\DE\Rule;
|
||||
use App\DataMapper\Tax\TaxModel;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test App\Services\Tax\Providers\EuTax
|
||||
@ -338,8 +338,18 @@ class EuTaxTest extends TestCase
|
||||
'has_valid_vat_number' => false,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
$this->assertEquals('EU', $process->seller_region);
|
||||
@ -382,12 +392,21 @@ class EuTaxTest extends TestCase
|
||||
'has_valid_vat_number' => false,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
|
||||
$this->assertEquals('EU', $process->seller_region);
|
||||
$this->assertEquals('EU', $process->seller_region);
|
||||
|
||||
$this->assertEquals('BE', $process->client_subregion);
|
||||
|
||||
@ -428,11 +447,18 @@ $this->assertEquals('EU', $process->seller_region);
|
||||
'has_valid_vat_number' => false,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setTaxData(new Response([
|
||||
'geoState' => 'CA',
|
||||
]));
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
$this->assertEquals('EU', $process->seller_region);
|
||||
@ -476,8 +502,18 @@ $this->assertEquals('EU', $process->seller_region);
|
||||
'has_valid_vat_number' => false,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
$this->assertInstanceOf(Rule::class, $process);
|
||||
@ -517,10 +553,21 @@ $this->assertEquals('EU', $process->seller_region);
|
||||
'has_valid_vat_number' => true,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
|
||||
$this->assertInstanceOf(Rule::class, $process);
|
||||
|
||||
$this->assertTrue($client->has_valid_vat_number);
|
||||
@ -556,11 +603,22 @@ $this->assertEquals('EU', $process->seller_region);
|
||||
'shipping_country_id' => 56,
|
||||
'has_valid_vat_number' => true,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
|
||||
$this->assertInstanceOf(Rule::class, $process);
|
||||
|
||||
$this->assertTrue($client->has_valid_vat_number);
|
||||
@ -597,10 +655,21 @@ $this->assertEquals('EU', $process->seller_region);
|
||||
'is_tax_exempt' => true,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
|
||||
$this->assertInstanceOf(Rule::class, $process);
|
||||
|
||||
$this->assertTrue($client->is_tax_exempt);
|
||||
@ -637,8 +706,18 @@ $this->assertEquals('EU', $process->seller_region);
|
||||
'is_tax_exempt' => true,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
$this->assertInstanceOf(Rule::class, $process);
|
||||
@ -676,11 +755,21 @@ $this->assertEquals('EU', $process->seller_region);
|
||||
'is_tax_exempt' => true,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'user_id' => $this->user->id,
|
||||
'status_id' => Invoice::STATUS_SENT,
|
||||
'tax_data' => new Response([
|
||||
'geoState' => 'CA',
|
||||
]),
|
||||
]);
|
||||
|
||||
$process = new Rule();
|
||||
$process->setTaxData(new Response([]));
|
||||
$process->setClient($client);
|
||||
$process->setInvoice($invoice);
|
||||
$process->init();
|
||||
|
||||
|
||||
$this->assertInstanceOf(Rule::class, $process);
|
||||
|
||||
$this->assertTrue($client->is_tax_exempt);
|
||||
|
Loading…
Reference in New Issue
Block a user