1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 13:12:50 +01:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
David Bomba 2015-12-22 22:19:43 +11:00
commit d044cffa44
16 changed files with 87 additions and 51 deletions

View File

@ -22,7 +22,6 @@ class ImportController extends BaseController
{ {
$source = Input::get('source'); $source = Input::get('source');
$files = []; $files = [];
$skipped = [];
foreach (ImportService::$entityTypes as $entityType) { foreach (ImportService::$entityTypes as $entityType) {
if (Input::file("{$entityType}_file")) { if (Input::file("{$entityType}_file")) {
@ -38,8 +37,8 @@ class ImportController extends BaseController
$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]);
} else { } else {
$skipped = $this->importService->import($source, $files); $results = $this->importService->import($source, $files);
return $this->showResult($skipped); return $this->showResult($results);
} }
} catch (Exception $exception) { } catch (Exception $exception) {
Utils::logError($exception); Utils::logError($exception);
@ -52,11 +51,10 @@ class ImportController extends BaseController
{ {
$map = Input::get('map'); $map = Input::get('map');
$headers = Input::get('headers'); $headers = Input::get('headers');
$skipped = [];
try { try {
$skipped = $this->importService->importCSV($map, $headers); $results = $this->importService->importCSV($map, $headers);
return $this->showResult($skipped); return $this->showResult($results);
} catch (Exception $exception) { } catch (Exception $exception) {
Utils::logError($exception); Utils::logError($exception);
Session::flash('error', $exception->getMessage()); Session::flash('error', $exception->getMessage());
@ -64,16 +62,29 @@ class ImportController extends BaseController
} }
} }
private function showResult($skipped) private function showResult($results)
{ {
if (count($skipped)) { $message = '';
$message = trans('texts.failed_to_import'); $skipped = [];
foreach ($skipped as $skip) {
$message .= '<br/>' . json_encode($skip); foreach ($results as $entityType => $entityResults) {
if ($count = count($entityResults[RESULT_SUCCESS])) {
$message .= trans("texts.created_{$entityType}s", ['count' => $count]) . '<br/>';
} }
if (count($entityResults[RESULT_FAILURE])) {
$skipped = array_merge($skipped, $entityResults[RESULT_FAILURE]);
}
}
if (count($skipped)) {
$message .= '<p/>' . trans('texts.failed_to_import') . '<br/>';
foreach ($skipped as $skip) {
$message .= json_encode($skip) . '<br/>';
}
}
if ($message) {
Session::flash('warning', $message); Session::flash('warning', $message);
} else {
Session::flash('message', trans('texts.imported_file'));
} }
return Redirect::to('/settings/' . ACCOUNT_IMPORT_EXPORT); return Redirect::to('/settings/' . ACCOUNT_IMPORT_EXPORT);

View File

@ -512,21 +512,20 @@ class PaymentController extends BaseController
try { try {
if (method_exists($gateway, 'completePurchase') if (method_exists($gateway, 'completePurchase')
&& !$accountGateway->isGateway(GATEWAY_TWO_CHECKOUT) && !$accountGateway->isGateway(GATEWAY_TWO_CHECKOUT)) {
&& !$accountGateway->isGateway(GATEWAY_MOLLIE)) { // TODO: implement webhook
$details = $this->paymentService->getPaymentDetails($invitation, $accountGateway); $details = $this->paymentService->getPaymentDetails($invitation, $accountGateway);
$response = $gateway->completePurchase($details)->send(); $response = $this->paymentService->completePurchase($gateway, $accountGateway, $details, $token);
$ref = $response->getTransactionReference() ?: $token; $ref = $response->getTransactionReference() ?: $token;
if ($response->isSuccessful()) { if ($response->isCancelled()) {
// do nothing
} elseif ($response->isSuccessful()) {
$payment = $this->paymentService->createPayment($invitation, $ref, $payerId); $payment = $this->paymentService->createPayment($invitation, $ref, $payerId);
Session::flash('message', trans('texts.applied_payment')); Session::flash('message', trans('texts.applied_payment'));
return Redirect::to($invitation->getLink());
} else { } else {
$this->error('offsite', $response->getMessage(), $accountGateway); $this->error('offsite', $response->getMessage(), $accountGateway);
return Redirect::to($invitation->getLink());
} }
return Redirect::to($invitation->getLink());
} else { } else {
$payment = $this->paymentService->createPayment($invitation, $token, $payerId); $payment = $this->paymentService->createPayment($invitation, $token, $payerId);
Session::flash('message', trans('texts.applied_payment')); Session::flash('message', trans('texts.applied_payment'));

View File

@ -63,7 +63,6 @@ Route::get('/auth_unlink', 'Auth\AuthController@authUnlink');
Route::post('/hook/email_bounced', 'AppController@emailBounced'); Route::post('/hook/email_bounced', 'AppController@emailBounced');
Route::post('/hook/email_opened', 'AppController@emailOpened'); Route::post('/hook/email_opened', 'AppController@emailOpened');
// Laravel auth routes // Laravel auth routes
get('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@getRegister')); get('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@getRegister'));
post('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@postRegister')); post('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@postRegister'));

View File

@ -25,6 +25,7 @@ class ContactMailer extends Mailer
'firstName', 'firstName',
'invoice', 'invoice',
'quote', 'quote',
'dueDate',
'viewLink', 'viewLink',
'viewButton', 'viewButton',
'paymentLink', 'paymentLink',
@ -234,6 +235,7 @@ class ContactMailer extends Mailer
'$invoice' => $invoice->invoice_number, '$invoice' => $invoice->invoice_number,
'$quote' => $invoice->invoice_number, '$quote' => $invoice->invoice_number,
'$link' => $invitation->getLink(), '$link' => $invitation->getLink(),
'$dueDate' => $account->formatDate($invoice->due_date),
'$viewLink' => $invitation->getLink(), '$viewLink' => $invitation->getLink(),
'$viewButton' => HTML::emailViewButton($invitation->getLink(), $invoice->getEntityType()), '$viewButton' => HTML::emailViewButton($invitation->getLink(), $invoice->getEntityType()),
'$paymentLink' => $invitation->getLink('payment'), '$paymentLink' => $invitation->getLink('payment'),

View File

@ -75,10 +75,12 @@ class ClientRepository extends BaseRepository
$client->fill($data); $client->fill($data);
$client->save(); $client->save();
/*
if ( ! isset($data['contact']) && ! isset($data['contacts'])) { if ( ! isset($data['contact']) && ! isset($data['contacts'])) {
return $client; return $client;
} }
*/
$first = true; $first = true;
$contacts = isset($data['contact']) ? [$data['contact']] : $data['contacts']; $contacts = isset($data['contact']) ? [$data['contact']] : $data['contacts'];
$contactIds = []; $contactIds = [];

View File

@ -317,6 +317,7 @@ class InvoiceRepository extends BaseRepository
$total -= $invoice->discount; $total -= $invoice->discount;
} else { } else {
$total *= (100 - $invoice->discount) / 100; $total *= (100 - $invoice->discount) / 100;
$total = round($total, 2);
} }
} }

