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());
$account = Auth::user()->account;
$account->loadAllData();
$account->load(['clients.contacts', 'clients.invoices.payments', 'clients.invoices.invoice_items']);
$resource = new Item($account, new AccountTransformer);
$data = $manager->createData($resource)->toArray();
$data = $manager->parseIncludes('clients.invoices.payments')
->createData($resource)
->toArray();
return response()->json($data);
}

View File

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

View File

@ -95,9 +95,9 @@ class InvoiceController extends BaseController
{
$account = Auth::user()->account;
$invoice = $request->entity()->load('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items', 'documents', 'expenses', 'expenses.documents', 'payments');
$entityType = $invoice->getEntityType();
$contactIds = DB::table('invitations')
->join('contacts', 'contacts.id', '=', 'invitations.contact_id')
->where('invitations.invoice_id', '=', $invoice->id)
@ -158,12 +158,12 @@ class InvoiceController extends BaseController
if (!$invoice->is_recurring && $invoice->balance > 0) {
$actions[] = ['url' => 'javascript:onPaymentClick()', 'label' => trans('texts.enter_payment')];
}
foreach ($invoice->payments as $payment) {
$label = trans("texts.view_payment");
if (count($invoice->payments) > 1) {
$label .= ' - ' . $account->formatMoney($payment->amount, $invoice->client);
}
$label .= ' - ' . $account->formatMoney($payment->amount, $invoice->client);
}
$actions[] = ['url' => $payment->present()->url, 'label' => $label];
}
}
@ -180,7 +180,7 @@ class InvoiceController extends BaseController
if(!Auth::user()->hasPermission('view_all')){
$clients = $clients->where('clients.user_id', '=', Auth::user()->id);
}
$data = array(
'clients' => $clients->get(),
'entityType' => $entityType,
@ -230,7 +230,7 @@ class InvoiceController extends BaseController
public function create(InvoiceRequest $request, $clientPublicId = 0, $isRecurring = false)
{
$account = Auth::user()->account;
$entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE;
$clientId = null;
@ -240,17 +240,17 @@ class InvoiceController extends BaseController
$invoice = $account->createInvoice($entityType, $clientId);
$invoice->public_id = 0;
if (Session::get('expenses')) {
$invoice->expenses = Expense::scope(Session::get('expenses'))->with('documents')->get();
}
$clients = Client::scope()->with('contacts', 'country')->orderBy('name');
if (!Auth::user()->hasPermission('view_all')) {
$clients = $clients->where('clients.user_id', '=', Auth::user()->id);
}
$data = [
'clients' => $clients->get(),
'entityType' => $invoice->getEntityType(),
@ -335,26 +335,26 @@ class InvoiceController extends BaseController
$rates = TaxRate::scope()->orderBy('name')->get();
$options = [];
$defaultTax = false;
foreach ($rates as $rate) {
$options[$rate->rate . ' ' . $rate->name] = $rate->name . ' ' . ($rate->rate+0) . '%';
$options[$rate->rate . ' ' . $rate->name] = $rate->name . ' ' . ($rate->rate+0) . '%';
// load default invoice tax
if ($rate->id == $account->default_tax_rate_id) {
$defaultTax = $rate;
}
}
}
// Check for any taxes which have been deleted
if ($invoice->exists) {
foreach ($invoice->getTaxes() as $key => $rate) {
if (isset($options[$key])) {
continue;
}
}
$options[$key] = $rate['name'] . ' ' . $rate['rate'] . '%';
}
}
return [
'data' => Input::old('data'),
'account' => Auth::user()->account->load('country'),
@ -396,10 +396,10 @@ class InvoiceController extends BaseController
{
$data = $request->input();
$data['documents'] = $request->file('documents');
$action = Input::get('action');
$entityType = Input::get('entityType');
$invoice = $this->invoiceService->save($data);
$entityType = $invoice->getEntityType();
$message = trans("texts.created_{$entityType}");
@ -433,7 +433,7 @@ class InvoiceController extends BaseController
{
$data = $request->input();
$data['documents'] = $request->file('documents');
$action = Input::get('action');
$entityType = Input::get('entityType');
@ -547,7 +547,7 @@ class InvoiceController extends BaseController
$clone = $this->invoiceService->convertQuote($request->entity());
Session::flash('message', trans('texts.converted_to_invoice'));
return Redirect::to('invoices/' . $clone->public_id);
}

View File

@ -23,14 +23,14 @@ class CreatePaymentRequest extends PaymentRequest
{
$input = $this->input();
$invoice = Invoice::scope($input['invoice'])->firstOrFail();
$rules = array(
'client' => 'required',
'invoice' => 'required',
'client' => 'required', // TODO: change to client_id once views are updated
'invoice' => 'required', // TODO: change to invoice_id once views are updated
'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'];
}

View File

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

View File

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

View File

@ -545,7 +545,7 @@ class Account extends Eloquent
if ($this->hasClientNumberPattern($invoice) && !$clientId) {
// do nothing, we don't yet know the value
} else {
} elseif ( ! $invoice->invoice_number) {
$invoice->invoice_number = $this->getNextInvoiceNumber($invoice);
}
}
@ -649,7 +649,7 @@ class Account extends Eloquent
return $this->getNextInvoiceNumber($invoice);
}
public function getNextInvoiceNumber($invoice)
public function getNextInvoiceNumber($invoice, $validateUnique = true)
{
if ($this->hasNumberPattern($invoice->invoice_type_id)) {
$number = $this->getNumberPattern($invoice);
@ -657,13 +657,16 @@ class Account extends Eloquent
$counter = $this->getCounter($invoice->invoice_type_id);
$prefix = $this->getNumberPrefix($invoice->invoice_type_id);
$counterOffset = 0;
$check = false;
// confirm the invoice number isn't already taken
do {
$number = $prefix . str_pad($counter, $this->invoice_number_padding, '0', STR_PAD_LEFT);
$check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
$counter++;
$counterOffset++;
if ($validateUnique) {
$check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
$counter++;
$counterOffset++;
}
} while ($check);
// update the invoice counter to be caught up
@ -688,7 +691,7 @@ class Account extends Eloquent
public function incrementCounter($invoice)
{
// 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;
}
@ -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());
});

