Merge pull request #9882 from turbo124/v5-develop

v5.10.20
This commit is contained in:
David Bomba 2024-08-08 09:48:33 +10:00 committed by GitHub
commit 3d9cbf5b91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 490 additions and 148 deletions

View File

@ -1 +1 @@
5.10.19 5.10.20

View File

@ -215,7 +215,7 @@ class BaseRule implements RuleInterface
$this->invoice->tax_data = $tax_data; $this->invoice->tax_data = $tax_data;
if(\DB::transactionLevel() == 0) { if(\DB::transactionLevel() == 0 && isset($this->invoice->id)) {
try { try {
$this->invoice->saveQuietly(); $this->invoice->saveQuietly();

View File

@ -43,6 +43,8 @@ class Rule extends BaseRule implements RuleInterface
public float $reduced_tax_rate = 0; public float $reduced_tax_rate = 0;
public string $tax_name1 = 'MwSt.'; public string $tax_name1 = 'MwSt.';
private string $tax_name;
/** /**
* Initializes the rules and builds any required data. * Initializes the rules and builds any required data.
* *
@ -50,6 +52,7 @@ class Rule extends BaseRule implements RuleInterface
*/ */
public function init(): self public function init(): self
{ {
$this->tax_name = $this->tax_name1;
$this->calculateRates(); $this->calculateRates();
return $this; return $this;
@ -91,6 +94,7 @@ class Rule extends BaseRule implements RuleInterface
*/ */
public function reverseTax($item): self public function reverseTax($item): self
{ {
$this->tax_name1 = $this->tax_name;
$this->tax_rate1 = 0; $this->tax_rate1 = 0;
return $this; return $this;
@ -103,6 +107,8 @@ class Rule extends BaseRule implements RuleInterface
*/ */
public function taxReduced($item): self public function taxReduced($item): self
{ {
$this->tax_name1 = $this->tax_name;
$this->tax_rate1 = $this->reduced_tax_rate; $this->tax_rate1 = $this->reduced_tax_rate;
return $this; return $this;
@ -115,6 +121,8 @@ class Rule extends BaseRule implements RuleInterface
*/ */
public function zeroRated($item): self public function zeroRated($item): self
{ {
$this->tax_name1 = $this->tax_name;
$this->tax_rate1 = 0; $this->tax_rate1 = 0;
return $this; return $this;
@ -142,6 +150,7 @@ class Rule extends BaseRule implements RuleInterface
public function taxDigital($item): self public function taxDigital($item): self
{ {
$this->tax_name1 = $this->tax_name;
$this->tax_rate1 = $this->tax_rate; $this->tax_rate1 = $this->tax_rate;
return $this; return $this;
@ -155,6 +164,7 @@ class Rule extends BaseRule implements RuleInterface
public function taxService($item): self public function taxService($item): self
{ {
$this->tax_name1 = $this->tax_name;
$this->tax_rate1 = $this->tax_rate; $this->tax_rate1 = $this->tax_rate;
return $this; return $this;
@ -168,6 +178,7 @@ class Rule extends BaseRule implements RuleInterface
public function taxShipping($item): self public function taxShipping($item): self
{ {
$this->tax_name1 = $this->tax_name;
$this->tax_rate1 = $this->tax_rate; $this->tax_rate1 = $this->tax_rate;
return $this; return $this;
@ -181,6 +192,7 @@ class Rule extends BaseRule implements RuleInterface
public function taxPhysical($item): self public function taxPhysical($item): self
{ {
$this->tax_name1 = $this->tax_name;
$this->tax_rate1 = $this->tax_rate; $this->tax_rate1 = $this->tax_rate;
return $this; return $this;

View File

@ -158,6 +158,18 @@ class ExpenseFilters extends QueryFilters
return $this->builder; return $this->builder;
} }
public function categories(string $categories = ''): Builder
{
$categories_exploded = explode(",", $categories);
if(empty($categories) || count(array_filter($categories_exploded)) == 0)
return $this->builder;
$categories_keys = $this->transformKeys($categories_exploded);
return $this->builder->whereIn('category_id', $categories_keys);
}
public function number(string $number = ''): Builder public function number(string $number = ''): Builder
{ {
if (strlen($number) == 0) { if (strlen($number) == 0) {

View File

@ -85,6 +85,10 @@ class TaskFilters extends QueryFilters
$this->builder->whereNull('invoice_id'); $this->builder->whereNull('invoice_id');
} }
if (in_array('is_running', $status_parameters)) {
$this->builder->where('is_running', true);
}
return $this->builder; return $this->builder;
} }

View File

@ -53,7 +53,6 @@ class ContactComponent extends Component
public function render() public function render()
{ {
\Debugbar::debug($this->attributes->getAttributes() + $this->defaults);
return render('gateways.rotessa.components.contact', $this->attributes->getAttributes() + $this->defaults ); return render('gateways.rotessa.components.contact', $this->attributes->getAttributes() + $this->defaults );
} }
} }

View File

@ -115,10 +115,9 @@ class PayPalBasePaymentDriver extends BaseDriver
$this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com'; $this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com';
if(\App\Utils\Ninja::isHosted()) { if(\App\Utils\Ninja::isHosted() && $this->company_gateway->gateway_key != '80af24a6a691230bbec33e930ab40665') {
$secret = config('ninja.paypal.secret'); $secret = config('ninja.paypal.secret');
$client_id = config('ninja.paypal.client_id'); $client_id = config('ninja.paypal.client_id');
} }
else { else {

View File

@ -147,6 +147,10 @@ class TaskRepository extends BaseRepository
$task->calculated_start_date = $this->harvestStartDate($time_log, $task); $task->calculated_start_date = $this->harvestStartDate($time_log, $task);
if(isset(end($time_log)[1])){
$task->is_running = end($time_log)[1] == 0;
}
$task->time_log = json_encode($time_log); $task->time_log = json_encode($time_log);
$task->saveQuietly(); $task->saveQuietly();
@ -259,7 +263,7 @@ class TaskRepository extends BaseRepository
$log = array_merge($log, [$new]); $log = array_merge($log, [$new]);
$task->time_log = json_encode($log); $task->time_log = json_encode($log);
$task->is_running = true;
$task->saveQuietly(); $task->saveQuietly();
} }
@ -303,6 +307,7 @@ class TaskRepository extends BaseRepository
$log = array_merge($log, [$last]);//check at this point, it may be prepending here. $log = array_merge($log, [$last]);//check at this point, it may be prepending here.
$task->time_log = json_encode($log); $task->time_log = json_encode($log);
$task->is_running = false;
$task->saveQuietly(); $task->saveQuietly();
} }
@ -418,4 +423,4 @@ class TaskRepository extends BaseRepository
} }
} }

View File

@ -137,14 +137,14 @@ class Storecove {
} }
public function sendDocument($document) public function sendDocument(string $document, int $routing_id, array $identifiers = [])
{ {
$payload = [ $payload = [
"legalEntityId"=> 290868, "legalEntityId" => $routing_id,
"idempotencyGuid"=> \Illuminate\Support\Str::uuid(), "idempotencyGuid"=> \Illuminate\Support\Str::uuid(),
"routing" => [ "routing" => [
"eIdentifiers" => [], "eIdentifiers" => $identifiers,
"emails" => ["david@invoiceninja.com"] "emails" => ["david@invoiceninja.com"]
], ],
"document"=> [ "document"=> [

View File

@ -57,6 +57,12 @@ class Peppol extends AbstractService
use NumberFormatter; use NumberFormatter;
/** /**
* Assumptions:
*
* Line Item Taxes Only
* Exclusive Taxes
*
*
* used as a proxy for * used as a proxy for
* the schemeID of partyidentification * the schemeID of partyidentification
* property - for Storecove only: * property - for Storecove only:
@ -152,6 +158,13 @@ class Peppol extends AbstractService
private InvoiceSum | InvoiceSumInclusive $calc; private InvoiceSum | InvoiceSumInclusive $calc;
private \InvoiceNinja\EInvoice\Models\Peppol\Invoice $p_invoice; private \InvoiceNinja\EInvoice\Models\Peppol\Invoice $p_invoice;
private ?\InvoiceNinja\EInvoice\Models\Peppol\Invoice $_client_settings;
private ?\InvoiceNinja\EInvoice\Models\Peppol\Invoice $_company_settings;
private EInvoice $e;
/** /**
* @param Invoice $invoice * @param Invoice $invoice
*/ */
@ -159,18 +172,21 @@ class Peppol extends AbstractService
{ {
$this->company = $invoice->company; $this->company = $invoice->company;
$this->calc = $this->invoice->calc(); $this->calc = $this->invoice->calc();
$this->setInvoice(); $this->e = new EInvoice();
$this->setSettings()->setInvoice();
} }
/**
* Rehydrates an existing e invoice - or - scaffolds a new one
*
* @return self
*/
private function setInvoice(): self private function setInvoice(): self
{ {
if($this->invoice->e_invoice){ if($this->invoice->e_invoice){
$this->p_invoice = $this->e->decode('Peppol', json_encode($this->invoice->e_invoice->Invoice), 'json');
$e = new EInvoice();
$this->p_invoice = $e->decode('Peppol', json_encode($this->invoice->e_invoice->Invoice), 'json');
return $this; return $this;
@ -182,6 +198,21 @@ class Peppol extends AbstractService
return $this; return $this;
} }
/**
* Transforms the settings props into usable models we can merge.
*
* @return self
*/
private function setSettings(): self
{
$this->_client_settings = isset($this->invoice->client->e_invoice->Invoice) ? $this->e->decode('Peppol', json_encode($this->invoice->client->e_invoice->Invoice), 'json') : null;
$this->_company_settings = isset($this->invoice->company->e_invoice->Invoice) ? $this->e->decode('Peppol', json_encode($this->invoice->company->e_invoice->Invoice), 'json') : null;
return $this;
}
public function getInvoice(): \InvoiceNinja\EInvoice\Models\Peppol\Invoice public function getInvoice(): \InvoiceNinja\EInvoice\Models\Peppol\Invoice
{ {
@ -211,8 +242,7 @@ class Peppol extends AbstractService
$json = $e->encode($this->p_invoice, 'json'); $json = $e->encode($this->p_invoice, 'json');
return $json; return $json;
// $prefixes = str_ireplace(["cac:","cbc:"], "", $json);
// return str_ireplace(["InvoiceLine", "PostalAddress", "PartyName"], ["invoiceLines","address", "companyName"], $prefixes);
} }
public function toArray(): array public function toArray(): array
@ -224,12 +254,16 @@ class Peppol extends AbstractService
{ {
$this->p_invoice->ID = $this->invoice->number; $this->p_invoice->ID = $this->invoice->number;
$this->p_invoice->IssueDate = new \DateTime($this->invoice->date); $this->p_invoice->IssueDate = new \DateTime($this->invoice->date);
if($this->invoice->due_date)
$this->p_invoice->DueDate = new \DateTime($this->invoice->due_date);
$this->p_invoice->InvoiceTypeCode = 380; // $this->p_invoice->InvoiceTypeCode = 380; //
$this->p_invoice->AccountingSupplierParty = $this->getAccountingSupplierParty(); $this->p_invoice->AccountingSupplierParty = $this->getAccountingSupplierParty();
$this->p_invoice->AccountingCustomerParty = $this->getAccountingCustomerParty(); $this->p_invoice->AccountingCustomerParty = $this->getAccountingCustomerParty();
$this->p_invoice->InvoiceLine = $this->getInvoiceLines(); $this->p_invoice->InvoiceLine = $this->getInvoiceLines();
$this->p_invoice->TaxTotal = $this->getTotalTaxes(); // $this->p_invoice->TaxTotal = $this->getTotalTaxes(); it only wants the aggregate here!!
$this->p_invoice->LegalMonetaryTotal = $this->getLegalMonetaryTotal(); $this->p_invoice->LegalMonetaryTotal = $this->getLegalMonetaryTotal();
$this->countryLevelMutators(); $this->countryLevelMutators();
@ -340,7 +374,7 @@ class Peppol extends AbstractService
$tax_total = new TaxTotal(); $tax_total = new TaxTotal();
$tax_total->TaxAmount = $tax_amount; $tax_total->TaxAmount = $tax_amount;
$tax_total->TaxSubtotal = $tax_subtotal; $tax_total->TaxSubtotal[] = $tax_subtotal;
$taxes[] = $tax_total; $taxes[] = $tax_total;
@ -372,7 +406,7 @@ class Peppol extends AbstractService
$tax_total = new TaxTotal(); $tax_total = new TaxTotal();
$tax_total->TaxAmount = $tax_amount; $tax_total->TaxAmount = $tax_amount;
$tax_total->TaxSubtotal = $tax_subtotal; $tax_total->TaxSubtotal[] = $tax_subtotal;
$taxes[] = $tax_total; $taxes[] = $tax_total;
@ -739,13 +773,13 @@ class Peppol extends AbstractService
public function getSetting(string $property_path): mixed public function getSetting(string $property_path): mixed
{ {
if($prop_value = PropertyResolver::resolve($this->invoice->e_invoice, $property_path)) if($prop_value = PropertyResolver::resolve($this->p_invoice, $property_path)) {
return $prop_value; return $prop_value;
elseif($prop_value = PropertyResolver::resolve($this->invoice->client->e_invoice, $property_path)) }elseif($prop_value = PropertyResolver::resolve($this->_client_settings, $property_path)) {
return $prop_value; return $prop_value;
elseif($prop_value = PropertyResolver::resolve($this->invoice->company->e_invoice, $property_path)) }elseif($prop_value = PropertyResolver::resolve($this->_company_settings, $property_path)) {
return $prop_value; return $prop_value;
}
return null; return null;
} }
@ -761,10 +795,10 @@ class Peppol extends AbstractService
private function setPaymentMeans(bool $required = false): self private function setPaymentMeans(bool $required = false): self
{ {
if($this->p_invoice->PaymentMeans) if(isset($this->p_invoice->PaymentMeans))
return $this; return $this;
elseif(!isset($this->p_invoice->PaymentMeans) && $paymentMeans = $this->getSetting('Invoice.PaymentMeans')){ elseif($paymentMeans = $this->getSetting('Invoice.PaymentMeans')){
$this->p_invoice->PaymentMeans = is_array($paymentMeans) ? $paymentMeans : [$paymentMeans]; $this->p_invoice->PaymentMeans = is_array($paymentMeans) ? $paymentMeans : [$paymentMeans];
return $this; return $this;
} }
@ -774,24 +808,48 @@ class Peppol extends AbstractService
return $this; return $this;
} }
/**
* DE
*
* @Completed
* @Tested
*
* @return self
*/
private function DE(): self private function DE(): self
{ {
// accountingsupplierparty.party.contact MUST be set - Name / Telephone / Electronic Mail
// this is forced by default.
$this->setPaymentMeans(true); $this->setPaymentMeans(true);
return $this; return $this;
} }
/**
* CH
*
* @Completed
*
* Completed - QR-Bill to be implemented at a later date.
* @return self
*/
private function CH(): self private function CH(): self
{ {
//if QR-Bill support required - then special flow required.... optional.
return $this; return $this;
} }
/**
* AT
*
* @Pending
*
* Need to ensure when sending to government entities that we route appropriately
* Also need to ensure customerAssignedAccountIdValue is set so that the sender can be resolved.
*
* Need a way to define if the client is a government entity.
*
* @return self
*/
private function AT(): self private function AT(): self
{ {
//special fields for sending to AT:GOV //special fields for sending to AT:GOV
@ -804,14 +862,28 @@ class Peppol extends AbstractService
//if payment means are included, they must be the same `type` //if payment means are included, they must be the same `type`
return $this; return $this;
} }
/**
* ES
*
* @Pending
*
* ES:DIRE - routing identifier
*
* testing. //293098
*
* @return self
*/
private function ES(): self private function ES(): self
{ {
// For B2B, provide an ES:DIRE routing identifier and an ES:VAT tax identifier. if(!isset($this->invoice->due_date))
// both sender and receiver must be an ES company; $this->p_invoice->DueDate = new \DateTime($this->invoice->date);
// you must have a "credit_transfer" PaymentMean;
// the "dueDate" property is mandatory. if($this->invoice->client->classification == 'business' && $this->invoice->company->getSetting('classification') == 'business') {
//must have a paymentmeans as credit_transfer
$this->setPaymentMeans(true);
}
// For B2G, provide three ES:FACE identifiers in the routing object, // For B2G, provide three ES:FACE identifiers in the routing object,
// as well as the ES:VAT tax identifier in the accountingCustomerParty.publicIdentifiers. // as well as the ES:VAT tax identifier in the accountingCustomerParty.publicIdentifiers.

View File

@ -1260,6 +1260,7 @@ class SubscriptionService
return Subscription::query() return Subscription::query()
->where('company_id', $this->subscription->company_id) ->where('company_id', $this->subscription->company_id)
->where('group_id', $this->subscription->group_id) ->where('group_id', $this->subscription->group_id)
->whereNotNull('group_id')
->where('id', '!=', $this->subscription->id) ->where('id', '!=', $this->subscription->id)
->get(); ->get();
} }

View File

@ -20,12 +20,18 @@ class PDF extends FPDI
public function Footer() public function Footer()
{ {
$this->SetXY(0, -6); $this->SetXY(0, -6);
$this->SetFont('Arial', 'I', 9); $this->SetFont('Arial', 'I', 9);
$this->SetTextColor(135, 135, 135); $this->SetTextColor(135, 135, 135);
$trans = ctrans('texts.pdf_page_info', ['current' => $this->PageNo(), 'total' => '{nb}']); $trans = ctrans('texts.pdf_page_info', ['current' => $this->PageNo(), 'total' => '{nb}']);
// $trans = iconv('UTF-8', 'ISO-8859-7', $trans);
try {
$trans = mb_convert_encoding($trans, 'ISO-8859-1', 'UTF-8');
}
catch(\Exception $e){}
$this->Cell(0, 5, $trans, 0, 0, $this->text_alignment); $this->Cell(0, 5, $trans, 0, 0, $this->text_alignment);
} }

View File

@ -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.10.19'), 'app_version' => env('APP_VERSION', '5.10.20'),
'app_tag' => env('APP_TAG', '5.10.19'), 'app_tag' => env('APP_TAG', '5.10.20'),
'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),

View File

@ -5311,6 +5311,7 @@ $lang = array(
'customer_type' => 'Customer Type', 'customer_type' => 'Customer Type',
'process_date' => 'Process Date', 'process_date' => 'Process Date',
'forever_free' => 'Forever Free', 'forever_free' => 'Forever Free',
'comments_only' => 'Comments Only',
); );
return $lang; return $lang;

View File

@ -199,7 +199,7 @@ $lang = array(
'removed_logo' => 'Logo eliminado correctamente', 'removed_logo' => 'Logo eliminado correctamente',
'sent_message' => 'Mensaje enviado correctamente', 'sent_message' => 'Mensaje enviado correctamente',
'invoice_error' => 'Seleccionar cliente y corregir errores.', 'invoice_error' => 'Seleccionar cliente y corregir errores.',
'limit_clients' => 'You\'ve hit the :count client limit on Free accounts. Congrats on your success!', 'limit_clients' => 'Has alcanzado el límite de :count clientes en cuentas gratuitas. ¡Felicitaciones por tu éxito!',
'payment_error' => 'Ha habido un error en el proceso de tu Pago. Inténtalo de nuevo más tarde.', 'payment_error' => 'Ha habido un error en el proceso de tu Pago. Inténtalo de nuevo más tarde.',
'registration_required' => 'Se requiere registro', 'registration_required' => 'Se requiere registro',
'confirmation_required' => 'Por favor, confirma tu dirección de correo electrónico, :link para reenviar el email de confirmación.', 'confirmation_required' => 'Por favor, confirma tu dirección de correo electrónico, :link para reenviar el email de confirmación.',
@ -1095,7 +1095,7 @@ $lang = array(
'invoice_embed_documents' => 'Documentos anexados', 'invoice_embed_documents' => 'Documentos anexados',
'invoice_embed_documents_help' => 'Incluye imagenes adjuntas en la factura', 'invoice_embed_documents_help' => 'Incluye imagenes adjuntas en la factura',
'document_email_attachment' => 'Adjuntar documentos', 'document_email_attachment' => 'Adjuntar documentos',
'ubl_email_attachment' => 'Attach UBL/E-Invoice', 'ubl_email_attachment' => 'Adjuntar UBL/E-Invoice',
'download_documents' => 'Descargar documentos (:size)', 'download_documents' => 'Descargar documentos (:size)',
'documents_from_expenses' => 'De los Gastos:', 'documents_from_expenses' => 'De los Gastos:',
'dropzone_default_message' => 'Arrastra ficheros aquí o Haz clic para subir', 'dropzone_default_message' => 'Arrastra ficheros aquí o Haz clic para subir',
@ -2691,7 +2691,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
'no_assets' => 'Sin imágenes, arrastra aquí para subir', 'no_assets' => 'Sin imágenes, arrastra aquí para subir',
'add_image' => 'Añadir Imagen', 'add_image' => 'Añadir Imagen',
'select_image' => 'Seleccionar Imagen', 'select_image' => 'Seleccionar Imagen',
'upgrade_to_upload_images' => 'Upgrade to the Enterprise Plan to upload files & images', 'upgrade_to_upload_images' => 'Actualice al plan Enterprise para cargar archivos e imágenes',
'delete_image' => 'Borrar Imagen', 'delete_image' => 'Borrar Imagen',
'delete_image_help' => 'Atención: borrar la imagen la eliminará de todas las propuestas.', 'delete_image_help' => 'Atención: borrar la imagen la eliminará de todas las propuestas.',
'amount_variable_help' => 'Nota: el campo de la factura $amount usará el campo parcial/depósito si se indica, de otra forma se usará el balance de la factura.', 'amount_variable_help' => 'Nota: el campo de la factura $amount usará el campo parcial/depósito si se indica, de otra forma se usará el balance de la factura.',
@ -2909,13 +2909,13 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
'mime_types' => 'Tipos de ficheros', 'mime_types' => 'Tipos de ficheros',
'mime_types_placeholder' => '.pdf , .docx, .jpg', 'mime_types_placeholder' => '.pdf , .docx, .jpg',
'mime_types_help' => 'Lista separada por comas de los tipos mime de fichero aceptados, déjalo en blanco para todos', 'mime_types_help' => 'Lista separada por comas de los tipos mime de fichero aceptados, déjalo en blanco para todos',
'ticket_number_start_help' => 'Ticket number must be greater than the current ticket number', 'ticket_number_start_help' => 'El número de ticket debe ser mayor que el número de ticket actual',
'new_ticket_template_id' => 'New ticket', 'new_ticket_template_id' => 'Nuevo Ticket',
'new_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a new ticket is created', 'new_ticket_autoresponder_help' => 'Al seleccionar una plantilla se enviará una respuesta automática a un cliente/contacto cuando se cree un nuevo ticket.',
'update_ticket_template_id' => 'Updated ticket', 'update_ticket_template_id' => 'Ticket actualizado',
'update_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a ticket is updated', 'update_ticket_autoresponder_help' => 'Al seleccionar una plantilla se enviará una respuesta automática a un cliente/contacto cuando se actualice un ticket.',
'close_ticket_template_id' => 'Closed ticket', 'close_ticket_template_id' => 'Ticket cerrado',
'close_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a ticket is closed', 'close_ticket_autoresponder_help' => 'Al seleccionar una plantilla se enviará una respuesta automática a un cliente/contacto cuando se cierre un ticket.',
'default_priority' => 'Prioridad por defecto', 'default_priority' => 'Prioridad por defecto',
'alert_new_comment_id' => 'Nuevo comentario', 'alert_new_comment_id' => 'Nuevo comentario',
'update_ticket_notification_list' => 'Notificaciones de nuevo comentario adicionales', 'update_ticket_notification_list' => 'Notificaciones de nuevo comentario adicionales',
@ -3041,7 +3041,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
'portal_mode' => 'Modo portal', 'portal_mode' => 'Modo portal',
'attach_pdf' => 'Adjuntar PDF', 'attach_pdf' => 'Adjuntar PDF',
'attach_documents' => 'Adjuntar Documentos', 'attach_documents' => 'Adjuntar Documentos',
'attach_ubl' => 'Attach UBL/E-Invoice', 'attach_ubl' => 'Adjuntar UBL/E-Invoice',
'email_style' => 'Estilo de correo electrónico', 'email_style' => 'Estilo de correo electrónico',
'processed' => 'Procesado', 'processed' => 'Procesado',
'fee_amount' => 'Importe de la cuota', 'fee_amount' => 'Importe de la cuota',
@ -3782,7 +3782,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
'entity_number_placeholder' => ':entity # :entity_number', 'entity_number_placeholder' => ':entity # :entity_number',
'email_link_not_working' => 'Si el botón de arriba no te está funcionando, por favor pulsa en el enlace', 'email_link_not_working' => 'Si el botón de arriba no te está funcionando, por favor pulsa en el enlace',
'display_log' => 'Mostrar Registro', 'display_log' => 'Mostrar Registro',
'send_fail_logs_to_our_server' => 'Report errors to help improve the app', 'send_fail_logs_to_our_server' => 'Informar errores para ayudar a mejorar la aplicación',
'setup' => 'Instalación', 'setup' => 'Instalación',
'quick_overview_statistics' => 'Vistazo rápido y estadísticas', 'quick_overview_statistics' => 'Vistazo rápido y estadísticas',
'update_your_personal_info' => 'Actualiza tu información personal', 'update_your_personal_info' => 'Actualiza tu información personal',
@ -4371,7 +4371,7 @@ Una vez que tenga los montos, vuelva a esta página de métodos de pago y haga c
'client_shipping_country' => 'País de envío del cliente', 'client_shipping_country' => 'País de envío del cliente',
'load_pdf' => 'Cargar PDF', 'load_pdf' => 'Cargar PDF',
'start_free_trial' => 'Iniciar prueba gratuita', 'start_free_trial' => 'Iniciar prueba gratuita',
'start_free_trial_message' => 'Start your FREE 14 day trial of the Pro Plan', 'start_free_trial_message' => 'Comience su prueba GRATUITA de 14 días del Plan Pro',
'due_on_receipt' => 'Adeudado a la recepción', 'due_on_receipt' => 'Adeudado a la recepción',
'is_paid' => 'Está pagado', 'is_paid' => 'Está pagado',
'age_group_paid' => 'Pagado', 'age_group_paid' => 'Pagado',
@ -5082,7 +5082,7 @@ De lo contrario, este campo deberá dejarse en blanco.',
'payment_refund_receipt' => 'Recibo de reembolso de pago Nº :number', 'payment_refund_receipt' => 'Recibo de reembolso de pago Nº :number',
'payment_receipt' => 'Recibo de pago Nº :number', 'payment_receipt' => 'Recibo de pago Nº :number',
'load_template_description' => 'La plantilla se aplicará a lo siguiente:', 'load_template_description' => 'La plantilla se aplicará a lo siguiente:',
'run_template' => 'Run Template', 'run_template' => 'Ejecutar plantilla',
'statement_design' => 'Diseño de Estado de Cuenta', 'statement_design' => 'Diseño de Estado de Cuenta',
'delivery_note_design' => 'Diseño de albarán de entrega', 'delivery_note_design' => 'Diseño de albarán de entrega',
'payment_receipt_design' => 'Diseño de recibo de pago', 'payment_receipt_design' => 'Diseño de recibo de pago',
@ -5121,7 +5121,7 @@ De lo contrario, este campo deberá dejarse en blanco.',
'all_contacts' => 'Todos los contactos', 'all_contacts' => 'Todos los contactos',
'insert_below' => 'Insertar abajo', 'insert_below' => 'Insertar abajo',
'nordigen_handler_subtitle' => 'Autenticación de cuenta bancaria. Seleccionar su institución para completar la solicitud con las credenciales de su cuenta.', 'nordigen_handler_subtitle' => 'Autenticación de cuenta bancaria. Seleccionar su institución para completar la solicitud con las credenciales de su cuenta.',
'nordigen_handler_error_heading_unknown' => 'Ha ocurrido un error', 'nordigen_handler_error_heading_unknown' => 'Se ha producido un error',
'nordigen_handler_error_contents_unknown' => '¡Se ha producido un error desconocido! Razón:', 'nordigen_handler_error_contents_unknown' => '¡Se ha producido un error desconocido! Razón:',
'nordigen_handler_error_heading_token_invalid' => 'Token no válido', 'nordigen_handler_error_heading_token_invalid' => 'Token no válido',
'nordigen_handler_error_contents_token_invalid' => 'El token proporcionado no era válido. Póngase en contacto con el soporte para obtener ayuda si este problema persiste.', 'nordigen_handler_error_contents_token_invalid' => 'El token proporcionado no era válido. Póngase en contacto con el soporte para obtener ayuda si este problema persiste.',
@ -5235,69 +5235,79 @@ De lo contrario, este campo deberá dejarse en blanco.',
'local_domain_help' => 'Dominio EHLO (opcional)', 'local_domain_help' => 'Dominio EHLO (opcional)',
'port_help' => 'Ej. 25.587.465', 'port_help' => 'Ej. 25.587.465',
'host_help' => 'Ej. smtp.gmail.com', 'host_help' => 'Ej. smtp.gmail.com',
'always_show_required_fields' => 'Allows show required fields form', 'always_show_required_fields' => 'Mostrar siempre los campos obligatorios del formulario',
'always_show_required_fields_help' => 'Displays the required fields form always at checkout', 'always_show_required_fields_help' => 'Muestra siempre el formulario de campos obligatorios al finalizar la compra',
'advanced_cards' => 'Advanced Cards', 'advanced_cards' => 'Tarjetas avanzadas',
'activity_140' => 'Statement sent to :client', 'activity_140' => 'Declaración enviada a :client',
'invoice_net_amount' => 'Invoice Net Amount', 'invoice_net_amount' => 'Importe neto de la factura',
'round_to_minutes' => 'Round To Minutes', 'round_to_minutes' => 'Redondear a minutos',
'1_second' => '1 Second', '1_second' => '1 segundo',
'1_minute' => '1 Minute', '1_minute' => '1 minuto',
'5_minutes' => '5 Minutes', '5_minutes' => '5 minutos',
'15_minutes' => '15 Minutes', '15_minutes' => '15 minutos',
'30_minutes' => '30 Minutes', '30_minutes' => '30 minutos',
'1_hour' => '1 Hour', '1_hour' => '1 hora',
'1_day' => '1 Day', '1_day' => '1 día',
'round_tasks' => 'Task Rounding Direction', 'round_tasks' => 'Dirección de redondeo de tareas',
'round_tasks_help' => 'Round task times up or down.', 'round_tasks_help' => 'Redondea los tiempos de las tareas hacia arriba o hacia abajo.',
'direction' => 'Direction', 'direction' => 'Dirección',
'round_up' => 'Round Up', 'round_up' => 'Redondeo',
'round_down' => 'Round Down', 'round_down' => 'Redondear a la baja',
'task_round_to_nearest' => 'Round To Nearest', 'task_round_to_nearest' => 'Redondear al más cercano',
'task_round_to_nearest_help' => 'The interval to round the task to.', 'task_round_to_nearest_help' => 'El intervalo al que se debe redondear la tarea.',
'bulk_updated' => 'Successfully updated data', 'bulk_updated' => 'Datos actualizados con éxito',
'bulk_update' => 'Bulk Update', 'bulk_update' => 'Actualización masiva',
'calculate' => 'Calculate', 'calculate' => 'Calcular',
'sum' => 'Sum', 'sum' => 'Suma',
'money' => 'Money', 'money' => 'Dinero',
'web_app' => 'Web App', 'web_app' => 'Aplicación Web',
'desktop_app' => 'Desktop App', 'desktop_app' => 'Aplicación de escritorio',
'disconnected' => 'Disconnected', 'disconnected' => 'Desconectado',
'reconnect' => 'Reconnect', 'reconnect' => 'Reconectar',
'e_invoice_settings' => 'E-Invoice Settings', 'e_invoice_settings' => 'Configuración de factura electrónica',
'btcpay_refund_subject' => 'Refund of your invoice via BTCPay', 'btcpay_refund_subject' => 'Reembolso de su factura a través de BTCPay',
'btcpay_refund_body' => 'A refund intended for you has been issued. To claim it via BTCPay, please click on this link:', 'btcpay_refund_body' => 'Se ha emitido un reembolso destinado a usted. Para reclamarlo a través de BTCPay, haga clic en este enlace:',
'currency_mauritanian_ouguiya' => 'Mauritanian Ouguiya', 'currency_mauritanian_ouguiya' => 'Mauritanian Ouguiya',
'currency_bhutan_ngultrum' => 'Bhutan Ngultrum', 'currency_bhutan_ngultrum' => 'Bhutan Ngultrum',
'end_of_month' => 'End Of Month', 'end_of_month' => 'Fin de mes',
'merge_e_invoice_to_pdf' => 'Merge E-Invoice and PDF', 'merge_e_invoice_to_pdf' => 'Fusionar factura electrónica y PDF',
'task_assigned_subject' => 'New task assignment [Task :task] [ :date ]', 'task_assigned_subject' => 'Nueva asignación de tarea [Tarea :task] [ :date ]',
'task_assigned_body' => 'You have been assigned task :task <br><br> Description: :description <br><br> Client: :client', 'task_assigned_body' => 'Se le ha asignado la tarea :task <br><br> Descripción: :description <br><br> Cliente: :client',
'activity_141' => 'User :user entered note: :notes', 'activity_141' => 'El usuario: :user ingresó la nota: :notes',
'quote_reminder_subject' => 'Reminder: Quote :quote from :company', 'quote_reminder_subject' => 'Recordatorio: Presupuesto :quote de :company',
'quote_reminder_message' => 'Reminder for quote :number for :amount', 'quote_reminder_message' => 'Recordatorio de presupuesto :number por :amount',
'quote_reminder1' => 'First Quote Reminder', 'quote_reminder1' => 'Recordatorio del primer presupuesto',
'before_valid_until_date' => 'Before the valid until date', 'before_valid_until_date' => 'Antes del válido hasta la fecha',
'after_valid_until_date' => 'After the valid until date', 'after_valid_until_date' => 'Después de la fecha de validez hasta',
'after_quote_date' => 'After the quote date', 'after_quote_date' => 'Después de la fecha del presupuesto',
'remind_quote' => 'Remind Quote', 'remind_quote' => 'Recordatorio de presupuesto',
'end_of_month' => 'End Of Month', 'end_of_month' => 'Fin de mes',
'tax_currency_mismatch' => 'Tax currency is different from invoice currency', 'tax_currency_mismatch' => 'La moneda del impuesto es diferente a la moneda de la factura',
'edocument_import_already_exists' => 'The invoice has already been imported on :date', 'edocument_import_already_exists' => 'La factura ya fué importada el :date',
'before_valid_until' => 'Before the valid until', 'before_valid_until' => 'Antes del válido hasta',
'after_valid_until' => 'After the valid until', 'after_valid_until' => 'Después del válido hasta',
'task_assigned_notification' => 'Task Assigned Notification', 'task_assigned_notification' => 'Notificación de tarea asignada',
'task_assigned_notification_help' => 'Send an email when a task is assigned', 'task_assigned_notification_help' => 'Enviar un correo electrónico cuando se asigna una tarea',
'invoices_locked_end_of_month' => 'Invoices are locked at the end of the month', 'invoices_locked_end_of_month' => 'Las facturas se bloquean al final del mes.',
'referral_url' => 'Referral URL', 'referral_url' => 'URL de referencia',
'add_comment' => 'Add Comment', 'add_comment' => 'Agregar comentario',
'added_comment' => 'Successfully saved comment', 'added_comment' => 'Comentario guardado correctamente',
'tickets' => 'Tickets', 'tickets' => 'Tickets',
'assigned_group' => 'Successfully assigned group', 'assigned_group' => 'Grupo asignado exitosamente',
'merge_to_pdf' => 'Merge to PDF', 'merge_to_pdf' => 'Fusionar a PDF',
'latest_requires_php_version' => 'Note: the latest version requires PHP :version', 'latest_requires_php_version' => 'Nota: la última versión requiere PHP :version',
'auto_expand_product_table_notes' => 'Automatically expand products table notes', 'auto_expand_product_table_notes' => 'Expandir automáticamente las notas de la tabla de productos',
'auto_expand_product_table_notes_help' => 'Automatically expands the notes section within the products table to display more lines.', 'auto_expand_product_table_notes_help' => 'Expande automáticamente la sección de notas dentro de la tabla de productos para mostrar más líneas.',
'institution_number' => 'Número de institución',
'transit_number' => 'Número de Tránsito',
'personal' => 'Personal',
'address_information' => 'Datos del Domicilio',
'enter_the_information_for_the_bank_account' => 'Introduzca la información de la cuenta bancaria',
'account_holder_information' => 'Información del titular de la cuenta',
'enter_information_for_the_account_holder' => 'Introducir información del titular de la cuenta',
'customer_type' => 'Tipo de cliente',
'process_date' => 'Fecha de procesamiento',
'forever_free' => 'Forever Free',
); );
return $lang; return $lang;

View File

@ -5235,7 +5235,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
'local_domain_help' => 'Domaine EHLO (facultatif)', 'local_domain_help' => 'Domaine EHLO (facultatif)',
'port_help' => 'ex. 25,587,465', 'port_help' => 'ex. 25,587,465',
'host_help' => 'ex. smtp.gmail.com', 'host_help' => 'ex. smtp.gmail.com',
'always_show_required_fields' => 'Permet l\'affichage des champs requis d\'un formulaire', 'always_show_required_fields' => 'Toujours afficher les champs requis d\'un formulaire',
'always_show_required_fields_help' => 'Affiche toujours les champs requis d\'un formulaire au paiement', 'always_show_required_fields_help' => 'Affiche toujours les champs requis d\'un formulaire au paiement',
'advanced_cards' => 'Cartes avancées', 'advanced_cards' => 'Cartes avancées',
'activity_140' => 'État de compte envoyé à :client', 'activity_140' => 'État de compte envoyé à :client',
@ -5298,7 +5298,17 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
'latest_requires_php_version' => 'Note: La dernière version requiert PHP :version', 'latest_requires_php_version' => 'Note: La dernière version requiert PHP :version',
'auto_expand_product_table_notes' => 'Développer automatiquement les notes du tableau de produits', 'auto_expand_product_table_notes' => 'Développer automatiquement les notes du tableau de produits',
'auto_expand_product_table_notes_help' => '  'auto_expand_product_table_notes_help' => ' 
Développe automatiquement la section des notes dans le tableau de produits pour afficher plus de lignes.' Développe automatiquement la section des notes dans le tableau de produits pour afficher plus de lignes.',
'institution_number' => 'Numéro d\'institution',
'transit_number' => 'Numéro de transit',
'personal' => 'Personnel',
'address_information' => 'Information d\'adresse',
'enter_the_information_for_the_bank_account' => 'Entrez l\'information du compte de banque',
'account_holder_information' => 'Information sur le détenteur du compte',
'enter_information_for_the_account_holder' => 'Entrez l\'information du détenteur du compte',
'customer_type' => 'Type de client',
'process_date' => 'Date de traitement',
'forever_free' => 'Gratuit pour toujours',
); );
return $lang; return $lang;

View File

@ -3428,7 +3428,7 @@ adva :date',
'reminder2_sent' => 'Emlékeztető 2 elküldve', 'reminder2_sent' => 'Emlékeztető 2 elküldve',
'reminder3_sent' => 'Emlékeztető 3 elküldve', 'reminder3_sent' => 'Emlékeztető 3 elküldve',
'reminder_last_sent' => 'Utolsó emlékeztető elküldve', 'reminder_last_sent' => 'Utolsó emlékeztető elküldve',
'pdf_page_info' => 'PDF oldal információ', 'pdf_page_info' => 'PDF oldal :current / :total',
'emailed_credits' => 'E-mailezett jóváírások', 'emailed_credits' => 'E-mailezett jóváírások',
'view_in_stripe' => 'Megtekintés a Stripe-ban', 'view_in_stripe' => 'Megtekintés a Stripe-ban',
'rows_per_page' => 'Sorok száma oldalanként', 'rows_per_page' => 'Sorok száma oldalanként',
@ -5108,7 +5108,7 @@ adva :date',
'all_contacts' => 'Minden névjegy', 'all_contacts' => 'Minden névjegy',
'insert_below' => 'Beszúrás alább', 'insert_below' => 'Beszúrás alább',
'nordigen_handler_subtitle' => 'Bankszámla hitelesítés. Intézményének kiválasztása a kérelem kitöltéséhez a fiók hitelesítő adataival.', 'nordigen_handler_subtitle' => 'Bankszámla hitelesítés. Intézményének kiválasztása a kérelem kitöltéséhez a fiók hitelesítő adataival.',
'nordigen_handler_error_heading_unknown' => 'Hiba történt', 'nordigen_handler_error_heading_unknown' => 'An error has occurred',
'nordigen_handler_error_contents_unknown' => 'Ismeretlen hiba lépett fel! Ok:', 'nordigen_handler_error_contents_unknown' => 'Ismeretlen hiba lépett fel! Ok:',
'nordigen_handler_error_heading_token_invalid' => 'Érvénytelen kód', 'nordigen_handler_error_heading_token_invalid' => 'Érvénytelen kód',
'nordigen_handler_error_contents_token_invalid' => 'A megadott token érvénytelen. Ha a probléma továbbra is fennáll, forduljon az ügyfélszolgálathoz.', 'nordigen_handler_error_contents_token_invalid' => 'A megadott token érvénytelen. Ha a probléma továbbra is fennáll, forduljon az ügyfélszolgálathoz.',
@ -5222,7 +5222,7 @@ adva :date',
'local_domain_help' => 'EHLO domain (optional)', 'local_domain_help' => 'EHLO domain (optional)',
'port_help' => 'ie. 25,587,465', 'port_help' => 'ie. 25,587,465',
'host_help' => 'ie. smtp.gmail.com', 'host_help' => 'ie. smtp.gmail.com',
'always_show_required_fields' => 'Allows show required fields form', 'always_show_required_fields' => 'Always show required fields form',
'always_show_required_fields_help' => 'Displays the required fields form always at checkout', 'always_show_required_fields_help' => 'Displays the required fields form always at checkout',
'advanced_cards' => 'Advanced Cards', 'advanced_cards' => 'Advanced Cards',
'activity_140' => 'Statement sent to :client', 'activity_140' => 'Statement sent to :client',
@ -5285,6 +5285,16 @@ adva :date',
'latest_requires_php_version' => 'Note: the latest version requires PHP :version', 'latest_requires_php_version' => 'Note: the latest version requires PHP :version',
'auto_expand_product_table_notes' => 'Automatically expand products table notes', 'auto_expand_product_table_notes' => 'Automatically expand products table notes',
'auto_expand_product_table_notes_help' => 'Automatically expands the notes section within the products table to display more lines.', 'auto_expand_product_table_notes_help' => 'Automatically expands the notes section within the products table to display more lines.',
'institution_number' => 'Institution Number',
'transit_number' => 'Transit Number',
'personal' => 'Personal',
'address_information' => 'Address Information',
'enter_the_information_for_the_bank_account' => 'Enter the Information for the Bank Account',
'account_holder_information' => 'Account Holder Information',
'enter_information_for_the_account_holder' => 'Enter Information for the Account Holder',
'customer_type' => 'Customer Type',
'process_date' => 'Process Date',
'forever_free' => 'Forever Free',
); );
return $lang; return $lang;

View File

@ -3444,7 +3444,7 @@ $lang = array(
'reminder2_sent' => 'ແຈ້ງເຕືອນ 2 ສົ່ງແລ້ວ', 'reminder2_sent' => 'ແຈ້ງເຕືອນ 2 ສົ່ງແລ້ວ',
'reminder3_sent' => 'ເຕືອນ 3 ສົ່ງແລ້ວ', 'reminder3_sent' => 'ເຕືອນ 3 ສົ່ງແລ້ວ',
'reminder_last_sent' => 'ເຕືອນທີ່ສົ່ງຫຼ້າສຸດ', 'reminder_last_sent' => 'ເຕືອນທີ່ສົ່ງຫຼ້າສຸດ',
'pdf_page_info' => 'ໜ້າ :ປັດຈຸບັນຂອງ :ທັງໝົດ', 'pdf_page_info' => 'ໜ້າ :current :total',
'emailed_credits' => 'ເຄຣດິດທີ່ສົ່ງອີເມວສຳເລັດແລ້ວ', 'emailed_credits' => 'ເຄຣດິດທີ່ສົ່ງອີເມວສຳເລັດແລ້ວ',
'view_in_stripe' => 'ເບິ່ງເປັນເສັ້ນດ່າງ', 'view_in_stripe' => 'ເບິ່ງເປັນເສັ້ນດ່າງ',
'rows_per_page' => 'ແຖວຕໍ່ໜ້າ', 'rows_per_page' => 'ແຖວຕໍ່ໜ້າ',
@ -5124,7 +5124,7 @@ $lang = array(
'all_contacts' => 'ຕິດຕໍ່ພົວພັນທັງໝົດ', 'all_contacts' => 'ຕິດຕໍ່ພົວພັນທັງໝົດ',
'insert_below' => 'ໃສ່ທາງລຸ່ມ', 'insert_below' => 'ໃສ່ທາງລຸ່ມ',
'nordigen_handler_subtitle' => 'ການຢືນຢັນບັນຊີທະນາຄານ. ການເລືອກສະຖາບັນຂອງທ່ານເພື່ອເຮັດສໍາເລັດຄໍາຮ້ອງຂໍທີ່ມີຂໍ້ມູນປະຈໍາບັນຊີຂອງທ່ານ.', 'nordigen_handler_subtitle' => 'ການຢືນຢັນບັນຊີທະນາຄານ. ການເລືອກສະຖາບັນຂອງທ່ານເພື່ອເຮັດສໍາເລັດຄໍາຮ້ອງຂໍທີ່ມີຂໍ້ມູນປະຈໍາບັນຊີຂອງທ່ານ.',
'nordigen_handler_error_heading_unknown' => 'ເກີດຄວາມຜິດພາດຂຶ້ນ', 'nordigen_handler_error_heading_unknown' => 'An error has occurred',
'nordigen_handler_error_contents_unknown' => 'ມີຄວາມຜິດພາດທີ່ບໍ່ຮູ້ຈັກເກີດຂຶ້ນ! ເຫດ​ຜົນ:', 'nordigen_handler_error_contents_unknown' => 'ມີຄວາມຜິດພາດທີ່ບໍ່ຮູ້ຈັກເກີດຂຶ້ນ! ເຫດ​ຜົນ:',
'nordigen_handler_error_heading_token_invalid' => 'ໂທເຄັນບໍ່ຖືກຕ້ອງ', 'nordigen_handler_error_heading_token_invalid' => 'ໂທເຄັນບໍ່ຖືກຕ້ອງ',
'nordigen_handler_error_contents_token_invalid' => 'ໂທເຄັນທີ່ໃຫ້ມາບໍ່ຖືກຕ້ອງ. ຕິດຕໍ່ຝ່າຍຊ່ວຍເຫຼືອເພື່ອຂໍຄວາມຊ່ວຍເຫຼືອ, ຖ້າບັນຫານີ້ຍັງຄົງຢູ່.', 'nordigen_handler_error_contents_token_invalid' => 'ໂທເຄັນທີ່ໃຫ້ມາບໍ່ຖືກຕ້ອງ. ຕິດຕໍ່ຝ່າຍຊ່ວຍເຫຼືອເພື່ອຂໍຄວາມຊ່ວຍເຫຼືອ, ຖ້າບັນຫານີ້ຍັງຄົງຢູ່.',
@ -5238,7 +5238,7 @@ $lang = array(
'local_domain_help' => 'EHLO domain (optional)', 'local_domain_help' => 'EHLO domain (optional)',
'port_help' => 'ie. 25,587,465', 'port_help' => 'ie. 25,587,465',
'host_help' => 'ie. smtp.gmail.com', 'host_help' => 'ie. smtp.gmail.com',
'always_show_required_fields' => 'ອະນຸຍາດໃຫ້ສະແດງແບບຟອມທີ່ຕ້ອງການ', 'always_show_required_fields' => 'Always show required fields form',
'always_show_required_fields_help' => 'ສະແດງແບບຟອມຊ່ອງຂໍ້ມູນທີ່ຕ້ອງການຢູ່ສະເໝີໃນເວລາຈ່າຍເງິນ', 'always_show_required_fields_help' => 'ສະແດງແບບຟອມຊ່ອງຂໍ້ມູນທີ່ຕ້ອງການຢູ່ສະເໝີໃນເວລາຈ່າຍເງິນ',
'advanced_cards' => 'ບັດຂັ້ນສູງ', 'advanced_cards' => 'ບັດຂັ້ນສູງ',
'activity_140' => 'Statement sent to :client', 'activity_140' => 'Statement sent to :client',
@ -5301,6 +5301,16 @@ $lang = array(
'latest_requires_php_version' => 'Note: the latest version requires PHP :version', 'latest_requires_php_version' => 'Note: the latest version requires PHP :version',
'auto_expand_product_table_notes' => 'Automatically expand products table notes', 'auto_expand_product_table_notes' => 'Automatically expand products table notes',
'auto_expand_product_table_notes_help' => 'Automatically expands the notes section within the products table to display more lines.', 'auto_expand_product_table_notes_help' => 'Automatically expands the notes section within the products table to display more lines.',
'institution_number' => 'Institution Number',
'transit_number' => 'Transit Number',
'personal' => 'Personal',
'address_information' => 'Address Information',
'enter_the_information_for_the_bank_account' => 'Enter the Information for the Bank Account',
'account_holder_information' => 'Account Holder Information',
'enter_information_for_the_account_holder' => 'Enter Information for the Account Holder',
'customer_type' => 'Customer Type',
'process_date' => 'Process Date',
'forever_free' => 'Forever Free',
); );
return $lang; return $lang;

View File

@ -1646,7 +1646,7 @@ Quando tiver as quantias, volte a esta página de formas de pagamento e clique "
'country_Turkey' => 'Turquia', 'country_Turkey' => 'Turquia',
'country_Turkmenistan' => 'Turcomenistão', 'country_Turkmenistan' => 'Turcomenistão',
'country_Turks and Caicos Islands' => 'Ilhas Turks e Caicos', 'country_Turks and Caicos Islands' => 'Ilhas Turks e Caicos',
'country_Tuvalu' => 'Tuvalu', 'country_Tuvalu' => ' Tuvalu',
'country_Uganda' => 'Uganda', 'country_Uganda' => 'Uganda',
'country_Ukraine' => 'Ucrânia', 'country_Ukraine' => 'Ucrânia',
'country_Macedonia, the former Yugoslav Republic of' => 'Macedônia, antiga República Iugoslava', 'country_Macedonia, the former Yugoslav Republic of' => 'Macedônia, antiga República Iugoslava',
@ -3441,7 +3441,7 @@ Quando tiver as quantias, volte a esta página de formas de pagamento e clique "
'reminder2_sent' => 'Lembrete 2 Enviado', 'reminder2_sent' => 'Lembrete 2 Enviado',
'reminder3_sent' => 'Lembrete 3 Enviado', 'reminder3_sent' => 'Lembrete 3 Enviado',
'reminder_last_sent' => 'Último Lembrete Enviado', 'reminder_last_sent' => 'Último Lembrete Enviado',
'pdf_page_info' => 'Página: atual de: total', 'pdf_page_info' => 'Página: :current de: :total',
'emailed_credits' => 'Créditos enviados por e-mail com sucesso', 'emailed_credits' => 'Créditos enviados por e-mail com sucesso',
'view_in_stripe' => 'Ver em Listra', 'view_in_stripe' => 'Ver em Listra',
'rows_per_page' => 'Linhas por Página', 'rows_per_page' => 'Linhas por Página',
@ -5121,7 +5121,7 @@ Quando tiver as quantias, volte a esta página de formas de pagamento e clique "
'all_contacts' => 'Todos os contatos', 'all_contacts' => 'Todos os contatos',
'insert_below' => 'Inserir abaixo', 'insert_below' => 'Inserir abaixo',
'nordigen_handler_subtitle' => 'Autenticação de conta bancária. Selecionando sua instituição para concluir a solicitação com as credenciais de sua conta.', 'nordigen_handler_subtitle' => 'Autenticação de conta bancária. Selecionando sua instituição para concluir a solicitação com as credenciais de sua conta.',
'nordigen_handler_error_heading_unknown' => 'Ocorreu um erro', 'nordigen_handler_error_heading_unknown' => 'An error has occurred',
'nordigen_handler_error_contents_unknown' => 'Um erro desconhecido ocorreu! Razão:', 'nordigen_handler_error_contents_unknown' => 'Um erro desconhecido ocorreu! Razão:',
'nordigen_handler_error_heading_token_invalid' => 'Token inválido', 'nordigen_handler_error_heading_token_invalid' => 'Token inválido',
'nordigen_handler_error_contents_token_invalid' => 'O token fornecido era inválido. Entre em contato com o suporte para obter ajuda, se o problema persistir.', 'nordigen_handler_error_contents_token_invalid' => 'O token fornecido era inválido. Entre em contato com o suporte para obter ajuda, se o problema persistir.',
@ -5235,7 +5235,7 @@ Quando tiver as quantias, volte a esta página de formas de pagamento e clique "
'local_domain_help' => 'EHLO domain (optional)', 'local_domain_help' => 'EHLO domain (optional)',
'port_help' => 'ie. 25,587,465', 'port_help' => 'ie. 25,587,465',
'host_help' => 'ie. smtp.gmail.com', 'host_help' => 'ie. smtp.gmail.com',
'always_show_required_fields' => 'Allows show required fields form', 'always_show_required_fields' => 'Always show required fields form',
'always_show_required_fields_help' => 'Displays the required fields form always at checkout', 'always_show_required_fields_help' => 'Displays the required fields form always at checkout',
'advanced_cards' => 'Advanced Cards', 'advanced_cards' => 'Advanced Cards',
'activity_140' => 'Statement sent to :client', 'activity_140' => 'Statement sent to :client',
@ -5298,6 +5298,16 @@ Quando tiver as quantias, volte a esta página de formas de pagamento e clique "
'latest_requires_php_version' => 'Note: the latest version requires PHP :version', 'latest_requires_php_version' => 'Note: the latest version requires PHP :version',
'auto_expand_product_table_notes' => 'Automatically expand products table notes', 'auto_expand_product_table_notes' => 'Automatically expand products table notes',
'auto_expand_product_table_notes_help' => 'Automatically expands the notes section within the products table to display more lines.', 'auto_expand_product_table_notes_help' => 'Automatically expands the notes section within the products table to display more lines.',
'institution_number' => 'Institution Number',
'transit_number' => 'Transit Number',
'personal' => 'Personal',
'address_information' => 'Address Information',
'enter_the_information_for_the_bank_account' => 'Enter the Information for the Bank Account',
'account_holder_information' => 'Account Holder Information',
'enter_information_for_the_account_holder' => 'Enter Information for the Account Holder',
'customer_type' => 'Customer Type',
'process_date' => 'Process Date',
'forever_free' => 'Forever Free',
); );
return $lang; return $lang;

View File

@ -3443,7 +3443,7 @@ debitar da sua conta de acordo com essas instruções. Está elegível a um reem
'reminder2_sent' => 'Lembrete 2 Enviado', 'reminder2_sent' => 'Lembrete 2 Enviado',
'reminder3_sent' => 'Lembrete 3 Enviado', 'reminder3_sent' => 'Lembrete 3 Enviado',
'reminder_last_sent' => 'Último Lembrete Enviado', 'reminder_last_sent' => 'Último Lembrete Enviado',
'pdf_page_info' => 'Página: atual de: total', 'pdf_page_info' => 'Página: :current de: :total',
'emailed_credits' => 'Créditos enviados por e-mail com sucesso', 'emailed_credits' => 'Créditos enviados por e-mail com sucesso',
'view_in_stripe' => 'Ver em Formato Lista', 'view_in_stripe' => 'Ver em Formato Lista',
'rows_per_page' => 'Colunas por Página', 'rows_per_page' => 'Colunas por Página',

View File

@ -67,10 +67,8 @@ class PeppolTest extends TestCase
$settings->country_id = '276'; $settings->country_id = '276';
$settings->currency_id = '3'; $settings->currency_id = '3';
$einvoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice(); $einvoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice();
$fib = new FinancialInstitutionBranch(); $fib = new FinancialInstitutionBranch();
$fib->ID = "DEUTDEMMXXX"; //BIC $fib->ID = "DEUTDEMMXXX"; //BIC
$fib->Name = 'Deutsche Bank'; $fib->Name = 'Deutsche Bank';
@ -88,10 +86,13 @@ class PeppolTest extends TestCase
$pm->PayeeFinancialAccount = $pfa; $pm->PayeeFinancialAccount = $pfa;
$einvoice->PaymentMeans[] = $pm; $einvoice->PaymentMeans[] = $pm;
$stub = new \stdClass;
$stub->Invoice = $einvoice;
$company = Company::factory()->create([ $company = Company::factory()->create([
'account_id' => $this->account->id, 'account_id' => $this->account->id,
'settings' => $settings, 'settings' => $settings,
'e_invoice' => $einvoice, 'e_invoice' => $stub,
]); ]);
$cu = CompanyUserFactory::create($this->user->id, $company->id, $this->account->id); $cu = CompanyUserFactory::create($this->user->id, $company->id, $this->account->id);
@ -149,11 +150,12 @@ class PeppolTest extends TestCase
$this->assertEquals(119, $invoice->amount); $this->assertEquals(119, $invoice->amount);
$peppol = new Peppol($invoice); $peppol = new Peppol($invoice);
$peppol->setInvoiceDefaults(); $peppol->setInvoiceDefaults();
$peppol->run(); $peppol->run();
nlog($peppol->toXml());
$de_invoice = $peppol->getInvoice(); $de_invoice = $peppol->getInvoice();
$this->assertNotNull($de_invoice); $this->assertNotNull($de_invoice);
@ -207,10 +209,14 @@ class PeppolTest extends TestCase
$pm->PayeeFinancialAccount = $pfa; $pm->PayeeFinancialAccount = $pfa;
$einvoice->PaymentMeans[] = $pm; $einvoice->PaymentMeans[] = $pm;
$stub = new \stdClass();
$stub->Invoice = $einvoice;
$company = Company::factory()->create([ $company = Company::factory()->create([
'account_id' => $this->account->id, 'account_id' => $this->account->id,
'settings' => $settings, 'settings' => $settings,
'e_invoice' => $einvoice, 'e_invoice' => $stub,
]); ]);
$cu = CompanyUserFactory::create($this->user->id, $company->id, $this->account->id); $cu = CompanyUserFactory::create($this->user->id, $company->id, $this->account->id);

View File

@ -314,21 +314,23 @@ class ExpenseApiTest extends TestCase
public function testExpenseBulkCategorize() public function testExpenseBulkCategorize()
{ {
$eXX = Expense::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
]);
$e = Expense::factory()->create([ $e = Expense::factory()->create([
'company_id' => $this->company->id, 'company_id' => $this->company->id,
'user_id' => $this->user->id, 'user_id' => $this->user->id,
]); ]);
$ec = ExpenseCategory::factory()->create([ $ec = ExpenseCategory::factory()->create([
'company_id' => $this->company->id, 'company_id' => $this->company->id,
'user_id' => $this->user->id, 'user_id' => $this->user->id,
'name' => 'Test Category', 'name' => 'Test Category',
]); ]);
nlog("expense category id = {$ec->hashed_id}");
$data = [ $data = [
'category_id' => $ec->hashed_id, 'category_id' => $ec->hashed_id,
'action' => 'bulk_categorize', 'action' => 'bulk_categorize',
@ -341,11 +343,32 @@ class ExpenseApiTest extends TestCase
])->post('/api/v1/expenses/bulk', $data); ])->post('/api/v1/expenses/bulk', $data);
$arr = $response->json(); $arr = $response->json();
nlog($arr);
$this->assertEquals($ec->hashed_id, $arr['data'][0]['category_id']); $this->assertEquals($ec->hashed_id, $arr['data'][0]['category_id']);
}
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/expenses");
$response->assertStatus(200);
$arr = $response->json();
$this->assertGreaterThan(1, count($arr['data']));
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->get("/api/v1/expenses?categories={$ec->hashed_id}");
$response->assertStatus(200);
$arr = $response->json();
$this->assertCount(1, $arr['data']);
}
public function testAddingExpense() public function testAddingExpense()
{ {

View File

@ -28,7 +28,7 @@ class StorecoveTest extends TestCase
use MockAccountData; use MockAccountData;
use DatabaseTransactions; use DatabaseTransactions;
private string $routing_id = ''; private int $routing_id;
protected function setUp(): void protected function setUp(): void
{ {
@ -352,7 +352,7 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
$sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove();
$sc->sendDocument($x); $sc->sendDocument($x, 290868);
} }
*/ */
@ -398,10 +398,117 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
} }
private function createESData()
{
$this->routing_id = 293098;
$settings = CompanySettings::defaults();
$settings->company_logo = 'https://pdf.invoicing.co/favicon-v2.png';
$settings->website = 'www.invoiceninja.de';
$settings->address1 = 'Calle Gran Vía, 28';
$settings->address2 = 'Edificio Telefónica';
$settings->city = 'Madrid';
$settings->state = 'Madrid';
$settings->postal_code = '28013';
$settings->phone = '030 1234567';
$settings->email = $this->faker->unique()->safeEmail();
$settings->country_id = '724'; // Germany's ISO country code
$settings->vat_number = 'ESB16645678';
$settings->id_number = 'HRB 12345';
$settings->use_credits_payment = 'always';
$settings->timezone_id = '1'; // CET (Central European Time)
$settings->entity_send_time = 0;
$settings->e_invoice_type = 'PEPPOL';
$settings->currency_id = '3';
$settings->classification = 'business';
$company = Company::factory()->create([
'account_id' => $this->account->id,
'settings' => $settings,
]);
$this->user->companies()->attach($company->id, [
'account_id' => $this->account->id,
'is_owner' => true,
'is_admin' => 1,
'is_locked' => 0,
'permissions' => '',
'notifications' => CompanySettings::notificationAdminDefaults(),
'settings' => null,
]);
Client::unguard();
$c =
Client::create([
'company_id' => $company->id,
'user_id' => $this->user->id,
'name' => 'Empresa Ejemplo S.A.',
'website' => 'https://www.empresa-ejemplo.es',
'private_notes' => 'Estas son notas privadas para el cliente de prueba.',
'balance' => 0,
'paid_to_date' => 0,
'vat_number' => 'ESB12345678', // Spanish VAT number with ES prefix
'id_number' => 'B12345678', // Typical format for Spanish company registration numbers
'custom_value1' => '2024-07-22 10:00:00',
'custom_value2' => 'azul', // Spanish for blue
'custom_value3' => 'palabraejemplo', // Spanish for sample word
'custom_value4' => 'test@ejemplo.com',
'address1' => 'Calle Ejemplo 123',
'address2' => '2ª Planta, Oficina 45',
'city' => 'Madrid',
'state' => 'Madrid',
'postal_code' => '28013',
'country_id' => '724', // Spain
'shipping_address1' => 'Calle Ejemplo 123',
'shipping_address2' => '2ª Planta, Oficina 45',
'shipping_city' => 'Madrid',
'shipping_state' => 'Madrid',
'shipping_postal_code' => '28013',
'shipping_country_id' => '724', // Spain
'settings' => ClientSettings::Defaults(),
'client_hash' => \Illuminate\Support\Str::random(32),
'routing_id' => '',
]);
$item = new InvoiceItem();
$item->product_key = "Product Key";
$item->notes = "Product Description";
$item->cost = 10;
$item->quantity = 10;
$item->tax_rate1 = 21;
$item->tax_name1 = 'IVA';
$invoice = Invoice::factory()->create([
'company_id' => $company->id,
'user_id' => $this->user->id,
'client_id' => $c->id,
'discount' => 0,
'uses_inclusive_taxes' => false,
'status_id' => 1,
'tax_rate1' => 0,
'tax_name1' => '',
'tax_rate2' => 0,
'tax_rate3' => 0,
'tax_name2' => '',
'tax_name3' => '',
'line_items' => [$item],
'number' => 'ES-'.rand(1000, 100000),
'date' => now()->format('Y-m-d'),
'due_date' => now()->addDays(14)->format('Y-m-d'),
]);
$invoice = $invoice->calc()->getInvoice();
$invoice->service()->markSent()->save();
return $invoice;
}
private function createDEData() private function createDEData()
{ {
$this->routing_id = '290868'; $this->routing_id = 290868;
$settings = CompanySettings::defaults(); $settings = CompanySettings::defaults();
$settings->company_logo = 'https://pdf.invoicing.co/favicon-v2.png'; $settings->company_logo = 'https://pdf.invoicing.co/favicon-v2.png';
@ -495,7 +602,8 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
'tax_name3' => '', 'tax_name3' => '',
'line_items' => [$item], 'line_items' => [$item],
'number' => 'DE-'.rand(1000, 100000), 'number' => 'DE-'.rand(1000, 100000),
'date' => now()->format('Y-m-d') 'date' => now()->format('Y-m-d'),
'due_date' => now()->addDays(14)->format('Y-m-d'),
]); ]);
$invoice = $invoice->calc()->getInvoice(); $invoice = $invoice->calc()->getInvoice();
@ -506,6 +614,42 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
} }
public function testEsRules()
{
$invoice = $this->createESData();
$e_invoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice();
$stub = json_decode('{"Invoice":{"Note":"Nooo","PaymentMeans":[{"ID":{"value":"afdasfasdfasdfas"},"PayeeFinancialAccount":{"Name":"PFA-NAME","ID":{"value":"DE89370400440532013000"},"AliasName":"PFA-Alias","AccountTypeCode":{"value":"CHECKING"},"AccountFormatCode":{"value":"IBAN"},"CurrencyCode":{"value":"EUR"},"FinancialInstitutionBranch":{"ID":{"value":"DEUTDEMMXXX"},"Name":"Deutsche Bank"}}}]}}');
foreach($stub as $key => $value) {
$e_invoice->{$key} = $value;
}
$invoice->e_invoice = $e_invoice;
$invoice->save();
$this->assertInstanceOf(Invoice::class, $invoice);
$this->assertInstanceof(\InvoiceNinja\EInvoice\Models\Peppol\Invoice::class, $e_invoice);
$p = new Peppol($invoice);
$p->run();
$xml = $p->toXml();
nlog($xml);
$identifiers = [
[
'scheme' => 'ES:VAT',
'id' => 'ESB53625999'
],
];
$sc = new \App\Services\EDocument\Gateway\Storecove\Storecove();
$sc->sendDocument($xml, $this->routing_id, $identifiers);
}
public function testDeRules() public function testDeRules()
{ {
$invoice = $this->createDEData(); $invoice = $this->createDEData();
@ -527,8 +671,16 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
$p->run(); $p->run();
$xml = $p->toXml(); $xml = $p->toXml();
nlog($xml); nlog($xml);
$sc = new \App\Services\EDocument\Gateway\Storecove\Storecove();
$sc->sendDocument($xml); $identifiers = [
[
'scheme' => 'DE:VAT',
'id' => 'DE010101010'
]
];
$sc = new \App\Services\EDocument\Gateway\Storecove\Storecove();
$sc->sendDocument($xml, $this->routing_id, $identifiers);
} }