View File

@ -56,35 +56,39 @@ class ImportService
public function import($source, $files) public function import($source, $files)
{ {
$skipped = []; $results = [];
$imported_files = null; $imported_files = null;
foreach ($files as $entityType => $file) { foreach ($files as $entityType => $file) {
$result = $this->execute($source, $entityType, $file); $results[$entityType] = $this->execute($source, $entityType, $file);
$skipped = array_merge($skipped, $result);
} }
return $skipped; return $results;
} }
private function execute($source, $entityType, $file) private function execute($source, $entityType, $file)
{ {
$skipped = []; $results = [
RESULT_SUCCESS => [],
RESULT_FAILURE => [],
];
Excel::load($file, function ($reader) use ($source, $entityType, &$skipped) { Excel::load($file, function ($reader) use ($source, $entityType, &$results) {
$this->checkData($entityType, count($reader->all())); $this->checkData($entityType, count($reader->all()));
$maps = $this->createMaps(); $maps = $this->createMaps();
$reader->each(function ($row) use ($source, $entityType, $maps, &$skipped) { $reader->each(function ($row) use ($source, $entityType, $maps, &$results) {
$result = $this->saveData($source, $entityType, $row, $maps); $result = $this->saveData($source, $entityType, $row, $maps);
if ( ! $result) { if ($result) {
$skipped[] = $row; $results[RESULT_SUCCESS][] = $result;
} else {
$results[RESULT_FAILURE][] = $row;
} }
}); });
}); });
return $skipped; return $results;
} }
private function saveData($source, $entityType, $row, $maps) private function saveData($source, $entityType, $row, $maps)
@ -346,19 +350,21 @@ class ImportService
public function importCSV($maps, $headers) public function importCSV($maps, $headers)
{ {
$skipped = []; $results = [];
foreach ($maps as $entityType => $map) { foreach ($maps as $entityType => $map) {
$result = $this->executeCSV($entityType, $map, $headers[$entityType]); $result[$entityType] = $this->executeCSV($entityType, $map, $headers[$entityType]);
$skipped = array_merge($skipped, $result);
} }
return $skipped; return $results;
} }
private function executeCSV($entityType, $map, $hasHeaders) private function executeCSV($entityType, $map, $hasHeaders)
{ {
$skipped = []; $results = [
RESULT_SUCCESS => [],
RESULT_FAILURE => [],
];
$source = IMPORT_CSV; $source = IMPORT_CSV;
$data = Session::get("{$entityType}-data"); $data = Session::get("{$entityType}-data");
@ -374,14 +380,16 @@ class ImportService
$row = $this->convertToObject($entityType, $row, $map); $row = $this->convertToObject($entityType, $row, $map);
$result = $this->saveData($source, $entityType, $row, $maps); $result = $this->saveData($source, $entityType, $row, $maps);
if ( ! $result) { if ($result) {
$skipped[] = $row; $results[RESULT_SUCCESS][] = $result;
} else {
$results[RESULT_FAILURE][] = $row;
} }
} }
Session::forget("{$entityType}-data"); Session::forget("{$entityType}-data");
return $skipped; return $results;
} }
private function convertToObject($entityType, $data, $map) private function convertToObject($entityType, $data, $map)

