diff --git a/app/Models/Product.php b/app/Models/Product.php
index 05944c9fff94..548d7b384521 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -16,6 +16,24 @@ class Product extends EntityModel
'default_tax_rate_id',
];
+ public static function getImportColumns()
+ {
+ return [
+ 'product_key',
+ 'notes',
+ 'cost',
+ ];
+ }
+
+ public static function getImportMap()
+ {
+ return [
+ 'product|item' => 'product_key',
+ 'notes|description|details' => 'notes',
+ 'cost|amount|price' => 'cost',
+ ];
+ }
+
public function getEntityType()
{
return ENTITY_PRODUCT;
diff --git a/app/Ninja/Import/BaseTransformer.php b/app/Ninja/Import/BaseTransformer.php
index 8e17bfeec36f..a06f420ca8c6 100644
--- a/app/Ninja/Import/BaseTransformer.php
+++ b/app/Ninja/Import/BaseTransformer.php
@@ -15,21 +15,38 @@ class BaseTransformer extends TransformerAbstract
protected function hasClient($name)
{
- $name = strtolower($name);
+ $name = trim(strtolower($name));
return isset($this->maps[ENTITY_CLIENT][$name]);
}
+ protected function hasProduct($key)
+ {
+ $key = trim(strtolower($key));
+ return isset($this->maps[ENTITY_PRODUCT][$key]);
+ }
+
protected function getString($data, $field)
{
return (isset($data->$field) && $data->$field) ? $data->$field : '';
}
+ protected function getNumber($data, $field)
+ {
+ return (isset($data->$field) && $data->$field) ? $data->$field : 0;
+ }
+
protected function getClientId($name)
{
$name = strtolower($name);
return isset($this->maps[ENTITY_CLIENT][$name]) ? $this->maps[ENTITY_CLIENT][$name] : null;
}
+ protected function getProductId($name)
+ {
+ $name = strtolower($name);
+ return isset($this->maps[ENTITY_PRODUCT][$name]) ? $this->maps[ENTITY_PRODUCT][$name] : null;
+ }
+
protected function getCountryId($name)
{
$name = strtolower($name);
@@ -53,7 +70,7 @@ class BaseTransformer extends TransformerAbstract
if ( ! $date instanceof DateTime) {
$date = DateTime::createFromFormat($format, $date);
}
-
+
return $date ? $date->format('Y-m-d') : null;
}
@@ -87,11 +104,11 @@ class BaseTransformer extends TransformerAbstract
return isset($this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber])? $this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber] : null;
}
-
+
protected function getVendorId($name)
{
$name = strtolower($name);
return isset($this->maps[ENTITY_VENDOR][$name]) ? $this->maps[ENTITY_VENDOR][$name] : null;
}
-
-}
\ No newline at end of file
+
+}
diff --git a/app/Ninja/Repositories/ProductRepository.php b/app/Ninja/Repositories/ProductRepository.php
index eb0e7383e9e5..968f9ca44398 100644
--- a/app/Ninja/Repositories/ProductRepository.php
+++ b/app/Ninja/Repositories/ProductRepository.php
@@ -11,6 +11,13 @@ class ProductRepository extends BaseRepository
return 'App\Models\Product';
}
+ public function all()
+ {
+ return Product::scope()
+ ->withTrashed()
+ ->get();
+ }
+
public function find($accountId)
{
return DB::table('products')
@@ -30,11 +37,11 @@ class ProductRepository extends BaseRepository
'products.deleted_at'
);
}
-
+
public function save($data, $product = null)
{
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
-
+
if ($product) {
// do nothing
} elseif ($publicId) {
@@ -50,4 +57,4 @@ class ProductRepository extends BaseRepository
return $product;
}
-}
\ No newline at end of file
+}
diff --git a/app/Services/ImportService.php b/app/Services/ImportService.php
index c17a8e359a80..61eb0a1881f9 100644
--- a/app/Services/ImportService.php
+++ b/app/Services/ImportService.php
@@ -13,6 +13,7 @@ use App\Ninja\Repositories\ContactRepository;
use App\Ninja\Repositories\ClientRepository;
use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\PaymentRepository;
+use App\Ninja\Repositories\ProductRepository;
use App\Ninja\Serializers\ArraySerializer;
use App\Models\Client;
use App\Models\Invoice;
@@ -23,6 +24,7 @@ class ImportService
protected $invoiceRepo;
protected $clientRepo;
protected $contactRepo;
+ protected $productRepo;
protected $processedRows = array();
public static $entityTypes = [
@@ -31,6 +33,8 @@ class ImportService
ENTITY_INVOICE,
ENTITY_PAYMENT,
ENTITY_TASK,
+ ENTITY_PRODUCT,
+ ENTITY_EXPENSE,
];
public static $sources = [
@@ -45,7 +49,14 @@ class ImportService
IMPORT_ZOHO,
];
- public function __construct(Manager $manager, ClientRepository $clientRepo, InvoiceRepository $invoiceRepo, PaymentRepository $paymentRepo, ContactRepository $contactRepo)
+ public function __construct(
+ Manager $manager,
+ ClientRepository $clientRepo,
+ InvoiceRepository $invoiceRepo,
+ PaymentRepository $paymentRepo,
+ ContactRepository $contactRepo,
+ ProductRepository $productRepo
+ )
{
$this->fractal = $manager;
$this->fractal->setSerializer(new ArraySerializer());
@@ -54,6 +65,7 @@ class ImportService
$this->invoiceRepo = $invoiceRepo;
$this->paymentRepo = $paymentRepo;
$this->contactRepo = $contactRepo;
+ $this->productRepo = $productRepo;
}
public function import($source, $files)
@@ -216,8 +228,11 @@ class ImportService
'invoice_number' => 'required|unique:invoices,invoice_number,,id,account_id,'.Auth::user()->account_id,
'discount' => 'positive',
];
- } else {
- return true;
+ }
+ if ($entityType === ENTITY_PRODUCT) {
+ $rules = [
+ 'product_key' => 'required',
+ ];
}
$validator = Validator::make($data, $rules);
@@ -251,6 +266,14 @@ class ImportService
}
}
+ $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');
@@ -269,6 +292,7 @@ class ImportService
ENTITY_CLIENT => $clientMap,
ENTITY_INVOICE => $invoiceMap,
ENTITY_INVOICE.'_'.ENTITY_CLIENT => $invoiceClientMap,
+ ENTITY_PRODUCT => $productMap,
'countries' => $countryMap,
'countries2' => $countryMap2,
'currencies' => $currencyMap,
@@ -280,13 +304,9 @@ class ImportService
$data = [];
foreach ($files as $entityType => $filename) {
- if ($entityType === ENTITY_CLIENT) {
- $columns = Client::getImportColumns();
- $map = Client::getImportMap();
- } else {
- $columns = Invoice::getImportColumns();
- $map = Invoice::getImportMap();
- }
+ $class = "App\\Models\\" . ucwords($entityType);
+ $columns = $class::getImportColumns();
+ $map = $class::getImportMap();
// Lookup field translations
foreach ($columns as $key => $value) {
@@ -452,12 +472,8 @@ class ImportService
private function convertToObject($entityType, $data, $map)
{
$obj = new stdClass();
-
- if ($entityType === ENTITY_CLIENT) {
- $columns = Client::getImportColumns();
- } else {
- $columns = Invoice::getImportColumns();
- }
+ $class = "App\\Models\\" . ucwords($entityType);
+ $columns = $class::getImportColumns();
foreach ($columns as $column) {
$obj->$column = false;
diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index 9bf85f0202ae..b96ed265e9d3 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -1314,6 +1314,13 @@ $LANG = array(
'wait_for_upload' => 'Please wait for the document upload to complete.',
'upgrade_for_permissions' => 'Upgrade to our Enterprise plan to enable permissions.',
'enable_second_tax_rate' => 'Enable specifying a second tax rate',
+ 'payment_file' => 'Payment File',
+ 'expense_file' => 'Expense File',
+ 'product_file' => 'Product File',
+ 'import_products' => 'Import Products',
+ 'products_will_create' => 'products will be created.',
+ 'product_key' => 'Product',
+ 'created_products' => 'Successfully created :count product(s)',
);
diff --git a/resources/views/accounts/import_export.blade.php b/resources/views/accounts/import_export.blade.php
index d2f482e0515b..b0f2fd5d7c26 100644
--- a/resources/views/accounts/import_export.blade.php
+++ b/resources/views/accounts/import_export.blade.php
@@ -4,9 +4,7 @@
@parent
@@ -34,7 +32,7 @@
@foreach (\App\Services\ImportService::$entityTypes as $entityType)
{!! Former::file("{$entityType}_file")
- ->addGroupClass("{$entityType}-file") !!}
+ ->addGroupClass("import-file {$entityType}-file") !!}
@endforeach
{!! Former::actions( Button::info(trans('texts.upload'))->submit()->large()->appendIcon(Icon::create('open'))) !!}
@@ -67,13 +65,17 @@
trans('texts.payments') => array('name' => ENTITY_PAYMENT, 'value' => 1),
])->check(ENTITY_CLIENT)->check(ENTITY_TASK)->check(ENTITY_INVOICE)->check(ENTITY_PAYMENT) !!}
- {!! Former::actions( Button::primary(trans('texts.download'))->submit()->large()->appendIcon(Icon::create('download-alt'))) !!}
+ {!! Former::actions( Button::primary(trans('texts.download'))->submit()->large()->appendIcon(Icon::create('download-alt'))) !!}
{!! Former::close() !!}
-@stop
\ No newline at end of file
+@stop
diff --git a/resources/views/accounts/import_map.blade.php b/resources/views/accounts/import_map.blade.php
index 12ac6766d693..5c3c76ac7c20 100644
--- a/resources/views/accounts/import_map.blade.php
+++ b/resources/views/accounts/import_map.blade.php
@@ -7,18 +7,16 @@
{!! Former::open('/import_csv')->addClass('warn-on-exit') !!}
- @if (isset($data[ENTITY_CLIENT]))
- @include('accounts.partials.map', $data[ENTITY_CLIENT])
- @endif
+ @foreach (App\Services\ImportService::$entityTypes as $entityType)
+ @if (isset($data[$entityType]))
+ @include('accounts.partials.map', $data[$entityType])
+ @endif
+ @endforeach
- @if (isset($data[ENTITY_INVOICE]))
- @include('accounts.partials.map', $data[ENTITY_INVOICE])
- @endif
-
- {!! Former::actions(
+ {!! Former::actions(
Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/settings/import_export'))->appendIcon(Icon::create('remove-circle')),
Button::success(trans('texts.import'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))) !!}
-
+
{!! Former::close() !!}
-@stop
\ No newline at end of file
+@stop