From 7c46791f88a7aad6b4d4bcf27f5b43ffd5bc0f6e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 07:44:52 +1100 Subject: [PATCH 1/9] Fixes for lock file --- composer.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/composer.lock b/composer.lock index a3e25bf94666..76d3b30340fc 100644 --- a/composer.lock +++ b/composer.lock @@ -116,16 +116,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.169.0", + "version": "3.170.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "d15a231355e4435fc33bab83df075ec31edd0a9b" + "reference": "7f457a08219173eba4b856cb7aef3a903cd790cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d15a231355e4435fc33bab83df075ec31edd0a9b", - "reference": "d15a231355e4435fc33bab83df075ec31edd0a9b", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7f457a08219173eba4b856cb7aef3a903cd790cc", + "reference": "7f457a08219173eba4b856cb7aef3a903cd790cc", "shasum": "" }, "require": { @@ -200,9 +200,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.169.0" + "source": "https://github.com/aws/aws-sdk-php/tree/3.170.0" }, - "time": "2020-12-14T19:12:33+00:00" + "time": "2020-12-15T19:13:22+00:00" }, { "name": "beganovich/chromium-pdf", @@ -2715,16 +2715,16 @@ }, { "name": "laravel/framework", - "version": "v8.18.1", + "version": "v8.19.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "31747193c26ba0a9cb7929a912895d3cdefd10cf" + "reference": "f5f331cee60f1bbe672503b7eb9ba5b22b2ceacb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/31747193c26ba0a9cb7929a912895d3cdefd10cf", - "reference": "31747193c26ba0a9cb7929a912895d3cdefd10cf", + "url": "https://api.github.com/repos/laravel/framework/zipball/f5f331cee60f1bbe672503b7eb9ba5b22b2ceacb", + "reference": "f5f331cee60f1bbe672503b7eb9ba5b22b2ceacb", "shasum": "" }, "require": { @@ -2878,7 +2878,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2020-12-08T22:05:12+00:00" + "time": "2020-12-15T16:16:31+00:00" }, { "name": "laravel/slack-notification-channel", From e6f6470adc21d2bf8b0ef5fe74a3137d7b512d6c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 07:59:38 +1100 Subject: [PATCH 2/9] Minor updates for composer --- composer.json | 2 +- composer.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index fdcd1945ef31..ccb68c9a9661 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ ], "type": "project", "require": { - "php": "^7.3|^7.4", + "php": "^7.3|^7.4|^8", "ext-json": "*", "asgrim/ofxparser": "^1.2", "authorizenet/authorizenet": "^2.0", diff --git a/composer.lock b/composer.lock index 76d3b30340fc..3f28a76109c2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "75cb7287f45830678381d8e27486cf4a", + "content-hash": "4b6a413f1316b8afef90d5a411e7d155", "packages": [ { "name": "asgrim/ofxparser", @@ -9558,22 +9558,22 @@ }, { "name": "turbo124/beacon", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/turbo124/beacon.git", - "reference": "687484955bdc8bfca957ccd060e6c1fa41ada056" + "reference": "ae328ad12364186dd07d893d35f6991880b97f18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/turbo124/beacon/zipball/687484955bdc8bfca957ccd060e6c1fa41ada056", - "reference": "687484955bdc8bfca957ccd060e6c1fa41ada056", + "url": "https://api.github.com/repos/turbo124/beacon/zipball/ae328ad12364186dd07d893d35f6991880b97f18", + "reference": "ae328ad12364186dd07d893d35f6991880b97f18", "shasum": "" }, "require": { "guzzlehttp/guzzle": "^7", "illuminate/support": "^6.0|^7.0|^8.0", - "php": "^7.3" + "php": "^7.3|^7.4|^8" }, "require-dev": { "orchestra/testbench": "^4.0", @@ -9615,9 +9615,9 @@ "turbo124" ], "support": { - "source": "https://github.com/turbo124/beacon/tree/1.0.3" + "source": "https://github.com/turbo124/beacon/tree/1.0.4" }, - "time": "2020-10-01T05:21:36+00:00" + "time": "2020-12-15T20:56:25+00:00" }, { "name": "turbo124/laravel-gmail", @@ -13887,7 +13887,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^7.3|^7.4", + "php": "^7.3|^7.4|^8", "ext-json": "*" }, "platform-dev": [], From 263a5cfa0b9f1f9505d821e62cffe18ab1f4341b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 08:03:20 +1100 Subject: [PATCH 3/9] Minor updates for composer --- .github/workflows/phpunit.yml | 2 +- composer.json | 4 ++-- composer.lock | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 804cc6dfe3bd..d743637eaec7 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['7.3', '7.4', '8.0'] + php-versions: ['7.3', '7.4'] env: DB_DATABASE1: ninja DB_USERNAME1: root diff --git a/composer.json b/composer.json index ccb68c9a9661..ae7d7823aa9a 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ ], "type": "project", "require": { - "php": "^7.3|^7.4|^8", + "php": "^7.3|^7.4", "ext-json": "*", "asgrim/ofxparser": "^1.2", "authorizenet/authorizenet": "^2.0", @@ -52,7 +52,7 @@ "league/flysystem-aws-s3-v3": "~1.0", "league/flysystem-cached-adapter": "^1.1", "league/fractal": "^0.17.0", - "league/omnipay": "^3.0", + "league/omnipay": "^3", "livewire/livewire": "^2.0", "maennchen/zipstream-php": "^1.2", "nwidart/laravel-modules": "^8.0", diff --git a/composer.lock b/composer.lock index 3f28a76109c2..ad280ddbd6d4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4b6a413f1316b8afef90d5a411e7d155", + "content-hash": "aeacc9e2738ddc41353c497c14feadb0", "packages": [ { "name": "asgrim/ofxparser", @@ -13887,7 +13887,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^7.3|^7.4|^8", + "php": "^7.3|^7.4", "ext-json": "*" }, "platform-dev": [], From 0452d8b3331f16a910cce0c0e2fbd3ab6f879002 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 08:10:40 +1100 Subject: [PATCH 4/9] fixes for composer update --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ae7d7823aa9a..603c68b22b5e 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "CRM", "Credit card billing", "projects", - "tasks" + "tasks", + "freelancer" ], "license": "Attribution Assurance License", "authors": [ From 7412c01ec29b2174e3dbc54a6611ee63bbf5ef3a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 08:35:50 +1100 Subject: [PATCH 5/9] Change actions runtime --- .github/workflows/phpunit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index d743637eaec7..994c92ea0a0d 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -9,7 +9,7 @@ on: name: phpunit jobs: phpunit: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 strategy: matrix: php-versions: ['7.3', '7.4'] From b087046489a5f91f22cd53f0f59e0bea9bb87f5c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 09:17:31 +1100 Subject: [PATCH 6/9] Client import map --- .github/workflows/phpunit.yml | 2 +- app/Import/Definitions/ClientMap.php | 109 +++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 app/Import/Definitions/ClientMap.php diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 994c92ea0a0d..d743637eaec7 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -9,7 +9,7 @@ on: name: phpunit jobs: phpunit: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest strategy: matrix: php-versions: ['7.3', '7.4'] diff --git a/app/Import/Definitions/ClientMap.php b/app/Import/Definitions/ClientMap.php new file mode 100644 index 000000000000..adb135b867b0 --- /dev/null +++ b/app/Import/Definitions/ClientMap.php @@ -0,0 +1,109 @@ + 'client.name', + 1 => 'client.user_id', + 2 => 'client.balance', + 3 => 'client.paid_to_date', + 4 => 'client.currency_id', + 5 => 'client.website', + 6 => 'client.private_notes', + 7 => 'client.industry_id', + 8 => 'client.size_id', + 9 => 'client.address1', + 10 => 'client.address2', + 11 => 'client.city', + 12 => 'client.state', + 13 => 'client.postal_code', + 14 => 'client.country_id', + 15 => 'client.custom_value1', + 16 => 'client.custom_value2', + 17 => 'client.custom_value3', + 18 => 'client.custom_value4', + 19 => 'client.shipping_address1', + 20 => 'client.shipping_address2', + 21 => 'client.shipping_city', + 22 => 'client.shipping_state', + 23 => 'client.shipping_postal_code', + 24 => 'client.shipping_country_id', + 25 => 'client.payment_terms', + 26 => 'client.vat_number', + 27 => 'client.id_number', + 28 => 'client.public_notes' + ]; + } + + public static function import_keys() + { + return [ + 0 => 'texts.client_name', + 1 => 'texts.user', + 2 => 'texts.amount', + 3 => 'texts.balance', + 4 => 'texts.client', + 5 => 'texts.discount', + 6 => 'texts.po_number', + 7 => 'texts.date', + 8 => 'texts.due_date', + 9 => 'texts.terms', + 10 => 'texts.public_notes', + 11 => 'texts.sent', + 12 => 'texts.private_notes', + 13 => 'texts.uses_inclusive_taxes', + 14 => 'texts.tax_name', + 15 => 'texts.tax_rate', + 16 => 'texts.tax_name', + 17 => 'texts.tax_rate', + 18 => 'texts.tax_name', + 19 => 'texts.tax_rate', + 20 => 'texts.is_amount_discount', + 21 => 'texts.footer', + 22 => 'texts.partial', + 23 => 'texts.partial_due_date', + 24 => 'texts.custom_value1', + 25 => 'texts.custom_value2', + 26 => 'texts.custom_value3', + 27 => 'texts.custom_value4', + 28 => 'texts.surcharge', + 29 => 'texts.surcharge', + 30 => 'texts.surcharge', + 31 => 'texts.surcharge', + 32 => 'texts.exchange_rate', + 33 => 'texts.payment_date', + 34 => 'texts.payment_amount', + 35 => 'texts.transaction_reference', + 36 => 'texts.quantity', + 37 => 'texts.cost', + 38 => 'texts.product_key', + 39 => 'texts.notes', + 40 => 'texts.discount', + 41 => 'texts.is_amount_discount', + 42 => 'texts.tax_name', + 43 => 'texts.tax_rate', + 44 => 'texts.tax_name', + 45 => 'texts.tax_rate', + 46 => 'texts.tax_name', + 47 => 'texts.tax_rate', + 48 => 'texts.custom_value', + 49 => 'texts.custom_value', + 50 => 'texts.custom_value', + 51 => 'texts.custom_value', + 52 => 'texts.type', + ]; + } +} From 8df553c4ccc47200f1fe05ce8837d4df45faa596 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 11:01:15 +1100 Subject: [PATCH 7/9] Working on CSV imports --- app/Http/Controllers/ImportController.php | 12 ++- app/Http/Requests/Import/ImportRequest.php | 6 +- app/Import/Definitions/ClientMap.php | 96 ++++++++++------------ app/Jobs/Import/CSVImport.php | 69 ++++++++++++++-- routes/api.php | 1 + 5 files changed, 119 insertions(+), 65 deletions(-) diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php index 8d65b0e33d13..e98adb53a90e 100644 --- a/app/Http/Controllers/ImportController.php +++ b/app/Http/Controllers/ImportController.php @@ -84,9 +84,11 @@ class ImportController extends Controller //parse CSV $csv_array = $this->getCsvData(file_get_contents($request->file('file')->getPathname())); + $class_map = $this->getEntityMap($request->input('entity_type')); + $data = [ 'hash' => $hash, - 'available' => InvoiceMap::importable(), + 'available' => $class_map::importable(), 'headers' => array_slice($csv_array, 0, 2) ]; @@ -95,11 +97,17 @@ class ImportController extends Controller public function import(ImportRequest $request) { - CSVImport::dispatch($request, auth()->user()->company()); + + CSVImport::dispatch($request->all(), auth()->user()->company()); return response()->json(['message' => 'Importing data, email will be sent on completion'], 200); } + private function getEntityMap($entity_type) + { + return sprintf('App\\Import\\Definitions\%sMap', ucfirst($entity_type)); + } + private function getCsvData($csvfile) { diff --git a/app/Http/Requests/Import/ImportRequest.php b/app/Http/Requests/Import/ImportRequest.php index a1f92a0dc465..a09837c92d20 100644 --- a/app/Http/Requests/Import/ImportRequest.php +++ b/app/Http/Requests/Import/ImportRequest.php @@ -29,8 +29,10 @@ class ImportRequest extends Request { return [ - 'hash' => 'required', - 'entity_type' => 'required', + 'hash' => 'required|string', + 'entity_type' => 'required|string', + 'column_map' => 'required|array', + 'skip_header' => 'required|boolean' ]; } diff --git a/app/Import/Definitions/ClientMap.php b/app/Import/Definitions/ClientMap.php index adb135b867b0..c8edf27e75fc 100644 --- a/app/Import/Definitions/ClientMap.php +++ b/app/Import/Definitions/ClientMap.php @@ -44,7 +44,15 @@ class ClientMap 25 => 'client.payment_terms', 26 => 'client.vat_number', 27 => 'client.id_number', - 28 => 'client.public_notes' + 28 => 'client.public_notes', + 29 => 'contact.first_name', + 30 => 'contact.last_name', + 31 => 'contact.email', + 32 => 'contact.phone', + 33 => 'contact.custom_value1', + 34 => 'contact.custom_value2', + 35 => 'contact.custom_value3', + 36 => 'contact.custom_value4', ]; } @@ -53,57 +61,41 @@ class ClientMap return [ 0 => 'texts.client_name', 1 => 'texts.user', - 2 => 'texts.amount', - 3 => 'texts.balance', - 4 => 'texts.client', - 5 => 'texts.discount', - 6 => 'texts.po_number', - 7 => 'texts.date', - 8 => 'texts.due_date', - 9 => 'texts.terms', - 10 => 'texts.public_notes', - 11 => 'texts.sent', - 12 => 'texts.private_notes', - 13 => 'texts.uses_inclusive_taxes', - 14 => 'texts.tax_name', - 15 => 'texts.tax_rate', - 16 => 'texts.tax_name', - 17 => 'texts.tax_rate', - 18 => 'texts.tax_name', - 19 => 'texts.tax_rate', - 20 => 'texts.is_amount_discount', - 21 => 'texts.footer', - 22 => 'texts.partial', - 23 => 'texts.partial_due_date', - 24 => 'texts.custom_value1', - 25 => 'texts.custom_value2', - 26 => 'texts.custom_value3', - 27 => 'texts.custom_value4', - 28 => 'texts.surcharge', - 29 => 'texts.surcharge', - 30 => 'texts.surcharge', - 31 => 'texts.surcharge', - 32 => 'texts.exchange_rate', - 33 => 'texts.payment_date', - 34 => 'texts.payment_amount', - 35 => 'texts.transaction_reference', - 36 => 'texts.quantity', - 37 => 'texts.cost', - 38 => 'texts.product_key', - 39 => 'texts.notes', - 40 => 'texts.discount', - 41 => 'texts.is_amount_discount', - 42 => 'texts.tax_name', - 43 => 'texts.tax_rate', - 44 => 'texts.tax_name', - 45 => 'texts.tax_rate', - 46 => 'texts.tax_name', - 47 => 'texts.tax_rate', - 48 => 'texts.custom_value', - 49 => 'texts.custom_value', - 50 => 'texts.custom_value', - 51 => 'texts.custom_value', - 52 => 'texts.type', + 2 => 'texts.balance', + 3 => 'texts.paid_to_date', + 4 => 'texts.currency', + 5 => 'texts.website', + 6 => 'texts.private_notes', + 7 => 'texts.industry', + 8 => 'texts.size', + 9 => 'texts.address1', + 10 => 'texts.address2', + 11 => 'texts.city', + 12 => 'texts.state', + 13 => 'texts.postal_code', + 14 => 'texts.country', + 15 => 'texts.custom_value', + 16 => 'texts.custom_value', + 17 => 'texts.custom_value', + 18 => 'texts.custom_value', + 19 => 'texts.address1', + 20 => 'texts.address2', + 21 => 'texts.shipping_city', + 22 => 'texts.shipping_state', + 23 => 'texts.shipping_postal_code', + 24 => 'texts.shipping_country', + 25 => 'texts.payment_terms', + 26 => 'texts.vat_number', + 27 => 'texts.id_number', + 28 => 'texts.public_notes', + 29 => 'texts.first_name', + 30 => 'texts.last_name', + 31 => 'texts.email', + 32 => 'texts.phone', + 33 => 'texts.custom_value', + 34 => 'texts.custom_value', + 35 => 'texts.custom_value', + 36 => 'texts.custom_value', ]; } } diff --git a/app/Jobs/Import/CSVImport.php b/app/Jobs/Import/CSVImport.php index 49657ce0d065..9b51b78409ca 100644 --- a/app/Jobs/Import/CSVImport.php +++ b/app/Jobs/Import/CSVImport.php @@ -12,6 +12,7 @@ namespace App\Jobs\Import; use App\Libraries\MultiDB; +use App\Models\Company; use Exception; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -20,6 +21,8 @@ use Illuminate\Http\Request; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Cache; +use League\Csv\Reader; +use League\Csv\Statement; class CSVImport implements ShouldQueue { @@ -33,19 +36,42 @@ class CSVImport implements ShouldQueue public $entity_type; - public $skip_headers; + public $skip_header; - public function __construct(Request $request, Company $company) + public $column_map; + + /* + [hash] => 2lTm7HVR3i9Zv3y86eQYZIO16yVJ7J6l + [entity_type] => client + [skip_header] => 1 + [column_map] => Array + ( + [0] => client.name + [1] => client.user_id + [2] => client.balance + [3] => client.paid_to_date + [4] => client.address1 + [5] => client.address2 + [6] => client.city + [7] => client.state + [8] => client.postal_code + [9] => client.country_id + [20] => client.currency_id + [21] => client.public_notes + [22] => client.private_notes + ) + */ + public function __construct(array $request, Company $company) { - $this->request = $request; - $this->company = $company; - $this->hash = $request->input('hash'); + $this->hash = $request['hash']; - $this->entity_type = $request->input('entity_type'); + $this->entity_type = $request['entity_type']; - $this->skip_headers = $request->input('skip_headers'); + $this->skip_header = $request['skip_header']; + + $this->column_map = $request['column_map']; } /** @@ -58,6 +84,10 @@ class CSVImport implements ShouldQueue { MultiDB::setDb($this->company->db); + foreach($this->getCsv() as $record) { + + } + } public function failed($exception) @@ -65,10 +95,31 @@ class CSVImport implements ShouldQueue } - private function getCsv() + private function getCsvData() { $base64_encoded_csv = Cache::get($this->hash); + $csv = base64_decode($base64_encoded_csv); + + $stmt = new Statement(); + $data = iterator_to_array($stmt->process($csv)); + + if (count($data) > 0) { + $headers = $data[0]; + + // Remove Invoice Ninja headers + if (count($headers) && count($data) > 4) { + $firstCell = $headers[0]; + if (strstr($firstCell, APP_NAME)) { + array_shift($data); // Invoice Ninja... + array_shift($data); // + array_shift($data); // Enitty Type Header + } + } + } + + return $data; + + - return base64_decode($base64_encoded_csv); } } diff --git a/routes/api.php b/routes/api.php index 85376b4e6e29..609f364eab58 100644 --- a/routes/api.php +++ b/routes/api.php @@ -169,6 +169,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::get('company_ledger', 'CompanyLedgerController@index')->name('company_ledger.index'); Route::post('preimport', 'ImportController@preimport')->name('import.preimport'); + Route::post('import', 'ImportController@import')->name('import.import'); /* Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit From 7353687c04f2379547746460ea8126e40a0a6ca7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 21:06:20 +1100 Subject: [PATCH 8/9] Working on client import --- app/Http/Controllers/ImportController.php | 2 +- app/Import/Transformers/BaseTransformer.php | 352 ++++++++++++++++++ app/Import/Transformers/ClientTransformer.php | 70 ++++ app/Jobs/Import/CSVImport.php | 101 ++++- public/.htaccess | 0 public/assets/AssetManifest.json | 0 public/assets/FontManifest.json | 0 public/assets/LICENSE | 0 public/assets/NOTICES | 0 public/assets/assets/images/google-icon.png | Bin public/assets/assets/images/logo.png | Bin .../assets/images/payment_types/ach.png | Bin .../assets/images/payment_types/amex.png | Bin .../images/payment_types/carteblanche.png | Bin .../images/payment_types/dinerscard.png | Bin .../assets/images/payment_types/discover.png | Bin .../assets/images/payment_types/jcb.png | Bin .../assets/images/payment_types/laser.png | Bin .../assets/images/payment_types/maestro.png | Bin .../images/payment_types/mastercard.png | Bin .../assets/images/payment_types/other.png | Bin .../assets/images/payment_types/paypal.png | Bin .../assets/images/payment_types/solo.png | Bin .../assets/images/payment_types/switch.png | Bin .../assets/images/payment_types/unionpay.png | Bin .../assets/images/payment_types/visa.png | Bin public/assets/fonts/MaterialIcons-Regular.otf | Bin public/assets/fonts/MaterialIcons-Regular.ttf | Bin public/assets/fonts/Roboto-Regular.ttf | Bin .../fonts/SF-Pro-Medium.ttf | Bin .../graphics/apple_logo_black.png | Bin .../graphics/apple_logo_white.png | Bin .../graphics/flogo-HexRBG-Wht-100.png | Bin .../graphics/google-logo.png | Bin .../graphics/ms-symbollockup_mssymbol_19.png | Bin .../lib/fonts/fa-brands-400.ttf | Bin .../lib/fonts/fa-regular-400.ttf | Bin .../lib/fonts/fa-solid-900.ttf | Bin .../web/assets/fonts/Roboto-Regular.ttf | Bin public/css/app.css | 0 public/css/card-js.min.css | 0 public/css/ninja.css | 0 public/css/ninja.min.css | 0 public/css/tailwind-1.2.0.css | 0 public/css/tailwindcss@1.4.6.css | 0 public/favicon.ico | Bin public/favicon.png | Bin public/flutter_service_worker.js | 0 public/icons/Icon-192.png | Bin public/icons/Icon-512.png | Bin public/images/american-express.png | Bin public/images/created-by-invoiceninja-new.png | Bin public/images/created-by-invoiceninja.jpg | Bin public/images/diners-club.png | Bin public/images/discover.png | Bin public/images/invoiceninja-black-logo-2.png | Bin public/images/invoiceninja-white-logo.png | Bin public/images/logo.png | Bin public/images/mastercard.png | Bin public/images/paypal.png | Bin public/images/svg/activity.svg | 0 public/images/svg/align-left.svg | 0 public/images/svg/clock.svg | 0 public/images/svg/credit-card.svg | 0 public/images/svg/download.svg | 0 public/images/svg/file-text.svg | 0 public/images/svg/file.svg | 0 public/images/svg/shield.svg | 0 public/images/svg/user.svg | 0 public/images/visa.png | Bin public/index.php | 0 public/js/app.js | 0 public/js/client_create.js | 0 public/js/client_create.min.js | 0 public/js/client_edit.js | 0 public/js/client_edit.min.js | 0 public/js/client_list.js | 0 public/js/client_list.min.js | 0 public/js/client_settings.js | 0 public/js/client_settings.min.js | 0 public/js/client_show.js | 0 public/js/client_show.min.js | 0 .../js/clients/invoices/action-selectors.js | 0 .../invoices/action-selectors.js.LICENSE.txt | 0 public/js/clients/invoices/payment.js | 0 .../clients/invoices/payment.js.LICENSE.txt | 0 .../clients/payment_methods/authorize-ach.js | 0 .../authorize-ach.js.LICENSE.txt | 0 .../authorize-authorize-card.js | 0 .../authorize-authorize-card.js.LICENSE.txt | 0 .../payment_methods/authorize-stripe-card.js | 0 .../authorize-stripe-card.js.LICENSE.txt | 0 .../js/clients/payment_methods/stripe-ach.js | 0 public/js/clients/payments/alipay.js | 0 .../js/clients/payments/alipay.js.LICENSE.txt | 0 .../payments/authorize-credit-card-payment.js | 0 ...thorize-credit-card-payment.js.LICENSE.txt | 0 public/js/clients/payments/card-js.min.js | 0 public/js/clients/payments/checkout.com.js | 0 .../payments/checkout.com.js.LICENSE.txt | 0 public/js/clients/payments/process.js | 0 .../clients/payments/process.js.LICENSE.txt | 0 public/js/clients/payments/sofort.js | 0 .../js/clients/payments/sofort.js.LICENSE.txt | 0 public/js/clients/payments/stripe-ach.js | 0 .../payments/stripe-ach.js.LICENSE.txt | 0 public/js/clients/payments/stripe-alipay.js | 0 .../payments/stripe-alipay.js.LICENSE.txt | 0 .../js/clients/payments/stripe-credit-card.js | 0 .../stripe-credit-card.js.LICENSE.txt | 0 public/js/clients/payments/stripe-sofort.js | 0 .../payments/stripe-sofort.js.LICENSE.txt | 0 public/js/clients/quotes/action-selectors.js | 0 .../quotes/action-selectors.js.LICENSE.txt | 0 public/js/clients/quotes/approve.js | 0 .../js/clients/quotes/approve.js.LICENSE.txt | 0 .../js/clients/shared/multiple-downloads.js | 0 public/js/clients/shared/pdf.js | 0 public/js/clients/shared/pdf.js.LICENSE.txt | 0 public/js/coreui.js | 0 public/js/coreui.min.js | 0 public/js/localization.js | 0 public/js/localization.min.js | 0 public/js/ninja.js | 0 public/js/ninja.min.js | 0 public/js/setup/setup.js | 0 public/js/setup/setup.js.LICENSE.txt | 0 public/js/vendor/app.js | 0 .../js/vendor/datatables/datatables.min.css | 0 public/js/vendor/datatables/datatables.min.js | 0 public/js/vendor/jquery-3.3.1/jquery-3.3.1.js | 0 .../vendor/jquery-3.3.1/jquery-3.3.1.min.js | 0 public/js/vendor/pdf.js/pdf.min.js | 0 public/js/vendor/pdf.js/pdf.worker.min.js | 0 public/main.dart.js | 0 public/main.dart.js.map | 0 public/manifest.json | 0 public/mix-manifest.json | 0 public/robots.txt | 0 public/svg/403.svg | 0 public/svg/404.svg | 0 public/svg/500.svg | 0 public/svg/503.svg | 0 public/vendor/dropzone-5.7.0/.gitignore | 0 public/vendor/dropzone-5.7.0/CONTRIBUTING.md | 0 public/vendor/dropzone-5.7.0/LICENSE | 0 public/vendor/dropzone-5.7.0/README.md | 0 public/vendor/dropzone-5.7.0/component.json | 0 public/vendor/dropzone-5.7.0/composer.json | 0 public/vendor/dropzone-5.7.0/dist/basic.css | 0 .../dist/dropzone-amd-module.js | 0 .../vendor/dropzone-5.7.0/dist/dropzone.css | 0 public/vendor/dropzone-5.7.0/dist/dropzone.js | 0 .../dropzone-5.7.0/dist/dropzone.js.map | 0 .../dropzone-5.7.0/dist/min/basic.min.css | 0 .../dist/min/dropzone-amd-module.min.js | 0 .../dropzone-5.7.0/dist/min/dropzone.min.css | 0 .../dropzone-5.7.0/dist/min/dropzone.min.js | 0 public/vendor/dropzone-5.7.0/index.js | 0 public/vendor/dropzone-5.7.0/package.json | 0 public/vendor/livewire/livewire.js | 0 public/vendor/livewire/livewire.js.map | 0 public/vendor/livewire/manifest.json | 0 public/version.json | 0 tests/Feature/Import/ImportCsvTest.php | 33 +- tests/Feature/Import/clients.csv | 24 ++ 166 files changed, 578 insertions(+), 4 deletions(-) create mode 100644 app/Import/Transformers/BaseTransformer.php create mode 100644 app/Import/Transformers/ClientTransformer.php mode change 100644 => 100755 public/.htaccess mode change 100644 => 100755 public/assets/AssetManifest.json mode change 100644 => 100755 public/assets/FontManifest.json mode change 100644 => 100755 public/assets/LICENSE mode change 100644 => 100755 public/assets/NOTICES mode change 100644 => 100755 public/assets/assets/images/google-icon.png mode change 100644 => 100755 public/assets/assets/images/logo.png mode change 100644 => 100755 public/assets/assets/images/payment_types/ach.png mode change 100644 => 100755 public/assets/assets/images/payment_types/amex.png mode change 100644 => 100755 public/assets/assets/images/payment_types/carteblanche.png mode change 100644 => 100755 public/assets/assets/images/payment_types/dinerscard.png mode change 100644 => 100755 public/assets/assets/images/payment_types/discover.png mode change 100644 => 100755 public/assets/assets/images/payment_types/jcb.png mode change 100644 => 100755 public/assets/assets/images/payment_types/laser.png mode change 100644 => 100755 public/assets/assets/images/payment_types/maestro.png mode change 100644 => 100755 public/assets/assets/images/payment_types/mastercard.png mode change 100644 => 100755 public/assets/assets/images/payment_types/other.png mode change 100644 => 100755 public/assets/assets/images/payment_types/paypal.png mode change 100644 => 100755 public/assets/assets/images/payment_types/solo.png mode change 100644 => 100755 public/assets/assets/images/payment_types/switch.png mode change 100644 => 100755 public/assets/assets/images/payment_types/unionpay.png mode change 100644 => 100755 public/assets/assets/images/payment_types/visa.png mode change 100644 => 100755 public/assets/fonts/MaterialIcons-Regular.otf mode change 100644 => 100755 public/assets/fonts/MaterialIcons-Regular.ttf mode change 100644 => 100755 public/assets/fonts/Roboto-Regular.ttf mode change 100644 => 100755 public/assets/packages/flutter_auth_buttons/fonts/SF-Pro-Medium.ttf mode change 100644 => 100755 public/assets/packages/flutter_auth_buttons/graphics/apple_logo_black.png mode change 100644 => 100755 public/assets/packages/flutter_auth_buttons/graphics/apple_logo_white.png mode change 100644 => 100755 public/assets/packages/flutter_auth_buttons/graphics/flogo-HexRBG-Wht-100.png mode change 100644 => 100755 public/assets/packages/flutter_auth_buttons/graphics/google-logo.png mode change 100644 => 100755 public/assets/packages/flutter_auth_buttons/graphics/ms-symbollockup_mssymbol_19.png mode change 100644 => 100755 public/assets/packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf mode change 100644 => 100755 public/assets/packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf mode change 100644 => 100755 public/assets/packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf mode change 100644 => 100755 public/assets/web/assets/fonts/Roboto-Regular.ttf mode change 100644 => 100755 public/css/app.css mode change 100644 => 100755 public/css/card-js.min.css mode change 100644 => 100755 public/css/ninja.css mode change 100644 => 100755 public/css/ninja.min.css mode change 100644 => 100755 public/css/tailwind-1.2.0.css mode change 100644 => 100755 public/css/tailwindcss@1.4.6.css mode change 100644 => 100755 public/favicon.ico mode change 100644 => 100755 public/favicon.png mode change 100644 => 100755 public/flutter_service_worker.js mode change 100644 => 100755 public/icons/Icon-192.png mode change 100644 => 100755 public/icons/Icon-512.png mode change 100644 => 100755 public/images/american-express.png mode change 100644 => 100755 public/images/created-by-invoiceninja-new.png mode change 100644 => 100755 public/images/created-by-invoiceninja.jpg mode change 100644 => 100755 public/images/diners-club.png mode change 100644 => 100755 public/images/discover.png mode change 100644 => 100755 public/images/invoiceninja-black-logo-2.png mode change 100644 => 100755 public/images/invoiceninja-white-logo.png mode change 100644 => 100755 public/images/logo.png mode change 100644 => 100755 public/images/mastercard.png mode change 100644 => 100755 public/images/paypal.png mode change 100644 => 100755 public/images/svg/activity.svg mode change 100644 => 100755 public/images/svg/align-left.svg mode change 100644 => 100755 public/images/svg/clock.svg mode change 100644 => 100755 public/images/svg/credit-card.svg mode change 100644 => 100755 public/images/svg/download.svg mode change 100644 => 100755 public/images/svg/file-text.svg mode change 100644 => 100755 public/images/svg/file.svg mode change 100644 => 100755 public/images/svg/shield.svg mode change 100644 => 100755 public/images/svg/user.svg mode change 100644 => 100755 public/images/visa.png mode change 100644 => 100755 public/index.php mode change 100644 => 100755 public/js/app.js mode change 100644 => 100755 public/js/client_create.js mode change 100644 => 100755 public/js/client_create.min.js mode change 100644 => 100755 public/js/client_edit.js mode change 100644 => 100755 public/js/client_edit.min.js mode change 100644 => 100755 public/js/client_list.js mode change 100644 => 100755 public/js/client_list.min.js mode change 100644 => 100755 public/js/client_settings.js mode change 100644 => 100755 public/js/client_settings.min.js mode change 100644 => 100755 public/js/client_show.js mode change 100644 => 100755 public/js/client_show.min.js mode change 100644 => 100755 public/js/clients/invoices/action-selectors.js mode change 100644 => 100755 public/js/clients/invoices/action-selectors.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/invoices/payment.js mode change 100644 => 100755 public/js/clients/invoices/payment.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payment_methods/authorize-ach.js mode change 100644 => 100755 public/js/clients/payment_methods/authorize-ach.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payment_methods/authorize-authorize-card.js mode change 100644 => 100755 public/js/clients/payment_methods/authorize-authorize-card.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payment_methods/authorize-stripe-card.js mode change 100644 => 100755 public/js/clients/payment_methods/authorize-stripe-card.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payment_methods/stripe-ach.js mode change 100644 => 100755 public/js/clients/payments/alipay.js mode change 100644 => 100755 public/js/clients/payments/alipay.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/authorize-credit-card-payment.js mode change 100644 => 100755 public/js/clients/payments/authorize-credit-card-payment.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/card-js.min.js mode change 100644 => 100755 public/js/clients/payments/checkout.com.js mode change 100644 => 100755 public/js/clients/payments/checkout.com.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/process.js mode change 100644 => 100755 public/js/clients/payments/process.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/sofort.js mode change 100644 => 100755 public/js/clients/payments/sofort.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/stripe-ach.js mode change 100644 => 100755 public/js/clients/payments/stripe-ach.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/stripe-alipay.js mode change 100644 => 100755 public/js/clients/payments/stripe-alipay.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/stripe-credit-card.js mode change 100644 => 100755 public/js/clients/payments/stripe-credit-card.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/payments/stripe-sofort.js mode change 100644 => 100755 public/js/clients/payments/stripe-sofort.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/quotes/action-selectors.js mode change 100644 => 100755 public/js/clients/quotes/action-selectors.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/quotes/approve.js mode change 100644 => 100755 public/js/clients/quotes/approve.js.LICENSE.txt mode change 100644 => 100755 public/js/clients/shared/multiple-downloads.js mode change 100644 => 100755 public/js/clients/shared/pdf.js mode change 100644 => 100755 public/js/clients/shared/pdf.js.LICENSE.txt mode change 100644 => 100755 public/js/coreui.js mode change 100644 => 100755 public/js/coreui.min.js mode change 100644 => 100755 public/js/localization.js mode change 100644 => 100755 public/js/localization.min.js mode change 100644 => 100755 public/js/ninja.js mode change 100644 => 100755 public/js/ninja.min.js mode change 100644 => 100755 public/js/setup/setup.js mode change 100644 => 100755 public/js/setup/setup.js.LICENSE.txt mode change 100644 => 100755 public/js/vendor/app.js mode change 100644 => 100755 public/js/vendor/datatables/datatables.min.css mode change 100644 => 100755 public/js/vendor/datatables/datatables.min.js mode change 100644 => 100755 public/js/vendor/jquery-3.3.1/jquery-3.3.1.js mode change 100644 => 100755 public/js/vendor/jquery-3.3.1/jquery-3.3.1.min.js mode change 100644 => 100755 public/js/vendor/pdf.js/pdf.min.js mode change 100644 => 100755 public/js/vendor/pdf.js/pdf.worker.min.js mode change 100644 => 100755 public/main.dart.js mode change 100644 => 100755 public/main.dart.js.map mode change 100644 => 100755 public/manifest.json mode change 100644 => 100755 public/mix-manifest.json mode change 100644 => 100755 public/robots.txt mode change 100644 => 100755 public/svg/403.svg mode change 100644 => 100755 public/svg/404.svg mode change 100644 => 100755 public/svg/500.svg mode change 100644 => 100755 public/svg/503.svg mode change 100644 => 100755 public/vendor/dropzone-5.7.0/.gitignore mode change 100644 => 100755 public/vendor/dropzone-5.7.0/CONTRIBUTING.md mode change 100644 => 100755 public/vendor/dropzone-5.7.0/LICENSE mode change 100644 => 100755 public/vendor/dropzone-5.7.0/README.md mode change 100644 => 100755 public/vendor/dropzone-5.7.0/component.json mode change 100644 => 100755 public/vendor/dropzone-5.7.0/composer.json mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/basic.css mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/dropzone-amd-module.js mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/dropzone.css mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/dropzone.js mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/dropzone.js.map mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/min/basic.min.css mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/min/dropzone-amd-module.min.js mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/min/dropzone.min.css mode change 100644 => 100755 public/vendor/dropzone-5.7.0/dist/min/dropzone.min.js mode change 100644 => 100755 public/vendor/dropzone-5.7.0/index.js mode change 100644 => 100755 public/vendor/dropzone-5.7.0/package.json mode change 100644 => 100755 public/vendor/livewire/livewire.js mode change 100644 => 100755 public/vendor/livewire/livewire.js.map mode change 100644 => 100755 public/vendor/livewire/manifest.json mode change 100644 => 100755 public/version.json create mode 100644 tests/Feature/Import/clients.csv diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php index e98adb53a90e..899b4060d105 100644 --- a/app/Http/Controllers/ImportController.php +++ b/app/Http/Controllers/ImportController.php @@ -79,7 +79,7 @@ class ImportController extends Controller $hash = Str::random(32); //store the csv in cache with an expiry of 10 minutes - Cache::put($hash, base64_encode(file_get_contents($request->file('file')->getPathname())), 60); + Cache::put($hash, base64_encode(file_get_contents($request->file('file')->getPathname())), 3600); //parse CSV $csv_array = $this->getCsvData(file_get_contents($request->file('file')->getPathname())); diff --git a/app/Import/Transformers/BaseTransformer.php b/app/Import/Transformers/BaseTransformer.php new file mode 100644 index 000000000000..559cc0e8e803 --- /dev/null +++ b/app/Import/Transformers/BaseTransformer.php @@ -0,0 +1,352 @@ +maps = $maps; + } + + + /** + * @param $data + * @param $field + * + * @return string + */ + public function getString($data, $field) + { + return (isset($data[$field]) && $data[$field]) ? $data[$field] : ''; + } + + public function getCurrencyByCode($data) + { + $code = $data['client.currency_id']; + + info(print_r($this->maps['currencies']->where('code', $code)->first(),1)); + + if($code) + return $this->maps['currencies']->where('code', $code)->first()->id; + + return $this->maps['company']->settings->currency_id; + } + + /** + * @param $name + * + * @return bool + */ + public function hasClient($name) + { + $name = trim(strtolower($name)); + + return isset($this->maps[ENTITY_CLIENT][$name]); + } + + /** + * @param $name + * + * @return bool + */ + public function hasVendor($name) + { + $name = trim(strtolower($name)); + + return isset($this->maps[ENTITY_VENDOR][$name]); + } + + + /** + * @param $key + * + * @return bool + */ + public function hasProduct($key) + { + $key = trim(strtolower($key)); + + return isset($this->maps[ENTITY_PRODUCT][$key]); + } + + + /** + * @param $data + * @param $field + * + * @return int + */ + public function getNumber($data, $field) + { + return (isset($data->$field) && $data->$field) ? $data->$field : 0; + } + + /** + * @param $data + * @param $field + * + * @return float + */ + public function getFloat($data, $field) + { + return (isset($data->$field) && $data->$field) ? Utils::parseFloat($data->$field) : 0; + } + + /** + * @param $name + * + * @return null + */ + public function getClientId($name) + { + $name = strtolower(trim($name)); + + return isset($this->maps[ENTITY_CLIENT][$name]) ? $this->maps[ENTITY_CLIENT][$name] : null; + } + + /** + * @param $name + * + * @return null + */ + public function getProduct($data, $key, $field, $default = false) + { + $productKey = trim(strtolower($data->$key)); + + if (! isset($this->maps['product'][$productKey])) { + return $default; + } + + $product = $this->maps['product'][$productKey]; + + return $product->$field ?: $default; + } + + /** + * @param $name + * + * @return null + */ + public function getContact($email) + { + $email = trim(strtolower($email)); + + if (! isset($this->maps['contact'][$email])) { + return false; + } + + return $this->maps['contact'][$email]; + } + + + /** + * @param $name + * + * @return null + */ + public function getCustomer($key) + { + $key = trim($key); + + if (! isset($this->maps['customer'][$key])) { + return false; + } + + return $this->maps['customer'][$key]; + } + + /** + * @param $name + * + * @return null + */ + public function getCountryId($name) + { + $name = strtolower(trim($name)); + + return isset($this->maps['countries'][$name]) ? $this->maps['countries'][$name] : null; + } + + /** + * @param $name + * + * @return null + */ + public function getCountryIdBy2($name) + { + $name = strtolower(trim($name)); + + return isset($this->maps['countries2'][$name]) ? $this->maps['countries2'][$name] : null; + } + + /** + * @param $name + * + * @return null + */ + public function getTaxRate($name) + { + $name = strtolower(trim($name)); + + return isset($this->maps['tax_rates'][$name]) ? $this->maps['tax_rates'][$name] : 0; + } + + /** + * @param $name + * + * @return null + */ + public function getTaxName($name) + { + $name = strtolower(trim($name)); + + return isset($this->maps['tax_names'][$name]) ? $this->maps['tax_names'][$name] : ''; + } + + /** + * @param $name + * + * @return mixed + */ + public function getFirstName($name) + { + $name = Utils::splitName($name); + + return $name[0]; + } + + /** + * @param $date + * @param string $format + * @param mixed $data + * @param mixed $field + * + * @return null + */ + public function getDate($data, $field) + { + if ($date = data_get($data, $field)) { + try { + $date = new Carbon($date); + } catch (Exception $e) { + // if we fail to parse return blank + $date = false; + } + } + + return $date ? $date->format('Y-m-d') : null; + } + + /** + * @param $name + * + * @return mixed + */ + public function getLastName($name) + { + $name = Utils::splitName($name); + + return $name[1]; + } + + /** + * @param $number + * + * @return string + */ + public function getInvoiceNumber($number) + { + return $number ? str_pad(trim($number), 4, '0', STR_PAD_LEFT) : null; + } + + /** + * @param $invoiceNumber + * + * @return null + */ + public function getInvoiceId($invoiceNumber) + { + $invoiceNumber = $this->getInvoiceNumber($invoiceNumber); + $invoiceNumber = strtolower($invoiceNumber); + return isset($this->maps[ENTITY_INVOICE][$invoiceNumber]) ? $this->maps[ENTITY_INVOICE][$invoiceNumber] : null; + } + + /** + * @param $invoiceNumber + * + * @return null + */ + public function getInvoicePublicId($invoiceNumber) + { + $invoiceNumber = $this->getInvoiceNumber($invoiceNumber); + $invoiceNumber = strtolower($invoiceNumber); + return isset($this->maps['invoices'][$invoiceNumber]) ? $this->maps['invoices'][$invoiceNumber]->public_id : null; + } + + /** + * @param $invoiceNumber + * + * @return bool + */ + public function hasInvoice($invoiceNumber) + { + $invoiceNumber = $this->getInvoiceNumber($invoiceNumber); + $invoiceNumber = strtolower($invoiceNumber); + + return isset($this->maps[ENTITY_INVOICE][$invoiceNumber]); + } + + /** + * @param $invoiceNumber + * + * @return null + */ + public function getInvoiceClientId($invoiceNumber) + { + $invoiceNumber = $this->getInvoiceNumber($invoiceNumber); + $invoiceNumber = strtolower($invoiceNumber); + + return isset($this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber]) ? $this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber] : null; + } + + /** + * @param $name + * + * @return null + */ + public function getVendorId($name) + { + $name = strtolower(trim($name)); + + return isset($this->maps[ENTITY_VENDOR][$name]) ? $this->maps[ENTITY_VENDOR][$name] : null; + } + + /** + * @param $name + * + * @return null + */ + public function getExpenseCategoryId($name) + { + $name = strtolower(trim($name)); + + return isset($this->maps[ENTITY_EXPENSE_CATEGORY][$name]) ? $this->maps[ENTITY_EXPENSE_CATEGORY][$name] : null; + } +} diff --git a/app/Import/Transformers/ClientTransformer.php b/app/Import/Transformers/ClientTransformer.php new file mode 100644 index 000000000000..f0a8c17adee2 --- /dev/null +++ b/app/Import/Transformers/ClientTransformer.php @@ -0,0 +1,70 @@ +name) && $this->hasClient($data->name)) { + return false; + } + + $settings = new \stdClass; + $settings->currency_id = (string)$this->getCurrencyByCode($data); + + return [ + 'company_id' => $this->maps['company']->id, + 'name' => $this->getString($data, 'client.name'), + 'work_phone' => $this->getString($data, 'client.phone'), + 'address1' => $this->getString($data, 'client.address1'), + 'address2' => $this->getString($data, 'client.address2'), + 'city' => $this->getString($data, 'client.city'), + 'state' => $this->getString($data, 'client.state'), + 'shipping_address1' => $this->getString($data, 'client.shipping_address1'), + 'shipping_address2' => $this->getString($data, 'client.shipping_address2'), + 'shipping_city' => $this->getString($data, 'client.shipping_city'), + 'shipping_state' => $this->getString($data, 'client.shipping_state'), + 'shipping_postal_code' => $this->getString($data, 'client.shipping_postal_code'), + 'public_notes' => $this->getString($data, 'client.public_notes'), + 'private_notes' => $this->getString($data, 'client.private_notes'), + 'website' => $this->getString($data, 'client.website'), + 'vat_number' => $this->getString($data, 'client.vat_number'), + 'id_number' => $this->getString($data, 'client.id_number'), + 'custom_value1' => $this->getString($data, 'client.custom1'), + 'custom_value2' => $this->getString($data, 'client.custom2'), + 'custom_value3' => $this->getString($data, 'client.custom3'), + 'custom_value4' => $this->getString($data, 'client.custom4'), + 'balance' => $this->getString($data, 'client.balance'), + 'paid_to_date' => $this->getString($data, 'client.paid_to_date'), + 'credit_balance' => 0, + 'settings' => $settings, + 'client_hash' => Str::random(40), + 'contacts' => [ + [ + 'first_name' => $this->getString($data, 'contact.first_name'), + 'last_name' => $this->getString($data, 'contact.last_name'), + 'email' => $this->getString($data, 'contact.email'), + 'phone' => $this->getString($data, 'contact.phone'), + 'custom_value1' => $this->getString($data, 'contact.custom1'), + 'custom_value2' => $this->getString($data, 'contact.custom2'), + 'custom_value3' => $this->getString($data, 'contact.custom3'), + 'custom_value4' => $this->getString($data, 'contact.custom4'), + ], + ], + 'country_id' => isset($data->country_id) ? $this->getCountryId($data->country_id) : null, + 'shipping_country_id' => isset($data->shipping_country_id) ? $this->getCountryId($data->shipping_country_id) : null, + ]; + + } +} diff --git a/app/Jobs/Import/CSVImport.php b/app/Jobs/Import/CSVImport.php index 9b51b78409ca..c899cea98a1d 100644 --- a/app/Jobs/Import/CSVImport.php +++ b/app/Jobs/Import/CSVImport.php @@ -11,8 +11,16 @@ namespace App\Jobs\Import; +use App\Factory\ClientFactory; +use App\Http\Requests\Client\StoreClientRequest; +use App\Import\Transformers\ClientTransformer; use App\Libraries\MultiDB; +use App\Models\Client; use App\Models\Company; +use App\Models\Currency; +use App\Models\User; +use App\Repositories\ClientContactRepository; +use App\Repositories\ClientRepository; use Exception; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -21,8 +29,11 @@ use Illuminate\Http\Request; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Str; use League\Csv\Reader; use League\Csv\Statement; +use Illuminate\Support\Facades\Validator; +use Illuminate\Support\Facades\Auth; class CSVImport implements ShouldQueue { @@ -40,6 +51,12 @@ class CSVImport implements ShouldQueue public $column_map; + public $import_array; + + public $error_array; + + public $maps; + /* [hash] => 2lTm7HVR3i9Zv3y86eQYZIO16yVJ7J6l [entity_type] => client @@ -84,7 +101,51 @@ class CSVImport implements ShouldQueue { MultiDB::setDb($this->company->db); - foreach($this->getCsv() as $record) { + $this->company->owner()->setCompany($this->company); + Auth::login($this->company->owner(), true); + + $this->buildMaps(); + + //sort the array by key + ksort($this->column_map); + + //clients + $records = $this->getCsvData(); + + $contact_repository = new ClientContactRepository(); + $client_repository = new ClientRepository($contact_repository); + $client_transformer = new ClientTransformer($this->maps); + + if($this->skip_header) + array_shift($records); + + foreach($records as $record) { + + $keys = $this->column_map; + $values = array_intersect_key($record, $this->column_map); + + $client_data = array_combine($keys, $values); + + $client = $client_transformer->transform($client_data); + + $validator = Validator::make($client, (new StoreClientRequest())->rules()); + + if ($validator->fails()) { + $this->error_array[] = ['client' => $client, 'error' => json_encode($validator->errors())]; + } + else{ + $client = $client_repository->save($client, ClientFactory::create($this->company->id, $this->setUser($record))); + + if(array_key_exists('client.balance', $client_data)) + $client->balance = preg_replace('/[^0-9,.]+/', '', $client_data['client.balance']); + + if(array_key_exists('client.paid_to_date', $client_data)) + $client->paid_to_date = preg_replace('/[^0-9,.]+/', '', $client_data['client.paid_to_date']); + + $client->save(); + + $this->import_array['clients'][] = $client->id; + } } @@ -95,10 +156,46 @@ class CSVImport implements ShouldQueue } +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + private function buildMaps() + { + $this->maps['currencies'] = Currency::all(); + $this->maps['users'] = $this->company->users; + $this->maps['company'] = $this->company; + + return $this; + } + + + private function setUser($record) + { + $user_key_exists = array_search('client.user_id', $this->column_map); + + if($user_key_exists) + return $this->findUser($record[$user_key_exists]); + else + return $this->company->owner()->id; + + } + + private function findUser($user_hash) + { + $user = User::where('company_id', $this->company->id) + ->where(\DB::raw('CONCAT_WS(" ", first_name, last_name)'), 'like', '%' . $user_hash . '%') + ->first(); + + if($user) + return $user->id; + else + return $this->company->owner()->id; + + } + private function getCsvData() { $base64_encoded_csv = Cache::get($this->hash); $csv = base64_decode($base64_encoded_csv); + $csv = Reader::createFromString($csv); $stmt = new Statement(); $data = iterator_to_array($stmt->process($csv)); @@ -109,7 +206,7 @@ class CSVImport implements ShouldQueue // Remove Invoice Ninja headers if (count($headers) && count($data) > 4) { $firstCell = $headers[0]; - if (strstr($firstCell, APP_NAME)) { + if (strstr($firstCell, config('ninja.app_name'))) { array_shift($data); // Invoice Ninja... array_shift($data); // array_shift($data); // Enitty Type Header diff --git a/public/.htaccess b/public/.htaccess old mode 100644 new mode 100755 diff --git a/public/assets/AssetManifest.json b/public/assets/AssetManifest.json old mode 100644 new mode 100755 diff --git a/public/assets/FontManifest.json b/public/assets/FontManifest.json old mode 100644 new mode 100755 diff --git a/public/assets/LICENSE b/public/assets/LICENSE old mode 100644 new mode 100755 diff --git a/public/assets/NOTICES b/public/assets/NOTICES old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/google-icon.png b/public/assets/assets/images/google-icon.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/logo.png b/public/assets/assets/images/logo.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/ach.png b/public/assets/assets/images/payment_types/ach.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/amex.png b/public/assets/assets/images/payment_types/amex.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/carteblanche.png b/public/assets/assets/images/payment_types/carteblanche.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/dinerscard.png b/public/assets/assets/images/payment_types/dinerscard.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/discover.png b/public/assets/assets/images/payment_types/discover.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/jcb.png b/public/assets/assets/images/payment_types/jcb.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/laser.png b/public/assets/assets/images/payment_types/laser.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/maestro.png b/public/assets/assets/images/payment_types/maestro.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/mastercard.png b/public/assets/assets/images/payment_types/mastercard.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/other.png b/public/assets/assets/images/payment_types/other.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/paypal.png b/public/assets/assets/images/payment_types/paypal.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/solo.png b/public/assets/assets/images/payment_types/solo.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/switch.png b/public/assets/assets/images/payment_types/switch.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/unionpay.png b/public/assets/assets/images/payment_types/unionpay.png old mode 100644 new mode 100755 diff --git a/public/assets/assets/images/payment_types/visa.png b/public/assets/assets/images/payment_types/visa.png old mode 100644 new mode 100755 diff --git a/public/assets/fonts/MaterialIcons-Regular.otf b/public/assets/fonts/MaterialIcons-Regular.otf old mode 100644 new mode 100755 diff --git a/public/assets/fonts/MaterialIcons-Regular.ttf b/public/assets/fonts/MaterialIcons-Regular.ttf old mode 100644 new mode 100755 diff --git a/public/assets/fonts/Roboto-Regular.ttf b/public/assets/fonts/Roboto-Regular.ttf old mode 100644 new mode 100755 diff --git a/public/assets/packages/flutter_auth_buttons/fonts/SF-Pro-Medium.ttf b/public/assets/packages/flutter_auth_buttons/fonts/SF-Pro-Medium.ttf old mode 100644 new mode 100755 diff --git a/public/assets/packages/flutter_auth_buttons/graphics/apple_logo_black.png b/public/assets/packages/flutter_auth_buttons/graphics/apple_logo_black.png old mode 100644 new mode 100755 diff --git a/public/assets/packages/flutter_auth_buttons/graphics/apple_logo_white.png b/public/assets/packages/flutter_auth_buttons/graphics/apple_logo_white.png old mode 100644 new mode 100755 diff --git a/public/assets/packages/flutter_auth_buttons/graphics/flogo-HexRBG-Wht-100.png b/public/assets/packages/flutter_auth_buttons/graphics/flogo-HexRBG-Wht-100.png old mode 100644 new mode 100755 diff --git a/public/assets/packages/flutter_auth_buttons/graphics/google-logo.png b/public/assets/packages/flutter_auth_buttons/graphics/google-logo.png old mode 100644 new mode 100755 diff --git a/public/assets/packages/flutter_auth_buttons/graphics/ms-symbollockup_mssymbol_19.png b/public/assets/packages/flutter_auth_buttons/graphics/ms-symbollockup_mssymbol_19.png old mode 100644 new mode 100755 diff --git a/public/assets/packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf b/public/assets/packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf old mode 100644 new mode 100755 diff --git a/public/assets/packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf b/public/assets/packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf old mode 100644 new mode 100755 diff --git a/public/assets/packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf b/public/assets/packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf old mode 100644 new mode 100755 diff --git a/public/assets/web/assets/fonts/Roboto-Regular.ttf b/public/assets/web/assets/fonts/Roboto-Regular.ttf old mode 100644 new mode 100755 diff --git a/public/css/app.css b/public/css/app.css old mode 100644 new mode 100755 diff --git a/public/css/card-js.min.css b/public/css/card-js.min.css old mode 100644 new mode 100755 diff --git a/public/css/ninja.css b/public/css/ninja.css old mode 100644 new mode 100755 diff --git a/public/css/ninja.min.css b/public/css/ninja.min.css old mode 100644 new mode 100755 diff --git a/public/css/tailwind-1.2.0.css b/public/css/tailwind-1.2.0.css old mode 100644 new mode 100755 diff --git a/public/css/tailwindcss@1.4.6.css b/public/css/tailwindcss@1.4.6.css old mode 100644 new mode 100755 diff --git a/public/favicon.ico b/public/favicon.ico old mode 100644 new mode 100755 diff --git a/public/favicon.png b/public/favicon.png old mode 100644 new mode 100755 diff --git a/public/flutter_service_worker.js b/public/flutter_service_worker.js old mode 100644 new mode 100755 diff --git a/public/icons/Icon-192.png b/public/icons/Icon-192.png old mode 100644 new mode 100755 diff --git a/public/icons/Icon-512.png b/public/icons/Icon-512.png old mode 100644 new mode 100755 diff --git a/public/images/american-express.png b/public/images/american-express.png old mode 100644 new mode 100755 diff --git a/public/images/created-by-invoiceninja-new.png b/public/images/created-by-invoiceninja-new.png old mode 100644 new mode 100755 diff --git a/public/images/created-by-invoiceninja.jpg b/public/images/created-by-invoiceninja.jpg old mode 100644 new mode 100755 diff --git a/public/images/diners-club.png b/public/images/diners-club.png old mode 100644 new mode 100755 diff --git a/public/images/discover.png b/public/images/discover.png old mode 100644 new mode 100755 diff --git a/public/images/invoiceninja-black-logo-2.png b/public/images/invoiceninja-black-logo-2.png old mode 100644 new mode 100755 diff --git a/public/images/invoiceninja-white-logo.png b/public/images/invoiceninja-white-logo.png old mode 100644 new mode 100755 diff --git a/public/images/logo.png b/public/images/logo.png old mode 100644 new mode 100755 diff --git a/public/images/mastercard.png b/public/images/mastercard.png old mode 100644 new mode 100755 diff --git a/public/images/paypal.png b/public/images/paypal.png old mode 100644 new mode 100755 diff --git a/public/images/svg/activity.svg b/public/images/svg/activity.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/align-left.svg b/public/images/svg/align-left.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/clock.svg b/public/images/svg/clock.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/credit-card.svg b/public/images/svg/credit-card.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/download.svg b/public/images/svg/download.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/file-text.svg b/public/images/svg/file-text.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/file.svg b/public/images/svg/file.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/shield.svg b/public/images/svg/shield.svg old mode 100644 new mode 100755 diff --git a/public/images/svg/user.svg b/public/images/svg/user.svg old mode 100644 new mode 100755 diff --git a/public/images/visa.png b/public/images/visa.png old mode 100644 new mode 100755 diff --git a/public/index.php b/public/index.php old mode 100644 new mode 100755 diff --git a/public/js/app.js b/public/js/app.js old mode 100644 new mode 100755 diff --git a/public/js/client_create.js b/public/js/client_create.js old mode 100644 new mode 100755 diff --git a/public/js/client_create.min.js b/public/js/client_create.min.js old mode 100644 new mode 100755 diff --git a/public/js/client_edit.js b/public/js/client_edit.js old mode 100644 new mode 100755 diff --git a/public/js/client_edit.min.js b/public/js/client_edit.min.js old mode 100644 new mode 100755 diff --git a/public/js/client_list.js b/public/js/client_list.js old mode 100644 new mode 100755 diff --git a/public/js/client_list.min.js b/public/js/client_list.min.js old mode 100644 new mode 100755 diff --git a/public/js/client_settings.js b/public/js/client_settings.js old mode 100644 new mode 100755 diff --git a/public/js/client_settings.min.js b/public/js/client_settings.min.js old mode 100644 new mode 100755 diff --git a/public/js/client_show.js b/public/js/client_show.js old mode 100644 new mode 100755 diff --git a/public/js/client_show.min.js b/public/js/client_show.min.js old mode 100644 new mode 100755 diff --git a/public/js/clients/invoices/action-selectors.js b/public/js/clients/invoices/action-selectors.js old mode 100644 new mode 100755 diff --git a/public/js/clients/invoices/action-selectors.js.LICENSE.txt b/public/js/clients/invoices/action-selectors.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/invoices/payment.js b/public/js/clients/invoices/payment.js old mode 100644 new mode 100755 diff --git a/public/js/clients/invoices/payment.js.LICENSE.txt b/public/js/clients/invoices/payment.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payment_methods/authorize-ach.js b/public/js/clients/payment_methods/authorize-ach.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payment_methods/authorize-ach.js.LICENSE.txt b/public/js/clients/payment_methods/authorize-ach.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payment_methods/authorize-authorize-card.js b/public/js/clients/payment_methods/authorize-authorize-card.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payment_methods/authorize-authorize-card.js.LICENSE.txt b/public/js/clients/payment_methods/authorize-authorize-card.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payment_methods/authorize-stripe-card.js b/public/js/clients/payment_methods/authorize-stripe-card.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payment_methods/authorize-stripe-card.js.LICENSE.txt b/public/js/clients/payment_methods/authorize-stripe-card.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payment_methods/stripe-ach.js b/public/js/clients/payment_methods/stripe-ach.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/alipay.js b/public/js/clients/payments/alipay.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/alipay.js.LICENSE.txt b/public/js/clients/payments/alipay.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/authorize-credit-card-payment.js b/public/js/clients/payments/authorize-credit-card-payment.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/authorize-credit-card-payment.js.LICENSE.txt b/public/js/clients/payments/authorize-credit-card-payment.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/card-js.min.js b/public/js/clients/payments/card-js.min.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/checkout.com.js b/public/js/clients/payments/checkout.com.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/checkout.com.js.LICENSE.txt b/public/js/clients/payments/checkout.com.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/process.js b/public/js/clients/payments/process.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/process.js.LICENSE.txt b/public/js/clients/payments/process.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/sofort.js b/public/js/clients/payments/sofort.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/sofort.js.LICENSE.txt b/public/js/clients/payments/sofort.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-ach.js b/public/js/clients/payments/stripe-ach.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-ach.js.LICENSE.txt b/public/js/clients/payments/stripe-ach.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-alipay.js b/public/js/clients/payments/stripe-alipay.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-alipay.js.LICENSE.txt b/public/js/clients/payments/stripe-alipay.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-credit-card.js b/public/js/clients/payments/stripe-credit-card.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-credit-card.js.LICENSE.txt b/public/js/clients/payments/stripe-credit-card.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-sofort.js b/public/js/clients/payments/stripe-sofort.js old mode 100644 new mode 100755 diff --git a/public/js/clients/payments/stripe-sofort.js.LICENSE.txt b/public/js/clients/payments/stripe-sofort.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/quotes/action-selectors.js b/public/js/clients/quotes/action-selectors.js old mode 100644 new mode 100755 diff --git a/public/js/clients/quotes/action-selectors.js.LICENSE.txt b/public/js/clients/quotes/action-selectors.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/quotes/approve.js b/public/js/clients/quotes/approve.js old mode 100644 new mode 100755 diff --git a/public/js/clients/quotes/approve.js.LICENSE.txt b/public/js/clients/quotes/approve.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/clients/shared/multiple-downloads.js b/public/js/clients/shared/multiple-downloads.js old mode 100644 new mode 100755 diff --git a/public/js/clients/shared/pdf.js b/public/js/clients/shared/pdf.js old mode 100644 new mode 100755 diff --git a/public/js/clients/shared/pdf.js.LICENSE.txt b/public/js/clients/shared/pdf.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/coreui.js b/public/js/coreui.js old mode 100644 new mode 100755 diff --git a/public/js/coreui.min.js b/public/js/coreui.min.js old mode 100644 new mode 100755 diff --git a/public/js/localization.js b/public/js/localization.js old mode 100644 new mode 100755 diff --git a/public/js/localization.min.js b/public/js/localization.min.js old mode 100644 new mode 100755 diff --git a/public/js/ninja.js b/public/js/ninja.js old mode 100644 new mode 100755 diff --git a/public/js/ninja.min.js b/public/js/ninja.min.js old mode 100644 new mode 100755 diff --git a/public/js/setup/setup.js b/public/js/setup/setup.js old mode 100644 new mode 100755 diff --git a/public/js/setup/setup.js.LICENSE.txt b/public/js/setup/setup.js.LICENSE.txt old mode 100644 new mode 100755 diff --git a/public/js/vendor/app.js b/public/js/vendor/app.js old mode 100644 new mode 100755 diff --git a/public/js/vendor/datatables/datatables.min.css b/public/js/vendor/datatables/datatables.min.css old mode 100644 new mode 100755 diff --git a/public/js/vendor/datatables/datatables.min.js b/public/js/vendor/datatables/datatables.min.js old mode 100644 new mode 100755 diff --git a/public/js/vendor/jquery-3.3.1/jquery-3.3.1.js b/public/js/vendor/jquery-3.3.1/jquery-3.3.1.js old mode 100644 new mode 100755 diff --git a/public/js/vendor/jquery-3.3.1/jquery-3.3.1.min.js b/public/js/vendor/jquery-3.3.1/jquery-3.3.1.min.js old mode 100644 new mode 100755 diff --git a/public/js/vendor/pdf.js/pdf.min.js b/public/js/vendor/pdf.js/pdf.min.js old mode 100644 new mode 100755 diff --git a/public/js/vendor/pdf.js/pdf.worker.min.js b/public/js/vendor/pdf.js/pdf.worker.min.js old mode 100644 new mode 100755 diff --git a/public/main.dart.js b/public/main.dart.js old mode 100644 new mode 100755 diff --git a/public/main.dart.js.map b/public/main.dart.js.map old mode 100644 new mode 100755 diff --git a/public/manifest.json b/public/manifest.json old mode 100644 new mode 100755 diff --git a/public/mix-manifest.json b/public/mix-manifest.json old mode 100644 new mode 100755 diff --git a/public/robots.txt b/public/robots.txt old mode 100644 new mode 100755 diff --git a/public/svg/403.svg b/public/svg/403.svg old mode 100644 new mode 100755 diff --git a/public/svg/404.svg b/public/svg/404.svg old mode 100644 new mode 100755 diff --git a/public/svg/500.svg b/public/svg/500.svg old mode 100644 new mode 100755 diff --git a/public/svg/503.svg b/public/svg/503.svg old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/.gitignore b/public/vendor/dropzone-5.7.0/.gitignore old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/CONTRIBUTING.md b/public/vendor/dropzone-5.7.0/CONTRIBUTING.md old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/LICENSE b/public/vendor/dropzone-5.7.0/LICENSE old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/README.md b/public/vendor/dropzone-5.7.0/README.md old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/component.json b/public/vendor/dropzone-5.7.0/component.json old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/composer.json b/public/vendor/dropzone-5.7.0/composer.json old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/basic.css b/public/vendor/dropzone-5.7.0/dist/basic.css old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/dropzone-amd-module.js b/public/vendor/dropzone-5.7.0/dist/dropzone-amd-module.js old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/dropzone.css b/public/vendor/dropzone-5.7.0/dist/dropzone.css old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/dropzone.js b/public/vendor/dropzone-5.7.0/dist/dropzone.js old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/dropzone.js.map b/public/vendor/dropzone-5.7.0/dist/dropzone.js.map old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/min/basic.min.css b/public/vendor/dropzone-5.7.0/dist/min/basic.min.css old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/min/dropzone-amd-module.min.js b/public/vendor/dropzone-5.7.0/dist/min/dropzone-amd-module.min.js old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/min/dropzone.min.css b/public/vendor/dropzone-5.7.0/dist/min/dropzone.min.css old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/dist/min/dropzone.min.js b/public/vendor/dropzone-5.7.0/dist/min/dropzone.min.js old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/index.js b/public/vendor/dropzone-5.7.0/index.js old mode 100644 new mode 100755 diff --git a/public/vendor/dropzone-5.7.0/package.json b/public/vendor/dropzone-5.7.0/package.json old mode 100644 new mode 100755 diff --git a/public/vendor/livewire/livewire.js b/public/vendor/livewire/livewire.js old mode 100644 new mode 100755 diff --git a/public/vendor/livewire/livewire.js.map b/public/vendor/livewire/livewire.js.map old mode 100644 new mode 100755 diff --git a/public/vendor/livewire/manifest.json b/public/vendor/livewire/manifest.json old mode 100644 new mode 100755 diff --git a/public/version.json b/public/version.json old mode 100644 new mode 100755 diff --git a/tests/Feature/Import/ImportCsvTest.php b/tests/Feature/Import/ImportCsvTest.php index 8d7fb687c662..807ecf7b921c 100644 --- a/tests/Feature/Import/ImportCsvTest.php +++ b/tests/Feature/Import/ImportCsvTest.php @@ -10,8 +10,11 @@ */ namespace Tests\Feature\Import; +use App\Jobs\Import\CSVImport; use App\Utils\Traits\MakesHash; use Illuminate\Routing\Middleware\ThrottleRequests; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Str; use League\Csv\Reader; use League\Csv\Statement; use Tests\MockAccountData; @@ -36,7 +39,7 @@ class ImportCsvTest extends TestCase // $this->faker = \Faker\Factory::create(); - // $this->makeTestData(); + $this->makeTestData(); $this->withoutExceptionHandling(); } @@ -49,6 +52,34 @@ class ImportCsvTest extends TestCase } + public function testClientCsvImport() + { + $csv = file_get_contents(base_path().'/tests/Feature/Import/clients.csv'); + $hash = Str::random(32); + $column_map = [ + 1 => 'client.balance', + 2 => 'client.paid_to_date', + 0 => 'client.name', + 19 => 'client.currency_id', + 20 => 'client.public_notes', + 21 => 'client.private_notes', + 22 => 'contact.first_name', + 23 => 'contact.last_name', + ]; + + $data = [ + 'hash' => $hash, + 'column_map' => $column_map, + 'skip_header' => true, + 'entity_type'=> 'client', + ]; + + Cache::put($hash, base64_encode($csv), 360); + + CSVImport::dispatchNow($data, $this->company); + + } + private function getCsvData($csvfile) { if (! ini_get('auto_detect_line_endings')) { diff --git a/tests/Feature/Import/clients.csv b/tests/Feature/Import/clients.csv new file mode 100644 index 000000000000..772d58a3d196 --- /dev/null +++ b/tests/Feature/Import/clients.csv @@ -0,0 +1,24 @@ +"Invoice Ninja v4.5.17 - December 15, 2020 10:58 pm","","","","","","","","","","","","","","","","","","","","","","","","","" +"","","","","","","","","","","","","","","","","","","","","","","","","","" +"CLIENTS","","","","","","","","","","","","","","","","","","","","","","","","","" +"Name","Balance","Paid to Date","Billing Street","Billing Apt/Suite","Billing City","Billing State/Province","Billing Postal Code","Billing Country","Shipping Street","Shipping Apt/Suite","Shipping City","Shipping State/Province","Shipping Postal Code","Shipping Country","ID Number","VAT Number","Website","Phone","Currency","Public Notes","Private Notes","First Name","Last Name","Email","Phone" +"Ludwig Krajcik DVM","$-142.85","$205.15","371 O'Connell Summit","Suite 612","Lornamouth","New York","83425-0771","","","","","","","","","","","","","","","Terrill","Ondricka","brook59@example.org","1-537-759-0369" +"Bradly Jaskolski Sr.","$310.81","$313.71","21854 Prosacco Isle","Suite 619","Vicentastad","Colorado","05144","","","","","","","","","","","","","","","Pink","Balistreri","gheidenreich@example.org","1-995-790-2394 x58884" +"Mr. Dustin Stehr I","$285.70","$250.97","2941 Terence Station","Apt. 761","Bernierbury","Massachusetts","47675","","","","","","","","","","","","","","","Shemar","Stehr","labadie.dominique@example.com","624-610-5940" +"Dr. Baron Armstrong Sr.","$241.53","$280.42","9469 Ofelia Gateway","Suite 748","Evelynside","New Hampshire","66872","","","","","","","","","","","","","","","Fabiola","Mitchell","nico78@example.net","1-986-772-8058 x00345" +"Dr. Clemens Douglas MD","$317.94","$342.92","2919 Thompson Common Suite 410","Suite 381","Port Margie","Nevada","49890","","","","","","","","","","","","","","","Lolita","Tremblay","daphney.marquardt@example.com","1-461-699-9192 x9875" +"Dr. Claire Huel Sr.","$333.45","$359.51","363 Arlene Causeway Suite 763","Suite 409","Millerstad","Florida","25750","","","","","","","","","","","","","","","Brown","Lakin","vbeer@example.net","(776) 821-0650 x839" +"Francisca Padberg","$366.58","$203.16","5558 Ratke Flats","Suite 511","Krystelport","Alabama","15359-3783","","","","","","","","","","","","","","","Hallie","Dooley","kgottlieb@example.net","1-573-770-4753 x72129" +"Dr. Roy Kihn","$272.12","$251.41","20236 O'Hara Shores","Suite 368","Aliciaport","North Carolina","35415","","","","","","","","","","","","","","","Elwyn","Daugherty","wunsch.rozella@example.org","(745) 859-5855 x04216" +"Nasir Vandervort","$401.23","$173.17","24599 Hills Centers Suite 467","Apt. 038","North German","Ohio","85363-4720","","","","","","","","","","","","","","","Tre","Moore","wilfrid.kuhic@example.com","1-519-675-7395" +"Garry Rosenbaum","$271.82","$306.63","7127 Heidenreich Union Apt. 168","Suite 441","North Murray","North Carolina","29242","","","","","","","","","","","","","","","Ricardo","Johnston","ddubuque@example.com","(682) 216-1962" +"Hildegard Crona PhD","$398.96","$162.49","60142 Janice Islands","Apt. 627","South Stantown","Colorado","10298-5737","","","","","","","","","","","","","","","Miles","Tremblay","sabrina86@example.org","775-210-8656 x93138" +"Kristopher White I","$318.14","$423.20","7498 Brook Crest Apt. 175","Suite 682","Marianoland","Connecticut","86235-9979","","","","","","","","","","","","","","","Mateo","Welch","jedidiah64@example.com","847.353.7644" +"Ethan Grant","$380.71","$367.38","26755 June Extension Suite 589","Suite 706","North Krystelmouth","Delaware","12414","","","","","","","","","","","","","","","Colton","Muller","dorian.mayert@example.net","(267) 647-0537" +"Terry Shields","$230.25","$290.83","60946 Kayden Camp Apt. 046","Apt. 178","Douglashaven","Wyoming","68992","","","","","","","","","","","","","","","Dashawn","Homenick","hills.gina@example.net","(478) 814-9961" +"Agustina Lockman","$351.60","$264.81","152 Pattie Coves","Suite 971","North Mohamed","Hawaii","52966","","","","","","","","","","","","","","","Bert","Fritsch","greilly@example.org","15342929833" +"Alfonso Schimmel","$343.71","$200.99","358 Hills Coves","Apt. 032","Lake Aisha","District of Columbia","68945-0439","","","","","","","","","","","","","","","Antonio","Hayes","dkshlerin@example.com","1-350-691-4459 x775" +"Vergie Monahan","$210.27","$201.10","64004 Anderson Mall Suite 207","Suite 469","Oleshire","California","78369","","","","","","","","","","","","","","","Hilario","Morissette","zjacobs@example.net","552.914.6800 x81120" +"Carol Cremin","$301.53","$473.39","68731 Bartoletti Crescent","Suite 855","Aaronland","Wyoming","07924","","","","","","","","","","","","","","","Nathen","Wehner","jacobi.rosendo@example.com","1-223-910-2060 x09970" +"Randal Bosco MD","$318.71","$226.47","51884 Peter Falls","Suite 314","Angelicaville","Nebraska","78016-3254","","","","","","","","","","","","","","","Angelo","Ward","kozey.aurelio@example.org","1-329-488-8800" +"Ms. Alena Cassin","$262.45","$388.50","706 Delfina Burgs","Apt. 996","Bertaton","Ohio","22957","","","","","","","","","","","","","","","Eusebio","Reinger","golden.green@example.org","429-551-1362" From ece104695c8e2e2347854ee9d336a9230f4e9aec Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 16 Dec 2020 21:13:02 +1100 Subject: [PATCH 9/9] Client Imports --- app/Import/Transformers/BaseTransformer.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/Import/Transformers/BaseTransformer.php b/app/Import/Transformers/BaseTransformer.php index 559cc0e8e803..f0153be91513 100644 --- a/app/Import/Transformers/BaseTransformer.php +++ b/app/Import/Transformers/BaseTransformer.php @@ -39,10 +39,8 @@ class BaseTransformer public function getCurrencyByCode($data) { - $code = $data['client.currency_id']; + $code = array_key_exists('client.currency_id', $data) ? $data['client.currency_id'] : false; - info(print_r($this->maps['currencies']->where('code', $code)->first(),1)); - if($code) return $this->maps['currencies']->where('code', $code)->first()->id;