View File

@ -224,6 +224,17 @@ class PaymentService extends BaseService
return $payment; return $payment;
} }
public function completePurchase($gateway, $accountGateway, $details, $token)
{
if ($accountGateway->isGateway(GATEWAY_MOLLIE)) {
$details['transactionReference'] = $token;
$response = $gateway->fetchTransaction($details)->send();
return $gateway->fetchTransaction($details)->send();
} else {
return $gateway->completePurchase($details)->send();
}
}
public function autoBillInvoice($invoice) public function autoBillInvoice($invoice)
{ {
$client = $invoice->client; $client = $invoice->client;

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -88,7 +88,7 @@ return array(
'company_details' => 'Company Details', 'company_details' => 'Company Details',
'online_payments' => 'Online Payments', 'online_payments' => 'Online Payments',
'notifications' => 'Email Notifications', 'notifications' => 'Email Notifications',
'import_export' => 'Import/Export', 'import_export' => 'Import/Export/Cancel',
'done' => 'Done', 'done' => 'Done',
'save' => 'Save', 'save' => 'Save',
'create' => 'Create', 'create' => 'Create',
@ -212,7 +212,7 @@ return array(
// 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 client(s)',
'updated_settings' => 'Successfully updated settings', 'updated_settings' => 'Successfully updated settings',
'removed_logo' => 'Successfully removed logo', 'removed_logo' => 'Successfully removed logo',
'sent_message' => 'Successfully sent message', 'sent_message' => 'Successfully sent message',
@ -980,5 +980,7 @@ return array(
'button_confirmation_message' => 'Click to confirm your email address.', 'button_confirmation_message' => 'Click to confirm your email address.',
'confirm' => 'Confirm', 'confirm' => 'Confirm',
'email_preferences' => 'Email Preferences', 'email_preferences' => 'Email Preferences',
'created_invoices' => 'Successfully created :count invoice(s)',
); );

View File

@ -97,7 +97,7 @@
<div class="modal-footer" style="margin-top: 0px"> <div class="modal-footer" style="margin-top: 0px">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.go_back') }}</button> <button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.go_back') }}</button>
<button type="button" class="btn btn-primary" onclick="confirmCancel()">{{ trans('texts.cancel_account') }}</button> <button type="button" class="btn btn-danger" onclick="confirmCancel()">{{ trans('texts.cancel_account') }}</button>
</div> </div>
</div> </div>

View File

