mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
f8d861bcdd
@ -1 +1 @@
|
|||||||
5.7.46
|
5.7.54
|
@ -85,7 +85,7 @@ class BackupUpdate extends Command
|
|||||||
->each(function ($company) {
|
->each(function ($company) {
|
||||||
$company_logo_path = $company->settings->company_logo;
|
$company_logo_path = $company->settings->company_logo;
|
||||||
|
|
||||||
if ($company_logo_path == 'https://invoicing.co/images/new_logo.png' || $company_logo_path == '') {
|
if ($company_logo_path == config('ninja.app_logo') || $company_logo_path == '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,7 +977,7 @@ class CheckData extends Command
|
|||||||
$cc = ClientContact::on('db-ninja-01')->where('company_id', config('ninja.ninja_default_company_id'))->where('email', $cu->user->email)->first();
|
$cc = ClientContact::on('db-ninja-01')->where('company_id', config('ninja.ninja_default_company_id'))->where('email', $cu->user->email)->first();
|
||||||
|
|
||||||
if ($cc) {
|
if ($cc) {
|
||||||
$ninja_portal_url = "https://invoiceninja.invoicing.co/client/ninja/{$cc->contact_key}/{$cu->account->key}";
|
$ninja_portal_url = config('ninja.ninja_client_portal')."/client/ninja/{$cc->contact_key}/{$cu->account->key}";
|
||||||
|
|
||||||
$cu->ninja_portal_url = $ninja_portal_url;
|
$cu->ninja_portal_url = $ninja_portal_url;
|
||||||
$cu->save();
|
$cu->save();
|
||||||
@ -990,7 +990,7 @@ class CheckData extends Command
|
|||||||
$cc = $c->contacts()->first();
|
$cc = $c->contacts()->first();
|
||||||
|
|
||||||
if ($cc) {
|
if ($cc) {
|
||||||
$ninja_portal_url = "https://invoiceninja.invoicing.co/client/ninja/{$cc->contact_key}/{$cu->account->key}";
|
$ninja_portal_url = config('ninja.ninja_client_portal')."/client/ninja/{$cc->contact_key}/{$cu->account->key}";
|
||||||
|
|
||||||
$cu->ninja_portal_url = $ninja_portal_url;
|
$cu->ninja_portal_url = $ninja_portal_url;
|
||||||
$cu->save();
|
$cu->save();
|
||||||
|
@ -11,52 +11,54 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\DataMapper\ClientRegistrationFields;
|
use stdClass;
|
||||||
use App\DataMapper\CompanySettings;
|
use Carbon\Carbon;
|
||||||
use App\DataMapper\FeesAndLimits;
|
use Faker\Factory;
|
||||||
use App\Events\Invoice\InvoiceWasCreated;
|
use App\Models\Task;
|
||||||
use App\Events\RecurringInvoice\RecurringInvoiceWasCreated;
|
use App\Models\User;
|
||||||
use App\Factory\GroupSettingFactory;
|
use App\Utils\Ninja;
|
||||||
use App\Factory\InvoiceFactory;
|
use App\Models\Quote;
|
||||||
use App\Factory\InvoiceItemFactory;
|
|
||||||
use App\Factory\RecurringInvoiceFactory;
|
|
||||||
use App\Factory\SubscriptionFactory;
|
|
||||||
use App\Helpers\Invoice\InvoiceSum;
|
|
||||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\Account;
|
|
||||||
use App\Models\BankIntegration;
|
|
||||||
use App\Models\BankTransaction;
|
|
||||||
use App\Models\BankTransactionRule;
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
|
||||||
use App\Models\Company;
|
|
||||||
use App\Models\CompanyGateway;
|
|
||||||
use App\Models\CompanyToken;
|
|
||||||
use App\Models\Country;
|
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\Account;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\Country;
|
||||||
use App\Models\Expense;
|
use App\Models\Expense;
|
||||||
|
use App\Models\Gateway;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Quote;
|
|
||||||
use App\Models\RecurringInvoice;
|
|
||||||
use App\Models\Task;
|
|
||||||
use App\Models\TaxRate;
|
use App\Models\TaxRate;
|
||||||
use App\Models\User;
|
use App\Libraries\MultiDB;
|
||||||
use App\Models\Vendor;
|
use App\Models\TaskStatus;
|
||||||
|
use App\Models\CompanyToken;
|
||||||
|
use App\Models\ClientContact;
|
||||||
use App\Models\VendorContact;
|
use App\Models\VendorContact;
|
||||||
use App\Repositories\InvoiceRepository;
|
use App\Models\CompanyGateway;
|
||||||
use App\Utils\Ninja;
|
use App\Factory\InvoiceFactory;
|
||||||
use App\Utils\Traits\GeneratesCounter;
|
use App\Models\BankIntegration;
|
||||||
|
use App\Models\BankTransaction;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Carbon\Carbon;
|
|
||||||
use Faker\Factory;
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use App\Models\RecurringInvoice;
|
||||||
|
use App\DataMapper\FeesAndLimits;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\Factory\InvoiceItemFactory;
|
||||||
|
use App\Helpers\Invoice\InvoiceSum;
|
||||||
|
use App\Models\BankTransactionRule;
|
||||||
|
use App\Factory\GroupSettingFactory;
|
||||||
|
use App\Factory\SubscriptionFactory;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
use stdClass;
|
use App\Repositories\InvoiceRepository;
|
||||||
|
use App\Factory\RecurringInvoiceFactory;
|
||||||
|
use App\Events\Invoice\InvoiceWasCreated;
|
||||||
|
use App\DataMapper\ClientRegistrationFields;
|
||||||
|
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||||
|
use App\Events\RecurringInvoice\RecurringInvoiceWasCreated;
|
||||||
|
|
||||||
class CreateSingleAccount extends Command
|
class CreateSingleAccount extends Command
|
||||||
{
|
{
|
||||||
@ -72,6 +74,7 @@ class CreateSingleAccount extends Command
|
|||||||
|
|
||||||
protected $gateway;
|
protected $gateway;
|
||||||
|
|
||||||
|
public $faker;
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
@ -79,6 +82,8 @@ class CreateSingleAccount extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
$this->faker = Factory::create();
|
||||||
|
|
||||||
if (Ninja::isHosted() || config('ninja.is_docker') || !$this->confirm('Are you sure you want to inject dummy data?')) {
|
if (Ninja::isHosted() || config('ninja.is_docker') || !$this->confirm('Are you sure you want to inject dummy data?')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -503,19 +508,61 @@ class CreateSingleAccount extends Command
|
|||||||
|
|
||||||
private function createTask($client)
|
private function createTask($client)
|
||||||
{
|
{
|
||||||
$vendor = Task::factory()->create([
|
$time_log = $this->createTimeLog(rand(1,20));
|
||||||
|
$status = TaskStatus::where('company_id', $client->company_id)->get()->random();
|
||||||
|
|
||||||
|
return Task::factory()->create([
|
||||||
'user_id' => $client->user->id,
|
'user_id' => $client->user->id,
|
||||||
'company_id' => $client->company->id,
|
'company_id' => $client->company->id,
|
||||||
|
'time_log' => $time_log,
|
||||||
|
'description' => $this->faker->paragraph,
|
||||||
|
'status_id' => $status->id ?? null,
|
||||||
|
'number' => rand(10000,100000000),
|
||||||
|
'rate' => rand(1,150),
|
||||||
|
'client_id' => $client->id
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createTimeLog(int $count)
|
||||||
|
{
|
||||||
|
$time_log = [];
|
||||||
|
|
||||||
|
$min = 0;
|
||||||
|
|
||||||
|
for ($x = 0; $x < $count; $x++) {
|
||||||
|
|
||||||
|
$rando = rand(300, 87000);
|
||||||
|
|
||||||
|
$time_log[] = [
|
||||||
|
Carbon::now()->addSeconds($min)->timestamp,
|
||||||
|
Carbon::now()->addSeconds($min += $rando)->timestamp,
|
||||||
|
$this->faker->sentence,
|
||||||
|
rand(0,1) === 0 ? false : true
|
||||||
|
];
|
||||||
|
|
||||||
|
$min += 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($time_log);
|
||||||
|
}
|
||||||
|
|
||||||
private function createProject($client)
|
private function createProject($client)
|
||||||
{
|
{
|
||||||
$vendor = Project::factory()->create([
|
$project = Project::factory()->create([
|
||||||
'user_id' => $client->user->id,
|
'user_id' => $client->user->id,
|
||||||
'company_id' => $client->company->id,
|
'company_id' => $client->company->id,
|
||||||
'client_id' => $client->id,
|
'client_id' => $client->id,
|
||||||
|
'due_date' => now()->addSeconds(rand(100000,1000000))->format('Y-m-d'),
|
||||||
|
'budgeted_hours' => rand(100,1000),
|
||||||
|
'task_rate' => rand(1,200),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
for($x=0; $x < rand(2, 5); $x++) {
|
||||||
|
$task = $this->createTask($client);
|
||||||
|
$task->project_id = $project->id;
|
||||||
|
$task->save();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createInvoice($client)
|
private function createInvoice($client)
|
||||||
@ -559,6 +606,7 @@ class CreateSingleAccount extends Command
|
|||||||
$invoice->amount = 100; // Braintree sandbox only allows payments under 2,000 to complete successfully.
|
$invoice->amount = 100; // Braintree sandbox only allows payments under 2,000 to complete successfully.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var \App\Models\Invoice $invoice */
|
||||||
$invoice->save();
|
$invoice->save();
|
||||||
$invoice->service()->createInvitations()->markSent();
|
$invoice->service()->createInvitations()->markSent();
|
||||||
|
|
||||||
@ -586,6 +634,7 @@ class CreateSingleAccount extends Command
|
|||||||
|
|
||||||
$credit = $invoice_calc->getCredit();
|
$credit = $invoice_calc->getCredit();
|
||||||
|
|
||||||
|
/** @var \App\Models\Credit $credit */
|
||||||
$credit->save();
|
$credit->save();
|
||||||
$credit->service()->markSent()->save();
|
$credit->service()->markSent()->save();
|
||||||
$credit->service()->createInvitations();
|
$credit->service()->createInvitations();
|
||||||
@ -628,6 +677,7 @@ class CreateSingleAccount extends Command
|
|||||||
|
|
||||||
$quote->save();
|
$quote->save();
|
||||||
|
|
||||||
|
/** @var \App\Models\Quote $quote */
|
||||||
$quote->service()->markSent()->save();
|
$quote->service()->markSent()->save();
|
||||||
$quote->service()->createInvitations();
|
$quote->service()->createInvitations();
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ class MobileLocalization extends Command
|
|||||||
|
|
||||||
private function laravelResources()
|
private function laravelResources()
|
||||||
{
|
{
|
||||||
$resources = $this->getResources();
|
$resources =(array)$this->getResources();
|
||||||
|
|
||||||
if(is_iterable($resources)){
|
if(is_iterable($resources)){
|
||||||
foreach ($resources as $key => $val) {
|
foreach ($resources as $key => $val) {
|
||||||
|
@ -229,7 +229,7 @@ class CompanySettings extends BaseSettings
|
|||||||
public $require_quote_signature = false; //@TODO ben to confirm
|
public $require_quote_signature = false; //@TODO ben to confirm
|
||||||
|
|
||||||
//email settings
|
//email settings
|
||||||
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun'//@implemented
|
public $email_sending_method = 'default'; //enum 'default','gmail','office365' 'client_postmark', 'client_mailgun' //@implemented
|
||||||
|
|
||||||
public $gmail_sending_user_id = '0'; //@implemented
|
public $gmail_sending_user_id = '0'; //@implemented
|
||||||
|
|
||||||
@ -491,7 +491,10 @@ class CompanySettings extends BaseSettings
|
|||||||
|
|
||||||
public $classification = ''; // individual, business, partnership, trust, charity, government, other
|
public $classification = ''; // individual, business, partnership, trust, charity, government, other
|
||||||
|
|
||||||
|
public $payment_email_all_contacts = false;
|
||||||
|
|
||||||
public static $casts = [
|
public static $casts = [
|
||||||
|
'payment_email_all_contacts' => 'bool',
|
||||||
'statement_design_id' => 'string',
|
'statement_design_id' => 'string',
|
||||||
'delivery_note_design_id' => 'string',
|
'delivery_note_design_id' => 'string',
|
||||||
'payment_receipt_design_id' => 'string',
|
'payment_receipt_design_id' => 'string',
|
||||||
|
@ -92,6 +92,11 @@ class EmailTemplateDefaults
|
|||||||
case 'email_subject_custom3':
|
case 'email_subject_custom3':
|
||||||
return self::emailInvoiceSubject();
|
return self::emailInvoiceSubject();
|
||||||
|
|
||||||
|
case 'email_vendor_notification_subject':
|
||||||
|
return self::emailVendorNotificationSubject();
|
||||||
|
|
||||||
|
case 'email_vendor_notification_body':
|
||||||
|
return self::emailVendorNotificationBody();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return self::emailInvoiceTemplate();
|
return self::emailInvoiceTemplate();
|
||||||
@ -99,6 +104,16 @@ class EmailTemplateDefaults
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function emailVendorNotificationSubject()
|
||||||
|
{
|
||||||
|
return self::transformText('vendor_notification_subject');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function emailVendorNotificationBody()
|
||||||
|
{
|
||||||
|
return self::transformText('vendor_notification_body');
|
||||||
|
}
|
||||||
|
|
||||||
public static function emailInvoiceSubject()
|
public static function emailInvoiceSubject()
|
||||||
{
|
{
|
||||||
return ctrans('texts.invoice_subject', ['number'=>'$number', 'account'=>'$company.name']);
|
return ctrans('texts.invoice_subject', ['number'=>'$number', 'account'=>'$company.name']);
|
||||||
|
@ -628,11 +628,11 @@ class BaseExport
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(in_array($column, ['client.user_id', 'user_id'])) {
|
if(in_array($column, ['client.user_id', 'user_id'])) {
|
||||||
return $entity->client->user->present()->name();
|
return $entity->client->user ? $entity->client->user->present()->name() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array($column, ['client.assigned_user_id', 'assigned_user_id'])) {
|
if(in_array($column, ['client.assigned_user_id', 'assigned_user_id'])) {
|
||||||
return $entity->client->assigned_user->present()->name();
|
return $entity->client->assigned_user ? $entity->client->assigned_user->present()->name() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array($column, ['client.country_id', 'country_id'])) {
|
if(in_array($column, ['client.country_id', 'country_id'])) {
|
||||||
|
@ -11,16 +11,17 @@
|
|||||||
|
|
||||||
namespace App\Export\CSV;
|
namespace App\Export\CSV;
|
||||||
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\Client;
|
|
||||||
use App\Models\Company;
|
|
||||||
use App\Transformers\ClientContactTransformer;
|
|
||||||
use App\Transformers\ClientTransformer;
|
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Number;
|
use App\Utils\Number;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use App\Models\Client;
|
||||||
use Illuminate\Support\Facades\App;
|
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use App\Export\Decorators\Decorator;
|
||||||
|
use App\Transformers\ClientTransformer;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use App\Transformers\ClientContactTransformer;
|
||||||
|
|
||||||
class ClientExport extends BaseExport
|
class ClientExport extends BaseExport
|
||||||
{
|
{
|
||||||
@ -32,6 +33,8 @@ class ClientExport extends BaseExport
|
|||||||
|
|
||||||
public string $date_key = 'created_at';
|
public string $date_key = 'created_at';
|
||||||
|
|
||||||
|
private Decorator $decorator;
|
||||||
|
|
||||||
public array $entity_keys = [
|
public array $entity_keys = [
|
||||||
'address1' => 'client.address1',
|
'address1' => 'client.address1',
|
||||||
'address2' => 'client.address2',
|
'address2' => 'client.address2',
|
||||||
@ -84,6 +87,8 @@ class ClientExport extends BaseExport
|
|||||||
$this->input = $input;
|
$this->input = $input;
|
||||||
$this->client_transformer = new ClientTransformer();
|
$this->client_transformer = new ClientTransformer();
|
||||||
$this->contact_transformer = new ClientContactTransformer();
|
$this->contact_transformer = new ClientContactTransformer();
|
||||||
|
$this->decorator = new Decorator();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function returnJson()
|
public function returnJson()
|
||||||
|
@ -177,6 +177,14 @@ class CreditExport extends BaseExport
|
|||||||
$entity['credit.status'] = $credit->stringStatus($credit->status_id);
|
$entity['credit.status'] = $credit->stringStatus($credit->status_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('credit.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['credit.assigned_user_id'] = $credit->assigned_user ? $credit->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('credit.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['credit.user_id'] = $credit->user ? $credit->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,14 @@ class InvoiceExport extends BaseExport
|
|||||||
$entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
$entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,13 @@ class InvoiceItemExport extends BaseExport
|
|||||||
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
|
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
|
|
||||||
namespace App\Export\CSV;
|
namespace App\Export\CSV;
|
||||||
|
|
||||||
use App\Libraries\MultiDB;
|
use App\Utils\Ninja;
|
||||||
|
use League\Csv\Writer;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Transformers\PaymentTransformer;
|
use App\Libraries\MultiDB;
|
||||||
use App\Utils\Ninja;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use League\Csv\Writer;
|
use App\Transformers\PaymentTransformer;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use App\Export\Decorators\Decorator;
|
||||||
|
|
||||||
class PaymentExport extends BaseExport
|
class PaymentExport extends BaseExport
|
||||||
{
|
{
|
||||||
@ -28,11 +29,14 @@ class PaymentExport extends BaseExport
|
|||||||
|
|
||||||
public Writer $csv;
|
public Writer $csv;
|
||||||
|
|
||||||
|
private Decorator $decorator;
|
||||||
|
|
||||||
public function __construct(Company $company, array $input)
|
public function __construct(Company $company, array $input)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
$this->input = $input;
|
$this->input = $input;
|
||||||
$this->entity_transformer = new PaymentTransformer();
|
$this->entity_transformer = new PaymentTransformer();
|
||||||
|
$this->decorator = new Decorator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function init(): Builder
|
private function init(): Builder
|
||||||
@ -113,6 +117,8 @@ class PaymentExport extends BaseExport
|
|||||||
} elseif (array_key_exists($key, $transformed_entity)) {
|
} elseif (array_key_exists($key, $transformed_entity)) {
|
||||||
$entity[$key] = $transformed_entity[$key];
|
$entity[$key] = $transformed_entity[$key];
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// $entity[$key] = $this->decorator->transform($key, $payment);
|
||||||
$entity[$key] = $this->resolveKey($key, $payment, $this->entity_transformer);
|
$entity[$key] = $this->resolveKey($key, $payment, $this->entity_transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +173,14 @@ class PaymentExport extends BaseExport
|
|||||||
$entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
|
$entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('payment.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['payment.assigned_user_id'] = $payment->assigned_user ? $payment->assigned_user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('payment.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['payment.user_id'] = $payment->user ? $payment->user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
// $entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
|
// $entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
|
@ -149,6 +149,15 @@ class QuoteExport extends BaseExport
|
|||||||
$entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
$entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +199,16 @@ class QuoteItemExport extends BaseExport
|
|||||||
$entity['status'] = $quote->stringStatus($quote->status_id);
|
$entity['status'] = $quote->stringStatus($quote->status_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,15 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
$entity['recurring_invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
$entity['recurring_invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('recurring_invoice.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['recurring_invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('recurring_invoice.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['recurring_invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
175
app/Export/Decorators/ClientDecorator.php
Normal file
175
app/Export/Decorators/ClientDecorator.php
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
use App\Models\Client;
|
||||||
|
|
||||||
|
class ClientDecorator extends Decorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
private $entity_key = 'client';
|
||||||
|
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
$client = false;
|
||||||
|
|
||||||
|
if($entity instanceof Client){
|
||||||
|
$client = $entity;
|
||||||
|
}
|
||||||
|
elseif($entity->client) {
|
||||||
|
$client = $entity->client;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($client && method_exists($this, $key)) {
|
||||||
|
return $this->{$key}($client);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function name(Client $client) {
|
||||||
|
return $client->present()->name();
|
||||||
|
}
|
||||||
|
public function number(Client $client) {
|
||||||
|
return $client->number ?? '';
|
||||||
|
}
|
||||||
|
public function user(Client $client) {
|
||||||
|
return $client->user->present()->name();
|
||||||
|
}
|
||||||
|
public function assigned_user(Client $client) {
|
||||||
|
return $client->assigned_user ? $client->user->present()->name() : '';
|
||||||
|
}
|
||||||
|
public function balance(Client $client) {
|
||||||
|
return $client->balance ?? 0;
|
||||||
|
}
|
||||||
|
public function paid_to_date(Client $client) {
|
||||||
|
return $client->paid_to_date ?? 0;
|
||||||
|
}
|
||||||
|
public function currency_id(Client $client) {
|
||||||
|
return $client->currency() ? $client->currency()->code : $client->company->currency()->code;
|
||||||
|
}
|
||||||
|
public function website(Client $client) {
|
||||||
|
return $client->website ?? '';
|
||||||
|
}
|
||||||
|
public function private_notes(Client $client) {
|
||||||
|
return $client->private_notes ?? '';
|
||||||
|
}
|
||||||
|
public function industry_id(Client $client) {
|
||||||
|
return $client->industry ? ctrans("texts.industry_{$client->industry->name}") : '';
|
||||||
|
}
|
||||||
|
public function size_id(Client $client) {
|
||||||
|
return $client->size ? ctrans("texts.size_{$client->size->name}") : '';
|
||||||
|
}
|
||||||
|
public function phone(Client $client) {
|
||||||
|
return $client->phone ?? '';
|
||||||
|
}
|
||||||
|
public function address1(Client $client) {
|
||||||
|
return $client->address1 ?? '';
|
||||||
|
}
|
||||||
|
public function address2(Client $client) {
|
||||||
|
return $client->address2 ?? '';
|
||||||
|
}
|
||||||
|
public function city(Client $client) {
|
||||||
|
return $client->city ?? '';
|
||||||
|
}
|
||||||
|
public function state(Client $client) {
|
||||||
|
return $client->state ?? '';
|
||||||
|
}
|
||||||
|
public function postal_code(Client $client) {
|
||||||
|
return $client->postal_code ?? '';
|
||||||
|
}
|
||||||
|
public function country_id(Client $client) {
|
||||||
|
return $client->country ? ctrans("texts.country_{$client->country->name}") : '';
|
||||||
|
}
|
||||||
|
public function shipping_address1(Client $client) {
|
||||||
|
return $client->shipping_address1 ?? '';
|
||||||
|
}
|
||||||
|
public function shipping_address2(Client $client) {
|
||||||
|
return $client->shipping_address2 ?? '';
|
||||||
|
}
|
||||||
|
public function shipping_city(Client $client) {
|
||||||
|
return $client->shipping_city ?? '';
|
||||||
|
}
|
||||||
|
public function shipping_state(Client $client) {
|
||||||
|
return $client->shipping_state ?? '';
|
||||||
|
}
|
||||||
|
public function shipping_postal_code(Client $client) {
|
||||||
|
return $client->shipping_postal_code ?? '';
|
||||||
|
}
|
||||||
|
public function shipping_country_id(Client $client) {
|
||||||
|
return $client->shipping_country ? ctrans("texts.country_{$client->shipping_country->name}") : '';
|
||||||
|
}
|
||||||
|
public function payment_terms(Client $client) {
|
||||||
|
return $client?->settings?->payment_terms ?? $client->company->settings->payment_terms;
|
||||||
|
}
|
||||||
|
public function vat_number(Client $client) {
|
||||||
|
return $client->vat_number ?? '';
|
||||||
|
}
|
||||||
|
public function id_number(Client $client) {
|
||||||
|
return $client->id_number ?? '';
|
||||||
|
}
|
||||||
|
public function public_notes(Client $client) {
|
||||||
|
return $client->public_notes ?? '';
|
||||||
|
}
|
||||||
|
public function custom_value1(Client $client) {
|
||||||
|
return $client->custom_value1 ?? '';
|
||||||
|
}
|
||||||
|
public function custom_value2(Client $client) {
|
||||||
|
return $client->custom_value2 ?? '';
|
||||||
|
}
|
||||||
|
public function custom_value3(Client $client) {
|
||||||
|
return $client->custom_value3 ?? '';
|
||||||
|
}
|
||||||
|
public function custom_value4(Client $client) {
|
||||||
|
return $client->custom_value4 ?? '';
|
||||||
|
}
|
||||||
|
public function payment_balance(Client $client) {
|
||||||
|
return $client->payment_balance ?? 0;
|
||||||
|
}
|
||||||
|
public function credit_balance(Client $client) {
|
||||||
|
return $client->credit_balance ?? 0;
|
||||||
|
}
|
||||||
|
public function classification(Client $client) {
|
||||||
|
ctrans("texts.{$client->classification}") ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////contact details/////////////////
|
||||||
|
/*
|
||||||
|
public function phone(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function first_name(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function last_name(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function email(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function custom_value1(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function custom_value2(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function custom_value3(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public function custom_value4(Client $client) {
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
20
app/Export/Decorators/ContactDecorator.php
Normal file
20
app/Export/Decorators/ContactDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ContactDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/CreditDecorator.php
Normal file
20
app/Export/Decorators/CreditDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class CreditDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
120
app/Export/Decorators/Decorator.php
Normal file
120
app/Export/Decorators/Decorator.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Models\Task;
|
||||||
|
use App\Models\Quote;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\Credit;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Payment;
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Models\PurchaseOrder;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
|
use App\Export\Decorators\DecoratorInterface;
|
||||||
|
|
||||||
|
class Decorator implements DecoratorInterface{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
$index = $this->getKeyPart(0, $key);
|
||||||
|
$column = $this->getKeyPart(1, $key);
|
||||||
|
|
||||||
|
return $this->{$index}()->transform($column, $entity);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invoice(): InvoiceDecorator
|
||||||
|
{
|
||||||
|
return new InvoiceDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function client(): ClientDecorator
|
||||||
|
{
|
||||||
|
return new ClientDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function contact(): ContactDecorator
|
||||||
|
{
|
||||||
|
return new ContactDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function vendor_contact(): VendorContactDecorator
|
||||||
|
{
|
||||||
|
return new VendorContactDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function payment(): PaymentDecorator
|
||||||
|
{
|
||||||
|
return new PaymentDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function credit(): CreditDecorator
|
||||||
|
{
|
||||||
|
return new CreditDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function vendor(): VendorDecorator
|
||||||
|
{
|
||||||
|
return new VendorDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function expense(): ExpenseDecorator
|
||||||
|
{
|
||||||
|
return new ExpenseDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function product(): ProductDecorator
|
||||||
|
{
|
||||||
|
return new ProductDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function project(): ProjectDecorator
|
||||||
|
{
|
||||||
|
return new ProjectDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function task(): TaskDecorator
|
||||||
|
{
|
||||||
|
return new TaskDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function quote(): QuoteDecorator
|
||||||
|
{
|
||||||
|
return new QuoteDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function recurring_invoice(): RecurringInvoiceDecorator
|
||||||
|
{
|
||||||
|
return new RecurringInvoiceDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function purchase_order(): PurchaseOrderDecorator
|
||||||
|
{
|
||||||
|
return new PurchaseOrderDecorator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKeyPart(int $index, string $key): string
|
||||||
|
{
|
||||||
|
$parts = explode('.', $key);
|
||||||
|
|
||||||
|
return $parts[$index];
|
||||||
|
}
|
||||||
|
}
|
16
app/Export/Decorators/DecoratorInterface.php
Normal file
16
app/Export/Decorators/DecoratorInterface.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
interface DecoratorInterface {
|
||||||
|
public function transform(string $key, mixed $entity): mixed;
|
||||||
|
}
|
20
app/Export/Decorators/ExpenseDecorator.php
Normal file
20
app/Export/Decorators/ExpenseDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ExpenseDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/InvoiceDecorator.php
Normal file
20
app/Export/Decorators/InvoiceDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class InvoiceDecorator extends Decorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
142
app/Export/Decorators/PaymentDecorator.php
Normal file
142
app/Export/Decorators/PaymentDecorator.php
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
use App\Models\Payment;
|
||||||
|
|
||||||
|
class PaymentDecorator extends Decorator implements DecoratorInterface{
|
||||||
|
|
||||||
|
private $entity_key = 'payment';
|
||||||
|
|
||||||
|
public function transform(string $key, $entity): mixed
|
||||||
|
{
|
||||||
|
$payment = false;
|
||||||
|
|
||||||
|
if($entity instanceof Payment){
|
||||||
|
$payment = $entity;
|
||||||
|
}
|
||||||
|
elseif($entity->payment) {
|
||||||
|
$payment = $entity->payment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($key == 'amount' && (!$entity instanceof Payment)){
|
||||||
|
return $entity->payments()->exists() ? $entity->payments()->withoutTrashed()->sum('paymentables.amount') : ctrans('texts.unpaid');
|
||||||
|
}
|
||||||
|
elseif($key == 'refunded' && (!$entity instanceof Payment)) {
|
||||||
|
return $entity->payments()->exists() ? $entity->payments()->withoutTrashed()->sum('paymentables.refunded') : '';
|
||||||
|
}
|
||||||
|
elseif($key == 'applied' && (!$entity instanceof Payment)) {
|
||||||
|
$refunded = $entity->payments()->withoutTrashed()->sum('paymentables.refunded');
|
||||||
|
$amount = $entity->payments()->withoutTrashed()->sum('paymentables.amount');
|
||||||
|
return $entity->payments()->withoutTrashed()->exists() ? ($amount - $refunded) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if($payment && method_exists($this, $key)) {
|
||||||
|
return $this->{$key}($payment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function date(Payment $payment) {
|
||||||
|
return $payment->date ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function amount(Payment $payment) {
|
||||||
|
return $payment->amount ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refunded(Payment $payment) {
|
||||||
|
return $payment->refunded ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applied(Payment $payment) {
|
||||||
|
return $payment->applied ?? '';
|
||||||
|
}
|
||||||
|
public function transaction_reference(Payment $payment) {
|
||||||
|
return $payment->transaction_reference ?? '';
|
||||||
|
}
|
||||||
|
public function currency(Payment $payment) {
|
||||||
|
return $payment->currency()->exists() ? $payment->currency->code : $payment->company->currency()->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exchange_rate(Payment $payment) {
|
||||||
|
return $payment->exchange_rate ?? 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function number(Payment $payment) {
|
||||||
|
return $payment->number ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function method(Payment $payment) {
|
||||||
|
return $payment->translatedType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function status(Payment $payment) {
|
||||||
|
return $payment->stringStatus($payment->status_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function private_notes(Payment $payment) {
|
||||||
|
return strip_tags($payment->private_notes) ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function custom_value1(Payment $payment) {
|
||||||
|
return $payment->custom_value1 ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function custom_value2(Payment $payment) {
|
||||||
|
return $payment->custom_value2 ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function custom_value3(Payment $payment) {
|
||||||
|
return $payment->custom_value3 ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function custom_value4(Payment $payment) {
|
||||||
|
return $payment->custom_value4 ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user_id(Payment $payment) {
|
||||||
|
return $payment->user ? $payment->user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function assigned_user_id(Payment $payment) {
|
||||||
|
return $payment->assigned_user ? $payment->assigned_user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function project_id(Payment $payment) {
|
||||||
|
return $payment->project()->exists() ? $payment->project->name : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public function vendor_id(Payment $payment){
|
||||||
|
return $payment->vendor()->exists() ? $payment->vendor->name : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exchange_currency(Payment $payment){
|
||||||
|
return $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function gateway_type_id(Payment $payment) {
|
||||||
|
return $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function client_id(Payment $payment) {
|
||||||
|
return $payment->client->present()->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function type_id(Payment $payment) {
|
||||||
|
return $payment->translatedType();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
app/Export/Decorators/ProductDecorator.php
Normal file
20
app/Export/Decorators/ProductDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ProductDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/ProjectDecorator.php
Normal file
20
app/Export/Decorators/ProjectDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ProjectDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/PurchaseOrderDecorator.php
Normal file
20
app/Export/Decorators/PurchaseOrderDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class PurchaseOrderDecorator extends Decorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/QuoteDecorator.php
Normal file
20
app/Export/Decorators/QuoteDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class QuoteDecorator extends Decorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/RecurringInvoiceDecorator.php
Normal file
20
app/Export/Decorators/RecurringInvoiceDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class RecurringInvoiceDecorator extends Decorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/TaskDecorator.php
Normal file
20
app/Export/Decorators/TaskDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class TaskDecorator extends Decorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/VendorContactDecorator.php
Normal file
20
app/Export/Decorators/VendorContactDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class VendorContactDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/VendorDecorator.php
Normal file
20
app/Export/Decorators/VendorDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class VendorDecorator extends Decorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(string $key, mixed $entity): mixed
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
@ -11,13 +11,13 @@
|
|||||||
|
|
||||||
namespace App\Factory;
|
namespace App\Factory;
|
||||||
|
|
||||||
use App\DataMapper\ClientRegistrationFields;
|
|
||||||
use App\DataMapper\CompanySettings;
|
|
||||||
use App\DataMapper\Tax\TaxModel;
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\Company;
|
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\DataMapper\Tax\TaxModel;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\DataMapper\ClientRegistrationFields;
|
||||||
|
|
||||||
class CompanyFactory
|
class CompanyFactory
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ class CompanyFactory
|
|||||||
$company->markdown_email_enabled = true;
|
$company->markdown_email_enabled = true;
|
||||||
$company->markdown_enabled = false;
|
$company->markdown_enabled = false;
|
||||||
$company->tax_data = new TaxModel();
|
$company->tax_data = new TaxModel();
|
||||||
|
$company->first_month_of_year = 1;
|
||||||
return $company;
|
return $company;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ class PurchaseOrderFactory
|
|||||||
$purchase_order->company_id = $company_id;
|
$purchase_order->company_id = $company_id;
|
||||||
$purchase_order->recurring_id = null;
|
$purchase_order->recurring_id = null;
|
||||||
$purchase_order->exchange_rate = 1;
|
$purchase_order->exchange_rate = 1;
|
||||||
|
$purchase_order->total_taxes = 0;
|
||||||
|
|
||||||
return $purchase_order;
|
return $purchase_order;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@ class DesignFilters extends QueryFilters
|
|||||||
|
|
||||||
return $this->builder->where('is_template', $bool_val);
|
return $this->builder->where('is_template', $bool_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter the designs by `is_custom` column.
|
* Filter the designs by `is_custom` column.
|
||||||
*
|
*
|
||||||
|
@ -69,7 +69,6 @@ class EpcQrGenerator
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function encodeMessage()
|
public function encodeMessage()
|
||||||
@ -86,7 +85,7 @@ class EpcQrGenerator
|
|||||||
$this->sepa['purpose'],
|
$this->sepa['purpose'],
|
||||||
substr($this->invoice->number, 0, 34),
|
substr($this->invoice->number, 0, 34),
|
||||||
'',
|
'',
|
||||||
''
|
' '
|
||||||
]), "\n");
|
]), "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class ContactLoginController extends Controller
|
|||||||
/** @var \App\Models\Company $company **/
|
/** @var \App\Models\Company $company **/
|
||||||
if ($company) {
|
if ($company) {
|
||||||
$account = $company->account;
|
$account = $company->account;
|
||||||
} elseif (! $company && strpos($request->getHost(), 'invoicing.co') !== false) {
|
} elseif (! $company && strpos($request->getHost(), config('ninja.app_domain')) !== false) {
|
||||||
$subdomain = explode('.', $request->getHost())[0];
|
$subdomain = explode('.', $request->getHost())[0];
|
||||||
MultiDB::findAndSetDbByDomain(['subdomain' => $subdomain]);
|
MultiDB::findAndSetDbByDomain(['subdomain' => $subdomain]);
|
||||||
$company = Company::where('subdomain', $subdomain)->first();
|
$company = Company::where('subdomain', $subdomain)->first();
|
||||||
|
@ -527,7 +527,10 @@ class LoginController extends BaseController
|
|||||||
|
|
||||||
if (request()->has('id_token')) {
|
if (request()->has('id_token')) {
|
||||||
$user = $google->getTokenResponse(request()->input('id_token'));
|
$user = $google->getTokenResponse(request()->input('id_token'));
|
||||||
} else {
|
}elseif(request()->has('access_token')){
|
||||||
|
$user = $google->harvestUser(request()->input('access_token'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
return response()->json(['message' => 'Illegal request'], 403);
|
return response()->json(['message' => 'Illegal request'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class YodleeController extends BaseController
|
|||||||
$this->getAccounts($company, $token);
|
$this->getAccounts($company, $token);
|
||||||
}
|
}
|
||||||
|
|
||||||
$redirect_url = isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react'] ? 'https://app.invoicing.co/#/' : 'https://invoicing.co/';
|
$redirect_url = isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react'] ? config('ninja.react_url') : config('ninja.app_url');
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'access_token' => $yodlee->getAccessToken(),
|
'access_token' => $yodlee->getAccessToken(),
|
||||||
|
@ -530,8 +530,8 @@ class BaseController extends Controller
|
|||||||
|
|
||||||
$paginator = $query->paginate($limit);
|
$paginator = $query->paginate($limit);
|
||||||
|
|
||||||
/** @phpstan-ignore-next-line **/
|
/** @phpstan-ignore-next-line */
|
||||||
$query = $paginator->getCollection();
|
$query = $paginator->getCollection(); // @phpstan-ignore-line
|
||||||
|
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
|
|
||||||
@ -636,7 +636,8 @@ class BaseController extends Controller
|
|||||||
$paginator = $query->paginate($limit);
|
$paginator = $query->paginate($limit);
|
||||||
|
|
||||||
/** @phpstan-ignore-next-line **/
|
/** @phpstan-ignore-next-line **/
|
||||||
$query = $paginator->getCollection();
|
$query = $paginator->getCollection();// @phpstan-ignore-line
|
||||||
|
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
}
|
}
|
||||||
@ -885,7 +886,8 @@ class BaseController extends Controller
|
|||||||
$paginator = $query->paginate($limit);
|
$paginator = $query->paginate($limit);
|
||||||
|
|
||||||
/** @phpstan-ignore-next-line **/
|
/** @phpstan-ignore-next-line **/
|
||||||
$query = $paginator->getCollection();
|
$query = $paginator->getCollection();// @phpstan-ignore-line
|
||||||
|
|
||||||
|
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
@ -951,7 +953,8 @@ class BaseController extends Controller
|
|||||||
if ($query instanceof Builder) {
|
if ($query instanceof Builder) {
|
||||||
$limit = $this->resolveQueryLimit();
|
$limit = $this->resolveQueryLimit();
|
||||||
$paginator = $query->paginate($limit);
|
$paginator = $query->paginate($limit);
|
||||||
$query = $paginator->getCollection();
|
$query = $paginator->getCollection();// @phpstan-ignore-line
|
||||||
|
|
||||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||||
}
|
}
|
||||||
@ -1092,8 +1095,8 @@ class BaseController extends Controller
|
|||||||
/** @var \App\Models\Account $account */
|
/** @var \App\Models\Account $account */
|
||||||
|
|
||||||
//always redirect invoicing.co to invoicing.co
|
//always redirect invoicing.co to invoicing.co
|
||||||
if (Ninja::isHosted() && !in_array(request()->getSchemeAndHttpHost(), ['https://staging.invoicing.co', 'https://invoicing.co', 'https://demo.invoicing.co', 'https://invoiceninja.net'])) {
|
if (Ninja::isHosted() && !in_array(request()->getSchemeAndHttpHost(), ['https://staging.invoicing.co', 'https://invoicing.co', 'https://demo.invoicing.co', 'https://invoiceninja.net', config('ninja.app_url')])) {
|
||||||
return redirect()->secure('https://invoicing.co');
|
return redirect()->secure(config('ninja.app_url'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config('ninja.require_https') && ! request()->isSecure()) {
|
if (config('ninja.require_https') && ! request()->isSecure()) {
|
||||||
|
@ -11,36 +11,37 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\Client\ClientWasCreated;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Client\ClientWasUpdated;
|
|
||||||
use App\Factory\ClientFactory;
|
|
||||||
use App\Filters\ClientFilters;
|
|
||||||
use App\Http\Requests\Client\BulkClientRequest;
|
|
||||||
use App\Http\Requests\Client\CreateClientRequest;
|
|
||||||
use App\Http\Requests\Client\DestroyClientRequest;
|
|
||||||
use App\Http\Requests\Client\EditClientRequest;
|
|
||||||
use App\Http\Requests\Client\PurgeClientRequest;
|
|
||||||
use App\Http\Requests\Client\ReactivateClientEmailRequest;
|
|
||||||
use App\Http\Requests\Client\ShowClientRequest;
|
|
||||||
use App\Http\Requests\Client\StoreClientRequest;
|
|
||||||
use App\Http\Requests\Client\UpdateClientRequest;
|
|
||||||
use App\Http\Requests\Client\UploadClientRequest;
|
|
||||||
use App\Jobs\Client\UpdateTaxData;
|
|
||||||
use App\Jobs\PostMark\ProcessPostmarkWebhook;
|
|
||||||
use App\Models\Account;
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
|
use App\Models\Account;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use App\Repositories\ClientRepository;
|
|
||||||
use App\Transformers\ClientTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\BulkOptions;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use App\Utils\Traits\Uploadable;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Postmark\PostmarkClient;
|
use Postmark\PostmarkClient;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use App\Factory\ClientFactory;
|
||||||
|
use App\Filters\ClientFilters;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use App\Jobs\Client\UpdateTaxData;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
use App\Repositories\ClientRepository;
|
||||||
|
use App\Events\Client\ClientWasCreated;
|
||||||
|
use App\Events\Client\ClientWasUpdated;
|
||||||
|
use App\Transformers\ClientTransformer;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Services\Template\TemplateAction;
|
||||||
|
use App\Jobs\PostMark\ProcessPostmarkWebhook;
|
||||||
|
use App\Http\Requests\Client\BulkClientRequest;
|
||||||
|
use App\Http\Requests\Client\EditClientRequest;
|
||||||
|
use App\Http\Requests\Client\ShowClientRequest;
|
||||||
|
use App\Http\Requests\Client\PurgeClientRequest;
|
||||||
|
use App\Http\Requests\Client\StoreClientRequest;
|
||||||
|
use App\Http\Requests\Client\CreateClientRequest;
|
||||||
|
use App\Http\Requests\Client\UpdateClientRequest;
|
||||||
|
use App\Http\Requests\Client\UploadClientRequest;
|
||||||
|
use App\Http\Requests\Client\DestroyClientRequest;
|
||||||
|
use App\Http\Requests\Client\ReactivateClientEmailRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ClientController.
|
* Class ClientController.
|
||||||
@ -217,12 +218,31 @@ class ClientController extends BaseController
|
|||||||
$clients = Client::withTrashed()
|
$clients = Client::withTrashed()
|
||||||
->company()
|
->company()
|
||||||
->whereIn('id', $request->ids)
|
->whereIn('id', $request->ids)
|
||||||
->cursor()
|
->get();
|
||||||
->each(function ($client) use ($action, $user) {
|
|
||||||
if ($user->can('edit', $client)) {
|
if($action == 'template' && $user->can('view', $clients->first())) {
|
||||||
$this->client_repo->{$action}($client);
|
|
||||||
}
|
$hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
|
||||||
});
|
|
||||||
|
TemplateAction::dispatch(
|
||||||
|
$clients->pluck('id')->toArray(),
|
||||||
|
$request->template_id,
|
||||||
|
Client::class,
|
||||||
|
$user->id,
|
||||||
|
$user->company(),
|
||||||
|
$user->company()->db,
|
||||||
|
$hash_or_response,
|
||||||
|
$request->boolean('send_email')
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash_or_response], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
$clients->each(function ($client) use ($action, $user) {
|
||||||
|
if ($user->can('edit', $client)) {
|
||||||
|
$this->client_repo->{$action}($client);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
|
return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
|
||||||
}
|
}
|
||||||
@ -364,8 +384,15 @@ class ClientController extends BaseController
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
/** @var \Postmark\Models\DynamicResponseModel $response */
|
||||||
$response = $postmark->activateBounce((int)$bounce_id);
|
$response = $postmark->activateBounce((int)$bounce_id);
|
||||||
|
|
||||||
|
if($response && $response?->Message == 'OK' && !$response->Bounce->Inactive && $response->Bounce->Email){
|
||||||
|
|
||||||
|
$email = $response->Bounce->Email;
|
||||||
|
//remove email from quarantine. //@TODO
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json(['message' => 'Success'], 200);
|
return response()->json(['message' => 'Success'], 200);
|
||||||
|
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
|
@ -44,7 +44,7 @@ class ApplePayDomainController extends Controller
|
|||||||
|
|
||||||
$domain_name = $request->getHost();
|
$domain_name = $request->getHost();
|
||||||
|
|
||||||
if (strpos($domain_name, 'invoicing.co') !== false) {
|
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
|
||||||
$subdomain = explode('.', $domain_name)[0];
|
$subdomain = explode('.', $domain_name)[0];
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
|
@ -167,11 +167,11 @@ class InvitationController extends Controller
|
|||||||
{
|
{
|
||||||
set_time_limit(45);
|
set_time_limit(45);
|
||||||
|
|
||||||
if (Ninja::isHosted()) {
|
// if (Ninja::isHosted()) {
|
||||||
return $this->returnRawPdf($entity, $invitation_key);
|
return $this->returnRawPdf($entity, $invitation_key);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return redirect('client/'.$entity.'/'.$invitation_key.'/download_pdf');
|
// return redirect('client/'.$entity.'/'.$invitation_key.'/download_pdf');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function returnRawPdf(string $entity, string $invitation_key)
|
private function returnRawPdf(string $entity, string $invitation_key)
|
||||||
|
@ -252,11 +252,9 @@ class InvoiceController extends Controller
|
|||||||
if ($invoices->count() == 1) {
|
if ($invoices->count() == 1) {
|
||||||
$invoice = $invoices->first();
|
$invoice = $invoices->first();
|
||||||
|
|
||||||
$file = $invoice->service()->getInvoicePdf(auth()->guard('contact')->user());
|
return response()->streamDownload(function () use ($invoice) {
|
||||||
|
echo $invoice->service()->getInvoicePdf(auth()->guard('contact')->user());
|
||||||
return response()->streamDownload(function () use ($file) {
|
}, $invoice->getFileName(), ['Content-Type' => 'application/pdf']);
|
||||||
echo Storage::get($file);
|
|
||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->buildZip($invoices);
|
return $this->buildZip($invoices);
|
||||||
|
@ -86,7 +86,10 @@ class NinjaPlanController extends Controller
|
|||||||
|
|
||||||
public function trial_confirmation(Request $request)
|
public function trial_confirmation(Request $request)
|
||||||
{
|
{
|
||||||
|
$trial_started = "Trial Started @ ".now()->format('Y-m-d H:i:s');
|
||||||
|
|
||||||
$client = auth()->guard('contact')->user()->client;
|
$client = auth()->guard('contact')->user()->client;
|
||||||
|
$client->private_notes = $trial_started;
|
||||||
$client->fill($request->all());
|
$client->fill($request->all());
|
||||||
$client->save();
|
$client->save();
|
||||||
|
|
||||||
@ -150,6 +153,7 @@ class NinjaPlanController extends Controller
|
|||||||
$account->plan_expires = now()->addDays(14);
|
$account->plan_expires = now()->addDays(14);
|
||||||
$account->is_trial=true;
|
$account->is_trial=true;
|
||||||
$account->hosted_company_count = 10;
|
$account->hosted_company_count = 10;
|
||||||
|
$account->trial_started = now();
|
||||||
$account->save();
|
$account->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,21 +194,27 @@ class CompanyGatewayController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function store(StoreCompanyGatewayRequest $request)
|
public function store(StoreCompanyGatewayRequest $request)
|
||||||
{
|
{
|
||||||
$company_gateway = CompanyGatewayFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$company_gateway = CompanyGatewayFactory::create($user->company()->id, $user->id);
|
||||||
$company_gateway->fill($request->all());
|
$company_gateway->fill($request->all());
|
||||||
$company_gateway->save();
|
$company_gateway->save();
|
||||||
|
|
||||||
/*Always ensure at least one fees and limits object is set per gateway*/
|
/*Always ensure at least one fees and limits object is set per gateway*/
|
||||||
if (! isset($company_gateway->fees_and_limits)) {
|
$gateway_types = $company_gateway->driver(new Client)->getAvailableMethods();
|
||||||
$gateway_types = $company_gateway->driver(new Client)->gatewayTypes();
|
|
||||||
|
|
||||||
$fees_and_limits = new \stdClass;
|
$fees_and_limits = $company_gateway->fees_and_limits;
|
||||||
$fees_and_limits->{$gateway_types[0]} = new FeesAndLimits;
|
|
||||||
|
|
||||||
$company_gateway->fees_and_limits = $fees_and_limits;
|
foreach($gateway_types as $key => $gateway_type)
|
||||||
$company_gateway->save();
|
{
|
||||||
|
if(!property_exists($fees_and_limits, $key))
|
||||||
|
$fees_and_limits->{$key} = new FeesAndLimits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$company_gateway->fees_and_limits = $fees_and_limits;
|
||||||
|
$company_gateway->save();
|
||||||
|
|
||||||
ApplePayDomain::dispatch($company_gateway, $company_gateway->company->db);
|
ApplePayDomain::dispatch($company_gateway, $company_gateway->company->db);
|
||||||
|
|
||||||
if (in_array($company_gateway->gateway_key, $this->stripe_keys)) {
|
if (in_array($company_gateway->gateway_key, $this->stripe_keys)) {
|
||||||
@ -381,10 +387,18 @@ class CompanyGatewayController extends BaseController
|
|||||||
{
|
{
|
||||||
$company_gateway->fill($request->all());
|
$company_gateway->fill($request->all());
|
||||||
|
|
||||||
if (! $request->has('fees_and_limits')) {
|
/*Always ensure at least one fees and limits object is set per gateway*/
|
||||||
$company_gateway->fees_and_limits = '';
|
$gateway_types = $company_gateway->driver(new Client)->getAvailableMethods();
|
||||||
|
|
||||||
|
$fees_and_limits = $company_gateway->fees_and_limits;
|
||||||
|
|
||||||
|
foreach($gateway_types as $key => $gateway_type) {
|
||||||
|
if(!property_exists($fees_and_limits, $key)) {
|
||||||
|
$fees_and_limits->{$key} = new FeesAndLimits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$company_gateway->fees_and_limits = $fees_and_limits;
|
||||||
$company_gateway->save();
|
$company_gateway->save();
|
||||||
|
|
||||||
if($company_gateway->gateway_key == $this->checkout_key) {
|
if($company_gateway->gateway_key == $this->checkout_key) {
|
||||||
|
@ -11,35 +11,36 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\Credit\CreditWasCreated;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Credit\CreditWasUpdated;
|
use App\Models\Client;
|
||||||
use App\Factory\CloneCreditFactory;
|
use App\Models\Credit;
|
||||||
|
use App\Models\Account;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use App\Factory\CreditFactory;
|
use App\Factory\CreditFactory;
|
||||||
use App\Filters\CreditFilters;
|
use App\Filters\CreditFilters;
|
||||||
use App\Http\Requests\Credit\ActionCreditRequest;
|
use App\Jobs\Credit\ZipCredits;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Jobs\Entity\EmailEntity;
|
||||||
|
use App\Factory\CloneCreditFactory;
|
||||||
|
use App\Services\PdfMaker\PdfMerge;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
use App\Repositories\CreditRepository;
|
||||||
|
use App\Events\Credit\CreditWasCreated;
|
||||||
|
use App\Events\Credit\CreditWasUpdated;
|
||||||
|
use App\Transformers\CreditTransformer;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Services\Template\TemplateAction;
|
||||||
use App\Http\Requests\Credit\BulkCreditRequest;
|
use App\Http\Requests\Credit\BulkCreditRequest;
|
||||||
use App\Http\Requests\Credit\CreateCreditRequest;
|
|
||||||
use App\Http\Requests\Credit\DestroyCreditRequest;
|
|
||||||
use App\Http\Requests\Credit\EditCreditRequest;
|
use App\Http\Requests\Credit\EditCreditRequest;
|
||||||
use App\Http\Requests\Credit\ShowCreditRequest;
|
use App\Http\Requests\Credit\ShowCreditRequest;
|
||||||
use App\Http\Requests\Credit\StoreCreditRequest;
|
use App\Http\Requests\Credit\StoreCreditRequest;
|
||||||
|
use App\Http\Requests\Credit\ActionCreditRequest;
|
||||||
|
use App\Http\Requests\Credit\CreateCreditRequest;
|
||||||
use App\Http\Requests\Credit\UpdateCreditRequest;
|
use App\Http\Requests\Credit\UpdateCreditRequest;
|
||||||
use App\Http\Requests\Credit\UploadCreditRequest;
|
use App\Http\Requests\Credit\UploadCreditRequest;
|
||||||
use App\Jobs\Credit\ZipCredits;
|
use App\Http\Requests\Credit\DestroyCreditRequest;
|
||||||
use App\Jobs\Entity\EmailEntity;
|
|
||||||
use App\Models\Account;
|
|
||||||
use App\Models\Client;
|
|
||||||
use App\Models\Credit;
|
|
||||||
use App\Models\Invoice;
|
|
||||||
use App\Repositories\CreditRepository;
|
|
||||||
use App\Services\PdfMaker\PdfMerge;
|
|
||||||
use App\Transformers\CreditTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\App;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CreditController.
|
* Class CreditController.
|
||||||
@ -550,6 +551,25 @@ class CreditController extends BaseController
|
|||||||
}, 'print.pdf', ['Content-Type' => 'application/pdf']);
|
}, 'print.pdf', ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($action == 'template' && $user->can('view', $credits->first())) {
|
||||||
|
|
||||||
|
$hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
|
||||||
|
|
||||||
|
TemplateAction::dispatch(
|
||||||
|
$credits->pluck('hashed_id')->toArray(),
|
||||||
|
$request->template_id,
|
||||||
|
Credit::class,
|
||||||
|
$user->id,
|
||||||
|
$user->company(),
|
||||||
|
$user->company()->db,
|
||||||
|
$hash_or_response,
|
||||||
|
$request->boolean('send_email')
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash_or_response], 200);
|
||||||
|
}
|
||||||
|
|
||||||
$credits->each(function ($credit, $key) use ($action, $user) {
|
$credits->each(function ($credit, $key) use ($action, $user) {
|
||||||
if ($user->can('edit', $credit)) {
|
if ($user->can('edit', $credit)) {
|
||||||
$this->performAction($credit, $action, true);
|
$this->performAction($credit, $action, true);
|
||||||
|
@ -69,8 +69,11 @@ class EmailController extends BaseController
|
|||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
if ($request->has('cc_email') && $request->cc_email && (Ninja::isSelfHost() || $user->account->isPaidHostedClient())) {
|
if ($request->cc_email && (Ninja::isSelfHost() || $user->account->isPaidHostedClient())) {
|
||||||
$mo->cc[] = new Address($request->cc_email);
|
|
||||||
|
foreach($request->cc_email as $email)
|
||||||
|
$mo->cc[] = new Address($email);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity_obj->invitations->each(function ($invitation) use ($entity_obj, $mo) {
|
$entity_obj->invitations->each(function ($invitation) use ($entity_obj, $mo) {
|
||||||
|
@ -56,11 +56,14 @@ class ExportController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function index(StoreExportRequest $request)
|
public function index(StoreExportRequest $request)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$hash = Str::uuid();
|
$hash = Str::uuid();
|
||||||
$url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
|
$url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
|
||||||
Cache::put($hash, $url, now()->addHour());
|
Cache::put($hash, $url, now()->addHour());
|
||||||
|
|
||||||
CompanyExport::dispatch(auth()->user()->getCompany(), auth()->user(), $hash);
|
CompanyExport::dispatch($user->getCompany(), $user, $hash);
|
||||||
|
|
||||||
return response()->json(['message' => 'Processing', 'url' => $url], 200);
|
return response()->json(['message' => 'Processing', 'url' => $url], 200);
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,6 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
$invoice->service()
|
$invoice->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request)
|
||||||
// ->deletePdf()
|
|
||||||
->adjustInventory($old_invoice);
|
->adjustInventory($old_invoice);
|
||||||
|
|
||||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
@ -526,11 +525,12 @@ class InvoiceController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'download' && $invoices->count() >=1 && $user->can('view', $invoices->first())) {
|
if ($action == 'download' && $invoices->count() >=1 && $user->can('view', $invoices->first())) {
|
||||||
$file = $invoices->first()->service()->getInvoicePdf();
|
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($file) {
|
$filename = $invoices->first()->getFileName();
|
||||||
echo Storage::get($file);
|
|
||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
return response()->streamDownload(function () use($invoices) {
|
||||||
|
echo $invoices->first()->service()->getInvoicePdf();
|
||||||
|
}, $filename, ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'bulk_print' && $user->can('view', $invoices->first())) {
|
if ($action == 'bulk_print' && $user->can('view', $invoices->first())) {
|
||||||
@ -538,10 +538,10 @@ class InvoiceController extends BaseController
|
|||||||
return (new \App\Jobs\Entity\CreateRawPdf($invoice->invitations->first()))->handle();
|
return (new \App\Jobs\Entity\CreateRawPdf($invoice->invitations->first()))->handle();
|
||||||
});
|
});
|
||||||
|
|
||||||
$merge = (new PdfMerge($paths->toArray()))->run();
|
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($merge) {
|
|
||||||
echo($merge);
|
return response()->streamDownload(function () use ($paths) {
|
||||||
|
echo $merge = (new PdfMerge($paths->toArray()))->run();
|
||||||
}, 'print.pdf', ['Content-Type' => 'application/pdf']);
|
}, 'print.pdf', ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,11 +700,9 @@ class InvoiceController extends BaseController
|
|||||||
break;
|
break;
|
||||||
case 'download':
|
case 'download':
|
||||||
|
|
||||||
$file = $invoice->service()->getInvoicePdf();
|
return response()->streamDownload(function () use ($invoice) {
|
||||||
|
echo $invoice->service()->getInvoicePdf();
|
||||||
return response()->streamDownload(function () use ($file) {
|
}, $invoice->getFileName(), ['Content-Type' => 'application/pdf']);
|
||||||
echo Storage::get($file);
|
|
||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
|
||||||
|
|
||||||
case 'restore':
|
case 'restore':
|
||||||
$this->invoice_repo->restore($invoice);
|
$this->invoice_repo->restore($invoice);
|
||||||
@ -936,15 +934,11 @@ class InvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function deliveryNote(ShowInvoiceRequest $request, Invoice $invoice)
|
public function deliveryNote(ShowInvoiceRequest $request, Invoice $invoice)
|
||||||
{
|
{
|
||||||
$file = $invoice->service()->getInvoiceDeliveryNote($invoice, $invoice->invitations->first()->contact);
|
|
||||||
|
|
||||||
return response()->streamDownload(function () use ($file) {
|
return response()->streamDownload(function () use ($invoice) {
|
||||||
echo $file;
|
echo $invoice->service()->getInvoiceDeliveryNote($invoice, $invoice->invitations->first()->contact);
|
||||||
}, basename($file), ['Content-Type' => 'application/pdf']);
|
}, $invoice->getDeliveryNoteName(), ['Content-Type' => 'application/pdf']);
|
||||||
|
|
||||||
// return response()->streamDownload(function () use ($file) {
|
|
||||||
// echo Storage::get($file);
|
|
||||||
// }, basename($file), ['Content-Type' => 'application/pdf']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,25 +11,27 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\Payment\PaymentWasUpdated;
|
use App\Utils\Ninja;
|
||||||
use App\Factory\PaymentFactory;
|
|
||||||
use App\Filters\PaymentFilters;
|
|
||||||
use App\Http\Requests\Payment\CreatePaymentRequest;
|
|
||||||
use App\Http\Requests\Payment\DestroyPaymentRequest;
|
|
||||||
use App\Http\Requests\Payment\EditPaymentRequest;
|
|
||||||
use App\Http\Requests\Payment\RefundPaymentRequest;
|
|
||||||
use App\Http\Requests\Payment\ShowPaymentRequest;
|
|
||||||
use App\Http\Requests\Payment\StorePaymentRequest;
|
|
||||||
use App\Http\Requests\Payment\UpdatePaymentRequest;
|
|
||||||
use App\Http\Requests\Payment\UploadPaymentRequest;
|
|
||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Repositories\PaymentRepository;
|
use Illuminate\Http\Response;
|
||||||
use App\Transformers\PaymentTransformer;
|
use App\Factory\PaymentFactory;
|
||||||
use App\Utils\Ninja;
|
use App\Filters\PaymentFilters;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Utils\Traits\SavesDocuments;
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Illuminate\Http\Response;
|
use App\Repositories\PaymentRepository;
|
||||||
|
use App\Transformers\PaymentTransformer;
|
||||||
|
use App\Events\Payment\PaymentWasUpdated;
|
||||||
|
use App\Services\Template\TemplateAction;
|
||||||
|
use App\Http\Requests\Payment\EditPaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\ShowPaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\StorePaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\CreatePaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\RefundPaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\UpdatePaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\UploadPaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\DestroyPaymentRequest;
|
||||||
|
use App\Http\Requests\Payment\BulkActionPaymentRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PaymentController.
|
* Class PaymentController.
|
||||||
@ -499,16 +501,39 @@ class PaymentController extends BaseController
|
|||||||
* ),
|
* ),
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
public function bulk()
|
public function bulk(BulkActionPaymentRequest $request)
|
||||||
{
|
{
|
||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$action = request()->input('action');
|
$action = $request->input('action');
|
||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = $request->input('ids');
|
||||||
|
|
||||||
|
$payments = Payment::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
||||||
|
|
||||||
|
if (!$payments) {
|
||||||
|
return response()->json(['message' => ctrans('texts.record_not_found')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($action == 'template' && $user->can('view', $payments->first())) {
|
||||||
|
|
||||||
|
$hash_or_response = request()->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
|
||||||
|
nlog($payments->pluck('hashed_id')->toArray());
|
||||||
|
TemplateAction::dispatch(
|
||||||
|
$payments->pluck('hashed_id')->toArray(),
|
||||||
|
$request->template_id,
|
||||||
|
Payment::class,
|
||||||
|
$user->id,
|
||||||
|
$user->company(),
|
||||||
|
$user->company()->db,
|
||||||
|
$hash_or_response,
|
||||||
|
$request->boolean('send_email')
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash_or_response], 200);
|
||||||
|
}
|
||||||
|
|
||||||
$payments = Payment::withTrashed()->find($this->transformKeys($ids));
|
|
||||||
|
|
||||||
$payments->each(function ($payment, $key) use ($action, $user) {
|
$payments->each(function ($payment, $key) use ($action, $user) {
|
||||||
if ($user->can('edit', $payment)) {
|
if ($user->can('edit', $payment)) {
|
||||||
|
@ -28,7 +28,6 @@ use App\Utils\HostedPDF\NinjaPdf;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use App\Services\PdfMaker\PdfMaker;
|
use App\Services\PdfMaker\PdfMaker;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use App\Utils\Traits\MakesInvoiceHtml;
|
use App\Utils\Traits\MakesInvoiceHtml;
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
use App\Utils\Traits\Pdf\PageNumbering;
|
use App\Utils\Traits\Pdf\PageNumbering;
|
||||||
@ -54,10 +53,6 @@ class PreviewController extends BaseController
|
|||||||
public function live(PreviewInvoiceRequest $request): mixed
|
public function live(PreviewInvoiceRequest $request): mixed
|
||||||
{
|
{
|
||||||
|
|
||||||
if (Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co'])) {
|
|
||||||
return response()->json(['message' => 'This server cannot handle this request.'], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
|
|
||||||
/** Build models */
|
/** Build models */
|
||||||
@ -84,141 +79,6 @@ class PreviewController extends BaseController
|
|||||||
|
|
||||||
$pdf = $ps->boot()->getPdf();
|
$pdf = $ps->boot()->getPdf();
|
||||||
|
|
||||||
|
|
||||||
if (Ninja::isHosted()) {
|
|
||||||
LightLogs::create(new LivePreview())
|
|
||||||
->increment()
|
|
||||||
->batch();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return PDF */
|
|
||||||
return response()->streamDownload(function () use ($pdf) {
|
|
||||||
echo $pdf;
|
|
||||||
}, 'preview.pdf', [
|
|
||||||
'Content-Disposition' => 'inline',
|
|
||||||
'Content-Type' => 'application/pdf',
|
|
||||||
'Cache-Control:' => 'no-cache',
|
|
||||||
'Server-Timing' => microtime(true)-$start
|
|
||||||
]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refactor - 2023-10-19
|
|
||||||
*
|
|
||||||
* New method does not require Transactions.
|
|
||||||
*
|
|
||||||
* @param PreviewInvoiceRequest $request
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function livexx(PreviewInvoiceRequest $request): mixed
|
|
||||||
{
|
|
||||||
|
|
||||||
if (Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co'])) {
|
|
||||||
return response()->json(['message' => 'This server cannot handle this request.'], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$start = microtime(true);
|
|
||||||
|
|
||||||
/** Build models */
|
|
||||||
$invitation = $request->resolveInvitation();
|
|
||||||
$client = $request->getClient();
|
|
||||||
$settings = $client->getMergedSettings();
|
|
||||||
|
|
||||||
/** Set translations */
|
|
||||||
App::forgetInstance('translator');
|
|
||||||
$t = app('translator');
|
|
||||||
App::setLocale($invitation->contact->preferredLocale());
|
|
||||||
$t->replace(Ninja::transformTranslations($settings));
|
|
||||||
|
|
||||||
$entity_prop = str_replace("recurring_", "", $request->entity);
|
|
||||||
$entity_obj = $invitation->{$request->entity};
|
|
||||||
$entity_obj->fill($request->all());
|
|
||||||
|
|
||||||
/** Update necessary objecty props */
|
|
||||||
if(!$entity_obj->id) {
|
|
||||||
$entity_obj->design_id = intval($this->decodePrimaryKey($settings->{$entity_prop."_design_id"}));
|
|
||||||
$entity_obj->footer = empty($entity_obj->footer) ? $settings->{$entity_prop."_footer"} : $entity_obj->footer;
|
|
||||||
$entity_obj->terms = empty($entity_obj->terms) ? $settings->{$entity_prop."_terms"} : $entity_obj->terms;
|
|
||||||
$entity_obj->public_notes = empty($entity_obj->public_notes) ? $request->getClient()->public_notes : $entity_obj->public_notes;
|
|
||||||
$invitation->{$request->entity} = $entity_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(empty($entity_obj->design_id)) {
|
|
||||||
$entity_obj->design_id = intval($this->decodePrimaryKey($settings->{$entity_prop."_design_id"}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Generate variables */
|
|
||||||
$html = new HtmlEngine($invitation);
|
|
||||||
$html->settings = $settings;
|
|
||||||
$variables = $html->generateLabelsAndValues();
|
|
||||||
|
|
||||||
$design = \App\Models\Design::query()->withTrashed()->find($entity_obj->design_id ?? 2);
|
|
||||||
|
|
||||||
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' => $client,
|
|
||||||
'entity' => $entity_obj,
|
|
||||||
'pdf_variables' => (array) $settings->pdf_variables,
|
|
||||||
'$product' => $design->design->product,
|
|
||||||
'variables' => $variables,
|
|
||||||
]),
|
|
||||||
'variables' => $variables,
|
|
||||||
'options' => [
|
|
||||||
'all_pages_header' => $client->getSetting('all_pages_header'),
|
|
||||||
'all_pages_footer' => $client->getSetting('all_pages_footer'),
|
|
||||||
'client' => $entity_obj->client ?? [],
|
|
||||||
'vendor' => $entity_obj->vendor ?? [],
|
|
||||||
$request->input('entity')."s" => [$entity_obj],
|
|
||||||
],
|
|
||||||
'process_markdown' => $client->company->markdown_enabled,
|
|
||||||
];
|
|
||||||
|
|
||||||
$maker = new PdfMaker($state);
|
|
||||||
|
|
||||||
$maker
|
|
||||||
->design($template)
|
|
||||||
->build();
|
|
||||||
|
|
||||||
/** Generate HTML */
|
|
||||||
$html = $maker->getCompiledHTML(true);
|
|
||||||
|
|
||||||
if (request()->query('html') == 'true') {
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if phantom js...... inject here..
|
|
||||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
|
||||||
return (new Phantom)->convertHtmlToPdf($html);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \App\Models\User $user */
|
|
||||||
$user = auth()->user();
|
|
||||||
$company = $user->company();
|
|
||||||
|
|
||||||
if (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') {
|
|
||||||
|
|
||||||
$pdf = (new NinjaPdf())->build($html);
|
|
||||||
$numbered_pdf = $this->pageNumbering($pdf, $company);
|
|
||||||
|
|
||||||
if ($numbered_pdf) {
|
|
||||||
$pdf = $numbered_pdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $pdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pdf = (new PreviewPdf($html, $company))->handle();
|
|
||||||
|
|
||||||
if (Ninja::isHosted()) {
|
if (Ninja::isHosted()) {
|
||||||
LightLogs::create(new LivePreview())
|
LightLogs::create(new LivePreview())
|
||||||
->increment()
|
->increment()
|
||||||
@ -388,6 +248,7 @@ class PreviewController extends BaseController
|
|||||||
$design_object = json_decode(json_encode(request()->input('design')), 1);
|
$design_object = json_decode(json_encode(request()->input('design')), 1);
|
||||||
|
|
||||||
$ts = (new TemplateService());
|
$ts = (new TemplateService());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$ts->setCompany($company)
|
$ts->setCompany($company)
|
||||||
->setTemplate($design_object)
|
->setTemplate($design_object)
|
||||||
@ -395,7 +256,6 @@ class PreviewController extends BaseController
|
|||||||
} catch(SyntaxError $e) {
|
} catch(SyntaxError $e) {
|
||||||
|
|
||||||
// return response()->json(['message' => 'Twig syntax is invalid.', 'errors' => new \stdClass], 422);
|
// return response()->json(['message' => 'Twig syntax is invalid.', 'errors' => new \stdClass], 422);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$html = $ts->getHtml();
|
$html = $ts->getHtml();
|
||||||
@ -429,11 +289,6 @@ class PreviewController extends BaseController
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function stubTemplateData()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function blankEntity()
|
private function blankEntity()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -11,23 +11,25 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Account;
|
||||||
|
use App\Models\Project;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
use App\Factory\ProjectFactory;
|
use App\Factory\ProjectFactory;
|
||||||
use App\Filters\ProjectFilters;
|
use App\Filters\ProjectFilters;
|
||||||
use App\Http\Requests\Project\CreateProjectRequest;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Http\Requests\Project\DestroyProjectRequest;
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
|
use App\Repositories\ProjectRepository;
|
||||||
|
use App\Transformers\ProjectTransformer;
|
||||||
|
use App\Services\Template\TemplateAction;
|
||||||
use App\Http\Requests\Project\EditProjectRequest;
|
use App\Http\Requests\Project\EditProjectRequest;
|
||||||
use App\Http\Requests\Project\ShowProjectRequest;
|
use App\Http\Requests\Project\ShowProjectRequest;
|
||||||
use App\Http\Requests\Project\StoreProjectRequest;
|
use App\Http\Requests\Project\StoreProjectRequest;
|
||||||
|
use App\Http\Requests\Project\CreateProjectRequest;
|
||||||
use App\Http\Requests\Project\UpdateProjectRequest;
|
use App\Http\Requests\Project\UpdateProjectRequest;
|
||||||
use App\Http\Requests\Project\UploadProjectRequest;
|
use App\Http\Requests\Project\UploadProjectRequest;
|
||||||
use App\Models\Account;
|
use App\Http\Requests\Project\DestroyProjectRequest;
|
||||||
use App\Models\Project;
|
use App\Http\Requests\Project\BulkProjectRequest;
|
||||||
use App\Repositories\ProjectRepository;
|
|
||||||
use App\Transformers\ProjectTransformer;
|
|
||||||
use App\Utils\Traits\GeneratesCounter;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ProjectController.
|
* Class ProjectController.
|
||||||
@ -490,18 +492,36 @@ class ProjectController extends BaseController
|
|||||||
* ),
|
* ),
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
public function bulk()
|
public function bulk(BulkProjectRequest $request)
|
||||||
{
|
{
|
||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$action = request()->input('action');
|
$action = $request->input('action');
|
||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = $request->input('ids');
|
||||||
|
|
||||||
$projects = Project::withTrashed()->find($this->transformKeys($ids));
|
$projects = Project::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
||||||
|
|
||||||
$projects->each(function ($project, $key) use ($action, $user) {
|
if($action == 'template' && $user->can('view', $projects->first())) {
|
||||||
|
|
||||||
|
$hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
|
||||||
|
|
||||||
|
TemplateAction::dispatch(
|
||||||
|
$projects->pluck('hashed_id')->toArray(),
|
||||||
|
$request->template_id,
|
||||||
|
Project::class,
|
||||||
|
$user->id,
|
||||||
|
$user->company(),
|
||||||
|
$user->company()->db,
|
||||||
|
$hash_or_response,
|
||||||
|
$request->boolean('send_email')
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash_or_response], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
$projects->each(function ($project) use ($action, $user) {
|
||||||
if ($user->can('edit', $project)) {
|
if ($user->can('edit', $project)) {
|
||||||
$this->project_repo->{$action}($project);
|
$this->project_repo->{$action}($project);
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,10 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
class ProtectedDownloadController extends BaseController
|
class ProtectedDownloadController extends BaseController
|
||||||
{
|
{
|
||||||
|
|
||||||
public function index(Request $request)
|
public function index(Request $request, string $hash)
|
||||||
{
|
{
|
||||||
/** @var string $hashed_path */
|
/** @var string $hashed_path */
|
||||||
$hashed_path = Cache::pull($request->hash);
|
$hashed_path = Cache::pull($hash);
|
||||||
|
|
||||||
if (!$hashed_path) {
|
if (!$hashed_path) {
|
||||||
throw new SystemError('File no longer available', 404);
|
throw new SystemError('File no longer available', 404);
|
||||||
|
@ -11,33 +11,34 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\PurchaseOrder\PurchaseOrderWasCreated;
|
use App\Utils\Ninja;
|
||||||
use App\Events\PurchaseOrder\PurchaseOrderWasUpdated;
|
use App\Models\Client;
|
||||||
|
use App\Models\Account;
|
||||||
|
use App\Models\PurchaseOrder;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Jobs\Entity\CreateRawPdf;
|
||||||
|
use App\Services\PdfMaker\PdfMerge;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use App\Factory\PurchaseOrderFactory;
|
use App\Factory\PurchaseOrderFactory;
|
||||||
use App\Filters\PurchaseOrderFilters;
|
use App\Filters\PurchaseOrderFilters;
|
||||||
use App\Http\Requests\PurchaseOrder\ActionPurchaseOrderRequest;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Services\Template\TemplateAction;
|
||||||
|
use App\Jobs\PurchaseOrder\ZipPurchaseOrders;
|
||||||
|
use App\Repositories\PurchaseOrderRepository;
|
||||||
|
use App\Jobs\PurchaseOrder\PurchaseOrderEmail;
|
||||||
|
use App\Transformers\PurchaseOrderTransformer;
|
||||||
|
use App\Events\PurchaseOrder\PurchaseOrderWasCreated;
|
||||||
|
use App\Events\PurchaseOrder\PurchaseOrderWasUpdated;
|
||||||
use App\Http\Requests\PurchaseOrder\BulkPurchaseOrderRequest;
|
use App\Http\Requests\PurchaseOrder\BulkPurchaseOrderRequest;
|
||||||
use App\Http\Requests\PurchaseOrder\CreatePurchaseOrderRequest;
|
|
||||||
use App\Http\Requests\PurchaseOrder\DestroyPurchaseOrderRequest;
|
|
||||||
use App\Http\Requests\PurchaseOrder\EditPurchaseOrderRequest;
|
use App\Http\Requests\PurchaseOrder\EditPurchaseOrderRequest;
|
||||||
use App\Http\Requests\PurchaseOrder\ShowPurchaseOrderRequest;
|
use App\Http\Requests\PurchaseOrder\ShowPurchaseOrderRequest;
|
||||||
use App\Http\Requests\PurchaseOrder\StorePurchaseOrderRequest;
|
use App\Http\Requests\PurchaseOrder\StorePurchaseOrderRequest;
|
||||||
|
use App\Http\Requests\PurchaseOrder\ActionPurchaseOrderRequest;
|
||||||
|
use App\Http\Requests\PurchaseOrder\CreatePurchaseOrderRequest;
|
||||||
use App\Http\Requests\PurchaseOrder\UpdatePurchaseOrderRequest;
|
use App\Http\Requests\PurchaseOrder\UpdatePurchaseOrderRequest;
|
||||||
use App\Http\Requests\PurchaseOrder\UploadPurchaseOrderRequest;
|
use App\Http\Requests\PurchaseOrder\UploadPurchaseOrderRequest;
|
||||||
use App\Jobs\Entity\CreateRawPdf;
|
use App\Http\Requests\PurchaseOrder\DestroyPurchaseOrderRequest;
|
||||||
use App\Jobs\PurchaseOrder\PurchaseOrderEmail;
|
|
||||||
use App\Jobs\PurchaseOrder\ZipPurchaseOrders;
|
|
||||||
use App\Models\Account;
|
|
||||||
use App\Models\Client;
|
|
||||||
use App\Models\PurchaseOrder;
|
|
||||||
use App\Repositories\PurchaseOrderRepository;
|
|
||||||
use App\Services\PdfMaker\PdfMerge;
|
|
||||||
use App\Transformers\PurchaseOrderTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
class PurchaseOrderController extends BaseController
|
class PurchaseOrderController extends BaseController
|
||||||
{
|
{
|
||||||
@ -524,6 +525,24 @@ class PurchaseOrderController extends BaseController
|
|||||||
}, 'print.pdf', ['Content-Type' => 'application/pdf']);
|
}, 'print.pdf', ['Content-Type' => 'application/pdf']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($action == 'template' && $user->can('view', $purchase_orders->first())) {
|
||||||
|
|
||||||
|
$hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
|
||||||
|
|
||||||
|
TemplateAction::dispatch(
|
||||||
|
$purchase_orders->pluck('hashed_id')->toArray(),
|
||||||
|
$request->template_id,
|
||||||
|
PurchaseOrder::class,
|
||||||
|
$user->id,
|
||||||
|
$user->company(),
|
||||||
|
$user->company()->db,
|
||||||
|
$hash_or_response,
|
||||||
|
$request->boolean('send_email')
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash_or_response], 200);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the other actions to the switch
|
* Send the other actions to the switch
|
||||||
*/
|
*/
|
||||||
|
@ -11,40 +11,41 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\Quote\QuoteWasCreated;
|
use App\Utils\Ninja;
|
||||||
use App\Events\Quote\QuoteWasUpdated;
|
use App\Models\Quote;
|
||||||
use App\Factory\CloneQuoteFactory;
|
use App\Models\Client;
|
||||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
use App\Models\Account;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Project;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use App\Factory\QuoteFactory;
|
use App\Factory\QuoteFactory;
|
||||||
use App\Filters\QuoteFilters;
|
use App\Filters\QuoteFilters;
|
||||||
use App\Http\Requests\Quote\ActionQuoteRequest;
|
use App\Jobs\Quote\ZipQuotes;
|
||||||
use App\Http\Requests\Quote\BulkActionQuoteRequest;
|
use Illuminate\Http\Response;
|
||||||
use App\Http\Requests\Quote\CreateQuoteRequest;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Http\Requests\Quote\DestroyQuoteRequest;
|
use App\Factory\CloneQuoteFactory;
|
||||||
|
use App\Services\PdfMaker\PdfMerge;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
use App\Events\Quote\QuoteWasCreated;
|
||||||
|
use App\Events\Quote\QuoteWasUpdated;
|
||||||
|
use App\Repositories\QuoteRepository;
|
||||||
|
use App\Transformers\QuoteTransformer;
|
||||||
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Transformers\InvoiceTransformer;
|
||||||
|
use App\Transformers\ProjectTransformer;
|
||||||
|
use App\Services\Template\TemplateAction;
|
||||||
|
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||||
use App\Http\Requests\Quote\EditQuoteRequest;
|
use App\Http\Requests\Quote\EditQuoteRequest;
|
||||||
use App\Http\Requests\Quote\ShowQuoteRequest;
|
use App\Http\Requests\Quote\ShowQuoteRequest;
|
||||||
use App\Http\Requests\Quote\StoreQuoteRequest;
|
use App\Http\Requests\Quote\StoreQuoteRequest;
|
||||||
|
use App\Http\Requests\Quote\ActionQuoteRequest;
|
||||||
|
use App\Http\Requests\Quote\CreateQuoteRequest;
|
||||||
use App\Http\Requests\Quote\UpdateQuoteRequest;
|
use App\Http\Requests\Quote\UpdateQuoteRequest;
|
||||||
use App\Http\Requests\Quote\UploadQuoteRequest;
|
use App\Http\Requests\Quote\UploadQuoteRequest;
|
||||||
use App\Jobs\Quote\ZipQuotes;
|
use App\Http\Requests\Quote\DestroyQuoteRequest;
|
||||||
use App\Models\Account;
|
use App\Http\Requests\Quote\BulkActionQuoteRequest;
|
||||||
use App\Models\Client;
|
|
||||||
use App\Models\Invoice;
|
|
||||||
use App\Models\Project;
|
|
||||||
use App\Models\Quote;
|
|
||||||
use App\Repositories\QuoteRepository;
|
|
||||||
use App\Services\PdfMaker\PdfMerge;
|
|
||||||
use App\Transformers\InvoiceTransformer;
|
|
||||||
use App\Transformers\ProjectTransformer;
|
|
||||||
use App\Transformers\QuoteTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\GeneratesCounter;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Illuminate\Support\Facades\App;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class QuoteController.
|
* Class QuoteController.
|
||||||
@ -517,9 +518,9 @@ class QuoteController extends BaseController
|
|||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$action = request()->input('action');
|
$action = $request->input('action');
|
||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = $request->input('ids');
|
||||||
|
|
||||||
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->account->account_sms_verified) {
|
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->account->account_sms_verified) {
|
||||||
return response(['message' => 'Please verify your account to send emails.'], 400);
|
return response(['message' => 'Please verify your account to send emails.'], 400);
|
||||||
@ -584,6 +585,28 @@ class QuoteController extends BaseController
|
|||||||
return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
return $this->listResponse(Quote::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($action == 'template' && $user->can('view', $quotes->first())) {
|
||||||
|
|
||||||
|
$hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
|
||||||
|
|
||||||
|
TemplateAction::dispatch(
|
||||||
|
$ids,
|
||||||
|
$request->template_id,
|
||||||
|
Quote::class,
|
||||||
|
$user->id,
|
||||||
|
$user->company(),
|
||||||
|
$user->company()->db,
|
||||||
|
$hash_or_response,
|
||||||
|
$request->boolean('send_email')
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash_or_response], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the other actions to the switch
|
* Send the other actions to the switch
|
||||||
*/
|
*/
|
||||||
@ -720,11 +743,9 @@ class QuoteController extends BaseController
|
|||||||
break;
|
break;
|
||||||
case 'download':
|
case 'download':
|
||||||
|
|
||||||
$file = $quote->service()->getQuotePdf();
|
return response()->streamDownload(function () use ($quote) {
|
||||||
|
echo $quote->service()->getQuotePdf();
|
||||||
return response()->streamDownload(function () use ($file) {
|
}, $quote->getFileName(), ['Content-Type' => 'application/pdf']);
|
||||||
echo $file;
|
|
||||||
}, $quote->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']);
|
|
||||||
|
|
||||||
case 'restore':
|
case 'restore':
|
||||||
$this->quote_repo->restore($quote);
|
$this->quote_repo->restore($quote);
|
||||||
@ -833,11 +854,9 @@ class QuoteController extends BaseController
|
|||||||
$headers = array_merge($headers, ['Content-Disposition' => 'inline']);
|
$headers = array_merge($headers, ['Content-Disposition' => 'inline']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = $quote->service()->getQuotePdf($contact);
|
return response()->streamDownload(function () use ($quote,$contact) {
|
||||||
|
echo $quote->service()->getQuotePdf($contact);
|
||||||
return response()->streamDownload(function () use ($file) {
|
}, $quote->getFileName(), $headers);
|
||||||
echo $file;
|
|
||||||
}, $quote->numberFormatter().".pdf", $headers);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ class SearchController extends Controller
|
|||||||
'integrations,api_tokens' => '/settings/integrations/api_tokens',
|
'integrations,api_tokens' => '/settings/integrations/api_tokens',
|
||||||
'integrations,api_webhooks' => '/settings/integrations/api_webhooks',
|
'integrations,api_webhooks' => '/settings/integrations/api_webhooks',
|
||||||
'integrations,analytics' => '/settings/integrations/analytics',
|
'integrations,analytics' => '/settings/integrations/analytics',
|
||||||
'gateways' => '/settings/gateways',
|
'gateways' => '/settings/online_payments',
|
||||||
'gateways,create' => '/settings/gateways/create',
|
'gateways,create' => '/settings/gateways/create',
|
||||||
'bank_accounts,transaction_rules' => '/settings/bank_accounts/transaction_rules',
|
'bank_accounts,transaction_rules' => '/settings/bank_accounts/transaction_rules',
|
||||||
'bank_accounts,transaction_rules/create' => '/settings/bank_accounts/transaction_rules/create',
|
'bank_accounts,transaction_rules/create' => '/settings/bank_accounts/transaction_rules/create',
|
||||||
|
@ -51,7 +51,7 @@ class StripeConnectController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$stripe_client_id = config('ninja.ninja_stripe_client_id');
|
$stripe_client_id = config('ninja.ninja_stripe_client_id');
|
||||||
$redirect_uri = 'https://invoicing.co/stripe/completed';
|
$redirect_uri = config('ninja.app_url').'/stripe/completed';
|
||||||
$endpoint = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id={$stripe_client_id}&redirect_uri={$redirect_uri}&scope=read_write&state={$token}";
|
$endpoint = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id={$stripe_client_id}&redirect_uri={$redirect_uri}&scope=read_write&state={$token}";
|
||||||
|
|
||||||
return redirect($endpoint);
|
return redirect($endpoint);
|
||||||
@ -139,9 +139,9 @@ class StripeConnectController extends BaseController
|
|||||||
|
|
||||||
// StripeWebhook::dispatch($company->company_key, $company_gateway->id);
|
// StripeWebhook::dispatch($company->company_key, $company_gateway->id);
|
||||||
if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) {
|
if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) {
|
||||||
$redirect_uri = 'https://app.invoicing.co/#/settings/online_payments';
|
$redirect_uri = config('ninja.react_url').'/#/settings/online_payments';
|
||||||
} else {
|
} else {
|
||||||
$redirect_uri = 'https://invoicing.co/stripe/completed';
|
$redirect_uri = config('ninja.app_url').'/stripe/completed';
|
||||||
}
|
}
|
||||||
|
|
||||||
//response here
|
//response here
|
||||||
|
@ -11,29 +11,31 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Events\Task\TaskWasCreated;
|
use App\Models\Task;
|
||||||
use App\Events\Task\TaskWasUpdated;
|
use App\Utils\Ninja;
|
||||||
|
use App\Models\Account;
|
||||||
|
use App\Models\TaskStatus;
|
||||||
use App\Factory\TaskFactory;
|
use App\Factory\TaskFactory;
|
||||||
use App\Filters\TaskFilters;
|
use App\Filters\TaskFilters;
|
||||||
use App\Http\Requests\Task\CreateTaskRequest;
|
use Illuminate\Http\Response;
|
||||||
use App\Http\Requests\Task\DestroyTaskRequest;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use App\Events\Task\TaskWasCreated;
|
||||||
|
use App\Events\Task\TaskWasUpdated;
|
||||||
|
use App\Repositories\TaskRepository;
|
||||||
|
use App\Utils\Traits\SavesDocuments;
|
||||||
|
use App\Transformers\TaskTransformer;
|
||||||
|
use App\Services\Template\TemplateAction;
|
||||||
|
use App\Http\Requests\Task\BulkTaskRequest;
|
||||||
use App\Http\Requests\Task\EditTaskRequest;
|
use App\Http\Requests\Task\EditTaskRequest;
|
||||||
use App\Http\Requests\Task\ShowTaskRequest;
|
use App\Http\Requests\Task\ShowTaskRequest;
|
||||||
use App\Http\Requests\Task\SortTaskRequest;
|
use App\Http\Requests\Task\SortTaskRequest;
|
||||||
use App\Http\Requests\Task\StoreTaskRequest;
|
use App\Http\Requests\Task\StoreTaskRequest;
|
||||||
|
use App\Http\Requests\Task\CreateTaskRequest;
|
||||||
use App\Http\Requests\Task\UpdateTaskRequest;
|
use App\Http\Requests\Task\UpdateTaskRequest;
|
||||||
use App\Http\Requests\Task\UploadTaskRequest;
|
use App\Http\Requests\Task\UploadTaskRequest;
|
||||||
use App\Models\Account;
|
use App\Http\Requests\Task\DestroyTaskRequest;
|
||||||
use App\Models\Task;
|
|
||||||
use App\Models\TaskStatus;
|
|
||||||
use App\Repositories\TaskRepository;
|
|
||||||
use App\Transformers\TaskTransformer;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Utils\Traits\BulkOptions;
|
|
||||||
use App\Utils\Traits\MakesHash;
|
|
||||||
use App\Utils\Traits\SavesDocuments;
|
|
||||||
use App\Utils\Traits\Uploadable;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TaskController.
|
* Class TaskController.
|
||||||
@ -497,16 +499,36 @@ class TaskController extends BaseController
|
|||||||
* ),
|
* ),
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
public function bulk()
|
public function bulk(BulkTaskRequest $request)
|
||||||
{
|
{
|
||||||
$action = request()->input('action');
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$ids = request()->input('ids');
|
$action = $request->input('action');
|
||||||
$tasks = Task::withTrashed()->find($this->transformKeys($ids));
|
|
||||||
|
|
||||||
$tasks->each(function ($task, $key) use ($action) {
|
$ids = $request->input('ids');
|
||||||
/** @var \App\Models\User $user */
|
|
||||||
$user = auth()->user();
|
$tasks = Task::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
||||||
|
|
||||||
|
if($action == 'template' && $user->can('view', $tasks->first())) {
|
||||||
|
|
||||||
|
$hash_or_response = request()->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid();
|
||||||
|
|
||||||
|
TemplateAction::dispatch(
|
||||||
|
$tasks->pluck('hashed_id')->toArray(),
|
||||||
|
$request->template_id,
|
||||||
|
Task::class,
|
||||||
|
$user->id,
|
||||||
|
$user->company(),
|
||||||
|
$user->company()->db,
|
||||||
|
$hash_or_response,
|
||||||
|
$request->boolean('send_email')
|
||||||
|
);
|
||||||
|
|
||||||
|
return response()->json(['message' => $hash_or_response], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tasks->each(function ($task) use ($action, $user) {
|
||||||
if ($user->can('edit', $task)) {
|
if ($user->can('edit', $task)) {
|
||||||
$this->task_repo->{$action}($task);
|
$this->task_repo->{$action}($task);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class ContactRegister
|
|||||||
$domain_name = $request->getHost();
|
$domain_name = $request->getHost();
|
||||||
|
|
||||||
/* Hosted */
|
/* Hosted */
|
||||||
if (strpos($domain_name, 'invoicing.co') !== false) {
|
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
|
||||||
$subdomain = explode('.', $domain_name)[0];
|
$subdomain = explode('.', $domain_name)[0];
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
|
@ -17,6 +17,48 @@ use Illuminate\Support\Facades\App;
|
|||||||
|
|
||||||
class Locale
|
class Locale
|
||||||
{
|
{
|
||||||
|
private array $locales = [
|
||||||
|
'en',
|
||||||
|
'it',
|
||||||
|
'de',
|
||||||
|
'fr',
|
||||||
|
'pt_BR',
|
||||||
|
'nl',
|
||||||
|
'es',
|
||||||
|
'nb_NO',
|
||||||
|
'da',
|
||||||
|
'ja',
|
||||||
|
'sv',
|
||||||
|
'es_ES',
|
||||||
|
'fr_CA',
|
||||||
|
'lt',
|
||||||
|
'pl',
|
||||||
|
'cs',
|
||||||
|
'hr',
|
||||||
|
'sq',
|
||||||
|
'el',
|
||||||
|
'en_GB',
|
||||||
|
'pt_PT',
|
||||||
|
'sl',
|
||||||
|
'fi',
|
||||||
|
'ro',
|
||||||
|
'tr_TR',
|
||||||
|
'th',
|
||||||
|
'mk_MK',
|
||||||
|
'zh_TW',
|
||||||
|
'ru_RU',
|
||||||
|
'ar',
|
||||||
|
'fa',
|
||||||
|
'lv_LV',
|
||||||
|
'sr',
|
||||||
|
'sk',
|
||||||
|
'et',
|
||||||
|
'bg',
|
||||||
|
'he',
|
||||||
|
'km_KH',
|
||||||
|
'hu',
|
||||||
|
'fr_CH',
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
@ -27,8 +69,8 @@ class Locale
|
|||||||
public function handle($request, Closure $next)
|
public function handle($request, Closure $next)
|
||||||
{
|
{
|
||||||
/*LOCALE SET */
|
/*LOCALE SET */
|
||||||
if ($request->has('lang') && is_string($request->input('lang'))) {
|
if ($request->has('lang') && in_array($request->input('lang','en'), $this->locales) ) {
|
||||||
$locale = $request->string('lang','en');
|
$locale = $request->input('lang');
|
||||||
App::setLocale($locale);
|
App::setLocale($locale);
|
||||||
} elseif (auth()->guard('contact')->user()) {
|
} elseif (auth()->guard('contact')->user()) {
|
||||||
App::setLocale(auth()->guard('contact')->user()->client()->setEagerLoads([])->first()->locale());
|
App::setLocale(auth()->guard('contact')->user()->client()->setEagerLoads([])->first()->locale());
|
||||||
|
@ -32,8 +32,7 @@ class SessionDomains
|
|||||||
|
|
||||||
$domain_name = $request->getHost();
|
$domain_name = $request->getHost();
|
||||||
|
|
||||||
if (strpos($domain_name, 'invoicing.co') !== false) {
|
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
|
||||||
// config(['session.domain' => '.invoicing.co']);
|
|
||||||
} else {
|
} else {
|
||||||
config(['session.domain' => $domain_name]);
|
config(['session.domain' => $domain_name]);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class SetDomainNameDb
|
|||||||
|
|
||||||
$domain_name = $request->getHost();
|
$domain_name = $request->getHost();
|
||||||
|
|
||||||
if (strpos($domain_name, 'invoicing.co') !== false) {
|
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
|
||||||
$subdomain = explode('.', $domain_name)[0];
|
$subdomain = explode('.', $domain_name)[0];
|
||||||
|
|
||||||
$query = [
|
$query = [
|
||||||
|
@ -17,6 +17,48 @@ use Illuminate\Support\Facades\App;
|
|||||||
|
|
||||||
class VendorLocale
|
class VendorLocale
|
||||||
{
|
{
|
||||||
|
private array $locales = [
|
||||||
|
'en',
|
||||||
|
'it',
|
||||||
|
'de',
|
||||||
|
'fr',
|
||||||
|
'pt_BR',
|
||||||
|
'nl',
|
||||||
|
'es',
|
||||||
|
'nb_NO',
|
||||||
|
'da',
|
||||||
|
'ja',
|
||||||
|
'sv',
|
||||||
|
'es_ES',
|
||||||
|
'fr_CA',
|
||||||
|
'lt',
|
||||||
|
'pl',
|
||||||
|
'cs',
|
||||||
|
'hr',
|
||||||
|
'sq',
|
||||||
|
'el',
|
||||||
|
'en_GB',
|
||||||
|
'pt_PT',
|
||||||
|
'sl',
|
||||||
|
'fi',
|
||||||
|
'ro',
|
||||||
|
'tr_TR',
|
||||||
|
'th',
|
||||||
|
'mk_MK',
|
||||||
|
'zh_TW',
|
||||||
|
'ru_RU',
|
||||||
|
'ar',
|
||||||
|
'fa',
|
||||||
|
'lv_LV',
|
||||||
|
'sr',
|
||||||
|
'sk',
|
||||||
|
'et',
|
||||||
|
'bg',
|
||||||
|
'he',
|
||||||
|
'km_KH',
|
||||||
|
'hu',
|
||||||
|
'fr_CH',
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
@ -32,7 +74,7 @@ class VendorLocale
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*LOCALE SET */
|
/*LOCALE SET */
|
||||||
if ($request->has('lang') && is_string($request->input('lang'))) {
|
if ($request->has('lang') && in_array($request->input('lang','en'), $this->locales) ) {
|
||||||
$locale = $request->input('lang');
|
$locale = $request->input('lang');
|
||||||
App::setLocale($locale);
|
App::setLocale($locale);
|
||||||
} elseif (auth()->guard('vendor')->user()) {
|
} elseif (auth()->guard('vendor')->user()) {
|
||||||
|
@ -45,10 +45,15 @@ class CreateAccountRequest extends Request
|
|||||||
return [
|
return [
|
||||||
'first_name' => 'string|max:100',
|
'first_name' => 'string|max:100',
|
||||||
'last_name' => 'string:max:100',
|
'last_name' => 'string:max:100',
|
||||||
'password' => 'required|string|min:6|max:1000',
|
'password' => 'required|string|min:6|max:100',
|
||||||
'email' => $email_rules,
|
'email' => $email_rules,
|
||||||
'privacy_policy' => 'required|boolean',
|
'privacy_policy' => 'required|boolean',
|
||||||
'terms_of_service' => 'required|boolean',
|
'terms_of_service' => 'required|boolean',
|
||||||
|
'utm_source' => 'sometimes|nullable|string',
|
||||||
|
'utm_medium' => 'sometimes|nullable|string',
|
||||||
|
'utm_campaign' => 'sometimes|nullable|string',
|
||||||
|
'utm_term' => 'sometimes|nullable|string',
|
||||||
|
'utm_content' => 'sometimes|nullable|string',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +35,13 @@ class BulkClientRequest extends Request
|
|||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
'action' => 'required|string|in:archive,restore,delete,template',
|
||||||
'ids' => ['required','bail','array',Rule::exists('clients', 'id')->where('company_id', $user->company()->id)],
|
'ids' => ['required','bail','array',Rule::exists('clients', 'id')->where('company_id', $user->company()->id)],
|
||||||
'action' => 'in:archive,restore,delete'
|
'template' => 'sometimes|string',
|
||||||
|
'template_id' => 'sometimes|string',
|
||||||
|
'send_email' => 'sometimes|bool'
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Requests\CompanyGateway;
|
namespace App\Http\Requests\CompanyGateway;
|
||||||
|
|
||||||
|
use App\DataMapper\FeesAndLimits;
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Http\ValidationRules\ValidCompanyGatewayFeesAndLimitsRule;
|
use App\Http\ValidationRules\ValidCompanyGatewayFeesAndLimitsRule;
|
||||||
use App\Models\Gateway;
|
use App\Models\Gateway;
|
||||||
@ -28,7 +29,10 @@ class StoreCompanyGatewayRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->isAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
@ -64,6 +68,7 @@ class StoreCompanyGatewayRequest extends Request
|
|||||||
if (isset($input['fees_and_limits'])) {
|
if (isset($input['fees_and_limits'])) {
|
||||||
$input['fees_and_limits'] = $this->cleanFeesAndLimits($input['fees_and_limits']);
|
$input['fees_and_limits'] = $this->cleanFeesAndLimits($input['fees_and_limits']);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
|
@ -27,7 +27,10 @@ class UpdateCompanyGatewayRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize()
|
public function authorize()
|
||||||
{
|
{
|
||||||
return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->isAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
|
@ -35,9 +35,15 @@ class BulkCreditRequest extends FormRequest
|
|||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'ids' => ['required','bail','array',Rule::exists('credits', 'id')->where('company_id', auth()->user()->company()->id)],
|
'ids' => ['required','bail','array',Rule::exists('credits', 'id')->where('company_id', $user->company()->id)],
|
||||||
'action' => 'required|bail|in:archive,restore,delete,email,bulk_download,bulk_print,mark_paid,clone_to_credit,history,mark_sent,download,send_email'
|
'action' => 'required|bail|in:archive,restore,delete,email,bulk_download,bulk_print,mark_paid,clone_to_credit,history,mark_sent,download,send_email,template',
|
||||||
|
'template' => 'sometimes|string',
|
||||||
|
'template_id' => 'sometimes|string',
|
||||||
|
'send_email' => 'sometimes|bool'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,10 @@ class SendEmailRequest extends Request
|
|||||||
'template' => 'bail|required',
|
'template' => 'bail|required',
|
||||||
'entity' => 'bail|required',
|
'entity' => 'bail|required',
|
||||||
'entity_id' => 'bail|required',
|
'entity_id' => 'bail|required',
|
||||||
'cc_email' => 'bail|sometimes|email|nullable',
|
'cc_email.*' => 'bail|sometimes|email',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
@ -72,6 +74,14 @@ class SendEmailRequest extends Request
|
|||||||
$input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
|
$input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isset($input['cc_email'])){
|
||||||
|
$input['cc_email'] = collect(explode(",", $input['cc_email']))->map(function($email){
|
||||||
|
return trim($email);
|
||||||
|
})->filter(function($email){
|
||||||
|
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
|
})->slice(0,4)->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,34 +28,45 @@ class StoreExpenseRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->can('create', Expense::class);
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->can('create', Expense::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$rules = [];
|
$rules = [];
|
||||||
|
|
||||||
if ($this->number) {
|
if ($this->number) {
|
||||||
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id);
|
$rules['number'] = Rule::unique('expenses')->where('company_id', $user->company()->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->client_id) {
|
if ($this->client_id) {
|
||||||
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
|
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.$user->company()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
$rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.$user->company()->id.',is_deleted,0';
|
||||||
|
$rules['payment_date'] = 'bail|nullable|sometimes|date:Y-m-d';
|
||||||
|
$rules['date'] = 'bail|sometimes|date:Y-m-d';
|
||||||
|
|
||||||
return $this->globalRules($rules);
|
return $this->globalRules($rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
$input = $this->decodePrimaryKeys($input);
|
$input = $this->decodePrimaryKeys($input);
|
||||||
|
|
||||||
if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
|
if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
|
||||||
$input['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
|
$input['currency_id'] = (string) $user->company()->settings->currency_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('color', $input) && is_null($input['color'])) {
|
if (array_key_exists('color', $input) && is_null($input['color'])) {
|
||||||
@ -80,7 +91,6 @@ class StoreExpenseRequest extends Request
|
|||||||
public function messages()
|
public function messages()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
// 'unique' => ctrans('validation.unique', ['attribute' => 'number']),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,10 @@ class ImportRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->isAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
|
40
app/Http/Requests/Payment/BulkActionPaymentRequest.php
Normal file
40
app/Http/Requests/Payment/BulkActionPaymentRequest.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Payment;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
|
||||||
|
class BulkActionPaymentRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
return [
|
||||||
|
'action' => 'required|string',
|
||||||
|
'ids' => 'required|array',
|
||||||
|
'template' => 'sometimes|string',
|
||||||
|
'template_id' => 'sometimes|string',
|
||||||
|
'send_email' => 'sometimes|bool'
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -93,7 +93,7 @@ class StorePaymentRequest extends Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! isset($input['date'])) {
|
if (! isset($input['date'])) {
|
||||||
$input['date'] = now()->addSeconds($user->company()->timezone()->utc_offset)->format('Y-m-d');
|
$input['date'] = now()->addSeconds($user->company()->utc_offset())->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! isset($input['idempotency_key'])) {
|
if (! isset($input['idempotency_key'])) {
|
||||||
|
45
app/Http/Requests/Project/BulkProjectRequest.php
Normal file
45
app/Http/Requests/Project/BulkProjectRequest.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Project;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
|
||||||
|
class BulkProjectRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
return [
|
||||||
|
'action' => 'required|string',
|
||||||
|
'ids' => 'required|array',
|
||||||
|
'template' => 'sometimes|string',
|
||||||
|
'template_id' => 'sometimes|string',
|
||||||
|
'send_email' => 'sometimes|bool'
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,10 @@ class BulkPurchaseOrderRequest extends Request
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'ids' => 'required|bail|array|min:1',
|
'ids' => 'required|bail|array|min:1',
|
||||||
'action' => 'in:archive,restore,delete,email,bulk_download,bulk_print,mark_sent,download,send_email,add_to_inventory,expense,cancel'
|
'action' => 'in:template,archive,restore,delete,email,bulk_download,bulk_print,mark_sent,download,send_email,add_to_inventory,expense,cancel',
|
||||||
|
'template' => 'sometimes|string',
|
||||||
|
'template_id' => 'sometimes|string',
|
||||||
|
'send_email' => 'sometimes|bool'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,11 @@ class BulkActionQuoteRequest extends Request
|
|||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
$rules = [
|
$rules = [
|
||||||
'action' => 'sometimes|in:convert_to_invoice,convert_to_project,email,bulk_download,bulk_print,clone_to_invoice,approve,download,restore,archive,delete,send_email,mark_sent',
|
'action' => 'sometimes|in:template,convert_to_invoice,convert_to_project,email,bulk_download,bulk_print,clone_to_invoice,approve,download,restore,archive,delete,send_email,mark_sent',
|
||||||
|
'ids' => 'required|array',
|
||||||
|
'template' => 'sometimes|string',
|
||||||
|
'template_id' => 'sometimes|string',
|
||||||
|
'send_email' => 'sometimes|bool'
|
||||||
];
|
];
|
||||||
|
|
||||||
if (in_array($input['action'], ['convert,convert_to_invoice'])) {
|
if (in_array($input['action'], ['convert,convert_to_invoice'])) {
|
||||||
|
@ -12,12 +12,9 @@
|
|||||||
namespace App\Http\Requests\Task;
|
namespace App\Http\Requests\Task;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Models\Task;
|
|
||||||
use App\Utils\Traits\BulkOptions;
|
|
||||||
|
|
||||||
class BulkTaskRequest extends Request
|
class BulkTaskRequest extends Request
|
||||||
{
|
{
|
||||||
use BulkOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the user is authorized to make this request.
|
* Determine if the user is authorized to make this request.
|
||||||
@ -26,7 +23,7 @@ class BulkTaskRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize()
|
public function authorize()
|
||||||
{
|
{
|
||||||
return auth()->user()->can(auth()->user()->isAdmin(), Task::class);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,13 +33,14 @@ class BulkTaskRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
$rules = $this->getGlobalRules();
|
|
||||||
|
|
||||||
/* We don't require IDs on bulk storing. */
|
return [
|
||||||
if ($this->action !== self::$STORE_METHOD) {
|
'action' => 'required|string',
|
||||||
$rules['ids'] = ['required'];
|
'ids' => 'required|array',
|
||||||
}
|
'template' => 'sometimes|string',
|
||||||
|
'template_id' => 'sometimes|string',
|
||||||
|
'send_email' => 'sometimes|bool'
|
||||||
|
];
|
||||||
|
|
||||||
return $rules;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,14 +54,14 @@ class StoreTaskRequest extends Request
|
|||||||
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0';
|
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0';
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules['time_log'] = ['bail', function ($attribute, $values, $fail) {
|
$rules['time_log'] = ['bail',function ($attribute, $values, $fail) {
|
||||||
|
|
||||||
if(is_string($values)) {
|
if(is_string($values))
|
||||||
$values = json_decode($values, 1);
|
$values = json_decode($values, true);
|
||||||
}
|
|
||||||
|
|
||||||
if(!is_array($values)) {
|
if(!is_array($values)) {
|
||||||
return $fail('The '.$attribute.' is invalid. Must be an array.');
|
$fail('The '.$attribute.' must be a valid array.');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($values as $k) {
|
foreach ($values as $k) {
|
||||||
@ -119,6 +119,10 @@ class StoreTaskRequest extends Request
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!isset($input['time_log']) || empty($input['time_log']) || $input['time_log'] == '{}'){
|
||||||
|
$input['time_log'] = json_encode([]);
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ class UpdateTaskRequest extends Request
|
|||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
|
||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
@ -61,14 +60,15 @@ class UpdateTaskRequest extends Request
|
|||||||
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0';
|
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.$user->company()->id.',is_deleted,0';
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules['time_log'] = ['bail',function ($attribute, $values, $fail) {
|
$rules['time_log'] = ['bail', function ($attribute, $values, $fail) {
|
||||||
|
|
||||||
if(is_string($values)) {
|
if(is_string($values)) {
|
||||||
$values = json_decode($values, 1);
|
$values = json_decode($values, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_array($values)) {
|
if(!is_array($values)) {
|
||||||
return $fail('The '.$attribute.' is invalid. Must be an array.');
|
$fail('The '.$attribute.' must be a valid array.');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($values as $k) {
|
foreach ($values as $k) {
|
||||||
@ -129,6 +129,10 @@ class UpdateTaskRequest extends Request
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!isset($input['time_log']) || empty($input['time_log']) || $input['time_log'] == '{}') {
|
||||||
|
$input['time_log'] = json_encode([]);
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ use Illuminate\Contracts\Validation\Rule;
|
|||||||
class BlackListRule implements Rule
|
class BlackListRule implements Rule
|
||||||
{
|
{
|
||||||
private array $blacklist = [
|
private array $blacklist = [
|
||||||
|
'ckptr.com',
|
||||||
'pretreer.com',
|
'pretreer.com',
|
||||||
'candassociates.com',
|
'candassociates.com',
|
||||||
'vusra.com',
|
'vusra.com',
|
||||||
|
66
app/Import/Definitions/TaskMap.php
Normal file
66
app/Import/Definitions/TaskMap.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Import\Definitions;
|
||||||
|
|
||||||
|
class TaskMap
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function importable()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
0 => 'task.number',
|
||||||
|
1 => 'task.user_id',
|
||||||
|
2 => 'task.rate',
|
||||||
|
3 => 'project.name',
|
||||||
|
4 => 'client.name',
|
||||||
|
5 => 'client.email',
|
||||||
|
6 => 'task.description',
|
||||||
|
7 => 'task.billable',
|
||||||
|
8 => 'task.start_date',
|
||||||
|
9 => 'task.end_date',
|
||||||
|
10 => 'task.start_time',
|
||||||
|
11 => 'task.end_time',
|
||||||
|
12 => 'task.duration',
|
||||||
|
13 => 'task.status',
|
||||||
|
14 => 'task.custom_value1',
|
||||||
|
15 => 'task.custom_value1',
|
||||||
|
16 => 'task.custom_value1',
|
||||||
|
17 => 'task.custom_value1',
|
||||||
|
18 => 'task.notes',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function import_keys()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
0 => 'texts.task_number',
|
||||||
|
1 => 'texts.user',
|
||||||
|
2 => 'texts.task_rate',
|
||||||
|
3 => 'texts.project',
|
||||||
|
4 => 'texts.client',
|
||||||
|
5 => 'texts.client_email',
|
||||||
|
6 => 'texts.description',
|
||||||
|
7 => 'texts.billable',
|
||||||
|
8 => 'texts.start_date',
|
||||||
|
9 => 'texts.end_date',
|
||||||
|
10 => 'texts.start_time',
|
||||||
|
11 => 'texts.end_time',
|
||||||
|
12 => 'texts.duration',
|
||||||
|
13 => 'texts.status',
|
||||||
|
14 => 'texts.task1',
|
||||||
|
15 => 'texts.task2',
|
||||||
|
16 => 'texts.task3',
|
||||||
|
17 => 'texts.task4',
|
||||||
|
18 => 'texts.notes',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ use App\Factory\InvoiceFactory;
|
|||||||
use App\Factory\PaymentFactory;
|
use App\Factory\PaymentFactory;
|
||||||
use App\Factory\QuoteFactory;
|
use App\Factory\QuoteFactory;
|
||||||
use App\Factory\RecurringInvoiceFactory;
|
use App\Factory\RecurringInvoiceFactory;
|
||||||
|
use App\Factory\TaskFactory;
|
||||||
use App\Http\Requests\Quote\StoreQuoteRequest;
|
use App\Http\Requests\Quote\StoreQuoteRequest;
|
||||||
use App\Import\ImportException;
|
use App\Import\ImportException;
|
||||||
use App\Jobs\Mail\NinjaMailerJob;
|
use App\Jobs\Mail\NinjaMailerJob;
|
||||||
@ -30,6 +31,7 @@ use App\Repositories\InvoiceRepository;
|
|||||||
use App\Repositories\PaymentRepository;
|
use App\Repositories\PaymentRepository;
|
||||||
use App\Repositories\QuoteRepository;
|
use App\Repositories\QuoteRepository;
|
||||||
use App\Repositories\RecurringInvoiceRepository;
|
use App\Repositories\RecurringInvoiceRepository;
|
||||||
|
use App\Repositories\TaskRepository;
|
||||||
use App\Utils\Traits\CleanLineItems;
|
use App\Utils\Traits\CleanLineItems;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
@ -158,6 +160,33 @@ class BaseImport
|
|||||||
}, $csvData);
|
}, $csvData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function groupTasks($csvData, $key)
|
||||||
|
{
|
||||||
|
nlog($csvData[0]);
|
||||||
|
|
||||||
|
if (! $key || !is_array($csvData) || count($csvData) == 0 || !isset($csvData[0]['task.number']) || empty($csvData[0]['task.number'])) {
|
||||||
|
return $csvData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group by tasks.
|
||||||
|
$grouped = [];
|
||||||
|
|
||||||
|
foreach ($csvData as $item) {
|
||||||
|
if (empty($item[$key])) {
|
||||||
|
$this->error_array['task'][] = [
|
||||||
|
'task' => $item,
|
||||||
|
'error' => 'No task number',
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$grouped[$item[$key]][] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $grouped;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private function groupInvoices($csvData, $key)
|
private function groupInvoices($csvData, $key)
|
||||||
{
|
{
|
||||||
if (! $key) {
|
if (! $key) {
|
||||||
@ -413,6 +442,65 @@ class BaseImport
|
|||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ingestTasks($tasks, $task_number_key)
|
||||||
|
{
|
||||||
|
$count = 0;
|
||||||
|
|
||||||
|
$task_transformer = $this->transformer;
|
||||||
|
|
||||||
|
$task_repository = new TaskRepository();
|
||||||
|
|
||||||
|
$tasks = $this->groupTasks($tasks, $task_number_key);
|
||||||
|
|
||||||
|
foreach ($tasks as $raw_task) {
|
||||||
|
$task_data = [];
|
||||||
|
try {
|
||||||
|
$task_data = $task_transformer->transform($raw_task);
|
||||||
|
$task_data['user_id'] = $this->company->owner()->id;
|
||||||
|
|
||||||
|
$validator = $this->request_name::runFormRequest($task_data);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->error_array['task'][] = [
|
||||||
|
'invoice' => $task_data,
|
||||||
|
'error' => $validator->errors()->all(),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$task = TaskFactory::create(
|
||||||
|
$this->company->id,
|
||||||
|
$this->company->owner()->id
|
||||||
|
);
|
||||||
|
|
||||||
|
$task_repository->save($task_data, $task);
|
||||||
|
|
||||||
|
$count++;
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
if (\DB::connection(config('database.default'))->transactionLevel() > 0) {
|
||||||
|
\DB::connection(config('database.default'))->rollBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ex instanceof ImportException) {
|
||||||
|
$message = $ex->getMessage();
|
||||||
|
} else {
|
||||||
|
report($ex);
|
||||||
|
$message = 'Unknown error ';
|
||||||
|
nlog($ex->getMessage());
|
||||||
|
nlog($task_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->error_array['task'][] = [
|
||||||
|
'task' => $task_data,
|
||||||
|
'error' => $message,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function ingestInvoices($invoices, $invoice_number_key)
|
public function ingestInvoices($invoices, $invoice_number_key)
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@ use App\Factory\PaymentFactory;
|
|||||||
use App\Factory\ProductFactory;
|
use App\Factory\ProductFactory;
|
||||||
use App\Factory\QuoteFactory;
|
use App\Factory\QuoteFactory;
|
||||||
use App\Factory\RecurringInvoiceFactory;
|
use App\Factory\RecurringInvoiceFactory;
|
||||||
|
use App\Factory\TaskFactory;
|
||||||
use App\Factory\VendorFactory;
|
use App\Factory\VendorFactory;
|
||||||
use App\Http\Requests\BankTransaction\StoreBankTransactionRequest;
|
use App\Http\Requests\BankTransaction\StoreBankTransactionRequest;
|
||||||
use App\Http\Requests\Client\StoreClientRequest;
|
use App\Http\Requests\Client\StoreClientRequest;
|
||||||
@ -28,6 +29,7 @@ use App\Http\Requests\Payment\StorePaymentRequest;
|
|||||||
use App\Http\Requests\Product\StoreProductRequest;
|
use App\Http\Requests\Product\StoreProductRequest;
|
||||||
use App\Http\Requests\Quote\StoreQuoteRequest;
|
use App\Http\Requests\Quote\StoreQuoteRequest;
|
||||||
use App\Http\Requests\RecurringInvoice\StoreRecurringInvoiceRequest;
|
use App\Http\Requests\RecurringInvoice\StoreRecurringInvoiceRequest;
|
||||||
|
use App\Http\Requests\Task\StoreTaskRequest;
|
||||||
use App\Http\Requests\Vendor\StoreVendorRequest;
|
use App\Http\Requests\Vendor\StoreVendorRequest;
|
||||||
use App\Import\Transformer\Bank\BankTransformer;
|
use App\Import\Transformer\Bank\BankTransformer;
|
||||||
use App\Import\Transformer\Csv\ClientTransformer;
|
use App\Import\Transformer\Csv\ClientTransformer;
|
||||||
@ -37,6 +39,7 @@ use App\Import\Transformer\Csv\PaymentTransformer;
|
|||||||
use App\Import\Transformer\Csv\ProductTransformer;
|
use App\Import\Transformer\Csv\ProductTransformer;
|
||||||
use App\Import\Transformer\Csv\QuoteTransformer;
|
use App\Import\Transformer\Csv\QuoteTransformer;
|
||||||
use App\Import\Transformer\Csv\RecurringInvoiceTransformer;
|
use App\Import\Transformer\Csv\RecurringInvoiceTransformer;
|
||||||
|
use App\Import\Transformer\Csv\TaskTransformer;
|
||||||
use App\Import\Transformer\Csv\VendorTransformer;
|
use App\Import\Transformer\Csv\VendorTransformer;
|
||||||
use App\Repositories\BankTransactionRepository;
|
use App\Repositories\BankTransactionRepository;
|
||||||
use App\Repositories\ClientRepository;
|
use App\Repositories\ClientRepository;
|
||||||
@ -46,6 +49,7 @@ use App\Repositories\PaymentRepository;
|
|||||||
use App\Repositories\ProductRepository;
|
use App\Repositories\ProductRepository;
|
||||||
use App\Repositories\QuoteRepository;
|
use App\Repositories\QuoteRepository;
|
||||||
use App\Repositories\RecurringInvoiceRepository;
|
use App\Repositories\RecurringInvoiceRepository;
|
||||||
|
use App\Repositories\TaskRepository;
|
||||||
use App\Repositories\VendorRepository;
|
use App\Repositories\VendorRepository;
|
||||||
use App\Services\Bank\BankMatchingService;
|
use App\Services\Bank\BankMatchingService;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
@ -69,6 +73,7 @@ class Csv extends BaseImport implements ImportInterface
|
|||||||
'quote',
|
'quote',
|
||||||
'bank_transaction',
|
'bank_transaction',
|
||||||
'recurring_invoice',
|
'recurring_invoice',
|
||||||
|
'task',
|
||||||
])
|
])
|
||||||
) {
|
) {
|
||||||
$this->{$entity}();
|
$this->{$entity}();
|
||||||
@ -348,6 +353,33 @@ class Csv extends BaseImport implements ImportInterface
|
|||||||
|
|
||||||
public function task()
|
public function task()
|
||||||
{
|
{
|
||||||
|
$entity_type = 'task';
|
||||||
|
|
||||||
|
$data = $this->getCsvData($entity_type);
|
||||||
|
|
||||||
|
if (is_array($data)) {
|
||||||
|
$data = $this->preTransformCsv($data, $entity_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data)) {
|
||||||
|
$this->entity_count['tasks'] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->request_name = StoreTaskRequest::class;
|
||||||
|
$this->repository_name = TaskRepository::class;
|
||||||
|
$this->factory_name = TaskFactory::class;
|
||||||
|
|
||||||
|
$this->repository = app()->make($this->repository_name);
|
||||||
|
// $this->repository->import_mode = true;
|
||||||
|
|
||||||
|
$this->transformer = new TaskTransformer($this->company);
|
||||||
|
|
||||||
|
$task_count = $this->ingestTasks($data, 'task.number');
|
||||||
|
|
||||||
|
$this->entity_count['tasks'] = $task_count;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transform(array $data)
|
public function transform(array $data)
|
||||||
|
@ -179,6 +179,7 @@ class BaseTransformer
|
|||||||
|
|
||||||
public function getClient($client_name, $client_email)
|
public function getClient($client_name, $client_email)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! empty($client_name)) {
|
if (! empty($client_name)) {
|
||||||
$client_id_search = Client::query()->where('company_id', $this->company->id)
|
$client_id_search = Client::query()->where('company_id', $this->company->id)
|
||||||
->where('is_deleted', false)
|
->where('is_deleted', false)
|
||||||
@ -676,6 +677,9 @@ class BaseTransformer
|
|||||||
*/
|
*/
|
||||||
public function getProjectId($name, $clientId = null)
|
public function getProjectId($name, $clientId = null)
|
||||||
{
|
{
|
||||||
|
if(strlen($name) == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
$project = Project::query()->where('company_id', $this->company->id)
|
$project = Project::query()->where('company_id', $this->company->id)
|
||||||
->where('is_deleted', false)
|
->where('is_deleted', false)
|
||||||
->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [
|
->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [
|
||||||
|
173
app/Import/Transformer/Csv/TaskTransformer.php
Normal file
173
app/Import/Transformer/Csv/TaskTransformer.php
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Import\Transformer\Csv;
|
||||||
|
|
||||||
|
use App\Models\TaskStatus;
|
||||||
|
use App\Import\Transformer\BaseTransformer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TaskTransformer.
|
||||||
|
*/
|
||||||
|
class TaskTransformer extends BaseTransformer
|
||||||
|
{
|
||||||
|
private int $stubbed_timestamp = 0;
|
||||||
|
/**
|
||||||
|
* @param $data
|
||||||
|
*
|
||||||
|
* @return bool|array
|
||||||
|
*/
|
||||||
|
public function transform($task_items_data)
|
||||||
|
{
|
||||||
|
$this->stubbed_timestamp = time();
|
||||||
|
|
||||||
|
if(count($task_items_data) == count($task_items_data, COUNT_RECURSIVE))
|
||||||
|
$task_data = $task_items_data;
|
||||||
|
else
|
||||||
|
$task_data = reset($task_items_data);
|
||||||
|
|
||||||
|
$clientId = $this->getClient(
|
||||||
|
$this->getString($task_data, 'client.name'),
|
||||||
|
$this->getString($task_data, 'client.email')
|
||||||
|
);
|
||||||
|
|
||||||
|
$projectId = $task_data['project.name'] ?? '';
|
||||||
|
|
||||||
|
$transformed = [
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'number' => $this->getString($task_data, 'task.number'),
|
||||||
|
'user_id' => $this->getString($task_data, 'task.user_id'),
|
||||||
|
'client_id' => $clientId,
|
||||||
|
'project_id' => $this->getProjectId($projectId, $clientId),
|
||||||
|
'description' => $this->getString($task_data, 'task.description'),
|
||||||
|
'status' => $this->getTaskStatusId($task_data),
|
||||||
|
'custom_value1' => $this->getString($task_data, 'task.custom_value1'),
|
||||||
|
'custom_value2' => $this->getString($task_data, 'task.custom_value2'),
|
||||||
|
'custom_value3' => $this->getString($task_data, 'task.custom_value3'),
|
||||||
|
'custom_value4' => $this->getString($task_data, 'task.custom_value4'),
|
||||||
|
];
|
||||||
|
|
||||||
|
if(count($task_items_data) == count($task_items_data, COUNT_RECURSIVE)) {
|
||||||
|
$transformed['time_log'] = json_encode([$this->parseLog($task_items_data)]);
|
||||||
|
return $transformed;
|
||||||
|
}
|
||||||
|
|
||||||
|
$time_log = collect($task_items_data)
|
||||||
|
->map(function ($item) {
|
||||||
|
|
||||||
|
return $this->parseLog($item);
|
||||||
|
|
||||||
|
})->toJson();
|
||||||
|
|
||||||
|
$transformed['time_log'] = $time_log;
|
||||||
|
|
||||||
|
return $transformed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseLog($item)
|
||||||
|
{
|
||||||
|
$start_date = false;
|
||||||
|
$end_date = false;
|
||||||
|
|
||||||
|
$notes = $item['task.notes'] ?? '';
|
||||||
|
|
||||||
|
if(isset($item['task.is_billable']) && is_string($item['task.is_billable']) && in_array($item['task.is_billable'], ['yes', 'true', '1']))
|
||||||
|
$is_billable = true;
|
||||||
|
elseif(isset($item['task.is_billable']) && is_bool($item['task.is_billable']))
|
||||||
|
$is_billable = $item['task.is_billable'];
|
||||||
|
else
|
||||||
|
$is_billable = false;
|
||||||
|
|
||||||
|
if(isset($item['task.start_date']) &&
|
||||||
|
isset($item['task.end_date'])) {
|
||||||
|
$start_date = $this->resolveStartDate($item);
|
||||||
|
$end_date = $this->resolveEndDate($item);
|
||||||
|
} elseif(isset($item['task.duration'])) {
|
||||||
|
$duration = strtotime($item['task.duration']) - strtotime('TODAY');
|
||||||
|
$start_date = $this->stubbed_timestamp;
|
||||||
|
$end_date = $this->stubbed_timestamp + $duration;
|
||||||
|
$this->stubbed_timestamp;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$start_date, $end_date, $notes, $is_billable];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveStartDate($item)
|
||||||
|
{
|
||||||
|
|
||||||
|
$stub_start_date = $item['task.start_date'];
|
||||||
|
$stub_start_date .= isset($item['task.start_time']) ? " ".$item['task.start_time'] : '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$stub_start_date = \Carbon\Carbon::parse($stub_start_date);
|
||||||
|
$this->stubbed_timestamp = $stub_start_date->timestamp;
|
||||||
|
|
||||||
|
return $stub_start_date->timestamp;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
nlog($e->getMessage());
|
||||||
|
return $this->stubbed_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveEndDate($item)
|
||||||
|
{
|
||||||
|
|
||||||
|
$stub_end_date = $item['task.end_date'];
|
||||||
|
$stub_end_date .= isset($item['task.end_time']) ? " ".$item['task.end_time'] : '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$stub_end_date = \Carbon\Carbon::parse($stub_end_date);
|
||||||
|
|
||||||
|
if($stub_end_date->timestamp == $this->stubbed_timestamp) {
|
||||||
|
$this->stubbed_timestamp;
|
||||||
|
return $this->stubbed_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->stubbed_timestamp = $stub_end_date->timestamp;
|
||||||
|
return $stub_end_date->timestamp;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
nlog($e->getMessage());
|
||||||
|
|
||||||
|
return $this->stubbed_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTaskStatusId($item): ?int
|
||||||
|
{
|
||||||
|
if(isset($item['task.status']))
|
||||||
|
{
|
||||||
|
$name = strtolower(trim($item['task.status']));
|
||||||
|
|
||||||
|
$ts = TaskStatus::query()->where('company_id', $this->company->id)
|
||||||
|
->where('is_deleted', false)
|
||||||
|
->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [
|
||||||
|
strtolower(str_replace(' ', '', $name)),
|
||||||
|
])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if($ts)
|
||||||
|
return $ts->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskStatus::where('company_id', $this->company->id)
|
||||||
|
->where('is_deleted', false)
|
||||||
|
->orderBy('status_order', 'asc')
|
||||||
|
->first()->id ?? null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -92,6 +92,8 @@ class CreateAccount
|
|||||||
|
|
||||||
$spaa9f78 = (new CreateUser($this->request, $sp794f3f, $sp035a66, true))->handle();
|
$spaa9f78 = (new CreateUser($this->request, $sp794f3f, $sp035a66, true))->handle();
|
||||||
|
|
||||||
|
$sp035a66->service()->localizeCompany($spaa9f78);
|
||||||
|
|
||||||
(new CreateCompanyPaymentTerms($sp035a66, $spaa9f78))->handle();
|
(new CreateCompanyPaymentTerms($sp035a66, $spaa9f78))->handle();
|
||||||
(new CreateCompanyTaskStatuses($sp035a66, $spaa9f78))->handle();
|
(new CreateCompanyTaskStatuses($sp035a66, $spaa9f78))->handle();
|
||||||
|
|
||||||
@ -124,8 +126,6 @@ class CreateAccount
|
|||||||
|
|
||||||
NinjaMailerJob::dispatch($nmo, true);
|
NinjaMailerJob::dispatch($nmo, true);
|
||||||
|
|
||||||
// \Modules\Admin\Jobs\Account\NinjaUser::dispatch([], $sp035a66);
|
|
||||||
|
|
||||||
(new \Modules\Admin\Jobs\Account\NinjaUser([], $sp035a66))->handle();
|
(new \Modules\Admin\Jobs\Account\NinjaUser([], $sp035a66))->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +492,7 @@ class CompanyExport implements ShouldQueue
|
|||||||
$nmo->company = $company_reference;
|
$nmo->company = $company_reference;
|
||||||
$nmo->settings = $this->company->settings;
|
$nmo->settings = $this->company->settings;
|
||||||
|
|
||||||
NinjaMailerJob::dispatch($nmo, true);
|
(new NinjaMailerJob($nmo, true))->handle();
|
||||||
|
|
||||||
UnlinkFile::dispatch(config('filesystems.default'), $storage_path)->delay(now()->addHours(1));
|
UnlinkFile::dispatch(config('filesystems.default'), $storage_path)->delay(now()->addHours(1));
|
||||||
|
|
||||||
|
@ -1152,7 +1152,7 @@ class CompanyImport implements ShouldQueue
|
|||||||
$new_document->vendor_id = $this->transformId('vendors', $document->vendor_id);
|
$new_document->vendor_id = $this->transformId('vendors', $document->vendor_id);
|
||||||
$new_document->url = $document->url;
|
$new_document->url = $document->url;
|
||||||
$new_document->preview = $document->preview;
|
$new_document->preview = $document->preview;
|
||||||
$new_document->name = $document->name;
|
$new_document->name = str_replace("/", "-", $document->name);
|
||||||
$new_document->type = $document->type;
|
$new_document->type = $document->type;
|
||||||
$new_document->disk = $document->disk;
|
$new_document->disk = $document->disk;
|
||||||
$new_document->hash = $document->hash;
|
$new_document->hash = $document->hash;
|
||||||
@ -1199,7 +1199,7 @@ class CompanyImport implements ShouldQueue
|
|||||||
{
|
{
|
||||||
$this->genericImport(
|
$this->genericImport(
|
||||||
Webhook::class,
|
Webhook::class,
|
||||||
['company_id', 'user_id'],
|
['company_id', 'user_id', 'hashed_id', 'id',],
|
||||||
[
|
[
|
||||||
['users' => 'user_id'],
|
['users' => 'user_id'],
|
||||||
],
|
],
|
||||||
|
@ -84,6 +84,7 @@ class CreateCompany
|
|||||||
match($settings->country_id) {
|
match($settings->country_id) {
|
||||||
'724' => $company = $this->spanishSetup($company),
|
'724' => $company = $this->spanishSetup($company),
|
||||||
'36' => $company = $this->australiaSetup($company),
|
'36' => $company = $this->australiaSetup($company),
|
||||||
|
'710' => $company = $this->southAfticaSetup($company),
|
||||||
default => $company->save(),
|
default => $company->save(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ class CreateCompany
|
|||||||
|
|
||||||
if(request()->hasHeader('cf-ipcountry')) {
|
if(request()->hasHeader('cf-ipcountry')) {
|
||||||
|
|
||||||
$c = Country::where('iso_3166_2', request()->header('cf-ipcountry'))->first();
|
$c = Country::query()->where('iso_3166_2', request()->header('cf-ipcountry'))->first();
|
||||||
|
|
||||||
if($c) {
|
if($c) {
|
||||||
return (string)$c->id;
|
return (string)$c->id;
|
||||||
@ -115,7 +116,7 @@ class CreateCompany
|
|||||||
|
|
||||||
if($details && property_exists($details, 'countryCode')) {
|
if($details && property_exists($details, 'countryCode')) {
|
||||||
|
|
||||||
$c = Country::where('iso_3166_2', $details->countryCode)->first();
|
$c = Country::query()->where('iso_3166_2', $details->countryCode)->first();
|
||||||
|
|
||||||
if($c) {
|
if($c) {
|
||||||
return (string)$c->id;
|
return (string)$c->id;
|
||||||
@ -153,15 +154,6 @@ class CreateCompany
|
|||||||
|
|
||||||
$company->save();
|
$company->save();
|
||||||
|
|
||||||
//user does not exist yet.
|
|
||||||
// MultiDB::setDb($company->db);
|
|
||||||
// $user = \App\Models\User::where('account_id', $company->account_id)->first();
|
|
||||||
|
|
||||||
// $tax_rate = TaxRateFactory::create($company->id, $user->id);
|
|
||||||
// $tax_rate->name = $company->tax_data->regions->EU->subregions->ES->tax_name;
|
|
||||||
// $tax_rate->rate = $company->tax_data->regions->EU->subregions->ES->tax_rate;
|
|
||||||
// $tax_rate->save();
|
|
||||||
|
|
||||||
return $company;
|
return $company;
|
||||||
|
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
@ -174,6 +166,40 @@ class CreateCompany
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function southAfticaSetup(Company $company): Company
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$company->enabled_item_tax_rates = 1;
|
||||||
|
$company->enabled_tax_rates = 1;
|
||||||
|
|
||||||
|
$translations = new \stdClass;
|
||||||
|
$translations->invoice = "Tax Invoice";
|
||||||
|
|
||||||
|
$settings = $company->settings;
|
||||||
|
$settings->currency_id = '4';
|
||||||
|
$settings->timezone_id = '56';
|
||||||
|
$settings->translations = $translations;
|
||||||
|
|
||||||
|
$company->settings = $settings;
|
||||||
|
|
||||||
|
$company->save();
|
||||||
|
|
||||||
|
return $company;
|
||||||
|
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
nlog($e->getMessage());
|
||||||
|
nlog("SETUP: could not complete setup for South African Locale");
|
||||||
|
}
|
||||||
|
|
||||||
|
$company->save();
|
||||||
|
|
||||||
|
return $company;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private function australiaSetup(Company $company): Company
|
private function australiaSetup(Company $company): Company
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -193,17 +219,6 @@ class CreateCompany
|
|||||||
|
|
||||||
$company->save();
|
$company->save();
|
||||||
|
|
||||||
//$user = $company->account->users()->first();
|
|
||||||
//user does not exist yet.
|
|
||||||
// MultiDB::setDb($company->db);
|
|
||||||
// $user = \App\Models\User::where('account_id', $company->account_id)->first();
|
|
||||||
|
|
||||||
|
|
||||||
// $tax_rate = TaxRateFactory::create($company->id, $user->id);
|
|
||||||
// $tax_rate->name = $company->tax_data->regions->AU->subregions->AU->tax_name;
|
|
||||||
// $tax_rate->rate = $company->tax_data->regions->AU->subregions->AU->tax_rate;
|
|
||||||
// $tax_rate->save();
|
|
||||||
|
|
||||||
return $company;
|
return $company;
|
||||||
|
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
|
@ -11,34 +11,23 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Entity;
|
namespace App\Jobs\Entity;
|
||||||
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\Design;
|
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Utils\HtmlEngine;
|
|
||||||
use App\Models\PurchaseOrder;
|
use App\Models\PurchaseOrder;
|
||||||
use App\Models\QuoteInvitation;
|
use App\Models\QuoteInvitation;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Models\CreditInvitation;
|
use App\Models\CreditInvitation;
|
||||||
use App\Models\RecurringInvoice;
|
use App\Models\RecurringInvoice;
|
||||||
use App\Services\Pdf\PdfService;
|
use App\Services\Pdf\PdfService;
|
||||||
use App\Utils\PhantomJS\Phantom;
|
|
||||||
use App\Models\InvoiceInvitation;
|
use App\Models\InvoiceInvitation;
|
||||||
use App\Utils\HostedPDF\NinjaPdf;
|
|
||||||
use App\Utils\Traits\Pdf\PdfMaker;
|
use App\Utils\Traits\Pdf\PdfMaker;
|
||||||
use Illuminate\Support\Facades\App;
|
|
||||||
use App\Jobs\Invoice\CreateEInvoice;
|
|
||||||
use App\Utils\Traits\NumberFormatter;
|
use App\Utils\Traits\NumberFormatter;
|
||||||
use App\Utils\Traits\MakesInvoiceHtml;
|
use App\Utils\Traits\MakesInvoiceHtml;
|
||||||
use App\Models\PurchaseOrderInvitation;
|
use App\Models\PurchaseOrderInvitation;
|
||||||
use App\Utils\Traits\Pdf\PageNumbering;
|
use App\Utils\Traits\Pdf\PageNumbering;
|
||||||
use App\Exceptions\FilePermissionsFailure;
|
use App\Exceptions\FilePermissionsFailure;
|
||||||
use App\Models\RecurringInvoiceInvitation;
|
use App\Models\RecurringInvoiceInvitation;
|
||||||
use horstoeko\zugferd\ZugferdDocumentPdfBuilder;
|
|
||||||
use App\Services\PdfMaker\Design as PdfDesignModel;
|
|
||||||
use App\Services\PdfMaker\Design as PdfMakerDesign;
|
|
||||||
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
|
|
||||||
|
|
||||||
class CreateRawPdf
|
class CreateRawPdf
|
||||||
{
|
{
|
||||||
@ -79,8 +68,6 @@ class CreateRawPdf
|
|||||||
$this->entity_string = 'purchase_order';
|
$this->entity_string = 'purchase_order';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->company = $invitation->company;
|
|
||||||
$this->contact = $invitation->contact;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resolveType(): string
|
private function resolveType(): string
|
||||||
@ -112,191 +99,12 @@ class CreateRawPdf
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$pdf = $ps->boot()->getPdf();
|
$pdf = $ps->boot()->getPdf();
|
||||||
return $pdf;
|
|
||||||
nlog("pdf timer = ". $ps->execution_time);
|
nlog("pdf timer = ". $ps->execution_time);
|
||||||
|
return $pdf;
|
||||||
/* Forget the singleton*/
|
|
||||||
App::forgetInstance('translator');
|
|
||||||
|
|
||||||
/* Init a new copy of the translator*/
|
|
||||||
$t = app('translator');
|
|
||||||
/* Set the locale*/
|
|
||||||
App::setLocale($this->contact->preferredLocale());
|
|
||||||
|
|
||||||
/* Set customized translations _NOW_ */
|
|
||||||
$t->replace(Ninja::transformTranslations($this->entity->client->getMergedSettings()));
|
|
||||||
|
|
||||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
|
||||||
return (new Phantom)->generate($this->invitation, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$entity_design_id = '';
|
|
||||||
$path = '';
|
|
||||||
|
|
||||||
if ($this->entity instanceof Invoice) {
|
|
||||||
$path = $this->entity->client->invoice_filepath($this->invitation);
|
|
||||||
$entity_design_id = 'invoice_design_id';
|
|
||||||
} elseif ($this->entity instanceof Quote) {
|
|
||||||
$path = $this->entity->client->quote_filepath($this->invitation);
|
|
||||||
$entity_design_id = 'quote_design_id';
|
|
||||||
} elseif ($this->entity instanceof Credit) {
|
|
||||||
$path = $this->entity->client->credit_filepath($this->invitation);
|
|
||||||
$entity_design_id = 'credit_design_id';
|
|
||||||
} elseif ($this->entity instanceof RecurringInvoice) {
|
|
||||||
$path = $this->entity->client->recurring_invoice_filepath($this->invitation);
|
|
||||||
$entity_design_id = 'invoice_design_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
$file_path = $path.$this->entity->numberFormatter().'.pdf';
|
|
||||||
|
|
||||||
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->entity->client->getSetting($entity_design_id));
|
|
||||||
|
|
||||||
$design = Design::query()->withTrashed()->find($entity_design_id);
|
|
||||||
|
|
||||||
/* Catch all in case migration doesn't pass back a valid design */
|
|
||||||
if (! $design) {
|
|
||||||
$design = Design::query()->find(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
$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));
|
|
||||||
}
|
|
||||||
|
|
||||||
$variables = $html->generateLabelsAndValues();
|
|
||||||
|
|
||||||
$state = [
|
|
||||||
'template' => $template->elements([
|
|
||||||
'client' => $this->entity->client,
|
|
||||||
'entity' => $this->entity,
|
|
||||||
'pdf_variables' => (array) $this->entity->company->settings->pdf_variables,
|
|
||||||
'$product' => $design->design->product,
|
|
||||||
'variables' => $variables,
|
|
||||||
]),
|
|
||||||
'variables' => $variables,
|
|
||||||
'options' => [
|
|
||||||
'all_pages_header' => $this->entity->client->getSetting('all_pages_header'),
|
|
||||||
'all_pages_footer' => $this->entity->client->getSetting('all_pages_footer'),
|
|
||||||
'client' => $this->entity->client,
|
|
||||||
'entity' => $this->entity,
|
|
||||||
'variables' => $variables,
|
|
||||||
],
|
|
||||||
'process_markdown' => $this->entity->client->company->markdown_enabled,
|
|
||||||
];
|
|
||||||
|
|
||||||
$maker = new PdfMakerService($state);
|
|
||||||
|
|
||||||
$maker
|
|
||||||
->design($template)
|
|
||||||
->build();
|
|
||||||
|
|
||||||
$pdf = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') {
|
|
||||||
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
|
||||||
|
|
||||||
$finfo = new \finfo(FILEINFO_MIME);
|
|
||||||
|
|
||||||
//fallback in case hosted PDF fails.
|
|
||||||
if ($finfo->buffer($pdf) != 'application/pdf; charset=binary') {
|
|
||||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
|
||||||
|
|
||||||
$numbered_pdf = $this->pageNumbering($pdf, $this->company);
|
|
||||||
|
|
||||||
if ($numbered_pdf) {
|
|
||||||
$pdf = $numbered_pdf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
|
||||||
|
|
||||||
$numbered_pdf = $this->pageNumbering($pdf, $this->company);
|
|
||||||
|
|
||||||
if ($numbered_pdf) {
|
|
||||||
$pdf = $numbered_pdf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
nlog(print_r($e->getMessage(), 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config('ninja.log_pdf_html')) {
|
|
||||||
info($maker->getCompiledHTML());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($pdf) {
|
|
||||||
$maker =null;
|
|
||||||
$state = null;
|
|
||||||
|
|
||||||
return $this->checkEInvoice($pdf);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new FilePermissionsFailure('Unable to generate the raw PDF');
|
throw new FilePermissionsFailure('Unable to generate the raw PDF');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Switch to determine if we need to embed the xml into the PDF itself
|
|
||||||
*
|
|
||||||
* @param string $pdf
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function checkEInvoice(string $pdf): string
|
|
||||||
{
|
|
||||||
if(!$this->entity instanceof Invoice || !$this->company->getSetting('enable_e_invoice')) {
|
|
||||||
return $pdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
$e_invoice_type = $this->entity->client->getSetting('e_invoice_type');
|
|
||||||
|
|
||||||
switch ($e_invoice_type) {
|
|
||||||
case "EN16931":
|
|
||||||
case "XInvoice_2_2":
|
|
||||||
case "XInvoice_2_1":
|
|
||||||
case "XInvoice_2_0":
|
|
||||||
case "XInvoice_1_0":
|
|
||||||
case "XInvoice-Extended":
|
|
||||||
case "XInvoice-BasicWL":
|
|
||||||
case "XInvoice-Basic":
|
|
||||||
return $this->embedEInvoiceZuGFerD($pdf) ?? $pdf;
|
|
||||||
//case "Facturae_3.2":
|
|
||||||
//case "Facturae_3.2.1":
|
|
||||||
//case "Facturae_3.2.2":
|
|
||||||
//
|
|
||||||
default:
|
|
||||||
return $pdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Embed the .xml file into the PDF
|
|
||||||
*
|
|
||||||
* @param string $pdf
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function embedEInvoiceZuGFerD(string $pdf): string
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
|
|
||||||
$e_rechnung = (new CreateEInvoice($this->entity, true))->handle();
|
|
||||||
$pdfBuilder = new ZugferdDocumentPdfBuilder($e_rechnung, $pdf);
|
|
||||||
$pdfBuilder->generateDocument();
|
|
||||||
return $pdfBuilder->downloadString(basename($this->entity->getFileName()));
|
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
nlog("E_Invoice Merge failed - " . $e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $pdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function failed($e)
|
public function failed($e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
99
app/Jobs/Expense/VendorExpenseNotify.php
Normal file
99
app/Jobs/Expense/VendorExpenseNotify.php
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Jobs\Expense;
|
||||||
|
|
||||||
|
use App\Utils\Ninja;
|
||||||
|
use App\Utils\Number;
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Models\Activity;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use App\Services\Email\Email;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use App\Services\Email\EmailObject;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use App\Repositories\ActivityRepository;
|
||||||
|
use App\Utils\Traits\MakesDates;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
|
||||||
|
class VendorExpenseNotify implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesDates;
|
||||||
|
|
||||||
|
public $tries = 1;
|
||||||
|
|
||||||
|
public function __construct(private Expense $expense, private string $db)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
MultiDB::setDB($this->db);
|
||||||
|
|
||||||
|
$this->expense->vendor->contacts->filter(function(VendorContact $contact){
|
||||||
|
return $contact->send_email && $contact->email;
|
||||||
|
})->each(function(VendorContact $contact){
|
||||||
|
$this->notify($contact);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function notify(VendorContact $contact)
|
||||||
|
{
|
||||||
|
|
||||||
|
$mo = new EmailObject;
|
||||||
|
$mo->contact = $contact;
|
||||||
|
$mo->vendor_contact_id = $contact->id;
|
||||||
|
$mo->user_id = $this->expense->user_id;
|
||||||
|
$mo->company_key = $this->expense->company->company_key;
|
||||||
|
$mo->subject = ctrans('texts.vendor_notification_subject', [
|
||||||
|
'amount' => Number::formatMoney($this->expense->amount, $contact->vendor),
|
||||||
|
'vendor' => $contact->vendor->present()->name(),
|
||||||
|
]);
|
||||||
|
$mo->body = ctrans('texts.vendor_notification_body', [
|
||||||
|
'vendor' => $this->expense->vendor->present()->name(),
|
||||||
|
'amount' => Number::formatMoney($this->expense->amount, $contact->vendor),
|
||||||
|
'contact' => $contact->present()->name(),
|
||||||
|
'payment_date' => $this->translateDate($this->expense->payment_date, $this->expense->company->date_format(), $this->expense->vendor->locale()),
|
||||||
|
'transaction_reference' => $this->expense->transaction_reference ?? '',
|
||||||
|
'number' => $this->expense->number,
|
||||||
|
]);
|
||||||
|
$mo->template = '';
|
||||||
|
$mo->email_template_body = 'vendor_notification_subject';
|
||||||
|
$mo->email_template_subject = 'vendor_notification_body';
|
||||||
|
$mo->vendor_id = $contact->vendor_id ?? null;
|
||||||
|
$mo->variables = [
|
||||||
|
'amount' => Number::formatMoney($this->expense->amount, $contact->vendor),
|
||||||
|
'contact' => $contact->present()->name(),
|
||||||
|
'vendor' => $contact->vendor->present()->name(),
|
||||||
|
'payment_date' => $this->translateDate($this->expense->payment_date, $this->expense->company->date_format(), $this->expense->vendor->locale()),
|
||||||
|
'transaction_reference' => $this->expense->transaction_reference ?? '',
|
||||||
|
'number' => $this->expense->number,
|
||||||
|
];
|
||||||
|
|
||||||
|
Email::dispatch($mo, $this->expense->company);
|
||||||
|
|
||||||
|
$fields = new \stdClass();
|
||||||
|
$fields->expense_id = $this->expense->id;
|
||||||
|
$fields->vendor_id = $contact->vendor_id;
|
||||||
|
$fields->vendor_contact_id = $contact->id;
|
||||||
|
$fields->user_id = $this->expense->user_id;
|
||||||
|
$fields->company_id = $contact->company_id;
|
||||||
|
$fields->activity_type_id = Activity::VENDOR_NOTIFICATION_EMAIL;
|
||||||
|
$fields->account_id = $this->expense->company->account_id;
|
||||||
|
|
||||||
|
$activity_repo = new ActivityRepository();
|
||||||
|
$activity_repo->save($fields, $this->expense, Ninja::eventVars());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -74,7 +74,7 @@ class CSVIngest implements ShouldQueue
|
|||||||
|
|
||||||
$engine = $this->bootEngine();
|
$engine = $this->bootEngine();
|
||||||
|
|
||||||
foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote', 'bank_transaction', 'recurring_invoice'] as $entity) {
|
foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote', 'bank_transaction', 'recurring_invoice', 'task'] as $entity) {
|
||||||
$engine->import($entity);
|
$engine->import($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ class AdjustProductInventory implements ShouldQueue
|
|||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, UserNotifies;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, UserNotifies;
|
||||||
|
|
||||||
|
private array $notified_products = [];
|
||||||
|
|
||||||
public function __construct(public Company $company, public Invoice $invoice, public $old_invoice = [])
|
public function __construct(public Company $company, public Invoice $invoice, public $old_invoice = [])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -56,18 +58,6 @@ class AdjustProductInventory implements ShouldQueue
|
|||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
|
|
||||||
// foreach ($this->invoice->line_items as $item) {
|
|
||||||
// $p = Product::where('product_key', $item->product_key)->where('company_id', $this->company->id)->first();
|
|
||||||
|
|
||||||
// if (! $p) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// $p->in_stock_quantity += $item->quantity;
|
|
||||||
|
|
||||||
// $p->saveQuietly();
|
|
||||||
// }
|
|
||||||
|
|
||||||
collect($this->invoice->line_items)->filter(function ($item) {
|
collect($this->invoice->line_items)->filter(function ($item) {
|
||||||
return $item->type_id == '1';
|
return $item->type_id == '1';
|
||||||
})->each(function ($i) {
|
})->each(function ($i) {
|
||||||
@ -147,11 +137,15 @@ class AdjustProductInventory implements ShouldQueue
|
|||||||
$nmo->company = $this->company;
|
$nmo->company = $this->company;
|
||||||
$nmo->settings = $this->company->settings;
|
$nmo->settings = $this->company->settings;
|
||||||
|
|
||||||
|
|
||||||
$this->company->company_users->each(function ($cu) use ($product, $nmo, $notification_level) {
|
$this->company->company_users->each(function ($cu) use ($product, $nmo, $notification_level) {
|
||||||
if ($this->checkNotificationExists($cu, $product, ['inventory_all', 'inventory_user', 'inventory_threshold_all', 'inventory_threshold_user'])) {
|
|
||||||
|
/** @var \App\Models\CompanyUser $cu */
|
||||||
|
if ($this->checkNotificationExists($cu, $product, ['inventory_all', 'inventory_user', 'inventory_threshold_all', 'inventory_threshold_user']) && (! in_array($product->id, $this->notified_products))) {
|
||||||
$nmo->mailable = new NinjaMailer((new InventoryNotificationObject($product, $notification_level, $cu->portalType()))->build());
|
$nmo->mailable = new NinjaMailer((new InventoryNotificationObject($product, $notification_level, $cu->portalType()))->build());
|
||||||
$nmo->to_user = $cu->user;
|
$nmo->to_user = $cu->user;
|
||||||
NinjaMailerJob::dispatch($nmo);
|
NinjaMailerJob::dispatch($nmo);
|
||||||
|
$this->notified_products[] = $product->id;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ use App\Models\Invoice;
|
|||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Repositories\ActivityRepository;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use GuzzleHttp\Exception\ClientException;
|
use GuzzleHttp\Exception\ClientException;
|
||||||
@ -164,7 +165,7 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
* this merges a text string with a json object
|
* this merges a text string with a json object
|
||||||
* need to harvest the ->Message property using the following
|
* need to harvest the ->Message property using the following
|
||||||
*/
|
*/
|
||||||
if (stripos($e->getMessage(), 'code 406') || stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413')) {
|
if (stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413')) {
|
||||||
$message = "Either Attachment too large, or recipient has been suppressed.";
|
$message = "Either Attachment too large, or recipient has been suppressed.";
|
||||||
|
|
||||||
$this->fail();
|
$this->fail();
|
||||||
@ -174,6 +175,20 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stripos($e->getMessage(), 'code 406')) {
|
||||||
|
|
||||||
|
$email = $this->nmo->to_user->email ?? '';
|
||||||
|
|
||||||
|
$message = "Recipient {$email} has been suppressed and cannot receive emails from you.";
|
||||||
|
|
||||||
|
$this->fail();
|
||||||
|
$this->logMailError($message, $this->company->clients()->first());
|
||||||
|
$this->cleanUpMailers();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//only report once, not on all tries
|
//only report once, not on all tries
|
||||||
if ($this->attempts() == $this->tries) {
|
if ($this->attempts() == $this->tries) {
|
||||||
/* If the is an entity attached to the message send a failure mailer */
|
/* If the is an entity attached to the message send a failure mailer */
|
||||||
|
@ -117,44 +117,46 @@ class SystemMaintenance implements ShouldQueue
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private function cleanPdfs()
|
//double check this is correct.
|
||||||
{
|
|
||||||
$company_keys = Company::query()
|
|
||||||
->pluck('company_key')
|
|
||||||
->toArray();
|
|
||||||
|
|
||||||
$directories = Storage::disk(config('filesystems.default'))->directories();
|
// private function cleanPdfs()
|
||||||
|
// {
|
||||||
|
// $company_keys = Company::query()
|
||||||
|
// ->pluck('company_key')
|
||||||
|
// ->toArray();
|
||||||
|
|
||||||
$del_dirs = ['quotes','invoices','credits','recurring_invoices', 'e_invoice'];
|
// $directories = Storage::disk(config('filesystems.default'))->directories();
|
||||||
|
|
||||||
collect($directories)->each(function ($parent_directory) use ($del_dirs, $company_keys) {
|
// $del_dirs = ['quotes','invoices','credits','recurring_invoices', 'e_invoice'];
|
||||||
|
|
||||||
if (! in_array($parent_directory, $company_keys)) {
|
// collect($directories)->each(function ($parent_directory) use ($del_dirs, $company_keys) {
|
||||||
nlog("Deleting {$parent_directory}");
|
|
||||||
|
|
||||||
/* Ensure we are not deleting the root folder */
|
// if (! in_array($parent_directory, $company_keys)) {
|
||||||
if (strlen($parent_directory) > 1) {
|
// nlog("Deleting {$parent_directory}");
|
||||||
nlog("Company No Longer Exists => deleting {$parent_directory}");
|
|
||||||
Storage::disk(config('filesystems.default'))->deleteDirectory($parent_directory);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
// /* Ensure we are not deleting the root folder */
|
||||||
|
// if (strlen($parent_directory) > 1) {
|
||||||
|
// nlog("Company No Longer Exists => deleting {$parent_directory}");
|
||||||
|
// Storage::disk(config('filesystems.default'))->deleteDirectory($parent_directory);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
$sub_directories = Storage::allDirectories($parent_directory);
|
// }
|
||||||
|
|
||||||
collect($sub_directories)->each(function ($sub_dir) use ($del_dirs) {
|
// $sub_directories = Storage::allDirectories($parent_directory);
|
||||||
foreach($del_dirs as $del_dir) {
|
|
||||||
if(stripos($sub_dir, $del_dir) !== false) {
|
|
||||||
nlog("Deleting {$sub_dir} as it matches {$del_dir}");
|
|
||||||
Storage::deleteDirectory($sub_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
// collect($sub_directories)->each(function ($sub_dir) use ($del_dirs) {
|
||||||
|
// foreach($del_dirs as $del_dir) {
|
||||||
|
// if(stripos($sub_dir, $del_dir) !== false) {
|
||||||
|
// nlog("Deleting {$sub_dir} as it matches {$del_dir}");
|
||||||
|
// Storage::deleteDirectory($sub_dir);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
});
|
// });
|
||||||
|
|
||||||
}
|
// });
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
@ -72,6 +72,11 @@ class EmailPayment implements ShouldQueue
|
|||||||
|
|
||||||
$email_builder = (new PaymentEmailEngine($this->payment, $this->contact))->build();
|
$email_builder = (new PaymentEmailEngine($this->payment, $this->contact))->build();
|
||||||
|
|
||||||
|
if($this->settings->payment_email_all_contacts && $this->payment->invoices && $this->payment->invoices->count() >= 1) {
|
||||||
|
$this->emailAllContacts($email_builder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$invitation = null;
|
$invitation = null;
|
||||||
|
|
||||||
$nmo = new NinjaMailerObject;
|
$nmo = new NinjaMailerObject;
|
||||||
@ -100,4 +105,25 @@ class EmailPayment implements ShouldQueue
|
|||||||
event(new PaymentWasEmailed($this->payment, $this->payment->company, $this->contact, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new PaymentWasEmailed($this->payment, $this->payment->company, $this->contact, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function emailAllContacts($email_builder): void
|
||||||
|
{
|
||||||
|
|
||||||
|
$invoice = $this->payment->invoices->first();
|
||||||
|
|
||||||
|
$invoice->invitations->each(function ($invite) use ($email_builder){
|
||||||
|
|
||||||
|
$nmo = new NinjaMailerObject;
|
||||||
|
$nmo->mailable = new TemplateEmail($email_builder, $invite->contact, $invite);
|
||||||
|
$nmo->to_user = $invite->contact;
|
||||||
|
$nmo->settings = $this->settings;
|
||||||
|
$nmo->company = $this->company;
|
||||||
|
$nmo->entity = $this->payment;
|
||||||
|
(new NinjaMailerJob($nmo))->handle();
|
||||||
|
|
||||||
|
event(new PaymentWasEmailed($this->payment, $this->payment->company, $invite->contact, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,6 @@ class EmailRefundPayment implements ShouldQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$nmo->mailable = new TemplateEmail($email_builder, $this->contact, $invitation);
|
$nmo->mailable = new TemplateEmail($email_builder, $this->contact, $invitation);
|
||||||
$nmo->to_user = $this->contact;
|
$nmo->to_user = $this->contact;
|
||||||
$nmo->settings = $this->settings;
|
$nmo->settings = $this->settings;
|
||||||
|
@ -388,7 +388,7 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
|||||||
'delivery_message' => $event->Details->DeliveryMessage ?? $event->Details->Summary ?? '',
|
'delivery_message' => $event->Details->DeliveryMessage ?? $event->Details->Summary ?? '',
|
||||||
'server' => $event->Details->DestinationServer ?? '',
|
'server' => $event->Details->DestinationServer ?? '',
|
||||||
'server_ip' => $event->Details->DestinationIP ?? '',
|
'server_ip' => $event->Details->DestinationIP ?? '',
|
||||||
'date' => \Carbon\Carbon::parse($event->ReceivedAt)->format('Y-m-d H:m:s') ?? '',
|
'date' => \Carbon\Carbon::parse($event->ReceivedAt)->format('Y-m-d H:i:s') ?? '',
|
||||||
];
|
];
|
||||||
|
|
||||||
})->toArray();
|
})->toArray();
|
||||||
|
@ -44,7 +44,7 @@ class PreviewReport implements ShouldQueue
|
|||||||
else
|
else
|
||||||
$report = $export->run();
|
$report = $export->run();
|
||||||
|
|
||||||
nlog($report);
|
// nlog($report);
|
||||||
|
|
||||||
Cache::put($this->hash, $report, 60 * 60);
|
Cache::put($this->hash, $report, 60 * 60);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user