mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #4491 from turbo124/v5-develop
Working on Import / Export 64b9f94
This commit is contained in:
commit
98130f2105
@ -173,7 +173,6 @@ class EmailTemplateDefaults
|
|||||||
|
|
||||||
public static function emailReminder1Subject()
|
public static function emailReminder1Subject()
|
||||||
{
|
{
|
||||||
info("reminder 1 subject");
|
|
||||||
return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']);
|
return ctrans('texts.reminder_subject', ['invoice'=>'$invoice.number', 'account'=>'$company.name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Events\Product;
|
namespace App\Events\Product;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ class Handler extends ExceptionHandler
|
|||||||
*/
|
*/
|
||||||
public function report(Throwable $exception)
|
public function report(Throwable $exception)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! Schema::hasTable('accounts')) {
|
if (! Schema::hasTable('accounts')) {
|
||||||
info('account table not found');
|
info('account table not found');
|
||||||
return;
|
return;
|
||||||
@ -90,8 +91,6 @@ class Handler extends ExceptionHandler
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// app('sentry')->setRelease(config('ninja.app_version'));
|
|
||||||
|
|
||||||
if($this->validException($exception))
|
if($this->validException($exception))
|
||||||
app('sentry')->captureException($exception);
|
app('sentry')->captureException($exception);
|
||||||
}
|
}
|
||||||
@ -102,15 +101,14 @@ class Handler extends ExceptionHandler
|
|||||||
private function validException($exception)
|
private function validException($exception)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(strpos($exception->getMessage(), 'file_put_contents') === TRUE)
|
if(strpos($exception->getMessage(), 'file_put_contents') !== FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if(strpos($exception->getMessage(), 'Permission denied') === TRUE)
|
if(strpos($exception->getMessage(), 'Permission denied') !== FALSE)
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if(strpos($exception->getMessage(), 'flock()') === TRUE)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if(strpos($exception->getMessage(), 'flock()') !== FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
39
app/Export/CSV/InvoiceExport.php
Normal file
39
app/Export/CSV/InvoiceExport.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\CSV;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use Excel;
|
||||||
|
|
||||||
|
class InvoiceExport
|
||||||
|
{
|
||||||
|
private $company;
|
||||||
|
|
||||||
|
public function __construct(Company $company)
|
||||||
|
{
|
||||||
|
$this->company = $company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export()
|
||||||
|
{
|
||||||
|
// $fileName = 'test.csv';
|
||||||
|
|
||||||
|
// $data = $this->company->invoices->get();
|
||||||
|
|
||||||
|
// return Excel::create($fileName, function ($excel) use ($data) {
|
||||||
|
// $excel->sheet('', function ($sheet) use ($data) {
|
||||||
|
// $sheet->loadView('export', $data);
|
||||||
|
// });
|
||||||
|
// })->download('csv');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -190,7 +190,6 @@ class ClientFilters extends QueryFilters
|
|||||||
* limit the user to only the invoices they have created
|
* limit the user to only the invoices they have created
|
||||||
*/
|
*/
|
||||||
if (Gate::denies('view-list', Client::class)) {
|
if (Gate::denies('view-list', Client::class)) {
|
||||||
info('the gate!');
|
|
||||||
$query->where('clients.user_id', '=', $user->id);
|
$query->where('clients.user_id', '=', $user->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,15 +54,12 @@ class DocumentController extends Controller
|
|||||||
return Storage::disk($document->disk)->download($document->url, $document->name);
|
return Storage::disk($document->disk)->download($document->url, $document->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function publicDownload(string $contact_key, Document $document)
|
public function publicDownload(string $document_hash)
|
||||||
{
|
{
|
||||||
//return failure if the contact is not associated with the document
|
|
||||||
$contact = ClientContact::where('contact_key', $contact_key)->firstOrFail();
|
|
||||||
|
|
||||||
if($contact->company_id == $document->company_id)
|
$document = Document::where('hash', $document_hash)->firstOrFail();
|
||||||
|
|
||||||
return Storage::disk($document->disk)->download($document->url, $document->name);
|
return Storage::disk($document->disk)->download($document->url, $document->name);
|
||||||
|
|
||||||
return response()->json(['message' => 'Access denied']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
|
public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
|
||||||
|
@ -170,6 +170,6 @@ class EmailController extends BaseController
|
|||||||
$this->entity_transformer = RecurringInvoiceTransformer::class;
|
$this->entity_transformer = RecurringInvoiceTransformer::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->itemResponse($entity_obj);
|
return $this->itemResponse($entity_obj->fresh());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,12 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Import\PreImportRequest;
|
use App\Http\Requests\Import\PreImportRequest;
|
||||||
|
use App\Import\Definitions\Import\ImportMap;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use League\Csv\Reader;
|
|
||||||
use League\Csv\Statement;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use League\Csv\Reader;
|
||||||
|
use League\Csv\Statement;
|
||||||
|
|
||||||
class ImportController extends Controller
|
class ImportController extends Controller
|
||||||
{
|
{
|
||||||
@ -80,8 +81,9 @@ class ImportController extends Controller
|
|||||||
//parse CSV
|
//parse CSV
|
||||||
$csv_array = $this->getCsvData(file_get_contents($request->file('file')->getPathname()));
|
$csv_array = $this->getCsvData(file_get_contents($request->file('file')->getPathname()));
|
||||||
|
|
||||||
$data['data'] = [
|
$data = [
|
||||||
'hash' => $hash,
|
'hash' => $hash,
|
||||||
|
'available' => InvoiceMap::importable(),
|
||||||
'headers' => array_slice($csv_array, 0, 2)
|
'headers' => array_slice($csv_array, 0, 2)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ class StoreExpenseRequest extends Request
|
|||||||
$input['category_id'] = $this->decodePrimaryKey($input['category_id']);
|
$input['category_id'] = $this->decodePrimaryKey($input['category_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! array_key_exists('currency_id', $input)) {
|
if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
|
||||||
$input['currency_id'] = auth()->user()->company()->settings->currency_id;
|
$input['currency_id'] = (string)auth()->user()->company()->settings->currency_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
|
98
app/Import/Definitions/InvoiceMap.php
Normal file
98
app/Import/Definitions/InvoiceMap.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Import\Definitions;
|
||||||
|
|
||||||
|
class InvoiceMap
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function importable()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
0 => 'number',
|
||||||
|
1 => 'user_id',
|
||||||
|
2 => 'amount',
|
||||||
|
3 => 'balance',
|
||||||
|
4 => 'client_id',
|
||||||
|
5 => 'status_id',
|
||||||
|
6 => 'is_deleted',
|
||||||
|
7 => 'discount',
|
||||||
|
8 => 'po_number',
|
||||||
|
9 => 'date',
|
||||||
|
10 => 'due_date',
|
||||||
|
11 => 'terms',
|
||||||
|
12 => 'public_notes',
|
||||||
|
13 => 'private_notes',
|
||||||
|
14 => 'uses_inclusive_taxes',
|
||||||
|
15 => 'tax_name1',
|
||||||
|
16 => 'tax_rate1',
|
||||||
|
17 => 'tax_name2',
|
||||||
|
18 => 'tax_rate2',
|
||||||
|
19 => 'tax_name3',
|
||||||
|
20 => 'tax_rate3',
|
||||||
|
21 => 'is_amount_discount',
|
||||||
|
22 => 'footer',
|
||||||
|
23 => 'partial',
|
||||||
|
24 => 'partial_due_date',
|
||||||
|
25 => 'custom_value1',
|
||||||
|
26 => 'custom_value2',
|
||||||
|
27 => 'custom_value3',
|
||||||
|
28 => 'custom_value4',
|
||||||
|
29 => 'custom_surcharge1',
|
||||||
|
30 => 'custom_surcharge2',
|
||||||
|
31 => 'custom_surcharge3',
|
||||||
|
32 => 'custom_surcharge4',
|
||||||
|
33 => 'exchange_rate',
|
||||||
|
34 => 'line_items',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function import_keys()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
0 => 'texts.invoice_number',
|
||||||
|
1 => 'texts.user',
|
||||||
|
2 => 'texts.amount',
|
||||||
|
3 => 'texts.balance',
|
||||||
|
4 => 'texts.client',
|
||||||
|
5 => 'texts.status',
|
||||||
|
6 => 'texts.deleted',
|
||||||
|
7 => 'texts.discount',
|
||||||
|
8 => 'texts.po_number',
|
||||||
|
9 => 'texts.date',
|
||||||
|
10 => 'texts.due_date',
|
||||||
|
11 => 'texts.terms',
|
||||||
|
12 => 'texts.public_notes',
|
||||||
|
13 => 'texts.private_notes',
|
||||||
|
14 => 'texts.uses_inclusive_taxes',
|
||||||
|
15 => 'texts.tax_name1',
|
||||||
|
16 => 'texts.tax_rate',
|
||||||
|
17 => 'texts.tax_name',
|
||||||
|
18 => 'texts.tax_rate',
|
||||||
|
19 => 'texts.tax_name',
|
||||||
|
20 => 'texts.tax_rate',
|
||||||
|
21 => 'texts.is_amount_discount',
|
||||||
|
22 => 'texts.footer',
|
||||||
|
23 => 'texts.partial',
|
||||||
|
24 => 'texts.partial_due_date',
|
||||||
|
25 => 'texts.custom_value1',
|
||||||
|
26 => 'texts.custom_value2',
|
||||||
|
27 => 'texts.custom_value3',
|
||||||
|
28 => 'texts.custom_value4',
|
||||||
|
29 => 'texts.surcharge',
|
||||||
|
30 => 'texts.surcharge',
|
||||||
|
31 => 'texts.surcharge',
|
||||||
|
32 => 'texts.surcharge',
|
||||||
|
33 => 'texts.exchange_rate',
|
||||||
|
34 => 'texts.items',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -164,4 +164,9 @@ class CreateEntityPdf implements ShouldQueue
|
|||||||
|
|
||||||
return $file_path;
|
return $file_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function failed(\Exception $exception)
|
||||||
|
{
|
||||||
|
info("help!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1048,13 +1048,11 @@ class Import implements ShouldQueue
|
|||||||
|
|
||||||
$cgt = ClientGatewayToken::Create($modified);
|
$cgt = ClientGatewayToken::Create($modified);
|
||||||
|
|
||||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
$key = "client_gateway_tokens_{$resource['id']}";
|
||||||
|
|
||||||
$this->ids['client_gateway_tokens'] = [
|
$this->ids['client_gateway_tokens'][$key] = [
|
||||||
"client_gateway_tokens_{$old_user_key}" => [
|
'old' => $resource['id'],
|
||||||
'old' => $resource['id'],
|
'new' => $cgt->id,
|
||||||
'new' => $cgt->id,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1079,13 +1077,11 @@ class Import implements ShouldQueue
|
|||||||
|
|
||||||
$task_status = TaskStatus::Create($modified);
|
$task_status = TaskStatus::Create($modified);
|
||||||
|
|
||||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
$key = "task_statuses_{$resource['id']}";
|
||||||
|
|
||||||
$this->ids['task_statuses'] = [
|
$this->ids['task_statuses'][$key] = [
|
||||||
"task_statuses_{$old_user_key}" => [
|
'old' => $resource['id'],
|
||||||
'old' => $resource['id'],
|
'new' => $task_status->id,
|
||||||
'new' => $task_status->id,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ class CompanyGateway extends BaseModel
|
|||||||
|
|
||||||
if ($fees_and_limits->fee_amount) {
|
if ($fees_and_limits->fee_amount) {
|
||||||
$fee += $fees_and_limits->fee_amount;
|
$fee += $fees_and_limits->fee_amount;
|
||||||
info("fee after adding fee amount = {$fee}");
|
// info("fee after adding fee amount = {$fee}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($fees_and_limits->fee_percent) {
|
if ($fees_and_limits->fee_percent) {
|
||||||
@ -289,7 +289,7 @@ class CompanyGateway extends BaseModel
|
|||||||
} else {
|
} else {
|
||||||
$fee += round(($amount * $fees_and_limits->fee_percent / 100), 2);
|
$fee += round(($amount * $fees_and_limits->fee_percent / 100), 2);
|
||||||
}
|
}
|
||||||
info("fee after adding fee percent = {$fee}");
|
// info("fee after adding fee percent = {$fee}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cap fee if we have to here. */
|
/* Cap fee if we have to here. */
|
||||||
@ -303,17 +303,17 @@ class CompanyGateway extends BaseModel
|
|||||||
if ($include_taxes) {
|
if ($include_taxes) {
|
||||||
if ($fees_and_limits->fee_tax_rate1) {
|
if ($fees_and_limits->fee_tax_rate1) {
|
||||||
$fee += round(($pre_tax_fee * $fees_and_limits->fee_tax_rate1 / 100), 2);
|
$fee += round(($pre_tax_fee * $fees_and_limits->fee_tax_rate1 / 100), 2);
|
||||||
info("fee after adding fee tax 1 = {$fee}");
|
// info("fee after adding fee tax 1 = {$fee}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($fees_and_limits->fee_tax_rate2) {
|
if ($fees_and_limits->fee_tax_rate2) {
|
||||||
$fee += round(($pre_tax_fee * $fees_and_limits->fee_tax_rate2 / 100), 2);
|
$fee += round(($pre_tax_fee * $fees_and_limits->fee_tax_rate2 / 100), 2);
|
||||||
info("fee after adding fee tax 2 = {$fee}");
|
// info("fee after adding fee tax 2 = {$fee}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($fees_and_limits->fee_tax_rate3) {
|
if ($fees_and_limits->fee_tax_rate3) {
|
||||||
$fee += round(($pre_tax_fee * $fees_and_limits->fee_tax_rate3 / 100), 2);
|
$fee += round(($pre_tax_fee * $fees_and_limits->fee_tax_rate3 / 100), 2);
|
||||||
info("fee after adding fee tax 3 = {$fee}");
|
// info("fee after adding fee tax 3 = {$fee}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ class ExpenseRepository extends BaseRepository
|
|||||||
*/
|
*/
|
||||||
public function save(array $data, Expense $expense) : ?Expense
|
public function save(array $data, Expense $expense) : ?Expense
|
||||||
{
|
{
|
||||||
|
|
||||||
$expense->fill($data);
|
$expense->fill($data);
|
||||||
$expense->number = empty($expense->number) ? $this->getNextExpenseNumber($expense) : $expense->number;
|
$expense->number = empty($expense->number) ? $this->getNextExpenseNumber($expense) : $expense->number;
|
||||||
$expense->save();
|
$expense->save();
|
||||||
|
@ -36,14 +36,13 @@ class ApplyPayment extends AbstractService
|
|||||||
->ledger()
|
->ledger()
|
||||||
->updatePaymentBalance($this->payment_amount * -1);
|
->updatePaymentBalance($this->payment_amount * -1);
|
||||||
|
|
||||||
info("apply payment method - current client balance = {$this->payment->client->balance}");
|
// info("apply payment method - current client balance = {$this->payment->client->balance}");
|
||||||
|
|
||||||
info("reducing client balance by payment amount {$this->payment_amount}");
|
// info("reducing client balance by payment amount {$this->payment_amount}");
|
||||||
|
|
||||||
$this->invoice->client->service()->updateBalance($this->payment_amount * -1)->save();
|
$this->invoice->client->service()->updateBalance($this->payment_amount * -1)->save();
|
||||||
// $this->invoice->client->service()->updateBalance($this->payment_amount*-1)->updatePaidToDate($this->payment_amount)->save();
|
|
||||||
|
|
||||||
info("post client balance = {$this->invoice->client->balance}");
|
// info("post client balance = {$this->invoice->client->balance}");
|
||||||
|
|
||||||
/* Update Pivot Record amount */
|
/* Update Pivot Record amount */
|
||||||
$this->payment->invoices->each(function ($inv) {
|
$this->payment->invoices->each(function ($inv) {
|
||||||
@ -55,8 +54,8 @@ class ApplyPayment extends AbstractService
|
|||||||
|
|
||||||
$this->invoice->fresh('client');
|
$this->invoice->fresh('client');
|
||||||
|
|
||||||
info("1 end of apply payment method the client balance = {$this->invoice->client->balance}");
|
// info("1 end of apply payment method the client balance = {$this->invoice->client->balance}");
|
||||||
|
|
||||||
if ($this->invoice->hasPartial()) {
|
if ($this->invoice->hasPartial()) {
|
||||||
//is partial and amount is exactly the partial amount
|
//is partial and amount is exactly the partial amount
|
||||||
if ($this->invoice->partial == $this->payment_amount) {
|
if ($this->invoice->partial == $this->payment_amount) {
|
||||||
@ -71,11 +70,11 @@ class ApplyPayment extends AbstractService
|
|||||||
} elseif ($this->payment_amount < $this->invoice->balance) { //partial invoice payment made
|
} elseif ($this->payment_amount < $this->invoice->balance) { //partial invoice payment made
|
||||||
$this->invoice->service()->clearPartial()->setStatus(Invoice::STATUS_PARTIAL)->updateBalance($this->payment_amount * -1);
|
$this->invoice->service()->clearPartial()->setStatus(Invoice::STATUS_PARTIAL)->updateBalance($this->payment_amount * -1);
|
||||||
}
|
}
|
||||||
info("2 end of apply payment method the client balnace = {$this->invoice->client->balance}");
|
// info("2 end of apply payment method the client balnace = {$this->invoice->client->balance}");
|
||||||
|
|
||||||
$this->invoice->service()->applyNumber()->save();
|
$this->invoice->service()->applyNumber()->save();
|
||||||
|
|
||||||
info("3 end of apply payment method the client balnace = {$this->invoice->client->balance}");
|
// info("3 end of apply payment method the client balnace = {$this->invoice->client->balance}");
|
||||||
|
|
||||||
return $this->invoice;
|
return $this->invoice;
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,6 @@ class MarkSent extends AbstractService
|
|||||||
return $this->invoice;
|
return $this->invoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
info("in mark sent");
|
|
||||||
info($this->invoice->balance);
|
|
||||||
|
|
||||||
$this->invoice->markInvitationsSent();
|
$this->invoice->markInvitationsSent();
|
||||||
|
|
||||||
$this->invoice->setReminder();
|
$this->invoice->setReminder();
|
||||||
@ -52,12 +49,8 @@ info($this->invoice->balance);
|
|||||||
->updateBalance($this->invoice->amount)
|
->updateBalance($this->invoice->amount)
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
info($this->invoice->balance);
|
|
||||||
|
|
||||||
$this->client->service()->updateBalance($this->invoice->balance)->save();
|
$this->client->service()->updateBalance($this->invoice->balance)->save();
|
||||||
|
|
||||||
info($this->client->balance);
|
|
||||||
|
|
||||||
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance);
|
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance);
|
||||||
|
|
||||||
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars()));
|
event(new InvoiceWasUpdated($this->invoice, $this->invoice->company, Ninja::eventVars()));
|
||||||
|
@ -59,7 +59,7 @@ class ExpenseTransformer extends EntityTransformer
|
|||||||
'bank_id' => (string) $expense->bank_id ?: '',
|
'bank_id' => (string) $expense->bank_id ?: '',
|
||||||
'invoice_currency_id' => (string) $expense->invoice_currency_id ?: '',
|
'invoice_currency_id' => (string) $expense->invoice_currency_id ?: '',
|
||||||
'expense_currency_id' => '', //todo remove redundant in 5.0.25
|
'expense_currency_id' => '', //todo remove redundant in 5.0.25
|
||||||
'currency_id' => (string) $expense->expense_currency_id ?: '',
|
'currency_id' => (string) $expense->currency_id ?: '',
|
||||||
'category_id' => $this->encodePrimaryKey($expense->category_id),
|
'category_id' => $this->encodePrimaryKey($expense->category_id),
|
||||||
'payment_type_id' => (string) $expense->payment_type_id ?: '',
|
'payment_type_id' => (string) $expense->payment_type_id ?: '',
|
||||||
'recurring_expense_id' => (string) $expense->recurring_expense_id ?: '',
|
'recurring_expense_id' => (string) $expense->recurring_expense_id ?: '',
|
||||||
|
12
composer.lock
generated
12
composer.lock
generated
@ -116,16 +116,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "aws/aws-sdk-php",
|
"name": "aws/aws-sdk-php",
|
||||||
"version": "3.168.2",
|
"version": "3.168.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||||
"reference": "1d6a976da857d13b156bd63613ee086c13f6dc29"
|
"reference": "49ef1f905388c8185012c9651b80941b8f2a218d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/1d6a976da857d13b156bd63613ee086c13f6dc29",
|
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/49ef1f905388c8185012c9651b80941b8f2a218d",
|
||||||
"reference": "1d6a976da857d13b156bd63613ee086c13f6dc29",
|
"reference": "49ef1f905388c8185012c9651b80941b8f2a218d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -200,9 +200,9 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.168.2"
|
"source": "https://github.com/aws/aws-sdk-php/tree/3.168.3"
|
||||||
},
|
},
|
||||||
"time": "2020-12-10T19:35:18+00:00"
|
"time": "2020-12-11T19:12:18+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
|
@ -3321,4 +3321,9 @@ return [
|
|||||||
'notification_invoice_reminder2_sent_subject' => 'Reminder 2 for Invoice :invoice was sent to :client',
|
'notification_invoice_reminder2_sent_subject' => 'Reminder 2 for Invoice :invoice was sent to :client',
|
||||||
'notification_invoice_reminder3_sent_subject' => 'Reminder 3 for Invoice :invoice was sent to :client',
|
'notification_invoice_reminder3_sent_subject' => 'Reminder 3 for Invoice :invoice was sent to :client',
|
||||||
'notification_invoice_reminder_endless_sent_subject' => 'Endless reminder for Invoice :invoice was sent to :client',
|
'notification_invoice_reminder_endless_sent_subject' => 'Endless reminder for Invoice :invoice was sent to :client',
|
||||||
|
'assigned_user' => 'Assigned User',
|
||||||
|
'custom_value3' => 'Custom Value',
|
||||||
|
'custom_value4' => 'Custom Value',
|
||||||
|
'inclusive_taxes' => 'Include taxes',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -22,7 +22,7 @@ Route::post('view/{entity_type}/{invitation_key}/password', 'ClientPortal\Entity
|
|||||||
Route::get('tmp_pdf/{hash}', 'ClientPortal\TempRouteController@index')->name('tmp_pdf');
|
Route::get('tmp_pdf/{hash}', 'ClientPortal\TempRouteController@index')->name('tmp_pdf');
|
||||||
|
|
||||||
Route::get('client/key_login/{contact_key}', 'ClientPortal\ContactHashLoginController@login')->name('client.contact_login')->middleware(['contact_key_login']);
|
Route::get('client/key_login/{contact_key}', 'ClientPortal\ContactHashLoginController@login')->name('client.contact_login')->middleware(['contact_key_login']);
|
||||||
Route::get('documents/{contact_key}/{document}/download', 'ClientPortal\DocumentController@publicDownload')->name('documents.public_download');
|
Route::get('documents/{document_hash}', 'ClientPortal\DocumentController@publicDownload')->name('documents.public_download');
|
||||||
|
|
||||||
//todo implement domain DB
|
//todo implement domain DB
|
||||||
Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
||||||
|
93
tests/Feature/Export/ExportCsvTest.php
Normal file
93
tests/Feature/Export/ExportCsvTest.php
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
namespace Tests\Feature\Export;
|
||||||
|
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use League\Csv\Reader;
|
||||||
|
use League\Csv\Statement;
|
||||||
|
use League\Csv\Writer;
|
||||||
|
use Tests\MockAccountData;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
class ExportCsvTest extends TestCase
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
use MockAccountData;
|
||||||
|
|
||||||
|
public function setUp() :void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->withoutMiddleware(
|
||||||
|
ThrottleRequests::class
|
||||||
|
);
|
||||||
|
|
||||||
|
// $this->faker = \Faker\Factory::create();
|
||||||
|
|
||||||
|
$this->makeTestData();
|
||||||
|
|
||||||
|
$this->withoutExceptionHandling();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testExportCsv()
|
||||||
|
{
|
||||||
|
$csv = Writer::createFromFileObject(new \SplTempFileObject());
|
||||||
|
|
||||||
|
$header_invoice = Invoice::take(10)->get()->toArray();
|
||||||
|
$header_item = $header_invoice[0]['line_items'][0];
|
||||||
|
unset($header_invoice[0]['line_items']);
|
||||||
|
|
||||||
|
$header_invoice_keys = array_keys($header_invoice[0]);
|
||||||
|
$header_item_keys = array_keys((array)$header_item);
|
||||||
|
|
||||||
|
$header_invoice_values = array_values($header_invoice[0]);
|
||||||
|
$header_item_values = array_values((array)$header_item);
|
||||||
|
|
||||||
|
$merged_values = array_merge($header_invoice_values, (array)$header_item_values);
|
||||||
|
$merged_keys = array_merge($header_invoice_keys, (array)$header_item_keys);
|
||||||
|
|
||||||
|
info(print_r( $merged_keys,1));
|
||||||
|
info(print_r( $merged_values,1));
|
||||||
|
|
||||||
|
|
||||||
|
foreach($merged_keys as &$key) {
|
||||||
|
$key = ctrans('texts.'.$key);
|
||||||
|
}
|
||||||
|
|
||||||
|
$csv->insertOne($merged_keys);
|
||||||
|
|
||||||
|
foreach(Invoice::take(10)->get() as $invoice){
|
||||||
|
|
||||||
|
foreach($invoice->line_items as $item) {
|
||||||
|
|
||||||
|
unset($invoice->line_items);
|
||||||
|
|
||||||
|
$csv->insertOne(array_merge($invoice->toArray(), (array)$item));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::put(base_path('invy.csv'), $csv->getContent());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user