mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 13:12:50 +01:00
Merge remote-tracking branch 'origin/v5-stripe-backend-refactor' into v2-frontend-refactor
This commit is contained in:
commit
d2e677cb9d
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -40,8 +40,8 @@ jobs:
|
||||
|
||||
- name: Cleanup Builds
|
||||
run: |
|
||||
#sudo rm -rf nodule_modules/
|
||||
sudo rm -rf bootstrap/cache/*
|
||||
sudo rm public/index.html
|
||||
|
||||
- name: Build project # This would actually build your project, using zip for an example artifact
|
||||
run: |
|
||||
|
@ -1 +1 @@
|
||||
5.0.19
|
||||
5.0.22
|
||||
|
@ -112,7 +112,7 @@ class CheckData extends Command
|
||||
->subject('Check-Data: '.strtoupper($this->isValid ? Account::RESULT_SUCCESS : Account::RESULT_FAILURE)." [{$database}]");
|
||||
});
|
||||
} elseif (! $this->isValid) {
|
||||
throw new Exception("Check data failed!!\n".$this->log);
|
||||
new Exception("Check data failed!!\n".$this->log);
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +333,8 @@ class CheckData extends Command
|
||||
$credit_total_applied += $payment->paymentables->where('paymentable_type', App\Models\Credit::class)->sum(\DB::raw('amount'));
|
||||
}
|
||||
|
||||
$total_invoice_payments += $credit_total_applied;
|
||||
if($credit_total_applied < 0)
|
||||
$total_invoice_payments += $credit_total_applied; //todo this is contentious
|
||||
|
||||
info("total invoice payments = {$total_invoice_payments} with client paid to date of of {$client->paid_to_date}");
|
||||
|
||||
|
@ -203,6 +203,10 @@ class CreateSingleAccount extends Command
|
||||
|
||||
$this->info('creating project for client #'.$client->id);
|
||||
$this->createProject($client);
|
||||
|
||||
$this->info('creating credit for client #'.$client->id);
|
||||
$this->createCredit($client);
|
||||
|
||||
}
|
||||
|
||||
$this->createGateways($company, $user);
|
||||
@ -237,6 +241,8 @@ class CreateSingleAccount extends Command
|
||||
|
||||
$settings = $client->settings;
|
||||
$settings->currency_id = "1";
|
||||
$settings->use_credits_payment = "always";
|
||||
|
||||
$client->settings = $settings;
|
||||
|
||||
$country = Country::all()->random();
|
||||
@ -344,11 +350,6 @@ class CreateSingleAccount extends Command
|
||||
|
||||
private function createCredit($client)
|
||||
{
|
||||
// for($x=0; $x<$this->count; $x++){
|
||||
|
||||
// dispatch(new CreateTestCreditJob($client));
|
||||
|
||||
// }
|
||||
$faker = \Faker\Factory::create();
|
||||
|
||||
$credit = Credit::factory()->create(['user_id' => $client->user->id, 'company_id' => $client->company->id, 'client_id' => $client->id]);
|
||||
@ -356,24 +357,9 @@ class CreateSingleAccount extends Command
|
||||
$dateable = Carbon::now()->subDays(rand(0, 90));
|
||||
$credit->date = $dateable;
|
||||
|
||||
$credit->line_items = $this->buildLineItems(rand(1, 10));
|
||||
$credit->line_items = $this->buildCreditItem();
|
||||
$credit->uses_inclusive_taxes = false;
|
||||
|
||||
if (rand(0, 1)) {
|
||||
$credit->tax_name1 = 'GST';
|
||||
$credit->tax_rate1 = 10.00;
|
||||
}
|
||||
|
||||
if (rand(0, 1)) {
|
||||
$credit->tax_name2 = 'VAT';
|
||||
$credit->tax_rate2 = 17.50;
|
||||
}
|
||||
|
||||
if (rand(0, 1)) {
|
||||
$credit->tax_name3 = 'CA Sales Tax';
|
||||
$credit->tax_rate3 = 5;
|
||||
}
|
||||
|
||||
$credit->save();
|
||||
|
||||
$invoice_calc = new InvoiceSum($credit);
|
||||
@ -428,6 +414,32 @@ class CreateSingleAccount extends Command
|
||||
$quote->service()->createInvitations();
|
||||
}
|
||||
|
||||
|
||||
private function buildCreditItem()
|
||||
{
|
||||
$line_items = [];
|
||||
|
||||
$item = InvoiceItemFactory::create();
|
||||
$item->quantity = 1;
|
||||
$item->cost = 1000;
|
||||
|
||||
$product = Product::all()->random();
|
||||
|
||||
$item->cost = (float) $product->cost;
|
||||
$item->product_key = $product->product_key;
|
||||
$item->notes = $product->notes;
|
||||
$item->custom_value1 = $product->custom_value1;
|
||||
$item->custom_value2 = $product->custom_value2;
|
||||
$item->custom_value3 = $product->custom_value3;
|
||||
$item->custom_value4 = $product->custom_value4;
|
||||
|
||||
$line_items[] = $item;
|
||||
|
||||
|
||||
return $line_items;
|
||||
}
|
||||
|
||||
|
||||
private function buildLineItems($count = 1)
|
||||
{
|
||||
$line_items = [];
|
||||
|
@ -17,6 +17,7 @@ use App\Factory\InvoiceFactory;
|
||||
use App\Factory\InvoiceItemFactory;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||
use App\Jobs\Ninja\CompanySizeCheck;
|
||||
use App\Jobs\Util\VersionCheck;
|
||||
use App\Models\Account;
|
||||
@ -175,6 +176,7 @@ class DemoMode extends Command
|
||||
}
|
||||
|
||||
CreateCompanyPaymentTerms::dispatchNow($company, $user);
|
||||
CreateCompanyTaskStatuses::dispatchNow($company, $user);
|
||||
|
||||
$company_token = new CompanyToken;
|
||||
$company_token->user_id = $user->id;
|
||||
|
@ -18,7 +18,7 @@ use App\Factory\CompanyUserFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\InvoiceInvitationFactory;
|
||||
use App\Helpers\Email\InvoiceEmail;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Invoice\CreateEntityPdf;
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\Account;
|
||||
use App\Models\Client;
|
||||
@ -149,7 +149,7 @@ class SendTestEmails extends Command
|
||||
$invoice->setRelation('invitations', $ii);
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
CreateInvoicePdf::dispatch($invoice->invitations()->first());
|
||||
CreateEntityPdf::dispatch($invoice->invitations()->first());
|
||||
|
||||
$cc_emails = [config('ninja.testvars.test_email')];
|
||||
$bcc_emails = [config('ninja.testvars.test_email')];
|
||||
|
@ -105,6 +105,9 @@ class CompanySettings extends BaseSettings
|
||||
public $payment_number_pattern = '';
|
||||
public $payment_number_counter = 1;
|
||||
|
||||
public $project_number_pattern = '';
|
||||
public $project_number_counter = 1;
|
||||
|
||||
public $shared_invoice_quote_counter = false;
|
||||
public $recurring_number_prefix = 'R';
|
||||
public $reset_counter_frequency_id = '0';
|
||||
@ -186,6 +189,7 @@ class CompanySettings extends BaseSettings
|
||||
public $enable_reminder1 = false;
|
||||
public $enable_reminder2 = false;
|
||||
public $enable_reminder3 = false;
|
||||
public $enable_reminder_endless = false;
|
||||
|
||||
public $num_days_reminder1 = 0;
|
||||
public $num_days_reminder2 = 0;
|
||||
@ -250,7 +254,11 @@ class CompanySettings extends BaseSettings
|
||||
public $client_portal_under_payment_minimum = 0;
|
||||
public $client_portal_allow_over_payment = false;
|
||||
|
||||
public $use_credits_payment = 'off'; //always, option, off
|
||||
|
||||
public static $casts = [
|
||||
'enable_reminder_endless' => 'bool',
|
||||
'use_credits_payment' => 'string',
|
||||
'recurring_invoice_number_pattern' => 'string',
|
||||
'recurring_invoice_number_counter' => 'int',
|
||||
'client_portal_under_payment_minimum'=> 'float',
|
||||
@ -313,6 +321,8 @@ class CompanySettings extends BaseSettings
|
||||
'embed_documents' => 'bool',
|
||||
'all_pages_header' => 'bool',
|
||||
'all_pages_footer' => 'bool',
|
||||
'project_number_pattern' => 'string',
|
||||
'project_number_counter' => 'int',
|
||||
'task_number_pattern' => 'string',
|
||||
'task_number_counter' => 'int',
|
||||
'expense_number_pattern' => 'string',
|
||||
|
@ -124,11 +124,6 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailInvoiceTemplate()
|
||||
{
|
||||
$converter = new CommonMarkConverter([
|
||||
'html_input' => 'strip',
|
||||
'allow_unsafe_links' => false,
|
||||
]);
|
||||
|
||||
$invoice_message = '<p>'.self::transformText('invoice_message').'</p><br><br><p>$view_link</p>';
|
||||
|
||||
return $invoice_message;
|
||||
@ -141,12 +136,9 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailQuoteTemplate()
|
||||
{
|
||||
$converter = new CommonMarkConverter([
|
||||
'html_input' => 'strip',
|
||||
'allow_unsafe_links' => false,
|
||||
]);
|
||||
$quote_message = '<p>'.self::transformText('quote_message').'</p><br><br><p>$view_link</p>';
|
||||
|
||||
return $converter->convertToHtml(self::transformText('quote_message'));
|
||||
return $quote_message;
|
||||
}
|
||||
|
||||
public static function emailPaymentSubject()
|
||||
@ -167,13 +159,9 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailCreditTemplate()
|
||||
{
|
||||
$converter = new CommonMarkConverter([
|
||||
'html_input' => 'strip',
|
||||
'allow_unsafe_links' => false,
|
||||
]);
|
||||
|
||||
return $converter->convertToHtml(self::transformText('credit_message'));
|
||||
$credit_message = '<p>'.self::transformText('credit_message').'</p><br><br><p>$view_link</p>';
|
||||
|
||||
return $credit_message;
|
||||
}
|
||||
|
||||
public static function emailPaymentPartialTemplate()
|
||||
@ -198,50 +186,47 @@ class EmailTemplateDefaults
|
||||
|
||||
public static function emailReminder1Template()
|
||||
{
|
||||
// return Parsedown::instance()->line('First Email Reminder Text');
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function emailReminder2Subject()
|
||||
{
|
||||
return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']);
|
||||
// return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
}
|
||||
|
||||
public static function emailReminder2Template()
|
||||
{
|
||||
// return Parsedown::instance()->line('Second Email Reminder Text');
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function emailReminder3Subject()
|
||||
{
|
||||
return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']);
|
||||
// return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
}
|
||||
|
||||
public static function emailReminder3Template()
|
||||
{
|
||||
// return Parsedown::instance()->line('Third Email Reminder Text');
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function emailReminderEndlessSubject()
|
||||
{
|
||||
return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']);
|
||||
// return Parsedown::instance()->line(self::transformText('reminder_subject'));
|
||||
}
|
||||
|
||||
public static function emailReminderEndlessTemplate()
|
||||
{
|
||||
return ctrans('Endless Email Reminder Text');
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function emailStatementSubject()
|
||||
{
|
||||
return ctrans('Statement Subject needs texts record!');
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function emailStatementTemplate()
|
||||
{
|
||||
return ctrans('Statement Templates needs texts record!');
|
||||
return '';
|
||||
}
|
||||
|
||||
private static function transformText($string)
|
||||
|
@ -13,13 +13,18 @@ namespace App\DataMapper;
|
||||
|
||||
class PaymentMethodMeta
|
||||
{
|
||||
/** @var string */
|
||||
public $exp_month;
|
||||
|
||||
/** @var string */
|
||||
public $exp_year;
|
||||
|
||||
/** @var string */
|
||||
public $brand;
|
||||
|
||||
/** @var string */
|
||||
public $last4;
|
||||
|
||||
/** @var int */
|
||||
public $type;
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
abstract class AbstractDesign
|
||||
{
|
||||
abstract public function includes();
|
||||
|
||||
abstract public function header();
|
||||
|
||||
abstract public function body();
|
||||
|
||||
abstract public function product();
|
||||
|
||||
abstract public function task();
|
||||
|
||||
abstract public function footer();
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Bold extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page: not(:first-of-type) { size: auto; margin-top: 5mm; }
|
||||
.table_header_thead_class {text-align:left;}
|
||||
.table_header_td_class {padding-left:3rem; padding-right:3rem; font-size:1rem; padding-left:1rem;padding-right:1rem; padding-top:.5rem;padding-bottom:.5rem}
|
||||
.table_body_td_class {background-color:#edf2f7; adding-top:1.25rem;padding-bottom:1.25rem; padding-left:3rem;}
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="bg-gray-800 p-12">
|
||||
<div class="grid grid-cols-6 gap-1">
|
||||
<div class="col-span-2 p-3">
|
||||
<div class="p-1 rounded-lg">
|
||||
$company_logo
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-2 p-3 text-white flex flex-col flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="col-span-2 p-3 text-white flex flex-col flex-wrap">
|
||||
$company_address
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="bg-white mt-16 pl-10">
|
||||
<div class="grid grid-cols-12 gap-2">
|
||||
<div class="col-span-7">
|
||||
<h2 class="text-2xl uppercase font-semibold text-teal-600 tracking-tight">$entity_label</h2>
|
||||
<div class="flex flex-col flex-wrap">$client_details</div>
|
||||
</div>
|
||||
<div class="col-span-5">
|
||||
<div class="bg-teal-600 px-5 py-3 text-white">
|
||||
<div class="w-80 flex flex-col text-white flex-wrap">
|
||||
$entity_details
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mx-10 mt-8">
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex px-4 mt-6 w-full px-12">
|
||||
<div class="w-1/2">
|
||||
$entity.public_notes
|
||||
</div>
|
||||
<div class="w-1/2 flex">
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
$subtotal_label $discount_label $total_tax_labels $line_tax_labels
|
||||
</div>
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
$subtotal $discount $total_tax_values $line_tax_values
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex px-4 mt-4 w-full items-end px-12">
|
||||
<div class="w-1/2 flex flex-col flex-wrap">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
$terms
|
||||
</div>
|
||||
<div class="w-1/2 flex">
|
||||
<div class="w-1/2 text-right flex flex-col flex-wrap">
|
||||
<span class="text-xl font-semibold">$balance_due_label</span>
|
||||
</div>
|
||||
<div class="w-1/2 text-right flex flex-col flex-wrap">
|
||||
<span class="text-xl text-teal-600 font-semibold">$balance_due</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Business extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
body { font-size:90% }
|
||||
@page
|
||||
{
|
||||
size: auto;
|
||||
margin-top: 5mm;
|
||||
}
|
||||
thead th:first-child {
|
||||
border-top-left-radius: 0.5rem;
|
||||
}
|
||||
thead th:last-child {
|
||||
border-top-right-radius: 0.5rem;
|
||||
}
|
||||
.table_header_thead_class { border-top-left-radius: .5rem; text-align: left }
|
||||
.table_header_td_class { color: white; padding: .5rem 1rem; font-weight: 800; background-color: #2a4365; }
|
||||
.table_body_td_class { color: #c05621; padding: 1rem; border-width: 4px; border-color: white; background-color: white; }
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="m-10">
|
||||
<div class="grid grid-cols-6 gap-1">
|
||||
<div class="col-span-2 p-3">
|
||||
$company_logo
|
||||
</div>
|
||||
<div class="flex flex-col flex-wrap col-span-2 p-3">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="flex flex-col flex-wrap col-span-2 p-3">
|
||||
$company_address
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="grid grid-cols-12 gap-1 mt-8">
|
||||
<div class="flex flex-col flex-wrap col-span-7 p-3">
|
||||
$client_details
|
||||
</div>
|
||||
<div class="flex flex-col h-auto col-span-5 p-3 px-4 py-4 bg-orange-600 rounded-lg">
|
||||
<div class="flex flex-col flex-wrap text-white">
|
||||
$entity_details
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="w-full mt-20 table-auto">
|
||||
<thead class="text-left">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line bg-gray-200">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full mt-20 table-auto">
|
||||
<thead class="text-left">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line bg-gray-200">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex items-center justify-between px-4 py-2 pb-4 bg-gray-200 rounded">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p>$entity.public_notes</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-1/3">
|
||||
<div class="flex px-3 mt-2">
|
||||
<section class="flex flex-col w-1/2 text-right">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</section>
|
||||
<section class="flex flex-col w-1/2 text-right">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between px-4 pb-4 mt-4">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
<p>$terms</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-2/5">
|
||||
<section class="flex px-4 py-2 py-3 text-white bg-blue-900 rounded">
|
||||
<p class="w-1/2">$balance_due_label</p>
|
||||
<p class="w-1/2 text-right">$balance_due</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="flex justify-between px-12 py-8 div_footer" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Clean extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page
|
||||
{
|
||||
size: auto;
|
||||
margin-top: 5mm;
|
||||
}
|
||||
.table_header_thead_class { text-align: left; }
|
||||
.table_header_td_class { padding: .5rem 1rem;}
|
||||
.table_body_td_class { border-bottom-width: 1px; border-top-width: 1px; border-color: #cbd5e0; padding: 1rem;}
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="px-12 my-10">
|
||||
<div class="flex items-center">
|
||||
<div class="w-1/3">
|
||||
<div class="h-14 w-14">$company_logo</div>
|
||||
</div>
|
||||
<div class="w-auto flex">
|
||||
<div class="mr-10 text-gray-600 flex flex-col flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="ml-5 text-gray-600 flex flex-col flex-wrap">
|
||||
$company_address
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<h1 class="mt-12 uppercase text-2xl text-blue-500 ml-4">
|
||||
$entity_label
|
||||
</h1>
|
||||
|
||||
<div class="border-b border-gray-400"></div>
|
||||
|
||||
<div class="ml-4 py-4">
|
||||
<div class="flex">
|
||||
<div class="w-40 flex flex-col flex-wrap">
|
||||
$entity_labels
|
||||
</div>
|
||||
<div class="w-48 flex flex-col flex-wrap">
|
||||
$entity_details
|
||||
</div>
|
||||
<div class="w-56 flex flex-col flex-wrap">
|
||||
$client_details
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-b border-gray-400"></div>
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex px-4 mt-6 w-full">
|
||||
<div class="w-1/2">
|
||||
$entity.public_notes
|
||||
</div>
|
||||
<div class="w-1/2 flex">
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</div>
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex px-4 mt-4 w-full items-end">
|
||||
<div class="w-1/2">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
$terms
|
||||
</div>
|
||||
<div class="w-1/2 flex">
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
<span>$balance_due_label</span>
|
||||
</div>
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
<span class="text-blue-600">$balance_due</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
/**
|
||||
* @wip: Table margins act weird.
|
||||
*/
|
||||
class Creative extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page
|
||||
{
|
||||
size: auto;
|
||||
margin-top: 6mm;
|
||||
}
|
||||
.table_header_thead_class { text-align: left; border-radius: .5rem; }
|
||||
.table_header_td_class { text-transform: uppercase; font-size: 1.25rem; color: #b83280; font-weight: 500 }
|
||||
.table_body_td_class { padding: 1rem;}
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="m-12">
|
||||
<div class="grid grid-cols-12 gap-4">
|
||||
<div class="col-span-3 flex flex-col flex-wrap break-all">$client_details</div>
|
||||
<div class="col-span-3 flex flex-col flex-wrap break-all">$company_details</div>
|
||||
<div class="col-span-3 flex flex-col flex-wrap break-all">$company_address</div>
|
||||
<div class="col-span-3 flex flex-wrap">$company_logo</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="grid grid-cols-12 mt-8">
|
||||
<div class="col-span-7">
|
||||
<p class="text-4xl text-pink-700">#$entity_number</p>
|
||||
</div>
|
||||
<div class="col-span-5 flex flex-col flex-wrap">$entity_details</div>
|
||||
</div>
|
||||
|
||||
<table class="w-full table-auto border-t-4 border-pink-700 bg-white mt-8">
|
||||
<thead class="text-left rounded-lg">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto border-t-4 border-pink-700 bg-white">
|
||||
<thead class="text-left rounded-lg">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="border-b-4 border-pink-700 mt-8">
|
||||
<div class="grid grid-cols-12 mt-2 px-4 pb-4">
|
||||
<div class="col-span-7 flex flex-col">
|
||||
<p>$entity.public_notes</p>
|
||||
</div>
|
||||
<div class="col-span-5 flex px-3 mt-2">
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
$subtotal_label $discount_label $total_tax_labels $line_tax_labels
|
||||
</div>
|
||||
<div class="w-1/2 text-right flex flex-col">
|
||||
$subtotal $discount $total_tax_values $line_tax_values
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-4 pb-4 px-4">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
<p>N21</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full flex justify-end mt-4">
|
||||
<p>$balance_due_label</p>
|
||||
<p class="ml-8 text-pink-700 font-semibold">$balance</p>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Custom
|
||||
{
|
||||
public $includes;
|
||||
|
||||
public $header;
|
||||
|
||||
public $body;
|
||||
|
||||
public $product;
|
||||
|
||||
public $task;
|
||||
|
||||
public $footer;
|
||||
|
||||
public $name;
|
||||
|
||||
public function __construct($design)
|
||||
{
|
||||
$this->name = $design->name;
|
||||
|
||||
$this->includes = $design->design->includes;
|
||||
|
||||
$this->header = $design->design->header;
|
||||
|
||||
$this->body = $design->design->body;
|
||||
|
||||
$this->product = $design->design->product;
|
||||
|
||||
$this->task = $design->design->task;
|
||||
|
||||
$this->footer = $design->design->footer;
|
||||
}
|
||||
}
|
@ -1,396 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
|
||||
class Designer
|
||||
{
|
||||
public $design;
|
||||
|
||||
protected $input_variables;
|
||||
|
||||
protected $exported_variables;
|
||||
|
||||
protected $html;
|
||||
|
||||
protected $entity_string;
|
||||
|
||||
protected $entity;
|
||||
|
||||
private static $custom_fields = [
|
||||
'invoice1',
|
||||
'invoice2',
|
||||
'invoice3',
|
||||
'invoice4',
|
||||
'surcharge1',
|
||||
'surcharge2',
|
||||
'surcharge3',
|
||||
'surcharge4',
|
||||
'client1',
|
||||
'client2',
|
||||
'client3',
|
||||
'client4',
|
||||
'contact1',
|
||||
'contact2',
|
||||
'contact3',
|
||||
'contact4',
|
||||
'company1',
|
||||
'company2',
|
||||
'company3',
|
||||
'company4',
|
||||
];
|
||||
|
||||
public function __construct($entity, $design, $input_variables, $entity_string)
|
||||
{
|
||||
$this->entity = $entity;
|
||||
|
||||
$this->design = $design->design;
|
||||
|
||||
$this->input_variables = json_decode(json_encode($input_variables), 1);
|
||||
|
||||
$this->entity_string = $entity_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the design
|
||||
* formatted HTML.
|
||||
* @return string The HTML design built
|
||||
*/
|
||||
public function build():self
|
||||
{
|
||||
$this->setHtml()
|
||||
->exportVariables()
|
||||
->setDesign($this->getSection('includes'))
|
||||
->setDesign($this->getSection('header'))
|
||||
->setDesign($this->getSection('body'))
|
||||
->setDesign($this->getSection('footer'));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->setHtml()
|
||||
->exportVariables();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIncludes()
|
||||
{
|
||||
return $this->getSection('includes');
|
||||
}
|
||||
|
||||
public function getHeader()
|
||||
{
|
||||
return $this->getSection('header');
|
||||
}
|
||||
|
||||
public function getFooter()
|
||||
{
|
||||
$div = '
|
||||
%s <!-- Placeholder for getSection(footer) -->
|
||||
<div class="flex items-center justify-between m-12">
|
||||
%s <!-- Placeholder for signature -->
|
||||
%s <!-- Placehoder for Invoice Ninja logo -->
|
||||
</div>';
|
||||
|
||||
$signature = '<img class="h-40" src="$contact.signature" />';
|
||||
$logo = '<div></div>';
|
||||
|
||||
if (! $this->entity->user->account->isPaid()) {
|
||||
$logo = '<img class="h-32" src="$app_url/images/created-by-invoiceninja-new.png" />';
|
||||
}
|
||||
|
||||
return sprintf($div, $this->getSection('footer'), $signature, $logo);
|
||||
}
|
||||
|
||||
public function getBody()
|
||||
{
|
||||
return $this->getSection('body');
|
||||
}
|
||||
|
||||
public function getHtml():string
|
||||
{
|
||||
return $this->html;
|
||||
}
|
||||
|
||||
public function setHtml()
|
||||
{
|
||||
$this->html = '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function setDesign($section)
|
||||
{
|
||||
$this->html .= $section;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the template section on with the
|
||||
* stacked variables replaced with single variables.
|
||||
*
|
||||
* @param string $section the method name to be executed ie header/body/table/footer
|
||||
* @return string The HTML of the template section
|
||||
*/
|
||||
public function getSection($section):string
|
||||
{
|
||||
return strtr($this->design->{$section}, $this->exported_variables);
|
||||
// return str_replace(array_keys($this->exported_variables), array_values($this->exported_variables), $this->design->{$section});
|
||||
}
|
||||
|
||||
private function exportVariables()
|
||||
{
|
||||
//$s = microtime(true);
|
||||
$company = $this->entity->company;
|
||||
|
||||
$this->exported_variables['$custom_css'] = $this->entity->generateCustomCSS();
|
||||
$this->exported_variables['$app_url'] = $this->entity->generateAppUrl();
|
||||
$this->exported_variables['$client_details'] = $this->processVariables($this->input_variables['client_details'], $this->clientDetails($company));
|
||||
$this->exported_variables['$company_details'] = $this->processVariables($this->input_variables['company_details'], $this->companyDetails($company));
|
||||
$this->exported_variables['$company_address'] = $this->processVariables($this->input_variables['company_address'], $this->companyAddress($company));
|
||||
|
||||
if ($this->entity_string == 'invoice') {
|
||||
//$this->exported_variables['$entity_labels'] = $this->processLabels($this->input_variables['invoice_details'], $this->invoiceDetails($company));
|
||||
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['invoice_details'], $this->invoiceDetails($company));
|
||||
} elseif ($this->entity_string == 'credit') {
|
||||
//$this->exported_variables['$entity_labels'] = $this->processLabels($this->input_variables['credit_details'], $this->creditDetails($company));
|
||||
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['credit_details'], $this->creditDetails($company));
|
||||
} elseif ($this->entity_string == 'quote') {
|
||||
//$this->exported_variables['$entity_labels'] = $this->processLabels($this->input_variables['quote_details'], $this->quoteDetails($company));
|
||||
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['quote_details'], $this->quoteDetails($company));
|
||||
} else {
|
||||
$this->exported_variables['$entity_details'] = $this->processVariables($this->input_variables['invoice_details'], $this->quoteDetails($company));
|
||||
}
|
||||
|
||||
$this->exported_variables['$product_table_header'] = $this->entity->buildTableHeader($this->input_variables['product_columns']);
|
||||
$this->exported_variables['$product_table_body'] = $this->entity->buildTableBody($this->input_variables['product_columns'], $this->design->product, '$product');
|
||||
$this->exported_variables['$task_table_header'] = $this->entity->buildTableHeader($this->input_variables['task_columns']);
|
||||
$this->exported_variables['$task_table_body'] = $this->entity->buildTableBody($this->input_variables['task_columns'], $this->design->task, '$task');
|
||||
|
||||
if (strlen($this->exported_variables['$task_table_body']) == 0) {
|
||||
$this->exported_variables['$task_table_header'] = '';
|
||||
}
|
||||
|
||||
if (strlen($this->exported_variables['$product_table_body']) == 0) {
|
||||
$this->exported_variables['$product_table_header'] = '';
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function processVariables($input_variables, $variables):string
|
||||
{
|
||||
$output = '';
|
||||
|
||||
foreach (array_values($input_variables) as $value) {
|
||||
if (array_key_exists($value, $variables)) {
|
||||
$output .= $variables[$value];
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function processLabels($input_variables, $variables):string
|
||||
{
|
||||
$output = '';
|
||||
|
||||
foreach (array_keys($input_variables) as $value) {
|
||||
if (array_key_exists($value, $variables)) {
|
||||
//$tmp = str_replace("</span>", "_label</span>", $variables[$value]);
|
||||
$tmp = strtr($variables[$value], '</span>', '_label</span>');
|
||||
$output .= $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function clientDetails(Company $company)
|
||||
{
|
||||
$data = [
|
||||
'$client.name' => '<p>$client.name</p>',
|
||||
'$client.id_number' => '<p>$client.id_number</p>',
|
||||
'$client.vat_number' => '<p>$client.vat_number</p>',
|
||||
'$client.address1' => '<p>$client.address1</p>',
|
||||
'$client.address2' => '<p>$client.address2</p>',
|
||||
'$client.city_state_postal' => '<p>$client.city_state_postal</p>',
|
||||
'$client.postal_city_state' => '<p>$client.postal_city_state</p>',
|
||||
'$client.country' => '<p>$client.country</p>',
|
||||
'$contact.email' => '<p>$client.email</p>',
|
||||
'$client.custom1' => '<p>$client.custom1</p>',
|
||||
'$client.custom2' => '<p>$client.custom2</p>',
|
||||
'$client.custom3' => '<p>$client.custom3</p>',
|
||||
'$client.custom4' => '<p>$client.custom4</p>',
|
||||
'$contact.contact1' => '<p>$contact.custom1</p>',
|
||||
'$contact.contact2' => '<p>$contact.custom2</p>',
|
||||
'$contact.contact3' => '<p>$contact.custom3</p>',
|
||||
'$contact.contact4' => '<p>$contact.custom4</p>',
|
||||
];
|
||||
|
||||
return $this->processCustomFields($company, $data);
|
||||
}
|
||||
|
||||
private function companyDetails(Company $company)
|
||||
{
|
||||
$data = [
|
||||
'$company.name' => '<span>$company.name</span>',
|
||||
'$company.id_number' => '<span>$company.id_number</span>',
|
||||
'$company.vat_number' => '<span>$company.vat_number</span>',
|
||||
'$company.website' => '<span>$company.website</span>',
|
||||
'$company.email' => '<span>$company.email</span>',
|
||||
'$company.phone' => '<span>$company.phone</span>',
|
||||
'$company.company1' => '<span>$company1</span>',
|
||||
'$company.company2' => '<span>$company2</span>',
|
||||
'$company.company3' => '<span>$company3</span>',
|
||||
'$company.company4' => '<span>$company4</span>',
|
||||
];
|
||||
|
||||
return $this->processCustomFields($company, $data);
|
||||
}
|
||||
|
||||
private function companyAddress(Company $company)
|
||||
{
|
||||
$data = [
|
||||
'$company.address1' => '<span>$company.address1</span>',
|
||||
'$company.address2' => '<span>$company.address2</span>',
|
||||
'$company.city_state_postal' => '<span>$company.city_state_postal</span>',
|
||||
'$company.postal_city_state' => '<span>$company.postal_city_state</span>',
|
||||
'$company.country' => '<span>$company.country</span>',
|
||||
'$company.company1' => '<span>$company1</span>',
|
||||
'$company.company2' => '<span>$company2</span>',
|
||||
'$company.company3' => '<span>$company3</span>',
|
||||
'$company.company4' => '<span>$company4</span>',
|
||||
];
|
||||
|
||||
return $this->processCustomFields($company, $data);
|
||||
}
|
||||
|
||||
private function invoiceDetails(Company $company)
|
||||
{
|
||||
$data = [
|
||||
'$invoice.number' => '<span class="flex justify-between items-center"><span>$invoice.number_label:</span><span> $invoice.number</span></span>',
|
||||
'$invoice.po_number' => '<span class="flex justify-between items-center"><span>$invoice.po_number_label:</span><span> $invoice.po_number</span></span>',
|
||||
'$invoice.date' => '<span class="flex justify-between items-center"><span>$invoice.date_label:</span><span> $invoice.date</span></span>',
|
||||
'$invoice.due_date' => '<span class="flex justify-between items-center"><span>$invoice.due_date_label:</span><span> $invoice.due_date</span></span>',
|
||||
'$invoice.balance_due' => '<span class="flex justify-between items-center"><span>$invoice.balance_due_label:</span><span> $invoice.balance_due</span></span>',
|
||||
'$invoice.total' => '<span class="flex justify-between items-center"><span>$invoice.total_label:</span><span> $invoice.total</span></span>',
|
||||
'$invoice.partial_due' => '<span class="flex justify-between items-center"><span>$invoice.partial_due_label:</span><span> $invoice.partial_due</span></span>',
|
||||
'$invoice.custom1' => '<span class="flex justify-between items-center"><span>$invoice1_label:</span><span> $invoice.custom1</span></span>',
|
||||
'$invoice.custom2' => '<span class="flex justify-between items-center"><span>$invoice2_label:</span><span> $invoice.custom2</span></span>',
|
||||
'$invoice.custom3' => '<span class="flex justify-between items-center"><span>$invoice3_label:</span><span> $invoice.custom3</span></span>',
|
||||
'$invoice.custom4' => '<span class="flex justify-between items-center"><span>$invoice4_label:</span><span> $invoice.custom4</span></span>',
|
||||
'$surcharge1' => '<span class="flex justify-between items-center"><span>$surcharge1_label:</span><span> $surcharge1</span></span>',
|
||||
'$surcharge2' => '<span class="flex justify-between items-center"><span>$surcharge2_label:</span><span> $surcharge2</span></span>',
|
||||
'$surcharge3' => '<span class="flex justify-between items-center"><span>$surcharge3_label:</span><span> $surcharge3</span></span>',
|
||||
'$surcharge4' => '<span class="flex justify-between items-center"><span>$surcharge4_label:</span><span> $surcharge4</span></span>',
|
||||
|
||||
];
|
||||
|
||||
return $this->processCustomFields($company, $data);
|
||||
}
|
||||
|
||||
private function quoteDetails(Company $company)
|
||||
{
|
||||
$data = [
|
||||
'$quote.quote_number' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.number_label:</span><span> $quote.number</span></span>',
|
||||
'$quote.po_number' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.po_number_label:</span><span> $quote.po_number</span></span>',
|
||||
'$quote.quote_date' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.date_label:</span><span> $quote.date</span></span>',
|
||||
'$quote.valid_until' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.valid_until_label:</span><span> $quote.valid_until</span></span>',
|
||||
'$quote.balance_due' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.balance_due_label:</span><span> $quote.balance_due</span></span>',
|
||||
'$quote.quote_total' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.total_label:</span><span> $quote.total</span></span>',
|
||||
'$quote.partial_due' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.partial_due_label:</span><span> $quote.partial_due</span></span>',
|
||||
'$quote.custom1' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom1_label:</span><span> $quote.custom1</span></span>',
|
||||
'$quote.custom2' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom2_label:</span><span> $quote.custom2</span></span>',
|
||||
'$quote.custom3' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom3_label:</span><span> $quote.custom3</span></span>',
|
||||
'$quote.custom4' => '<span class="flex flex-wrap justify-between items-center"><span>$quote.custom4_label:</span><span> $quote.custom4</span></span>',
|
||||
'$quote.surcharge1' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge1_label:</span><span> $surcharge1</span></span>',
|
||||
'$quote.surcharge2' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge2_label:</span><span> $surcharge2</span></span>',
|
||||
'$quote.surcharge3' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge3_label:</span><span> $surcharge3</span></span>',
|
||||
'$quote.surcharge4' => '<span class="flex flex-wrap justify-between items-center"><span>$surcharge4_label:</span><span> $surcharge4</span></span>',
|
||||
|
||||
];
|
||||
|
||||
return $this->processCustomFields($company, $data);
|
||||
}
|
||||
|
||||
private function creditDetails(Company $company)
|
||||
{
|
||||
$data = [
|
||||
'$credit.number' => '<span class="flex justify-between items-center">$credit.number_label<span></span><span>$credit.number</span></span>',
|
||||
'$credit.po_number' => '<span class="flex justify-between items-center">$credit.po_number_label<span></span><span>$credit.po_number</span></span>',
|
||||
'$credit.date' => '<span class="flex justify-between items-center">$credit.date_label<span></span><span>$credit.date</span></span>',
|
||||
'$credit.balance' => '<span class="flex justify-between items-center">$credit.balance_label<span></span><span>$credit.balance</span></span>',
|
||||
'$credit.total' => '<span class="flex justify-between items-center">$credit.total_label<span></span><span>$credit.total</span></span>',
|
||||
'$credit.partial_due' => '<span class="flex justify-between items-center">$credit.partial_due_label<span></span><span>$credit.partial_due</span></span>',
|
||||
'$credit.custom1' => '<span class="flex justify-between items-center">$credit.custom1_label<span></span><span>$credit.custom1</span></span>',
|
||||
'$credit.custom2' => '<span class="flex justify-between items-center">$credit.custom2_label<span></span><span>$credit.custom2</span></span>',
|
||||
'$credit.custom3' => '<span class="flex justify-between items-center">$credit.custom3_label<span></span><span>$credit.custom3</span></span>',
|
||||
'$credit.custom4' => '<span class="flex justify-between items-center">$credit.custom4_label<span></span><span>$credit.custom4</span></span>',
|
||||
'$credit.surcharge1' => '<span class="flex justify-between items-center">$surcharge1_label<span></span><span>$surcharge1_label: $surcharge1</span></span>',
|
||||
'$credit.surcharge2' => '<span class="flex justify-between items-center">$surcharge2_label<span></span><span>$surcharge2_label: $surcharge2</span></span>',
|
||||
'$credit.surcharge3' => '<span class="flex justify-between items-center">$surcharge3_label<span></span><span>$surcharge3_label: $surcharge3</span></span>',
|
||||
'$credit.surcharge4' => '<span class="flex justify-between items-center">$surcharge4_label<span></span><span>$surcharge4_label: $surcharge4</span></span>',
|
||||
|
||||
];
|
||||
|
||||
return $this->processCustomFields($company, $data);
|
||||
}
|
||||
|
||||
private function processCustomFields(Company $company, $data)
|
||||
{
|
||||
$custom_fields = $company->custom_fields;
|
||||
|
||||
if (! $custom_fields) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach (self::$custom_fields as $cf) {
|
||||
if (! property_exists($custom_fields, $cf) || (strlen($custom_fields->{$cf}) == 0)) {
|
||||
unset($data[$cf]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
// private function processInputVariables($company, $variables)
|
||||
// {
|
||||
// if(is_object($variables))
|
||||
// $variables = json_decode(json_encode($variables),true);
|
||||
|
||||
// $custom_fields = $company->custom_fields;
|
||||
|
||||
// $matches = array_intersect(self::$custom_fields, $variables);
|
||||
|
||||
// foreach ($matches as $match) {
|
||||
|
||||
// if (!property_exists($custom_fields, $match) || (strlen($custom_fields->{$match}) == 0)) {
|
||||
// foreach ($variables as $key => $value) {
|
||||
// if ($value == $match) {
|
||||
// unset($variables[$key]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// return $variables;
|
||||
|
||||
// }
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Elegant extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page
|
||||
{
|
||||
size: auto;
|
||||
margin-top: 5mm;
|
||||
}
|
||||
.table_header_thead_class { text-align: left; border-bottom-width: 1px; border-style: dashed; border-color: black; }
|
||||
.table_header_td_class { font-weight: normal; color: #2f855a; padding: .5rem 1rem; }
|
||||
.table_body_td_class { padding: 1rem; }
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="m-10">
|
||||
<div class="grid grid-cols-12 border-b-4 border-black pb-6">
|
||||
<div class="col-span-8">
|
||||
$company_logo
|
||||
</div>
|
||||
<div class="col-span-4 flex flex-col flex-wrap">
|
||||
$entity_details
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-px border-b border-black mt-1"></div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="grid grid-cols-12 gap-4 mt-8">
|
||||
<div class="col-span-4 mr-6 flex flex-col pr-2 border-r border-dashed border-black flex-wrap">
|
||||
$client_details
|
||||
</div>
|
||||
<div class="col-span-4 flex flex-col mr-6 flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="col-span-4 flex flex-col flex-wrap">
|
||||
$company_address
|
||||
</div>
|
||||
</div>
|
||||
<table class="w-full table-auto mb-6 mt-16">
|
||||
<thead class="text-left border-dashed border-b border-black">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto mb-6 mt-16">
|
||||
<thead class="text-left border-dashed border-b border-black">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex items-center justify-between mt-2 px-4 pb-4">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p>$entity.public_notes</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/3 flex flex-col">
|
||||
<div class="flex px-3 mt-2">
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</section>
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-4 pb-4 px-4">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
<p>$terms</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-2/5 flex-col">
|
||||
<section class="flex py-2 text-green-700 border-t border-b border-dashed border-black px-2 mt-1">
|
||||
<p class="w-1/2">$balance_due_label</p>
|
||||
<p class="text-right w-1/2">$balance</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center border-b-4 border-black mt-6">
|
||||
<h4 class="text-2xl font-semibold mb-4">Thanks</h4>
|
||||
</div>
|
||||
<div class="p-px border-b border-black mt-1"></div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Hipster extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page
|
||||
{
|
||||
size: auto;
|
||||
margin-top: 5mm;
|
||||
}
|
||||
|
||||
.table_header_thead_class { text-align: left }
|
||||
.table_header_td_class { text-transform: uppercase; padding: .5rem 1rem; font-weight: 600; border-color: black; }
|
||||
.table_body_td_class { border-left-width: 2px; border-color: black; padding: 1rem; }
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="px-12 py-16">
|
||||
<div class="flex">
|
||||
<div class="w-1/2 border-l pl-4 border-black mr-4">
|
||||
<p class="font-semibold uppercase text-yellow-600">From:</p>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col mr-5 flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="flex flex-col flex-wrap">
|
||||
$company_address
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/3 border-l pl-4 border-black flex flex-col flex-wrap">
|
||||
<p class="font-semibold uppercase text-yellow-600">To:</p>
|
||||
$client_details
|
||||
</div>
|
||||
<div class="w-1/3 mt-5 h-16">
|
||||
$company_logo
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="flex flex-col mx-6 mt-10">
|
||||
<h1 class="font-semibold uppercase text-6xl">$entity_label</h1>
|
||||
<div class="flex mt-1">
|
||||
<span class="font-semibold uppercase text-yellow-600">$entity_number</span>
|
||||
<div class="ml-4">
|
||||
<span class="uppercase">$date_label</span>
|
||||
<span>$date</span>
|
||||
</div>
|
||||
<div class="ml-10">
|
||||
<span class="uppercase">$due_date_label</span>
|
||||
<span>$due_date</span>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<span class="uppercase">$balance_due_label</span>
|
||||
<span class="text-yellow-600">$balance_due</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="w-full table-auto mt-24">
|
||||
<thead class="text-left">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto mt-24">
|
||||
<thead class="text-left">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex justify-between mt-8">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p>$entity.public_notes</p>
|
||||
<div class="pt-4">
|
||||
<p class="font-bold">$terms_label</p>
|
||||
<p>$terms</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/3 flex flex-col">
|
||||
<div class="flex px-3 mt-6">
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</section>
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</section>
|
||||
</div>
|
||||
<section class="flex bg-black text-white px-3 mt-1">
|
||||
<p class="w-1/2 text-right">$balance_due_label</p>
|
||||
<p class="text-right w-1/2">$balance_due</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Modern extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
.table_header_thead_class {text-align:left; text-align:left; color:#fff; background-color:#1a202c;}
|
||||
.table_header_td_class {padding-left:1rem;padding-right:1rem; padding-top:.5rem;padding-bottom:.5rem}
|
||||
.table_body_td_class {border-top-width:1px; border-bottom-width:1px; border-color:#1a202c; padding-left:1rem;padding-right:1rem; padding-top:1rem;padding-bottom:1rem;}
|
||||
$custom_css
|
||||
</style>
|
||||
</head>
|
||||
<body>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '
|
||||
<div class="header bg-orange-600 flex justify-between py-12 px-12" style="page-break-inside: avoid;">
|
||||
<div class="grid grid-cols-6 gap-1">
|
||||
<div class="col-span-2 p-3">
|
||||
<h1 class="text-white font-bold text-3xl">$company.name</h1>
|
||||
</div>
|
||||
<div class="col-span-2 p-3 flex flex-col text-white flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="col-span-2 p-3 flex flex-col text-white flex-wrap">
|
||||
$entity_details
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '
|
||||
<table class="container"><thead><tr><td><div class="header-space"></div></td></tr></thead>
|
||||
<tbody><tr><td>
|
||||
<div class="grid grid-cols-5 gap-1 px-12 pt-12">
|
||||
<div class="col-span-2 p-3">
|
||||
$company_logo
|
||||
</div>
|
||||
<div class="col-span-3 p-3 flex flex-col flex-wrap">
|
||||
$client_details
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-12 pt-5 pb-20">
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left text-white bg-gray-900 display: table-header-group;">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left text-white bg-gray-900 display: table-header-group;">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex px-4 mt-6 w-full" style="page-break-inside: avoid;">
|
||||
<div class="w-1/2">
|
||||
$entity.public_notes
|
||||
</div>
|
||||
<div class="w-1/2 flex" style="page-break-inside: avoid;">
|
||||
<div class="w-1/2 text-right flex flex-col" style="page-break-inside: avoid;">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</div>
|
||||
<div class="w-1/2 text-right flex flex-col" style="page-break-inside: avoid;">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="page-break-inside: avoid;">
|
||||
<div class="flex px-4 mt-4 w-full items-end mt-5" >
|
||||
<div class="w-1/2" style="page-break-inside: avoid;">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
$terms
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 px-4 py-2 bg-gray-900 text-white" style="">
|
||||
<div class="w-1/2"></div>
|
||||
<div class="w-auto flex justify-end" style="page-break-inside: avoid;">
|
||||
<div class="w-56" style="page-break-inside: avoid;">
|
||||
<p class="font-bold">$balance_due_label</p>
|
||||
</div>
|
||||
<p>$balance_due</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td></tr></tbody><tfoot><tr><td><div class="footer-space"></div></td></tr></tfoot></table>
|
||||
';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<div class="footer bg-orange-600 flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
<div class="grid grid-cols-12 gap-4">
|
||||
<div class="col-start-4 col-span-4 p-3 flex flex-col text-white text-right flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="col-span-4 p-3 flex flex-col text-white text-right flex-wrap">
|
||||
$company_address
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Photo extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page {
|
||||
size: auto;
|
||||
margin-top: 5mm;
|
||||
}
|
||||
#imageContainer {
|
||||
background-image: url();
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.table_header_thead_class { text-align: left; border-bottom-width: 4px; border-color: black; }
|
||||
.table_header_td_class { font-weight: 400; text-transform: uppercase; padding: 1rem .5rem; }
|
||||
.table_body_td_class { padding: 1rem; }
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="px-16 py-10">
|
||||
<div class="grid grid-cols-12 mt-2">
|
||||
<div class="col-span-7">
|
||||
$company_logo
|
||||
</div>
|
||||
<div class="col-span-5">
|
||||
<div class="flex flex-col flex-wrap">
|
||||
$entity_details
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="flex content-center flex-wrap bg-gray-200 h-auto p-16" id="imageContainer">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex">
|
||||
<p class="uppercase text-orange-800">$to_label:</p>
|
||||
<div class="flex flex-col ml-2 flex-wrap">
|
||||
$client_details
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex mt-5">
|
||||
<p class="uppercase text-orange-800">$from_label:</p>
|
||||
<div class="flex flex-col ml-2 flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-16 py-16">
|
||||
<table class="w-full table-auto">
|
||||
<thead class="text-left border-b-4 border-black">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto">
|
||||
<thead class="text-left border-b-4 border-black">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex items-center justify-between mt-2 px-4 pb-4">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p>$entity.public_notes</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/3 flex flex-col">
|
||||
<div class="flex px-3 mt-2">
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</section>
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-4 pb-4 px-4">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
<p>$terms</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-2/5 flex-col">
|
||||
<section class="flex bg-orange-700 py-2 text-white px-2 mt-1">
|
||||
<p class="w-1/2">$balance_due_label</p>
|
||||
<p class="text-right w-1/2">$balance_due</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Plain extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page {
|
||||
size: auto;
|
||||
margin-top: 5mm;
|
||||
}
|
||||
.table_header_thead_class { text-align: left; background-color: #e2e8f0 }
|
||||
.table_header_td_class { padding: 1rem .5rem; }
|
||||
.table_body_td_class { padding: 1rem; border-bottom-width: 1px; border-top-width: 2px; border-color: #e2e8f0 }
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="px-12 py-8">
|
||||
<div class="grid grid-cols-6 gap-1">
|
||||
<div class="col-span-2 p-3">
|
||||
$company_logo
|
||||
</div>
|
||||
<div class="col-span-2 p-3 flex flex-col flex-wrap">
|
||||
$company_details
|
||||
</div>
|
||||
<div class="col-span-2 p-3 flex flex-col flex-wrap">
|
||||
$entity_details
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="flex flex-col mt-8 flex-wrap">
|
||||
$client_details
|
||||
</div>
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left bg-gray-300">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody>
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto mt-8">
|
||||
<thead class="text-left bg-gray-300">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody>
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="grid grid-cols-12 gap-1">
|
||||
<div class="col-span-6 p-3">
|
||||
<div class="flex flex-col">
|
||||
<p>$entity.public_notes</p>
|
||||
<div class="pt-4">
|
||||
<p class="font-bold">$terms_label</p>
|
||||
<p>$terms</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6 p-3">
|
||||
<div class="grid grid-cols-2 gap-1">
|
||||
<div class="col-span-1 text-right flex flex-col">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</div>
|
||||
<div class="col-span-1 text-right flex flex-col">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-1 bg-gray-300">
|
||||
<div class="col-span-1 text-right flex flex-col">
|
||||
$balance_due_label
|
||||
</div>
|
||||
<div class="col-span-1 text-right flex flex-col">
|
||||
$balance_due
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Designs;
|
||||
|
||||
class Playful extends AbstractDesign
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function includes()
|
||||
{
|
||||
return '<title>$number</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<link href="$app_url/css/tailwind-1.2.0.css" rel="stylesheet">
|
||||
<style>
|
||||
body {font-size:90%}
|
||||
@page
|
||||
{
|
||||
size: auto;
|
||||
margin-top: 5mm;
|
||||
}
|
||||
.table_header_thead_class { text-align: left; background-color: #319795; border-radius: .5rem; }
|
||||
.table_header_td_class { padding: .75rem 1rem; font-weight: 600; color: white; }
|
||||
.table_body_td_class { padding: 1rem; border-bottom-width: 4px; border-style: dashed; border-color: #319795; color: black }
|
||||
$custom_css
|
||||
</style>';
|
||||
}
|
||||
|
||||
public function header()
|
||||
{
|
||||
return '<div class="my-12 mx-16">
|
||||
<div class="grid grid-cols-12 items-center justify-between">
|
||||
<div class="col-span-7">
|
||||
$company_logo
|
||||
</div>
|
||||
<div class="col-span-5 bg-teal-600 p-5 text-white">
|
||||
<div class="flex flex-col flex-wrap">
|
||||
$entity_details
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
public function body()
|
||||
{
|
||||
return '<div class="flex mt-16">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col">
|
||||
<p class="font-semibold text-teal-600 pl-4">$to_label:</p>
|
||||
<div class="flex border-dashed border-t-4 border-b-4 border-teal-600 py-4 mt-4 pl-4">
|
||||
<section class="flex flex-col flex-wrap">
|
||||
$client_details
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/2 ml-24">
|
||||
<div class="flex flex-col">
|
||||
<p class="font-semibold text-teal-600 pl-4">$from_label:</p>
|
||||
<div class="flex border-dashed border-t-4 border-b-4 border-teal-600 py-4 mt-4 pl-4">
|
||||
<section class="flex flex-col flex-wrap">
|
||||
$company_details
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="w-full table-auto mt-20 mb-8">
|
||||
<thead class="text-left bg-teal-600 rounded-lg">
|
||||
$product_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$product_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="w-full table-auto mt-20 mb-8">
|
||||
<thead class="text-left bg-teal-600 rounded-lg">
|
||||
$task_table_header
|
||||
</thead>
|
||||
<tbody class="whitespace-pre-line">
|
||||
$task_table_body
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="grid grid-cols-12 gap-4">
|
||||
<div class="col-span-7 flex flex-col">
|
||||
$entity.public_notes
|
||||
</div>
|
||||
<div class="col-span-5 flex">
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount_label
|
||||
$total_tax_labels
|
||||
$line_tax_labels
|
||||
</section>
|
||||
<section class="w-1/2 text-right flex flex-col">
|
||||
$discount
|
||||
$total_tax_values
|
||||
$line_tax_values
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-span-7">
|
||||
<p class="font-semibold">$terms_label</p>
|
||||
<p>$terms</p>
|
||||
</div>
|
||||
<div class="col-span-5">
|
||||
<div class="flex bg-teal-600 py-3 px-4 text-white">
|
||||
<p class="w-1/2">$balance_due_label</p>
|
||||
<p class="text-right w-1/2">$balance_due</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>';
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function product()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function footer()
|
||||
{
|
||||
return '
|
||||
<footer>
|
||||
<div class="div_footer flex justify-between py-8 px-12" style="page-break-inside: avoid;">
|
||||
</div>
|
||||
</footer>';
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@
|
||||
namespace App\Events\Credit;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\CreditWasViewed;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,6 @@
|
||||
namespace App\Events\Quote;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\QuoteWasViewed;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
|
21
app/Exceptions/PaymentFailed.php
Normal file
21
app/Exceptions/PaymentFailed.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class PaymentFailed extends Exception
|
||||
{
|
||||
public function report()
|
||||
{
|
||||
// ..
|
||||
}
|
||||
|
||||
public function render($request)
|
||||
{
|
||||
return render('gateways.unsuccessful', [
|
||||
'message' => $this->getMessage(),
|
||||
'code' => $this->getCode(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -33,6 +33,15 @@ class ExpenseFactory
|
||||
$expense->tax_rate3 = 0;
|
||||
$expense->date = null;
|
||||
$expense->payment_date = null;
|
||||
$expense->amount = 0;
|
||||
$expense->foreign_amount = 0;
|
||||
$expense->private_notes = '';
|
||||
$expense->public_notes = '';
|
||||
$expense->transaction_reference = '';
|
||||
$expense->custom_value1 = '';
|
||||
$expense->custom_value2 = '';
|
||||
$expense->custom_value3 = '';
|
||||
$expense->custom_value4 = '';
|
||||
|
||||
return $expense;
|
||||
}
|
||||
|
27
app/Factory/TaskStatusFactory.php
Normal file
27
app/Factory/TaskStatusFactory.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Models\TaskStatus;
|
||||
|
||||
class TaskStatusFactory
|
||||
{
|
||||
public static function create(int $company_id, int $user_id) :TaskStatus
|
||||
{
|
||||
$task_status = new TaskStatus;
|
||||
$task_status->user_id = $user_id;
|
||||
$task_status->company_id = $company_id;
|
||||
$task_status->name = '';
|
||||
|
||||
return $task_status;
|
||||
}
|
||||
}
|
@ -20,26 +20,6 @@ class EmailBuilder
|
||||
public $view_link;
|
||||
public $view_text;
|
||||
|
||||
private function parseTemplate(string $data, bool $is_markdown = true, $contact = null): string
|
||||
{
|
||||
//process variables
|
||||
if (! empty($this->variables)) {
|
||||
$data = str_replace(array_keys($this->variables), array_values($this->variables), $data);
|
||||
}
|
||||
|
||||
//process markdown
|
||||
if ($is_markdown) {
|
||||
$converter = new CommonMarkConverter([
|
||||
'html_input' => 'allow',
|
||||
'allow_unsafe_links' => true,
|
||||
]);
|
||||
|
||||
$data = $converter->convertToHtml($data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $footer
|
||||
* @return $this
|
||||
@ -75,7 +55,6 @@ class EmailBuilder
|
||||
*/
|
||||
public function setSubject($subject)
|
||||
{
|
||||
//$this->subject = $this->parseTemplate($subject, false, $this->contact);
|
||||
|
||||
if (! empty($this->variables)) {
|
||||
$subject = str_replace(array_keys($this->variables), array_values($this->variables), $subject);
|
||||
@ -92,8 +71,7 @@ class EmailBuilder
|
||||
*/
|
||||
public function setBody($body)
|
||||
{
|
||||
//$this->body = $this->parseTemplate($body, true);
|
||||
|
||||
//todo move this to use HTMLEngine
|
||||
if (! empty($this->variables)) {
|
||||
$body = str_replace(array_keys($this->variables), array_values($this->variables), $body);
|
||||
}
|
||||
|
@ -8,8 +8,10 @@
|
||||
|
||||
namespace App\Helpers\Email;
|
||||
|
||||
use App\Helpers\Email\EntityEmailInterface;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\Number;
|
||||
|
||||
class InvoiceEmail extends EmailBuilder
|
||||
@ -21,7 +23,7 @@ class InvoiceEmail extends EmailBuilder
|
||||
$contact = $invitation->contact;
|
||||
|
||||
if (! $reminder_template) {
|
||||
$reminder_template = $invoice->calculateTemplate();
|
||||
$reminder_template = $invoice->calculateTemplate('invoice');
|
||||
}
|
||||
|
||||
$body_template = $client->getSetting('email_template_'.$reminder_template);
|
||||
@ -68,7 +70,7 @@ class InvoiceEmail extends EmailBuilder
|
||||
|
||||
$this->setTemplate($client->getSetting('email_style'))
|
||||
->setContact($contact)
|
||||
->setVariables($invoice->makeValues($contact))
|
||||
->setVariables((new HtmlEngine($invitation))->makeValues())
|
||||
->setSubject($subject_template)
|
||||
->setBody($body_template)
|
||||
->setFooter("<a href='{$invitation->getLink()}'>".ctrans('texts.view_invoice').'</a>')
|
||||
|
@ -10,6 +10,7 @@ namespace App\Helpers\Email;
|
||||
|
||||
use App\Models\Quote;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Utils\HtmlEngine;
|
||||
|
||||
class QuoteEmail extends EmailBuilder
|
||||
{
|
||||
@ -56,7 +57,7 @@ class QuoteEmail extends EmailBuilder
|
||||
$this->setTemplate($quote->client->getSetting('email_style'))
|
||||
->setContact($contact)
|
||||
->setFooter("<a href='{$invitation->getLink()}'>Quote Link</a>")
|
||||
->setVariables($quote->makeValues($contact))
|
||||
->setVariables((new HtmlEngine($invitation))->makeValues())
|
||||
->setSubject($subject_template)
|
||||
->setBody($body_template);
|
||||
|
||||
|
@ -187,6 +187,18 @@ class InvoiceSum
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
public function getRecurringInvoice()
|
||||
{
|
||||
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
$this->invoice->total_taxes = $this->getTotalTaxes();
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
|
||||
$this->invoice->save();
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build $this->invoice variables after
|
||||
* calculations have been performed.
|
||||
|
@ -174,6 +174,18 @@ class InvoiceSumInclusive
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRecurringInvoice()
|
||||
{
|
||||
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
$this->invoice->total_taxes = $this->getTotalTaxes();
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
|
||||
|
||||
$this->invoice->save();
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
public function getInvoice()
|
||||
{
|
||||
//Build invoice values here and return Invoice
|
||||
|
@ -63,40 +63,42 @@ class BaseController extends Controller
|
||||
'user.company_user',
|
||||
'token.company_user',
|
||||
'company.activities',
|
||||
'company.designs.company',
|
||||
'company.task_statuses',
|
||||
'company.expense_categories',
|
||||
'company.documents',
|
||||
'company.users.company_user',
|
||||
'company.tax_rates',
|
||||
'company.groups',
|
||||
'company.company_gateways.gateway',
|
||||
'company.clients.contacts',
|
||||
'company.clients.contacts.company',
|
||||
'company.clients.gateway_tokens',
|
||||
'company.clients.documents',
|
||||
'company.products',
|
||||
'company.products.documents',
|
||||
'company.recurring_invoices',
|
||||
'company.company_gateways.gateway',
|
||||
'company.credits.invitations.contact',
|
||||
'company.credits.invitations.company',
|
||||
'company.credits.documents',
|
||||
'company.expenses.documents',
|
||||
'company.groups',
|
||||
'company.invoices.invitations.contact',
|
||||
'company.invoices.invitations.company',
|
||||
'company.invoices.documents',
|
||||
'company.products',
|
||||
'company.products.documents',
|
||||
'company.payments.paymentables',
|
||||
'company.payments.documents',
|
||||
'company.payment_terms.company',
|
||||
'company.projects.documents',
|
||||
'company.recurring_invoices',
|
||||
'company.recurring_invoices.invitations.contact',
|
||||
'company.recurring_invoices.invitations.company',
|
||||
'company.recurring_invoices.documents',
|
||||
'company.payments.paymentables',
|
||||
'company.payments.documents',
|
||||
'company.quotes.invitations.contact',
|
||||
'company.quotes.invitations.company',
|
||||
'company.quotes.documents',
|
||||
'company.credits.invitations.contact',
|
||||
'company.credits.invitations.company',
|
||||
'company.credits.documents',
|
||||
'company.payment_terms.company',
|
||||
'company.vendors.contacts',
|
||||
'company.expenses.documents',
|
||||
'company.tasks.documents',
|
||||
'company.projects.documents',
|
||||
'company.designs.company',
|
||||
'company.documents',
|
||||
'company.webhooks',
|
||||
'company.tax_rates',
|
||||
'company.tokens_hashed',
|
||||
'company.vendors.contacts.company',
|
||||
'company.vendors.documents',
|
||||
'company.webhooks',
|
||||
];
|
||||
|
||||
private $mini_load = [
|
||||
@ -208,55 +210,61 @@ class BaseController extends Controller
|
||||
$query->whereNotNull('updated_at')->with('documents');
|
||||
},
|
||||
'company.clients' => function ($query) use ($updated_at) {
|
||||
$query->where('clients.updated_at', '>=', $updated_at)->with('contacts', 'gateway_tokens','documents');
|
||||
},
|
||||
'company.tax_rates' => function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.groups' => function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
$query->where('clients.updated_at', '>=', $updated_at)->with('contacts.company', 'gateway_tokens','documents');
|
||||
},
|
||||
'company.company_gateways' => function ($query) {
|
||||
$query->whereNotNull('updated_at');
|
||||
},
|
||||
'company.products' => function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('documents');
|
||||
'company.credits'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'documents',);
|
||||
},
|
||||
'company.recurring_invoices'=> function ($query) use ($updated_at) {
|
||||
'company.designs'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('company');
|
||||
},
|
||||
'company.invoices'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'company', 'documents');
|
||||
'company.documents'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.recurring_invoices'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'company', 'documents');
|
||||
'company.expenses'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('documents' );
|
||||
},
|
||||
'company.groups' => function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.invoices'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'documents');
|
||||
},
|
||||
'company.payments'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('paymentables','documents');
|
||||
},
|
||||
'company.quotes'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'documents');
|
||||
},
|
||||
'company.credits'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'documents');
|
||||
$query->where('updated_at', '>=', $updated_at)->with('paymentables','documents', );
|
||||
},
|
||||
'company.payment_terms'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.vendors'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('contacts');
|
||||
},
|
||||
'company.expenses'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.tasks'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
'company.products' => function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('documents');
|
||||
},
|
||||
'company.projects'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('documents' );
|
||||
},
|
||||
'company.quotes'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'documents',);
|
||||
},
|
||||
'company.recurring_invoices'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('invitations', 'documents');
|
||||
},
|
||||
'company.tasks'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('documents' );
|
||||
},
|
||||
'company.tax_rates' => function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.designs'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('company');
|
||||
'company.vendors'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('contacts','documents' );
|
||||
},
|
||||
'company.expense_categories'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
'company.task_statuses'=> function ($query) use ($updated_at) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
},
|
||||
]
|
||||
);
|
||||
@ -419,7 +427,8 @@ class BaseController extends Controller
|
||||
|
||||
public function flutterRoute()
|
||||
{
|
||||
if ((bool) $this->checkAppSetup() !== false && Schema::hasTable('accounts') && $account = Account::first()) {
|
||||
// if ((bool) $this->checkAppSetup() !== false && Schema::hasTable('accounts') && $account = Account::first()) {
|
||||
if ((bool) $this->checkAppSetup() !== false && $account = Account::first()) {
|
||||
if (config('ninja.require_https') && ! request()->isSecure()) {
|
||||
return redirect()->secure(request()->getRequestUri());
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ class PaymentController extends Controller
|
||||
$payment_method_id = $request->input('payment_method_id');
|
||||
$invoice_totals = $payable_invoices->sum('amount');
|
||||
$first_invoice = $invoices->first();
|
||||
$credit_totals = $first_invoice->company->use_credits_payment == 'off' ? 0 : $first_invoice->client->service()->getCreditBalance();
|
||||
$credit_totals = $first_invoice->client->getSetting('use_credits_payment') == 'off' ? 0 : $first_invoice->client->service()->getCreditBalance();
|
||||
$starting_invoice_amount = $first_invoice->amount;
|
||||
|
||||
if($gateway)
|
||||
@ -193,7 +193,7 @@ class PaymentController extends Controller
|
||||
|
||||
$payment_hash = new PaymentHash;
|
||||
$payment_hash->hash = Str::random(128);
|
||||
$payment_hash->data = $payable_invoices->toArray();
|
||||
$payment_hash->data = ['invoices' => $payable_invoices->toArray()];
|
||||
$payment_hash->fee_total = $fee_totals;
|
||||
$payment_hash->fee_invoice_id = $first_invoice->id;
|
||||
$payment_hash->save();
|
||||
@ -220,17 +220,19 @@ class PaymentController extends Controller
|
||||
return $gateway
|
||||
->driver(auth()->user()->client)
|
||||
->setPaymentMethod($payment_method_id)
|
||||
->setPaymentHash($payment_hash)
|
||||
->processPaymentView($data);
|
||||
}
|
||||
|
||||
public function response(PaymentResponseRequest $request)
|
||||
{
|
||||
/*Payment Gateway*/
|
||||
$gateway = CompanyGateway::find($request->input('company_gateway_id'))->firstOrFail();
|
||||
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->payment_hash])->first();
|
||||
|
||||
return $gateway
|
||||
->driver(auth()->user()->client)
|
||||
->setPaymentMethod($request->input('payment_method_id'))
|
||||
->setPaymentHash($payment_hash)
|
||||
->processPaymentResponse($request);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ use App\Http\Requests\Company\UpdateCompanyRequest;
|
||||
use App\Http\Requests\SignupRequest;
|
||||
use App\Jobs\Company\CreateCompany;
|
||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Jobs\Ninja\RefundCancelledAccount;
|
||||
use App\Jobs\RegisterNewAccount;
|
||||
@ -205,6 +206,7 @@ class CompanyController extends BaseController
|
||||
$company = CreateCompany::dispatchNow($request->all(), auth()->user()->company()->account);
|
||||
|
||||
CreateCompanyPaymentTerms::dispatchNow($company, auth()->user());
|
||||
CreateCompanyTaskStatuses::dispatchNow($company, auth()->user());
|
||||
|
||||
$company = $this->company_repo->save($request->all(), $company);
|
||||
|
||||
|
@ -16,6 +16,7 @@ use App\Http\Requests\Credit\ShowCreditRequest;
|
||||
use App\Http\Requests\Credit\StoreCreditRequest;
|
||||
use App\Http\Requests\Credit\UpdateCreditRequest;
|
||||
use App\Jobs\Credit\StoreCredit;
|
||||
use App\Jobs\Entity\EmailEntity;
|
||||
use App\Jobs\Invoice\EmailCredit;
|
||||
use App\Jobs\Invoice\MarkInvoicePaid;
|
||||
use App\Models\Client;
|
||||
@ -545,7 +546,13 @@ class CreditController extends BaseController
|
||||
}
|
||||
break;
|
||||
case 'email':
|
||||
EmailCredit::dispatch($credit, $credit->company);
|
||||
// EmailCredit::dispatch($credit, $credit->company);
|
||||
|
||||
$credit->invitations->load('contact.client.country', 'credit.client.country', 'credit.company')->each(function ($invitation) use ($credit) {
|
||||
EmailEntity::dispatch($invitation, $credit->company);
|
||||
});
|
||||
|
||||
|
||||
if (! $bulk) {
|
||||
return response()->json(['message'=>'email sent'], 200);
|
||||
}
|
||||
|
@ -13,15 +13,18 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Email\InvoiceEmail;
|
||||
use App\Http\Requests\Email\SendEmailRequest;
|
||||
use App\Jobs\Entity\EmailEntity;
|
||||
use App\Jobs\Invoice\EmailInvoice;
|
||||
use App\Jobs\Mail\EntitySentMailer;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Quote;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Notifications\SendGenericNotification;
|
||||
use App\Transformers\CreditTransformer;
|
||||
use App\Transformers\InvoiceTransformer;
|
||||
use App\Transformers\QuoteTransformer;
|
||||
use App\Transformers\RecurringInvoiceTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class EmailController extends BaseController
|
||||
@ -116,32 +119,41 @@ class EmailController extends BaseController
|
||||
|
||||
$entity_obj->invitations->each(function ($invitation) use ($subject, $body, $entity_string, $entity_obj) {
|
||||
if ($invitation->contact->send_email && $invitation->contact->email) {
|
||||
$when = now()->addSeconds(1);
|
||||
|
||||
$invitation->contact->notify((new SendGenericNotification($invitation, $entity_string, $subject, $body))->delay($when));
|
||||
EmailEntity::dispatchNow($invitation, $invitation->company);
|
||||
//$invitation->contact->notify((new SendGenericNotification($invitation, $entity_string, $subject, $body))->delay($when));
|
||||
}
|
||||
});
|
||||
|
||||
$entity_obj->last_sent_date = now();
|
||||
$entity_obj->save();
|
||||
|
||||
/*Only notify the admin ONCE, not once per contact/invite*/
|
||||
$invitation = $entity_obj->invitations->first();
|
||||
|
||||
EntitySentMailer::dispatch($invitation, $entity_string, $entity_obj->user, $invitation->company);
|
||||
|
||||
if ($this instanceof Invoice) {
|
||||
if ($entity_obj instanceof Invoice) {
|
||||
$this->entity_type = Invoice::class;
|
||||
$this->entity_transformer = InvoiceTransformer::class;
|
||||
}
|
||||
|
||||
if ($this instanceof Quote) {
|
||||
if ($entity_obj instanceof Quote) {
|
||||
$this->entity_type = Quote::class;
|
||||
$this->entity_transformer = QuoteTransformer::class;
|
||||
}
|
||||
|
||||
if ($this instanceof Credit) {
|
||||
if ($entity_obj instanceof Credit) {
|
||||
$this->entity_type = Credit::class;
|
||||
$this->entity_transformer = CreditTransformer::class;
|
||||
}
|
||||
|
||||
if ($entity_obj instanceof RecurringInvoice) {
|
||||
$this->entity_type = RecurringInvoice::class;
|
||||
$this->entity_transformer = RecurringInvoiceTransformer::class;
|
||||
}
|
||||
|
||||
|
||||
$entity_obj->service()->markSent()->save();
|
||||
|
||||
return $this->itemResponse($entity_obj);
|
||||
|
@ -28,8 +28,7 @@ use App\Http\Requests\Invoice\EditInvoiceRequest;
|
||||
use App\Http\Requests\Invoice\ShowInvoiceRequest;
|
||||
use App\Http\Requests\Invoice\StoreInvoiceRequest;
|
||||
use App\Http\Requests\Invoice\UpdateInvoiceRequest;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Invoice\EmailInvoice;
|
||||
use App\Jobs\Entity\EmailEntity;
|
||||
use App\Jobs\Invoice\StoreInvoice;
|
||||
use App\Jobs\Invoice\ZipInvoices;
|
||||
use App\Jobs\Util\UnlinkFile;
|
||||
@ -707,7 +706,7 @@ class InvoiceController extends BaseController
|
||||
if (request()->has('email_type') && property_exists($invoice->company->settings, request()->input('email_type'))) {
|
||||
$this->reminder_template = $invoice->client->getSetting(request()->input('email_type'));
|
||||
} else {
|
||||
$this->reminder_template = $invoice->calculateTemplate();
|
||||
$this->reminder_template = $invoice->calculateTemplate('invoice');
|
||||
}
|
||||
|
||||
//touch reminder1,2,3_sent + last_sent here if the email is a reminder.
|
||||
@ -717,7 +716,7 @@ class InvoiceController extends BaseController
|
||||
$invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) use ($invoice) {
|
||||
$email_builder = (new InvoiceEmail())->build($invitation, $this->reminder_template);
|
||||
|
||||
EmailInvoice::dispatch($email_builder, $invitation, $invoice->company);
|
||||
EmailEntity::dispatch($invitation, $invoice->company);
|
||||
});
|
||||
|
||||
if (! $bulk) {
|
||||
|
12
app/Http/Controllers/OpenAPI/TaskStatusSchema.php
Normal file
12
app/Http/Controllers/OpenAPI/TaskStatusSchema.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="TaskStatus",
|
||||
* type="object",
|
||||
* @OA\Property(property="name", type="string", example="Backlog", description="The task status name"),
|
||||
* @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* @OA\Property(property="is_deleted", type="boolean", example=true, description="______"),
|
||||
* @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* @OA\Property(property="archived_at", type="number", format="integer", example="134341234234", description="Timestamp"),
|
||||
* )
|
||||
*/
|
@ -14,7 +14,6 @@ namespace App\Http\Controllers;
|
||||
use App\Designs\Custom;
|
||||
use App\Designs\Designer;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Jobs\Invoice\CreateInvoicePdf;
|
||||
use App\Jobs\Util\PreviewPdf;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
@ -99,7 +98,7 @@ class PreviewController extends BaseController
|
||||
|
||||
$entity_obj->load('client');
|
||||
|
||||
$html = new HtmlEngine(null, $entity_obj->invitations()->first(), request()->entity_type);
|
||||
$html = new HtmlEngine($entity_obj->invitations()->first());
|
||||
|
||||
$design_namespace = 'App\Services\PdfMaker\Designs\\'.request()->design['name'];
|
||||
|
||||
@ -176,7 +175,7 @@ class PreviewController extends BaseController
|
||||
return response()->json(['message' => 'Invalid custom design object'], 400);
|
||||
}
|
||||
|
||||
$html = new HtmlEngine(null, $invoice->invitations()->first(), 'invoice');
|
||||
$html = new HtmlEngine($invoice->invitations()->first());
|
||||
|
||||
$design = new Design(Design::CUSTOM, ['custom_partials' => request()->design['design']]);
|
||||
|
||||
@ -196,8 +195,6 @@ class PreviewController extends BaseController
|
||||
->design($design)
|
||||
->build();
|
||||
|
||||
// info($maker->getCompiledHTML(true));
|
||||
|
||||
$file_path = PreviewPdf::dispatchNow($maker->getCompiledHTML(true), auth()->user()->company());
|
||||
|
||||
DB::rollBack();
|
||||
|
@ -24,6 +24,7 @@ use App\Models\Project;
|
||||
use App\Repositories\ProjectRepository;
|
||||
use App\Transformers\ProjectTransformer;
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\SavesDocuments;
|
||||
use Illuminate\Http\Request;
|
||||
@ -36,6 +37,7 @@ class ProjectController extends BaseController
|
||||
{
|
||||
use MakesHash;
|
||||
use SavesDocuments;
|
||||
use GeneratesCounter;
|
||||
|
||||
protected $entity_type = Project::class;
|
||||
|
||||
@ -353,6 +355,7 @@ class ProjectController extends BaseController
|
||||
{
|
||||
$project = ProjectFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
$project->fill($request->all());
|
||||
$project->number = $this->getNextProjectNumber($request->getClient($request->input('client_id')));
|
||||
$project->save();
|
||||
|
||||
if ($request->has('documents')) {
|
||||
|
@ -16,6 +16,7 @@ use App\Http\Requests\Setup\CheckDatabaseRequest;
|
||||
use App\Http\Requests\Setup\CheckMailRequest;
|
||||
use App\Http\Requests\Setup\StoreSetupRequest;
|
||||
use App\Jobs\Account\CreateAccount;
|
||||
use App\Jobs\Util\VersionCheck;
|
||||
use App\Models\Account;
|
||||
use App\Utils\SystemHealth;
|
||||
use Illuminate\Http\Response;
|
||||
@ -124,6 +125,8 @@ class SetupController extends Controller
|
||||
CreateAccount::dispatchNow($request->all());
|
||||
}
|
||||
|
||||
VersionCheck::dispatchNow();
|
||||
|
||||
return redirect('/');
|
||||
} catch (\Exception $e) {
|
||||
info($e->getMessage());
|
||||
@ -192,7 +195,7 @@ class SetupController extends Controller
|
||||
return $this->testPhantom();
|
||||
}
|
||||
|
||||
Browsershot::html('PDF GENERATION WORKS! Thank you for using Invoice Ninja!')
|
||||
Browsershot::html('GENERATING PDFs WORKS! Thank you for using Invoice Ninja!')
|
||||
->setNodeBinary(config('ninja.system.node_path'))
|
||||
->setNpmBinary(config('ninja.system.npm_path'))
|
||||
->noSandbox()
|
||||
|
463
app/Http/Controllers/TaskStatusController.php
Normal file
463
app/Http/Controllers/TaskStatusController.php
Normal file
@ -0,0 +1,463 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Factory\TaskStatusFactory;
|
||||
use App\Http\Requests\TaskStatus\CreateTaskStatusRequest;
|
||||
use App\Http\Requests\TaskStatus\DestroyTaskStatusRequest;
|
||||
use App\Http\Requests\TaskStatus\ShowTaskStatusRequest;
|
||||
use App\Http\Requests\TaskStatus\StoreTaskStatusRequest;
|
||||
use App\Http\Requests\TaskStatus\UpdateTaskStatusRequest;
|
||||
use App\Models\TaskStatus;
|
||||
use App\Repositories\TaskStatusRepository;
|
||||
use App\Transformers\TaskStatusTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TaskStatusController extends BaseController
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
protected $entity_type = TaskStatus::class;
|
||||
|
||||
protected $entity_transformer = TaskStatusTransformer::class;
|
||||
|
||||
/**
|
||||
* @var TaskStatusRepository
|
||||
*/
|
||||
protected $task_status_repo;
|
||||
|
||||
/**
|
||||
* TaskStatusController constructor.
|
||||
*
|
||||
* @param \App\Repositories\TaskStatusRepository $task_status_repo The payment term repo
|
||||
*/
|
||||
public function __construct(TaskStatusRepository $task_status_repo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->task_status_repo = $task_status_repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/task_status",
|
||||
* operationId="getTaskStatuss",
|
||||
* tags={"task_status"},
|
||||
* summary="Gets a list of task statuses",
|
||||
* description="Lists task statuses",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="A list of task statuses",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$task_status = TaskStatus::whereCompanyId(auth()->user()->company()->id)->orWhere('company_id', null);
|
||||
|
||||
return $this->listResponse($task_status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Http\Requests\TaskStatus\CreateTaskStatusRequest $request The request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
* path="/api/v1/task_statuses/create",
|
||||
* operationId="getTaskStatussCreate",
|
||||
* tags={"task_status"},
|
||||
* summary="Gets a new blank TaskStatus object",
|
||||
* description="Returns a blank object with default values",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="A blank TaskStatus object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function create(CreateTaskStatusRequest $request)
|
||||
{
|
||||
$task_status = TaskStatusFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
|
||||
return $this->itemResponse($task_status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\TaskStatus\StoreTaskStatusRequest $request The request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/task_status",
|
||||
* operationId="storeTaskStatus",
|
||||
* tags={"task_status"},
|
||||
* summary="Adds a TaskStatus",
|
||||
* description="Adds a TaskStatusto the system",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\RequestBody(
|
||||
* description="The task_status request",
|
||||
* required=true,
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the saved TaskStatus object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function store(StoreTaskStatusRequest $request)
|
||||
{
|
||||
$task_status = TaskStatusFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||
$task_status->fill($request->all());
|
||||
$task_status->save();
|
||||
|
||||
return $this->itemResponse($task_status->fresh());
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/task_statuses/{id}",
|
||||
* operationId="showTaskStatus",
|
||||
* tags={"task_status"},
|
||||
* summary="Shows a TaskStatus Term",
|
||||
* description="Displays an TaskStatusby id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The TaskStatusHashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the TaskStatusobject",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function show(ShowTaskStatusRequest $request, TaskStatus $task_status)
|
||||
{
|
||||
return $this->itemResponse($task_status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/task_statuses/{id}/edit",
|
||||
* operationId="editTaskStatuss",
|
||||
* tags={"task_status"},
|
||||
* summary="Shows an TaskStatusfor editting",
|
||||
* description="Displays an TaskStatusby id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The TaskStatusHashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the TaskStatus object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function edit(EditTaskStatusRequest $request, TaskStatus $payment)
|
||||
{
|
||||
return $this->itemResponse($payment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\TaskStatus\UpdateTaskStatusRequest $request The request
|
||||
* @param \App\Models\TaskStatus $task_status The payment term
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Put(
|
||||
* path="/api/v1/task_statuses/{id}",
|
||||
* operationId="updateTaskStatus",
|
||||
* tags={"task_status"},
|
||||
* summary="Updates a TaskStatus Term",
|
||||
* description="Handles the updating of an TaskStatus Termby id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The TaskStatusHashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the TaskStatusobject",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function update(UpdateTaskStatusRequest $request, TaskStatus $task_status)
|
||||
{
|
||||
$task_status->fill($request->all());
|
||||
$task_status->save();
|
||||
|
||||
return $this->itemResponse($task_status->fresh());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Http\Requests\TaskStatus\DestroyTaskStatusRequest $request
|
||||
* @param \App\Models\TaskStatus $task_status
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Delete(
|
||||
* path="/api/v1/task_statuses/{id}",
|
||||
* operationId="deleteTaskStatus",
|
||||
* tags={"task_statuss"},
|
||||
* summary="Deletes a TaskStatus Term",
|
||||
* description="Handles the deletion of an TaskStatus by id",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* description="The TaskStatusHashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns a HTTP status",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function destroy(DestroyTaskStatusRequest $request, TaskStatus $task_status)
|
||||
{
|
||||
$task_status->delete();
|
||||
|
||||
return response()->json([], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @return Collection
|
||||
*
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/task_statuses/bulk",
|
||||
* operationId="bulkTaskStatuss",
|
||||
* tags={"task_status"},
|
||||
* summary="Performs bulk actions on an array of task statuses",
|
||||
* description="",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||
* @OA\RequestBody(
|
||||
* description="TaskStatus Ter,s",
|
||||
* required=true,
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="integer",
|
||||
* description="Array of hashed IDs to be bulk 'actioned",
|
||||
* example="[0,1,2,3]",
|
||||
* ),
|
||||
* )
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="The TaskStatus Terms response",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/TaskStatus"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function bulk()
|
||||
{
|
||||
$action = request()->input('action');
|
||||
|
||||
$ids = request()->input('ids');
|
||||
|
||||
$task_status = TaskStatus::withTrashed()->company()->find($this->transformKeys($ids));
|
||||
|
||||
$task_status->each(function ($task_status, $key) use ($action) {
|
||||
if (auth()->user()->can('edit', $task_status)) {
|
||||
$this->task_status_repo->{$action}($task_status);
|
||||
}
|
||||
});
|
||||
|
||||
return $this->listResponse(TaskStatus::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||
}
|
||||
}
|
@ -52,10 +52,9 @@ class Kernel extends HttpKernel
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
'throttle:300,1',
|
||||
'bindings',
|
||||
'query_logging',
|
||||
//\App\Http\Middleware\StartupCheck::class,
|
||||
\App\Http\Middleware\Cors::class,
|
||||
],
|
||||
'contact' => [
|
||||
@ -75,7 +74,7 @@ class Kernel extends HttpKernel
|
||||
\App\Http\Middleware\QueryLogging::class,
|
||||
],
|
||||
'shop' => [
|
||||
'throttle:60,1',
|
||||
'throttle:120,1',
|
||||
'bindings',
|
||||
'query_logging',
|
||||
],
|
||||
|
@ -33,8 +33,6 @@ class ContactKeyLogin
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
info($request->segment(3));
|
||||
info($request->route('contact_key'));
|
||||
|
||||
if(Auth::guard('contact')->check())
|
||||
Auth::guard('contact')->logout();
|
||||
|
@ -54,6 +54,7 @@ class QueryLogging
|
||||
|
||||
// if($count > 50)
|
||||
// Log::info($queries);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,9 +84,8 @@ class StoreClientRequest extends Request
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
|
||||
//is no settings->currency_id is set then lets dive in and find either a group or company currency all the below may be redundant!!
|
||||
if (! property_exists($settings, 'currency_id') && isset($input['group_settings_id'])) {
|
||||
@ -108,29 +107,6 @@ class StoreClientRequest extends Request
|
||||
|
||||
$input['settings'] = $settings;
|
||||
|
||||
if (isset($input['contacts'])) {
|
||||
foreach ($input['contacts'] as $key => $contact) {
|
||||
if (array_key_exists('id', $contact) && is_numeric($contact['id'])) {
|
||||
unset($input['contacts'][$key]['id']);
|
||||
} elseif (array_key_exists('id', $contact) && is_string($contact['id'])) {
|
||||
$input['contacts'][$key]['id'] = $this->decodePrimaryKey($contact['id']);
|
||||
}
|
||||
|
||||
//Filter the client contact password - if it is sent with ***** we should ignore it!
|
||||
if (isset($contact['password'])) {
|
||||
if (strlen($contact['password']) == 0) {
|
||||
$input['contacts'][$key]['password'] = '';
|
||||
} else {
|
||||
$contact['password'] = str_replace('*', '', $contact['password']);
|
||||
|
||||
if (strlen($contact['password']) == 0) {
|
||||
unset($input['contacts'][$key]['password']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($input['country_code'])) {
|
||||
$input['country_id'] = $this->getCountryCode($input['country_code']);
|
||||
}
|
||||
|
@ -95,33 +95,7 @@ class UpdateClientRequest extends Request
|
||||
$input['group_settings_id'] = $this->decodePrimaryKey($input['group_settings_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (isset($input['contacts'])) {
|
||||
foreach ($input['contacts'] as $key => $contact) {
|
||||
if (array_key_exists('id', $contact) && is_numeric($contact['id'])) {
|
||||
unset($input['contacts'][$key]['id']);
|
||||
} elseif (array_key_exists('id', $contact) && is_string($contact['id'])) {
|
||||
$input['contacts'][$key]['id'] = $this->decodePrimaryKey($contact['id']);
|
||||
}
|
||||
|
||||
//Filter the client contact password - if it is sent with ***** we should ignore it!
|
||||
if (isset($contact['password'])) {
|
||||
if (strlen($contact['password']) == 0) {
|
||||
$input['contacts'][$key]['password'] = '';
|
||||
} else {
|
||||
$input['contacts'][$key]['password'] = str_replace('*', '', $contact['password']);
|
||||
|
||||
if (strlen($contact['password']) == 0) {
|
||||
unset($input['contacts'][$key]['password']);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
if (array_key_exists('settings', $input)) {
|
||||
$input['settings'] = $this->filterSaveableSettings($input['settings']);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Requests\ClientPortal;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CreatePaymentMethodRequest extends FormRequest
|
||||
|
@ -14,6 +14,7 @@ namespace App\Http\Requests\ClientPortal\Documents;
|
||||
|
||||
use App\Models\Document;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ShowDocumentRequest extends FormRequest
|
||||
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\Credit;
|
||||
|
||||
|
@ -1,11 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Credit;
|
||||
|
||||
use App\Models\Credit;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class CreateCreditRequest extends FormRequest
|
||||
class CreateCreditRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Credit;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class DestroyCreditRequest extends FormRequest
|
||||
class DestroyCreditRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Credit;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class EditCreditRequest extends FormRequest
|
||||
class EditCreditRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Credit;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class ShowCreditRequest extends FormRequest
|
||||
class ShowCreditRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -1,4 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\Credit;
|
||||
|
||||
@ -6,9 +15,9 @@ use App\Http\ValidationRules\Credit\UniqueCreditNumberRule;
|
||||
use App\Models\Credit;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class StoreCreditRequest extends FormRequest
|
||||
class StoreCreditRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
use CleanLineItems;
|
||||
@ -57,37 +66,7 @@ class StoreCreditRequest extends FormRequest
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (isset($input['client_contacts'])) {
|
||||
foreach ($input['client_contacts'] as $key => $contact) {
|
||||
if (! array_key_exists('send_email', $contact) || ! array_key_exists('id', $contact)) {
|
||||
unset($input['client_contacts'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($input['invitations'])) {
|
||||
foreach ($input['invitations'] as $key => $value) {
|
||||
if (isset($input['invitations'][$key]['id']) && is_numeric($input['invitations'][$key]['id'])) {
|
||||
unset($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (isset($input['invitations'][$key]['id']) && is_string($input['invitations'][$key]['id'])) {
|
||||
$input['invitations'][$key]['id'] = $this->decodePrimaryKey($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (is_string($input['invitations'][$key]['client_contact_id'])) {
|
||||
$input['invitations'][$key]['client_contact_id'] = $this->decodePrimaryKey($input['invitations'][$key]['client_contact_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
//$input['line_items'] = json_encode($input['line_items']);
|
||||
|
@ -1,13 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Credit;
|
||||
|
||||
use App\Utils\Traits\ChecksEntityStatus;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class UpdateCreditRequest extends FormRequest
|
||||
class UpdateCreditRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
use CleanLineItems;
|
||||
@ -53,33 +63,7 @@ class UpdateCreditRequest extends FormRequest
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
|
||||
if (isset($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (isset($input['invitations'])) {
|
||||
foreach ($input['invitations'] as $key => $value) {
|
||||
if (is_numeric($input['invitations'][$key]['id'])) {
|
||||
unset($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (is_string($input['invitations'][$key]['id'])) {
|
||||
$input['invitations'][$key]['id'] = $this->decodePrimaryKey($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (is_string($input['invitations'][$key]['client_contact_id'])) {
|
||||
$input['invitations'][$key]['client_contact_id'] = $this->decodePrimaryKey($input['invitations'][$key]['client_contact_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
|
||||
|
@ -12,9 +12,9 @@
|
||||
|
||||
namespace App\Http\Requests\Document;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class DownloadMultipleDocumentsRequest extends FormRequest
|
||||
class DownloadMultipleDocumentsRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -1,12 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Expense;
|
||||
|
||||
use App\Models\Expense;
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class BulkExpenseRequest extends FormRequest
|
||||
class BulkExpenseRequest extends Request
|
||||
{
|
||||
use BulkOptions;
|
||||
|
||||
|
@ -14,6 +14,7 @@ namespace App\Http\Requests\Expense;
|
||||
use App\DataMapper\ExpenseSettings;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\Expense\UniqueExpenseNumberRule;
|
||||
use App\Http\ValidationRules\User\RelatedUserRule;
|
||||
use App\Http\ValidationRules\ValidExpenseGroupSettingsRule;
|
||||
use App\Models\Expense;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
@ -36,33 +37,24 @@ class StoreExpenseRequest extends Request
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
//$rules['name'] = 'required|min:1';
|
||||
$rules['id_number'] = 'unique:expenses,id_number,'.$this->id.',id,company_id,'.$this->company_id;
|
||||
//$rules['settings'] = new ValidExpenseGroupSettingsRule();
|
||||
$rules['contacts.*.email'] = 'nullable|distinct';
|
||||
|
||||
$rules['number'] = new UniqueExpenseNumberRule($this->all());
|
||||
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||
|
||||
// $contacts = request('contacts');
|
||||
|
||||
// if (is_array($contacts)) {
|
||||
// for ($i = 0; $i < count($contacts); $i++) {
|
||||
|
||||
// //$rules['contacts.' . $i . '.email'] = 'nullable|email|distinct';
|
||||
// }
|
||||
// }
|
||||
|
||||
return $rules;
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
// $input = $this->all();
|
||||
$input = $this->all();
|
||||
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
// $this->replace($input);
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
public function messages()
|
||||
|
@ -46,16 +46,7 @@ class UpdateExpenseRequest extends Request
|
||||
$rules['number'] = 'unique:expenses,number,'.$this->id.',id,company_id,'.$this->expense->company_id;
|
||||
}
|
||||
|
||||
$contacts = request('contacts');
|
||||
|
||||
if (is_array($contacts)) {
|
||||
// for ($i = 0; $i < count($contacts); $i++) {
|
||||
// // $rules['contacts.' . $i . '.email'] = 'nullable|email|unique:client_contacts,email,' . isset($contacts[$i]['id'].',company_id,'.$this->company_id);
|
||||
// //$rules['contacts.' . $i . '.email'] = 'nullable|email';
|
||||
// }
|
||||
}
|
||||
|
||||
return $rules;
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
public function messages()
|
||||
@ -72,6 +63,8 @@ class UpdateExpenseRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\ExpenseCategory;
|
||||
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class BulkExpenseCategoryRequest extends FormRequest
|
||||
class BulkExpenseCategoryRequest extends Request
|
||||
{
|
||||
use BulkOptions;
|
||||
|
||||
|
@ -63,45 +63,7 @@ class StoreInvoiceRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('project_id', $input) && is_string($input['project_id'])) {
|
||||
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (isset($input['client_contacts'])) {
|
||||
foreach ($input['client_contacts'] as $key => $contact) {
|
||||
if (! array_key_exists('send_email', $contact) || ! array_key_exists('id', $contact)) {
|
||||
unset($input['client_contacts'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($input['invitations'])) {
|
||||
foreach ($input['invitations'] as $key => $value) {
|
||||
if (isset($input['invitations'][$key]['id']) && is_numeric($input['invitations'][$key]['id'])) {
|
||||
unset($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (isset($input['invitations'][$key]['id']) && is_string($input['invitations'][$key]['id'])) {
|
||||
$input['invitations'][$key]['id'] = $this->decodePrimaryKey($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (is_string($input['invitations'][$key]['client_contact_id'])) {
|
||||
$input['invitations'][$key]['client_contact_id'] = $this->decodePrimaryKey($input['invitations'][$key]['client_contact_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
//$input['line_items'] = json_encode($input['line_items']);
|
||||
|
@ -62,35 +62,10 @@ class UpdateInvoiceRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
|
||||
if (isset($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (isset($input['invitations'])) {
|
||||
foreach ($input['invitations'] as $key => $value) {
|
||||
if (array_key_exists('id', $input['invitations'][$key]) && is_numeric($input['invitations'][$key]['id'])) {
|
||||
unset($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('id', $input['invitations'][$key]) && is_string($input['invitations'][$key]['id'])) {
|
||||
$input['invitations'][$key]['id'] = $this->decodePrimaryKey($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (is_string($input['invitations'][$key]['client_contact_id'])) {
|
||||
$input['invitations'][$key]['client_contact_id'] = $this->decodePrimaryKey($input['invitations'][$key]['client_contact_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
$input['id'] = $this->invoice->id;
|
||||
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
|
||||
$this->replace($input);
|
||||
|
@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Migration;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class UploadMigrationFileRequest extends FormRequest
|
||||
class UploadMigrationFileRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -38,7 +38,7 @@ class StorePaymentRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
//info(print_r($input,1));
|
||||
// info(print_r($input,1));
|
||||
|
||||
$invoices_total = 0;
|
||||
$credits_total = 0;
|
||||
@ -77,7 +77,7 @@ class StorePaymentRequest extends Request
|
||||
|
||||
if (! isset($input['amount']) || $input['amount'] == 0) {
|
||||
//$input['amount'] = $invoices_total - $credits_total;
|
||||
$input['amount'] = $invoices_total;
|
||||
$input['amount'] = $invoices_total - $credits_total; //todo the payment amount is always less the credit amount applied
|
||||
}
|
||||
|
||||
$input['is_manual'] = true;
|
||||
@ -94,17 +94,15 @@ class StorePaymentRequest extends Request
|
||||
$rules = [
|
||||
'amount' => 'numeric|required',
|
||||
'amount' => [new PaymentAmountsBalanceRule(), new ValidCreditsPresentRule()],
|
||||
//'date' => 'required',
|
||||
'client_id' => 'bail|required|exists:clients,id',
|
||||
'invoices.*.invoice_id' => 'required|distinct|exists:invoices,id',
|
||||
'invoices.*.invoice_id' => 'bail|required|distinct|exists:invoices,id',
|
||||
'invoices.*.invoice_id' => new ValidInvoicesRules($this->all()),
|
||||
'invoices.*.amount' => 'required',
|
||||
'credits.*.credit_id' => 'required|exists:credits,id',
|
||||
'credits.*.credit_id' => 'bail|required|exists:credits,id',
|
||||
'credits.*.credit_id' => new ValidCreditsRules($this->all()),
|
||||
'credits.*.amount' => 'required',
|
||||
'invoices' => new ValidPayableInvoicesRule(),
|
||||
'number' => 'nullable|unique:payments,number,'.$this->id.',id,company_id,'.$this->company_id,
|
||||
//'number' => 'nullable',
|
||||
'number' => 'bail|nullable|unique:payments,number,'.$this->id.',id,company_id,'.$this->company_id,
|
||||
];
|
||||
|
||||
if ($this->input('documents') && is_array($this->input('documents'))) {
|
||||
|
@ -34,12 +34,13 @@ class UpdatePaymentRequest extends Request
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{//min:1 removed, 'required'
|
||||
{
|
||||
|
||||
$rules = [
|
||||
'number' => 'nullable|unique:payments,number,'.$this->id.',id,company_id,'.$this->payment->company_id,
|
||||
'invoices' => ['array', new PaymentAppliedValidAmount, new ValidCreditsPresentRule],
|
||||
'invoices.*.invoice_id' => 'distinct',
|
||||
'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
|
||||
'number' => 'nullable|unique:payments,number,'.$this->id.',id,company_id,'.$this->company_id,
|
||||
];
|
||||
|
||||
if ($this->input('documents') && is_array($this->input('documents'))) {
|
||||
@ -59,9 +60,7 @@ class UpdatePaymentRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
if (isset($input['client_id'])) {
|
||||
unset($input['client_id']);
|
||||
@ -71,18 +70,6 @@ class UpdatePaymentRequest extends Request
|
||||
unset($input['amount']);
|
||||
}
|
||||
|
||||
// if (isset($input['type_id'])) {
|
||||
// unset($input['type_id']);
|
||||
// }
|
||||
|
||||
// if (isset($input['date'])) {
|
||||
// unset($input['date']);
|
||||
// }
|
||||
|
||||
// if (isset($input['transaction_reference'])) {
|
||||
// unset($input['transaction_reference']);
|
||||
// }
|
||||
|
||||
if (isset($input['number'])) {
|
||||
unset($input['number']);
|
||||
}
|
||||
|
@ -1,12 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Payments;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyGateway;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class PaymentWebhookRequest extends FormRequest
|
||||
class PaymentWebhookRequest extends Request
|
||||
{
|
||||
public function authorize()
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Http\Requests\Project;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Client;
|
||||
use App\Models\Project;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
@ -33,7 +34,6 @@ class StoreProjectRequest extends Request
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
//$rules['name'] ='required|unique:projects,name,null,null,company_id,'.auth()->user()->companyId();
|
||||
$rules['name'] = 'required';
|
||||
$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||
|
||||
@ -42,13 +42,13 @@ class StoreProjectRequest extends Request
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
public function getClient($client_id)
|
||||
{
|
||||
return Client::find($client_id);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class UpdateProjectRequest extends Request
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ class UpdateRecurringInvoiceRequest extends Request
|
||||
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$rules = [];
|
||||
|
||||
if ($this->input('documents') && is_array($this->input('documents'))) {
|
||||
@ -49,7 +50,7 @@ class UpdateRecurringInvoiceRequest extends Request
|
||||
}
|
||||
|
||||
if ($this->input('number')) {
|
||||
$rules['number'] = 'unique:recurring_invoices,number,'.$this->id.',id,company_id,'.$this->recurring_invoice->company_id;
|
||||
$rules['number'] = 'unique:recurring_invoices,number,'.$this->recurring_invoice->id.',id,company_id,'.$this->recurring_invoice->company_id;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
@ -11,10 +11,14 @@
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\ValidationRules\User\RelatedUserRule;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class Request extends FormRequest
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
@ -24,4 +28,124 @@ class Request extends FormRequest
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function globalRules($rules)
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
foreach($this->all() as $key => $value)
|
||||
{
|
||||
if(method_exists($this, $key))
|
||||
$rules = $this->{$key}($rules);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
private function assigned_user_id($rules)
|
||||
{
|
||||
$rules['assigned_user_id'] = [
|
||||
'bail' ,
|
||||
'sometimes',
|
||||
'nullable',
|
||||
new RelatedUserRule($this->all())
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
private function invoice_id($rules)
|
||||
{
|
||||
$rules['invoice_id'] = 'bail|nullable|sometimes|exists:invoices,id,company_id,'.auth()->user()->company()->id.',client_id,'.$this['client_id'];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
private function vendor_id($rules)
|
||||
{
|
||||
$rules['vendor_id'] = 'bail|nullable|sometimes|exists:vendors,id,company_id,'.auth()->user()->company()->id;
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function decodePrimaryKeys($input)
|
||||
{
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('user_id', $input) && is_string($input['user_id'])) {
|
||||
$input['user_id'] = $this->decodePrimaryKey($input['user_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('vendor_id', $input) && is_string($input['vendor_id'])) {
|
||||
$input['vendor_id'] = $this->decodePrimaryKey($input['vendor_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('invoice_id', $input) && is_string($input['invoice_id'])) {
|
||||
$input['invoice_id'] = $this->decodePrimaryKey($input['invoice_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('project_id', $input) && is_string($input['project_id'])) {
|
||||
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
|
||||
}
|
||||
|
||||
if (isset($input['client_contacts'])) {
|
||||
foreach ($input['client_contacts'] as $key => $contact) {
|
||||
if (! array_key_exists('send_email', $contact) || ! array_key_exists('id', $contact)) {
|
||||
unset($input['client_contacts'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($input['invitations'])) {
|
||||
foreach ($input['invitations'] as $key => $value) {
|
||||
if (isset($input['invitations'][$key]['id']) && is_numeric($input['invitations'][$key]['id'])) {
|
||||
unset($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (isset($input['invitations'][$key]['id']) && is_string($input['invitations'][$key]['id'])) {
|
||||
$input['invitations'][$key]['id'] = $this->decodePrimaryKey($input['invitations'][$key]['id']);
|
||||
}
|
||||
|
||||
if (is_string($input['invitations'][$key]['client_contact_id'])) {
|
||||
$input['invitations'][$key]['client_contact_id'] = $this->decodePrimaryKey($input['invitations'][$key]['client_contact_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($input['contacts'])) {
|
||||
foreach ($input['contacts'] as $key => $contact) {
|
||||
if (array_key_exists('id', $contact) && is_numeric($contact['id'])) {
|
||||
unset($input['contacts'][$key]['id']);
|
||||
} elseif (array_key_exists('id', $contact) && is_string($contact['id'])) {
|
||||
$input['contacts'][$key]['id'] = $this->decodePrimaryKey($contact['id']);
|
||||
}
|
||||
|
||||
//Filter the client contact password - if it is sent with ***** we should ignore it!
|
||||
if (isset($contact['password'])) {
|
||||
if (strlen($contact['password']) == 0) {
|
||||
$input['contacts'][$key]['password'] = '';
|
||||
} else {
|
||||
$contact['password'] = str_replace('*', '', $contact['password']);
|
||||
|
||||
if (strlen($contact['password']) == 0) {
|
||||
unset($input['contacts'][$key]['password']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Setup;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class CheckDatabaseRequest extends FormRequest
|
||||
class CheckDatabaseRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -1,10 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Setup;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class CheckMailRequest extends FormRequest
|
||||
class CheckMailRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
|
@ -1,12 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Task;
|
||||
|
||||
use App\Models\Task;
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class BulkTaskRequest extends FormRequest
|
||||
class BulkTaskRequest extends Request
|
||||
{
|
||||
use BulkOptions;
|
||||
|
||||
|
@ -37,49 +37,17 @@ class StoreTaskRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
//$rules['name'] = 'required|min:1';
|
||||
//$rules['client_id'] = 'required|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
||||
|
||||
// $rules['number'] = new UniqueTaskNumberRule($this->all());
|
||||
|
||||
|
||||
return $rules;
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('project_id', $input) && is_string($input['project_id'])) {
|
||||
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('invoice_id', $input) && is_string($input['invoice_id'])) {
|
||||
$input['invoice_id'] = $this->decodePrimaryKey($input['invoice_id']);
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
// public function messages()
|
||||
// {
|
||||
// // return [
|
||||
// // 'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
// // //'required' => trans('validation.required', ['attribute' => 'email']),
|
||||
// // 'contacts.*.email.required' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
// // ];
|
||||
// }
|
||||
}
|
||||
|
@ -40,45 +40,15 @@ class UpdateTaskRequest extends Request
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
|
||||
if ($this->input('number')) {
|
||||
$rules['number'] = 'unique:tasks,number,'.$this->id.',id,company_id,'.$this->taskss->company_id;
|
||||
$rules['number'] = 'unique:tasks,number,'.$this->id.',id,company_id,'.$this->task->company_id;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
return $this->globalRules($rules);
|
||||
}
|
||||
|
||||
// public function messages()
|
||||
// {
|
||||
// return [
|
||||
// 'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||
// 'email' => ctrans('validation.email', ['attribute' => 'email']),
|
||||
// 'name.required' => ctrans('validation.required', ['attribute' => 'name']),
|
||||
// 'required' => ctrans('validation.required', ['attribute' => 'email']),
|
||||
// ];
|
||||
// }
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('design_id', $input) && is_string($input['design_id'])) {
|
||||
$input['design_id'] = $this->decodePrimaryKey($input['design_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('client_id', $input) && is_string($input['client_id'])) {
|
||||
$input['client_id'] = $this->decodePrimaryKey($input['client_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('project_id', $input) && is_string($input['project_id'])) {
|
||||
$input['project_id'] = $this->decodePrimaryKey($input['project_id']);
|
||||
}
|
||||
|
||||
if (array_key_exists('invoice_id', $input) && is_string($input['invoice_id'])) {
|
||||
$input['invoice_id'] = $this->decodePrimaryKey($input['invoice_id']);
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($this->all());
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
28
app/Http/Requests/TaskStatus/ActionTaskStatusRequest.php
Normal file
28
app/Http/Requests/TaskStatus/ActionTaskStatusRequest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\TaskStatus;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Payment;
|
||||
|
||||
class ActionTaskStatusRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
}
|
28
app/Http/Requests/TaskStatus/CreateTaskStatusRequest.php
Normal file
28
app/Http/Requests/TaskStatus/CreateTaskStatusRequest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\TaskStatus;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\TaskStatus;
|
||||
|
||||
class CreateTaskStatusRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
}
|
28
app/Http/Requests/TaskStatus/DestroyTaskStatusRequest.php
Normal file
28
app/Http/Requests/TaskStatus/DestroyTaskStatusRequest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\TaskStatus;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\TaskStatus;
|
||||
|
||||
class DestroyTaskStatusRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
}
|
44
app/Http/Requests/TaskStatus/EditTaskStatusRequest.php
Normal file
44
app/Http/Requests/TaskStatus/EditTaskStatusRequest.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\TaskStatus;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\TaskStatus;
|
||||
|
||||
class EditTaskStatusRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
//$input['id'] = $this->encodePrimaryKey($input['id']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
28
app/Http/Requests/TaskStatus/ShowTaskStatusRequest.php
Normal file
28
app/Http/Requests/TaskStatus/ShowTaskStatusRequest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\TaskStatus;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\TaskStatus;
|
||||
|
||||
class ShowTaskStatusRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
}
|
47
app/Http/Requests/TaskStatus/StoreTaskStatusRequest.php
Normal file
47
app/Http/Requests/TaskStatus/StoreTaskStatusRequest.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\TaskStatus;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\TaskStatus;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class StoreTaskStatusRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
$rules['name'] ='required|unique:task_statuses,name,null,null,company_id,'.auth()->user()->companyId();
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
42
app/Http/Requests/TaskStatus/UpdateTaskStatusRequest.php
Normal file
42
app/Http/Requests/TaskStatus/UpdateTaskStatusRequest.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\TaskStatus;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateTaskStatusRequest extends Request
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
if ($this->input('name'))
|
||||
$rules['name'] = 'unique:task_statuses,name,'.$this->id.',id,company_id,'.$this->task_status->company_id;
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Token;
|
||||
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class BulkTokenRequest extends FormRequest
|
||||
class BulkTokenRequest extends Request
|
||||
{
|
||||
use BulkOptions;
|
||||
|
||||
|
14
app/Http/Requests/Vendor/BulkVendorRequest.php
vendored
14
app/Http/Requests/Vendor/BulkVendorRequest.php
vendored
@ -1,12 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Vendor;
|
||||
|
||||
use App\Models\Vendor;
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class BulkVendorRequest extends FormRequest
|
||||
class BulkVendorRequest extends Request
|
||||
{
|
||||
use BulkOptions;
|
||||
|
||||
|
@ -50,9 +50,7 @@ class StoreVendorRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (array_key_exists('assigned_user_id', $input) && is_string($input['assigned_user_id'])) {
|
||||
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
|
||||
}
|
||||
$input = $this->decodePrimaryKeys($input);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
@ -1,12 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
|
||||
namespace App\Http\Requests\Webhook;
|
||||
|
||||
use App\Models\Vendor;
|
||||
use App\Utils\Traits\BulkOptions;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class BulkWebhookRequest extends FormRequest
|
||||
class BulkWebhookRequest extends Request
|
||||
{
|
||||
use BulkOptions;
|
||||
|
||||
|
@ -55,15 +55,27 @@ class UniqueExpenseNumberRule implements Rule
|
||||
*/
|
||||
private function checkIfExpenseNumberUnique() : bool
|
||||
{
|
||||
$expense = Expense::where('client_id', $this->input['client_id'])
|
||||
->where('number', $this->input['number'])
|
||||
->withTrashed()
|
||||
->exists();
|
||||
|
||||
if ($expense) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(empty($this->input['number']))
|
||||
return true;
|
||||
|
||||
$expense = Expense::query()
|
||||
->where('number', $this->input['number'])
|
||||
->withTrashed();
|
||||
|
||||
// if(isset($this->input['client_id']))
|
||||
// $expense->where('client_id', $this->input['client_id']);
|
||||
|
||||
return $expense->exists();
|
||||
|
||||
// $expense = Expense::where('client_id', $this->input['client_id'])
|
||||
// ->where('number', $this->input['number'])
|
||||
// ->withTrashed()
|
||||
// ->exists();
|
||||
|
||||
// if ($expense) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,9 @@ class PaymentAmountsBalanceRule implements Rule
|
||||
return true;
|
||||
} // if no invoices are present, then this is an unapplied payment, let this pass validation!
|
||||
|
||||
// info("payment amounts = {$payment_amounts}");
|
||||
// info("invoice amounts = {$invoice_amounts}");
|
||||
|
||||
return $payment_amounts >= $invoice_amounts;
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ class ValidProjectForClient implements Rule
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
if(empty($this->input['project_id']))
|
||||
return true;
|
||||
|
||||
if(is_string($this->input['project_id']))
|
||||
$this->input['project_id'] = $this->decodePrimaryKey($this->input['project_id']);
|
||||
|
||||
|
62
app/Http/ValidationRules/User/RelatedUserRule.php
Normal file
62
app/Http/ValidationRules/User/RelatedUserRule.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\ValidationRules\User;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Class RelatedUserRule.
|
||||
*/
|
||||
class RelatedUserRule implements Rule
|
||||
{
|
||||
public $input;
|
||||
|
||||
public function __construct($input)
|
||||
{
|
||||
$this->input = $input;
|
||||
}
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
return $this->checkUserIsRelated($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return 'User not associated with this account';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $email
|
||||
* @return bool
|
||||
*/
|
||||
private function checkUserIsRelated($user_id) : bool
|
||||
{
|
||||
|
||||
if(empty($user_id))
|
||||
return true;
|
||||
|
||||
return User::query()
|
||||
->where('id', $user_id)
|
||||
->where('account_id', auth()->user()->company()->account_id)
|
||||
->exists();
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ use App\DataMapper\Analytics\AccountCreated as AnalyticsAccountCreated;
|
||||
use App\Events\Account\AccountCreated;
|
||||
use App\Jobs\Company\CreateCompany;
|
||||
use App\Jobs\Company\CreateCompanyPaymentTerms;
|
||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Jobs\User\CreateUser;
|
||||
use App\Models\Account;
|
||||
@ -74,6 +75,7 @@ class CreateAccount
|
||||
$spaa9f78 = CreateUser::dispatchNow($this->request, $sp794f3f, $sp035a66, true);
|
||||
|
||||
CreateCompanyPaymentTerms::dispatchNow($sp035a66, $spaa9f78);
|
||||
CreateCompanyTaskStatuses::dispatchNow($sp035a66, $spaa9f78);
|
||||
|
||||
if ($spaa9f78) {
|
||||
auth()->login($spaa9f78, false);
|
||||
|
61
app/Jobs/Company/CreateCompanyTaskStatuses.php
Normal file
61
app/Jobs/Company/CreateCompanyTaskStatuses.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Company;
|
||||
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Events\UserSignedUp;
|
||||
use App\Models\Company;
|
||||
use App\Models\PaymentTerm;
|
||||
use App\Models\TaskStatus;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreateCompanyTaskStatuses
|
||||
{
|
||||
use MakesHash;
|
||||
use Dispatchable;
|
||||
|
||||
protected $company;
|
||||
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($company, $user)
|
||||
{
|
||||
$this->company = $company;
|
||||
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$task_statuses = [
|
||||
['name' => ctrans('texts.backlog'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now()],
|
||||
['name' => ctrans('texts.ready_to_do'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now()],
|
||||
['name' => ctrans('texts.in_progress'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now()],
|
||||
['name' => ctrans('texts.done'), 'company_id' => $this->company->id, 'user_id' => $this->user->id, 'created_at' => now(), 'updated_at' => now()],
|
||||
|
||||
];
|
||||
|
||||
TaskStatus::insert($task_statuses);
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Credit;
|
||||
|
||||
use App\Designs\Custom;
|
||||
use App\Designs\Designer;
|
||||
use App\Designs\Modern;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Design;
|
||||
use App\Models\Invoice;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\MakesInvoiceHtml;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Spatie\Browsershot\Browsershot;
|
||||
|
||||
class CreateCreditPdf implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml, PdfMaker, MakesHash;
|
||||
|
||||
public $credit;
|
||||
|
||||
public $company;
|
||||
|
||||
public $contact;
|
||||
|
||||
private $disk;
|
||||
|
||||
public $invitation;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invitation)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
|
||||
$this->credit = $invitation->credit;
|
||||
|
||||
$this->company = $invitation->company;
|
||||
|
||||
$this->contact = $invitation->contact;
|
||||
|
||||
$this->disk = $disk ?? config('filesystems.default');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
if (config('ninja.phantomjs_key')) {
|
||||
return (new Phantom)->generate($this->invitation);
|
||||
}
|
||||
|
||||
$this->credit->load('client');
|
||||
|
||||
App::setLocale($this->contact->preferredLocale());
|
||||
|
||||
$path = $this->credit->client->credit_filepath();
|
||||
|
||||
$file_path = $path.$this->credit->number.'.pdf';
|
||||
|
||||
$credit_design_id = $this->credit->design_id ? $this->credit->design_id : $this->decodePrimaryKey($this->credit->client->getSetting('credit_design_id'));
|
||||
|
||||
$design = Design::find($credit_design_id);
|
||||
|
||||
$designer = new Designer($this->credit, $design, $this->credit->client->getSetting('pdf_variables'), 'credit');
|
||||
|
||||
$html = (new HtmlEngine($designer, $this->invitation, 'credit'))->build();
|
||||
|
||||
Storage::makeDirectory($path, 0775);
|
||||
|
||||
$pdf = $this->makePdf(null, null, $html);
|
||||
|
||||
$instance = Storage::disk($this->disk)->put($file_path, $pdf);
|
||||
|
||||
return $file_path;
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Credit;
|
||||
|
||||
use App\Events\Credit\CreditWasEmailed;
|
||||
use App\Events\Credit\CreditWasEmailedAndFailed;
|
||||
use App\Jobs\Mail\BaseMailerJob;
|
||||
use App\Jobs\Mail\MailRouter;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\Company;
|
||||
use App\Models\Credit;
|
||||
use App\Models\SystemLog;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
/*Multi Mailer implemented*/
|
||||
class EmailCredit extends BaseMailerJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $credit;
|
||||
|
||||
public $message_array = [];
|
||||
|
||||
public $settings;
|
||||
|
||||
public $company;
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Credit $credit, Company $company)
|
||||
{
|
||||
$this->credit = $credit;
|
||||
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
//todo - change runtime config of mail driver if necessary
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
$this->settings = $this->credit->client->getMergedSettings();
|
||||
|
||||
$template_style = $this->credit->client->getSetting('email_style');
|
||||
|
||||
$this->setMailDriver();
|
||||
|
||||
$this->credit->invitations->each(function ($invitation) use ($template_style) {
|
||||
|
||||
if ($invitation->contact->send_email && $invitation->contact->email)
|
||||
{
|
||||
|
||||
$message_array = $this->credit->getEmailData('', $invitation->contact);
|
||||
$message_array['title'] = &$message_array['subject'];
|
||||
$message_array['footer'] = 'Sent to '.$invitation->contact->present()->name();
|
||||
|
||||
MailRouter::dispatch(new TemplateEmail($message_array, $template_style, $invitation->contact->user, $invitation->contact->client), $invitation->company, $invitation->contact);
|
||||
|
||||
//fire any events
|
||||
event(new CreditWasEmailed($this->credit, $this->company, Ninja::eventVars()));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private function logMailError($errors)
|
||||
{
|
||||
SystemLogger::dispatch(
|
||||
$errors,
|
||||
SystemLog::CATEGORY_MAIL,
|
||||
SystemLog::EVENT_MAIL_SEND,
|
||||
SystemLog::TYPE_FAILURE,
|
||||
$this->credit->client
|
||||
);
|
||||
}
|
||||
}
|
@ -54,7 +54,7 @@ class RecurringInvoicesCron
|
||||
|
||||
info("Current date = " . now()->format("Y-m-d") . " Recurring date = " .$recurring_invoice->next_send_date);
|
||||
|
||||
SendRecurring::dispatch($recurring_invoice, $recurring_invoice->company->db);
|
||||
SendRecurring::dispatchNow($recurring_invoice, $recurring_invoice->company->db);
|
||||
|
||||
});
|
||||
|
||||
@ -74,7 +74,7 @@ class RecurringInvoicesCron
|
||||
|
||||
info("Current date = " . now()->format("Y-m-d") . " Recurring date = " .$recurring_invoice->next_send_date);
|
||||
|
||||
SendRecurring::dispatch($recurring_invoice, $recurring_invoice->company->db);
|
||||
SendRecurring::dispatchNow($recurring_invoice, $recurring_invoice->company->db);
|
||||
|
||||
});
|
||||
}
|
||||
|
166
app/Jobs/Entity/CreateEntityPdf.php
Normal file
166
app/Jobs/Entity/CreateEntityPdf.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Entity Ninja (https://entityninja.com).
|
||||
*
|
||||
* @link https://github.com/entityninja/entityninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Entity Ninja LLC (https://entityninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Entity;
|
||||
|
||||
use App\Designs\Custom;
|
||||
use App\Designs\Designer;
|
||||
use App\Designs\Modern;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Credit;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\Design;
|
||||
use App\Models\Entity;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\Quote;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Services\PdfMaker\Design as PdfDesignModel;
|
||||
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
||||
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\MakesInvoiceHtml;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Spatie\Browsershot\Browsershot;
|
||||
|
||||
class CreateEntityPdf implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml, PdfMaker, MakesHash;
|
||||
|
||||
public $entity;
|
||||
|
||||
public $company;
|
||||
|
||||
public $contact;
|
||||
|
||||
private $disk;
|
||||
|
||||
public $invitation;
|
||||
|
||||
public $entity_string = '';
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invitation)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
|
||||
if($invitation instanceof InvoiceInvitation){
|
||||
$this->entity = $invitation->invoice;
|
||||
$this->entity_string = 'invoice';
|
||||
}
|
||||
elseif($invitation instanceof QuoteInvitation){
|
||||
$this->entity = $invitation->quote;
|
||||
$this->entity_string = 'quote';
|
||||
}
|
||||
elseif($invitation instanceof CreditInvitation){
|
||||
$this->entity = $invitation->credit;
|
||||
$this->entity_string = 'credit';
|
||||
}
|
||||
elseif($invitation instanceof RecurringInvoiceInvitation){
|
||||
$this->entity = $invitation->recurring_invoice;
|
||||
$this->entity_string = 'recurring_invoice';
|
||||
}
|
||||
|
||||
$this->company = $invitation->company;
|
||||
|
||||
$this->contact = $invitation->contact;
|
||||
|
||||
$this->disk = $disk ?? config('filesystems.default');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
|
||||
if (config('ninja.phantomjs_key')) {
|
||||
return (new Phantom)->generate($this->invitation);
|
||||
}
|
||||
|
||||
App::setLocale($this->contact->preferredLocale());
|
||||
|
||||
$entity_design_id = '';
|
||||
|
||||
if($this->entity instanceof Invoice){
|
||||
$path = $this->entity->client->invoice_filepath();
|
||||
$entity_design_id = 'invoice_design_id';
|
||||
}
|
||||
elseif($this->entity instanceof Quote){
|
||||
$path = $this->entity->client->quote_filepath();
|
||||
$entity_design_id = 'quote_design_id';
|
||||
}
|
||||
elseif($this->entity instanceof Credit){
|
||||
$path = $this->entity->client->credit_filepath();
|
||||
$entity_design_id = 'credit_design_id';
|
||||
}
|
||||
|
||||
$file_path = $path.$this->entity->number.'.pdf';
|
||||
|
||||
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->entity->client->getSetting($entity_design_id));
|
||||
|
||||
$design = Design::find($entity_design_id);
|
||||
$html = new HtmlEngine($this->invitation);
|
||||
|
||||
if ($design->is_custom) {
|
||||
$options = [
|
||||
'custom_partials' => json_decode(json_encode($design->design), true)
|
||||
];
|
||||
$template = new PdfMakerDesign(PdfDesignModel::CUSTOM, $options);
|
||||
} else {
|
||||
$template = new PdfMakerDesign(strtolower($design->name));
|
||||
}
|
||||
|
||||
$state = [
|
||||
'template' => $template->elements([
|
||||
'client' => $this->entity->client,
|
||||
'entity' => $this->entity,
|
||||
'pdf_variables' => (array) $this->entity->company->settings->pdf_variables,
|
||||
'products' => $design->design->product,
|
||||
]),
|
||||
'variables' => $html->generateLabelsAndValues(),
|
||||
'options' => [
|
||||
'all_pages_header' => $this->entity->client->getSetting('all_pages_header'),
|
||||
'all_pages_footer' => $this->entity->client->getSetting('all_pages_footer'),
|
||||
],
|
||||
];
|
||||
|
||||
$maker = new PdfMakerService($state);
|
||||
|
||||
$maker
|
||||
->design($template)
|
||||
->build();
|
||||
|
||||
//todo - move this to the client creation stage so we don't keep hitting this unnecessarily
|
||||
Storage::makeDirectory($path, 0775);
|
||||
|
||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
||||
|
||||
$instance = Storage::disk($this->disk)->put($file_path, $pdf);
|
||||
|
||||
return $file_path;
|
||||
}
|
||||
}
|
187
app/Jobs/Entity/EmailEntity.php
Normal file
187
app/Jobs/Entity/EmailEntity.php
Normal file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Entity;
|
||||
|
||||
use App\DataMapper\Analytics\EmailInvoiceFailure;
|
||||
use App\Events\Invoice\InvoiceWasEmailed;
|
||||
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
|
||||
use App\Helpers\Email\InvoiceEmail;
|
||||
use App\Jobs\Mail\BaseMailerJob;
|
||||
use App\Jobs\Utils\SystemLogger;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\TemplateEmail;
|
||||
use App\Models\Company;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Models\SystemLog;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Mime\Test\Constraint\EmailTextBodyContains;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
|
||||
/*Multi Mailer implemented*/
|
||||
|
||||
class EmailEntity extends BaseMailerJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $invitation;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public $entity_string;
|
||||
|
||||
public $reminder_template;
|
||||
|
||||
public $entity;
|
||||
|
||||
public $html_engine;
|
||||
|
||||
public $email_entity_builder;
|
||||
|
||||
/**
|
||||
* EmailEntity constructor.
|
||||
* @param Invitation $invitation
|
||||
* @param Company $company
|
||||
* @param ?string $reminder_template
|
||||
*/
|
||||
public function __construct($invitation, Company $company, ?string $reminder_template = null)
|
||||
{
|
||||
$this->company = $company;
|
||||
|
||||
$this->invitation = $invitation;
|
||||
|
||||
$this->settings = $invitation->contact->client->getMergedSettings();
|
||||
|
||||
$this->entity_string = $this->resolveEntityString();
|
||||
|
||||
$this->entity = $invitation->{$this->entity_string};
|
||||
|
||||
$this->reminder_template = $reminder_template ?: $this->findReminderTemplate();
|
||||
|
||||
$this->html_engine = new HtmlEngine($invitation);
|
||||
|
||||
$this->email_entity_builder = $this->resolveEmailBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
MultiDB::setDB($this->company->db);
|
||||
|
||||
$this->setMailDriver();
|
||||
|
||||
try {
|
||||
Mail::to($this->invitation->contact->email, $this->invitation->contact->present()->name())
|
||||
->send(
|
||||
new TemplateEmail(
|
||||
$this->email_entity_builder,
|
||||
$this->invitation->contact->user,
|
||||
$this->invitation->contact->client
|
||||
)
|
||||
);
|
||||
} catch (\Swift_TransportException $e) {
|
||||
$this->entityEmailFailed($e->getMessage());
|
||||
}
|
||||
|
||||
if (count(Mail::failures()) > 0) {
|
||||
$this->logMailError(Mail::failures(), $this->entity->client);
|
||||
} else {
|
||||
$this->entityEmailSucceeded();
|
||||
}
|
||||
|
||||
/* Mark entity sent */
|
||||
$this->entity->service()->markSent()->save();
|
||||
}
|
||||
|
||||
public function failed($exception = null)
|
||||
{
|
||||
info('the job failed');
|
||||
|
||||
$job_failure = new EmailInvoiceFailure();
|
||||
$job_failure->string_metric5 = $this->entity_string;
|
||||
$job_failure->string_metric6 = $exception->getMessage();
|
||||
|
||||
LightLogs::create($job_failure)
|
||||
->batch();
|
||||
|
||||
}
|
||||
|
||||
private function resolveEntityString() :string
|
||||
{
|
||||
if($this->invitation instanceof InvoiceInvitation)
|
||||
return 'invoice';
|
||||
elseif($this->invitation instanceof QuoteInvitation)
|
||||
return 'quote';
|
||||
elseif($this->invitation instanceof CreditInvitation)
|
||||
return 'credit';
|
||||
elseif($this->invitation instanceof RecurringInvoiceInvitation)
|
||||
return 'recurring_invoice';
|
||||
}
|
||||
|
||||
private function entityEmailFailed($message)
|
||||
{
|
||||
switch ($this->entity_string) {
|
||||
case 'invoice':
|
||||
event(new InvoiceWasEmailedAndFailed($this->invitation->invoice, $this->company, $message, Ninja::eventVars()));
|
||||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function entityEmailSucceeded()
|
||||
{
|
||||
switch ($this->entity_string) {
|
||||
case 'invoice':
|
||||
event(new InvoiceWasEmailed($this->invitation, $this->company, Ninja::eventVars()));
|
||||
break;
|
||||
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function findReminderTemplate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private function resolveEmailBuilder()
|
||||
{
|
||||
$class = 'App\Mail\Engine\\' . ucfirst(Str::camel($this->entity_string)) . "EmailEngine";
|
||||
|
||||
return (new $class($this->invitation, $this->reminder_template))->build();
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Invoice;
|
||||
|
||||
use App\Designs\Custom;
|
||||
use App\Designs\Designer;
|
||||
use App\Designs\Modern;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Company;
|
||||
use App\Models\Design;
|
||||
use App\Models\Invoice;
|
||||
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
||||
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
|
||||
use App\Utils\HtmlEngine;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\MakesInvoiceHtml;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Spatie\Browsershot\Browsershot;
|
||||
|
||||
class CreateInvoicePdf implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, NumberFormatter, MakesInvoiceHtml, PdfMaker, MakesHash;
|
||||
|
||||
public $invoice;
|
||||
|
||||
public $company;
|
||||
|
||||
public $contact;
|
||||
|
||||
private $disk;
|
||||
|
||||
public $invitation;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invitation)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
|
||||
$this->invoice = $invitation->invoice;
|
||||
|
||||
$this->company = $invitation->company;
|
||||
|
||||
$this->contact = $invitation->contact;
|
||||
|
||||
$this->disk = $disk ?? config('filesystems.default');
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
|
||||
if (config('ninja.phantomjs_key')) {
|
||||
return (new Phantom)->generate($this->invitation);
|
||||
}
|
||||
|
||||
App::setLocale($this->contact->preferredLocale());
|
||||
|
||||
$path = $this->invoice->client->invoice_filepath();
|
||||
|
||||
$file_path = $path.$this->invoice->number.'.pdf';
|
||||
|
||||
$invoice_design_id = $this->invoice->design_id ? $this->invoice->design_id : $this->decodePrimaryKey($this->invoice->client->getSetting('invoice_design_id'));
|
||||
|
||||
$design = Design::find($invoice_design_id);
|
||||
$html = new HtmlEngine(null, $this->invitation, 'invoice');
|
||||
|
||||
$template = new PdfMakerDesign(strtolower($design->name));
|
||||
|
||||
$state = [
|
||||
'template' => $template->elements([
|
||||
'client' => $this->invoice->client,
|
||||
'entity' => $this->invoice,
|
||||
'pdf_variables' => (array) $this->invoice->company->settings->pdf_variables,
|
||||
'products' => $design->design->product,
|
||||
]),
|
||||
'variables' => $html->generateLabelsAndValues(),
|
||||
'options' => [
|
||||
'all_pages_header' => $this->invoice->client->getSetting('all_pages_header'),
|
||||
'all_pages_footer' => $this->invoice->client->getSetting('all_pages_footer'),
|
||||
],
|
||||
];
|
||||
|
||||
$maker = new PdfMakerService($state);
|
||||
|
||||
$maker
|
||||
->design($template)
|
||||
->build();
|
||||
|
||||
//todo - move this to the client creation stage so we don't keep hitting this unnecessarily
|
||||
Storage::makeDirectory($path, 0775);
|
||||
|
||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
||||
|
||||
$instance = Storage::disk($this->disk)->put($file_path, $pdf);
|
||||
|
||||
return $file_path;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user