mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-01 07:04:34 -04:00
commit
d09643a574
@ -28,15 +28,6 @@ REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="user@example.com"
|
||||
MAIL_FROM_NAME="Self Hosted User"
|
||||
|
||||
POSTMARK_API_TOKEN=
|
||||
REQUIRE_HTTPS=false
|
||||
|
||||
|
9
.github/workflows/phpunit.yml
vendored
9
.github/workflows/phpunit.yml
vendored
@ -13,8 +13,8 @@ jobs:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system: ['ubuntu-20.04', 'ubuntu-22.04']
|
||||
php-versions: ['8.1','8.2']
|
||||
operating-system: ['ubuntu-22.04','ubuntu-24.04']
|
||||
php-versions: ['8.2']
|
||||
phpunit-versions: ['latest']
|
||||
ci_node_total: [ 8 ]
|
||||
ci_node_index: [ 0, 1, 2, 3, 4, 5, 6, 7]
|
||||
@ -95,14 +95,15 @@ jobs:
|
||||
- name: Get Composer Cache Directory
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
- uses: actions/cache@v3
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.php }}-composer-
|
||||
|
||||
|
||||
- name: Install composer dependencies
|
||||
run: |
|
||||
composer config -g github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
|
||||
|
8
.github/workflows/react_release.yml
vendored
8
.github/workflows/react_release.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
php-version: 8.2
|
||||
extensions: mysql, mysqlnd, sqlite3, bcmath, gd, curl, zip, openssl, mbstring, xml
|
||||
|
||||
- name: Checkout code
|
||||
@ -44,6 +44,7 @@ jobs:
|
||||
git clone https://${{secrets.commit_secret}}@github.com/invoiceninja/ui.git
|
||||
cd ui
|
||||
git checkout develop
|
||||
cp ../vite.config.ts.react ./vite.config.js
|
||||
npm i
|
||||
npm run build
|
||||
cp -r dist/* ../public/
|
||||
@ -60,11 +61,12 @@ jobs:
|
||||
sudo rm -rf node_modules
|
||||
sudo rm -rf .git
|
||||
sudo rm .env
|
||||
|
||||
sudo rm -rf ui
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
shopt -s dotglob
|
||||
tar --exclude='public/storage' --exclude='.htaccess' --exclude='invoiceninja.zip' -zcvf /home/runner/work/invoiceninja/react-invoiceninja.tar *
|
||||
tar --exclude='public/storage' --exclude='./htaccess' --exclude='invoiceninja.zip' -zcvf /home/runner/work/invoiceninja/react-invoiceninja.tar *
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
php-version: 8.2
|
||||
extensions: mysql, mysqlnd, sqlite3, bcmath, gd, curl, zip, openssl, mbstring, xml
|
||||
|
||||
- name: Checkout code
|
||||
@ -72,9 +72,8 @@ jobs:
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
zip -r /home/runner/work/invoiceninja/invoiceninja.zip .* -x "../*"
|
||||
shopt -s dotglob
|
||||
tar --exclude='public/storage' --exclude='.htaccess' --exclude='invoiceninja.zip' -zcvf /home/runner/work/invoiceninja/invoiceninja.tar *
|
||||
tar --exclude='public/storage' --exclude='./htaccess' --exclude='invoiceninja.zip' -zcvf /home/runner/work/invoiceninja/invoiceninja.tar *
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
@ -82,5 +81,4 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: |
|
||||
/home/runner/work/invoiceninja/invoiceninja.tar
|
||||
/home/runner/work/invoiceninja/invoiceninja.zip
|
||||
/home/runner/work/invoiceninja/invoiceninja.tar
|
@ -1 +1 @@
|
||||
5.8.48
|
||||
5.9.6
|
@ -172,18 +172,18 @@ class CheckData extends Command
|
||||
CompanyUser::query()->cursor()->each(function ($cu) {
|
||||
|
||||
if (CompanyToken::where('user_id', $cu->user_id)->where('company_id', $cu->company_id)->where('is_system', 1)->doesntExist()) {
|
||||
|
||||
|
||||
|
||||
if ($cu->company && $cu->user) {
|
||||
$this->logMessage("Creating missing company token for user # {$cu->user_id} for company id # {$cu->company_id}");
|
||||
(new CreateCompanyToken($cu->company, $cu->user, 'System'))->handle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$cu->user) {
|
||||
$this->logMessage("No user found for company user - removing company user");
|
||||
$cu->forceDelete();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -208,7 +208,7 @@ class CheckData extends Command
|
||||
->cursor()
|
||||
->each(function ($client) {
|
||||
if ($client->recurring_invoices()->where('is_deleted', 0)->where('deleted_at', null)->count() > 1) {
|
||||
$this->logMessage("Duplicate Recurring Invoice => {$client->custom_value1}");
|
||||
$this->logMessage("Duplicate Recurring Invoice => {$client->custom_value1} || {$client->id}}");
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -477,14 +477,13 @@ class CheckData extends Command
|
||||
}
|
||||
} else {
|
||||
$this->logMessage("No contact present, so cannot add invitation for {$entity_key} - {$entity->id}");
|
||||
|
||||
try{
|
||||
$entity->service()->createInvitations()->save();
|
||||
}
|
||||
catch(\Exception $e){
|
||||
|
||||
try {
|
||||
$entity->service()->createInvitations()->save();
|
||||
} catch(\Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
@ -949,12 +948,12 @@ class CheckData extends Command
|
||||
|
||||
});
|
||||
|
||||
Company::whereDoesntHave('company_users', function ($query){
|
||||
$query->where('is_owner', 1);
|
||||
Company::whereDoesntHave('company_users', function ($query) {
|
||||
$query->where('is_owner', 1);
|
||||
})
|
||||
->cursor()
|
||||
->when(Ninja::isHosted())
|
||||
->each(function ($c){
|
||||
->each(function ($c) {
|
||||
|
||||
$this->logMessage("Orphan Account # {$c->account_id}");
|
||||
|
||||
@ -963,8 +962,8 @@ class CheckData extends Command
|
||||
CompanyUser::whereDoesntHave('tokens')
|
||||
->cursor()
|
||||
->when(Ninja::isHosted())
|
||||
->each(function ($cu){
|
||||
|
||||
->each(function ($cu) {
|
||||
|
||||
$this->logMessage("Missing tokens for Company User # {$cu->id}");
|
||||
|
||||
});
|
||||
|
@ -1016,7 +1016,7 @@ class CreateSingleAccount extends Command
|
||||
$cg->fees_and_limits = $fees_and_limits;
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
|
||||
if (config('ninja.testvars.eway') && ($this->gateway == 'all' || $this->gateway == 'eway')) {
|
||||
$cg = new CompanyGateway();
|
||||
$cg->company_id = $company->id;
|
||||
@ -1038,12 +1038,12 @@ class CreateSingleAccount extends Command
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (config('ninja.testvars.gocardless') && ($this->gateway == 'all' || $this->gateway == 'gocardless')) {
|
||||
|
||||
$c_settings = ClientSettings::defaults();
|
||||
$c_settings->currency_id = '2';
|
||||
|
||||
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
|
@ -110,7 +110,9 @@ class DemoMode extends Command
|
||||
|
||||
$this->info('Creating Small Account and Company');
|
||||
|
||||
$account = Account::factory()->create();
|
||||
$account = Account::factory()->create([
|
||||
"set_react_as_default_ap" => 0,
|
||||
]);
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $account->id,
|
||||
'slack_webhook_url' => config('ninja.notification.slack'),
|
||||
|
@ -1,69 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\DataProviders\FatturaPADataProvider;
|
||||
|
||||
class EDocLint extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ninja:edoclint';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Builds json files component data maps';
|
||||
|
||||
private array $classes = [
|
||||
FatturaPADataProvider::class,
|
||||
];
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
foreach($this->classes as $class)
|
||||
{
|
||||
|
||||
$provider = new $class();
|
||||
|
||||
foreach($provider as $key => $value) {
|
||||
|
||||
$json = json_encode($provider->{$key}, JSON_PRETTY_PRINT);
|
||||
Storage::disk('local')->put($key.'.json', $json);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ class ReactBuilder extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ninja:react';
|
||||
protected $signature = 'ninja:react {--type=}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
@ -46,31 +46,39 @@ class ReactBuilder extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// $includes = '';
|
||||
if($this->option('type') == 'local') {
|
||||
|
||||
// $directoryIterator = false;
|
||||
|
||||
// try {
|
||||
// $directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
// } catch (\Exception $e) {
|
||||
// $this->error('React files not found');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
|
||||
// if ($file->getExtension() == 'js') {
|
||||
// if (str_contains($file->getFileName(), 'index-')) {
|
||||
// $includes .= '<script type="module" crossorigin src="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'"></script>'."\n";
|
||||
// } else {
|
||||
// $includes .= '<link rel="modulepreload" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
// }
|
||||
// }
|
||||
$includes = '';
|
||||
|
||||
$directoryIterator = false;
|
||||
|
||||
try {
|
||||
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('React files not found');
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
|
||||
if ($file->getExtension() == 'js') {
|
||||
if (str_contains($file->getFileName(), 'index-')) {
|
||||
$includes .= '<script type="module" crossorigin src="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'"></script>'."\n";
|
||||
} else {
|
||||
$includes .= '<link rel="modulepreload" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (str_contains($file->getFileName(), '.css')) {
|
||||
$includes .= '<link rel="stylesheet" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents(resource_path('views/react/head.blade.php'), $includes);
|
||||
|
||||
}
|
||||
|
||||
// if (str_contains($file->getFileName(), '.css')) {
|
||||
// $includes .= '<link rel="stylesheet" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
// }
|
||||
// }
|
||||
|
||||
// file_put_contents(resource_path('views/react/head.blade.php'), $includes);
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,10 @@ class DbQuery extends GenericMixedMetric
|
||||
|
||||
public $string_metric7 = 'ip_address';
|
||||
|
||||
public $string_metric8 = 'client_version';
|
||||
|
||||
public $string_metric9 = 'platform';
|
||||
|
||||
/**
|
||||
* The counter
|
||||
* set to 1.
|
||||
@ -62,12 +66,14 @@ class DbQuery extends GenericMixedMetric
|
||||
|
||||
public $double_metric2 = 1;
|
||||
|
||||
public function __construct($string_metric5, $string_metric6, $int_metric1, $double_metric2, $string_metric7)
|
||||
public function __construct($string_metric5, $string_metric6, $int_metric1, $double_metric2, $string_metric7, $string_metric8, $string_metric9)
|
||||
{
|
||||
$this->int_metric1 = $int_metric1;
|
||||
$this->string_metric5 = $string_metric5;
|
||||
$this->string_metric6 = $string_metric6;
|
||||
$this->double_metric2 = $double_metric2;
|
||||
$this->string_metric7 = $string_metric7;
|
||||
$this->string_metric8 = $string_metric8;
|
||||
$this->string_metric9 = $string_metric9;
|
||||
}
|
||||
}
|
||||
|
61
app/DataMapper/Analytics/LoginMeta.php
Normal file
61
app/DataMapper/Analytics/LoginMeta.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class LoginMeta extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
*
|
||||
* Monotonically incrementing counter
|
||||
*
|
||||
* - counter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'mixed_metric';
|
||||
|
||||
/**
|
||||
* The name of the counter.
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'login.meta';
|
||||
|
||||
/**
|
||||
* The datetime of the counter measurement.
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
/**
|
||||
* The Class failure name
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric5 = 'email';
|
||||
public $string_metric6 = 'ip';
|
||||
public $string_metric7 = 'result';
|
||||
|
||||
public $int_metric1 = 1;
|
||||
|
||||
public function __construct($string_metric5, $string_metric6, $string_metric7)
|
||||
{
|
||||
$this->string_metric7 = $string_metric7;
|
||||
$this->string_metric6 = $string_metric6;
|
||||
$this->string_metric5 = $string_metric5;
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ class RevenueTrack extends GenericMixedMetric
|
||||
* The name of the counter.
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'app.revenue';
|
||||
public $name = 'app.cac';
|
||||
|
||||
/**
|
||||
* The datetime of the counter measurement.
|
||||
@ -59,14 +59,14 @@ class RevenueTrack extends GenericMixedMetric
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric7 = 'product';
|
||||
public $string_metric7 = 'plan';
|
||||
|
||||
/**
|
||||
* Gateway Reference
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric8 = 'gateway_reference';
|
||||
public $string_metric8 = 'plan_term';
|
||||
|
||||
public $string_metric9 = 'entity_reference';
|
||||
|
||||
|
@ -29,7 +29,7 @@ class CompanySettings extends BaseSettings
|
||||
|
||||
public $besr_id = ''; //@implemented
|
||||
|
||||
public $lock_invoices = 'off'; //off,when_sent,when_paid //@implemented
|
||||
public $lock_invoices = 'off'; //off,when_sent,when_paid,end_of_month //@implemented
|
||||
|
||||
public $enable_client_portal_tasks = false; //@ben to implement
|
||||
|
||||
@ -503,7 +503,13 @@ class CompanySettings extends BaseSettings
|
||||
|
||||
public $enable_rappen_rounding = false;
|
||||
|
||||
public bool $task_round_up = true;
|
||||
|
||||
public int $task_round_to_nearest = 1;
|
||||
|
||||
public static $casts = [
|
||||
'task_round_up' => 'bool',
|
||||
'task_round_to_nearest' => 'int',
|
||||
'e_quote_type' => 'string',
|
||||
'enable_rappen_rounding' => 'bool',
|
||||
'use_unapplied_payment' => 'string',
|
||||
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\EDoc;
|
||||
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
class Fact1 extends Data
|
||||
{
|
||||
public string $sectorCode = 'SECTOR1';
|
||||
public string $BankId = '';
|
||||
public string $BankName = '';
|
||||
public string $PaymentMeans = 'TP02';
|
||||
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\EDoc;
|
||||
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
class FatturaPA extends Data
|
||||
{
|
||||
public string $RegimeFiscale = 'RF01';
|
||||
public string $TipoDocumento = 'TD01';
|
||||
public string $ModalitaPagamento = 'MP01';
|
||||
public string $CondizioniPagamento = 'TP02';
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper;
|
||||
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\Optional;
|
||||
use App\DataMapper\EDoc\FatturaPA;
|
||||
|
||||
class EDocSettings extends Data
|
||||
{
|
||||
public FatturaPA|Optional $FatturaPA;
|
||||
|
||||
public function __construct() {}
|
||||
|
||||
public function createFatturaPA(): FatturaPA
|
||||
{
|
||||
return $this->FatturaPA ??= new FatturaPA();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DatiAnagraficiVettore extends Data{
|
||||
|
||||
public string $IdFiscaleIVA = '';
|
||||
public string $CodiceFiscale = '';
|
||||
public string $Anagrafica = '';
|
||||
}
|
||||
|
||||
class DatiTrasporto extends Data{
|
||||
public string $DataOraConsegna = ''; //datetime in this format 2017-01-10T16:46:12.000+02:00
|
||||
//public DatiAnagraficiVettore
|
||||
}
|
||||
|
||||
class DatiOrdineAcquisto extends Data{
|
||||
public string $RiferimentoNumeroLinea = '';
|
||||
public string $IdDocumento = '';
|
||||
public string $Data = '';
|
||||
public string $NumItem = '';
|
||||
public string $CodiceCommessaConvenzione = '';
|
||||
public string $CodiceCUP = '';
|
||||
public string $CodiceCIG = '';
|
||||
}
|
||||
|
||||
class DatiContratto extends Data{
|
||||
public string $RiferimentoNumeroLinea = '';
|
||||
public string $IdDocumento = '';
|
||||
public string $Data = '';
|
||||
public string $NumItem = '';
|
||||
public string $CodiceCommessaConvenzione = '';
|
||||
public string $CodiceCUP = '';
|
||||
public string $CodiceCIG = '';
|
||||
}
|
||||
|
||||
class DatiRicezione extends Data{
|
||||
public string $RiferimentoNumeroLinea = '';
|
||||
public string $IdDocumento = '';
|
||||
public string $Data = '';
|
||||
public string $NumItem = '';
|
||||
public string $CodiceCommessaConvenzione = '';
|
||||
public string $CodiceCUP = '';
|
||||
public string $CodiceCIG = '';
|
||||
}
|
@ -64,9 +64,9 @@ class InvoiceItem
|
||||
public $task_id = '';
|
||||
|
||||
public $expense_id = '';
|
||||
|
||||
|
||||
public $unit_code = 'C62';
|
||||
|
||||
|
||||
public static $casts = [
|
||||
'task_id' => 'string',
|
||||
'expense_id' => 'string',
|
||||
|
297
app/DataMapper/Sources/PayPalBalanceAffecting.php
Normal file
297
app/DataMapper/Sources/PayPalBalanceAffecting.php
Normal file
@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Sources;
|
||||
|
||||
use App\DataMapper\InvoiceItem;
|
||||
|
||||
class PayPalBalanceAffecting
|
||||
{
|
||||
private array $key_map = [
|
||||
'Date' => 'date',
|
||||
'Time' => 'time',
|
||||
'TimeZone' => 'timezone',
|
||||
'Name' => 'name',
|
||||
'Type' => 'type',
|
||||
'Status' => 'status',
|
||||
'Currency' => 'currency',
|
||||
'Gross' => 'gross',
|
||||
'Fee' => 'fee',
|
||||
'Net' => 'net',
|
||||
'From Email Address' => 'fromEmailAddress',
|
||||
'To Email Address' => 'toEmailAddress',
|
||||
'Transaction ID' => 'transactionId',
|
||||
'Shipping Address' => 'shippingAddress',
|
||||
'Item Title' => 'itemTitle',
|
||||
'Item ID' => 'itemId',
|
||||
'Option 1 Name' => 'option1Name',
|
||||
'Option 1 Value' => 'option1Value',
|
||||
'Option 2 Name' => 'option2Name',
|
||||
'Option 2 Value' => 'option2Value',
|
||||
'Reference Txn ID' => 'referenceTxId',
|
||||
'Invoice Number' => 'invoiceNumber',
|
||||
'Custom Number' => 'customNumber',
|
||||
'Quantity' => 'quantity',
|
||||
'Receipt ID' => 'receiptId',
|
||||
'Address Line 1' => 'addressLine1',
|
||||
'Address Line 2/District/Neighborhood' => 'addressLine2DistrictNeighborhood',
|
||||
'Town/City' => 'townCity',
|
||||
'State/Province/Region/County/Territory/Prefecture/Republic' => 'stateProvinceRegionCountyTerritoryPrefectureRepublic',
|
||||
'Zip/Postal Code' => 'zipPostalCode',
|
||||
'Country' => 'country',
|
||||
'Contact Phone Number' => 'contactPhoneNumber',
|
||||
'Subject' => 'subject',
|
||||
'Note' => 'note',
|
||||
'Transaction Event Code' => 'transactionEventCode',
|
||||
'Payment Tracking ID' => 'paymentTrackingId',
|
||||
'Item Details' => 'itemDetails',
|
||||
'Authorization Review Status' => 'authorizationReviewStatus',
|
||||
'Country Code' => 'countryCode',
|
||||
'Tip' => 'tip',
|
||||
'Discount' => 'discount',
|
||||
'Credit Transactional Fee' => 'creditTransactionalFee',
|
||||
'Original Invoice ID' => 'originalInvoiceId',
|
||||
];
|
||||
|
||||
public $date;
|
||||
public $time;
|
||||
public $timezone;
|
||||
public $name;
|
||||
public $type;
|
||||
public $status;
|
||||
public $currency;
|
||||
public $gross;
|
||||
public $fee;
|
||||
public $net;
|
||||
public $fromEmailAddress;
|
||||
public $toEmailAddress;
|
||||
public $transactionId;
|
||||
public $shippingAddress;
|
||||
public $itemTitle;
|
||||
public $itemId;
|
||||
public $option1Name;
|
||||
public $option1Value;
|
||||
public $option2Name;
|
||||
public $option2Value;
|
||||
public $referenceTxnId;
|
||||
public $invoiceNumber;
|
||||
public $customNumber;
|
||||
public $quantity;
|
||||
public $receiptId;
|
||||
public $addressLine1;
|
||||
public $addressLine2DistrictNeighborhood;
|
||||
public $townCity;
|
||||
public $stateProvinceRegionCountyTerritoryPrefectureRepublic;
|
||||
public $zipPostalCode;
|
||||
public $country;
|
||||
public $contactPhoneNumber;
|
||||
public $subject;
|
||||
public $note;
|
||||
public $transactionEventCode;
|
||||
public $paymentTrackingId;
|
||||
public $itemDetails;
|
||||
public $authorizationReviewStatus;
|
||||
public $countryCode;
|
||||
public $tip;
|
||||
public $discount;
|
||||
public $creditTransactionalFee;
|
||||
public $originalInvoiceId;
|
||||
|
||||
public function __construct(private array $import_row)
|
||||
{
|
||||
}
|
||||
|
||||
public function run(): self
|
||||
{
|
||||
$this->cleanUp();
|
||||
|
||||
foreach($this->import_row as $key => $value) {
|
||||
|
||||
$prop = $this->key_map[$key] ?? false;
|
||||
|
||||
if($prop) {
|
||||
|
||||
echo "Setting {$prop} to {$value}".PHP_EOL;
|
||||
$this->{$prop} = $value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function cleanUp(): self
|
||||
{
|
||||
|
||||
foreach($this->key_map as $value) {
|
||||
echo "Setting {$value} to null".PHP_EOL;
|
||||
$this->{$value} = null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getClient(): array
|
||||
{
|
||||
$client = [
|
||||
'name' => $this->name,
|
||||
'contacts' => [$this->getContact()],
|
||||
'email' => $this->fromEmailAddress,
|
||||
];
|
||||
|
||||
$client = array_merge($client, $this->returnAddress());
|
||||
$client = array_merge($client, $this->returnShippingAddress());
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
public function getInvoice(): array
|
||||
{
|
||||
$item = new InvoiceItem();
|
||||
$item->cost = $this->gross ?? 0;
|
||||
$item->product_key = $this->itemId ?? '';
|
||||
$item->notes = $this->subject ?? $this->itemDetails;
|
||||
$item->quantity = 1;
|
||||
|
||||
return [
|
||||
'number' => trim($this->invoiceNumber ?? $this->transactionId),
|
||||
'date' => str_replace('/', '-', $this->date ?? ''),
|
||||
'line_items' => [$item],
|
||||
'name' => $this->name ?? '',
|
||||
'email' => $this->fromEmailAddress ?? '',
|
||||
'transaction_reference' => $this->transactionId ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
public function getContact(): array
|
||||
{
|
||||
$name_parts = explode(" ", $this->name ?? '');
|
||||
|
||||
if(count($name_parts) == 2) {
|
||||
$contact['first_name'] = $name_parts[0];
|
||||
$contact['last_name'] = $name_parts[1];
|
||||
} else {
|
||||
$contact['first_name'] = $this->name ?? '';
|
||||
}
|
||||
|
||||
$contact['email'] = $this->fromEmailAddress ?? '';
|
||||
$contact['phone'] = $this->contactPhoneNumber ?? '';
|
||||
|
||||
return $contact;
|
||||
}
|
||||
|
||||
private function returnAddress(): array
|
||||
{
|
||||
return [
|
||||
'address1' => $this->addressLine1 ?? '',
|
||||
'address2' => $this->addressLine2DistrictNeighborhood ?? '',
|
||||
'city' => $this->townCity ?? '',
|
||||
'state' => $this->stateProvinceRegionCountyTerritoryPrefectureRepublic ?? '',
|
||||
'country_id' => $this->countryCode ?? '',
|
||||
'postal_code' => $this->zipPostalCode ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
private function returnShippingAddress(): array
|
||||
{
|
||||
if(strlen($this->shippingAddress ?? '') < 3) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$ship_parts = explode(",", $this->shippingAddress);
|
||||
|
||||
if(count($ship_parts) != 7) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'shipping_address1' => $ship_parts[2],
|
||||
'shipping_address2' => '',
|
||||
'shipping_city' => $ship_parts[3],
|
||||
'shipping_state' => $ship_parts[4],
|
||||
'shipping_postal_code' => $ship_parts[5],
|
||||
'shipping_country_id' => $ship_parts[6],
|
||||
];
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type ?? '';
|
||||
}
|
||||
|
||||
public function isInvoiceType(): bool
|
||||
{
|
||||
return $this->type == 'Website Payment';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// $csv = Reader::createFromString($csvFile);
|
||||
// // $csvdelimiter = self::detectDelimiter($csvfile);
|
||||
// $csv->setDelimiter(",");
|
||||
// $stmt = new Statement();
|
||||
// $data = iterator_to_array($stmt->process($csv));
|
||||
|
||||
// $header = $data[0];
|
||||
// $arr = [];
|
||||
|
||||
// foreach($data as $key => $value) {
|
||||
|
||||
|
||||
// if($key == 0) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// $arr[] = array_combine($header, $value);
|
||||
|
||||
// }
|
||||
|
||||
// $arr;
|
||||
|
||||
// $company = Company::find(3358);
|
||||
// $owner = $company->owner();
|
||||
// $client_repo = new ClientRepository(new ClientContactRepository());
|
||||
// $invoice_repo = new InvoiceRepository();
|
||||
|
||||
// foreach($arr as $pp) {
|
||||
|
||||
// $p = new PayPalBalanceAffecting($pp);
|
||||
// $p->run();
|
||||
|
||||
|
||||
// if(!$p->isInvoiceType()) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// $import_c = $p->getClient();
|
||||
// $import_i = $p->getInvoice();
|
||||
|
||||
|
||||
// $contact = ClientContact::where('company_id', 3358)->where('email', $import_c['email'])->first();
|
||||
|
||||
|
||||
// if(!$contact) {
|
||||
|
||||
// $cc = ClientFactory::create($company->id, $owner->id);
|
||||
|
||||
// $client = $client_repo->save($import_c, $cc);
|
||||
|
||||
// } else {
|
||||
// $client = $contact->client;
|
||||
// }
|
||||
|
||||
// $i = InvoiceFactory::create($company->id, $owner->id);
|
||||
// $i->client_id = $client->id;
|
||||
// $invoice_repo->save($import_i, $i);
|
||||
|
||||
|
||||
// }
|
@ -11,11 +11,12 @@
|
||||
|
||||
namespace App\DataMapper\Tax;
|
||||
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
use App\DataProviders\USStates;
|
||||
use App\Models\Quote;
|
||||
use App\Models\Client;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Product;
|
||||
use App\DataProviders\USStates;
|
||||
use App\DataMapper\Tax\ZipTax\Response;
|
||||
|
||||
class BaseRule implements RuleInterface
|
||||
{
|
||||
@ -210,7 +211,7 @@ class BaseRule implements RuleInterface
|
||||
}
|
||||
|
||||
/** Applies the tax data to the invoice */
|
||||
if($this->invoice instanceof Invoice && $tax_data) {
|
||||
if(($this->invoice instanceof Invoice || $this->invoice instanceof Quote) && $tax_data) {
|
||||
|
||||
$this->invoice->tax_data = $tax_data;
|
||||
|
||||
|
@ -235,17 +235,17 @@ class Rule extends BaseRule implements RuleInterface
|
||||
} elseif(in_array($this->client_subregion, $this->eu_country_codes) && !$this->client->vat_number) { //eu country / no valid vat
|
||||
if(($this->client->company->tax_data->seller_subregion != $this->client_subregion) && $this->client->company->tax_data->regions->EU->has_sales_above_threshold) {
|
||||
// nlog("eu zone with sales above threshold");
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_tax_rate;
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->tax_rate ?? 0;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->country->iso_3166_2}->reduced_tax_rate ?? 0;
|
||||
} else {
|
||||
// nlog("EU with intra-community supply ie DE to DE");
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate ?? 0;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate ?? 0;
|
||||
}
|
||||
} else {
|
||||
// nlog("default tax");
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate ?? 0;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate ?? 0;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -18,6 +18,7 @@ namespace App\DataProviders;
|
||||
class Domains
|
||||
{
|
||||
private static array $verify_domains = [
|
||||
'looksecure.net',
|
||||
'0-00.usa.cc',
|
||||
'0-180.com',
|
||||
'0-30-24.com',
|
||||
|
@ -1,124 +0,0 @@
|
||||
<?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\DataProviders;
|
||||
|
||||
class FatturaPADataProvider
|
||||
{
|
||||
public array $regime_fiscale = [
|
||||
"RF01" => "Regime ordinario",
|
||||
"RF02" => "Regime dei contribuenti minimi (art. 1,c.96-117, L. 244/2007)",
|
||||
"RF04" => "Agricoltura e attività connesse e pesca (artt. 34 e 34-bis, D.P.R. 633/1972)",
|
||||
"RF05" => "Vendita sali e tabacchi (art. 74, c.1, D.P.R. 633/1972)",
|
||||
"RF06" => "Commercio dei fiammiferi (art. 74, c.1, D.P.R. 633/1972)",
|
||||
"RF07" => "Editoria (art. 74, c.1, D.P.R. 633/1972)",
|
||||
"RF08" => "Gestione di servizi di telefonia pubblica (art. 74, c.1, D.P.R. 633/1972)" ,
|
||||
"RF09" => "Rivendita di documenti di trasporto pubblico e di sosta (art. 74, c.1, D.P.R. 633/1972)" ,
|
||||
"RF10" => "Intrattenimenti, giochi e altre attività di cui alla tariffa allegata al D.P.R. 640/72 (art. 74, c.6, D.P.R. 633/1972)" ,
|
||||
"RF11" => "Agenzie di viaggi e turismo (art. 74-ter, D.P.R. 633/1972)" ,
|
||||
"RF12" => "Agriturismo (art. 5, c.2, L. 413/1991)" ,
|
||||
"RF13" => "Vendite a domicilio (art. 25-bis, c.6, D.P.R. 600/1973)" ,
|
||||
"RF14" => "Rivendita di beni usati, di oggetti d’arte, d’antiquariato o da collezione (art. 36, D.L. 41/1995)" ,
|
||||
"RF15" => "Agenzie di vendite all’asta di oggetti d’arte, antiquariato o da collezione (art. 40-bis, D.L. 41/1995)" ,
|
||||
"RF16" => "IVA per cassa P.A. (art. 6, c.5, D.P.R. 633/1972)" ,
|
||||
"RF17" => "IVA per cassa (art. 32-bis, D.L. 83/2012)" ,
|
||||
"RF19" => "Regime forfettario" ,
|
||||
"RF18" => "Altro"
|
||||
];
|
||||
|
||||
public array $tipo_documento = [
|
||||
'TD01' => 'Fattura',
|
||||
'TD02' => 'Acconto/Anticipo su fattura',
|
||||
'TD03' => 'Acconto/Anticipo su parcella',
|
||||
'TD04' => 'Nota di Credito',
|
||||
'TD05' => 'Nota di Debito',
|
||||
'TD06' => 'Parcella',
|
||||
'TD16' => 'Integrazione fattura reverse charge interno',
|
||||
'TD17' => 'Integrazione/autofattura per acquisto servizi dall’estero',
|
||||
'TD18' => 'Integrazione per acquisto di beni intracomunitari',
|
||||
'TD19' => 'Integrazione/autofattura per acquisto di beni ex art.17 c.2 DPR 633/72',
|
||||
'TD20' => 'Autofattura per regolarizzazione e integrazione delle fatture',
|
||||
'TD21' => 'Autofattura per splafonamento',
|
||||
'TD22' => 'Estrazione beni da Deposito IVA',
|
||||
'TD23' => 'Estrazione beni da Deposito IVA con versamento dell’IVA',
|
||||
'TD24' => 'Fattura differita di cui all’art.21, comma 4, lett. a)',
|
||||
'TD25' => 'Fattura differita di cui all’art.21, comma 4, terzo periodo lett. b)',
|
||||
'TD26' => 'Cessione di beni ammortizzabili e per passaggi interni ',
|
||||
'TD27' => 'Fattura per autoconsumo o per cessioni gratuite senza rivalsa',
|
||||
];
|
||||
|
||||
public array $esigibilita_iva = [
|
||||
'I' => 'IVA ad esigibilità immediata',
|
||||
'D' => 'IVA ad esigibilità differita',
|
||||
'S' => 'Scissione dei pagamenti',
|
||||
];
|
||||
|
||||
public array $modalita_pagamento = [
|
||||
'MP01' => 'contanti', //cash
|
||||
'MP02' => 'assegno', //check
|
||||
'MP03' => 'assegno circolare', //cashier's check
|
||||
'MP04' => 'contanti presso Tesoreria', //cash at treasury
|
||||
'MP05' => 'bonifico', //bank transfer
|
||||
'MP06' => 'vaglia cambiario', //bill of exchange
|
||||
'MP07' => 'bollettino bancario', //bank bulletin
|
||||
'MP08' => 'carta di pagamento', //payment card
|
||||
'MP09' => 'RID', //RID
|
||||
'MP10' => 'RID utenze', //RID utilities
|
||||
'MP11' => 'RID veloce', //fast RID
|
||||
'MP12' => 'Riba', //Riba
|
||||
'MP13' => 'MAV //MAV',
|
||||
'MP14' => 'quietanza erario stato', //state treasury receipt
|
||||
'MP15' => 'giroconto su conti di contabilità speciale', //transfer to special accounting accounts
|
||||
'MP16' => 'domiciliazione bancaria', //bank domiciliation
|
||||
'MP17' => 'domiciliazione postale', //postal domiciliation
|
||||
'MP18' => 'bollettino di c/c postale', //postal giro account
|
||||
'MP19' => 'SEPA Direct Debit', //SEPA Direct Debit
|
||||
'MP20' => 'SEPA Direct Debit CORE', //SEPA Direct Debit CORE
|
||||
'MP21' => 'SEPA Direct Debit B2B', //SEPA Direct Debit B2B
|
||||
'MP22' => 'Trattenuta su somme già riscosse', //Withholding on sums already collected
|
||||
'MP23' => 'PagoPA', //PagoPA
|
||||
];
|
||||
|
||||
public array $esigibilita_pagamento = [
|
||||
'TP01' => 'Pagamento a rate',
|
||||
'TP02' => 'Pagamento completo',
|
||||
'TP03' => 'Anticipo',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function getRegimeFiscale(): array
|
||||
{
|
||||
return $this->regime_fiscale;
|
||||
}
|
||||
public function getTipoDocumento(): array
|
||||
{
|
||||
return $this->tipo_documento;
|
||||
}
|
||||
|
||||
public function getEsigibilitaIva(): array
|
||||
{
|
||||
return $this->esigibilita_iva;
|
||||
}
|
||||
|
||||
public function getModalitaPagamento(): array
|
||||
{
|
||||
return $this->modalita_pagamento;
|
||||
}
|
||||
|
||||
public function getEsigibilitaPagamento(): array
|
||||
{
|
||||
return $this->esigibilita_pagamento;
|
||||
}
|
||||
|
||||
}
|
42
app/Events/Statement/StatementWasEmailed.php
Normal file
42
app/Events/Statement/StatementWasEmailed.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Events\Statement;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class StatementWasEmailed.
|
||||
*/
|
||||
class StatementWasEmailed
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithSockets;
|
||||
use SerializesModels;
|
||||
|
||||
public function __construct(public Client $client, public Company $company, public string $end_date, public array $event_vars)
|
||||
{
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the channels the event should broadcast on.
|
||||
// *
|
||||
// * @return Channel|array
|
||||
// */
|
||||
public function broadcastOn()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -67,7 +67,6 @@ class Handler extends ExceptionHandler
|
||||
];
|
||||
|
||||
protected $hostedDontReport = [
|
||||
PDOException::class,
|
||||
MaxAttemptsExceededException::class,
|
||||
CommandNotFoundException::class,
|
||||
ValidationException::class,
|
||||
|
@ -122,6 +122,7 @@ class ActivityExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -448,6 +448,7 @@ class BaseExport
|
||||
'custom_value4' => 'task.custom_value4',
|
||||
'status' => 'task.status_id',
|
||||
'project' => 'task.project_id',
|
||||
'billable' => 'task.billable',
|
||||
];
|
||||
|
||||
protected array $forced_client_fields = [
|
||||
@ -837,12 +838,12 @@ class BaseExport
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply Product Filters
|
||||
*
|
||||
* @param Builder $query
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function applyProductFilters(Builder $query): Builder
|
||||
@ -862,13 +863,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Client Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param mixed $clients
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addClientFilter(Builder $query, $clients): Builder
|
||||
@ -879,22 +880,19 @@ class BaseExport
|
||||
|
||||
$transformed_clients = $this->transformKeys($clients);
|
||||
|
||||
nlog($transformed_clients);
|
||||
|
||||
if(count($transformed_clients) > 0) {
|
||||
nlog("yus");
|
||||
$query->whereIn('client_id', $transformed_clients);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Vendor Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $vendors
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addVendorFilter(Builder$query, string $vendors): Builder
|
||||
@ -912,13 +910,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AddProjectFilter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $projects
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addProjectFilter(Builder $query, string $projects): Builder
|
||||
@ -936,13 +934,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Category Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $expense_categories
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addCategoryFilter(Builder $query, string $expense_categories): Builder
|
||||
@ -961,13 +959,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Payment Status Filters
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addPaymentStatusFilters(Builder $query, string $status): Builder
|
||||
@ -978,7 +976,7 @@ class BaseExport
|
||||
if(in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
$query->where(function ($query) use ($status_parameters) {
|
||||
$payment_filters = [];
|
||||
|
||||
@ -1018,13 +1016,13 @@ class BaseExport
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add RecurringInvoice Status Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addRecurringInvoiceStatusFilter(Builder $query, string $status): Builder
|
||||
@ -1032,7 +1030,7 @@ class BaseExport
|
||||
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0){
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
@ -1062,7 +1060,7 @@ class BaseExport
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addQuoteStatusFilter(Builder $query, string $status): Builder
|
||||
@ -1128,12 +1126,12 @@ class BaseExport
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addPurchaseOrderStatusFilter(Builder $query, string $status): Builder
|
||||
{
|
||||
|
||||
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
@ -1236,7 +1234,7 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Date Range
|
||||
*
|
||||
@ -1283,13 +1281,13 @@ class BaseExport
|
||||
$this->end_date = now()->startOfMonth()->subMonth()->endOfMonth()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [now()->startOfMonth()->subMonth(), now()->startOfMonth()->subMonth()->endOfMonth()])->orderBy($this->date_key, 'ASC');
|
||||
case 'this_quarter':
|
||||
$this->start_date = (new \Carbon\Carbon('-3 months'))->firstOfQuarter()->format('Y-m-d');
|
||||
$this->end_date = (new \Carbon\Carbon('-3 months'))->lastOfQuarter()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('-3 months'))->firstOfQuarter(), (new \Carbon\Carbon('-3 months'))->lastOfQuarter()])->orderBy($this->date_key, 'ASC');
|
||||
$this->start_date = (new \Carbon\Carbon('0 months'))->startOfQuarter()->format('Y-m-d');
|
||||
$this->end_date = (new \Carbon\Carbon('0 months'))->endOfQuarter()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('0 months'))->startOfQuarter(), (new \Carbon\Carbon('0 months'))->endOfQuarter()])->orderBy($this->date_key, 'ASC');
|
||||
case 'last_quarter':
|
||||
$this->start_date = (new \Carbon\Carbon('-6 months'))->firstOfQuarter()->format('Y-m-d');
|
||||
$this->end_date = (new \Carbon\Carbon('-6 months'))->lastOfQuarter()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('-6 months'))->firstOfQuarter(), (new \Carbon\Carbon('-6 months'))->lastOfQuarter()])->orderBy($this->date_key, 'ASC');
|
||||
$this->start_date = (new \Carbon\Carbon('-3 months'))->startOfQuarter()->format('Y-m-d');
|
||||
$this->end_date = (new \Carbon\Carbon('-3 months'))->endOfQuarter()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [(new \Carbon\Carbon('-3 months'))->startOfQuarter(), (new \Carbon\Carbon('-3 months'))->endOfQuarter()])->orderBy($this->date_key, 'ASC');
|
||||
case 'last365_days':
|
||||
$this->start_date = now()->startOfDay()->subDays(365)->format('Y-m-d');
|
||||
$this->end_date = now()->startOfDay()->format('Y-m-d');
|
||||
@ -1580,7 +1578,7 @@ class BaseExport
|
||||
|
||||
public function queueDocuments(Builder $query)
|
||||
{
|
||||
|
||||
|
||||
if($query->getModel() instanceof Document) {
|
||||
$documents = $query->pluck('id')->toArray();
|
||||
} else {
|
||||
|
@ -41,7 +41,6 @@ class ClientExport extends BaseExport
|
||||
'balance' => 'client.balance',
|
||||
'city' => 'client.city',
|
||||
'country' => 'client.country_id',
|
||||
'credit_balance' => 'client.credit_balance',
|
||||
'custom_value1' => 'client.custom_value1',
|
||||
'custom_value2' => 'client.custom_value2',
|
||||
'custom_value3' => 'client.custom_value3',
|
||||
@ -126,8 +125,11 @@ class ClientExport extends BaseExport
|
||||
|
||||
$query = Client::query()->with('contacts')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -145,6 +147,7 @@ class ClientExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
@ -179,14 +182,10 @@ class ClientExport extends BaseExport
|
||||
} elseif (is_array($parts) && $parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
|
||||
$entity[$key] = $transformed_contact[$parts[1]];
|
||||
} else {
|
||||
// nlog($key);
|
||||
$entity[$key] = $this->decorator->transform($key, $client);
|
||||
// $entity[$key] = '';
|
||||
}
|
||||
}
|
||||
|
||||
// return $entity;
|
||||
|
||||
return $this->decorateAdvancedFields($client, $entity);
|
||||
}
|
||||
|
||||
@ -229,6 +228,18 @@ class ClientExport extends BaseExport
|
||||
$entity['client.classification'] = ctrans("texts.{$client->classification}") ?? '';
|
||||
}
|
||||
|
||||
if (in_array('client.industry_id', $this->input['report_keys']) && isset($client->industry_id)) {
|
||||
$entity['client.industry_id'] = ctrans("texts.industry_{$client->industry->name}") ?? '';
|
||||
}
|
||||
|
||||
if (in_array('client.country_id', $this->input['report_keys']) && isset($client->country_id)) {
|
||||
$entity['client.country_id'] = $client->country ? $client->country->full_name : '';
|
||||
}
|
||||
|
||||
if (in_array('client.shipping_country_id', $this->input['report_keys']) && isset($client->shipping_country_id)) {
|
||||
$entity['client.shipping_country_id'] = $client->shipping_country ? $client->shipping_country->full_name : '';
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,10 @@ class ContactExport extends BaseExport
|
||||
}
|
||||
|
||||
$query = ClientContact::query()
|
||||
->where('company_id', $this->company->id);
|
||||
->where('company_id', $this->company->id)
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
});
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -73,6 +76,7 @@ class ContactExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -102,6 +102,9 @@ class CreditExport extends BaseExport
|
||||
$query = Credit::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
|
||||
@ -129,6 +132,7 @@ class CreditExport extends BaseExport
|
||||
$query = $this->init();
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -92,6 +92,7 @@ class DocumentExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -82,8 +82,12 @@ class ExpenseExport extends BaseExport
|
||||
$query = Expense::query()
|
||||
->with('client')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -121,6 +125,7 @@ class ExpenseExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
@ -215,17 +220,17 @@ class ExpenseExport extends BaseExport
|
||||
// $entity['expense.client'] = $expense->client ? $expense->client->present()->name() : '';
|
||||
// }
|
||||
|
||||
// if (in_array('expense.invoice_id', $this->input['report_keys'])) {
|
||||
// $entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : '';
|
||||
// }
|
||||
if (in_array('expense.invoice_id', $this->input['report_keys'])) {
|
||||
$entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : '';
|
||||
}
|
||||
|
||||
// if (in_array('expense.category', $this->input['report_keys'])) {
|
||||
// $entity['expense.category'] = $expense->category ? $expense->category->name : '';
|
||||
// }
|
||||
|
||||
// if (in_array('expense.vendor_id', $this->input['report_keys'])) {
|
||||
// $entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : '';
|
||||
// }
|
||||
if (in_array('expense.vendor_id', $this->input['report_keys'])) {
|
||||
$entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : '';
|
||||
}
|
||||
|
||||
// if (in_array('expense.payment_type_id', $this->input['report_keys'])) {
|
||||
// $entity['expense.payment_type_id'] = $expense->payment_type ? $expense->payment_type->name : '';
|
||||
|
@ -57,8 +57,15 @@ class InvoiceExport extends BaseExport
|
||||
$query = Invoice::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -105,6 +112,7 @@ class InvoiceExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
@ -141,18 +149,6 @@ class InvoiceExport extends BaseExport
|
||||
private function decorateAdvancedFields(Invoice $invoice, array $entity): array
|
||||
{
|
||||
|
||||
// if (in_array('invoice.country_id', $this->input['report_keys'])) {
|
||||
// $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
|
||||
// }
|
||||
|
||||
// if (in_array('invoice.currency_id', $this->input['report_keys'])) {
|
||||
// $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
|
||||
// }
|
||||
|
||||
// if (in_array('invoice.client_id', $this->input['report_keys'])) {
|
||||
// $entity['invoice.client_id'] = $invoice->client->present()->name();
|
||||
// }
|
||||
|
||||
// if (in_array('invoice.status', $this->input['report_keys'])) {
|
||||
// $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
|
||||
// }
|
||||
|
@ -70,8 +70,14 @@ class InvoiceItemExport extends BaseExport
|
||||
$query = Invoice::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -128,6 +134,7 @@ class InvoiceItemExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -56,6 +56,9 @@ class PaymentExport extends BaseExport
|
||||
|
||||
$query = Payment::query()
|
||||
->withTrashed()
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
|
||||
@ -68,7 +71,7 @@ class PaymentExport extends BaseExport
|
||||
}
|
||||
|
||||
$query = $this->addPaymentStatusFilters($query, $this->input['status'] ?? '');
|
||||
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
@ -102,6 +105,7 @@ class PaymentExport extends BaseExport
|
||||
$query = $this->init();
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -73,8 +73,12 @@ class ProductExport extends BaseExport
|
||||
|
||||
$query = Product::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -93,6 +97,7 @@ class ProductExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -25,6 +25,7 @@ class ProductSalesExport extends BaseExport
|
||||
{
|
||||
public string $date_key = 'created_at';
|
||||
|
||||
/** @var Collection<\App\Models\Product> $products*/
|
||||
protected Collection $products;
|
||||
|
||||
public Writer $csv;
|
||||
@ -80,20 +81,20 @@ class ProductSalesExport extends BaseExport
|
||||
|
||||
public function filterByProducts($query)
|
||||
{
|
||||
|
||||
|
||||
$product_keys = &$this->input['product_key'];
|
||||
|
||||
if ($product_keys && !empty($this->input['product_key'])) {
|
||||
|
||||
$keys = explode(",", $product_keys);
|
||||
$query->where(function ($q) use ($keys){
|
||||
$query->where(function ($q) use ($keys) {
|
||||
|
||||
foreach($keys as $key) {
|
||||
foreach($keys as $key) {
|
||||
$q->orWhereJsonContains('line_items', ['product_key' => $key]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $query;
|
||||
@ -112,6 +113,7 @@ class ProductSalesExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||
@ -120,6 +122,9 @@ class ProductSalesExport extends BaseExport
|
||||
//insert the header
|
||||
$query = Invoice::query()
|
||||
->withTrashed()
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL, Invoice::STATUS_PAID]);
|
||||
@ -134,24 +139,29 @@ class ProductSalesExport extends BaseExport
|
||||
|
||||
$product_keys = &$this->input['product_key'];
|
||||
|
||||
if($product_keys){
|
||||
if($product_keys) {
|
||||
$product_keys = explode(",", $product_keys);
|
||||
}
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($invoice) use($product_keys) {
|
||||
->each(function ($invoice) use ($product_keys) {
|
||||
foreach ($invoice->line_items as $item) {
|
||||
|
||||
if($product_keys && in_array($item->product_key, $product_keys))
|
||||
$this->csv->insertOne($this->buildRow($invoice, $item));
|
||||
if($product_keys) {
|
||||
if(in_array($item->product_key, $product_keys)) {
|
||||
$this->csv->insertOne($this->buildRow($invoice, $item));
|
||||
}
|
||||
} else {
|
||||
$this->csv->insertOne($this->buildRow($invoice, $item));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$grouped = $this->sales->groupBy('product_key')->map(function ($key, $value) use($product_keys){
|
||||
$grouped = $this->sales->groupBy('product_key')->map(function ($key, $value) use ($product_keys) {
|
||||
|
||||
if($product_keys && !in_array($value, $product_keys)){
|
||||
if($product_keys && !in_array($value, $product_keys)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -175,7 +185,8 @@ class ProductSalesExport extends BaseExport
|
||||
|
||||
})->reject(function ($value) {
|
||||
return $value === false;
|
||||
});;
|
||||
});
|
||||
;
|
||||
|
||||
$this->csv->insertOne([]);
|
||||
$this->csv->insertOne([]);
|
||||
@ -317,9 +328,9 @@ class ProductSalesExport extends BaseExport
|
||||
* getProduct
|
||||
*
|
||||
* @param string $product_key
|
||||
* @return Product
|
||||
* @return ?\Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
private function getProduct(string $product_key): ?Product
|
||||
private function getProduct(string $product_key)
|
||||
{
|
||||
return $this->products->firstWhere('product_key', $product_key);
|
||||
}
|
||||
|
@ -58,16 +58,23 @@ class PurchaseOrderExport extends BaseExport
|
||||
$query = PurchaseOrder::query()
|
||||
->withTrashed()
|
||||
->with('vendor')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->whereHas('vendor', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
|
||||
$clients = &$this->input['client_id'];
|
||||
|
||||
if($clients)
|
||||
if($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
|
||||
$query = $this->addPurchaseOrderStatusFilter($query, $this->input['status'] ?? '');
|
||||
|
||||
@ -105,6 +112,7 @@ class PurchaseOrderExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -62,8 +62,14 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
|
||||
$query = PurchaseOrder::query()
|
||||
->withTrashed()
|
||||
->with('vendor')->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->whereHas('vendor', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->with('vendor')->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -112,6 +118,7 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
{
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
$query = $this->init();
|
||||
|
||||
|
@ -64,8 +64,14 @@ class QuoteExport extends BaseExport
|
||||
$query = Quote::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -110,6 +116,7 @@ class QuoteExport extends BaseExport
|
||||
{
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
$query = $this->init();
|
||||
|
||||
|
@ -65,8 +65,14 @@ class QuoteItemExport extends BaseExport
|
||||
|
||||
$query = Quote::query()
|
||||
->withTrashed()
|
||||
->with('client')->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->with('client')->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -118,6 +124,7 @@ class QuoteItemExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
$query = $this->init();
|
||||
|
||||
|
@ -56,8 +56,14 @@ class RecurringInvoiceExport extends BaseExport
|
||||
$query = RecurringInvoice::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -80,6 +86,7 @@ class RecurringInvoiceExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
@ -68,20 +68,25 @@ class TaskExport extends BaseExport
|
||||
|
||||
$query = Task::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
|
||||
$clients = &$this->input['client_id'];
|
||||
|
||||
if($clients)
|
||||
if($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
|
||||
$document_attachments = &$this->input['document_email_attachment'];
|
||||
|
||||
if($document_attachments)
|
||||
if($document_attachments) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
@ -94,6 +99,7 @@ class TaskExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
@ -220,7 +226,7 @@ class TaskExport extends BaseExport
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Task Status Filter
|
||||
*
|
||||
@ -230,7 +236,7 @@ class TaskExport extends BaseExport
|
||||
*/
|
||||
protected function addTaskStatusFilter(Builder $query, string $status): Builder
|
||||
{
|
||||
|
||||
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
|
@ -54,6 +54,7 @@ class VendorExport extends BaseExport
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
\League\Csv\CharsetConverter::addTo($this->csv, 'UTF-8', 'UTF-8');
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->input['report_keys'] = array_values($this->vendor_report_keys);
|
||||
@ -61,8 +62,11 @@ class VendorExport extends BaseExport
|
||||
|
||||
$query = Vendor::query()->with('contacts')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', $this->input['include_deleted'] ?? false);
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
|
@ -23,8 +23,13 @@ class ContactDecorator implements DecoratorInterface
|
||||
$contact = $entity;
|
||||
} elseif($entity->contacts) {
|
||||
$contact = $entity->contacts()->first();
|
||||
} elseif($entity->client) {
|
||||
$contact = $entity->client->primary_contact->first() ?? $entity->client->contacts()->whereNotNull('email')->first();
|
||||
} elseif($entity->vendor) {
|
||||
$contact = $entity->vendor->primary_contact->first() ?? $entity->vendor->contacts()->whereNotNull('email')->first();
|
||||
}
|
||||
|
||||
|
||||
if($contact && method_exists($this, $key)) {
|
||||
return $this->{$key}($contact);
|
||||
} elseif($contact && ($contact->{$key} ?? false)) {
|
||||
|
@ -23,14 +23,13 @@ class BankIntegrationFactory
|
||||
$bank_integration->company_id = $company_id;
|
||||
|
||||
$bank_integration->provider_name = '';
|
||||
$bank_integration->bank_account_id = '';
|
||||
$bank_integration->bank_account_name = '';
|
||||
$bank_integration->bank_account_number = '';
|
||||
$bank_integration->bank_account_status = '';
|
||||
$bank_integration->bank_account_type = '';
|
||||
$bank_integration->balance = 0;
|
||||
$bank_integration->currency = '';
|
||||
$bank_integration->auto_sync = 1;
|
||||
$bank_integration->auto_sync = true;
|
||||
|
||||
return $bank_integration;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ class ClientFactory
|
||||
$client->balance = 0;
|
||||
$client->paid_to_date = 0;
|
||||
$client->country_id = null;
|
||||
$client->is_deleted = 0;
|
||||
$client->is_deleted = false;
|
||||
$client->client_hash = Str::random(40);
|
||||
$client->settings = ClientSettings::defaults();
|
||||
$client->classification = '';
|
||||
|
@ -33,7 +33,7 @@ class CloneQuoteToProjectFactory
|
||||
$project->custom_value2 = '';
|
||||
$project->custom_value3 = '';
|
||||
$project->custom_value4 = '';
|
||||
$project->is_deleted = 0;
|
||||
$project->is_deleted = false;
|
||||
|
||||
return $project;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class CompanyFactory
|
||||
$company->markdown_email_enabled = true;
|
||||
$company->markdown_enabled = false;
|
||||
$company->tax_data = new TaxModel();
|
||||
$company->first_month_of_year = 1;
|
||||
$company->first_month_of_year = '1';
|
||||
$company->smtp_encryption = 'tls';
|
||||
$company->smtp_host = '';
|
||||
$company->smtp_local_domain = '';
|
||||
@ -56,7 +56,7 @@ class CompanyFactory
|
||||
$company->smtp_port = '';
|
||||
$company->smtp_username = '';
|
||||
$company->smtp_verify_peer = true;
|
||||
|
||||
|
||||
return $company;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class CompanyGatewayFactory
|
||||
$company_gateway->require_billing_address = false;
|
||||
$company_gateway->require_shipping_address = false;
|
||||
$company_gateway->config = encrypt(json_encode(new \stdClass()));
|
||||
$company_gateway->always_show_required_fields = true;
|
||||
|
||||
return $company_gateway;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class PurchaseOrderFactory
|
||||
$purchase_order->exchange_rate = 1;
|
||||
$purchase_order->total_taxes = 0;
|
||||
$purchase_order->uses_inclusive_taxes = false;
|
||||
|
||||
|
||||
return $purchase_order;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class SubscriptionFactory
|
||||
$billing_subscription->company_id = $company_id;
|
||||
$billing_subscription->user_id = $user_id;
|
||||
$billing_subscription->steps = collect(Purchase::defaultSteps())
|
||||
->map(fn($step) => StepService::mapClassNameToString($step))
|
||||
->map(fn ($step) => StepService::mapClassNameToString($step))
|
||||
->implode(',');
|
||||
|
||||
return $billing_subscription;
|
||||
|
@ -20,7 +20,7 @@ class TaxRateFactory
|
||||
$tax_rate = new TaxRate();
|
||||
|
||||
$tax_rate->name = '';
|
||||
$tax_rate->rate = '';
|
||||
$tax_rate->rate = 0;
|
||||
$tax_rate->company_id = $company_id;
|
||||
$tax_rate->user_id = $user_id;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserFactory
|
||||
{
|
||||
@ -29,6 +30,7 @@ class UserFactory
|
||||
$user->signature = '';
|
||||
$user->theme_id = 0;
|
||||
$user->user_logged_in_notification = true;
|
||||
$user->referral_code = Str::lower(Str::random(32));
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class VendorFactory
|
||||
$vendor->private_notes = '';
|
||||
$vendor->public_notes = '';
|
||||
$vendor->country_id = 4;
|
||||
$vendor->is_deleted = 0;
|
||||
$vendor->is_deleted = false;
|
||||
$vendor->vendor_hash = Str::random(40);
|
||||
// $vendor->classification = '';
|
||||
|
||||
|
@ -115,6 +115,29 @@ class BankTransactionFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filters the list based on Bank Accounts.
|
||||
*
|
||||
* @param string $ids Comma Separated List of bank account ids
|
||||
* @return Builder
|
||||
*/
|
||||
public function bank_integration_ids(string $ids = ''): Builder
|
||||
{
|
||||
if(strlen($ids) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
$ids = $this->transformKeys(explode(",", $ids));
|
||||
|
||||
$this->builder->where(function ($query) use ($ids) {
|
||||
$query->whereIn('bank_integration_id', $ids);
|
||||
});
|
||||
|
||||
return $this->builder;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
|
@ -160,6 +160,10 @@ class ClientFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'documents') {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'display_name') {
|
||||
$sort_col[0] = 'name';
|
||||
}
|
||||
|
@ -58,10 +58,11 @@ class DesignFilters extends QueryFilters
|
||||
|
||||
public function entities(string $entities = ''): Builder
|
||||
{
|
||||
|
||||
if(stripos($entities, 'statement') !== false)
|
||||
|
||||
if(stripos($entities, 'statement') !== false) {
|
||||
$entities = 'client';
|
||||
|
||||
}
|
||||
|
||||
if (strlen($entities) == 0 || str_contains($entities, ',')) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
@ -49,22 +49,22 @@ class DocumentFilters extends QueryFilters
|
||||
*/
|
||||
public function client_id(string $client_id = ''): Builder
|
||||
{
|
||||
|
||||
|
||||
return $this->builder->where(function ($query) use ($client_id) {
|
||||
$query->whereHasMorph('documentable', [
|
||||
\App\Models\Invoice::class,
|
||||
\App\Models\Quote::class,
|
||||
\App\Models\Credit::class,
|
||||
\App\Models\Expense::class,
|
||||
\App\Models\Payment::class,
|
||||
\App\Models\Invoice::class,
|
||||
\App\Models\Quote::class,
|
||||
\App\Models\Credit::class,
|
||||
\App\Models\Expense::class,
|
||||
\App\Models\Payment::class,
|
||||
\App\Models\Task::class,
|
||||
\App\Models\RecurringExpense::class,
|
||||
\App\Models\RecurringInvoice::class,
|
||||
\App\Models\Project::class,
|
||||
], function ($q2) use ($client_id) {
|
||||
$q2->where('client_id', $this->decodePrimaryKey($client_id));
|
||||
})->orWhereHasMorph('documentable', [\App\Models\Client::class], function ($q3) use ($client_id) {
|
||||
$q3->where('id', $this->decodePrimaryKey($client_id));
|
||||
$q2->where('client_id', $this->decodePrimaryKey($client_id));
|
||||
})->orWhereHasMorph('documentable', [\App\Models\Client::class], function ($q3) use ($client_id) {
|
||||
$q3->where('id', $this->decodePrimaryKey($client_id));
|
||||
});
|
||||
});
|
||||
|
||||
@ -74,8 +74,7 @@ class DocumentFilters extends QueryFilters
|
||||
{
|
||||
$types = explode(',', $types);
|
||||
|
||||
foreach ($types as $type)
|
||||
{
|
||||
foreach ($types as $type) {
|
||||
match($type) {
|
||||
'private' => $this->builder->where('is_public', 0),
|
||||
'public' => $this->builder->where('is_public', 1),
|
||||
@ -87,7 +86,7 @@ class DocumentFilters extends QueryFilters
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
|
@ -44,6 +44,9 @@ class ExpenseFilters extends QueryFilters
|
||||
})
|
||||
->orWhereHas('vendor', function ($q) use ($filter) {
|
||||
$q->where('name', 'like', '%'.$filter.'%');
|
||||
})
|
||||
->orWhereHas('client', function ($q) use ($filter) {
|
||||
$q->where('name', 'like', '%'.$filter.'%');
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -107,6 +110,12 @@ class ExpenseFilters extends QueryFilters
|
||||
$query->whereNull('payment_date');
|
||||
});
|
||||
}
|
||||
|
||||
if(in_array('uncategorized', $status_parameters)) {
|
||||
$query->orWhere(function ($query) {
|
||||
$query->whereNull('category_id');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// nlog($this->builder->toSql());
|
||||
@ -200,7 +209,7 @@ class ExpenseFilters extends QueryFilters
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
}
|
||||
|
||||
if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) {
|
||||
if (is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['amount', 'public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4'])) {
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,12 @@ class InvoiceFilters extends QueryFilters
|
||||
if (is_numeric($date)) {
|
||||
$date = Carbon::createFromTimestamp((int)$date);
|
||||
} else {
|
||||
$date = Carbon::parse($date);
|
||||
|
||||
try {
|
||||
$date = Carbon::parse($date);
|
||||
} catch(\Exception $e) {
|
||||
return $this->builder;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->builder->where('date', '>=', $date);
|
||||
@ -333,7 +338,7 @@ class InvoiceFilters extends QueryFilters
|
||||
// return $this->builder->orderByRaw('CAST(number AS UNSIGNED), number ' . $dir);
|
||||
// return $this->builder->orderByRaw("number REGEXP '^[A-Za-z]+$',CAST(number as SIGNED INTEGER),CAST(REPLACE(number,'-','')AS SIGNED INTEGER) ,number");
|
||||
// return $this->builder->orderByRaw('ABS(number) ' . $dir);
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $dir);
|
||||
|
@ -146,14 +146,14 @@ class RecurringExpenseFilters extends QueryFilters
|
||||
return $this->builder
|
||||
->orderByRaw('ISNULL(client_id), client_id '. $sort_col[1])
|
||||
->orderBy(\App\Models\Client::select('name')
|
||||
->whereColumn('clients.id', 'expenses.client_id'), $sort_col[1]);
|
||||
->whereColumn('clients.id', 'recurring_expenses.client_id'), $sort_col[1]);
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'vendor_id' && in_array($sort_col[1], ['asc', 'desc'])) {
|
||||
return $this->builder
|
||||
->orderByRaw('ISNULL(vendor_id), vendor_id '. $sort_col[1])
|
||||
->orderBy(\App\Models\Vendor::select('name')
|
||||
->whereColumn('vendors.id', 'expenses.vendor_id'), $sort_col[1]);
|
||||
->whereColumn('vendors.id', 'recurring_expenses.vendor_id'), $sort_col[1]);
|
||||
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ class RecurringExpenseFilters extends QueryFilters
|
||||
return $this->builder
|
||||
->orderByRaw('ISNULL(category_id), category_id '. $sort_col[1])
|
||||
->orderBy(\App\Models\ExpenseCategory::select('name')
|
||||
->whereColumn('expense_categories.id', 'expenses.category_id'), $sort_col[1]);
|
||||
->whereColumn('expense_categories.id', 'recurring_expenses.category_id'), $sort_col[1]);
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'number') {
|
||||
|
@ -133,6 +133,10 @@ class RecurringInvoiceFilters extends QueryFilters
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'next_send_datetime') {
|
||||
$sort_col[0] = 'next_send_date';
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $dir);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ class TaskFilters extends QueryFilters
|
||||
*
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
public function filter(string $filter = ''): Builder
|
||||
{
|
||||
@ -89,7 +88,7 @@ class TaskFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
public function project_tasks($project): Builder
|
||||
public function project_tasks(string $project = ''): Builder
|
||||
{
|
||||
if (strlen($project) == 0) {
|
||||
return $this->builder;
|
||||
|
@ -24,9 +24,10 @@ use App\Services\Email\Email;
|
||||
use App\Models\BankIntegration;
|
||||
use App\Services\Email\EmailObject;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
use App\Helpers\Bank\Nordigen\Transformer\AccountTransformer;
|
||||
use App\Helpers\Bank\Nordigen\Transformer\TransactionTransformer;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
|
||||
class Nordigen
|
||||
{
|
||||
@ -99,7 +100,7 @@ class Nordigen
|
||||
} catch (\Exception $e) {
|
||||
|
||||
nlog("Nordigen getAccount() failed => {$account_id} => " . $e->getMessage());
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
@ -149,6 +150,11 @@ class Nordigen
|
||||
|
||||
public function disabledAccountEmail(BankIntegration $bank_integration): void
|
||||
{
|
||||
$cache_key = "email_quota:{$bank_integration->company->company_key}:{$bank_integration->id}";
|
||||
|
||||
if(Cache::has($cache_key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
App::setLocale($bank_integration->company->getLocale());
|
||||
|
||||
@ -164,6 +170,7 @@ class Nordigen
|
||||
|
||||
Email::dispatch($mo, $bank_integration->company);
|
||||
|
||||
Cache::put($cache_key, true, 60 * 60 * 24);
|
||||
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ class TransactionTransformer implements BankRevenueInterface
|
||||
|
||||
private Company $company;
|
||||
|
||||
function __construct(Company $company)
|
||||
public function __construct(Company $company)
|
||||
{
|
||||
$this->company = $company;
|
||||
}
|
||||
@ -148,7 +148,7 @@ class TransactionTransformer implements BankRevenueInterface
|
||||
'description' => $description,
|
||||
'participant' => $participant,
|
||||
'participant_name' => $participant_name,
|
||||
'base_type' => (int) $transaction["transactionAmount"]["amount"] <= 0 ? 'DEBIT' : 'CREDIT',
|
||||
'base_type' => $amount < 0 ? 'DEBIT' : 'CREDIT',
|
||||
];
|
||||
|
||||
}
|
||||
@ -191,7 +191,11 @@ class TransactionTransformer implements BankRevenueInterface
|
||||
$date_format_default = $date_format->format;
|
||||
}
|
||||
|
||||
return Carbon::createFromFormat("d-m-Y", $input)->setTimezone($timezone_name)->format($date_format_default) ?? $input;
|
||||
try {
|
||||
return Carbon::createFromFormat("d-m-Y", $input)->setTimezone($timezone_name)->format($date_format_default) ?? $input;
|
||||
} catch (\Exception $e) {
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* [
|
||||
"account": [
|
||||
[
|
||||
|
@ -73,22 +73,42 @@ class EpcQrGenerator
|
||||
|
||||
public function encodeMessage()
|
||||
{
|
||||
return rtrim(implode("\n", [
|
||||
$this->sepa['serviceTag'],
|
||||
sprintf('%03d', $this->sepa['version']),
|
||||
$this->sepa['characterSet'],
|
||||
$this->sepa['identification'],
|
||||
isset($this->company?->custom_fields?->company2) ? $this->company->settings->custom_value2 : '',
|
||||
$this->company->present()->name(),
|
||||
isset($this->company?->custom_fields?->company1) ? $this->company->settings->custom_value1 : '',
|
||||
$this->formatMoney($this->amount),
|
||||
$this->sepa['purpose'],
|
||||
substr($this->invoice->number, 0, 34),
|
||||
'',
|
||||
' '
|
||||
]), "\n");
|
||||
// return rtrim(implode("\n", [
|
||||
// $this->sepa['serviceTag'],
|
||||
// sprintf('%03d', $this->sepa['version']),
|
||||
// $this->sepa['characterSet'],
|
||||
// $this->sepa['identification'],
|
||||
// isset($this->company?->custom_fields?->company2) ? $this->company->settings->custom_value2 : '',
|
||||
// $this->company->present()->name(),
|
||||
// isset($this->company?->custom_fields?->company1) ? $this->company->settings->custom_value1 : '',
|
||||
// $this->formatMoney($this->amount),
|
||||
// $this->sepa['purpose'],
|
||||
// substr($this->invoice->number, 0, 34),
|
||||
// '',
|
||||
// ' '
|
||||
// ]), "\n");
|
||||
|
||||
|
||||
$data = [
|
||||
'BCD',
|
||||
'002', // Version
|
||||
'1', // Encoding: 1 = UTF-8
|
||||
'SCT', // Service Tag: SEPA Credit Transfer
|
||||
isset($this->company?->custom_fields?->company2) ? $this->company->settings->custom_value2 : '', // BIC
|
||||
$this->company->present()->name(), // Name of the beneficiary
|
||||
isset($this->company?->custom_fields?->company1) ? $this->company->settings->custom_value1 : '', // IBAN
|
||||
$this->formatMoney($this->amount), // Amount with EUR prefix
|
||||
'', // Reference
|
||||
substr($this->invoice->number, 0, 34) // Unstructured remittance information
|
||||
];
|
||||
|
||||
return implode("\n", $data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// substr("{$this->invoice->number} {$this->invoice->client->number}", 0,139),
|
||||
|
||||
private function validateFields()
|
||||
{
|
||||
if (Ninja::isSelfHost() && isset($this->company?->custom_fields?->company2)) {
|
||||
|
@ -44,3 +44,29 @@ function nlog($output, $context = []): void
|
||||
$output = null;
|
||||
$context = null;
|
||||
}
|
||||
|
||||
|
||||
function nrlog($output, $context = []): void
|
||||
{
|
||||
if (! config('ninja.expanded_logging')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gettype($output) == 'object') {
|
||||
$output = print_r($output, 1);
|
||||
}
|
||||
|
||||
// $trace = debug_backtrace();
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
try {
|
||||
info($output);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
} else {
|
||||
\Illuminate\Support\Facades\Log::channel('invoiceninja-reminders')->info($output, $context);
|
||||
}
|
||||
|
||||
$output = null;
|
||||
$context = null;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ trait CustomValuer
|
||||
|
||||
public function valuerTax($custom_value, $has_custom_invoice_taxes)
|
||||
{
|
||||
|
||||
|
||||
if (isset($custom_value) && is_numeric($custom_value) && $has_custom_invoice_taxes !== false) {
|
||||
return round($custom_value * ($this->invoice->tax_rate1 / 100), 2) + round($custom_value * ($this->invoice->tax_rate2 / 100), 2) + round($custom_value * ($this->invoice->tax_rate3 / 100), 2);
|
||||
}
|
||||
@ -35,17 +35,18 @@ trait CustomValuer
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function multiInclusiveTax($value, $has_custom_invoice_taxes) {
|
||||
public function multiInclusiveTax($custom_value, $has_custom_invoice_taxes)
|
||||
{
|
||||
|
||||
if (isset($custom_value) && is_numeric($custom_value) && $has_custom_invoice_taxes !== false) {
|
||||
|
||||
$tax = 0;
|
||||
$tax = 0;
|
||||
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate1 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate2 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate3 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate1 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate2 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate3 / 100))), 2);
|
||||
|
||||
return round($tax,2);
|
||||
return round($tax, 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -182,7 +182,7 @@ class InvoiceItemSum
|
||||
$class = "App\DataMapper\Tax\\".$this->client->company->country()->iso_3166_2."\\Rule";
|
||||
|
||||
$this->rule = new $class();
|
||||
|
||||
|
||||
if($this->rule->regionWithNoTaxCoverage($this->client->country->iso_3166_2)) {
|
||||
return $this;
|
||||
}
|
||||
|
@ -227,12 +227,15 @@ class InvoiceSum
|
||||
|
||||
public function getRecurringInvoice()
|
||||
{
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->precision);
|
||||
$this->invoice->total_taxes = $this->getTotalTaxes();
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->precision);
|
||||
// $this->invoice->amount = $this->formatValue($this->getTotal(), $this->precision);
|
||||
// $this->invoice->total_taxes = $this->getTotalTaxes();
|
||||
|
||||
$this->setCalculatedAttributes();
|
||||
$this->invoice->balance = $this->invoice->amount;
|
||||
$this->invoice->saveQuietly();
|
||||
|
||||
// $this->invoice->saveQuietly();
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
@ -242,12 +245,10 @@ class InvoiceSum
|
||||
*/
|
||||
private function setCalculatedAttributes(): self
|
||||
{
|
||||
/* If amount != balance then some money has been paid on the invoice, need to subtract this difference from the total to set the new balance */
|
||||
|
||||
if ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
if($this->invoice->status_id == Invoice::STATUS_CANCELLED) {
|
||||
$this->invoice->balance = 0;
|
||||
} elseif ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
if ($this->invoice->amount != $this->invoice->balance) {
|
||||
// $paid_to_date = $this->invoice->amount - $this->invoice->balance;
|
||||
|
||||
$this->invoice->balance = Number::roundValue($this->getTotal(), $this->precision) - $this->invoice->paid_to_date; //21-02-2024 cannot use the calculated $paid_to_date here as it could send the balance backward.
|
||||
} else {
|
||||
$this->invoice->balance = Number::roundValue($this->getTotal(), $this->precision);
|
||||
@ -256,7 +257,7 @@ class InvoiceSum
|
||||
/* Set new calculated total */
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->precision);
|
||||
|
||||
if($this->rappen_rounding){
|
||||
if($this->rappen_rounding) {
|
||||
$this->invoice->amount = $this->roundRappen($this->invoice->amount);
|
||||
$this->invoice->balance = $this->roundRappen($this->invoice->balance);
|
||||
}
|
||||
@ -267,7 +268,7 @@ class InvoiceSum
|
||||
}
|
||||
|
||||
|
||||
function roundRappen($value): float
|
||||
public function roundRappen($value): float
|
||||
{
|
||||
return round($value / .05, 0) * .05;
|
||||
}
|
||||
|
@ -11,14 +11,14 @@
|
||||
|
||||
namespace App\Helpers\Invoice;
|
||||
|
||||
use App\Models\Quote;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\Quote;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\RecurringQuote;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
|
||||
class InvoiceSumInclusive
|
||||
{
|
||||
@ -74,8 +74,8 @@ class InvoiceSumInclusive
|
||||
{
|
||||
$this->calculateLineItems()
|
||||
->calculateDiscount()
|
||||
->calculateCustomValues()
|
||||
->calculateInvoiceTaxes()
|
||||
->calculateCustomValues()
|
||||
->setTaxMap()
|
||||
->calculateTotals() //just don't add the taxes!!
|
||||
->calculateBalance()
|
||||
@ -119,7 +119,6 @@ class InvoiceSumInclusive
|
||||
$this->total_taxes += $this->multiInclusiveTax($this->invoice->custom_surcharge4, $this->invoice->custom_surcharge_tax4);
|
||||
$this->total_custom_values += $this->valuer($this->invoice->custom_surcharge4);
|
||||
|
||||
|
||||
$this->total += $this->total_custom_values;
|
||||
|
||||
return $this;
|
||||
@ -138,21 +137,21 @@ class InvoiceSumInclusive
|
||||
}
|
||||
|
||||
//Handles cases where the surcharge is not taxed
|
||||
if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && $this->invoice->custom_surcharge_tax1) {
|
||||
$amount += $this->invoice->custom_surcharge1;
|
||||
}
|
||||
// if(is_numeric($this->invoice->custom_surcharge1) && $this->invoice->custom_surcharge1 > 0 && !$this->invoice->custom_surcharge_tax1) {
|
||||
// $amount += $this->invoice->custom_surcharge1;
|
||||
// }
|
||||
|
||||
if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && $this->invoice->custom_surcharge_tax2) {
|
||||
$amount += $this->invoice->custom_surcharge2;
|
||||
}
|
||||
// if(is_numeric($this->invoice->custom_surcharge2) && $this->invoice->custom_surcharge2 > 0 && !$this->invoice->custom_surcharge_tax2) {
|
||||
// $amount += $this->invoice->custom_surcharge2;
|
||||
// }
|
||||
|
||||
if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && $this->invoice->custom_surcharge_tax3) {
|
||||
$amount += $this->invoice->custom_surcharge3;
|
||||
}
|
||||
// if(is_numeric($this->invoice->custom_surcharge3) && $this->invoice->custom_surcharge3 > 0 && !$this->invoice->custom_surcharge_tax3) {
|
||||
// $amount += $this->invoice->custom_surcharge3;
|
||||
// }
|
||||
|
||||
if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && $this->invoice->custom_surcharge_tax4) {
|
||||
$amount += $this->invoice->custom_surcharge4;
|
||||
}
|
||||
// if(is_numeric($this->invoice->custom_surcharge4) && $this->invoice->custom_surcharge4 > 0 && !$this->invoice->custom_surcharge_tax4) {
|
||||
// $amount += $this->invoice->custom_surcharge4;
|
||||
// }
|
||||
|
||||
if (is_string($this->invoice->tax_name1) && strlen($this->invoice->tax_name1) > 1) {
|
||||
$tax = $this->calcInclusiveLineTax($this->invoice->tax_rate1, $amount);
|
||||
@ -280,10 +279,10 @@ class InvoiceSumInclusive
|
||||
private function setCalculatedAttributes()
|
||||
{
|
||||
/* If amount != balance then some money has been paid on the invoice, need to subtract this difference from the total to set the new balance */
|
||||
if ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
if($this->invoice->status_id == Invoice::STATUS_CANCELLED) {
|
||||
$this->invoice->balance = 0;
|
||||
} elseif ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
if ($this->invoice->amount != $this->invoice->balance) {
|
||||
// $paid_to_date = $this->invoice->amount - $this->invoice->balance;
|
||||
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->precision) - $this->invoice->paid_to_date;
|
||||
} else {
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->precision);
|
||||
@ -302,8 +301,8 @@ class InvoiceSumInclusive
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
function roundRappen($value): float
|
||||
|
||||
public function roundRappen($value): float
|
||||
{
|
||||
return round($value / .05, 0) * .05;
|
||||
}
|
||||
@ -373,7 +372,7 @@ class InvoiceSumInclusive
|
||||
|
||||
$this->total_taxes += $total_line_tax;
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ class GmailTransport extends AbstractTransport
|
||||
$message = MessageConverter::toEmail($message->getOriginalMessage());
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$token = $message->getHeaders()->get('gmailtoken')->getValue();
|
||||
$token = $message->getHeaders()->get('gmailtoken')->getValue(); // @phpstan-ignore-line
|
||||
$message->getHeaders()->remove('gmailtoken');
|
||||
|
||||
$client = new Client();
|
||||
@ -53,9 +53,8 @@ class GmailTransport extends AbstractTransport
|
||||
if ($bccs) {
|
||||
$bcc_list = 'Bcc: ';
|
||||
|
||||
foreach ($bccs->getAddresses() as $address) {
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
foreach ($bccs->getAddresses() as $address) {
|
||||
$bcc_list .= $address->getAddress() .',';
|
||||
}
|
||||
|
||||
@ -64,15 +63,23 @@ class GmailTransport extends AbstractTransport
|
||||
|
||||
$body->setRaw($this->base64_encode($bcc_list.$message->toString()));
|
||||
|
||||
try {
|
||||
$service->users_messages->send('me', $body, []);
|
||||
} catch(\Google\Service\Exception $e) {
|
||||
/* Need to slow down */
|
||||
if ($e->getCode() == '429') {
|
||||
nlog("429 google - retrying ");
|
||||
$service->users_messages->send('me', $body, []);
|
||||
}
|
||||
}
|
||||
// try {
|
||||
$service->users_messages->send('me', $body, []);
|
||||
// } catch(\Google\Service\Exception $e) {
|
||||
// /* Need to slow down */
|
||||
// if ($e->getCode() == '429') {
|
||||
// nlog("429 google - retrying ");
|
||||
|
||||
// sleep(rand(3,8));
|
||||
|
||||
// try {
|
||||
// $service->users_messages->send('me', $body, []);
|
||||
// } catch(\Google\Service\Exception $e) {
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private function base64_encode($data)
|
||||
|
@ -54,12 +54,19 @@ class Office365MailTransport extends AbstractTransport
|
||||
->setReturnType(\Microsoft\Graph\Model\Message::class)
|
||||
->execute();
|
||||
} catch (\Exception $e) {
|
||||
sleep(5);
|
||||
$graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail')
|
||||
->attachBody(base64_encode($bcc_list.$message->toString()))
|
||||
->addHeaders(['Content-Type' => 'text/plain'])
|
||||
->setReturnType(\Microsoft\Graph\Model\Message::class)
|
||||
->execute();
|
||||
|
||||
sleep(rand(5, 10));
|
||||
|
||||
try {
|
||||
$graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail')
|
||||
->attachBody(base64_encode($bcc_list.$message->toString()))
|
||||
->addHeaders(['Content-Type' => 'text/plain'])
|
||||
->setReturnType(\Microsoft\Graph\Model\Message::class)
|
||||
->execute();
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,13 +178,13 @@ class SwissQrGenerator
|
||||
if(is_iterable($qrBill->getViolations())) {
|
||||
|
||||
foreach ($qrBill->getViolations() as $key => $violation) {
|
||||
nlog("qr");
|
||||
nlog($violation);
|
||||
// nlog("qr");
|
||||
// nlog($violation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nlog($e->getMessage());
|
||||
// nlog($e->getMessage());
|
||||
|
||||
return '';
|
||||
// return $e->getMessage();
|
||||
|
@ -61,7 +61,7 @@ class AccountController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param CreateAccountRequest $request
|
||||
* @return Response
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*/
|
||||
public function store(CreateAccountRequest $request)
|
||||
|
@ -105,6 +105,14 @@ class ActivityController extends BaseController
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* downloadHistoricalEntity
|
||||
*
|
||||
* @param DownloadHistoricalEntityRequest $request
|
||||
* @param Activity $activity
|
||||
* @return \Symfony\Component\HttpFoundation\StreamedResponse | \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function downloadHistoricalEntity(DownloadHistoricalEntityRequest $request, Activity $activity)
|
||||
{
|
||||
$backup = $activity->backup;
|
||||
|
@ -165,7 +165,9 @@ class ContactLoginController extends Controller
|
||||
|
||||
private function setRedirectPath()
|
||||
{
|
||||
if (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_INVOICES) {
|
||||
if (auth()->guard('contact')->user()->client->getSetting('enable_client_portal_dashboard') === true) {
|
||||
$this->redirectTo = '/client/dashboard';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_INVOICES) {
|
||||
$this->redirectTo = '/client/invoices';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_RECURRING_INVOICES) {
|
||||
$this->redirectTo = '/client/recurring_invoices';
|
||||
|
@ -50,7 +50,7 @@ class ContactRegisterController extends Controller
|
||||
public function register(RegisterRequest $request)
|
||||
{
|
||||
$request->merge(['company' => $request->company()]);
|
||||
|
||||
|
||||
$service = new ClientRegisterService(
|
||||
company: $request->company(),
|
||||
);
|
||||
|
@ -46,7 +46,7 @@ class ForgotPasswordController extends Controller
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function sendResetLinkEmail(Request $request)
|
||||
|
@ -13,6 +13,7 @@
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\DataMapper\Analytics\LoginFailure;
|
||||
use App\DataMapper\Analytics\LoginMeta;
|
||||
use App\DataMapper\Analytics\LoginSuccess;
|
||||
use App\Events\User\UserLoggedIn;
|
||||
use App\Http\Controllers\BaseController;
|
||||
@ -111,6 +112,9 @@ class LoginController extends BaseController
|
||||
->increment()
|
||||
->batch();
|
||||
|
||||
LightLogs::create(new LoginMeta($request->email, $request->ip, 'success'))
|
||||
->batch();
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = $this->guard()->user();
|
||||
|
||||
@ -159,6 +163,9 @@ class LoginController extends BaseController
|
||||
->increment()
|
||||
->batch();
|
||||
|
||||
LightLogs::create(new LoginMeta($request->email, $request->ip, 'failure'))
|
||||
->batch();
|
||||
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
return response()
|
||||
@ -172,7 +179,7 @@ class LoginController extends BaseController
|
||||
* Refreshes the data feed with the current Company User.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response|JsonResponse
|
||||
* @return \Illuminate\Http\Response|JsonResponse
|
||||
*/
|
||||
public function refresh(Request $request)
|
||||
{
|
||||
@ -391,8 +398,8 @@ class LoginController extends BaseController
|
||||
$truth->setCompany($set_company);
|
||||
|
||||
//21-03-2024
|
||||
$cu->each(function ($cu){
|
||||
if(CompanyToken::where('company_id', $cu->company_id)->where('user_id', $cu->user_id)->where('is_system', true)->doesntExist()){
|
||||
$cu->each(function ($cu) {
|
||||
if(CompanyToken::where('company_id', $cu->company_id)->where('user_id', $cu->user_id)->where('is_system', true)->doesntExist()) {
|
||||
(new CreateCompanyToken($cu->company, $cu->user, request()->server('HTTP_USER_AGENT')))->handle();
|
||||
}
|
||||
});
|
||||
@ -481,7 +488,7 @@ class LoginController extends BaseController
|
||||
* send login response to oauthed users
|
||||
*
|
||||
* @param \App\Models\User $existing_user
|
||||
* @return Response | JsonResponse
|
||||
* @return Response| \Illuminate\Http\JsonResponse | JsonResponse
|
||||
*/
|
||||
private function existingOauthUser($existing_user)
|
||||
{
|
||||
@ -651,7 +658,9 @@ class LoginController extends BaseController
|
||||
}
|
||||
|
||||
if(request()->hasHeader('X-REACT') || request()->query('react')) {
|
||||
Cache::put("react_redir:".auth()->user()?->account->key, 'true', 300);
|
||||
/**@var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
Cache::put("react_redir:".$user?->account->key, 'true', 300);
|
||||
}
|
||||
|
||||
if (request()->has('code')) {
|
||||
|
@ -78,7 +78,7 @@ class ResetPasswordController extends Controller
|
||||
* Reset the given user's password.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse|JsonResponse
|
||||
* @return \Illuminate\Http\RedirectResponse | \Illuminate\Http\RedirectResponse|JsonResponse
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function reset(Request $request)
|
||||
|
@ -35,7 +35,7 @@ class NordigenController extends BaseController
|
||||
/** @var array $context */
|
||||
$context = $request->getTokenContent();
|
||||
$company = $request->getCompany();
|
||||
$lang = $company->locale();
|
||||
$lang = substr($company->locale(), 0, 2);
|
||||
$context["lang"] = $lang;
|
||||
|
||||
if (!$context) {
|
||||
@ -143,7 +143,7 @@ class NordigenController extends BaseController
|
||||
$data = $request->all();
|
||||
$company = $request->getCompany();
|
||||
$account = $company->account;
|
||||
$lang = $company->locale();
|
||||
$lang = substr($company->locale(), 0, 2);
|
||||
|
||||
/** @var array $context */
|
||||
$context = $request->getTokenContent();
|
||||
|
@ -301,8 +301,30 @@ class YodleeController extends BaseController
|
||||
|
||||
$summary = $yodlee->getAccountSummary($account_number);
|
||||
|
||||
$transformed_summary = AccountSummary::from($summary[0]);
|
||||
//@todo remove laravel-data
|
||||
// $transformed_summary = AccountSummary::from($summary[0]);
|
||||
$transformed_summary = $this->transformSummary($summary[0]);
|
||||
|
||||
return response()->json($transformed_summary, 200);
|
||||
}
|
||||
|
||||
private function transformSummary($summary): array
|
||||
{
|
||||
$dto = new \stdClass();
|
||||
$dto->id = $summary['id'] ?? 0;
|
||||
$dto->account_type = $summary['CONTAINER'] ?? '';
|
||||
|
||||
$dto->account_status = $summary['accountStatus'] ?? '';
|
||||
$dto->account_number = $summary['accountNumber'] ?? '';
|
||||
$dto->provider_account_id = $summary['providerAccountId'] ?? '';
|
||||
$dto->provider_id = $summary['providerId'] ?? '';
|
||||
$dto->provider_name = $summary['providerName'] ?? '';
|
||||
$dto->nickname = $summary['nickname'] ?? '';
|
||||
$dto->account_name = $summary['accountName'] ?? '';
|
||||
$dto->current_balance = $summary['currentBalance']['amount'] ?? 0;
|
||||
$dto->account_currency = $summary['currentBalance']['currency'] ?? 0;
|
||||
|
||||
return (array)$dto;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class BankIntegrationController extends BaseController
|
||||
|
||||
/**
|
||||
* @param BankIntegrationFilters $filters
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function index(BankIntegrationFilters $filters)
|
||||
{
|
||||
@ -69,7 +69,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param ShowBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function show(ShowBankIntegrationRequest $request, BankIntegration $bank_integration)
|
||||
@ -83,7 +83,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param EditBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function edit(EditBankIntegrationRequest $request, BankIntegration $bank_integration)
|
||||
@ -96,7 +96,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param UpdateBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function update(UpdateBankIntegrationRequest $request, BankIntegration $bank_integration)
|
||||
@ -111,7 +111,7 @@ class BankIntegrationController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateBankIntegrationRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*/
|
||||
@ -130,7 +130,7 @@ class BankIntegrationController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreBankIntegrationRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function store(StoreBankIntegrationRequest $request)
|
||||
@ -150,7 +150,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param DestroyBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
@ -165,7 +165,7 @@ class BankIntegrationController extends BaseController
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function bulk(BulkBankIntegrationRequest $request)
|
||||
@ -295,7 +295,7 @@ class BankIntegrationController extends BaseController
|
||||
* Return the remote list of accounts stored on the third party provider
|
||||
* and update our local cache.
|
||||
*
|
||||
* @return Response | JsonResponse
|
||||
* @return Response| \Illuminate\Http\JsonResponse | JsonResponse
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -85,7 +85,7 @@ class BankTransactionRuleController extends BaseController
|
||||
* ),
|
||||
* )
|
||||
* @param BankTransactionRuleFilters $filters
|
||||
* @return Response|mixed
|
||||
* @return Response| \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function index(BankTransactionRuleFilters $filters)
|
||||
{
|
||||
@ -99,7 +99,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param ShowBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -154,7 +154,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param EditBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -208,7 +208,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param UpdateBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -269,7 +269,7 @@ class BankTransactionRuleController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateBankTransactionRuleRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -317,7 +317,7 @@ class BankTransactionRuleController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreBankTransactionRuleRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -369,7 +369,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param DestroyBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @throws \Exception
|
||||
@ -424,7 +424,7 @@ class BankTransactionRuleController extends BaseController
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/bank_transation_rules/bulk",
|
||||
|
@ -11,36 +11,37 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Models\BankIntegration;
|
||||
use App\Models\BankTransaction;
|
||||
use App\Models\BankTransactionRule;
|
||||
use App\Models\User;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Client;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\Design;
|
||||
use App\Models\ExpenseCategory;
|
||||
use App\Models\GroupSetting;
|
||||
use App\Models\PaymentTerm;
|
||||
use App\Utils\Statics;
|
||||
use App\Models\Account;
|
||||
use App\Models\TaxRate;
|
||||
use App\Models\Webhook;
|
||||
use App\Models\Scheduler;
|
||||
use App\Models\TaskStatus;
|
||||
use App\Models\TaxRate;
|
||||
use App\Models\User;
|
||||
use App\Models\Webhook;
|
||||
use App\Transformers\ArraySerializer;
|
||||
use App\Transformers\EntityTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Statics;
|
||||
use App\Utils\Traits\AppSetup;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Models\PaymentTerm;
|
||||
use Illuminate\Support\Str;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use App\Models\GroupSetting;
|
||||
use Illuminate\Http\Response;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Utils\Traits\AppSetup;
|
||||
use App\Models\BankIntegration;
|
||||
use App\Models\BankTransaction;
|
||||
use App\Models\ExpenseCategory;
|
||||
use League\Fractal\Resource\Item;
|
||||
use App\Models\BankTransactionRule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Transformers\ArraySerializer;
|
||||
use App\Transformers\EntityTransformer;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use InvoiceNinja\EInvoice\Decoder\Schema;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
|
||||
/**
|
||||
* Class BaseController.
|
||||
@ -261,7 +262,7 @@ class BaseController extends Controller
|
||||
|
||||
/**
|
||||
* 404 for the client portal.
|
||||
* @return Response 404 response
|
||||
* @return Response| \Illuminate\Http\JsonResponse 404 response
|
||||
*/
|
||||
public function notFoundClient()
|
||||
{
|
||||
@ -276,9 +277,9 @@ class BaseController extends Controller
|
||||
/**
|
||||
* API Error response.
|
||||
*
|
||||
* @param string $message The return error message
|
||||
* @param string|array $message The return error message
|
||||
* @param int $httpErrorCode 404/401/403 etc
|
||||
* @return Response The JSON response
|
||||
* @return Response| \Illuminate\Http\JsonResponse The JSON response
|
||||
* @throws BindingResolutionException
|
||||
*/
|
||||
protected function errorResponse($message, $httpErrorCode = 400)
|
||||
@ -296,7 +297,7 @@ class BaseController extends Controller
|
||||
* Refresh API response with latest cahnges
|
||||
*
|
||||
* @param Builder $query
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function refreshResponse($query)
|
||||
{
|
||||
@ -459,7 +460,7 @@ class BaseController extends Controller
|
||||
}
|
||||
},
|
||||
'company.tasks' => function ($query) use ($updated_at, $user) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('project','documents');
|
||||
$query->where('updated_at', '>=', $updated_at)->with('project', 'documents');
|
||||
|
||||
if (! $user->hasPermission('view_task')) {
|
||||
$query->whereNested(function ($query) use ($user) {
|
||||
@ -797,7 +798,7 @@ class BaseController extends Controller
|
||||
}
|
||||
},
|
||||
'company.tasks' => function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('project.documents','documents');
|
||||
$query->where('created_at', '>=', $created_at)->with('project.documents', 'documents');
|
||||
|
||||
if (! $user->hasPermission('view_task')) {
|
||||
$query->whereNested(function ($query) use ($user) {
|
||||
@ -889,7 +890,6 @@ class BaseController extends Controller
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$query = $paginator->getCollection();// @phpstan-ignore-line
|
||||
|
||||
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
}
|
||||
@ -969,7 +969,7 @@ class BaseController extends Controller
|
||||
* Sorts the response by keys
|
||||
*
|
||||
* @param mixed $response
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function response($response)
|
||||
{
|
||||
@ -993,7 +993,18 @@ class BaseController extends Controller
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$response['static'] = Statics::company($user->getCompany()->getLocale());
|
||||
$response_data = Statics::company($user->getCompany()->getLocale());
|
||||
|
||||
if(request()->has('einvoice')) {
|
||||
|
||||
if(class_exists(Schema::class)){
|
||||
$ro = new Schema();
|
||||
$response_data['einvoice_schema'] = $ro('Peppol');
|
||||
}
|
||||
}
|
||||
|
||||
$response['static'] = $response_data;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1010,7 +1021,7 @@ class BaseController extends Controller
|
||||
* Item Response
|
||||
*
|
||||
* @param mixed $item
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function itemResponse($item)
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ class ClientController extends BaseController
|
||||
/**
|
||||
*
|
||||
* @param ClientFilters $filters
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function index(ClientFilters $filters)
|
||||
@ -106,7 +106,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param ShowClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function show(ShowClientRequest $request, Client $client)
|
||||
@ -119,7 +119,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param EditClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function edit(EditClientRequest $request, Client $client)
|
||||
@ -132,7 +132,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param UpdateClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function update(UpdateClientRequest $request, Client $client)
|
||||
@ -157,7 +157,7 @@ class ClientController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateClientRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function create(CreateClientRequest $request)
|
||||
@ -174,7 +174,7 @@ class ClientController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreClientRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function store(StoreClientRequest $request)
|
||||
@ -203,7 +203,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param DestroyClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
@ -217,7 +217,7 @@ class ClientController extends BaseController
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function bulk(BulkClientRequest $request)
|
||||
@ -250,10 +250,22 @@ class ClientController extends BaseController
|
||||
return response()->json(['message' => $hash_or_response], 200);
|
||||
}
|
||||
|
||||
if($action == 'assign_group' && $user->can('edit', $clients->first())){
|
||||
if($action == 'assign_group' && $user->can('edit', $clients->first())) {
|
||||
|
||||
$this->client_repo->assignGroup($clients, $request->group_settings_id);
|
||||
|
||||
|
||||
return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
|
||||
|
||||
}
|
||||
|
||||
if($action == 'bulk_update' && $user->can('edit', $clients->first())) {
|
||||
|
||||
$clients = Client::withTrashed()
|
||||
->company()
|
||||
->whereIn('id', $request->ids);
|
||||
|
||||
$this->client_repo->bulkUpdate($clients, $request->column, $request->new_value);
|
||||
|
||||
return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
|
||||
|
||||
}
|
||||
@ -272,7 +284,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param UploadClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function upload(UploadClientRequest $request, Client $client)
|
||||
@ -293,7 +305,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*/
|
||||
public function purge(PurgeClientRequest $request, Client $client)
|
||||
@ -321,7 +333,7 @@ class ClientController extends BaseController
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @param string $mergeable_client
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*/
|
||||
|
||||
@ -339,9 +351,10 @@ class ClientController extends BaseController
|
||||
return response()->json(['message' => "Client not found"], 400);
|
||||
}
|
||||
|
||||
if($m_client->id == $client->id)
|
||||
if($m_client->id == $client->id) {
|
||||
return response()->json(['message' => "Attempting to merge the same client is not possible."], 400);
|
||||
|
||||
}
|
||||
|
||||
$merged_client = $client->service()->merge($m_client)->save();
|
||||
|
||||
return $this->itemResponse($merged_client);
|
||||
@ -352,7 +365,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*/
|
||||
public function updateTaxData(PurgeClientRequest $request, Client $client)
|
||||
{
|
||||
@ -368,7 +381,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param ReactivateClientEmailRequest $request
|
||||
* @param string $bounce_id //could also be the invitationId
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*/
|
||||
public function reactivateEmail(ReactivateClientEmailRequest $request, string $bounce_id)
|
||||
{
|
||||
@ -401,6 +414,12 @@ class ClientController extends BaseController
|
||||
}
|
||||
|
||||
$bounce_id = $resolved_bounce_id;
|
||||
|
||||
$record = $log->log;
|
||||
$record['ID'] = '';
|
||||
$log->log = $record;
|
||||
$log->save();
|
||||
|
||||
}
|
||||
|
||||
$postmark = new PostmarkClient(config('services.postmark.token'));
|
||||
|
@ -89,7 +89,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* ),
|
||||
* )
|
||||
* @param ListClientGatewayTokenRequest $request
|
||||
* @return Response|mixed
|
||||
* @return Response| \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function index(ListClientGatewayTokenRequest $request)
|
||||
{
|
||||
@ -103,7 +103,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param ShowClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -157,7 +157,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param EditClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -211,7 +211,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param UpdateClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -267,7 +267,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateClientGatewayTokenRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -317,7 +317,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreClientGatewayTokenRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -369,7 +369,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param DestroyClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
* @throws \Exception
|
||||
|
@ -21,7 +21,7 @@ class ContactHashLoginController extends Controller
|
||||
/**
|
||||
* Logs a user into the client portal using their contact_key
|
||||
* @param string $contact_key The contact key
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function login(string $contact_key)
|
||||
{
|
||||
@ -50,7 +50,7 @@ class ContactHashLoginController extends Controller
|
||||
/**
|
||||
* Generic error page for client portal.
|
||||
*
|
||||
* @return void
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function errorPage()
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ class DashboardController extends Controller
|
||||
{
|
||||
if (auth()->guard('contact')->user()->client->getSetting('enable_client_portal_dashboard') === false) {
|
||||
return redirect()->route('client.invoices.index');
|
||||
}
|
||||
}
|
||||
|
||||
$total_invoices = Invoice::withTrashed()
|
||||
->where('client_id', auth()->guard('contact')->user()->client_id)
|
||||
|
@ -207,7 +207,6 @@ class InvoiceController extends Controller
|
||||
|
||||
//format data
|
||||
$invoices->map(function ($invoice) {
|
||||
// $invoice->service()->removeUnpaidGatewayFees();
|
||||
$invoice->balance = $invoice->balance > 0 ? Number::formatValue($invoice->balance, $invoice->client->currency()) : 0;
|
||||
$invoice->partial = $invoice->partial > 0 ? Number::formatValue($invoice->partial, $invoice->client->currency()) : 0;
|
||||
|
||||
|
@ -103,7 +103,7 @@ class PaymentController extends Controller
|
||||
* and invoice ids for reference.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse|mixed
|
||||
* @return \Illuminate\Http\RedirectResponse|mixed
|
||||
*/
|
||||
public function process(Request $request)
|
||||
{
|
||||
@ -157,7 +157,7 @@ class PaymentController extends Controller
|
||||
* Pay for invoice/s using credits only.
|
||||
*
|
||||
* @param Request $request The request object
|
||||
* @return \Response The response view
|
||||
* @return \Illuminate\Http\RedirectResponse The response view
|
||||
*/
|
||||
public function credit_response(Request $request)
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ class PaymentMethodController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param ClientGatewayToken $payment_method
|
||||
* @return RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(ClientGatewayToken $payment_method)
|
||||
{
|
||||
|
@ -48,6 +48,9 @@ class PrePaymentController extends Controller
|
||||
'allows_recurring' => true,
|
||||
'minimum' => $minimum,
|
||||
'minimum_amount' => $minimum_amount,
|
||||
'notes' => request()->has('notes') ? request()->input('notes') : "",
|
||||
'amount' => request()->has('amount') ? request()->input('amount') : "",
|
||||
'show' => request()->has('is_recurring') ? "true" : "false",
|
||||
];
|
||||
|
||||
return $this->render('pre_payments.index', $data);
|
||||
@ -105,7 +108,7 @@ class PrePaymentController extends Controller
|
||||
return $invoice;
|
||||
});
|
||||
|
||||
|
||||
|
||||
$variables = false;
|
||||
|
||||
if(($invitation = $invoices->first()->invitations()->first() ?? false) && $invoice->client->getSetting('show_accept_invoice_terms')) {
|
||||
|
@ -38,7 +38,7 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @param UpdateContactRequest $request
|
||||
* @param ClientContact $client_contact
|
||||
* @return RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateContactRequest $request, ClientContact $client_contact)
|
||||
{
|
||||
|
@ -178,6 +178,9 @@ class QuoteController extends Controller
|
||||
->where('client_id', auth()->guard('contact')->user()->client->id)
|
||||
->where('company_id', auth()->guard('contact')->user()->client->company_id)
|
||||
->whereIn('status_id', [Quote::STATUS_DRAFT, Quote::STATUS_SENT])
|
||||
->where(function ($q) {
|
||||
$q->whereNull('due_date')->orWhere('due_date', '>=', now());
|
||||
})
|
||||
->withTrashed()
|
||||
->get();
|
||||
|
||||
|
@ -66,7 +66,7 @@ class RecurringInvoiceController extends Controller
|
||||
* @param RequestCancellationRequest $request [description]
|
||||
* @param RecurringInvoice $recurring_invoice [description]
|
||||
*
|
||||
* @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function requestCancellation(RequestCancellationRequest $request, RecurringInvoice $recurring_invoice)
|
||||
{
|
||||
|
@ -13,14 +13,13 @@ namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class TempRouteController extends Controller
|
||||
{
|
||||
/**
|
||||
* Logs a user into the client portal using their contact_key
|
||||
* @param string $hash The hash
|
||||
* @return Redirect
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(string $hash)
|
||||
{
|
||||
|
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