View File

@ -9,22 +9,31 @@ class EntityModel extends Eloquent
public $timestamps = true;
protected $hidden = ['id'];
public static $notifySubscriptions = true;
public static function createNew($context = null)
{
$className = get_called_class();
$entity = new $className();
if ($context) {
$entity->user_id = $context instanceof User ? $context->id : $context->user_id;
$entity->account_id = $context->account_id;
$user = $context instanceof User ? $context : $context->user;
$account = $context->account;
} elseif (Auth::check()) {
$entity->user_id = Auth::user()->id;
$entity->account_id = Auth::user()->account_id;
$user = Auth::user();
$account = Auth::user()->account;
} else {
Utils::fatalError();
}
if(method_exists($className, 'withTrashed')){
$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')){
$lastEntity = $className::withTrashed()
->scope(false, $entity->account_id);
} else {

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
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 [
'amount' => $data->paid,
'payment_date_sql' => $data->create_date,
@ -16,4 +16,4 @@ class PaymentTransformer extends BaseTransformer
];
});
}
}
}

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
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 [
'amount' => $data->paid_total,
'payment_date_sql' => $this->getDate($data->last_paid_on),
@ -16,4 +16,4 @@ class PaymentTransformer extends BaseTransformer
];
});
}
}
}

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
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 [
'amount' => $data->paid,
'payment_date_sql' => $data->date_paid,
@ -16,4 +16,4 @@ class PaymentTransformer extends BaseTransformer
];
});
}
}
}

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
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 [
'amount' => (float) $data->paid_to_date,
'payment_date_sql' => $this->getDate($data->date),
@ -16,4 +16,4 @@ class PaymentTransformer extends BaseTransformer
];
});
}
}
}

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
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 [
'amount' => (float) $data->total - (float) $data->balance,
'payment_date_sql' => $data->date_paid,
@ -16,4 +16,4 @@ class PaymentTransformer extends BaseTransformer
];
});
}
}
}

View File

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

View File

@ -5,9 +5,9 @@ use League\Fractal\Resource\Item;
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 [
'amount' => (float) $data->total - (float) $data->balance,
'payment_date_sql' => $data->last_payment_date,
@ -16,4 +16,4 @@ class PaymentTransformer extends BaseTransformer
];
});
}
}
}

View File

