mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 21:24:29 -04:00
Merging import changes
This commit is contained in:
parent
9f4cd62832
commit
24bcb0e2e5
@ -1,6 +1,7 @@
|
|||||||
<?php namespace App\Http\Controllers;
|
<?php namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use Exception;
|
||||||
use File;
|
use File;
|
||||||
use Image;
|
use Image;
|
||||||
use Input;
|
use Input;
|
||||||
@ -36,6 +37,7 @@ use App\Models\Timezone;
|
|||||||
use App\Models\Industry;
|
use App\Models\Industry;
|
||||||
use App\Models\InvoiceDesign;
|
use App\Models\InvoiceDesign;
|
||||||
use App\Models\TaxRate;
|
use App\Models\TaxRate;
|
||||||
|
use App\Ninja\Import\DataImporterServiceInterface;
|
||||||
use App\Ninja\Repositories\AccountRepository;
|
use App\Ninja\Repositories\AccountRepository;
|
||||||
use App\Ninja\Repositories\ClientRepository;
|
use App\Ninja\Repositories\ClientRepository;
|
||||||
use App\Ninja\Repositories\ReferralRepository;
|
use App\Ninja\Repositories\ReferralRepository;
|
||||||
@ -55,7 +57,7 @@ class AccountController extends BaseController
|
|||||||
protected $contactMailer;
|
protected $contactMailer;
|
||||||
protected $referralRepository;
|
protected $referralRepository;
|
||||||
|
|
||||||
public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer, ReferralRepository $referralRepository)
|
public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer, ReferralRepository $referralRepository, ClientRepository $clientRepository, DataImporterServiceInterface $dataImporterService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
@ -63,6 +65,8 @@ class AccountController extends BaseController
|
|||||||
$this->userMailer = $userMailer;
|
$this->userMailer = $userMailer;
|
||||||
$this->contactMailer = $contactMailer;
|
$this->contactMailer = $contactMailer;
|
||||||
$this->referralRepository = $referralRepository;
|
$this->referralRepository = $referralRepository;
|
||||||
|
$this->clientRepository = $clientRepository;
|
||||||
|
$this->dataImporterService = $dataImporterService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function demo()
|
public function demo()
|
||||||
@ -413,6 +417,8 @@ class AccountController extends BaseController
|
|||||||
return AccountController::saveLocalization();
|
return AccountController::saveLocalization();
|
||||||
} elseif ($section === ACCOUNT_IMPORT_EXPORT) {
|
} elseif ($section === ACCOUNT_IMPORT_EXPORT) {
|
||||||
return AccountController::importFile();
|
return AccountController::importFile();
|
||||||
|
} elseif ($section === IMPORT_FROM_FRESHBOOKS) {
|
||||||
|
return AccountController::importData();
|
||||||
} elseif ($section === ACCOUNT_MAP) {
|
} elseif ($section === ACCOUNT_MAP) {
|
||||||
return AccountController::mapFile();
|
return AccountController::mapFile();
|
||||||
} elseif ($section === ACCOUNT_NOTIFICATIONS) {
|
} elseif ($section === ACCOUNT_NOTIFICATIONS) {
|
||||||
@ -721,8 +727,7 @@ class AccountController extends BaseController
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$clientRepository = new ClientRepository();
|
$this->clientRepository->save($data);
|
||||||
$clientRepository->save($data);
|
|
||||||
$count++;
|
$count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,6 +737,26 @@ class AccountController extends BaseController
|
|||||||
return Redirect::to('clients');
|
return Redirect::to('clients');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function importData()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$files['client'] = Input::file('client_file');
|
||||||
|
$files['invoice'] = Input::file('invoice_file');
|
||||||
|
$files['timesheet'] = Input::file('timesheet_file');
|
||||||
|
$imported_files = $this->dataImporterService->import($files);
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
Session::flash('error', $e->getMessage());
|
||||||
|
return Redirect::to('settings/' . ACCOUNT_IMPORT_EXPORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::flash('message', trans('texts.imported_file').' - '.$imported_files);
|
||||||
|
|
||||||
|
return Redirect::to('settings/' . ACCOUNT_IMPORT_EXPORT);
|
||||||
|
}
|
||||||
|
|
||||||
private function mapFile()
|
private function mapFile()
|
||||||
{
|
{
|
||||||
$file = Input::file('file');
|
$file = Input::file('file');
|
||||||
|
@ -337,6 +337,8 @@ if (!defined('CONTACT_EMAIL')) {
|
|||||||
define('DEFAULT_FONT_SIZE', 9);
|
define('DEFAULT_FONT_SIZE', 9);
|
||||||
define('DEFAULT_SEND_RECURRING_HOUR', 8);
|
define('DEFAULT_SEND_RECURRING_HOUR', 8);
|
||||||
|
|
||||||
|
define('IMPORT_FROM_FRESHBOOKS', 'import_from_freshbook');
|
||||||
|
|
||||||
define('MAX_NUM_CLIENTS', 100);
|
define('MAX_NUM_CLIENTS', 100);
|
||||||
define('MAX_NUM_CLIENTS_PRO', 20000);
|
define('MAX_NUM_CLIENTS_PRO', 20000);
|
||||||
define('MAX_NUM_CLIENTS_LEGACY', 500);
|
define('MAX_NUM_CLIENTS_LEGACY', 500);
|
||||||
|
15
app/Ninja/Import/DataImporterServiceInterface.php
Normal file
15
app/Ninja/Import/DataImporterServiceInterface.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: eduardocruz
|
||||||
|
* Date: 11/9/15
|
||||||
|
* Time: 11:03
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Ninja\Import;
|
||||||
|
|
||||||
|
|
||||||
|
interface DataImporterServiceInterface
|
||||||
|
{
|
||||||
|
public function import($files);
|
||||||
|
}
|
107
app/Ninja/Import/FreshBooks/ClientTransformer.php
Normal file
107
app/Ninja/Import/FreshBooks/ClientTransformer.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: eduardocruz
|
||||||
|
* Date: 11/9/15
|
||||||
|
* Time: 11:47
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace app\Ninja\Import\FreshBooks;
|
||||||
|
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
use League\Fractal\Resource\Collection;
|
||||||
|
use stdClass;
|
||||||
|
use App\Models\Country;
|
||||||
|
|
||||||
|
class ClientTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function transform($data)
|
||||||
|
{
|
||||||
|
return new Collection($data, function(array $data) {
|
||||||
|
$data = $this->arrayToObject($data);
|
||||||
|
return [
|
||||||
|
'name' => $data->organization !== array() ? $data->organization : '',
|
||||||
|
'work_phone' => $data->busPhone !== array() ? $data->busPhone : '',
|
||||||
|
'address1' => $data->street !== array() ? $data->street : '',
|
||||||
|
'address2' => $data->street2 !== array() ? $data->street2 : '',
|
||||||
|
'city' => $data->city !== array() ? $data->city : '',
|
||||||
|
'state' => $data->province !== array() ? $data->province : '',
|
||||||
|
'postal_code' => $data->postalCode !== array() ? $data->postalCode : '',
|
||||||
|
'private_notes' => $data->notes !== array() ? $data->notes : '',
|
||||||
|
'contacts' => [
|
||||||
|
[
|
||||||
|
'public_id' => '',
|
||||||
|
'first_name' => $data->firstName !== array() ? $data->firstName : '',
|
||||||
|
'last_name' => $data->lastName !== array() ? $data->lastName : '',
|
||||||
|
'email' => $data->email !== array() ? $data->email : '',
|
||||||
|
'phone' => $data->mobPhone !== array() ? $data->mobPhone : $data->homePhone,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'country_id' => !Country::where('name', $data->country)
|
||||||
|
->get()
|
||||||
|
->isEmpty() ? Country::where('name', $data->country)
|
||||||
|
->first()->id : null,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function arrayToObject($array)
|
||||||
|
{
|
||||||
|
$object = new stdClass();
|
||||||
|
$object->organization = $array[0];
|
||||||
|
$object->firstName = $array[1];
|
||||||
|
$object->lastName = $array[2];
|
||||||
|
$object->email = $array[3];
|
||||||
|
$object->street = $array[4];
|
||||||
|
$object->street2 = $array[5];
|
||||||
|
$object->city = $array[6];
|
||||||
|
$object->province = $array[7];
|
||||||
|
$object->country = $array[8];
|
||||||
|
$object->postalCode = $array[9];
|
||||||
|
$object->busPhone = $array[10];
|
||||||
|
$object->homePhone = $array[11];
|
||||||
|
$object->mobPhone = $array[12];
|
||||||
|
$object->fax = $array[13];
|
||||||
|
$object->secStreet = $array[14];
|
||||||
|
$object->secStreet2 = $array[15];
|
||||||
|
$object->secCity = $array[16];
|
||||||
|
$object->secProvince = $array[17];
|
||||||
|
$object->secCountry = $array[18];
|
||||||
|
$object->secPostalCode = $array[19];
|
||||||
|
$object->notes = $array[20];
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateHeader($csvHeader)
|
||||||
|
{
|
||||||
|
$header = [0 => "Organization",
|
||||||
|
1 => "FirstName",
|
||||||
|
2 => "LastName",
|
||||||
|
3 => "Email",
|
||||||
|
4 => "Street",
|
||||||
|
5 => "Street2",
|
||||||
|
6 => "City",
|
||||||
|
7 => "Province",
|
||||||
|
8 => "Country",
|
||||||
|
9 => "PostalCode",
|
||||||
|
10 => "BusPhone",
|
||||||
|
11 => "HomePhone",
|
||||||
|
12 => "MobPhone",
|
||||||
|
13 => "Fax",
|
||||||
|
14 => "SecStreet",
|
||||||
|
15 => "SecStreet2",
|
||||||
|
16 => "SecCity",
|
||||||
|
17 => "SecProvince",
|
||||||
|
18 => "SecCountry",
|
||||||
|
19 => "SecPostalCode",
|
||||||
|
20 => "Notes"];
|
||||||
|
|
||||||
|
if(!empty(array_diff($header, $csvHeader)))
|
||||||
|
throw new Exception(trans('texts.invalid_csv_header'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
154
app/Ninja/Import/FreshBooks/FreshBooksDataImporterService.php
Normal file
154
app/Ninja/Import/FreshBooks/FreshBooksDataImporterService.php
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: eduardocruz
|
||||||
|
* Date: 11/9/15
|
||||||
|
* Time: 11:10
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Ninja\Import\FreshBooks;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use App\Ninja\Import\DataImporterServiceInterface;
|
||||||
|
use League\Fractal\Manager;
|
||||||
|
use parseCSV;
|
||||||
|
use App\Ninja\Repositories\ClientRepository;
|
||||||
|
use App\Ninja\Repositories\InvoiceRepository;
|
||||||
|
use Illuminate\Contracts\Container\Container;
|
||||||
|
|
||||||
|
class FreshBooksDataImporterService implements DataImporterServiceInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $transformer;
|
||||||
|
//protected $repository;
|
||||||
|
protected $invoiceRepo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FreshBooksDataImporterService constructor.
|
||||||
|
*/
|
||||||
|
public function __construct(Manager $manager, ClientRepository $clientRepo, InvoiceRepository $invoiceRepo, Container $container)
|
||||||
|
{
|
||||||
|
$this->clientRepo = $clientRepo;
|
||||||
|
$this->invoiceRepo = $invoiceRepo;
|
||||||
|
$this->container = $container;
|
||||||
|
|
||||||
|
$this->fractal = $manager;
|
||||||
|
$this->transformerList = array(
|
||||||
|
'client' => __NAMESPACE__ . '\ClientTransformer',
|
||||||
|
'invoice' => __NAMESPACE__ . '\InvoiceTransformer',
|
||||||
|
'timesheet' => __NAMESPACE__ . '\TimesheetTransformer',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->repositoryList = array(
|
||||||
|
'client' => '\App\Ninja\Repositories\ClientRepository',
|
||||||
|
'invoice' => '\App\Ninja\Repositories\InvoiceRepository',
|
||||||
|
'timesheet' => '\App\Ninja\Repositories\TaskRepository',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import($files)
|
||||||
|
{
|
||||||
|
$imported_files = null;
|
||||||
|
|
||||||
|
foreach($files as $entity => $file)
|
||||||
|
{
|
||||||
|
$imported_files = $imported_files . $this->execute($entity, $file);
|
||||||
|
}
|
||||||
|
return $imported_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function execute($entity, $file)
|
||||||
|
{
|
||||||
|
$this->transformer = $this->createTransformer($entity);
|
||||||
|
$this->repository = $this->createRepository($entity);
|
||||||
|
|
||||||
|
$data = $this->parseCSV($file);
|
||||||
|
$ignore_header = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$rows = $this->mapCsvToModel($data, $ignore_header);
|
||||||
|
} catch(Exception $e)
|
||||||
|
{
|
||||||
|
throw new Exception($e->getMessage() . ' - ' . $file->getClientOriginalName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
$errorMessages = null;
|
||||||
|
|
||||||
|
foreach($rows as $row)
|
||||||
|
{
|
||||||
|
if($entity=='timesheet')
|
||||||
|
{
|
||||||
|
$publicId = false;
|
||||||
|
$this->repository->save($publicId, $row);
|
||||||
|
} else {
|
||||||
|
$this->repository->save($row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $file->getClientOriginalName().' '.$errorMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseCSV($file)
|
||||||
|
{
|
||||||
|
if ($file == null)
|
||||||
|
throw new Exception(trans('texts.select_file'));
|
||||||
|
|
||||||
|
$name = $file->getRealPath();
|
||||||
|
|
||||||
|
require_once app_path().'/Includes/parsecsv.lib.php';
|
||||||
|
$csv = new parseCSV();
|
||||||
|
$csv->heading = false;
|
||||||
|
$csv->auto($name);
|
||||||
|
|
||||||
|
//Review this code later. Free users can only have 100 clients.
|
||||||
|
/*
|
||||||
|
if (count($csv->data) + Client::scope()->count() > Auth::user()->getMaxNumClients()) {
|
||||||
|
$message = trans('texts.limit_clients', ['count' => Auth::user()->getMaxNumClients()]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return $csv->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $data
|
||||||
|
* Header of the Freshbook CSV File
|
||||||
|
|
||||||
|
* @param $ignore_header
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function mapCsvToModel($data, $ignore_header)
|
||||||
|
{
|
||||||
|
if($ignore_header)
|
||||||
|
{
|
||||||
|
$header = array_shift($data);
|
||||||
|
$this->transformer->validateHeader($header);
|
||||||
|
}
|
||||||
|
|
||||||
|
$resource = $this->transformer->transform($data);
|
||||||
|
$data = $this->fractal->createData($resource)->toArray();
|
||||||
|
|
||||||
|
return $data['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createTransformer($type)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($type, $this->transformerList)) {
|
||||||
|
throw new \InvalidArgumentException("$type is not a valid Transformer");
|
||||||
|
}
|
||||||
|
$className = $this->transformerList[$type];
|
||||||
|
return new $className();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createRepository($type)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($type, $this->repositoryList)) {
|
||||||
|
throw new \InvalidArgumentException("$type is not a valid Repository");
|
||||||
|
}
|
||||||
|
$className = $this->repositoryList[$type];
|
||||||
|
return $this->container->make($className);
|
||||||
|
//return new $className();
|
||||||
|
}
|
||||||
|
}
|
103
app/Ninja/Import/FreshBooks/InvoiceTransformer.php
Normal file
103
app/Ninja/Import/FreshBooks/InvoiceTransformer.php
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: eduardocruz
|
||||||
|
* Date: 11/9/15
|
||||||
|
* Time: 11:47
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace app\Ninja\Import\FreshBooks;
|
||||||
|
|
||||||
|
use App\Models\Client;
|
||||||
|
use Exception;
|
||||||
|
use League\Fractal\Resource\Collection;
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
class InvoiceTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function transform($data)
|
||||||
|
{
|
||||||
|
return new Collection($data, function(array $data) {
|
||||||
|
$data = $this->arrayToObject($data);
|
||||||
|
$client = Client::where('name', $data->organization)->orderBy('created_at', 'desc')->first();
|
||||||
|
$data->client_id = $client->id;
|
||||||
|
$data->user_id = $client->user_id;
|
||||||
|
$data->account_id = $client->account_id;
|
||||||
|
$create_date = new \DateTime($data->create_date);
|
||||||
|
$data->create_date = date_format($create_date, DEFAULT_DATE_FORMAT);
|
||||||
|
return [
|
||||||
|
'invoice_number' => $data->invoice_number !== array() ? $data->invoice_number : '',
|
||||||
|
'client_id' => (int)$data->client_id !== array() ? $data->client_id : '',
|
||||||
|
'user_id' => (int)$data->user_id !== array() ? $data->user_id : '',
|
||||||
|
'account_id' => (int)$data->account_id !== array() ? $data->account_id : '',
|
||||||
|
'amount' => (int)$data->amount !== array() ? $data->amount : '',
|
||||||
|
'po_number' => $data->po_number !== array() ? $data->po_number : '',
|
||||||
|
'terms' => $data->terms !== array() ? $data->terms : '',
|
||||||
|
'public_notes' => $data->notes !== array() ? $data->notes : '',
|
||||||
|
//Best guess on required fields
|
||||||
|
'invoice_date' => $data->create_date !== array() ? $data->create_date : '',
|
||||||
|
'due_date' => $data->create_date !== array() ? $data->create_date : '',
|
||||||
|
'discount' => 0,
|
||||||
|
'invoice_footer' => '',
|
||||||
|
'invoice_design_id' => 1,
|
||||||
|
'invoice_items' => '',
|
||||||
|
'is_amount_discount' => 0,
|
||||||
|
'partial' => 0,
|
||||||
|
'invoice_items' => [
|
||||||
|
[
|
||||||
|
'product_key' => '',
|
||||||
|
'notes' => $data->notes !== array() ? $data->notes : '',
|
||||||
|
'task_public_id' => '',
|
||||||
|
'cost' => (int)$data->amount !== array() ? $data->amount : '',
|
||||||
|
'qty' => 1,
|
||||||
|
'tax' => '',
|
||||||
|
'tax_name' => '',
|
||||||
|
'tax_rate' => 0
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function arrayToObject($array)
|
||||||
|
{
|
||||||
|
$object = new stdClass();
|
||||||
|
$object->invoice_number = $array[0];
|
||||||
|
$object->organization = $array[1];
|
||||||
|
$object->fname = $array[2];
|
||||||
|
$object->lname = $array[3];
|
||||||
|
$object->amount = $array[4];
|
||||||
|
$object->paid = $array[5];
|
||||||
|
$object->po_number = $array[6];
|
||||||
|
$object->create_date = $array[7];
|
||||||
|
$object->date_paid = $array[8];
|
||||||
|
$object->terms = $array[9];
|
||||||
|
$object->notes = $array[10];
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateHeader($csvHeader)
|
||||||
|
{
|
||||||
|
$header = [0 => "invoice_number",
|
||||||
|
1 => "organization",
|
||||||
|
2 => "fname",
|
||||||
|
3 => "lname",
|
||||||
|
4 => "amount",
|
||||||
|
5 => "paid",
|
||||||
|
6 => "po_number",
|
||||||
|
7 => "create_date",
|
||||||
|
8 => "date_paid",
|
||||||
|
9 => "terms",
|
||||||
|
10 => "notes"];
|
||||||
|
|
||||||
|
if(!empty(array_diff($header, $csvHeader)))
|
||||||
|
throw new Exception(trans('texts.invalid_csv_header'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
88
app/Ninja/Import/FreshBooks/StaffTransformer.php
Normal file
88
app/Ninja/Import/FreshBooks/StaffTransformer.php
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: eduardocruz
|
||||||
|
* Date: 11/9/15
|
||||||
|
* Time: 11:47
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace app\Ninja\Import\FreshBooks;
|
||||||
|
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
use League\Fractal\Resource\Collection;
|
||||||
|
use stdClass;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class StaffTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
public function transform($data)
|
||||||
|
{
|
||||||
|
return new Collection($data, function(array $data) {
|
||||||
|
$data = $this->arrayToObject($data);
|
||||||
|
return [
|
||||||
|
'account_id' => Auth::user()->account_id,
|
||||||
|
'first_name' => $data->fname !== array() ? $data->fname : '',
|
||||||
|
'last_name' => $data->lname !== array() ? $data->lname : '',
|
||||||
|
'phone' => $data->bus_phone !== array() ? $data->bus_phone : $data->mob_phone,
|
||||||
|
'username' => $data->email !== array() ? $data->email : '',
|
||||||
|
'email' => $data->email !== array() ? $data->email : '',
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function arrayToObject($array)
|
||||||
|
{
|
||||||
|
$object = new stdClass();
|
||||||
|
$object->fname = $array[0];
|
||||||
|
$object->lname = $array[1];
|
||||||
|
$object->email = $array[2];
|
||||||
|
$object->p_stret = $array[3];
|
||||||
|
$object->p_street2 = $array[4];
|
||||||
|
$object->p_city = $array[5];
|
||||||
|
$object->p_province = $array[6];
|
||||||
|
$object->p_country = $array[7];
|
||||||
|
$object->p_code = $array[8];
|
||||||
|
$object->bus_phone = $array[9];
|
||||||
|
$object->home_phone = $array[10];
|
||||||
|
$object->mob_phone = $array[11];
|
||||||
|
$object->fax = $array[12];
|
||||||
|
$object->s_street = $array[13];
|
||||||
|
$object->s_street2 = $array[14];
|
||||||
|
$object->s_city = $array[15];
|
||||||
|
$object->s_province = $array[16];
|
||||||
|
$object->s_country = $array[17];
|
||||||
|
$object->s_code = $array[18];
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateHeader($csvHeader)
|
||||||
|
{
|
||||||
|
$header = [0 => "fname",
|
||||||
|
1 => "lname",
|
||||||
|
2 => "email",
|
||||||
|
3 => "p_stret",
|
||||||
|
4 => "p_street2",
|
||||||
|
5 => "p_city",
|
||||||
|
6 => "p_province",
|
||||||
|
7 => "p_country",
|
||||||
|
8 => "p_code",
|
||||||
|
9 => "bus_phone",
|
||||||
|
10 => "home_phone",
|
||||||
|
11 => "mob_phone",
|
||||||
|
12 => "fax",
|
||||||
|
13 => "s_street",
|
||||||
|
14 => "s_street2",
|
||||||
|
15 => "s_city",
|
||||||
|
16 => "s_province",
|
||||||
|
17 => "s_country",
|
||||||
|
18 => "s_code"];
|
||||||
|
|
||||||
|
if(empty($difference))
|
||||||
|
return;
|
||||||
|
|
||||||
|
$difference = array_diff($header, $csvHeader);
|
||||||
|
$difference = implode(',', $difference);
|
||||||
|
throw new Exception(trans('texts.invalid_csv_header') . " - $difference - ");
|
||||||
|
}
|
||||||
|
}
|
68
app/Ninja/Import/FreshBooks/TimesheetTransformer.php
Normal file
68
app/Ninja/Import/FreshBooks/TimesheetTransformer.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: eduardocruz
|
||||||
|
* Date: 11/9/15
|
||||||
|
* Time: 11:47
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace app\Ninja\Import\FreshBooks;
|
||||||
|
|
||||||
|
use League\Fractal\TransformerAbstract;
|
||||||
|
use League\Fractal\Resource\Collection;
|
||||||
|
use stdClass;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class TimesheetTransformer extends TransformerAbstract
|
||||||
|
{
|
||||||
|
|
||||||
|
public function transform($data)
|
||||||
|
{
|
||||||
|
return new Collection($data, function(array $data) {
|
||||||
|
$data = $this->arrayToObject($data);
|
||||||
|
// start by converting to seconds
|
||||||
|
$seconds = ($data->hours * 3600);
|
||||||
|
$timeLogFinish = strtotime($data->date);
|
||||||
|
$timeLogStart = intval($timeLogFinish - $seconds);
|
||||||
|
$timeLog[] = [];
|
||||||
|
$timelog[] = $timeLogStart;
|
||||||
|
$timelog[] = $timeLogFinish;
|
||||||
|
//dd(json_decode("[[$timeLogStart,$timeLogFinish]]"));
|
||||||
|
$timeLog = json_encode(array($timelog));
|
||||||
|
return [
|
||||||
|
'action' => 'stop',
|
||||||
|
'time_log' => $timeLog !== array() ? $timeLog : '',
|
||||||
|
'user_id' => Auth::user()->id,
|
||||||
|
'description' => $data->task !== array() ? $data->task : '',
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function arrayToObject($array)
|
||||||
|
{
|
||||||
|
$object = new stdClass();
|
||||||
|
$object->fname = $array[0];
|
||||||
|
$object->lname = $array[1];
|
||||||
|
$object->date = $array[2];
|
||||||
|
$object->project = $array[3];
|
||||||
|
$object->task = $array[4];
|
||||||
|
$object->hours = $array[5];
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateHeader($csvHeader)
|
||||||
|
{
|
||||||
|
$header = [
|
||||||
|
0 => "fname",
|
||||||
|
1 => "lname",
|
||||||
|
2 => "date",
|
||||||
|
3 => "project",
|
||||||
|
4 => "task",
|
||||||
|
5 => "hours"];
|
||||||
|
|
||||||
|
if(!empty(array_diff($header, $csvHeader)))
|
||||||
|
throw new Exception(trans('texts.invalid_csv_header'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -189,6 +189,11 @@ class AppServiceProvider extends ServiceProvider {
|
|||||||
'Illuminate\Contracts\Auth\Registrar',
|
'Illuminate\Contracts\Auth\Registrar',
|
||||||
'App\Services\Registrar'
|
'App\Services\Registrar'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->app->bind(
|
||||||
|
'App\Ninja\Import\DataImporterServiceInterface',
|
||||||
|
'App\Ninja\Import\FreshBooks\FreshBooksDataImporterService'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -195,9 +195,6 @@ return array(
|
|||||||
'site_updates' => 'Site Updates',
|
'site_updates' => 'Site Updates',
|
||||||
'custom_messages' => 'Custom Messages',
|
'custom_messages' => 'Custom Messages',
|
||||||
'default_email_footer' => 'Set default <b>email signature</b>',
|
'default_email_footer' => 'Set default <b>email signature</b>',
|
||||||
'import_clients' => 'Import Client Data',
|
|
||||||
'csv_file' => 'Select CSV file',
|
|
||||||
'export_clients' => 'Export Client Data',
|
|
||||||
'select_file' => 'Please select a file',
|
'select_file' => 'Please select a file',
|
||||||
'first_row_headers' => 'Use first row as headers',
|
'first_row_headers' => 'Use first row as headers',
|
||||||
'column' => 'Column',
|
'column' => 'Column',
|
||||||
@ -208,6 +205,18 @@ return array(
|
|||||||
'email_settings' => 'Email Settings',
|
'email_settings' => 'Email Settings',
|
||||||
'pdf_email_attachment' => 'Attach PDFs',
|
'pdf_email_attachment' => 'Attach PDFs',
|
||||||
|
|
||||||
|
//import CSV data pages
|
||||||
|
'import_clients' => 'Import Client Data',
|
||||||
|
'import_from_freshbooks' => 'Import From FreshBooks',
|
||||||
|
'csv_file' => 'Select CSV file',
|
||||||
|
'csv_client_file' => 'Select CSV Client file',
|
||||||
|
'csv_invoice_file' => 'Select CSV Invoice file',
|
||||||
|
'csv_timesheet_file' => 'Select CSV Timesheet file',
|
||||||
|
'export_clients' => 'Export Client Data',
|
||||||
|
'no_mapper' => 'No valid mapping for file',
|
||||||
|
'invalid_csv_header' => 'Invalid CSV Header',
|
||||||
|
|
||||||
|
|
||||||
// application messages
|
// application messages
|
||||||
'created_client' => 'Successfully created client',
|
'created_client' => 'Successfully created client',
|
||||||
'created_clients' => 'Successfully created :count clients',
|
'created_clients' => 'Successfully created :count clients',
|
||||||
@ -249,6 +258,7 @@ return array(
|
|||||||
'archived_credits' => 'Successfully archived :count credits',
|
'archived_credits' => 'Successfully archived :count credits',
|
||||||
'deleted_credit' => 'Successfully deleted credit',
|
'deleted_credit' => 'Successfully deleted credit',
|
||||||
'deleted_credits' => 'Successfully deleted :count credits',
|
'deleted_credits' => 'Successfully deleted :count credits',
|
||||||
|
'imported_file' => 'Successfully imported file',
|
||||||
|
|
||||||
// Emails
|
// Emails
|
||||||
'confirmation_subject' => 'Invoice Ninja Account Confirmation',
|
'confirmation_subject' => 'Invoice Ninja Account Confirmation',
|
||||||
|
@ -17,6 +17,20 @@
|
|||||||
</div>
|
</div>
|
||||||
{!! Former::close() !!}
|
{!! Former::close() !!}
|
||||||
|
|
||||||
|
{!! Former::open_for_files('settings/' . IMPORT_FROM_FRESHBOOKS) !!}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{!! trans('texts.import_from_freshbooks') !!}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{!! Former::file('client_file')->label(trans('texts.csv_client_file')) !!}
|
||||||
|
{!! Former::file('invoice_file')->label(trans('texts.csv_invoice_file')) !!}
|
||||||
|
{!! Former::file('timesheet_file')->label(trans('texts.csv_timesheet_file')) !!}
|
||||||
|
{!! Former::actions( Button::info(trans('texts.upload'))->submit()->large()->appendIcon(Icon::create('open'))) !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{!! Former::close() !!}
|
||||||
|
|
||||||
|
|
||||||
{!! Former::open('/export') !!}
|
{!! Former::open('/export') !!}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
{!! Former::actions(
|
{!! Former::actions(
|
||||||
Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/settings/import_export'))->appendIcon(Icon::create('remove-circle')),
|
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'))) !!}
|
Button::success(trans('texts.import'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))) !!}
|
||||||
{!! Former::close() !!}
|
{!! Former::close() !!}
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user