@ -184,13 +184,14 @@
var keys = {!! json_encode(\App\Ninja\Mailers\ContactMailer::$variableFields) !!}; var keys = {!! json_encode(\App\Ninja\Mailers\ContactMailer::$variableFields) !!};
var vals = [ var vals = [
{!! json_encode($emailFooter) !!}, {!! json_encode($emailFooter) !!},
"{{ Auth::user()->account->getDisplayName() }}", "{{ $account->getDisplayName() }}",
"Client Name", "Client Name",
formatMoney(100), formatMoney(100),
"Contact Name", "Contact Name",
"First Name", "First Name",
"0001", "0001",
"0001", "0001",
"{{ $account->formatDate($account->getDateTime()) }}",
"{{ URL::to('/view/...') }}", "{{ URL::to('/view/...') }}",
'{!! HTML::flatButton('view_invoice', '#0b4d78') !!}', '{!! HTML::flatButton('view_invoice', '#0b4d78') !!}',
"{{ URL::to('/payment/...') }}", "{{ URL::to('/payment/...') }}",

View File

@ -71,7 +71,7 @@
<div class="panel panel-default dashboard" style="height:320px"> <div class="panel panel-default dashboard" style="height:320px">
<div class="panel-heading" style="background-color:#0b4d78 !important"> <div class="panel-heading" style="background-color:#0b4d78 !important">
<h3 class="panel-title in-bold-white"> <h3 class="panel-title in-bold-white">
<i class="glyphicon glyphicon-exclamation-sign"></i> {{ trans('texts.notifications') }} <i class="glyphicon glyphicon-exclamation-sign"></i> {{ trans('texts.activity') }}
<div class="pull-right" style="font-size:14px;padding-top:4px"> <div class="pull-right" style="font-size:14px;padding-top:4px">
{{ trans_choice('texts.invoices_sent', $invoicesSent) }} {{ trans_choice('texts.invoices_sent', $invoicesSent) }}
</div> </div>

View File

@ -4,7 +4,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head> </head>
<body style="min-height: 700px; color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 12px; -webkit-text-size-adjust: none; -ms-text-size-adjust: none; background: #F4F5F5; margin: 0; padding: 0;" <body style="min-height: 600px; color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 12px; -webkit-text-size-adjust: none; -ms-text-size-adjust: none; background: #F4F5F5; margin: 0; padding: 0;"
alink="#FF0000" link="#FF0000" bgcolor="#F4F5F5" text="#000000" yahoo="fix"> alink="#FF0000" link="#FF0000" bgcolor="#F4F5F5" text="#000000" yahoo="fix">
@yield('markup') @yield('markup')
@ -48,7 +48,7 @@
} }
</style> </style>
<div id="body_style" style="min-height: 700px; color: #2E2B2B; font-family: Helvetica, sans-serif; font-size: 16px; <div id="body_style" style="min-height: 600px; color: #2E2B2B; font-family: Helvetica, sans-serif; font-size: 16px;
background: #F4F5F5; padding: 0px 15px;"> background: #F4F5F5; padding: 0px 15px;">
<table cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF" width="600" align="center"> <table cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF" width="600" align="center">

View File

@ -6,7 +6,7 @@
@else @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') }}" /> <meta name="description" content="{{ isset($description) ? $description : trans('texts.app_description') }}" />
<link href="{{ asset('favicon-v2.png') }}" rel="shortcut icon"> <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/hillelcoren/invoice-ninja -->

View File

@ -66,7 +66,7 @@
$('#dbTestResult').html('Working...').css('color', 'black'); $('#dbTestResult').html('Working...').css('color', 'black');
// Send / Test Information // Send / Test Information
$.post( "/setup", data, function( data ) { $.post( "{{ URL::to('/setup') }}", data, function( data ) {
var color = 'red'; var color = 'red';
if(data == 'Success'){ if(data == 'Success'){
color = 'green'; color = 'green';
@ -86,7 +86,7 @@
$('#mailTestResult').html('Working...').css('color', 'black'); $('#mailTestResult').html('Working...').css('color', 'black');
// Send / Test Information // Send / Test Information
$.post( "/setup", data, function( data ) { $.post( "{{ URL::to('/setup') }}", data, function( data ) {
var color = 'red'; var color = 'red';
if(data == 'Sent'){ if(data == 'Sent'){
color = 'green'; color = 'green';