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"