mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
latest merge
This commit is contained in:
commit
3efff86066
@ -4,6 +4,7 @@ APP_KEY=base64:RR++yx2rJ9kdxbdh3+AmbHLDQu+Q76i++co9Y8ybbno=
|
||||
APP_DEBUG=false
|
||||
|
||||
APP_URL=http://localhost
|
||||
REACT_URL=http://localhost:3001
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
MULTI_DB_ENABLED=false
|
||||
@ -33,8 +34,8 @@ MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS='user@example.com'
|
||||
MAIL_FROM_NAME='Self Hosted User'
|
||||
MAIL_FROM_ADDRESS="user@example.com"
|
||||
MAIL_FROM_NAME="Self Hosted User"
|
||||
|
||||
POSTMARK_API_TOKEN=
|
||||
REQUIRE_HTTPS=false
|
||||
@ -67,4 +68,4 @@ MICROSOFT_REDIRECT_URI=
|
||||
|
||||
APPLE_CLIENT_ID=
|
||||
APPLE_CLIENT_SECRET=
|
||||
APPLE_REDIRECT_URI=
|
||||
APPLE_REDIRECT_URI=
|
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -46,7 +46,9 @@ jobs:
|
||||
git checkout main
|
||||
npm i
|
||||
npm run build
|
||||
cp -r dist/react/* ../public/react
|
||||
cp -r dist/react/* ../public/react
|
||||
mkdir -p ../public/tinymce_6.4.2/tinymce/js/
|
||||
cp -r node_modules/tinymce ../public/tinymce_6.4.2/tinymce/js/
|
||||
cd ..
|
||||
rm -rf ui
|
||||
php artisan ninja:react
|
||||
|
@ -1 +1 @@
|
||||
5.6.5
|
||||
5.6.25
|
@ -17,7 +17,7 @@ class EncryptedCast implements CastsAttributes
|
||||
{
|
||||
public function get($model, string $key, $value, array $attributes)
|
||||
{
|
||||
return strlen($value) > 1 ? decrypt($value) : null;
|
||||
return is_string($value) && strlen($value) > 1 ? decrypt($value) : null;
|
||||
}
|
||||
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
|
@ -154,7 +154,7 @@ class CheckData extends Command
|
||||
->subject('Check-Data: '.strtoupper($this->isValid ? Account::RESULT_SUCCESS : Account::RESULT_FAILURE)." [{$database}]");
|
||||
});
|
||||
} elseif (! $this->isValid) {
|
||||
new Exception("Check data failed!!\n".$this->log);
|
||||
new \Exception("Check data failed!!".$this->log);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -711,6 +711,29 @@ class CreateSingleAccount extends Command
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
if (config('ninja.testvars.paypal_rest') && ($this->gateway == 'all' || $this->gateway == 'paypal_rest')) {
|
||||
$cg = new CompanyGateway;
|
||||
$cg->company_id = $company->id;
|
||||
$cg->user_id = $user->id;
|
||||
$cg->gateway_key = '80af24a6a691230bbec33e930ab40665';
|
||||
$cg->require_cvv = true;
|
||||
$cg->require_billing_address = true;
|
||||
$cg->require_shipping_address = true;
|
||||
$cg->update_details = true;
|
||||
$cg->config = encrypt(config('ninja.testvars.paypal_rest'));
|
||||
$cg->save();
|
||||
|
||||
// $gateway_types = $cg->driver()->gatewayTypes();
|
||||
|
||||
$fees_and_limits = new stdClass;
|
||||
$fees_and_limits->{3} = new FeesAndLimits;
|
||||
|
||||
$cg->fees_and_limits = $fees_and_limits;
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (config('ninja.testvars.checkout') && ($this->gateway == 'all' || $this->gateway == 'checkout')) {
|
||||
$cg = new CompanyGateway;
|
||||
$cg->company_id = $company->id;
|
||||
|
@ -64,8 +64,6 @@ class ImportMigrations extends Command
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->faker = Factory::create();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
@ -76,6 +74,8 @@ class ImportMigrations extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->faker = Factory::create();
|
||||
|
||||
$this->buildCache();
|
||||
|
||||
$path = $this->option('path') ?? public_path('storage/migrations/import');
|
||||
@ -105,7 +105,7 @@ class ImportMigrations extends Command
|
||||
$import_file = public_path("storage/migrations/$filename/migration.json");
|
||||
|
||||
Import::dispatch($import_file, $this->getUser()->companies()->first(), $this->getUser());
|
||||
// StartMigration::dispatch($file->getRealPath(), $this->getUser(), $this->getUser()->companies()->first());
|
||||
|
||||
} catch (NonExistingMigrationFile | ProcessingMigrationArchiveFailed | ResourceNotAvailableForMigration | MigrationValidatorFailed | ResourceDependencyMissing $e) {
|
||||
\Mail::to($user)->send(new MigrationFailed($e, $company));
|
||||
|
||||
|
@ -93,17 +93,6 @@ class MobileLocalization extends Command
|
||||
$text = str_replace(['<i>', '</i>'], '', $text);
|
||||
$text = str_replace(['<strong>', '</strong>'], '', $text);
|
||||
|
||||
//replace the three lines above with this
|
||||
// if($language->locale == 'ar') {
|
||||
// $text = str_replace('\n', " ", $text);
|
||||
// }
|
||||
|
||||
// $text = str_replace(['<strong>', '</strong>','<i>', '</i>','<b>', '</b>'], '', $text);
|
||||
// $text = str_replace('"', "'", $text);
|
||||
|
||||
|
||||
|
||||
|
||||
echo "'$key': '$text',\n";
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,7 @@ class OpenApiYaml extends Command
|
||||
Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components.yaml'));
|
||||
|
||||
Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/responses.yaml'));
|
||||
Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/examples.yaml'));
|
||||
|
||||
$directory = new DirectoryIterator($path . '/components/responses/');
|
||||
|
||||
|
@ -51,6 +51,7 @@ class TranslationsExport extends Command
|
||||
'fi',
|
||||
'fr',
|
||||
'fr_CA',
|
||||
'fr_CH',
|
||||
'he',
|
||||
'hr',
|
||||
'hu',
|
||||
@ -133,11 +134,9 @@ class TranslationsExport extends Command
|
||||
Storage::disk('local')->makeDirectory('lang');
|
||||
|
||||
foreach ($this->langs as $lang) {
|
||||
nlog($lang);
|
||||
Storage::disk('local')->makeDirectory("lang/{$lang}");
|
||||
|
||||
$translations = Lang::getLoader()->load($lang, 'texts');
|
||||
nlog($translations);
|
||||
Storage::disk('local')->put("lang/{$lang}/{$lang}.json", json_encode(Arr::dot($translations), JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ class AccountCreated extends GenericCounter
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class AccountDeleted extends GenericCounter
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class AccountPlatform extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class AccountSignup extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
@ -61,7 +60,7 @@ class AccountSignup extends GenericMixedMetric
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
* @var int
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class BankAccountsCreated extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class DbQuery extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
@ -57,7 +56,7 @@ class DbQuery extends GenericMixedMetric
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
* @var int
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class EmailCount extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class EmailFailure extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
@ -61,7 +60,6 @@ class EmailFailure extends GenericMixedMetric
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class EmailInvoiceFailure extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class EmailSuccess extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
@ -61,7 +60,6 @@ class EmailSuccess extends GenericMixedMetric
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class LivePreview extends GenericCounter
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class LoginFailure extends GenericCounter
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class LoginSuccess extends GenericCounter
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
|
@ -37,7 +37,6 @@ class EmailBounce extends GenericMixedMetric
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
@ -67,7 +66,6 @@ class EmailBounce extends GenericMixedMetric
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
|
@ -16,13 +16,13 @@ namespace App\DataMapper;
|
||||
*/
|
||||
class BaseSettings
|
||||
{
|
||||
//@deprecated
|
||||
public function __construct($obj)
|
||||
{
|
||||
// foreach ($obj as $key => $value) {
|
||||
// $obj->{$key} = $value;
|
||||
// }
|
||||
}
|
||||
// //@deprecated
|
||||
// public function __construct($obj)
|
||||
// {
|
||||
// // foreach ($obj as $key => $value) {
|
||||
// // $obj->{$key} = $value;
|
||||
// // }
|
||||
// }
|
||||
|
||||
public static function setCasts($obj, $casts)
|
||||
{
|
||||
|
@ -47,17 +47,17 @@ class ClientSettings extends BaseSettings
|
||||
'send_reminders' => 'bool',
|
||||
];
|
||||
|
||||
/**
|
||||
* Cast object values and return entire class
|
||||
* prevents missing properties from not being returned
|
||||
* and always ensure an up to date class is returned.
|
||||
*
|
||||
* @param $obj
|
||||
*/
|
||||
public function __construct($obj)
|
||||
{
|
||||
parent::__construct($obj);
|
||||
}
|
||||
// /**
|
||||
// * Cast object values and return entire class
|
||||
// * prevents missing properties from not being returned
|
||||
// * and always ensure an up to date class is returned.
|
||||
// *
|
||||
// * @param $obj
|
||||
// */
|
||||
// public function __construct($obj)
|
||||
// {
|
||||
// // parent::__construct($obj);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Default Client Settings scaffold.
|
||||
@ -78,8 +78,8 @@ class ClientSettings extends BaseSettings
|
||||
/**
|
||||
* Merges settings from Company to Client.
|
||||
*
|
||||
* @param stdClass $company_settings
|
||||
* @param stdClass $client_settings
|
||||
* @param $company_settings
|
||||
* @param $client_settings
|
||||
* @return stdClass of merged settings
|
||||
*/
|
||||
public static function buildClientSettings($company_settings, $client_settings)
|
||||
|
@ -767,18 +767,18 @@ class CompanySettings extends BaseSettings
|
||||
'purchase_order_design_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Cast object values and return entire class
|
||||
* prevents missing properties from not being returned
|
||||
* and always ensure an up to date class is returned.
|
||||
*
|
||||
* @param $obj
|
||||
* @deprecated
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// parent::__construct($obj);
|
||||
}
|
||||
// /**
|
||||
// * Cast object values and return entire class
|
||||
// * prevents missing properties from not being returned
|
||||
// * and always ensure an up to date class is returned.
|
||||
// *
|
||||
// * @param $obj
|
||||
// * @deprecated
|
||||
// */
|
||||
// public function __construct()
|
||||
// {
|
||||
// // parent::__construct($obj);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Provides class defaults on init.
|
||||
|
@ -34,13 +34,4 @@ class DefaultSettings extends BaseSettings
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return stdClass
|
||||
*/
|
||||
private static function userSettingsObject() : stdClass
|
||||
{
|
||||
return (object) [
|
||||
// 'per_page' => self::$per_page,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
@ -24,92 +24,78 @@ class EmailTemplateDefaults
|
||||
|
||||
case 'email_template_invoice':
|
||||
return self::emailInvoiceTemplate();
|
||||
break;
|
||||
case 'email_template_quote':
|
||||
return self::emailQuoteTemplate();
|
||||
break;
|
||||
case 'email_template_credit':
|
||||
return self::emailCreditTemplate();
|
||||
break;
|
||||
case 'email_template_payment':
|
||||
return self::emailPaymentTemplate();
|
||||
break;
|
||||
case 'email_template_payment_partial':
|
||||
return self::emailPaymentPartialTemplate();
|
||||
break;
|
||||
case 'email_template_statement':
|
||||
return self::emailStatementTemplate();
|
||||
break;
|
||||
case 'email_template_reminder1':
|
||||
return self::emailReminder1Template();
|
||||
break;
|
||||
case 'email_template_reminder2':
|
||||
return self::emailReminder2Template();
|
||||
break;
|
||||
case 'email_template_reminder3':
|
||||
return self::emailReminder3Template();
|
||||
break;
|
||||
case 'email_template_reminder_endless':
|
||||
return self::emailReminderEndlessTemplate();
|
||||
break;
|
||||
case 'email_template_custom1':
|
||||
return self::emailInvoiceTemplate();
|
||||
break;
|
||||
case 'email_template_custom2':
|
||||
return self::emailInvoiceTemplate();
|
||||
break;
|
||||
case 'email_template_custom3':
|
||||
return self::emailInvoiceTemplate();
|
||||
case 'email_template_purchase_order':
|
||||
return self::emailPurchaseOrderTemplate();
|
||||
break;
|
||||
|
||||
/* Subject */
|
||||
case 'email_subject_purchase_order':
|
||||
return self::emailPurchaseOrderSubject();
|
||||
case 'email_subject_invoice':
|
||||
return self::emailInvoiceSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_quote':
|
||||
return self::emailQuoteSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_credit':
|
||||
return self::emailCreditSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_payment':
|
||||
return self::emailPaymentSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_payment_partial':
|
||||
return self::emailPaymentPartialSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_statement':
|
||||
return self::emailStatementSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_reminder1':
|
||||
return self::emailReminder1Subject();
|
||||
break;
|
||||
|
||||
case 'email_subject_reminder2':
|
||||
return self::emailReminder2Subject();
|
||||
break;
|
||||
|
||||
case 'email_subject_reminder3':
|
||||
return self::emailReminder3Subject();
|
||||
break;
|
||||
|
||||
case 'email_subject_reminder_endless':
|
||||
return self::emailReminderEndlessSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_custom1':
|
||||
return self::emailInvoiceSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_custom2':
|
||||
return self::emailInvoiceSubject();
|
||||
break;
|
||||
|
||||
case 'email_subject_custom3':
|
||||
return self::emailInvoiceSubject();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return self::emailInvoiceTemplate();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,6 @@ class FreeCompanySettings extends BaseSettings
|
||||
|
||||
public static $casts = [
|
||||
'portal_design_id' => 'string',
|
||||
'currency_id' => 'string',
|
||||
'task_number_pattern' => 'string',
|
||||
'task_number_counter' => 'int',
|
||||
'expense_number_pattern' => 'string',
|
||||
@ -191,16 +190,16 @@ class FreeCompanySettings extends BaseSettings
|
||||
'website' => 'string',
|
||||
];
|
||||
|
||||
/**
|
||||
* Cast object values and return entire class
|
||||
* prevents missing properties from not being returned
|
||||
* and always ensure an up to date class is returned.
|
||||
*
|
||||
* @param $obj
|
||||
*/
|
||||
public function __construct($obj)
|
||||
{
|
||||
}
|
||||
// /**
|
||||
// * Cast object values and return entire class
|
||||
// * prevents missing properties from not being returned
|
||||
// * and always ensure an up to date class is returned.
|
||||
// *
|
||||
// * @param $obj
|
||||
// */
|
||||
// public function __construct($obj)
|
||||
// {
|
||||
// }
|
||||
|
||||
/**
|
||||
* Provides class defaults on init.
|
||||
@ -223,7 +222,7 @@ class FreeCompanySettings extends BaseSettings
|
||||
$data->date_format_id = (string) config('ninja.i18n.date_format_id');
|
||||
$data->country_id = (string) config('ninja.i18n.country_id');
|
||||
$data->translations = (object) [];
|
||||
$data->pdf_variables = (object) self::getEntityVariableDefaults();
|
||||
// $data->pdf_variables = (object) self::getEntityVariableDefaults();
|
||||
|
||||
return self::setCasts($data, self::$casts);
|
||||
}
|
||||
|
@ -223,9 +223,12 @@ class Rule extends BaseRule implements RuleInterface
|
||||
public function calculateRates(): self
|
||||
{
|
||||
if ($this->client->is_tax_exempt) {
|
||||
// nlog("tax exempt");
|
||||
|
||||
$this->tax_rate = 0;
|
||||
$this->reduced_tax_rate = 0;
|
||||
|
||||
return $this;
|
||||
}
|
||||
// } elseif($this->client_subregion != $this->client->company->tax_data->seller_subregion && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt) {
|
||||
// nlog("euro zone and tax exempt");
|
||||
// $this->tax_rate = 0;
|
||||
@ -246,10 +249,9 @@ class Rule extends BaseRule implements RuleInterface
|
||||
// $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;
|
||||
// }
|
||||
} else {
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
|
||||
}
|
||||
|
||||
$this->tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
$this->reduced_tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
|
||||
|
||||
return $this;
|
||||
|
||||
|
@ -197,7 +197,7 @@ class BaseRule implements RuleInterface
|
||||
}
|
||||
|
||||
/** If we are in a Origin based state, force the company tax here */
|
||||
if($company->origin_tax_data?->originDestination == 'O' && ($company->tax_data?->seller_subregion == $this->client_subregion)) {
|
||||
if($company->origin_tax_data->originDestination == 'O' && ($company->tax_data?->seller_subregion == $this->client_subregion)) {
|
||||
|
||||
$tax_data = $company->origin_tax_data;
|
||||
|
||||
@ -235,7 +235,7 @@ class BaseRule implements RuleInterface
|
||||
$this->client_region = $this->region_codes[$this->client->country->iso_3166_2];
|
||||
|
||||
match($this->client_region){
|
||||
'US' => $this->client_subregion = strlen($this->invoice?->client?->tax_data?->geoState) > 1 ? $this->invoice->client->tax_data->geoState : $this->getUSState(),
|
||||
'US' => $this->client_subregion = isset($this->invoice?->client?->tax_data?->geoState) ? $this->invoice->client->tax_data->geoState : $this->getUSState(),
|
||||
'EU' => $this->client_subregion = $this->client->country->iso_3166_2,
|
||||
'AU' => $this->client_subregion = 'AU',
|
||||
default => $this->client_subregion = $this->client->country->iso_3166_2,
|
||||
|
@ -33859,8 +33859,6 @@ class USStates
|
||||
'99926' => 'AK',
|
||||
'99927' => 'AK',
|
||||
'99929' => 'AK',
|
||||
'13021' => 'NY',
|
||||
'13024' => 'NY',
|
||||
];
|
||||
|
||||
public static function get(): array
|
||||
|
@ -30,7 +30,7 @@ class DesignWasCreated
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return PrivateChannel
|
||||
* @return PrivateChannel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ class DesignWasDeleted
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return PrivateChannel
|
||||
* @return PrivateChannel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ class DesignWasRestored
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return PrivateChannel
|
||||
* @return PrivateChannel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ class DesignWasUpdated
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return PrivateChannel
|
||||
* @return PrivateChannel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
|
@ -17,8 +17,10 @@ use App\Utils\Ninja;
|
||||
use Sentry\State\Scope;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Http\Request;
|
||||
use InvalidArgumentException;
|
||||
use Sentry\Laravel\Integration;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Aws\Exception\CredentialsException;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use League\Flysystem\UnableToCreateDirectory;
|
||||
@ -34,7 +36,6 @@ use Symfony\Component\Console\Exception\CommandNotFoundException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
@ -64,7 +65,7 @@ class Handler extends ExceptionHandler
|
||||
ConnectException::class,
|
||||
RuntimeException::class,
|
||||
InvalidArgumentException::class,
|
||||
Aws\Exception\CredentialsException::class,
|
||||
CredentialsException::class,
|
||||
];
|
||||
|
||||
protected $hostedDontReport = [
|
||||
|
@ -14,7 +14,7 @@ namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class PaymentRefundFailed extends Exception
|
||||
{
|
||||
@ -32,14 +32,14 @@ class PaymentRefundFailed extends Exception
|
||||
* Render the exception into an HTTP response.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function render($request)
|
||||
{
|
||||
// $msg = 'Unable to refund the transaction';
|
||||
$msg = ctrans('texts.warning_local_refund');
|
||||
|
||||
if ($this->getMessage() && strlen($this->getMessage()) >= 1) {
|
||||
if ($this->getMessage() && strlen($this->getMessage()) > 1) {
|
||||
$msg = $this->getMessage();
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class QuoteConversion extends Exception
|
||||
{
|
||||
@ -32,7 +32,7 @@ class QuoteConversion extends Exception
|
||||
* Render the exception into an HTTP response.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function render($request)
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class YodleeApiException extends Exception
|
||||
{
|
||||
@ -32,14 +32,14 @@ class YodleeApiException extends Exception
|
||||
* Render the exception into an HTTP response.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function render($request)
|
||||
{
|
||||
// $msg = 'Unable to refund the transaction';
|
||||
$msg = ctrans('texts.error');
|
||||
|
||||
if ($this->getMessage() && strlen($this->getMessage()) >= 1) {
|
||||
if ($this->getMessage() && strlen($this->getMessage()) > 1) {
|
||||
$msg = $this->getMessage();
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,7 @@ use App\Transformers\ActivityTransformer;
|
||||
|
||||
class ActivityExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
|
||||
private $entity_transformer;
|
||||
|
||||
public string $date_key = 'created_at';
|
||||
|
@ -11,16 +11,26 @@
|
||||
|
||||
namespace App\Export\CSV;
|
||||
|
||||
use App\Utils\Number;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use League\Fractal\Manager;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Transformers\PaymentTransformer;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
|
||||
class BaseExport
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
public Company $company;
|
||||
|
||||
public array $input;
|
||||
|
||||
public string $date_key = '';
|
||||
@ -35,6 +45,312 @@ class BaseExport
|
||||
|
||||
public array $forced_keys = [];
|
||||
|
||||
protected array $vendor_report_keys = [
|
||||
'address1' => 'vendor.address1',
|
||||
'address2' => 'vendor.address2',
|
||||
'city' => 'vendor.city',
|
||||
'country' => 'vendor.country_id',
|
||||
'custom_value1' => 'vendor.custom_value1',
|
||||
'custom_value2' => 'vendor.custom_value2',
|
||||
'custom_value3' => 'vendor.custom_value3',
|
||||
'custom_value4' => 'vendor.custom_value4',
|
||||
'id_number' => 'vendor.id_number',
|
||||
'name' => 'vendor.name',
|
||||
'number' => 'vendor.number',
|
||||
'client_phone' => 'vendor.phone',
|
||||
'postal_code' => 'vendor.postal_code',
|
||||
'private_notes' => 'vendor.private_notes',
|
||||
'public_notes' => 'vendor.public_notes',
|
||||
'state' => 'vendor.state',
|
||||
'vat_number' => 'vendor.vat_number',
|
||||
'website' => 'vendor.website',
|
||||
'currency' => 'vendor.currency',
|
||||
'first_name' => 'vendor_contact.first_name',
|
||||
'last_name' => 'vendor_contact.last_name',
|
||||
'contact_phone' => 'vendor_contact.phone',
|
||||
'contact_custom_value1' => 'vendor_contact.custom_value1',
|
||||
'contact_custom_value2' => 'vendor_contact.custom_value2',
|
||||
'contact_custom_value3' => 'vendor_contact.custom_value3',
|
||||
'contact_custom_value4' => 'vendor_contact.custom_value4',
|
||||
'email' => 'vendor_contact.email',
|
||||
'status' => 'vendor.status',
|
||||
];
|
||||
|
||||
protected array $client_report_keys = [
|
||||
"name" => "client.name",
|
||||
"user" => "client.user",
|
||||
"assigned_user" => "client.assigned_user",
|
||||
"balance" => "client.balance",
|
||||
"paid_to_date" => "client.paid_to_date",
|
||||
"currency" => "client.currency_id",
|
||||
"website" => "client.website",
|
||||
"private_notes" => "client.private_notes",
|
||||
"industry" => "client.industry_id",
|
||||
"size" => "client.size_id",
|
||||
"work_phone" => "client.phone",
|
||||
"address1" => "client.address1",
|
||||
"address2" => "client.address2",
|
||||
"city" => "client.city",
|
||||
"state" => "client.state",
|
||||
"postal_code" => "client.postal_code",
|
||||
"country" => "client.country_id",
|
||||
"custom_value4" => "contact.custom_value4",
|
||||
"shipping_address1" => "client.shipping_address1",
|
||||
"shipping_address2" => "client.shipping_address2",
|
||||
"shipping_city" => "client.shipping_city",
|
||||
"shipping_state" => "client.shipping_state",
|
||||
"shipping_postal_code" => "client.shipping_postal_code",
|
||||
"shipping_country" => "client.shipping_country_id",
|
||||
"payment_terms" => "client.payment_terms",
|
||||
"vat_number" => "client.vat_number",
|
||||
"id_number" => "client.id_number",
|
||||
"public_notes" => "client.public_notes",
|
||||
"phone" => "contact.phone",
|
||||
"first_name" => "contact.first_name",
|
||||
"last_name" => "contact.last_name",
|
||||
"email" => "contact.email",
|
||||
];
|
||||
|
||||
protected array $invoice_report_keys = [
|
||||
"invoice_number" => "invoice.number",
|
||||
"amount" => "invoice.amount",
|
||||
"balance" => "invoice.balance",
|
||||
"paid_to_date" => "invoice.paid_to_date",
|
||||
"po_number" => "invoice.po_number",
|
||||
"date" => "invoice.date",
|
||||
"due_date" => "invoice.due_date",
|
||||
"terms" => "invoice.terms",
|
||||
"footer" => "invoice.footer",
|
||||
"status" => "invoice.status",
|
||||
"public_notes" => "invoice.public_notes",
|
||||
"private_notes" => "invoice.private_notes",
|
||||
"uses_inclusive_taxes" => "invoice.uses_inclusive_taxes",
|
||||
"is_amount_discount" => "invoice.is_amount_discount",
|
||||
"partial" => "invoice.partial",
|
||||
"partial_due_date" => "invoice.partial_due_date",
|
||||
"surcharge1" => "invoice.custom_surcharge1",
|
||||
"surcharge2" => "invoice.custom_surcharge2",
|
||||
"surcharge3" => "invoice.custom_surcharge3",
|
||||
"surcharge4" => "invoice.custom_surcharge4",
|
||||
"exchange_rate" => "invoice.exchange_rate",
|
||||
"tax_amount" => "invoice.total_taxes",
|
||||
"assigned_user" => "invoice.assigned_user_id",
|
||||
"user" => "invoice.user_id",
|
||||
];
|
||||
|
||||
protected array $recurring_invoice_report_keys = [
|
||||
"invoice_number" => "recurring_invoice.number",
|
||||
"amount" => "recurring_invoice.amount",
|
||||
"balance" => "recurring_invoice.balance",
|
||||
"paid_to_date" => "recurring_invoice.paid_to_date",
|
||||
"po_number" => "recurring_invoice.po_number",
|
||||
"date" => "recurring_invoice.date",
|
||||
"due_date" => "recurring_invoice.due_date",
|
||||
"terms" => "recurring_invoice.terms",
|
||||
"footer" => "recurring_invoice.footer",
|
||||
"status" => "recurring_invoice.status",
|
||||
"public_notes" => "recurring_invoice.public_notes",
|
||||
"private_notes" => "recurring_invoice.private_notes",
|
||||
"uses_inclusive_taxes" => "recurring_invoice.uses_inclusive_taxes",
|
||||
"is_amount_discount" => "recurring_invoice.is_amount_discount",
|
||||
"partial" => "recurring_invoice.partial",
|
||||
"partial_due_date" => "recurring_invoice.partial_due_date",
|
||||
"surcharge1" => "recurring_invoice.custom_surcharge1",
|
||||
"surcharge2" => "recurring_invoice.custom_surcharge2",
|
||||
"surcharge3" => "recurring_invoice.custom_surcharge3",
|
||||
"surcharge4" => "recurring_invoice.custom_surcharge4",
|
||||
"exchange_rate" => "recurring_invoice.exchange_rate",
|
||||
"tax_amount" => "recurring_invoice.total_taxes",
|
||||
"assigned_user" => "recurring_invoice.assigned_user_id",
|
||||
"user" => "recurring_invoice.user_id",
|
||||
"frequency_id" => "recurring_invoice.frequency_id",
|
||||
"next_send_date" => "recurring_invoice.next_send_date"
|
||||
];
|
||||
|
||||
protected array $purchase_order_report_keys = [
|
||||
'amount' => 'purchase_order.amount',
|
||||
'balance' => 'purchase_order.balance',
|
||||
'vendor' => 'purchase_order.vendor_id',
|
||||
// 'custom_surcharge1' => 'purchase_order.custom_surcharge1',
|
||||
// 'custom_surcharge2' => 'purchase_order.custom_surcharge2',
|
||||
// 'custom_surcharge3' => 'purchase_order.custom_surcharge3',
|
||||
// 'custom_surcharge4' => 'purchase_order.custom_surcharge4',
|
||||
'custom_value1' => 'purchase_order.custom_value1',
|
||||
'custom_value2' => 'purchase_order.custom_value2',
|
||||
'custom_value3' => 'purchase_order.custom_value3',
|
||||
'custom_value4' => 'purchase_order.custom_value4',
|
||||
'date' => 'purchase_order.date',
|
||||
'discount' => 'purchase_order.discount',
|
||||
'due_date' => 'purchase_order.due_date',
|
||||
'exchange_rate' => 'purchase_order.exchange_rate',
|
||||
'footer' => 'purchase_order.footer',
|
||||
'number' => 'purchase_order.number',
|
||||
'paid_to_date' => 'purchase_order.paid_to_date',
|
||||
'partial' => 'purchase_order.partial',
|
||||
'partial_due_date' => 'purchase_order.partial_due_date',
|
||||
'po_number' => 'purchase_order.po_number',
|
||||
'private_notes' => 'purchase_order.private_notes',
|
||||
'public_notes' => 'purchase_order.public_notes',
|
||||
'status' => 'purchase_order.status_id',
|
||||
'tax_name1' => 'purchase_order.tax_name1',
|
||||
'tax_name2' => 'purchase_order.tax_name2',
|
||||
'tax_name3' => 'purchase_order.tax_name3',
|
||||
'tax_rate1' => 'purchase_order.tax_rate1',
|
||||
'tax_rate2' => 'purchase_order.tax_rate2',
|
||||
'tax_rate3' => 'purchase_order.tax_rate3',
|
||||
'terms' => 'purchase_order.terms',
|
||||
'total_taxes' => 'purchase_order.total_taxes',
|
||||
'currency_id' => 'purchase_order.currency_id',
|
||||
];
|
||||
|
||||
protected array $item_report_keys = [
|
||||
"quantity" => "item.quantity",
|
||||
"cost" => "item.cost",
|
||||
"product_key" => "item.product_key",
|
||||
"notes" => "item.notes",
|
||||
"item_tax1" => "item.tax_name1",
|
||||
"item_tax_rate1" => "item.tax_rate1",
|
||||
"item_tax2" => "item.tax_name2",
|
||||
"item_tax_rate2" => "item.tax_rate2",
|
||||
"item_tax3" => "item.tax_name3",
|
||||
"item_tax_rate3" => "item.tax_rate3",
|
||||
"custom_value1" => "item.custom_value1",
|
||||
"custom_value2" => "item.custom_value2",
|
||||
"custom_value3" => "item.custom_value3",
|
||||
"custom_value4" => "item.custom_value4",
|
||||
"discount" => "item.discount",
|
||||
"type" => "item.type_id",
|
||||
"tax_category" => "item.tax_id",
|
||||
];
|
||||
|
||||
protected array $quote_report_keys = [
|
||||
'custom_value1' => 'quote.custom_value1',
|
||||
'custom_value2' => 'quote.custom_value2',
|
||||
'custom_value3' => 'quote.custom_value3',
|
||||
'custom_value4' => 'quote.custom_value4',
|
||||
"number" => "quote.number",
|
||||
"amount" => "quote.amount",
|
||||
"balance" => "quote.balance",
|
||||
"paid_to_date" => "quote.paid_to_date",
|
||||
"po_number" => "quote.po_number",
|
||||
"date" => "quote.date",
|
||||
"valid_until" => "quote.due_date",
|
||||
"terms" => "quote.terms",
|
||||
"footer" => "quote.footer",
|
||||
"status" => "quote.status",
|
||||
"public_notes" => "quote.public_notes",
|
||||
"private_notes" => "quote.private_notes",
|
||||
"uses_inclusive_taxes" => "quote.uses_inclusive_taxes",
|
||||
"is_amount_discount" => "quote.is_amount_discount",
|
||||
"partial" => "quote.partial",
|
||||
"partial_due_date" => "quote.partial_due_date",
|
||||
"surcharge1" => "quote.custom_surcharge1",
|
||||
"surcharge2" => "quote.custom_surcharge2",
|
||||
"surcharge3" => "quote.custom_surcharge3",
|
||||
"surcharge4" => "quote.custom_surcharge4",
|
||||
"exchange_rate" => "quote.exchange_rate",
|
||||
"tax_amount" => "quote.total_taxes",
|
||||
"assigned_user" => "quote.assigned_user_id",
|
||||
"user" => "quote.user_id",
|
||||
];
|
||||
|
||||
protected array $credit_report_keys = [
|
||||
"credit_number" => "credit.number",
|
||||
"amount" => "credit.amount",
|
||||
"balance" => "credit.balance",
|
||||
"paid_to_date" => "credit.paid_to_date",
|
||||
"po_number" => "credit.po_number",
|
||||
"date" => "credit.date",
|
||||
"due_date" => "credit.due_date",
|
||||
"terms" => "credit.terms",
|
||||
"footer" => "credit.footer",
|
||||
"status" => "credit.status",
|
||||
"public_notes" => "credit.public_notes",
|
||||
"private_notes" => "credit.private_notes",
|
||||
"uses_inclusive_taxes" => "credit.uses_inclusive_taxes",
|
||||
"is_amount_discount" => "credit.is_amount_discount",
|
||||
"partial" => "credit.partial",
|
||||
"partial_due_date" => "credit.partial_due_date",
|
||||
"surcharge1" => "credit.custom_surcharge1",
|
||||
"surcharge2" => "credit.custom_surcharge2",
|
||||
"surcharge3" => "credit.custom_surcharge3",
|
||||
"surcharge4" => "credit.custom_surcharge4",
|
||||
"exchange_rate" => "credit.exchange_rate",
|
||||
"tax_amount" => "credit.total_taxes",
|
||||
"assigned_user" => "credit.assigned_user_id",
|
||||
"user" => "credit.user_id",
|
||||
];
|
||||
|
||||
protected array $payment_report_keys = [
|
||||
"date" => "payment.date",
|
||||
"amount" => "payment.amount",
|
||||
"refunded" => "payment.refunded",
|
||||
"applied" => "payment.applied",
|
||||
"transaction_reference" => "payment.transaction_reference",
|
||||
"currency" => "payment.currency",
|
||||
"exchange_rate" => "payment.exchange_rate",
|
||||
"number" => "payment.number",
|
||||
"method" => "payment.method",
|
||||
"status" => "payment.status",
|
||||
"private_notes" => "payment.private_notes",
|
||||
"custom_value1" => "payment.custom_value1",
|
||||
"custom_value2" => "payment.custom_value2",
|
||||
"custom_value3" => "payment.custom_value3",
|
||||
"custom_value4" => "payment.custom_value4",
|
||||
"user" => "payment.user_id",
|
||||
"assigned_user" => "payment.assigned_user_id",
|
||||
];
|
||||
|
||||
protected array $expense_report_keys = [
|
||||
'amount' => 'expense.amount',
|
||||
'category' => 'expense.category_id',
|
||||
'client' => 'expense.client_id',
|
||||
'custom_value1' => 'expense.custom_value1',
|
||||
'custom_value2' => 'expense.custom_value2',
|
||||
'custom_value3' => 'expense.custom_value3',
|
||||
'custom_value4' => 'expense.custom_value4',
|
||||
'currency' => 'expense.currency_id',
|
||||
'date' => 'expense.date',
|
||||
'exchange_rate' => 'expense.exchange_rate',
|
||||
'converted_amount' => 'expense.foreign_amount',
|
||||
'invoice_currency_id' => 'expense.invoice_currency_id',
|
||||
'payment_date' => 'expense.payment_date',
|
||||
'number' => 'expense.number',
|
||||
'payment_type_id' => 'expense.payment_type_id',
|
||||
'private_notes' => 'expense.private_notes',
|
||||
'project' => 'expense.project_id',
|
||||
'public_notes' => 'expense.public_notes',
|
||||
'tax_amount1' => 'expense.tax_amount1',
|
||||
'tax_amount2' => 'expense.tax_amount2',
|
||||
'tax_amount3' => 'expense.tax_amount3',
|
||||
'tax_name1' => 'expense.tax_name1',
|
||||
'tax_name2' => 'expense.tax_name2',
|
||||
'tax_name3' => 'expense.tax_name3',
|
||||
'tax_rate1' => 'expense.tax_rate1',
|
||||
'tax_rate2' => 'expense.tax_rate2',
|
||||
'tax_rate3' => 'expense.tax_rate3',
|
||||
'transaction_reference' => 'expense.transaction_reference',
|
||||
'vendor' => 'expense.vendor_id',
|
||||
'invoice' => 'expense.invoice_id',
|
||||
'user' => 'expense.user',
|
||||
'assigned_user' => 'expense.assigned_user',
|
||||
];
|
||||
|
||||
protected array $task_report_keys = [
|
||||
'start_date' => 'task.start_date',
|
||||
'end_date' => 'task.end_date',
|
||||
'duration' => 'task.duration',
|
||||
'rate' => 'task.rate',
|
||||
'number' => 'task.number',
|
||||
'description' => 'task.description',
|
||||
'custom_value1' => 'task.custom_value1',
|
||||
'custom_value2' => 'task.custom_value2',
|
||||
'custom_value3' => 'task.custom_value3',
|
||||
'custom_value4' => 'task.custom_value4',
|
||||
'status' => 'task.status_id',
|
||||
'project' => 'task.project_id',
|
||||
];
|
||||
|
||||
protected function filterByClients($query)
|
||||
{
|
||||
if (isset($this->input['client_id']) && $this->input['client_id'] != 'all') {
|
||||
@ -50,6 +366,325 @@ class BaseExport
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function resolveKey($key, $entity, $transformer) :string
|
||||
{
|
||||
$parts = explode(".", $key);
|
||||
|
||||
if(!is_array($parts) || count($parts) < 2)
|
||||
return '';
|
||||
|
||||
$value = '';
|
||||
|
||||
match($parts[0]) {
|
||||
'contact' => $value = $this->resolveClientContactKey($parts[1], $entity, $transformer),
|
||||
'client' => $value = $this->resolveClientKey($parts[1], $entity, $transformer),
|
||||
'expense' => $value = $this->resolveExpenseKey($parts[1], $entity, $transformer),
|
||||
'vendor' => $value = $this->resolveVendorKey($parts[1], $entity, $transformer),
|
||||
'vendor_contact' => $value = $this->resolveVendorContactKey($parts[1], $entity, $transformer),
|
||||
'invoice' => $value = $this->resolveInvoiceKey($parts[1], $entity, $transformer),
|
||||
'recurring_invoice' => $value = $this->resolveInvoiceKey($parts[1], $entity, $transformer),
|
||||
'quote' => $value = $this->resolveQuoteKey($parts[1], $entity, $transformer),
|
||||
'purchase_order' => $value = $this->resolvePurchaseOrderKey($parts[1], $entity, $transformer),
|
||||
'payment' => $value = $this->resolvePaymentKey($parts[1], $entity, $transformer),
|
||||
'task' => $value = $this->resolveTaskKey($parts[1], $entity, $transformer),
|
||||
default => $value = '',
|
||||
};
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
private function resolveClientContactKey($column, $entity, $transformer)
|
||||
{
|
||||
|
||||
if(!$entity->client) {
|
||||
return "";
|
||||
}
|
||||
|
||||
$primary_contact = $entity->client->primary_contact()->first() ?? $entity->client->contacts()->first();
|
||||
|
||||
return $primary_contact ? $primary_contact?->{$column} ?? '' : '';
|
||||
|
||||
}
|
||||
|
||||
private function resolveVendorContactKey($column, $entity, $transformer)
|
||||
{
|
||||
if(!$entity->vendor)
|
||||
return "";
|
||||
|
||||
$primary_contact = $entity->vendor->primary_contact()->first() ?? $entity->vendor->contacts()->first();
|
||||
|
||||
return $primary_contact ? $primary_contact?->{$column} ?? '' : '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function resolveExpenseKey($column, $entity, $transformer)
|
||||
{
|
||||
|
||||
if($column == 'user' && $entity?->expense?->user)
|
||||
return $entity->expense->user->present()->name() ?? ' ';
|
||||
|
||||
if($column == 'assigned_user' && $entity?->expense?->assigned_user)
|
||||
return $entity->expense->assigned_user->present()->name() ?? ' ';
|
||||
|
||||
if($column == 'category' && $entity->expense) {
|
||||
return $entity->expense->category?->name ?? ' ';
|
||||
}
|
||||
|
||||
if($entity instanceof Expense)
|
||||
return '';
|
||||
|
||||
$transformed_entity = $transformer->includeExpense($entity);
|
||||
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$transformed_entity = $manager->createData($transformed_entity)->toArray();
|
||||
|
||||
if(array_key_exists($column, $transformed_entity))
|
||||
return $transformed_entity[$column];
|
||||
|
||||
if(property_exists($entity, $column))
|
||||
return $entity?->{$column} ?? '';
|
||||
|
||||
nlog("export: Could not resolve expense key: {$column}");
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
private function resolveTaskKey($column, $entity, $transformer)
|
||||
{
|
||||
// nlog("searching for {$column}");
|
||||
|
||||
$transformed_entity = $transformer->transform($entity);
|
||||
|
||||
if(array_key_exists($column, $transformed_entity)) {
|
||||
return $transformed_entity[$column];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function resolveVendorKey($column, $entity, $transformer)
|
||||
{
|
||||
|
||||
if(!$entity->vendor)
|
||||
return '';
|
||||
|
||||
$transformed_entity = $transformer->includeVendor($entity);
|
||||
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$transformed_entity = $manager->createData($transformed_entity)->toArray();
|
||||
|
||||
if($column == 'name')
|
||||
return $entity->vendor->present()->name() ?: '';
|
||||
|
||||
if($column == 'user_id')
|
||||
return $entity->vendor->user->present()->name() ?: '';
|
||||
|
||||
if($column == 'country_id')
|
||||
return $entity->vendor->country ? ctrans("texts.country_{$entity->vendor->country->name}") : '';
|
||||
|
||||
if ($column == 'currency_id') {
|
||||
return $entity->vendor->currency() ? $entity->vendor->currency()->code : $entity->company->currency()->code;
|
||||
}
|
||||
|
||||
if($column == 'status')
|
||||
return $entity->stringStatus($entity->status_id) ?: '';
|
||||
|
||||
if(array_key_exists($column, $transformed_entity))
|
||||
return $transformed_entity[$column];
|
||||
|
||||
// nlog("export: Could not resolve vendor key: {$column}");
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function resolveClientKey($column, $entity, $transformer)
|
||||
{
|
||||
|
||||
if(!$entity->client)
|
||||
return '';
|
||||
|
||||
$transformed_client = $transformer->includeClient($entity);
|
||||
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$transformed_client = $manager->createData($transformed_client)->toArray();
|
||||
|
||||
if($column == 'name')
|
||||
return $transformed_client['display_name'];
|
||||
|
||||
if($column == 'user_id')
|
||||
return $entity->client->user->present()->name();
|
||||
|
||||
if($column == 'country_id')
|
||||
return $entity->client->country ? ctrans("texts.country_{$entity->client->country->name}") : '';
|
||||
|
||||
if($column == 'shipping_country_id')
|
||||
return $entity->client->shipping_country ? ctrans("texts.country_{$entity->client->shipping_country->name}") : '';
|
||||
|
||||
if($column == 'size_id')
|
||||
return $entity->client->size?->name ?? '';
|
||||
|
||||
if($column == 'industry_id')
|
||||
return $entity->client->industry?->name ?? '';
|
||||
|
||||
if ($column == 'currency_id') {
|
||||
return $entity->client->currency() ? $entity->client->currency()->code : $entity->company->currency()->code;
|
||||
}
|
||||
|
||||
if($column == 'client.payment_terms') {
|
||||
return $entity->client->getSetting('payment_terms');
|
||||
}
|
||||
|
||||
if(array_key_exists($column, $transformed_client))
|
||||
return $transformed_client[$column];
|
||||
|
||||
// nlog("export: Could not resolve client key: {$column}");
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
private function resolvePurchaseOrderKey($column, $entity, $transformer)
|
||||
{
|
||||
// nlog("searching for {$column}");
|
||||
|
||||
$transformed_entity = $transformer->transform($entity);
|
||||
|
||||
if($column == 'status')
|
||||
return $entity->stringStatus($entity->status_id);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function resolveQuoteKey($column, $entity, $transformer)
|
||||
{
|
||||
// nlog("searching for {$column}");
|
||||
|
||||
$transformed_entity = $transformer->transform($entity);
|
||||
|
||||
if(array_key_exists($column, $transformed_entity)) {
|
||||
return $transformed_entity[$column];
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
private function resolveInvoiceKey($column, $entity, $transformer)
|
||||
{
|
||||
// nlog("searching for {$column}");
|
||||
$transformed_invoice = false;
|
||||
|
||||
if($transformer instanceof PaymentTransformer) {
|
||||
$transformed_invoices = $transformer->includeInvoices($entity);
|
||||
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$transformed_invoices = $manager->createData($transformed_invoices)->toArray();
|
||||
|
||||
if(!isset($transformed_invoices['App\\Models\\Invoice']))
|
||||
return '';
|
||||
|
||||
$transformed_invoices = $transformed_invoices['App\\Models\\Invoice'];
|
||||
|
||||
if(count($transformed_invoices) == 1 && array_key_exists($column, $transformed_invoices[0]))
|
||||
return $transformed_invoices[0][$column];
|
||||
|
||||
if(count($transformed_invoices) > 1 && array_key_exists($column, $transformed_invoices[0]))
|
||||
return implode(', ', array_column($transformed_invoices, $column));
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
if($transformer instanceof TaskTransformer) {
|
||||
$transformed_invoice = $transformer->includeInvoice($entity);
|
||||
|
||||
if(!$transformed_invoice)
|
||||
return '';
|
||||
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$transformed_invoice = $manager->createData($transformed_invoice)->toArray();
|
||||
|
||||
}
|
||||
|
||||
if($transformed_invoice && array_key_exists($column, $transformed_invoice)) {
|
||||
return $transformed_invoice[$column];
|
||||
} elseif ($transformed_invoice && array_key_exists(str_replace("invoice.", "", $column), $transformed_invoice)) {
|
||||
return $transformed_invoice[$column];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function resolvePaymentKey($column, $entity, $transformer)
|
||||
{
|
||||
|
||||
if($entity instanceof Payment){
|
||||
|
||||
$transformed_payment = $transformer->transform($entity);
|
||||
|
||||
if(array_key_exists($column, $transformed_payment)) {
|
||||
return $transformed_payment[$column];
|
||||
} elseif (array_key_exists(str_replace("payment.", "", $column), $transformed_payment)) {
|
||||
return $transformed_payment[$column];
|
||||
}
|
||||
|
||||
// nlog("export: Could not resolve payment key: {$column}");
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
if($column == 'amount')
|
||||
return $entity->payments()->exists() ? $entity->payments()->withoutTrashed()->sum('paymentables.amount') : ctrans('texts.unpaid');
|
||||
|
||||
if($column == 'refunded') {
|
||||
return $entity->payments()->exists() ? $entity->payments()->withoutTrashed()->sum('paymentables.refunded') : '';
|
||||
}
|
||||
|
||||
if($column == 'applied') {
|
||||
$refunded = $entity->payments()->withoutTrashed()->sum('paymentables.refunded');
|
||||
$amount = $entity->payments()->withoutTrashed()->sum('paymentables.amount');
|
||||
|
||||
return $entity->payments()->withoutTrashed()->exists() ? ($amount - $refunded) : '';
|
||||
}
|
||||
|
||||
$payment = $entity->payments()->withoutTrashed()->first();
|
||||
|
||||
if(!$payment)
|
||||
return '';
|
||||
|
||||
if($column == 'method')
|
||||
return $payment->translatedType();
|
||||
|
||||
if($column == 'currency')
|
||||
return $payment?->currency?->code ?? '';
|
||||
|
||||
$payment_transformer = new PaymentTransformer();
|
||||
$transformed_payment = $payment_transformer->transform($payment);
|
||||
|
||||
if($column == 'status'){
|
||||
return $payment->stringStatus($transformed_payment['status_id']);
|
||||
}
|
||||
|
||||
if(array_key_exists($column, $transformed_payment))
|
||||
return $transformed_payment[$column];
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
protected function addInvoiceStatusFilter($query, $status): Builder
|
||||
{
|
||||
|
||||
@ -154,8 +789,27 @@ class BaseExport
|
||||
$this->end_date = now()->startOfDay()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [now()->subDays(365), now()])->orderBy($this->date_key, 'ASC');
|
||||
case 'this_year':
|
||||
$this->start_date = now()->startOfYear()->format('Y-m-d');
|
||||
$this->end_date = now()->format('Y-m-d');
|
||||
|
||||
$first_month_of_year = $this->company->getSetting('first_month_of_year') ?? 1;
|
||||
$fin_year_start = now()->createFromDate(now()->year, $first_month_of_year, 1);
|
||||
|
||||
if(now()->lt($fin_year_start))
|
||||
$fin_year_start->subYearNoOverflow();
|
||||
|
||||
$this->start_date = $fin_year_start->format('Y-m-d');
|
||||
$this->end_date = $fin_year_start->copy()->addYear()->subDay()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [now()->startOfYear(), now()])->orderBy($this->date_key, 'ASC');
|
||||
case 'last_year':
|
||||
|
||||
$first_month_of_year = $this->company->getSetting('first_month_of_year') ?? 1;
|
||||
$fin_year_start = now()->createFromDate(now()->year, $first_month_of_year, 1);
|
||||
$fin_year_start->subYearNoOverflow();
|
||||
|
||||
if(now()->subYear()->lt($fin_year_start))
|
||||
$fin_year_start->subYearNoOverflow();
|
||||
|
||||
$this->start_date = $fin_year_start->format('Y-m-d');
|
||||
$this->end_date = $fin_year_start->copy()->addYear()->subDay()->format('Y-m-d');
|
||||
return $query->whereBetween($this->date_key, [now()->startOfYear(), now()])->orderBy($this->date_key, 'ASC');
|
||||
case 'custom':
|
||||
$this->start_date = $custom_start_date->format('Y-m-d');
|
||||
@ -172,17 +826,100 @@ class BaseExport
|
||||
{
|
||||
$header = [];
|
||||
|
||||
// nlog($this->input['report_keys']);
|
||||
|
||||
foreach (array_merge($this->input['report_keys'], $this->forced_keys) as $value) {
|
||||
|
||||
$key = array_search($value, $this->entity_keys);
|
||||
|
||||
$prefix = '';
|
||||
|
||||
if(!$key) {
|
||||
$prefix = stripos($value, 'client.') !== false ? ctrans('texts.client')." " : ctrans('texts.contact')." ";
|
||||
$key = array_search($value, $this->client_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.invoice')." ";
|
||||
$key = array_search($value, $this->invoice_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.recurring_invoice')." ";
|
||||
$key = array_search($value, $this->recurring_invoice_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.payment')." ";
|
||||
$key = array_search($value, $this->payment_report_keys);
|
||||
}
|
||||
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.quote')." ";
|
||||
$key = array_search($value, $this->quote_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.credit')." ";
|
||||
$key = array_search($value, $this->credit_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.item')." ";
|
||||
$key = array_search($value, $this->item_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.expense')." ";
|
||||
$key = array_search($value, $this->expense_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.task')." ";
|
||||
$key = array_search($value, $this->task_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.vendor')." ";
|
||||
$key = array_search($value, $this->vendor_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = ctrans('texts.purchase_order')." ";
|
||||
$key = array_search($value, $this->purchase_order_report_keys);
|
||||
}
|
||||
|
||||
if(!$key) {
|
||||
$prefix = '';
|
||||
}
|
||||
|
||||
$key = str_replace('item.', '', $key);
|
||||
$key = str_replace('recurring_invoice.', '', $key);
|
||||
$key = str_replace('purchase_order.', '', $key);
|
||||
$key = str_replace('invoice.', '', $key);
|
||||
$key = str_replace('quote.', '', $key);
|
||||
$key = str_replace('credit.', '', $key);
|
||||
$key = str_replace('task.', '', $key);
|
||||
$key = str_replace('client.', '', $key);
|
||||
$key = str_replace('vendor.', '', $key);
|
||||
$key = str_replace('contact.', '', $key);
|
||||
$key = str_replace('payment.', '', $key);
|
||||
$key = str_replace('expense.', '', $key);
|
||||
|
||||
$header[] = ctrans("texts.{$key}");
|
||||
if(in_array($key, ['quote1','quote2','quote3','quote4','credit1','credit2','credit3','credit4','purchase_order1','purchase_order2','purchase_order3','purchase_order4']))
|
||||
{
|
||||
$number = substr($key, -1);
|
||||
$header[] = ctrans('texts.item') . " ". ctrans("texts.custom_value{$number}");
|
||||
}
|
||||
else
|
||||
{
|
||||
$header[] = "{$prefix}" . ctrans("texts.{$key}");
|
||||
}
|
||||
}
|
||||
|
||||
// nlog($header);
|
||||
|
||||
return $header;
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,6 @@ use League\Csv\Writer;
|
||||
|
||||
class ClientExport extends BaseExport
|
||||
{
|
||||
private $company;
|
||||
|
||||
private $client_transformer;
|
||||
|
||||
private $contact_transformer;
|
||||
@ -82,7 +80,6 @@ class ClientExport extends BaseExport
|
||||
];
|
||||
|
||||
public array $forced_keys = [
|
||||
'status',
|
||||
];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
@ -132,6 +129,8 @@ class ClientExport extends BaseExport
|
||||
|
||||
$transformed_client = $this->client_transformer->transform($client);
|
||||
|
||||
$transformed_contact = [];
|
||||
|
||||
if ($contact = $client->contacts()->first()) {
|
||||
$transformed_contact = $this->contact_transformer->transform($contact);
|
||||
}
|
||||
@ -140,15 +139,13 @@ class ClientExport extends BaseExport
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$parts = explode('.', $key);
|
||||
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if ($parts[0] == 'client' && array_key_exists($parts[1], $transformed_client)) {
|
||||
$entity[$keyval] = $transformed_client[$parts[1]];
|
||||
} elseif ($parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
|
||||
$entity[$keyval] = $transformed_contact[$parts[1]];
|
||||
|
||||
if (is_array($parts) && $parts[0] == 'client' && array_key_exists($parts[1], $transformed_client)) {
|
||||
$entity[$key] = $transformed_client[$parts[1]];
|
||||
} elseif (is_array($parts) && $parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
|
||||
$entity[$key] = $transformed_contact[$parts[1]];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
$entity[$key] = '';
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,24 +154,30 @@ class ClientExport extends BaseExport
|
||||
|
||||
private function decorateAdvancedFields(Client $client, array $entity) :array
|
||||
{
|
||||
if (in_array('client.user', $this->input['report_keys'])) {
|
||||
$entity['client.user'] = $client->user->present()->name();
|
||||
}
|
||||
|
||||
if (in_array('client.assigned_user', $this->input['report_keys'])) {
|
||||
$entity['client.assigned_user'] = $client->assigned_user ? $client->user->present()->name() : '';
|
||||
}
|
||||
|
||||
if (in_array('client.country_id', $this->input['report_keys'])) {
|
||||
$entity['country'] = $client->country ? ctrans("texts.country_{$client->country->name}") : '';
|
||||
$entity['client.country_id'] = $client->country ? ctrans("texts.country_{$client->country->name}") : '';
|
||||
}
|
||||
|
||||
if (in_array('client.shipping_country_id', $this->input['report_keys'])) {
|
||||
$entity['shipping_country'] = $client->shipping_country ? ctrans("texts.country_{$client->shipping_country->name}") : '';
|
||||
$entity['client.shipping_country_id'] = $client->shipping_country ? ctrans("texts.country_{$client->shipping_country->name}") : '';
|
||||
}
|
||||
|
||||
if (in_array('client.currency', $this->input['report_keys'])) {
|
||||
$entity['currency'] = $client->currency() ? $client->currency()->code : $client->company->currency()->code;
|
||||
if (in_array('client.currency_id', $this->input['report_keys'])) {
|
||||
$entity['client.currency_id'] = $client->currency() ? $client->currency()->code : $client->company->currency()->code;
|
||||
}
|
||||
|
||||
if (in_array('client.industry_id', $this->input['report_keys'])) {
|
||||
$entity['industry_id'] = $client->industry ? ctrans("texts.industry_{$client->industry->name}") : '';
|
||||
}
|
||||
|
||||
$entity['status'] = $this->calculateStatus($client);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
@ -185,7 +188,7 @@ class ClientExport extends BaseExport
|
||||
}
|
||||
|
||||
if ($client->deleted_at) {
|
||||
return ctrans('texts.arcvived');
|
||||
return ctrans('texts.archived');
|
||||
}
|
||||
|
||||
return ctrans('texts.active');
|
||||
|
@ -23,7 +23,6 @@ use League\Csv\Writer;
|
||||
|
||||
class ContactExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private ClientTransformer $client_transformer;
|
||||
|
||||
|
@ -21,7 +21,6 @@ use League\Csv\Writer;
|
||||
|
||||
class CreditExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private CreditTransformer $credit_transformer;
|
||||
|
||||
@ -123,10 +122,19 @@ class CreditExport extends BaseExport
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval)
|
||||
$keyval = array_search(str_replace("credit.", "", $key), $this->entity_keys) ?? $key;
|
||||
|
||||
if(!$keyval)
|
||||
$keyval = $key;
|
||||
|
||||
if (array_key_exists($key, $transformed_credit)) {
|
||||
$entity[$keyval] = $transformed_credit[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
} elseif (array_key_exists($keyval, $transformed_credit)) {
|
||||
$entity[$keyval] = $transformed_credit[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,9 +146,9 @@ class CreditExport extends BaseExport
|
||||
if (in_array('country_id', $this->input['report_keys'])) {
|
||||
$entity['country'] = $credit->client->country ? ctrans("texts.country_{$credit->client->country->name}") : '';
|
||||
}
|
||||
|
||||
|
||||
if (in_array('currency_id', $this->input['report_keys'])) {
|
||||
$entity['currency_id'] = $credit->client->currency() ? $credit->client->currency()->code : $invoice->company->currency()->code;
|
||||
$entity['currency_id'] = $credit->client->currency() ? $credit->client->currency()->code : $credit->company->currency()->code;
|
||||
}
|
||||
|
||||
if (in_array('invoice_id', $this->input['report_keys'])) {
|
||||
@ -155,6 +163,10 @@ class CreditExport extends BaseExport
|
||||
$entity['status'] = $credit->stringStatus($credit->status_id);
|
||||
}
|
||||
|
||||
if(in_array('credit.status', $this->input['report_keys'])) {
|
||||
$entity['credit.status'] = $credit->stringStatus($credit->status_id);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ use League\Csv\Writer;
|
||||
|
||||
class DocumentExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $entity_transformer;
|
||||
|
||||
|
@ -21,7 +21,6 @@ use League\Csv\Writer;
|
||||
|
||||
class ExpenseExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $expense_transformer;
|
||||
|
||||
@ -30,36 +29,38 @@ class ExpenseExport extends BaseExport
|
||||
public Writer $csv;
|
||||
|
||||
public array $entity_keys = [
|
||||
'amount' => 'amount',
|
||||
'category' => 'category_id',
|
||||
'client' => 'client_id',
|
||||
'custom_value1' => 'custom_value1',
|
||||
'custom_value2' => 'custom_value2',
|
||||
'custom_value3' => 'custom_value3',
|
||||
'custom_value4' => 'custom_value4',
|
||||
'currency' => 'currency_id',
|
||||
'date' => 'date',
|
||||
'exchange_rate' => 'exchange_rate',
|
||||
'converted_amount' => 'foreign_amount',
|
||||
'invoice_currency_id' => 'invoice_currency_id',
|
||||
'payment_date' => 'payment_date',
|
||||
'number' => 'number',
|
||||
'payment_type_id' => 'payment_type_id',
|
||||
'private_notes' => 'private_notes',
|
||||
'project' => 'project_id',
|
||||
'public_notes' => 'public_notes',
|
||||
'tax_amount1' => 'tax_amount1',
|
||||
'tax_amount2' => 'tax_amount2',
|
||||
'tax_amount3' => 'tax_amount3',
|
||||
'tax_name1' => 'tax_name1',
|
||||
'tax_name2' => 'tax_name2',
|
||||
'tax_name3' => 'tax_name3',
|
||||
'tax_rate1' => 'tax_rate1',
|
||||
'tax_rate2' => 'tax_rate2',
|
||||
'tax_rate3' => 'tax_rate3',
|
||||
'transaction_reference' => 'transaction_reference',
|
||||
'vendor' => 'vendor_id',
|
||||
'invoice' => 'invoice_id',
|
||||
'amount' => 'expense.amount',
|
||||
'category' => 'expense.category',
|
||||
'client' => 'expense.client_id',
|
||||
'custom_value1' => 'expense.custom_value1',
|
||||
'custom_value2' => 'expense.custom_value2',
|
||||
'custom_value3' => 'expense.custom_value3',
|
||||
'custom_value4' => 'expense.custom_value4',
|
||||
'currency' => 'expense.currency_id',
|
||||
'date' => 'expense.date',
|
||||
'exchange_rate' => 'expense.exchange_rate',
|
||||
'converted_amount' => 'expense.foreign_amount',
|
||||
'invoice_currency_id' => 'expense.invoice_currency_id',
|
||||
'payment_date' => 'expense.payment_date',
|
||||
'number' => 'expense.number',
|
||||
'payment_type_id' => 'expense.payment_type_id',
|
||||
'private_notes' => 'expense.private_notes',
|
||||
'project' => 'expense.project_id',
|
||||
'public_notes' => 'expense.public_notes',
|
||||
'tax_amount1' => 'expense.tax_amount1',
|
||||
'tax_amount2' => 'expense.tax_amount2',
|
||||
'tax_amount3' => 'expense.tax_amount3',
|
||||
'tax_name1' => 'expense.tax_name1',
|
||||
'tax_name2' => 'expense.tax_name2',
|
||||
'tax_name3' => 'expense.tax_name3',
|
||||
'tax_rate1' => 'expense.tax_rate1',
|
||||
'tax_rate2' => 'expense.tax_rate2',
|
||||
'tax_rate3' => 'expense.tax_rate3',
|
||||
'transaction_reference' => 'expense.transaction_reference',
|
||||
'vendor' => 'expense.vendor_id',
|
||||
'invoice' => 'expense.invoice_id',
|
||||
'user' => 'expense.user',
|
||||
'assigned_user' => 'expense.assigned_user',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
@ -120,13 +121,17 @@ class ExpenseExport extends BaseExport
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$parts = explode('.', $key);
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_expense)) {
|
||||
$entity[$keyval] = $transformed_expense[$key];
|
||||
if (is_array($parts) && $parts[0] == 'expense' && array_key_exists($parts[1], $transformed_expense)) {
|
||||
$entity[$key] = $transformed_expense[$parts[1]];
|
||||
} elseif (array_key_exists($key, $transformed_expense)) {
|
||||
$entity[$key] = $transformed_expense[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
$entity[$key] = $this->resolveKey($key, $expense, $this->expense_transformer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->decorateAdvancedFields($expense, $entity);
|
||||
@ -134,32 +139,40 @@ class ExpenseExport extends BaseExport
|
||||
|
||||
private function decorateAdvancedFields(Expense $expense, array $entity) :array
|
||||
{
|
||||
if (in_array('currency_id', $this->input['report_keys'])) {
|
||||
$entity['currency'] = $expense->currency ? $expense->currency->code : '';
|
||||
if (in_array('expense.currency_id', $this->input['report_keys'])) {
|
||||
$entity['expense.currency_id'] = $expense->currency ? $expense->currency->code : '';
|
||||
}
|
||||
|
||||
if (in_array('client_id', $this->input['report_keys'])) {
|
||||
$entity['client'] = $expense->client ? $expense->client->present()->name() : '';
|
||||
if (in_array('expense.client_id', $this->input['report_keys'])) {
|
||||
$entity['expense.client'] = $expense->client ? $expense->client->present()->name() : '';
|
||||
}
|
||||
|
||||
if (in_array('invoice_id', $this->input['report_keys'])) {
|
||||
$entity['invoice'] = $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('category_id', $this->input['report_keys'])) {
|
||||
$entity['category'] = $expense->category ? $expense->category->name : '';
|
||||
if (in_array('expense.category', $this->input['report_keys'])) {
|
||||
$entity['expense.category'] = $expense->category ? $expense->category->name : '';
|
||||
}
|
||||
|
||||
if (in_array('vendor_id', $this->input['report_keys'])) {
|
||||
$entity['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('payment_type_id', $this->input['report_keys'])) {
|
||||
$entity['payment_type'] = $expense->payment_type ? $expense->payment_type->name : '';
|
||||
if (in_array('expense.payment_type_id', $this->input['report_keys'])) {
|
||||
$entity['expense.payment_type_id'] = $expense->payment_type ? $expense->payment_type->name : '';
|
||||
}
|
||||
|
||||
if (in_array('project_id', $this->input['report_keys'])) {
|
||||
$entity['project'] = $expense->project ? $expense->project->name : '';
|
||||
if (in_array('expense.project_id', $this->input['report_keys'])) {
|
||||
$entity['expense.project_id'] = $expense->project ? $expense->project->name : '';
|
||||
}
|
||||
|
||||
if (in_array('expense.user', $this->input['report_keys'])) {
|
||||
$entity['expense.user'] = $expense->user ? $expense->user->present()->name() : '';
|
||||
}
|
||||
|
||||
if (in_array('expense.assigned_user', $this->input['report_keys'])) {
|
||||
$entity['expense.assigned_user'] = $expense->assigned_user ? $expense->assigned_user->present()->name() : '';
|
||||
}
|
||||
|
||||
return $entity;
|
||||
|
@ -23,8 +23,6 @@ use App\Transformers\InvoiceTransformer;
|
||||
|
||||
class InvoiceExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $invoice_transformer;
|
||||
|
||||
public string $date_key = 'date';
|
||||
@ -80,6 +78,7 @@ class InvoiceExport extends BaseExport
|
||||
'project',
|
||||
];
|
||||
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
$this->company = $company;
|
||||
@ -134,10 +133,21 @@ class InvoiceExport extends BaseExport
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
} elseif (array_key_exists($keyval, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,15 +172,15 @@ class InvoiceExport extends BaseExport
|
||||
$entity['status'] = $invoice->stringStatus($invoice->status_id);
|
||||
}
|
||||
|
||||
$payment_exists = $invoice->payments()->exists();
|
||||
// $payment_exists = $invoice->payments()->exists();
|
||||
|
||||
$entity['payment_number'] = $payment_exists ? $invoice->payments()->pluck('number')->implode(',') : '';
|
||||
// $entity['payment_number'] = $payment_exists ? $invoice->payments()->pluck('number')->implode(',') : '';
|
||||
|
||||
$entity['payment_date'] = $payment_exists ? $invoice->payments()->pluck('date')->implode(',') : '';
|
||||
// $entity['payment_date'] = $payment_exists ? $invoice->payments()->pluck('date')->implode(',') : '';
|
||||
|
||||
$entity['payment_amount'] = $payment_exists ? Number::formatMoney($invoice->payments()->sum('paymentables.amount'), $invoice->company) : ctrans('texts.unpaid');
|
||||
// $entity['payment_amount'] = $payment_exists ? Number::formatMoney($invoice->payments()->sum('paymentables.amount'), $invoice->company) : ctrans('texts.unpaid');
|
||||
|
||||
$entity['method'] = $payment_exists ? $invoice->payments()->first()->translatedType() : "";
|
||||
// $entity['method'] = $payment_exists ? $invoice->payments()->first()->translatedType() : "";
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ use League\Csv\Writer;
|
||||
|
||||
class InvoiceItemExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $invoice_transformer;
|
||||
|
||||
@ -30,6 +29,8 @@ class InvoiceItemExport extends BaseExport
|
||||
|
||||
public Writer $csv;
|
||||
|
||||
private bool $force_keys = false;
|
||||
|
||||
public array $entity_keys = [
|
||||
'amount' => 'amount',
|
||||
'balance' => 'balance',
|
||||
@ -67,9 +68,9 @@ class InvoiceItemExport extends BaseExport
|
||||
'total_taxes' => 'total_taxes',
|
||||
'currency' => 'currency_id',
|
||||
'quantity' => 'item.quantity',
|
||||
'unit_cost' => 'item.cost',
|
||||
'cost' => 'item.cost',
|
||||
'product_key' => 'item.product_key',
|
||||
'cost' => 'item.product_cost',
|
||||
'buy_price' => 'item.product_cost',
|
||||
'notes' => 'item.notes',
|
||||
'discount' => 'item.discount',
|
||||
'is_amount_discount' => 'item.is_amount_discount',
|
||||
@ -85,6 +86,8 @@ class InvoiceItemExport extends BaseExport
|
||||
'invoice2' => 'item.custom_value2',
|
||||
'invoice3' => 'item.custom_value3',
|
||||
'invoice4' => 'item.custom_value4',
|
||||
'tax_category' => 'item.tax_id',
|
||||
'type' => 'item.type_id',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
@ -112,6 +115,7 @@ class InvoiceItemExport extends BaseExport
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->force_keys = true;
|
||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||
}
|
||||
|
||||
@ -140,24 +144,36 @@ class InvoiceItemExport extends BaseExport
|
||||
$transformed_items = [];
|
||||
|
||||
foreach ($invoice->line_items as $item) {
|
||||
$item_array = [];
|
||||
$item_array = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
|
||||
|
||||
if (str_contains($key, "item.")) {
|
||||
|
||||
$key = str_replace("item.", "", $key);
|
||||
|
||||
$keyval = $key;
|
||||
|
||||
$keyval = str_replace("custom_value", "invoice", $key);
|
||||
|
||||
if($key == 'type_id')
|
||||
$keyval = 'type';
|
||||
|
||||
if($key == 'tax_id')
|
||||
$keyval = 'tax_category';
|
||||
|
||||
if (property_exists($item, $key)) {
|
||||
$item_array[$key] = $item->{$key};
|
||||
$item_array[$keyval] = $item->{$key};
|
||||
} else {
|
||||
$item_array[$key] = '';
|
||||
$item_array[$keyval] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
foreach (array_values($this->input['report_keys']) as $key) { //create an array of report keys only
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_items)) {
|
||||
$entity[$keyval] = $transformed_items[$key];
|
||||
@ -182,10 +198,21 @@ class InvoiceItemExport extends BaseExport
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$key];
|
||||
} else {
|
||||
$entity[$keyval] = "";
|
||||
} elseif (array_key_exists($keyval, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,13 +225,20 @@ class InvoiceItemExport extends BaseExport
|
||||
$entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
|
||||
}
|
||||
|
||||
// if(in_array('client_id', $this->input['report_keys']))
|
||||
$entity['client'] = $invoice->client->present()->name();
|
||||
$entity['client_id_number'] = $invoice->client->id_number;
|
||||
$entity['client_number'] = $invoice->client->number;
|
||||
if(array_key_exists('type', $entity)) {
|
||||
$entity['type'] = $invoice->typeIdString($entity['type']);
|
||||
}
|
||||
|
||||
// if(in_array('status_id', $this->input['report_keys']))
|
||||
$entity['status'] = $invoice->stringStatus($invoice->status_id);
|
||||
if(array_key_exists('tax_category', $entity)) {
|
||||
$entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
|
||||
}
|
||||
|
||||
if($this->force_keys) {
|
||||
$entity['client'] = $invoice->client->present()->name();
|
||||
$entity['client_id_number'] = $invoice->client->id_number;
|
||||
$entity['client_number'] = $invoice->client->number;
|
||||
$entity['status'] = $invoice->stringStatus($invoice->status_id);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
@ -21,8 +21,6 @@ use League\Csv\Writer;
|
||||
|
||||
class PaymentExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $entity_transformer;
|
||||
|
||||
public string $date_key = 'date';
|
||||
@ -112,10 +110,21 @@ class PaymentExport extends BaseExport
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("payment.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $payment, $this->entity_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,6 +149,10 @@ class PaymentExport extends BaseExport
|
||||
$entity['currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
|
||||
}
|
||||
|
||||
if (in_array('payment.currency', $this->input['report_keys'])) {
|
||||
$entity['payment.currency'] = $payment->currency()->exists() ? $payment->currency->code : '';
|
||||
}
|
||||
|
||||
if (in_array('exchange_currency_id', $this->input['report_keys'])) {
|
||||
$entity['exchange_currency'] = $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : '';
|
||||
}
|
||||
@ -152,11 +165,19 @@ class PaymentExport extends BaseExport
|
||||
$entity['type'] = $payment->translatedType();
|
||||
}
|
||||
|
||||
if (in_array('payment.method', $this->input['report_keys'])) {
|
||||
$entity['payment.method'] = $payment->translatedType();
|
||||
}
|
||||
|
||||
if (in_array('payment.status', $this->input['report_keys'])) {
|
||||
$entity['payment.status'] = $payment->stringStatus($payment->status_id);
|
||||
}
|
||||
|
||||
if (in_array('gateway_type_id', $this->input['report_keys'])) {
|
||||
$entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
|
||||
}
|
||||
|
||||
$entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
|
||||
// $entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
@ -22,8 +22,6 @@ use League\Csv\Writer;
|
||||
|
||||
class ProductExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $entity_transformer;
|
||||
|
||||
public string $date_key = 'created_at';
|
||||
|
@ -23,8 +23,6 @@ use League\Csv\Writer;
|
||||
|
||||
class ProductSalesExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
public string $date_key = 'created_at';
|
||||
|
||||
protected Collection $products;
|
||||
|
171
app/Export/CSV/PurchaseOrderExport.php
Normal file
171
app/Export/CSV/PurchaseOrderExport.php
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* PurchaseOrder Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. PurchaseOrder Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Export\CSV;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Company;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Transformers\PurchaseOrderTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Number;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
class PurchaseOrderExport extends BaseExport
|
||||
{
|
||||
|
||||
private $purchase_order_transformer;
|
||||
|
||||
public string $date_key = 'date';
|
||||
|
||||
public Writer $csv;
|
||||
|
||||
public array $entity_keys = [
|
||||
'amount' => 'purchase_order.amount',
|
||||
'balance' => 'purchase_order.balance',
|
||||
'vendor' => 'purchase_order.vendor_id',
|
||||
// 'custom_surcharge1' => 'purchase_order.custom_surcharge1',
|
||||
// 'custom_surcharge2' => 'purchase_order.custom_surcharge2',
|
||||
// 'custom_surcharge3' => 'purchase_order.custom_surcharge3',
|
||||
// 'custom_surcharge4' => 'purchase_order.custom_surcharge4',
|
||||
'custom_value1' => 'purchase_order.custom_value1',
|
||||
'custom_value2' => 'purchase_order.custom_value2',
|
||||
'custom_value3' => 'purchase_order.custom_value3',
|
||||
'custom_value4' => 'purchase_order.custom_value4',
|
||||
'date' => 'purchase_order.date',
|
||||
'discount' => 'purchase_order.discount',
|
||||
'due_date' => 'purchase_order.due_date',
|
||||
'exchange_rate' => 'purchase_order.exchange_rate',
|
||||
'footer' => 'purchase_order.footer',
|
||||
'number' => 'purchase_order.number',
|
||||
'paid_to_date' => 'purchase_order.paid_to_date',
|
||||
'partial' => 'purchase_order.partial',
|
||||
'partial_due_date' => 'purchase_order.partial_due_date',
|
||||
'po_number' => 'purchase_order.po_number',
|
||||
'private_notes' => 'purchase_order.private_notes',
|
||||
'public_notes' => 'purchase_order.public_notes',
|
||||
'status' => 'purchase_order.status_id',
|
||||
'tax_name1' => 'purchase_order.tax_name1',
|
||||
'tax_name2' => 'purchase_order.tax_name2',
|
||||
'tax_name3' => 'purchase_order.tax_name3',
|
||||
'tax_rate1' => 'purchase_order.tax_rate1',
|
||||
'tax_rate2' => 'purchase_order.tax_rate2',
|
||||
'tax_rate3' => 'purchase_order.tax_rate3',
|
||||
'terms' => 'purchase_order.terms',
|
||||
'total_taxes' => 'purchase_order.total_taxes',
|
||||
'currency_id' => 'purchase_order.currency_id',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'country',
|
||||
'currency_id',
|
||||
'status',
|
||||
'vendor',
|
||||
'project',
|
||||
];
|
||||
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->input = $input;
|
||||
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||
}
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
$query = PurchaseOrder::query()
|
||||
->withTrashed()
|
||||
->with('vendor')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
// if(isset($this->input['status'])) {
|
||||
// $query = $this->addPurchaseOrderStatusFilter($query, $this->input['status']);
|
||||
// }
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($purchase_order) {
|
||||
$this->csv->insertOne($this->buildRow($purchase_order));
|
||||
});
|
||||
|
||||
return $this->csv->toString();
|
||||
}
|
||||
|
||||
private function buildRow(PurchaseOrder $purchase_order) :array
|
||||
{
|
||||
$transformed_purchase_order = $this->purchase_order_transformer->transform($purchase_order);
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("purchase_order.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_purchase_order)) {
|
||||
$entity[$keyval] = $transformed_purchase_order[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_purchase_order)) {
|
||||
$entity[$keyval] = $transformed_purchase_order[$keyval];
|
||||
} else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $purchase_order, $this->purchase_order_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->decorateAdvancedFields($purchase_order, $entity);
|
||||
}
|
||||
|
||||
private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity) :array
|
||||
{
|
||||
if (in_array('country_id', $this->input['report_keys'])) {
|
||||
$entity['country'] = $purchase_order->vendor->country ? ctrans("texts.country_{$purchase_order->vendor->country->name}") : '';
|
||||
}
|
||||
|
||||
if (in_array('currency_id', $this->input['report_keys'])) {
|
||||
$entity['currency_id'] = $purchase_order->vendor->currency() ? $purchase_order->vendor->currency()->code : $purchase_order->company->currency()->code;
|
||||
}
|
||||
|
||||
if (in_array('vendor_id', $this->input['report_keys'])) {
|
||||
$entity['vendor'] = $purchase_order->vendor->present()->name();
|
||||
}
|
||||
|
||||
if (in_array('status_id', $this->input['report_keys'])) {
|
||||
$entity['status'] = $purchase_order->stringStatus($purchase_order->status_id);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
245
app/Export/CSV/PurchaseOrderItemExport.php
Normal file
245
app/Export/CSV/PurchaseOrderItemExport.php
Normal file
@ -0,0 +1,245 @@
|
||||
<?php
|
||||
/**
|
||||
* PurchaseOrder Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. PurchaseOrder Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Export\CSV;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Company;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Transformers\PurchaseOrderTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
class PurchaseOrderItemExport extends BaseExport
|
||||
{
|
||||
|
||||
private $purchase_order_transformer;
|
||||
|
||||
public string $date_key = 'date';
|
||||
|
||||
public Writer $csv;
|
||||
|
||||
private bool $force_keys = false;
|
||||
|
||||
public array $entity_keys = [
|
||||
'amount' => 'amount',
|
||||
'balance' => 'balance',
|
||||
'vendor' => 'vendor_id',
|
||||
'vendor_number' => 'vendor.number',
|
||||
'vendor_id_number' => 'vendor.id_number',
|
||||
// 'custom_surcharge1' => 'custom_surcharge1',
|
||||
// 'custom_surcharge2' => 'custom_surcharge2',
|
||||
// 'custom_surcharge3' => 'custom_surcharge3',
|
||||
// 'custom_surcharge4' => 'custom_surcharge4',
|
||||
// 'custom_value1' => 'custom_value1',
|
||||
// 'custom_value2' => 'custom_value2',
|
||||
// 'custom_value3' => 'custom_value3',
|
||||
// 'custom_value4' => 'custom_value4',
|
||||
'date' => 'date',
|
||||
'discount' => 'discount',
|
||||
'due_date' => 'due_date',
|
||||
'exchange_rate' => 'exchange_rate',
|
||||
'footer' => 'footer',
|
||||
'number' => 'number',
|
||||
'paid_to_date' => 'paid_to_date',
|
||||
'partial' => 'partial',
|
||||
'partial_due_date' => 'partial_due_date',
|
||||
'po_number' => 'po_number',
|
||||
'private_notes' => 'private_notes',
|
||||
'public_notes' => 'public_notes',
|
||||
'status' => 'status_id',
|
||||
'tax_name1' => 'tax_name1',
|
||||
'tax_name2' => 'tax_name2',
|
||||
'tax_name3' => 'tax_name3',
|
||||
'tax_rate1' => 'tax_rate1',
|
||||
'tax_rate2' => 'tax_rate2',
|
||||
'tax_rate3' => 'tax_rate3',
|
||||
'terms' => 'terms',
|
||||
'total_taxes' => 'total_taxes',
|
||||
'currency' => 'currency_id',
|
||||
'quantity' => 'item.quantity',
|
||||
'cost' => 'item.cost',
|
||||
'product_key' => 'item.product_key',
|
||||
'buy_price' => 'item.product_cost',
|
||||
'notes' => 'item.notes',
|
||||
'discount' => 'item.discount',
|
||||
'is_amount_discount' => 'item.is_amount_discount',
|
||||
'tax_rate1' => 'item.tax_rate1',
|
||||
'tax_rate2' => 'item.tax_rate2',
|
||||
'tax_rate3' => 'item.tax_rate3',
|
||||
'tax_name1' => 'item.tax_name1',
|
||||
'tax_name2' => 'item.tax_name2',
|
||||
'tax_name3' => 'item.tax_name3',
|
||||
'line_total' => 'item.line_total',
|
||||
'gross_line_total' => 'item.gross_line_total',
|
||||
'purchase_order1' => 'item.custom_value1',
|
||||
'purchase_order2' => 'item.custom_value2',
|
||||
'purchase_order3' => 'item.custom_value3',
|
||||
'purchase_order4' => 'item.custom_value4',
|
||||
'tax_category' => 'item.tax_id',
|
||||
'type' => 'item.type_id',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'client',
|
||||
'currency_id',
|
||||
'status'
|
||||
];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->input = $input;
|
||||
$this->purchase_order_transformer = new PurchaseOrderTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->force_keys = true;
|
||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||
}
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
$query = PurchaseOrder::query()
|
||||
->withTrashed()
|
||||
->with('vendor')->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($purchase_order) {
|
||||
$this->iterateItems($purchase_order);
|
||||
});
|
||||
|
||||
return $this->csv->toString();
|
||||
}
|
||||
|
||||
private function iterateItems(PurchaseOrder $purchase_order)
|
||||
{
|
||||
$transformed_purchase_order = $this->buildRow($purchase_order);
|
||||
|
||||
$transformed_items = [];
|
||||
|
||||
foreach ($purchase_order->line_items as $item) {
|
||||
$item_array = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
|
||||
|
||||
if (str_contains($key, "item.")) {
|
||||
|
||||
$key = str_replace("item.", "", $key);
|
||||
|
||||
$keyval = $key;
|
||||
|
||||
$keyval = str_replace("custom_value", "purchase_order", $key);
|
||||
|
||||
if($key == 'type_id') {
|
||||
$keyval = 'type';
|
||||
}
|
||||
|
||||
if($key == 'tax_id') {
|
||||
$keyval = 'tax_category';
|
||||
}
|
||||
|
||||
if (property_exists($item, $key)) {
|
||||
$item_array[$keyval] = $item->{$key};
|
||||
} else {
|
||||
$item_array[$keyval] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) { //create an array of report keys only
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_items)) {
|
||||
$entity[$keyval] = $transformed_items[$key];
|
||||
} else {
|
||||
$entity[$keyval] = "";
|
||||
}
|
||||
}
|
||||
|
||||
$transformed_items = array_merge($transformed_purchase_order, $item_array);
|
||||
$entity = $this->decorateAdvancedFields($purchase_order, $transformed_items);
|
||||
|
||||
$this->csv->insertOne($entity);
|
||||
}
|
||||
}
|
||||
|
||||
private function buildRow(PurchaseOrder $purchase_order) :array
|
||||
{
|
||||
$transformed_purchase_order = $this->purchase_order_transformer->transform($purchase_order);
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("purchase_order.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_purchase_order)) {
|
||||
$entity[$keyval] = $transformed_purchase_order[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_purchase_order)) {
|
||||
$entity[$keyval] = $transformed_purchase_order[$keyval];
|
||||
} else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $purchase_order, $this->purchase_order_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->decorateAdvancedFields($purchase_order, $entity);
|
||||
}
|
||||
|
||||
private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity) :array
|
||||
{
|
||||
if (in_array('currency_id', $this->input['report_keys'])) {
|
||||
$entity['currency'] = $purchase_order->vendor->currency() ? $purchase_order->vendor->currency()->code : $purchase_order->company->currency()->code;
|
||||
}
|
||||
|
||||
if(array_key_exists('type', $entity)) {
|
||||
$entity['type'] = $purchase_order->typeIdString($entity['type']);
|
||||
}
|
||||
|
||||
if(array_key_exists('tax_category', $entity)) {
|
||||
$entity['tax_category'] = $purchase_order->taxTypeString($entity['tax_category']);
|
||||
}
|
||||
|
||||
if($this->force_keys) {
|
||||
$entity['vendor'] = $purchase_order->vendor->present()->name();
|
||||
$entity['vendor_id_number'] = $purchase_order->vendor->id_number;
|
||||
$entity['vendor_number'] = $purchase_order->vendor->number;
|
||||
$entity['status'] = $purchase_order->stringStatus($purchase_order->status_id);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
@ -21,7 +21,6 @@ use League\Csv\Writer;
|
||||
|
||||
class QuoteExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $quote_transformer;
|
||||
|
||||
@ -43,7 +42,7 @@ class QuoteExport extends BaseExport
|
||||
'custom_value4' => 'custom_value4',
|
||||
'date' => 'date',
|
||||
'discount' => 'discount',
|
||||
'due_date' => 'due_date',
|
||||
'valid_until' => 'due_date',
|
||||
'exchange_rate' => 'exchange_rate',
|
||||
'footer' => 'footer',
|
||||
'number' => 'number',
|
||||
@ -115,17 +114,28 @@ class QuoteExport extends BaseExport
|
||||
|
||||
private function buildRow(Quote $quote) :array
|
||||
{
|
||||
$transformed_quote = $this->quote_transformer->transform($quote);
|
||||
$transformed_entity = $this->quote_transformer->transform($quote);
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_quote)) {
|
||||
$entity[$keyval] = $transformed_quote[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $quote, $this->quote_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ use League\Csv\Writer;
|
||||
|
||||
class QuoteItemExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $quote_transformer;
|
||||
|
||||
@ -63,10 +62,11 @@ class QuoteItemExport extends BaseExport
|
||||
'terms' => 'terms',
|
||||
'total_taxes' => 'total_taxes',
|
||||
'currency' => 'currency_id',
|
||||
'qty' => 'item.quantity',
|
||||
'unit_cost' => 'item.cost',
|
||||
'quantity' => 'item.quantity',
|
||||
'cost' => 'item.cost',
|
||||
'product_key' => 'item.product_key',
|
||||
'cost' => 'item.product_cost',
|
||||
'buy_price' => 'item.product_cost',
|
||||
'cost' => 'item.cost',
|
||||
'notes' => 'item.notes',
|
||||
'discount' => 'item.discount',
|
||||
'is_amount_discount' => 'item.is_amount_discount',
|
||||
@ -77,11 +77,13 @@ class QuoteItemExport extends BaseExport
|
||||
'tax_name2' => 'item.tax_name2',
|
||||
'tax_name3' => 'item.tax_name3',
|
||||
'line_total' => 'item.line_total',
|
||||
// 'gross_line_total' => 'item.gross_line_total',
|
||||
'custom_value1' => 'item.custom_value1',
|
||||
'custom_value2' => 'item.custom_value2',
|
||||
'custom_value3' => 'item.custom_value3',
|
||||
'custom_value4' => 'item.custom_value4',
|
||||
'gross_line_total' => 'item.gross_line_total',
|
||||
'quote1' => 'item.custom_value1',
|
||||
'quote2' => 'item.custom_value2',
|
||||
'quote3' => 'item.custom_value3',
|
||||
'quote4' => 'item.custom_value4',
|
||||
'tax_category' => 'item.tax_id',
|
||||
'type' => 'item.type_id',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
@ -135,25 +137,44 @@ class QuoteItemExport extends BaseExport
|
||||
|
||||
$transformed_items = [];
|
||||
|
||||
foreach ($quote->line_items as $item) {
|
||||
$item_array = [];
|
||||
$transformed_items = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
if (str_contains($key, 'item.')) {
|
||||
$key = str_replace('item.', '', $key);
|
||||
$item_array[$key] = $item->{$key};
|
||||
foreach ($quote->line_items as $item) {
|
||||
$item_array = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
|
||||
|
||||
if (str_contains($key, "item.")) {
|
||||
|
||||
$key = str_replace("item.", "", $key);
|
||||
|
||||
$keyval = $key;
|
||||
|
||||
$keyval = str_replace("custom_value", "quote", $key);
|
||||
|
||||
if($key == 'type_id')
|
||||
$keyval = 'type';
|
||||
|
||||
if($key == 'tax_id')
|
||||
$keyval = 'tax_category';
|
||||
|
||||
if (property_exists($item, $key)) {
|
||||
$item_array[$keyval] = $item->{$key};
|
||||
} else {
|
||||
$item_array[$keyval] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
foreach (array_values($this->input['report_keys']) as $key) { //create an array of report keys only
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_items)) {
|
||||
$entity[$keyval] = $transformed_items[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
$entity[$keyval] = "";
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,16 +194,26 @@ class QuoteItemExport extends BaseExport
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("quote.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_quote)) {
|
||||
$entity[$keyval] = $transformed_quote[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
} elseif (array_key_exists($keyval, $transformed_quote)) {
|
||||
$entity[$keyval] = $transformed_quote[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $quote, $this->quote_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->decorateAdvancedFields($quote, $entity);
|
||||
}
|
||||
|
||||
private function decorateAdvancedFields(Quote $quote, array $entity) :array
|
||||
{
|
||||
if (in_array('currency_id', $this->input['report_keys'])) {
|
||||
|
@ -21,7 +21,6 @@ use League\Csv\Writer;
|
||||
|
||||
class RecurringInvoiceExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $invoice_transformer;
|
||||
|
||||
@ -33,10 +32,10 @@ class RecurringInvoiceExport extends BaseExport
|
||||
'amount' => 'amount',
|
||||
'balance' => 'balance',
|
||||
'client' => 'client_id',
|
||||
'custom_surcharge1' => 'custom_surcharge1',
|
||||
'custom_surcharge2' => 'custom_surcharge2',
|
||||
'custom_surcharge3' => 'custom_surcharge3',
|
||||
'custom_surcharge4' => 'custom_surcharge4',
|
||||
// 'custom_surcharge1' => 'custom_surcharge1',
|
||||
// 'custom_surcharge2' => 'custom_surcharge2',
|
||||
// 'custom_surcharge3' => 'custom_surcharge3',
|
||||
// 'custom_surcharge4' => 'custom_surcharge4',
|
||||
'custom_value1' => 'custom_value1',
|
||||
'custom_value2' => 'custom_value2',
|
||||
'custom_value3' => 'custom_value3',
|
||||
@ -66,7 +65,8 @@ class RecurringInvoiceExport extends BaseExport
|
||||
'currency' => 'currency_id',
|
||||
'vendor' => 'vendor_id',
|
||||
'project' => 'project_id',
|
||||
'frequency' => 'frequency_id'
|
||||
'frequency_id' => 'frequency_id',
|
||||
'next_send_date' => 'next_send_date'
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
@ -127,11 +127,22 @@ class RecurringInvoiceExport extends BaseExport
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("recurring_invoice.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_invoice)) {
|
||||
$entity[$keyval] = $transformed_invoice[$keyval];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->decorateAdvancedFields($invoice, $entity);
|
||||
@ -163,7 +174,9 @@ class RecurringInvoiceExport extends BaseExport
|
||||
$entity['vendor'] = $invoice->vendor ? $invoice->vendor->name : '';
|
||||
}
|
||||
|
||||
$entity['frequency'] = $invoice->frequencyForKey($invoice->frequency_id);
|
||||
if (in_array('recurring_invoice.frequency_id', $this->input['report_keys']) || in_array('frequency_id', $this->input['report_keys'])) {
|
||||
$entity['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ use League\Csv\Writer;
|
||||
|
||||
class TaskExport extends BaseExport
|
||||
{
|
||||
private Company $company;
|
||||
|
||||
private $entity_transformer;
|
||||
|
||||
@ -47,9 +46,7 @@ class TaskExport extends BaseExport
|
||||
'custom_value4' => 'custom_value4',
|
||||
'status' => 'status_id',
|
||||
'project' => 'project_id',
|
||||
'invoice' => 'invoice_id',
|
||||
'client' => 'client_id',
|
||||
];
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'status',
|
||||
@ -110,38 +107,39 @@ class TaskExport extends BaseExport
|
||||
$entity = [];
|
||||
$transformed_entity = $this->entity_transformer->transform($task);
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = array_search(str_replace("task.", "", $key), $this->entity_keys) ?? $key;
|
||||
}
|
||||
|
||||
if(!$keyval) {
|
||||
$keyval = $key;
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} elseif (array_key_exists($keyval, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$keyval];
|
||||
}
|
||||
else {
|
||||
$entity[$keyval] = $this->resolveKey($keyval, $task, $this->entity_transformer);
|
||||
}
|
||||
}
|
||||
|
||||
$entity['start_date'] = '';
|
||||
$entity['end_date'] = '';
|
||||
$entity['duration'] = '';
|
||||
|
||||
|
||||
if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) {
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$entity['start_date'] = '';
|
||||
$entity['end_date'] = '';
|
||||
$entity['duration'] = '';
|
||||
|
||||
$entity = $this->decorateAdvancedFields($task, $entity);
|
||||
|
||||
ksort($entity);
|
||||
$this->csv->insertOne($entity);
|
||||
} elseif (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) > 0) {
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (array_key_exists($key, $transformed_entity)) {
|
||||
$entity[$keyval] = $transformed_entity[$key];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->iterateLogs($task, $entity);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function iterateLogs(Task $task, array $entity)
|
||||
@ -164,39 +162,26 @@ class TaskExport extends BaseExport
|
||||
}
|
||||
|
||||
foreach ($logs as $key => $item) {
|
||||
if (in_array('start_date', $this->input['report_keys'])) {
|
||||
if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
|
||||
$entity['start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
|
||||
}
|
||||
|
||||
if (in_array('end_date', $this->input['report_keys']) && $item[1] > 0) {
|
||||
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] > 0) {
|
||||
$entity['end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
|
||||
}
|
||||
|
||||
if (in_array('end_date', $this->input['report_keys']) && $item[1] == 0) {
|
||||
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] == 0) {
|
||||
$entity['end_date'] = ctrans('texts.is_running');
|
||||
}
|
||||
|
||||
if (in_array('duration', $this->input['report_keys'])) {
|
||||
if (in_array('task.duration', $this->input['report_keys']) || in_array('duration', $this->input['report_keys'])) {
|
||||
$entity['duration'] = $task->calcDuration();
|
||||
}
|
||||
|
||||
if (! array_key_exists('duration', $entity)) {
|
||||
$entity['duration'] = '';
|
||||
}
|
||||
|
||||
if (! array_key_exists('start_date', $entity)) {
|
||||
$entity['start_date'] = '';
|
||||
}
|
||||
|
||||
if (! array_key_exists('end_date', $entity)) {
|
||||
$entity['end_date'] = '';
|
||||
}
|
||||
|
||||
|
||||
$entity = $this->decorateAdvancedFields($task, $entity);
|
||||
|
||||
ksort($entity);
|
||||
|
||||
$this->csv->insertOne($entity);
|
||||
|
||||
|
||||
unset($entity['start_date']);
|
||||
unset($entity['end_date']);
|
||||
unset($entity['duration']);
|
||||
@ -213,14 +198,6 @@ class TaskExport extends BaseExport
|
||||
$entity['project'] = $task->project()->exists() ? $task->project->name : '';
|
||||
}
|
||||
|
||||
if (in_array('client_id', $this->input['report_keys'])) {
|
||||
$entity['client'] = $task->client ? $task->client->present()->name() : '';
|
||||
}
|
||||
|
||||
if (in_array('invoice_id', $this->input['report_keys'])) {
|
||||
$entity['invoice'] = $task->invoice ? $task->invoice->number : '';
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
|
171
app/Export/CSV/VendorExport.php
Normal file
171
app/Export/CSV/VendorExport.php
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Export\CSV;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Company;
|
||||
use App\Transformers\VendorContactTransformer;
|
||||
use App\Transformers\VendorTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use League\Csv\Writer;
|
||||
|
||||
class VendorExport extends BaseExport
|
||||
{
|
||||
|
||||
private $vendor_transformer;
|
||||
|
||||
private $contact_transformer;
|
||||
|
||||
public Writer $csv;
|
||||
|
||||
public string $date_key = 'created_at';
|
||||
|
||||
public array $entity_keys = [
|
||||
'address1' => 'vendor.address1',
|
||||
'address2' => 'vendor.address2',
|
||||
'city' => 'vendor.city',
|
||||
'country' => 'vendor.country_id',
|
||||
'custom_value1' => 'vendor.custom_value1',
|
||||
'custom_value2' => 'vendor.custom_value2',
|
||||
'custom_value3' => 'vendor.custom_value3',
|
||||
'custom_value4' => 'vendor.custom_value4',
|
||||
'id_number' => 'vendor.id_number',
|
||||
'name' => 'vendor.name',
|
||||
'number' => 'vendor.number',
|
||||
'phone' => 'vendor.phone',
|
||||
'postal_code' => 'vendor.postal_code',
|
||||
'private_notes' => 'vendor.private_notes',
|
||||
'public_notes' => 'vendor.public_notes',
|
||||
'state' => 'vendor.state',
|
||||
'vat_number' => 'vendor.vat_number',
|
||||
'website' => 'vendor.website',
|
||||
'currency' => 'vendor.currency',
|
||||
'first_name' => 'vendor_contact.first_name',
|
||||
'last_name' => 'vendor_contact.last_name',
|
||||
'contact_phone' => 'vendor_contact.phone',
|
||||
'contact_custom_value1' => 'vendor_contact.custom_value1',
|
||||
'contact_custom_value2' => 'vendor_contact.custom_value2',
|
||||
'contact_custom_value3' => 'vendor_contact.custom_value3',
|
||||
'contact_custom_value4' => 'vendor_contact.custom_value4',
|
||||
'email' => 'vendor_contact.email',
|
||||
'status' => 'vendor.status'
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'vendor.country_id',
|
||||
'vendor.currency',
|
||||
];
|
||||
|
||||
public array $forced_keys = [
|
||||
// 'vendor.status'
|
||||
];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->input = $input;
|
||||
$this->vendor_transformer = new VendorTransformer();
|
||||
$this->contact_transformer = new VendorContactTransformer();
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
App::forgetInstance('translator');
|
||||
App::setLocale($this->company->locale());
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||
|
||||
//load the CSV document from a string
|
||||
$this->csv = Writer::createFromString();
|
||||
|
||||
if (count($this->input['report_keys']) == 0) {
|
||||
$this->input['report_keys'] = array_values($this->entity_keys);
|
||||
}
|
||||
|
||||
//insert the header
|
||||
$this->csv->insertOne($this->buildHeader());
|
||||
|
||||
$query = Vendor::query()->with('contacts')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', 0);
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($vendor) {
|
||||
$this->csv->insertOne($this->buildRow($vendor));
|
||||
});
|
||||
|
||||
return $this->csv->toString();
|
||||
}
|
||||
|
||||
private function buildRow(Vendor $vendor) :array
|
||||
{
|
||||
$transformed_contact = [];
|
||||
|
||||
$transformed_vendor = $this->vendor_transformer->transform($vendor);
|
||||
|
||||
if ($contact = $vendor->contacts()->first()) {
|
||||
$transformed_contact = $this->contact_transformer->transform($contact);
|
||||
}
|
||||
|
||||
$entity = [];
|
||||
|
||||
foreach (array_values($this->input['report_keys']) as $key) {
|
||||
$parts = explode('.', $key);
|
||||
|
||||
$keyval = array_search($key, $this->entity_keys);
|
||||
|
||||
if (is_array($parts) && $parts[0] == 'vendor' && array_key_exists($parts[1], $transformed_vendor)) {
|
||||
$entity[$keyval] = $transformed_vendor[$parts[1]];
|
||||
} elseif (is_array($parts) && $parts[0] == 'vendor_contact' && array_key_exists($parts[1], $transformed_contact)) {
|
||||
$entity[$keyval] = $transformed_contact[$parts[1]];
|
||||
} else {
|
||||
$entity[$keyval] = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->decorateAdvancedFields($vendor, $entity);
|
||||
}
|
||||
|
||||
private function decorateAdvancedFields(Vendor $vendor, array $entity) :array
|
||||
{
|
||||
if (in_array('vendor.country_id', $this->input['report_keys'])) {
|
||||
$entity['country'] = $vendor->country ? ctrans("texts.country_{$vendor->country->name}") : '';
|
||||
}
|
||||
|
||||
if (in_array('vendor.currency', $this->input['report_keys'])) {
|
||||
$entity['currency'] = $vendor->currency() ? $vendor->currency()->code : $vendor->company->currency()->code;
|
||||
}
|
||||
|
||||
$entity['status'] = $this->calculateStatus($vendor);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
private function calculateStatus($vendor)
|
||||
{
|
||||
if ($vendor->is_deleted) {
|
||||
return ctrans('texts.deleted');
|
||||
}
|
||||
|
||||
if ($vendor->deleted_at) {
|
||||
return ctrans('texts.archived');
|
||||
}
|
||||
|
||||
return ctrans('texts.active');
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ class CreditFactory
|
||||
$credit->user_id = $user_id;
|
||||
$credit->company_id = $company_id;
|
||||
$credit->recurring_id = null;
|
||||
|
||||
$credit->exchange_rate = 1;
|
||||
return $credit;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class ExpenseFactory
|
||||
$expense->tax_rate2 = 0;
|
||||
$expense->tax_name3 = '';
|
||||
$expense->tax_rate3 = 0;
|
||||
$expense->date = null;
|
||||
$expense->date = now()->format('Y-m-d');
|
||||
$expense->payment_date = null;
|
||||
$expense->amount = 0;
|
||||
$expense->foreign_amount = 0;
|
||||
|
@ -49,7 +49,8 @@ class PurchaseOrderFactory
|
||||
$purchase_order->user_id = $user_id;
|
||||
$purchase_order->company_id = $company_id;
|
||||
$purchase_order->recurring_id = null;
|
||||
|
||||
$purchase_order->exchange_rate = 1;
|
||||
|
||||
return $purchase_order;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ class QuoteFactory
|
||||
$quote->user_id = $user_id;
|
||||
$quote->company_id = $company_id;
|
||||
$quote->paid_to_date = 0;
|
||||
$quote->exchange_rate = 1;
|
||||
|
||||
return $quote;
|
||||
}
|
||||
|
@ -40,16 +40,13 @@ class RecurringExpenseToExpenseFactory
|
||||
$expense->tax_name3 = $recurring_expense->tax_name3;
|
||||
$expense->tax_rate3 = $recurring_expense->tax_rate3;
|
||||
$expense->date = now()->format('Y-m-d');
|
||||
$expense->payment_date = $recurring_expense->payment_date ?: now()->format('Y-m-d');
|
||||
// $expense->payment_date = $recurring_expense->payment_date ?: now()->format('Y-m-d');
|
||||
$expense->amount = $recurring_expense->amount;
|
||||
$expense->foreign_amount = $recurring_expense->foreign_amount ?: 0;
|
||||
|
||||
//11-09-2022 - we should be tracking the recurring expense!!
|
||||
$expense->recurring_expense_id = $recurring_expense->id;
|
||||
|
||||
// $expense->private_notes = $recurring_expense->private_notes;
|
||||
// $expense->public_notes = $recurring_expense->public_notes;
|
||||
|
||||
$expense->public_notes = self::transformObject($recurring_expense->public_notes, $recurring_expense);
|
||||
$expense->private_notes = self::transformObject($recurring_expense->private_notes, $recurring_expense);
|
||||
|
||||
@ -58,7 +55,7 @@ class RecurringExpenseToExpenseFactory
|
||||
$expense->custom_value2 = $recurring_expense->custom_value2;
|
||||
$expense->custom_value3 = $recurring_expense->custom_value3;
|
||||
$expense->custom_value4 = $recurring_expense->custom_value4;
|
||||
$expense->transaction_id = $recurring_expense->transaction_id;
|
||||
$expense->transaction_id = null;
|
||||
$expense->category_id = $recurring_expense->category_id;
|
||||
$expense->payment_type_id = $recurring_expense->payment_type_id;
|
||||
$expense->project_id = $recurring_expense->project_id;
|
||||
|
@ -37,7 +37,7 @@ class BankTransactionFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -118,7 +118,7 @@ class BankTransactionFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
@ -151,7 +151,7 @@ class BankTransactionFilters extends QueryFilters
|
||||
/**
|
||||
* Filters the query by the users company ID.
|
||||
*
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function entityFilter()
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ class BankTransactionRuleFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -54,7 +54,7 @@ class BankTransactionRuleFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
@ -71,7 +71,7 @@ class BankTransactionRuleFilters extends QueryFilters
|
||||
/**
|
||||
* Filters the query by the users company ID.
|
||||
*
|
||||
* @return Illuminate\Database\Query\Builder
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function entityFilter()
|
||||
{
|
||||
|
@ -32,11 +32,13 @@ class ExpenseFilters extends QueryFilters
|
||||
}
|
||||
|
||||
return $this->builder->where(function ($query) use ($filter) {
|
||||
$query->where('public_notes', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value1', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value2', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value3', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value4', 'like', '%'.$filter.'%');
|
||||
$query->where('number', 'like', '%'.$filter.'%')
|
||||
->orWhere('amount', 'like', '%'.$filter.'%')
|
||||
->orWhere('public_notes', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value1', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value2', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value3', 'like', '%'.$filter.'%')
|
||||
->orWhere('custom_value4', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
@ -164,6 +166,17 @@ class ExpenseFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'client_id') {
|
||||
return $this->builder->orderBy(\App\Models\Client::select('name')
|
||||
->whereColumn('clients.id', 'expenses.client_id'), $sort_col[1]);
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'vendor_id') {
|
||||
return $this->builder->orderBy(\App\Models\Vendor::select('name')
|
||||
->whereColumn('vendors.id', 'expenses.vendor_id'), $sort_col[1]);
|
||||
}
|
||||
|
||||
|
||||
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'])) {
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
@ -55,6 +55,10 @@ class InvoiceFilters extends QueryFilters
|
||||
$this->builder->where(function ($query) use ($status_parameters) {
|
||||
$invoice_filters = [];
|
||||
|
||||
if (in_array('draft', $status_parameters)) {
|
||||
$invoice_filters[] = Invoice::STATUS_DRAFT;
|
||||
}
|
||||
|
||||
if (in_array('paid', $status_parameters)) {
|
||||
$invoice_filters[] = Invoice::STATUS_PAID;
|
||||
}
|
||||
@ -131,19 +135,6 @@ class InvoiceFilters extends QueryFilters
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function without_deleted_clients(): Builder
|
||||
{
|
||||
return $this->builder->whereHas('client', function ($query) {
|
||||
$query->where('is_deleted', 0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
* @return Builder
|
||||
@ -192,6 +183,48 @@ class InvoiceFilters extends QueryFilters
|
||||
->where('client_id', $this->decodePrimaryKey($client_id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
* @return Builder
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function date(string $date = ''): Builder
|
||||
{
|
||||
if (strlen($date) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if (is_numeric($date)) {
|
||||
$date = Carbon::createFromTimestamp((int)$date);
|
||||
} else {
|
||||
$date = Carbon::parse($date);
|
||||
}
|
||||
|
||||
return $this->builder->where('date', '>=', $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
* @return Builder
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function due_date(string $date = ''): Builder
|
||||
{
|
||||
if (strlen($date) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if (is_numeric($date)) {
|
||||
$date = Carbon::createFromTimestamp((int)$date);
|
||||
} else {
|
||||
$date = Carbon::parse($date);
|
||||
}
|
||||
|
||||
return $this->builder->where('due_date', '>=', $date);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
|
@ -120,6 +120,7 @@ class PaymentFilters extends QueryFilters
|
||||
*/
|
||||
public function match_transactions($value = 'true'): Builder
|
||||
{
|
||||
|
||||
if ($value == 'true') {
|
||||
return $this->builder
|
||||
->where('is_deleted', 0)
|
||||
|
@ -21,7 +21,7 @@ class PaymentTermFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -39,7 +39,7 @@ class PaymentTermFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -123,6 +123,11 @@ class PurchaseOrderFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'vendor_id') {
|
||||
return $this->builder->orderBy(\App\Models\Vendor::select('name')
|
||||
->whereColumn('vendors.id', 'purchase_orders.vendor_id'), $sort_col[1]);
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
//use Illuminate\Database\Query\Builder;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
@ -288,6 +287,31 @@ abstract class QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function without_deleted_clients(): Builder
|
||||
{
|
||||
return $this->builder->where(function ($query) {
|
||||
$query->whereHas('client', function ($sub_query) {
|
||||
$sub_query->where('is_deleted', 0);
|
||||
})->orWhere('client_id', null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function without_deleted_vendors(): Builder
|
||||
{
|
||||
return $this->builder->where(function ($query) {
|
||||
$query->whereHas('vendor', function ($sub_query) {
|
||||
$sub_query->where('is_deleted', 0);
|
||||
})->orWhere('vendor_id', null);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function with(string $value = ''): Builder
|
||||
{
|
||||
if (strlen($value) == 0) {
|
||||
|
@ -22,7 +22,7 @@ class QuoteFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -53,7 +53,7 @@ class QuoteFilters extends QueryFilters
|
||||
* - paused
|
||||
* - completed
|
||||
*
|
||||
* @param string client_status The invoice status as seen by the client
|
||||
* @param string $value The invoice status as seen by the client
|
||||
* @return Builder
|
||||
*/
|
||||
public function client_status(string $value = ''): Builder
|
||||
@ -124,7 +124,7 @@ class QuoteFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
@ -152,7 +152,7 @@ class QuoteFilters extends QueryFilters
|
||||
/**
|
||||
* Filters the query by the users company ID.
|
||||
*
|
||||
* @return Illuminate\Eloquent\Query\Builder
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function entityFilter(): Builder
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ class RecurringExpenseFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -52,7 +52,7 @@ class RecurringExpenseFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
@ -69,7 +69,7 @@ class RecurringExpenseFilters extends QueryFilters
|
||||
/**
|
||||
* Filters the query by the users company ID.
|
||||
*
|
||||
* @return Illuminate\Eloquent\Builder
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function entityFilter(): Builder
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ class SubscriptionFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -39,7 +39,7 @@ class SubscriptionFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -48,7 +48,7 @@ class SystemLogFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -64,7 +64,7 @@ class SystemLogFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -24,7 +24,7 @@ class TaskFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -56,7 +56,7 @@ class TaskFilters extends QueryFilters
|
||||
* - all
|
||||
* - invoiced
|
||||
*
|
||||
* @param string client_status The invoice status as seen by the client
|
||||
* @param string $value The invoice status as seen by the client
|
||||
* @return Builder
|
||||
*/
|
||||
public function client_status(string $value = ''): Builder
|
||||
@ -99,7 +99,7 @@ class TaskFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
@ -123,6 +123,21 @@ class TaskFilters extends QueryFilters
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
}
|
||||
|
||||
public function task_status(string $value = ''): Builder
|
||||
{
|
||||
if (strlen($value) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
$status_parameters = explode(',', $value);
|
||||
|
||||
if(count($status_parameters) >= 1)
|
||||
$this->builder->whereIn('status_id', $this->transformKeys($status_parameters));
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filters the query by the users company ID.
|
||||
*
|
||||
|
@ -21,7 +21,7 @@ class TaskStatusFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -39,7 +39,7 @@ class TaskStatusFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -21,7 +21,7 @@ class TaxRateFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -39,7 +39,7 @@ class TaxRateFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -21,7 +21,7 @@ class TokenFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -36,10 +36,16 @@ class TokenFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function is_system(string $value = 'false'): Builder
|
||||
{
|
||||
return $this->builder->where('is_system', $value == 'false' ? false : true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -21,7 +21,7 @@ class UserFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -43,7 +43,7 @@ class UserFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
@ -69,6 +69,19 @@ class UserFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters users that have been removed from the
|
||||
* company, but not deleted from the system.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hideRemovedUsers()
|
||||
{
|
||||
return $this->builder->whereHas('company_users', function ($q) {
|
||||
$q->where('company_id', '=', auth()->user()->company()->id)->whereNull('deleted_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the base with() function as no company ID
|
||||
* exists on the user table
|
||||
|
@ -21,7 +21,7 @@ class VendorFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -58,7 +58,7 @@ class VendorFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -21,7 +21,7 @@ class WebhookFilters extends QueryFilters
|
||||
/**
|
||||
* Filter based on search text.
|
||||
*
|
||||
* @param string query filter
|
||||
* @param string $filter
|
||||
* @return Builder
|
||||
* @deprecated
|
||||
*/
|
||||
@ -39,7 +39,7 @@ class WebhookFilters extends QueryFilters
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
* @param string sort formatted as column|asc
|
||||
* @param string $sort formatted as column|asc
|
||||
* @return Builder
|
||||
*/
|
||||
public function sort(string $sort = ''): Builder
|
||||
|
@ -81,6 +81,19 @@ class AccountTransformer implements AccountTransformerInterface
|
||||
|
||||
public function transformAccount($account)
|
||||
{
|
||||
$current_balance = 0;
|
||||
$account_currency = '';
|
||||
|
||||
if(property_exists($account, 'currentBalance')) {
|
||||
$current_balance = $account->currentBalance->amount ?? 0;
|
||||
$account_currency = $account->currentBalance->currency ?? '';
|
||||
}
|
||||
elseif(property_exists($account, 'balance')){
|
||||
$current_balance = $account->balance->amount ?? 0;
|
||||
$account_currency = $account->balance->currency ?? '';
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
'id' => $account->id,
|
||||
'account_type' => $account->CONTAINER,
|
||||
@ -92,8 +105,8 @@ class AccountTransformer implements AccountTransformerInterface
|
||||
'provider_id' => $account->providerId,
|
||||
'provider_name' => $account->providerName,
|
||||
'nickname' => property_exists($account, 'nickname') ? $account->nickname : '',
|
||||
'current_balance' => property_exists($account, 'currentBalance') ? $account->currentBalance->amount : 0,
|
||||
'account_currency' => property_exists($account, 'currency') ? $account->currentBalance->currency : '',
|
||||
'current_balance' => $current_balance,
|
||||
'account_currency' => $account_currency,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -185,6 +185,21 @@ class Yodlee
|
||||
}
|
||||
}
|
||||
|
||||
public function getAccountSummary($account_id)
|
||||
{
|
||||
$token = $this->getAccessToken();
|
||||
|
||||
$response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/accounts/{$account_id}", []);
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->object();
|
||||
}
|
||||
|
||||
if ($response->failed()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteAccount($account_id)
|
||||
{
|
||||
$token = $this->getAccessToken();
|
||||
|
@ -19,7 +19,7 @@ use Illuminate\View\View;
|
||||
*
|
||||
* @param $page
|
||||
* @param bool $boolean
|
||||
* @return bool
|
||||
* @return bool | string
|
||||
*/
|
||||
function isActive($page, bool $boolean = false)
|
||||
{
|
||||
@ -40,8 +40,6 @@ function isActive($page, bool $boolean = false)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -53,9 +53,8 @@ class EpcQrGenerator
|
||||
$qr = $writer->writeString($this->encodeMessage(), 'utf-8');
|
||||
} catch(\Throwable $e) {
|
||||
return '';
|
||||
} catch(\Exception $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return "<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>
|
||||
<rect x='0' y='0' width='100%'' height='100%' />{$qr}</svg>";
|
||||
}
|
||||
|
@ -238,14 +238,20 @@ class InvoiceItemSum
|
||||
{
|
||||
$this->rule->tax($this->item);
|
||||
|
||||
$precision = strlen(substr(strrchr($this->rule->tax_rate1, "."), 1));
|
||||
|
||||
$this->item->tax_name1 = $this->rule->tax_name1;
|
||||
$this->item->tax_rate1 = $this->rule->tax_rate1;
|
||||
$this->item->tax_rate1 = round($this->rule->tax_rate1, $precision);
|
||||
|
||||
$precision = strlen(substr(strrchr($this->rule->tax_rate2, "."), 1));
|
||||
|
||||
$this->item->tax_name2 = $this->rule->tax_name2;
|
||||
$this->item->tax_rate2 = $this->rule->tax_rate2;
|
||||
$this->item->tax_rate2 = round($this->rule->tax_rate2, $precision);
|
||||
|
||||
$precision = strlen(substr(strrchr($this->rule->tax_rate3, "."), 1));
|
||||
|
||||
$this->item->tax_name3 = $this->rule->tax_name3;
|
||||
$this->item->tax_rate3 = $this->rule->tax_rate3;
|
||||
$this->item->tax_rate3 = round($this->rule->tax_rate3, $precision);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -12,11 +12,13 @@
|
||||
namespace App\Helpers\Invoice;
|
||||
|
||||
use App\Models\Quote;
|
||||
use App\Models\Client;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\RecurringQuote;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\DataMapper\Tax\RuleInterface;
|
||||
use App\Utils\Traits\NumberFormatter;
|
||||
|
||||
class InvoiceItemSumInclusive
|
||||
@ -25,6 +27,71 @@ class InvoiceItemSumInclusive
|
||||
use Discounter;
|
||||
use Taxer;
|
||||
|
||||
|
||||
private array $eu_tax_jurisdictions = [
|
||||
'AT', // Austria
|
||||
'BE', // Belgium
|
||||
'BG', // Bulgaria
|
||||
'CY', // Cyprus
|
||||
'CZ', // Czech Republic
|
||||
'DE', // Germany
|
||||
'DK', // Denmark
|
||||
'EE', // Estonia
|
||||
'ES', // Spain
|
||||
'FI', // Finland
|
||||
'FR', // France
|
||||
'GR', // Greece
|
||||
'HR', // Croatia
|
||||
'HU', // Hungary
|
||||
'IE', // Ireland
|
||||
'IT', // Italy
|
||||
'LT', // Lithuania
|
||||
'LU', // Luxembourg
|
||||
'LV', // Latvia
|
||||
'MT', // Malta
|
||||
'NL', // Netherlands
|
||||
'PL', // Poland
|
||||
'PT', // Portugal
|
||||
'RO', // Romania
|
||||
'SE', // Sweden
|
||||
'SI', // Slovenia
|
||||
'SK', // Slovakia
|
||||
];
|
||||
|
||||
private array $tax_jurisdictions = [
|
||||
'AT', // Austria
|
||||
'BE', // Belgium
|
||||
'BG', // Bulgaria
|
||||
'CY', // Cyprus
|
||||
'CZ', // Czech Republic
|
||||
'DE', // Germany
|
||||
'DK', // Denmark
|
||||
'EE', // Estonia
|
||||
'ES', // Spain
|
||||
'FI', // Finland
|
||||
'FR', // France
|
||||
'GR', // Greece
|
||||
'HR', // Croatia
|
||||
'HU', // Hungary
|
||||
'IE', // Ireland
|
||||
'IT', // Italy
|
||||
'LT', // Lithuania
|
||||
'LU', // Luxembourg
|
||||
'LV', // Latvia
|
||||
'MT', // Malta
|
||||
'NL', // Netherlands
|
||||
'PL', // Poland
|
||||
'PT', // Portugal
|
||||
'RO', // Romania
|
||||
'SE', // Sweden
|
||||
'SI', // Slovenia
|
||||
'SK', // Slovakia
|
||||
|
||||
'US', // USA
|
||||
|
||||
'AU', // Australia
|
||||
];
|
||||
|
||||
protected RecurringInvoice | Invoice | Quote | Credit | PurchaseOrder | RecurringQuote $invoice;
|
||||
|
||||
private $currency;
|
||||
@ -39,6 +106,12 @@ class InvoiceItemSumInclusive
|
||||
|
||||
private $tax_collection;
|
||||
|
||||
private bool $calc_tax = false;
|
||||
|
||||
private ?Client $client;
|
||||
|
||||
private RuleInterface $rule;
|
||||
|
||||
public function __construct(RecurringInvoice | Invoice | Quote | Credit | PurchaseOrder | RecurringQuote $invoice)
|
||||
{
|
||||
$this->tax_collection = collect([]);
|
||||
@ -47,6 +120,8 @@ class InvoiceItemSumInclusive
|
||||
|
||||
if ($this->invoice->client) {
|
||||
$this->currency = $this->invoice->client->currency();
|
||||
$this->client = $this->invoice->client;
|
||||
$this->shouldCalculateTax();
|
||||
} else {
|
||||
$this->currency = $this->invoice->vendor->currency();
|
||||
}
|
||||
@ -107,12 +182,46 @@ class InvoiceItemSumInclusive
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to calculate taxes based on the clients location
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
private function calcTaxesAutomatically(): self
|
||||
{
|
||||
$this->rule->tax($this->item);
|
||||
|
||||
$precision = strlen(substr(strrchr($this->rule->tax_rate1, "."), 1));
|
||||
|
||||
$this->item->tax_name1 = $this->rule->tax_name1;
|
||||
$this->item->tax_rate1 = round($this->rule->tax_rate1, $precision);
|
||||
|
||||
$precision = strlen(substr(strrchr($this->rule->tax_rate2, "."), 1));
|
||||
|
||||
$this->item->tax_name2 = $this->rule->tax_name2;
|
||||
$this->item->tax_rate2 = round($this->rule->tax_rate2, $precision);
|
||||
|
||||
$precision = strlen(substr(strrchr($this->rule->tax_rate3, "."), 1));
|
||||
|
||||
$this->item->tax_name3 = $this->rule->tax_name3;
|
||||
$this->item->tax_rate3 = round($this->rule->tax_rate3, $precision);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Taxes effect the line totals and item costs. we decrement both on
|
||||
* application of inclusive tax rates.
|
||||
*/
|
||||
private function calcTaxes()
|
||||
{
|
||||
|
||||
if ($this->calc_tax) {
|
||||
$this->calcTaxesAutomatically();
|
||||
}
|
||||
|
||||
$item_tax = 0;
|
||||
|
||||
$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / 100));
|
||||
@ -121,7 +230,6 @@ class InvoiceItemSumInclusive
|
||||
|
||||
$item_tax += $this->formatValue($item_tax_rate1_total, $this->currency->precision);
|
||||
|
||||
// if($item_tax_rate1_total != 0)
|
||||
if (strlen($this->item->tax_name1) > 1) {
|
||||
$this->groupTax($this->item->tax_name1, $this->item->tax_rate1, $item_tax_rate1_total);
|
||||
}
|
||||
@ -275,4 +383,36 @@ class InvoiceItemSumInclusive
|
||||
|
||||
$this->setTotalTaxes($item_tax);
|
||||
}
|
||||
|
||||
|
||||
private function shouldCalculateTax(): self
|
||||
{
|
||||
|
||||
if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {
|
||||
$this->calc_tax = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (in_array($this->client->company->country()->iso_3166_2, $this->tax_jurisdictions) ) { //only calculate for supported tax jurisdictions
|
||||
|
||||
$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;
|
||||
|
||||
$this->rule
|
||||
->setEntity($this->invoice)
|
||||
->init();
|
||||
|
||||
$this->calc_tax = $this->rule->shouldCalcTax();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ class ProRata
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var \App\Models\RecurringInvoice $recurring_invoice **/
|
||||
$recurring_invoice = RecurringInvoice::find($invoice->recurring_id)->first();
|
||||
|
||||
if (! $recurring_invoice) {
|
||||
@ -110,13 +111,13 @@ class ProRata
|
||||
case RecurringInvoice::FREQUENCY_MONTHLY:
|
||||
return now()->diffInDays(now()->addMonthNoOverflow());
|
||||
case RecurringInvoice::FREQUENCY_TWO_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthNoOverflow(2));
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(2));
|
||||
case RecurringInvoice::FREQUENCY_THREE_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthNoOverflow(3));
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(3));
|
||||
case RecurringInvoice::FREQUENCY_FOUR_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthNoOverflow(4));
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(4));
|
||||
case RecurringInvoice::FREQUENCY_SIX_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthNoOverflow(6));
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(6));
|
||||
case RecurringInvoice::FREQUENCY_ANNUALLY:
|
||||
return now()->diffInDays(now()->addYear());
|
||||
case RecurringInvoice::FREQUENCY_TWO_YEARS:
|
||||
|
@ -64,6 +64,7 @@ class SubscriptionCalculator
|
||||
}
|
||||
|
||||
if ($refund_invoice) {
|
||||
/** @var \App\Models\Subscription $subscription **/
|
||||
$subscription = Subscription::find($this->invoice->subscription_id);
|
||||
$pro_rata = new ProRata;
|
||||
|
||||
|
@ -11,24 +11,23 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
|
||||
use App\Models\Activity;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Utils\HostedPDF\NinjaPdf;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\Pdf\PageNumbering;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use stdClass;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Activity;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\HostedPDF\NinjaPdf;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use App\Utils\Traits\Pdf\PageNumbering;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Http\Requests\Activity\ShowActivityRequest;
|
||||
use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
|
||||
|
||||
class ActivityController extends BaseController
|
||||
{
|
||||
use PdfMaker, PageNumbering;
|
||||
use PdfMaker, PageNumbering, MakesHash;
|
||||
|
||||
protected $entity_type = Activity::class;
|
||||
|
||||
@ -39,50 +38,6 @@ class ActivityController extends BaseController
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/activities",
|
||||
* operationId="getActivities",
|
||||
* tags={"actvities"},
|
||||
* summary="Gets a list of actvities",
|
||||
* description="Lists all activities",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||
* @OA\Parameter(
|
||||
* name="rows",
|
||||
* in="query",
|
||||
* description="The number of activities to return",
|
||||
* example="50",
|
||||
* required=false,
|
||||
* @OA\Schema(
|
||||
* type="number",
|
||||
* format="integer",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="A list of actvities",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/Activity"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
* @param Request $request
|
||||
* @return Response|mixed
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$default_activities = $request->has('rows') ? $request->input('rows') : 75;
|
||||
@ -91,47 +46,7 @@ class ActivityController extends BaseController
|
||||
->orderBy('created_at', 'DESC')
|
||||
->company()
|
||||
->take($default_activities);
|
||||
|
||||
// if ($request->has('react')) {
|
||||
|
||||
// /** @var \App\Models\User auth()->user() */
|
||||
// $user = auth()->user();
|
||||
|
||||
// if (!$user->isAdmin()) {
|
||||
// $activities->where('user_id', auth()->user()->id);
|
||||
// }
|
||||
|
||||
// $system = ctrans('texts.system');
|
||||
|
||||
// $data = $activities->cursor()->map(function ($activity) {
|
||||
|
||||
// $arr =
|
||||
// [
|
||||
// 'client' => $activity->client ? $activity->client : '',
|
||||
// 'contact' => $activity->client ? $activity->contact : '',
|
||||
// 'quote' => $activity->quote ? $activity->quote : '',
|
||||
// 'user' => $activity->user ? $activity->user : '',
|
||||
// 'expense' => $activity->expense ? $activity->expense : '',
|
||||
// 'invoice' => $activity->invoice ? $activity->invoice : '',
|
||||
// 'recurring_invoice' => $activity->recurring_invoice ? $activity->recurring_invoice : '',
|
||||
// 'payment' => $activity->payment ? $activity->payment : '',
|
||||
// 'credit' => $activity->credit ? $activity->credit : '',
|
||||
// 'task' => $activity->task ? $activity->task : '',
|
||||
// 'vendor' => $activity->vendor ? $activity->vendor : '',
|
||||
// 'purchase_order' => $activity->purchase_order ? $activity->purchase_order : '',
|
||||
// 'subscription' => $activity->subscription ? $activity->subscription : '',
|
||||
// 'vendor_contact' => $activity->vendor_contact ? $activity->vendor_contact : '',
|
||||
// 'recurring_expense' => $activity->recurring_expense ? $activity->recurring_expense : '',
|
||||
// ];
|
||||
|
||||
// $activity_array = $activity->toArray();
|
||||
|
||||
// return array_merge($arr, $activity_array);
|
||||
// });
|
||||
|
||||
// return response()->json(['data' => $data->toArray()], 200);
|
||||
// }
|
||||
// else
|
||||
|
||||
if($request->has('reactv2')) {
|
||||
|
||||
/** @var \App\Models\User auth()->user() */
|
||||
@ -143,7 +58,7 @@ class ActivityController extends BaseController
|
||||
|
||||
$system = ctrans('texts.system');
|
||||
|
||||
$data = $activities->cursor()->map(function ($activity) use ($system) {
|
||||
$data = $activities->cursor()->map(function ($activity) {
|
||||
|
||||
return $activity->activity_string();
|
||||
|
||||
@ -155,47 +70,36 @@ class ActivityController extends BaseController
|
||||
return $this->listResponse($activities);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/api/v1/actvities/download_entity/{activity_id}",
|
||||
* operationId="getActivityHistoricalEntityPdf",
|
||||
* tags={"actvities"},
|
||||
* summary="Gets a PDF for the given activity",
|
||||
* description="Gets a PDF for the given activity",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(
|
||||
* name="activity_id",
|
||||
* in="path",
|
||||
* description="The Activity Hashed ID",
|
||||
* example="D2J234DFA",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* format="string",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="PDF File",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=404,
|
||||
* description="No file exists for the given record",
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
* @param DownloadHistoricalEntityRequest $request
|
||||
* @param Activity $activity
|
||||
* @return JsonResponse|StreamedResponse
|
||||
*/
|
||||
public function entityActivity(ShowActivityRequest $request)
|
||||
{
|
||||
|
||||
$default_activities = request()->has('rows') ? request()->input('rows') : 75;
|
||||
|
||||
$activities = Activity::with('user')
|
||||
->orderBy('created_at', 'DESC')
|
||||
->company()
|
||||
->where("{$request->entity}_id", $request->entity_id)
|
||||
->take($default_activities);
|
||||
|
||||
/** @var \App\Models\User auth()->user() */
|
||||
$user = auth()->user();
|
||||
|
||||
if (!$user->isAdmin()) {
|
||||
$activities->where('user_id', auth()->user()->id);
|
||||
}
|
||||
|
||||
$system = ctrans('texts.system');
|
||||
|
||||
$data = $activities->cursor()->map(function ($activity) {
|
||||
|
||||
return $activity->activity_string();
|
||||
|
||||
});
|
||||
|
||||
return response()->json(['data' => $data->toArray()], 200);
|
||||
|
||||
}
|
||||
|
||||
public function downloadHistoricalEntity(DownloadHistoricalEntityRequest $request, Activity $activity)
|
||||
{
|
||||
$backup = $activity->backup;
|
||||
@ -244,6 +148,8 @@ class ActivityController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
$activity->company->setLocale();
|
||||
|
||||
if (isset($activity->invoice_id)) {
|
||||
$filename = $activity->invoice->numberFormatter().'.pdf';
|
||||
} elseif (isset($activity->quote_id)) {
|
||||
|
@ -62,11 +62,15 @@ class ContactForgotPasswordController extends Controller
|
||||
|
||||
if (Ninja::isHosted() && $request->session()->has('company_key')) {
|
||||
MultiDB::findAndSetDbByCompanyKey($request->session()->get('company_key'));
|
||||
|
||||
/** @var \App\Models\Company $company **/
|
||||
$company = Company::where('company_key', $request->session()->get('company_key'))->first();
|
||||
$account = $company->account;
|
||||
}
|
||||
|
||||
if (! $account) {
|
||||
|
||||
/** @var \App\Models\Account $account **/
|
||||
$account = Account::first();
|
||||
$company = $account->companies->first();
|
||||
}
|
||||
@ -97,7 +101,11 @@ class ContactForgotPasswordController extends Controller
|
||||
|
||||
$this->validateEmail($request);
|
||||
|
||||
|
||||
if (Ninja::isHosted() && $company = Company::where('company_key', $request->input('company_key'))->first()) {
|
||||
/** @var \App\Models\Company $company **/
|
||||
|
||||
/** @var \App\Models\ClientContact $contact **/
|
||||
$contact = ClientContact::where(['email' => $request->input('email'), 'company_id' => $company->id])
|
||||
->whereHas('client', function ($query) {
|
||||
$query->where('is_deleted', 0);
|
||||
|
@ -52,6 +52,7 @@ class ContactLoginController extends Controller
|
||||
$company = Company::where('company_key', $company_key)->first();
|
||||
}
|
||||
|
||||
/** @var \App\Models\Company $company **/
|
||||
if ($company) {
|
||||
$account = $company->account;
|
||||
} elseif (! $company && strpos($request->getHost(), 'invoicing.co') !== false) {
|
||||
@ -63,6 +64,7 @@ class ContactLoginController extends Controller
|
||||
|
||||
$company = Company::where('portal_domain', $request->getSchemeAndHttpHost())->first();
|
||||
} elseif (Ninja::isSelfHost()) {
|
||||
/** @var \App\Models\Account $account **/
|
||||
$account = Account::first();
|
||||
$company = $account->default_company;
|
||||
} else {
|
||||
@ -97,6 +99,7 @@ class ContactLoginController extends Controller
|
||||
}
|
||||
|
||||
if (Ninja::isHosted() && $request->has('password') && $company = Company::where('company_key', $request->input('company_key'))->first()) {
|
||||
/** @var \App\Models\Company $company **/
|
||||
$contact = ClientContact::where(['email' => $request->input('email'), 'company_id' => $company->id])
|
||||
->whereHas('client', function ($query) {
|
||||
$query->where('is_deleted', 0);
|
||||
|
@ -39,7 +39,8 @@ class ContactRegisterController extends Controller
|
||||
} else {
|
||||
$key = request()->session()->has('company_key') ? request()->session()->get('company_key') : $company_key;
|
||||
}
|
||||
|
||||
|
||||
/** @var \App\Models\Company $company **/
|
||||
$company = Company::where('company_key', $key)->firstOrFail();
|
||||
|
||||
App::forgetInstance('translator');
|
||||
|
@ -71,6 +71,8 @@ class ContactResetPasswordController extends Controller
|
||||
{
|
||||
if ($request->session()->has('company_key')) {
|
||||
MultiDB::findAndSetDbByCompanyKey($request->session()->get('company_key'));
|
||||
|
||||
/** @var \App\Models\Company $company **/
|
||||
$company = Company::where('company_key', $request->session()->get('company_key'))->first();
|
||||
$db = $company->db;
|
||||
$account = $company->account;
|
||||
@ -79,10 +81,12 @@ class ContactResetPasswordController extends Controller
|
||||
|
||||
if ($account_key) {
|
||||
MultiDB::findAndSetDbByAccountKey($account_key);
|
||||
/** @var \App\Models\Account $account **/
|
||||
$account = Account::where('key', $account_key)->first();
|
||||
$db = $account->companies->first()->db;
|
||||
$company = $account->companies->first();
|
||||
} else {
|
||||
/** @var \App\Models\Account $account **/
|
||||
$account = Account::first();
|
||||
$db = $account->companies->first()->db;
|
||||
$company = $account->companies->first();
|
||||
|
@ -82,6 +82,7 @@ class ForgotPasswordController extends Controller
|
||||
{
|
||||
if ($request->has('company_key')) {
|
||||
MultiDB::findAndSetDbByCompanyKey($request->input('company_key'));
|
||||
/** @var \App\Models\Company $company **/
|
||||
$company = Company::where('company_key', $request->input('company_key'))->first();
|
||||
$account = $company->account;
|
||||
} else {
|
||||
|
@ -60,6 +60,7 @@ class ResetPasswordController extends Controller
|
||||
|
||||
if (Ninja::isHosted()) {
|
||||
MultiDB::findAndSetDbByCompanyKey($request->session()->get('company_key'));
|
||||
/** @var \App\Models\Company $company **/
|
||||
$company = Company::where('company_key', $request->session()->get('company_key'))->first();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use App\Models\BankIntegration;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@ -50,7 +51,7 @@ class BankIntegrationController extends BaseController
|
||||
|
||||
/**
|
||||
* @param BankIntegrationFilters $filters
|
||||
* @return Responsec
|
||||
* @return Response
|
||||
*/
|
||||
public function index(BankIntegrationFilters $filters)
|
||||
{
|
||||
@ -209,7 +210,12 @@ class BankIntegrationController extends BaseController
|
||||
$accounts = $yodlee->getAccounts();
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
if (!BankIntegration::withTrashed()->where('bank_account_id', $account['id'])->where('company_id', $user->company()->id)->exists()) {
|
||||
if ($bi = BankIntegration::withTrashed()->where('bank_account_id', $account['id'])->where('company_id', $user->company()->id)->first()){
|
||||
$bi->balance = $account['current_balance'];
|
||||
$bi->currency = $account['account_currency'];
|
||||
$bi->save();
|
||||
}
|
||||
else {
|
||||
$bank_integration = new BankIntegration();
|
||||
$bank_integration->company_id = $user->company()->id;
|
||||
$bank_integration->account_id = $user->account_id;
|
||||
@ -245,7 +251,7 @@ class BankIntegrationController extends BaseController
|
||||
* Return the remote list of accounts stored on the third party provider
|
||||
* and update our local cache.
|
||||
*
|
||||
* @return Response
|
||||
* @return Response | JsonResponse
|
||||
*
|
||||
*/
|
||||
|
||||
|
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