Support importing settings

This commit is contained in:
Hillel Coren 2017-03-22 11:50:55 +02:00
parent 7159dd13ce
commit 1f01c006eb
6 changed files with 313 additions and 92 deletions

View File

@ -45,9 +45,11 @@ class ImportController extends BaseController
return View::make('accounts.import_map', ['data' => $data]); return View::make('accounts.import_map', ['data' => $data]);
} elseif ($source === IMPORT_JSON) { } elseif ($source === IMPORT_JSON) {
$results = $this->importService->importJSON($files[IMPORT_JSON]); $includeData = filter_var(Input::get('data'), FILTER_VALIDATE_BOOLEAN);
$includeSettings = filter_var(Input::get('settings'), FILTER_VALIDATE_BOOLEAN);
$results = $this->importService->importJSON($files[IMPORT_JSON], $includeData, $includeSettings);
return $this->showResult($results); return $this->showResult($results, $includeSettings);
} else { } else {
$results = $this->importService->importFiles($source, $files); $results = $this->importService->importFiles($source, $files);
@ -78,11 +80,15 @@ class ImportController extends BaseController
} }
} }
private function showResult($results) private function showResult($results, $includeSettings = false)
{ {
$message = ''; $message = '';
$skipped = []; $skipped = [];
if ($includeSettings) {
$message = trans('texts.imported_settings') . '<br/>';
}
foreach ($results as $entityType => $entityResults) { foreach ($results as $entityType => $entityResults) {
if ($count = count($entityResults[RESULT_SUCCESS])) { if ($count = count($entityResults[RESULT_SUCCESS])) {
$message .= trans("texts.created_{$entityType}s", ['count' => $count]) . '<br/>'; $message .= trans("texts.created_{$entityType}s", ['count' => $count]) . '<br/>';

View File

@ -48,50 +48,128 @@ class Account extends Eloquent
* @var array * @var array
*/ */
protected $fillable = [ protected $fillable = [
'timezone_id',
'date_format_id',
'datetime_format_id',
'currency_id',
'name', 'name',
'id_number',
'vat_number',
'work_email',
'website',
'work_phone',
'address1', 'address1',
'address2', 'address2',
'city', 'city',
'state', 'state',
'postal_code', 'postal_code',
'country_id', 'country_id',
'size_id', 'invoice_terms',
'industry_id',
'email_footer', 'email_footer',
'timezone_id', 'industry_id',
'date_format_id', 'size_id',
'datetime_format_id',
'currency_id',
'language_id',
'military_time',
'invoice_taxes', 'invoice_taxes',
'invoice_item_taxes', 'invoice_item_taxes',
'invoice_design_id',
'work_phone',
'work_email',
'language_id',
'custom_label1',
'custom_value1',
'custom_label2',
'custom_value2',
'custom_client_label1',
'custom_client_label2',
'fill_products',
'update_products',
'primary_color',
'secondary_color',
'hide_quantity',
'hide_paid_to_date',
'custom_invoice_label1',
'custom_invoice_label2',
'custom_invoice_taxes1',
'custom_invoice_taxes2',
'vat_number',
'invoice_number_prefix',
'invoice_number_counter',
'quote_number_prefix',
'quote_number_counter',
'share_counter',
'id_number',
'email_template_invoice',
'email_template_quote',
'email_template_payment',
'token_billing_type_id',
'invoice_footer',
'pdf_email_attachment',
'font_size',
'invoice_labels',
'custom_design',
'show_item_taxes', 'show_item_taxes',
'military_time',
'email_subject_invoice',
'email_subject_quote',
'email_subject_payment',
'email_subject_reminder1',
'email_subject_reminder2',
'email_subject_reminder3',
'email_template_reminder1',
'email_template_reminder2',
'email_template_reminder3',
'enable_reminder1',
'enable_reminder2',
'enable_reminder3',
'num_days_reminder1',
'num_days_reminder2',
'num_days_reminder3',
'custom_invoice_text_label1',
'custom_invoice_text_label2',
'default_tax_rate_id', 'default_tax_rate_id',
'enable_second_tax_rate', 'recurring_hour',
'include_item_taxes_inline', 'invoice_number_pattern',
'start_of_week', 'quote_number_pattern',
'financial_year_start', 'quote_terms',
'enable_client_portal', 'email_design_id',
'enable_client_portal_dashboard', 'enable_email_markup',
'website',
'direction_reminder1',
'direction_reminder2',
'direction_reminder3',
'field_reminder1',
'field_reminder2',
'field_reminder3',
'header_font_id',
'body_font_id',
'auto_convert_quote',
'all_pages_footer',
'all_pages_header',
'show_currency_code',
'enable_portal_password', 'enable_portal_password',
'send_portal_password', 'send_portal_password',
'custom_invoice_item_label1',
'custom_invoice_item_label2',
'recurring_invoice_number_prefix',
'enable_client_portal',
'invoice_fields',
'invoice_embed_documents',
'document_email_attachment',
'enable_client_portal_dashboard',
'page_size',
'live_preview',
'invoice_number_padding',
'enable_second_tax_rate',
'auto_bill_on_due_date',
'start_of_week',
'enable_buy_now_buttons', 'enable_buy_now_buttons',
'include_item_taxes_inline',
'financial_year_start',
'enabled_modules',
'enabled_dashboard_sections',
'show_accept_invoice_terms', 'show_accept_invoice_terms',
'show_accept_quote_terms', 'show_accept_quote_terms',
'require_invoice_signature', 'require_invoice_signature',
'require_quote_signature', 'require_quote_signature',
'pdf_email_attachment', 'client_number_prefix',
'document_email_attachment', 'client_number_counter',
'email_design_id', 'client_number_pattern',
'enable_email_markup',
'domain_id',
'payment_terms', 'payment_terms',
'reset_counter_frequency_id',
'payment_type_id', 'payment_type_id',
'gateway_fee_location', 'gateway_fee_location',
]; ];

View File

@ -136,6 +136,7 @@ class AccountTransformer extends EntityTransformer
{ {
return [ return [
'account_key' => $account->account_key, 'account_key' => $account->account_key,
'logo' => $account->logo,
'name' => $account->present()->name, 'name' => $account->present()->name,
'id_number' => $account->id_number, 'id_number' => $account->id_number,
'currency_id' => (int) $account->currency_id, 'currency_id' => (int) $account->currency_id,
@ -172,7 +173,97 @@ class AccountTransformer extends EntityTransformer
'custom_label2' => $account->custom_label2, 'custom_label2' => $account->custom_label2,
'custom_value1' => $account->custom_value1, 'custom_value1' => $account->custom_value1,
'custom_value2' => $account->custom_value2, 'custom_value2' => $account->custom_value2,
'logo' => $account->logo, 'primary_color' => $account->primary_color,
'secondary_color' => $account->secondary_color,
'custom_client_label1' => $account->custom_client_label1,
'custom_client_label2' => $account->custom_client_label2,
'hide_quantity' => (bool) $account->hide_quantity,
'hide_paid_to_date' => (bool) $account->hide_paid_to_date,
'invoice_number_prefix' => $account->invoice_number_prefix,
'invoice_number_counter' => $account->invoice_number_counter,
'quote_number_prefix' => $account->quote_number_prefix,
'quote_number_counter' => $account->quote_number_counter,
'share_counter' => (bool) $account->share_counter,
'email_template_invoice' => $account->email_template_invoice,
'email_template_quote' => $account->email_template_quote,
'email_template_payment' => $account->email_template_payment,
'token_billing_type_id' => (int) $account->token_billing_type_id,
'invoice_footer' => $account->invoice_footer,
'pdf_email_attachment' => (bool) $account->pdf_email_attachment,
'font_size' => $account->font_size,
'invoice_labels' => $account->invoice_labels,
'custom_design' => $account->custom_design,
'show_item_taxes' => (bool) $account->show_item_taxes,
'military_time' => (bool) $account->military_time,
'email_subject_invoice' => $account->email_subject_invoice,
'email_subject_quote' => $account->email_subject_quote,
'email_subject_payment' => $account->email_subject_payment,
'email_subject_reminder1' => $account->email_subject_reminder1,
'email_subject_reminder2' => $account->email_subject_reminder2,
'email_subject_reminder3' => $account->email_subject_reminder3,
'email_template_reminder1' => $account->email_template_reminder1,
'email_template_reminder2' => $account->email_template_reminder2,
'email_template_reminder3' => $account->email_template_reminder3,
'enable_reminder1' => $account->enable_reminder1,
'enable_reminder2' => $account->enable_reminder2,
'enable_reminder3' => $account->enable_reminder3,
'num_days_reminder1' => $account->num_days_reminder1,
'num_days_reminder2' => $account->num_days_reminder2,
'num_days_reminder3' => $account->num_days_reminder3,
'custom_invoice_text_label1' => $account->custom_invoice_text_label1,
'custom_invoice_text_label2' => $account->custom_invoice_text_label2,
'default_tax_rate_id' => $account->default_tax_rate_id,
'recurring_hour' => $account->recurring_hour,
'invoice_number_pattern' => $account->invoice_number_pattern,
'quote_number_pattern' => $account->quote_number_pattern,
'quote_terms' => $account->quote_terms,
'email_design_id' => $account->email_design_id,
'enable_email_markup' => (bool) $account->enable_email_markup,
'website' => $account->website,
'direction_reminder1' => (int) $account->direction_reminder1,
'direction_reminder2' => (int) $account->direction_reminder2,
'direction_reminder3' => (int) $account->direction_reminder3,
'field_reminder1' => (int) $account->field_reminder1,
'field_reminder2' => (int) $account->field_reminder2,
'field_reminder3' => (int) $account->field_reminder3,
'header_font_id' => (int) $account->header_font_id,
'body_font_id' => (int) $account->body_font_id,
'auto_convert_quote' => (bool) $account->auto_convert_quote,
'all_pages_footer' => (bool) $account->all_pages_footer,
'all_pages_header' => (bool) $account->all_pages_header,
'show_currency_code' => (bool) $account->show_currency_code,
'enable_portal_password' => (bool) $account->enable_portal_password,
'send_portal_password' => (bool) $account->send_portal_password,
'custom_invoice_item_label1' => $account->custom_invoice_item_label1,
'custom_invoice_item_label2' => $account->custom_invoice_item_label2,
'recurring_invoice_number_prefix' => $account->recurring_invoice_number_prefix,
'enable_client_portal' => (bool) $account->enable_client_portal,
'invoice_fields' => $account->invoice_fields,
'invoice_embed_documents' => (bool) $account->invoice_embed_documents,
'document_email_attachment' => (bool) $account->document_email_attachment,
'enable_client_portal_dashboard' => (bool) $account->enable_client_portal_dashboard,
'page_size' => $account->page_size,
'live_preview' => (bool) $account->live_preview,
'invoice_number_padding' => (int) $account->invoice_number_padding,
'enable_second_tax_rate' => (bool) $account->enable_second_tax_rate,
'auto_bill_on_due_date' => (bool) $account->auto_bill_on_due_date,
'start_of_week' => $account->start_of_week,
'enable_buy_now_buttons' => (bool) $account->enable_buy_now_buttons,
'include_item_taxes_inline' => (bool) $account->include_item_taxes_inline,
'financial_year_start' => $account->financial_year_start,
'enabled_modules' => (int) $account->enabled_modules,
'enabled_dashboard_sections' => (int) $account->enabled_dashboard_sections,
'show_accept_invoice_terms' => (bool) $account->show_accept_invoice_terms,
'show_accept_quote_terms' => (bool) $account->show_accept_quote_terms,
'require_invoice_signature' => (bool) $account->require_invoice_signature,
'require_quote_signature' => (bool) $account->require_quote_signature,
'client_number_prefix' => $account->client_number_prefix,
'client_number_counter' => (int) $account->client_number_counter,
'client_number_pattern' => $account->client_number_pattern,
'payment_terms' => (int) $account->payment_terms,
'reset_counter_frequency_id' => (int) $account->reset_counter_frequency_id,
'payment_type_id' => (int) $account->payment_type_id,
'gateway_fee_location' => $account->gateway_fee_location,
]; ];
} }
} }

View File

@ -145,7 +145,7 @@ class ImportService
* *
* @return array * @return array
*/ */
public function importJSON($file) public function importJSON($file, $includeData, $includeSettings)
{ {
$this->initMaps(); $this->initMaps();
@ -156,52 +156,70 @@ class ImportService
$this->checkClientCount(count($json['clients'])); $this->checkClientCount(count($json['clients']));
foreach ($json['products'] as $jsonProduct) { if ($includeSettings) {
if ($transformer->hasProduct($jsonProduct['product_key'])) { // remove blank id values
continue; $settings = [];
} foreach ($json as $field => $value) {
if (EntityModel::validate($jsonProduct, ENTITY_PRODUCT) === true) { if (strstr($field, '_id') && ! $value) {
$product = $this->productRepo->save($jsonProduct); // continue;
$this->addProductToMaps($product); } else {
$this->addSuccess($product); $settings[$field] = $value;
} else { }
$this->addFailure(ENTITY_PRODUCT, $jsonProduct);
continue;
} }
//dd($settings);
$account = Auth::user()->account;
$account->fill($settings);
$account->save();
} }
foreach ($json['clients'] as $jsonClient) { if ($includeData) {
if (EntityModel::validate($jsonClient, ENTITY_CLIENT) === true) { foreach ($json['products'] as $jsonProduct) {
$client = $this->clientRepo->save($jsonClient); if ($transformer->hasProduct($jsonProduct['product_key'])) {
$this->addClientToMaps($client); continue;
$this->addSuccess($client); }
} else { if (EntityModel::validate($jsonProduct, ENTITY_PRODUCT) === true) {
$this->addFailure(ENTITY_CLIENT, $jsonClient); $product = $this->productRepo->save($jsonProduct);
continue; $this->addProductToMaps($product);
$this->addSuccess($product);
} else {
$this->addFailure(ENTITY_PRODUCT, $jsonProduct);
continue;
}
} }
foreach ($jsonClient['invoices'] as $jsonInvoice) { foreach ($json['clients'] as $jsonClient) {
$jsonInvoice['client_id'] = $client->id; if (EntityModel::validate($jsonClient, ENTITY_CLIENT) === true) {
if (EntityModel::validate($jsonInvoice, ENTITY_INVOICE) === true) { $client = $this->clientRepo->save($jsonClient);
$invoice = $this->invoiceRepo->save($jsonInvoice); $this->addClientToMaps($client);
$this->addInvoiceToMaps($invoice); $this->addSuccess($client);
$this->addSuccess($invoice);
} else { } else {
$this->addFailure(ENTITY_INVOICE, $jsonInvoice); $this->addFailure(ENTITY_CLIENT, $jsonClient);
continue; continue;
} }
foreach ($jsonInvoice['payments'] as $jsonPayment) { foreach ($jsonClient['invoices'] as $jsonInvoice) {
$jsonPayment['invoice_id'] = $invoice->public_id; $jsonInvoice['client_id'] = $client->id;
if (EntityModel::validate($jsonPayment, ENTITY_PAYMENT) === true) { if (EntityModel::validate($jsonInvoice, ENTITY_INVOICE) === true) {
$jsonPayment['client_id'] = $client->id; $invoice = $this->invoiceRepo->save($jsonInvoice);
$jsonPayment['invoice_id'] = $invoice->id; $this->addInvoiceToMaps($invoice);
$payment = $this->paymentRepo->save($jsonPayment); $this->addSuccess($invoice);
$this->addSuccess($payment);
} else { } else {
$this->addFailure(ENTITY_PAYMENT, $jsonPayment); $this->addFailure(ENTITY_INVOICE, $jsonInvoice);
continue; continue;
} }
foreach ($jsonInvoice['payments'] as $jsonPayment) {
$jsonPayment['invoice_id'] = $invoice->public_id;
if (EntityModel::validate($jsonPayment, ENTITY_PAYMENT) === true) {
$jsonPayment['client_id'] = $client->id;
$jsonPayment['invoice_id'] = $invoice->id;
$payment = $this->paymentRepo->save($jsonPayment);
$this->addSuccess($payment);
} else {
$this->addFailure(ENTITY_PAYMENT, $jsonPayment);
continue;
}
}
} }
} }
} }

View File

@ -2427,7 +2427,8 @@ $LANG = array(
'logo_warning_invalid' => 'There was a problem reading the image file, please try a different format.', 'logo_warning_invalid' => 'There was a problem reading the image file, please try a different format.',
'error_refresh_page' => 'An error occurred, please refresh the page and try again.', 'error_refresh_page' => 'An error occurred, please refresh the page and try again.',
'data' => 'Data',
'imported_settings' => 'Successfully imported settings',
); );
return $LANG; return $LANG;

View File

@ -30,11 +30,26 @@
->options(array_combine(\App\Services\ImportService::$sources, \App\Services\ImportService::$sources)) ->options(array_combine(\App\Services\ImportService::$sources, \App\Services\ImportService::$sources))
->style('width: 200px') !!} ->style('width: 200px') !!}
<br/>
@foreach (\App\Services\ImportService::$entityTypes as $entityType) @foreach (\App\Services\ImportService::$entityTypes as $entityType)
{!! Former::file("{$entityType}_file") {!! Former::file("{$entityType}_file")
->addGroupClass("import-file {$entityType}-file") !!} ->addGroupClass("import-file {$entityType}-file") !!}
@endforeach @endforeach
<div id="jsonIncludes" style="display:none">
{!! Former::checkboxes('json_include_radio')
->label(trans('texts.include'))
//->check([
// 'data' => true,
// 'settings' => true
//])
->checkboxes([
trans('texts.data') => 'data',
trans('texts.settings') => 'settings',
]) !!}
</div>
<br/>
{!! Former::actions( Button::info(trans('texts.upload'))->submit()->large()->appendIcon(Icon::create('open'))) !!} {!! Former::actions( Button::info(trans('texts.upload'))->submit()->large()->appendIcon(Icon::create('open'))) !!}
{!! Former::close() !!} {!! Former::close() !!}
@ -57,34 +72,36 @@
->help('<br/>' . trans('texts.export_help')) !!} ->help('<br/>' . trans('texts.export_help')) !!}
{!! Former::inline_radios('include_radio') <div id="csvIncludes">
->onchange('setCheckboxesEnabled()') {!! Former::inline_radios('include_radio')
->label(trans('texts.include')) ->onchange('setCheckboxesEnabled()')
->radios([ ->label(trans('texts.include'))
trans('texts.all') . ' &nbsp; ' => ['value' => 'all', 'name' => 'include'], ->radios([
trans('texts.selected') => ['value' => 'selected', 'name' => 'include'], trans('texts.all') . ' &nbsp; ' => ['value' => 'all', 'name' => 'include'],
])->check('all') !!} trans('texts.selected') => ['value' => 'selected', 'name' => 'include'],
])->check('all') !!}
<div class="form-group entity-types"> <div class="form-group entity-types">
<label class="control-label col-lg-4 col-sm-4"></label> <label class="control-label col-lg-4 col-sm-4"></label>
<div class="col-lg-2 col-sm-2"> <div class="col-lg-2 col-sm-2">
@include('partials/checkbox', ['field' => 'clients']) @include('partials/checkbox', ['field' => 'clients'])
@include('partials/checkbox', ['field' => 'contacts']) @include('partials/checkbox', ['field' => 'contacts'])
@include('partials/checkbox', ['field' => 'credits']) @include('partials/checkbox', ['field' => 'credits'])
@include('partials/checkbox', ['field' => 'tasks']) @include('partials/checkbox', ['field' => 'tasks'])
</div> </div>
<div class="col-lg-2 col-sm-2"> <div class="col-lg-2 col-sm-2">
@include('partials/checkbox', ['field' => 'invoices']) @include('partials/checkbox', ['field' => 'invoices'])
@include('partials/checkbox', ['field' => 'quotes']) @include('partials/checkbox', ['field' => 'quotes'])
@include('partials/checkbox', ['field' => 'recurring']) @include('partials/checkbox', ['field' => 'recurring'])
@include('partials/checkbox', ['field' => 'payments']) @include('partials/checkbox', ['field' => 'payments'])
</div> </div>
<div class="col-lg-3 col-sm-3"> <div class="col-lg-3 col-sm-3">
@include('partials/checkbox', ['field' => 'products']) @include('partials/checkbox', ['field' => 'products'])
@include('partials/checkbox', ['field' => 'expenses']) @include('partials/checkbox', ['field' => 'expenses'])
@include('partials/checkbox', ['field' => 'vendors']) @include('partials/checkbox', ['field' => 'vendors'])
@include('partials/checkbox', ['field' => 'vendor_contacts']) @include('partials/checkbox', ['field' => 'vendor_contacts'])
</div>
</div> </div>
</div><br/> </div><br/>
@ -101,18 +118,28 @@
}); });
function setCheckboxesEnabled() { function setCheckboxesEnabled() {
var $checkboxes = $('input[type=checkbox]'); var $checkboxes = $('.entity-types input[type=checkbox]');
var include = $('input[name=include]:checked').val() var include = $('input[name=include]:checked').val()
var format = $('#format').val(); var format = $('#format').val();
if (include === 'all' || format === 'JSON') { if (include === 'all') {
$checkboxes.attr('disabled', true); $checkboxes.attr('disabled', true);
} else { } else {
$checkboxes.removeAttr('disabled'); $checkboxes.removeAttr('disabled');
} }
if (format === 'JSON') {
$('#csvIncludes').hide();
} else {
$('#csvIncludes').show();
}
} }
function setFileTypesVisible() { function setFileTypesVisible() {
var val = $('#source').val(); var val = $('#source').val();
if (val === 'JSON') {
$('#jsonIncludes').show();
} else {
$('#jsonIncludes').hide();
}
@foreach (\App\Services\ImportService::$entityTypes as $entityType) @foreach (\App\Services\ImportService::$entityTypes as $entityType)
$('.{{ $entityType }}-file').hide(); $('.{{ $entityType }}-file').hide();
@endforeach @endforeach