@ -118,9 +118,11 @@ class ClientRepository extends BaseRepository
$first = false;
}
foreach ($client->contacts as $contact) {
if (!in_array($contact->public_id, $contactIds)) {
$contact->delete();
if ( ! $client->wasRecentlyCreated) {
foreach ($client->contacts as $contact) {
if (!in_array($contact->public_id, $contactIds)) {
$contact->delete();
}
}
}

View File

@ -494,13 +494,15 @@ class InvoiceRepository extends BaseRepository
}
}
foreach ($invoice->documents as $document){
if(!in_array($document->public_id, $document_ids)){
// Removed
// Not checking permissions; deleting a document is just editing the invoice
if($document->invoice_id == $invoice->id){
// Make sure the document isn't on a clone
$document->delete();
if ( ! $invoice->wasRecentlyCreated) {
foreach ($invoice->documents as $document){
if(!in_array($document->public_id, $document_ids)){
// Removed
// Not checking permissions; deleting a document is just editing the invoice
if($document->invoice_id == $invoice->id){
// Make sure the document isn't on a clone
$document->delete();
}
}
}
}

View File

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

View File

@ -24,7 +24,7 @@ class RouteServiceProvider extends ServiceProvider {
{
parent::boot($router);
}

View File

@ -17,6 +17,7 @@ use App\Ninja\Repositories\ProductRepository;
use App\Ninja\Serializers\ArraySerializer;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\EntityModel;
class ImportService
{
@ -25,9 +26,13 @@ class ImportService
protected $clientRepo;
protected $contactRepo;
protected $productRepo;
protected $processedRows = array();
protected $processedRows = [];
private $maps = [];
public $results = [];
public static $entityTypes = [
IMPORT_JSON,
ENTITY_CLIENT,
ENTITY_CONTACT,
ENTITY_INVOICE,
@ -39,6 +44,7 @@ class ImportService
public static $sources = [
IMPORT_CSV,
IMPORT_JSON,
IMPORT_FRESHBOOKS,
//IMPORT_HARVEST,
IMPORT_HIVEAGE,
@ -68,10 +74,70 @@ class ImportService
$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 = [];
$imported_files = null;
$this->initMaps();
foreach ($files as $entityType => $file) {
$results[$entityType] = $this->execute($source, $entityType, $file);
@ -89,12 +155,12 @@ class ImportService
// Convert the data
$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()));
$reader->each(function ($row) use ($source, $entityType, $maps, &$row_list, &$results) {
$data_index = $this->transformRow($source, $entityType, $row, $maps);
$reader->each(function ($row) use ($source, $entityType, &$row_list, &$results) {
$data_index = $this->transformRow($source, $entityType, $row);
if ($data_index !== false) {
if ($data_index !== true) {
@ -109,7 +175,7 @@ class ImportService
// Save the 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) {
$results[RESULT_SUCCESS][] = $result;
} else {
@ -120,10 +186,10 @@ class ImportService
return $results;
}
private function transformRow($source, $entityType, $row, $maps)
private function transformRow($source, $entityType, $row)
{
$transformer = $this->getTransformer($source, $entityType, $maps);
$resource = $transformer->transform($row, $maps);
$transformer = $this->getTransformer($source, $entityType, $this->maps);
$resource = $transformer->transform($row);
if (!$resource) {
return false;
@ -138,7 +204,7 @@ class ImportService
$data['invoice_number'] = $account->getNextInvoiceNumber($invoice);
}
if ($this->validate($source, $data, $entityType) !== true) {
if ($this->validate($data, $entityType) !== true) {
return false;
}
@ -160,14 +226,18 @@ class ImportService
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];
$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 ($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;
@ -200,21 +270,22 @@ class ImportService
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->invoice_id = $invoiceId;
if ($resource = $paymentTransformer->transform($data, $maps)) {
if ($resource = $paymentTransformer->transform($data)) {
$data = $this->fractal->createData($resource)->toArray();
$this->paymentRepo->save($data);
}
}
private function validate($source, $data, $entityType)
private function validate($data, $entityType)
{
/*
// Harvest's contacts are listed separately
if ($entityType === ENTITY_CLIENT && $source != IMPORT_HARVEST) {
$rules = [
@ -234,71 +305,21 @@ class ImportService
'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()) {
$messages = $validator->messages();
return $messages->first();
return $validator->messages()->first();
} else {
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)
{
$data = [];
@ -430,7 +451,7 @@ class ImportService
$data = Session::get("{$entityType}-data");
$this->checkData($entityType, count($data));
$maps = $this->createMaps();
$this->initMaps();
// Convert the data
$row_list = array();
@ -441,7 +462,7 @@ class ImportService
}
$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 !== true) {
@ -455,7 +476,7 @@ class ImportService
// Save the 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) {
$results[RESULT_SUCCESS][] = $result;
@ -493,4 +514,93 @@ class ImportService
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.',
'product_key' => 'Product',
'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('XLS', 'XLS')
->addOption('JSON', 'JSON')
->style('max-width: 200px') !!}
->style('max-width: 200px')
->inlineHelp('export_help') !!}
{!! Former::checkbox('entity_types')
->label('include')
@ -100,6 +101,11 @@
@endif
@endforeach
}
@if ($source === IMPORT_JSON)
if (val === '{{ $source }}') {
$('.JSON-file').show();
}
@endif
@endforeach
}

View File

@ -4,12 +4,12 @@
@if (isset($account) && $account instanceof \App\Models\Account && $account->hasFeature(FEATURE_WHITE_LABEL))
<title>{{ trans('texts.client_portal') }}</title>
@else
<title>{{ isset($title) ? ($title . ' | Invoice Ninja') : ('Invoice Ninja | ' . trans('texts.app_title')) }}</title>
<title>{{ isset($title) ? ($title . ' | Invoice Ninja') : ('Invoice Ninja | ' . trans('texts.app_title')) }}</title>
<meta name="description" content="{{ isset($description) ? $description : trans('texts.app_description') }}" />
<link href="{{ asset('favicon-v2.png') }}" rel="shortcut icon" type="image/png">
@endif
<!-- Source: https://github.com/hillelcoren/invoice-ninja -->
<!-- Source: https://github.com/invoiceninja/invoiceninja -->
<!-- Version: {{ NINJA_VERSION }} -->
<meta charset="utf-8">
@ -22,24 +22,24 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="msapplication-config" content="none"/>
<meta name="msapplication-config" content="none"/>
<link rel="canonical" href="{{ NINJA_APP_URL }}/{{ Request::path() }}" />
<script src="{{ asset('built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
<script src="{{ asset('built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
<script type="text/javascript">
var NINJA = NINJA || {};
NINJA.fontSize = 9;
NINJA.isRegistered = {{ \Utils::isRegistered() ? 'true' : 'false' }};
window.onerror = function (errorMsg, url, lineNumber, column, error) {
if (errorMsg.indexOf('Script error.') > -1) {
return;
}
try {
// Use StackTraceJS to parse the error context
// Use StackTraceJS to parse the error context
if (error) {
var message = error.message ? error.message : error;
StackTrace.fromError(error).then(function(result) {
@ -51,7 +51,7 @@
} else {
logError(errorMsg);
}
trackEvent('/error', errorMsg);
} catch(err) {}
@ -78,7 +78,7 @@
'sSearch': ''
}
} );
/* This causes problems with some languages. ie, fr_CA
var appLocale = '{{App::getLocale()}}';
$.extend( true, $.fn.datepicker.defaults, {
@ -108,7 +108,7 @@
_fbq.loaded = true;
}
})();
@else
function fbq() {
// do nothing
@ -116,7 +116,7 @@
@endif
window._fbq = window._fbq || [];
</script>
@ -132,7 +132,7 @@
<body class="body">
@if (isset($_ENV['TAG_MANAGER_KEY']) && $_ENV['TAG_MANAGER_KEY'])
@if (isset($_ENV['TAG_MANAGER_KEY']) && $_ENV['TAG_MANAGER_KEY'])
<!-- Google Tag Manager -->
<noscript><iframe src="//www.googletagmanager.com/ns.html?id={{ $_ENV['TAG_MANAGER_KEY'] }}"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
@ -140,20 +140,20 @@
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','{{ $_ENV['TAG_MANAGER_KEY'] }}');</script>
})(window,document,'script','dataLayer','{{ $_ENV['TAG_MANAGER_KEY'] }}');</script>
<!-- End Google Tag Manager -->
<script>
function trackEvent(category, action) {}
</script>
@elseif (isset($_ENV['ANALYTICS_KEY']) && $_ENV['ANALYTICS_KEY'])
@elseif (isset($_ENV['ANALYTICS_KEY']) && $_ENV['ANALYTICS_KEY'])
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '{{ $_ENV['ANALYTICS_KEY'] }}', 'auto');
ga('create', '{{ $_ENV['ANALYTICS_KEY'] }}', 'auto');
ga('send', 'pageview');
function trackEvent(category, action) {
@ -165,7 +165,7 @@
function trackEvent(category, action) {}
</script>
@endif
@yield('body')
<script type="text/javascript">
@ -174,7 +174,7 @@
$(function() {
$('form.warn-on-exit input, form.warn-on-exit textarea, form.warn-on-exit select').change(function() {
NINJA.formIsChanged = true;
});
});
@if (Session::has('trackEventCategory') && Session::has('trackEventAction'))
@if (Session::get('trackEventAction') === '/buy_pro_plan')
@ -195,12 +195,12 @@
} else {
return undefined;
}
});
});
function openUrl(url, track) {
trackEvent('/view_link', track ? track : url);
window.open(url, '_blank');
}
</script>
</script>
</body>