Support importing JSON file

This commit is contained in:
Hillel Coren 2016-06-02 22:03:59 +03:00
parent e312f00b80
commit 0acf4ff1fc
23 changed files with 323 additions and 172 deletions

View File

@ -43,10 +43,12 @@ class ExportController extends BaseController
$manager->setSerializer(new ArraySerializer()); $manager->setSerializer(new ArraySerializer());
$account = Auth::user()->account; $account = Auth::user()->account;
$account->loadAllData(); $account->load(['clients.contacts', 'clients.invoices.payments', 'clients.invoices.invoice_items']);
$resource = new Item($account, new AccountTransformer); $resource = new Item($account, new AccountTransformer);
$data = $manager->createData($resource)->toArray(); $data = $manager->parseIncludes('clients.invoices.payments')
->createData($resource)
->toArray();
return response()->json($data); return response()->json($data);
} }

View File

@ -36,8 +36,11 @@ class ImportController extends BaseController
if ($source === IMPORT_CSV) { if ($source === IMPORT_CSV) {
$data = $this->importService->mapCSV($files); $data = $this->importService->mapCSV($files);
return View::make('accounts.import_map', ['data' => $data]); return View::make('accounts.import_map', ['data' => $data]);
} elseif ($source === IMPORT_JSON) {
$results = $this->importService->importJSON($files[IMPORT_JSON]);
return $this->showResult($results);
} else { } else {
$results = $this->importService->import($source, $files); $results = $this->importService->importFiles($source, $files);
return $this->showResult($results); return $this->showResult($results);
} }
} catch (Exception $exception) { } catch (Exception $exception) {

View File

@ -25,12 +25,12 @@ class CreatePaymentRequest extends PaymentRequest
$invoice = Invoice::scope($input['invoice'])->firstOrFail(); $invoice = Invoice::scope($input['invoice'])->firstOrFail();
$rules = array( $rules = array(
'client' => 'required', 'client' => 'required', // TODO: change to client_id once views are updated
'invoice' => 'required', 'invoice' => 'required', // TODO: change to invoice_id once views are updated
'amount' => "required|less_than:{$invoice->balance}|positive", 'amount' => "required|less_than:{$invoice->balance}|positive",
); );
if ($input['payment_type_id'] == PAYMENT_TYPE_CREDIT) { if ( ! empty($input['payment_type_id']) && $input['payment_type_id'] == PAYMENT_TYPE_CREDIT) {
$rules['payment_type_id'] = 'has_credit:'.$input['client'].','.$input['amount']; $rules['payment_type_id'] = 'has_credit:'.$input['client'].','.$input['amount'];
} }

View File

@ -472,6 +472,7 @@ if (!defined('CONTACT_EMAIL')) {
define('DEFAULT_SEND_RECURRING_HOUR', 8); define('DEFAULT_SEND_RECURRING_HOUR', 8);
define('IMPORT_CSV', 'CSV'); define('IMPORT_CSV', 'CSV');
define('IMPORT_JSON', 'JSON');
define('IMPORT_FRESHBOOKS', 'FreshBooks'); define('IMPORT_FRESHBOOKS', 'FreshBooks');
define('IMPORT_WAVE', 'Wave'); define('IMPORT_WAVE', 'Wave');
define('IMPORT_RONIN', 'Ronin'); define('IMPORT_RONIN', 'Ronin');

View File

@ -3,6 +3,7 @@
use Auth; use Auth;
use Utils; use Utils;
use App\Models\EntityModel;
use App\Events\ClientWasCreated; use App\Events\ClientWasCreated;
use App\Events\QuoteWasCreated; use App\Events\QuoteWasCreated;
use App\Events\InvoiceWasCreated; use App\Events\InvoiceWasCreated;
@ -63,6 +64,10 @@ class SubscriptionListener
private function checkSubscriptions($eventId, $entity, $transformer, $include = '') private function checkSubscriptions($eventId, $entity, $transformer, $include = '')
{ {
if ( ! EntityModel::$notifySubscriptions) {
return;
}
$subscription = $entity->account->getSubscription($eventId); $subscription = $entity->account->getSubscription($eventId);
if ($subscription) { if ($subscription) {

View File

@ -545,7 +545,7 @@ class Account extends Eloquent
if ($this->hasClientNumberPattern($invoice) && !$clientId) { if ($this->hasClientNumberPattern($invoice) && !$clientId) {
// do nothing, we don't yet know the value // do nothing, we don't yet know the value
} else { } elseif ( ! $invoice->invoice_number) {
$invoice->invoice_number = $this->getNextInvoiceNumber($invoice); $invoice->invoice_number = $this->getNextInvoiceNumber($invoice);
} }
} }
@ -649,7 +649,7 @@ class Account extends Eloquent
return $this->getNextInvoiceNumber($invoice); return $this->getNextInvoiceNumber($invoice);
} }
public function getNextInvoiceNumber($invoice) public function getNextInvoiceNumber($invoice, $validateUnique = true)
{ {
if ($this->hasNumberPattern($invoice->invoice_type_id)) { if ($this->hasNumberPattern($invoice->invoice_type_id)) {
$number = $this->getNumberPattern($invoice); $number = $this->getNumberPattern($invoice);
@ -657,13 +657,16 @@ class Account extends Eloquent
$counter = $this->getCounter($invoice->invoice_type_id); $counter = $this->getCounter($invoice->invoice_type_id);
$prefix = $this->getNumberPrefix($invoice->invoice_type_id); $prefix = $this->getNumberPrefix($invoice->invoice_type_id);
$counterOffset = 0; $counterOffset = 0;
$check = false;
// confirm the invoice number isn't already taken // confirm the invoice number isn't already taken
do { do {
$number = $prefix . str_pad($counter, $this->invoice_number_padding, '0', STR_PAD_LEFT); $number = $prefix . str_pad($counter, $this->invoice_number_padding, '0', STR_PAD_LEFT);
if ($validateUnique) {
$check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first(); $check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
$counter++; $counter++;
$counterOffset++; $counterOffset++;
}
} while ($check); } while ($check);
// update the invoice counter to be caught up // update the invoice counter to be caught up
@ -688,7 +691,7 @@ class Account extends Eloquent
public function incrementCounter($invoice) public function incrementCounter($invoice)
{ {
// if they didn't use the counter don't increment it // if they didn't use the counter don't increment it
if ($invoice->invoice_number != $this->getNextInvoiceNumber($invoice)) { if ($invoice->invoice_number != $this->getNextInvoiceNumber($invoice, false)) {
return; return;
} }
@ -1452,6 +1455,14 @@ class Account extends Eloquent
} }
} }
Account::updated(function ($account) { Account::updated(function ($account)
{
// prevent firing event if the invoice/quote counter was changed
// TODO: remove once counters are moved to separate table
$dirty = $account->getDirty();
if (isset($dirty['invoice_number_counter']) || isset($dirty['quote_number_counter'])) {
return;
}
Event::fire(new UserSettingsChanged()); Event::fire(new UserSettingsChanged());
}); });

View File

@ -9,21 +9,30 @@ class EntityModel extends Eloquent
public $timestamps = true; public $timestamps = true;
protected $hidden = ['id']; protected $hidden = ['id'];
public static $notifySubscriptions = true;
public static function createNew($context = null) public static function createNew($context = null)
{ {
$className = get_called_class(); $className = get_called_class();
$entity = new $className(); $entity = new $className();
if ($context) { if ($context) {
$entity->user_id = $context instanceof User ? $context->id : $context->user_id; $user = $context instanceof User ? $context : $context->user;
$entity->account_id = $context->account_id; $account = $context->account;
} elseif (Auth::check()) { } elseif (Auth::check()) {
$entity->user_id = Auth::user()->id; $user = Auth::user();
$entity->account_id = Auth::user()->account_id; $account = Auth::user()->account;
} else { } else {
Utils::fatalError(); Utils::fatalError();
} }
$entity->user_id = $user->id;
$entity->account_id = $account->id;
// store references to the original user/account to prevent needing to reload them
$entity->setRelation('user', $user);
$entity->setRelation('account', $account);
if (method_exists($className, 'withTrashed')){ if (method_exists($className, 'withTrashed')){
$lastEntity = $className::withTrashed() $lastEntity = $className::withTrashed()
->scope(false, $entity->account_id); ->scope(false, $entity->account_id);

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
class PaymentTransformer extends BaseTransformer class PaymentTransformer extends BaseTransformer
{ {
public function transform($data, $maps) public function transform($data)
{ {
return new Item($data, function ($data) use ($maps) { return new Item($data, function ($data) {
return [ return [
'amount' => $data->paid, 'amount' => $data->paid,
'payment_date_sql' => $data->create_date, 'payment_date_sql' => $data->create_date,

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
class PaymentTransformer extends BaseTransformer class PaymentTransformer extends BaseTransformer
{ {
public function transform($data, $maps) public function transform($data)
{ {
return new Item($data, function ($data) use ($maps) { return new Item($data, function ($data) {
return [ return [
'amount' => $data->paid_total, 'amount' => $data->paid_total,
'payment_date_sql' => $this->getDate($data->last_paid_on), 'payment_date_sql' => $this->getDate($data->last_paid_on),

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
class PaymentTransformer extends BaseTransformer class PaymentTransformer extends BaseTransformer
{ {
public function transform($data, $maps) public function transform($data)
{ {
return new Item($data, function ($data) use ($maps) { return new Item($data, function ($data) {
return [ return [
'amount' => $data->paid, 'amount' => $data->paid,
'payment_date_sql' => $data->date_paid, 'payment_date_sql' => $data->date_paid,

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
class PaymentTransformer extends BaseTransformer class PaymentTransformer extends BaseTransformer
{ {
public function transform($data, $maps) public function transform($data)
{ {
return new Item($data, function ($data) use ($maps) { return new Item($data, function ($data) {
return [ return [
'amount' => (float) $data->paid_to_date, 'amount' => (float) $data->paid_to_date,
'payment_date_sql' => $this->getDate($data->date), 'payment_date_sql' => $this->getDate($data->date),

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
class PaymentTransformer extends BaseTransformer class PaymentTransformer extends BaseTransformer
{ {
public function transform($data, $maps) public function transform($data)
{ {
return new Item($data, function ($data) use ($maps) { return new Item($data, function ($data) {
return [ return [
'amount' => (float) $data->total - (float) $data->balance, 'amount' => (float) $data->total - (float) $data->balance,
'payment_date_sql' => $data->date_paid, 'payment_date_sql' => $data->date_paid,

View File

@ -5,13 +5,13 @@ use League\Fractal\Resource\Item;
class PaymentTransformer extends BaseTransformer class PaymentTransformer extends BaseTransformer
{ {
public function transform($data, $maps) public function transform($data)
{ {
if ( ! $this->getInvoiceClientId($data->invoice_num)) { if ( ! $this->getInvoiceClientId($data->invoice_num)) {
return false; return false;
} }
return new Item($data, function ($data) use ($maps) { return new Item($data, function ($data) {
return [ return [
'amount' => (float) $data->amount, 'amount' => (float) $data->amount,
'payment_date_sql' => $this->getDate($data->payment_date), 'payment_date_sql' => $this->getDate($data->payment_date),

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
class PaymentTransformer extends BaseTransformer class PaymentTransformer extends BaseTransformer
{ {
public function transform($data, $maps) public function transform($data)
{ {
return new Item($data, function ($data) use ($maps) { return new Item($data, function ($data) {
return [ return [
'amount' => (float) $data->total - (float) $data->balance, 'amount' => (float) $data->total - (float) $data->balance,
'payment_date_sql' => $data->last_payment_date, 'payment_date_sql' => $data->last_payment_date,

View File

@ -118,11 +118,13 @@ class ClientRepository extends BaseRepository
$first = false; $first = false;
} }
if ( ! $client->wasRecentlyCreated) {
foreach ($client->contacts as $contact) { foreach ($client->contacts as $contact) {
if (!in_array($contact->public_id, $contactIds)) { if (!in_array($contact->public_id, $contactIds)) {
$contact->delete(); $contact->delete();
} }
} }
}
if (!$publicId || $publicId == '-1') { if (!$publicId || $publicId == '-1') {
event(new ClientWasCreated($client)); event(new ClientWasCreated($client));

View File

@ -494,6 +494,7 @@ class InvoiceRepository extends BaseRepository
} }
} }
if ( ! $invoice->wasRecentlyCreated) {
foreach ($invoice->documents as $document){ foreach ($invoice->documents as $document){
if(!in_array($document->public_id, $document_ids)){ if(!in_array($document->public_id, $document_ids)){
// Removed // Removed
@ -504,6 +505,7 @@ class InvoiceRepository extends BaseRepository
} }
} }
} }
}
foreach ($data['invoice_items'] as $item) { foreach ($data['invoice_items'] as $item) {
$item = (array) $item; $item = (array) $item;

View File

@ -11,7 +11,6 @@ class EventServiceProvider extends ServiceProvider {
* @var array * @var array
*/ */
protected $listen = [ protected $listen = [
// Clients // Clients
'App\Events\ClientWasCreated' => [ 'App\Events\ClientWasCreated' => [
'App\Listeners\ActivityListener@createdClient', 'App\Listeners\ActivityListener@createdClient',
@ -151,7 +150,6 @@ class EventServiceProvider extends ServiceProvider {
'App\Events\UserSettingsChanged' => [ 'App\Events\UserSettingsChanged' => [
'App\Listeners\HandleUserSettingsChanged', 'App\Listeners\HandleUserSettingsChanged',
], ],
]; ];
/** /**

View File

@ -17,6 +17,7 @@ use App\Ninja\Repositories\ProductRepository;
use App\Ninja\Serializers\ArraySerializer; use App\Ninja\Serializers\ArraySerializer;
use App\Models\Client; use App\Models\Client;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\EntityModel;
class ImportService class ImportService
{ {
@ -25,9 +26,13 @@ class ImportService
protected $clientRepo; protected $clientRepo;
protected $contactRepo; protected $contactRepo;
protected $productRepo; protected $productRepo;
protected $processedRows = array(); protected $processedRows = [];
private $maps = [];
public $results = [];
public static $entityTypes = [ public static $entityTypes = [
IMPORT_JSON,
ENTITY_CLIENT, ENTITY_CLIENT,
ENTITY_CONTACT, ENTITY_CONTACT,
ENTITY_INVOICE, ENTITY_INVOICE,
@ -39,6 +44,7 @@ class ImportService
public static $sources = [ public static $sources = [
IMPORT_CSV, IMPORT_CSV,
IMPORT_JSON,
IMPORT_FRESHBOOKS, IMPORT_FRESHBOOKS,
//IMPORT_HARVEST, //IMPORT_HARVEST,
IMPORT_HIVEAGE, IMPORT_HIVEAGE,
@ -68,10 +74,70 @@ class ImportService
$this->productRepo = $productRepo; $this->productRepo = $productRepo;
} }
public function import($source, $files) public function importJSON($file)
{
$this->init();
$file = file_get_contents($file);
$json = json_decode($file, true);
$json = $this->removeIdFields($json);
$this->checkClientCount(count($json['clients']));
foreach ($json['clients'] as $jsonClient) {
if ($this->validate($jsonClient, ENTITY_CLIENT) === true) {
$client = $this->clientRepo->save($jsonClient);
$this->addSuccess($client);
} else {
$this->addFailure(ENTITY_CLIENT, $jsonClient);
continue;
}
foreach ($jsonClient['invoices'] as $jsonInvoice) {
$jsonInvoice['client_id'] = $client->id;
if ($this->validate($jsonInvoice, ENTITY_INVOICE) === true) {
$invoice = $this->invoiceRepo->save($jsonInvoice);
$this->addSuccess($invoice);
} else {
$this->addFailure(ENTITY_INVOICE, $jsonInvoice);
continue;
}
foreach ($jsonInvoice['payments'] as $jsonPayment) {
$jsonPayment['client_id'] = $jsonPayment['client'] = $client->id; // TODO: change to client_id once views are updated
$jsonPayment['invoice_id'] = $jsonPayment['invoice'] = $invoice->id; // TODO: change to invoice_id once views are updated
if ($this->validate($jsonPayment, ENTITY_PAYMENT) === true) {
$payment = $this->paymentRepo->save($jsonPayment);
$this->addSuccess($payment);
} else {
$this->addFailure(ENTITY_PAYMENT, $jsonPayment);
continue;
}
}
}
}
return $this->results;
}
public function removeIdFields($array)
{
foreach ($array as $key => $val) {
if (is_array($val)) {
$array[$key] = $this->removeIdFields($val);
} elseif ($key === 'id') {
unset($array[$key]);
}
}
return $array;
}
public function importFiles($source, $files)
{ {
$results = []; $results = [];
$imported_files = null; $imported_files = null;
$this->initMaps();
foreach ($files as $entityType => $file) { foreach ($files as $entityType => $file) {
$results[$entityType] = $this->execute($source, $entityType, $file); $results[$entityType] = $this->execute($source, $entityType, $file);
@ -89,12 +155,12 @@ class ImportService
// Convert the data // Convert the data
$row_list = array(); $row_list = array();
$maps = $this->createMaps();
Excel::load($file, function ($reader) use ($source, $entityType, $maps, &$row_list, &$results) { Excel::load($file, function ($reader) use ($source, $entityType, &$row_list, &$results) {
$this->checkData($entityType, count($reader->all())); $this->checkData($entityType, count($reader->all()));
$reader->each(function ($row) use ($source, $entityType, $maps, &$row_list, &$results) { $reader->each(function ($row) use ($source, $entityType, &$row_list, &$results) {
$data_index = $this->transformRow($source, $entityType, $row, $maps); $data_index = $this->transformRow($source, $entityType, $row);
if ($data_index !== false) { if ($data_index !== false) {
if ($data_index !== true) { if ($data_index !== true) {
@ -109,7 +175,7 @@ class ImportService
// Save the data // Save the data
foreach ($row_list as $row_data) { foreach ($row_list as $row_data) {
$result = $this->saveData($source, $entityType, $row_data['row'], $row_data['data_index'], $maps); $result = $this->saveData($source, $entityType, $row_data['row'], $row_data['data_index']);
if ($result) { if ($result) {
$results[RESULT_SUCCESS][] = $result; $results[RESULT_SUCCESS][] = $result;
} else { } else {
@ -120,10 +186,10 @@ class ImportService
return $results; return $results;
} }
private function transformRow($source, $entityType, $row, $maps) private function transformRow($source, $entityType, $row)
{ {
$transformer = $this->getTransformer($source, $entityType, $maps); $transformer = $this->getTransformer($source, $entityType, $this->maps);
$resource = $transformer->transform($row, $maps); $resource = $transformer->transform($row);
if (!$resource) { if (!$resource) {
return false; return false;
@ -138,7 +204,7 @@ class ImportService
$data['invoice_number'] = $account->getNextInvoiceNumber($invoice); $data['invoice_number'] = $account->getNextInvoiceNumber($invoice);
} }
if ($this->validate($source, $data, $entityType) !== true) { if ($this->validate($data, $entityType) !== true) {
return false; return false;
} }
@ -160,14 +226,18 @@ class ImportService
return key($this->processedRows); return key($this->processedRows);
} }
private function saveData($source, $entityType, $row, $data_index, $maps) private function saveData($source, $entityType, $row, $data_index)
{ {
$data = $this->processedRows[$data_index]; $data = $this->processedRows[$data_index];
$entity = $this->{"{$entityType}Repo"}->save($data); $entity = $this->{"{$entityType}Repo"}->save($data);
// update the entity maps
$mapFunction = 'add' . ucwords($entity->getEntityType()) . 'ToMaps';
$this->$mapFunction($entity);
// if the invoice is paid we'll also create a payment record // if the invoice is paid we'll also create a payment record
if ($entityType === ENTITY_INVOICE && isset($data['paid']) && $data['paid'] > 0) { if ($entityType === ENTITY_INVOICE && isset($data['paid']) && $data['paid'] > 0) {
$this->createPayment($source, $row, $maps, $data['client_id'], $entity->id); $this->createPayment($source, $row, $data['client_id'], $entity->id);
} }
return $entity; return $entity;
@ -200,21 +270,22 @@ class ImportService
return new $className($maps); return new $className($maps);
} }
private function createPayment($source, $data, $maps, $clientId, $invoiceId) private function createPayment($source, $data, $clientId, $invoiceId)
{ {
$paymentTransformer = $this->getTransformer($source, ENTITY_PAYMENT, $maps); $paymentTransformer = $this->getTransformer($source, ENTITY_PAYMENT, $this->maps);
$data->client_id = $clientId; $data->client_id = $clientId;
$data->invoice_id = $invoiceId; $data->invoice_id = $invoiceId;
if ($resource = $paymentTransformer->transform($data, $maps)) { if ($resource = $paymentTransformer->transform($data)) {
$data = $this->fractal->createData($resource)->toArray(); $data = $this->fractal->createData($resource)->toArray();
$this->paymentRepo->save($data); $this->paymentRepo->save($data);
} }
} }
private function validate($source, $data, $entityType) private function validate($data, $entityType)
{ {
/*
// Harvest's contacts are listed separately // Harvest's contacts are listed separately
if ($entityType === ENTITY_CLIENT && $source != IMPORT_HARVEST) { if ($entityType === ENTITY_CLIENT && $source != IMPORT_HARVEST) {
$rules = [ $rules = [
@ -234,71 +305,21 @@ class ImportService
'product_key' => 'required', 'product_key' => 'required',
]; ];
} }
*/
$requestClass = 'App\\Http\\Requests\\Create' . ucwords($entityType) . 'Request';
$request = new $requestClass();
$request->setUserResolver(function() { return Auth::user(); });
$request->replace($data);
$validator = Validator::make($data, $rules); $validator = Validator::make($data, $request->rules());
if ($validator->fails()) { if ($validator->fails()) {
$messages = $validator->messages(); return $validator->messages()->first();
return $messages->first();
} else { } else {
return true; return true;
} }
} }
private function createMaps()
{
$clientMap = [];
$clients = $this->clientRepo->all();
foreach ($clients as $client) {
if ($name = strtolower(trim($client->name))) {
$clientMap[$name] = $client->id;
}
}
$invoiceMap = [];
$invoiceClientMap = [];
$invoices = $this->invoiceRepo->all();
foreach ($invoices as $invoice) {
if ($number = strtolower(trim($invoice->invoice_number))) {
$invoiceMap[$number] = $invoice->id;
$invoiceClientMap[$number] = $invoice->client_id;
}
}
$productMap = [];
$products = $this->productRepo->all();
foreach ($products as $product) {
if ($key = strtolower(trim($product->product_key))) {
$productMap[$key] = $product->id;
}
}
$countryMap = [];
$countryMap2 = [];
$countries = Cache::get('countries');
foreach ($countries as $country) {
$countryMap[strtolower($country->name)] = $country->id;
$countryMap2[strtolower($country->iso_3166_2)] = $country->id;
}
$currencyMap = [];
$currencies = Cache::get('currencies');
foreach ($currencies as $currency) {
$currencyMap[strtolower($currency->code)] = $currency->id;
}
return [
ENTITY_CLIENT => $clientMap,
ENTITY_INVOICE => $invoiceMap,
ENTITY_INVOICE.'_'.ENTITY_CLIENT => $invoiceClientMap,
ENTITY_PRODUCT => $productMap,
'countries' => $countryMap,
'countries2' => $countryMap2,
'currencies' => $currencyMap,
];
}
public function mapCSV($files) public function mapCSV($files)
{ {
$data = []; $data = [];
@ -430,7 +451,7 @@ class ImportService
$data = Session::get("{$entityType}-data"); $data = Session::get("{$entityType}-data");
$this->checkData($entityType, count($data)); $this->checkData($entityType, count($data));
$maps = $this->createMaps(); $this->initMaps();
// Convert the data // Convert the data
$row_list = array(); $row_list = array();
@ -441,7 +462,7 @@ class ImportService
} }
$row = $this->convertToObject($entityType, $row, $map); $row = $this->convertToObject($entityType, $row, $map);
$data_index = $this->transformRow($source, $entityType, $row, $maps); $data_index = $this->transformRow($source, $entityType, $row);
if ($data_index !== false) { if ($data_index !== false) {
if ($data_index !== true) { if ($data_index !== true) {
@ -455,7 +476,7 @@ class ImportService
// Save the data // Save the data
foreach ($row_list as $row_data) { foreach ($row_list as $row_data) {
$result = $this->saveData($source, $entityType, $row_data['row'], $row_data['data_index'], $maps); $result = $this->saveData($source, $entityType, $row_data['row'], $row_data['data_index']);
if ($result) { if ($result) {
$results[RESULT_SUCCESS][] = $result; $results[RESULT_SUCCESS][] = $result;
@ -493,4 +514,93 @@ class ImportService
return $obj; return $obj;
} }
private function addSuccess($entity)
{
$this->results[$entity->getEntityType()][RESULT_SUCCESS][] = $entity;
}
private function addFailure($entityType, $data)
{
$this->results[$entityType][RESULT_FAILURE][] = $data;
}
private function init()
{
EntityModel::$notifySubscriptions = false;
foreach ([ENTITY_CLIENT, ENTITY_INVOICE, ENTITY_PAYMENT] as $entityType) {
$this->results[$entityType] = [
RESULT_SUCCESS => [],
RESULT_FAILURE => [],
];
}
}
private function initMaps()
{
$this->init();
$this->maps = [
'client' => [],
'invoice' => [],
'invoice_client' => [],
'product' => [],
'countries' => [],
'countries2' => [],
'currencies' => [],
'client_ids' => [],
'invoice_ids' => [],
];
$clients = $this->clientRepo->all();
foreach ($clients as $client) {
$this->addClientToMaps($client);
}
$invoices = $this->invoiceRepo->all();
foreach ($invoices as $invoice) {
$this->addInvoiceToMaps($invoice);
}
$products = $this->productRepo->all();
foreach ($products as $product) {
$this->addProductToMaps($product);
}
$countries = Cache::get('countries');
foreach ($countries as $country) {
$this->maps['countries'][strtolower($country->name)] = $country->id;
$this->maps['countries2'][strtolower($country->iso_3166_2)] = $country->id;
}
$currencies = Cache::get('currencies');
foreach ($currencies as $currency) {
$this->maps['currencies'][strtolower($currency->code)] = $currency->id;
}
}
private function addInvoiceToMaps($invoice)
{
if ($number = strtolower(trim($invoice->invoice_number))) {
$this->maps['invoice'][$number] = $invoice->id;
$this->maps['invoice_client'][$number] = $invoice->client_id;
$this->maps['invoice_ids'][$invoice->public_id] = $invoice->id;
}
}
private function addClientToMaps($client)
{
if ($name = strtolower(trim($client->name))) {
$this->maps['client'][$name] = $client->id;
$this->maps['client_ids'][$client->public_id] = $client->id;
}
}
private function addProductToMaps($product)
{
if ($key = strtolower(trim($product->product_key))) {
$this->maps['product'][$key] = $product->id;
}
}
} }

View File

@ -1321,6 +1321,8 @@ $LANG = array(
'products_will_create' => 'products will be created.', 'products_will_create' => 'products will be created.',
'product_key' => 'Product', 'product_key' => 'Product',
'created_products' => 'Successfully created :count product(s)', 'created_products' => 'Successfully created :count product(s)',
'export_help' => 'Use JSON if you plan to import the data into Invoice Ninja.',
'JSON_file' => 'JSON File',
); );

View File

@ -53,7 +53,8 @@
->addOption('CSV', 'CSV') ->addOption('CSV', 'CSV')
->addOption('XLS', 'XLS') ->addOption('XLS', 'XLS')
->addOption('JSON', 'JSON') ->addOption('JSON', 'JSON')
->style('max-width: 200px') !!} ->style('max-width: 200px')
->inlineHelp('export_help') !!}
{!! Former::checkbox('entity_types') {!! Former::checkbox('entity_types')
->label('include') ->label('include')
@ -100,6 +101,11 @@
@endif @endif
@endforeach @endforeach
} }
@if ($source === IMPORT_JSON)
if (val === '{{ $source }}') {
$('.JSON-file').show();
}
@endif
@endforeach @endforeach
} }

View File

@ -9,7 +9,7 @@
<link href="{{ asset('favicon-v2.png') }}" rel="shortcut icon" type="image/png"> <link href="{{ asset('favicon-v2.png') }}" rel="shortcut icon" type="image/png">
@endif @endif
<!-- Source: https://github.com/hillelcoren/invoice-ninja --> <!-- Source: https://github.com/invoiceninja/invoiceninja -->
<!-- Version: {{ NINJA_VERSION }} --> <!-- Version: {{ NINJA_VERSION }} -->
<meta charset="utf-8"> <meta charset="utf-8">