mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 12:42:36 +01:00
Working on basic reports
This commit is contained in:
parent
bc10719fbe
commit
1d6013178f
@ -98,7 +98,7 @@ class AccountController extends BaseController
|
|||||||
|
|
||||||
Auth::login($user, true);
|
Auth::login($user, true);
|
||||||
Event::fire(new UserLoggedIn());
|
Event::fire(new UserLoggedIn());
|
||||||
|
|
||||||
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
|
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,40 +343,27 @@ class AccountController extends BaseController
|
|||||||
header('Content-Disposition:attachment;filename=export.csv');
|
header('Content-Disposition:attachment;filename=export.csv');
|
||||||
|
|
||||||
$clients = Client::scope()->get();
|
$clients = Client::scope()->get();
|
||||||
AccountController::exportData($output, $clients->toArray());
|
Utils::exportData($output, $clients->toArray());
|
||||||
|
|
||||||
$contacts = Contact::scope()->get();
|
$contacts = Contact::scope()->get();
|
||||||
AccountController::exportData($output, $contacts->toArray());
|
Utils::exportData($output, $contacts->toArray());
|
||||||
|
|
||||||
$invoices = Invoice::scope()->get();
|
$invoices = Invoice::scope()->get();
|
||||||
AccountController::exportData($output, $invoices->toArray());
|
Utils::exportData($output, $invoices->toArray());
|
||||||
|
|
||||||
$invoiceItems = InvoiceItem::scope()->get();
|
$invoiceItems = InvoiceItem::scope()->get();
|
||||||
AccountController::exportData($output, $invoiceItems->toArray());
|
Utils::exportData($output, $invoiceItems->toArray());
|
||||||
|
|
||||||
$payments = Payment::scope()->get();
|
$payments = Payment::scope()->get();
|
||||||
AccountController::exportData($output, $payments->toArray());
|
Utils::exportData($output, $payments->toArray());
|
||||||
|
|
||||||
$credits = Credit::scope()->get();
|
$credits = Credit::scope()->get();
|
||||||
AccountController::exportData($output, $credits->toArray());
|
Utils::exportData($output, $credits->toArray());
|
||||||
|
|
||||||
fclose($output);
|
fclose($output);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function exportData($output, $data)
|
|
||||||
{
|
|
||||||
if (count($data) > 0) {
|
|
||||||
fputcsv($output, array_keys($data[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($data as $record) {
|
|
||||||
fputcsv($output, $record);
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite($output, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private function importFile()
|
private function importFile()
|
||||||
{
|
{
|
||||||
$data = Session::get('data');
|
$data = Session::get('data');
|
||||||
|
@ -187,7 +187,7 @@ class InvoiceController extends BaseController
|
|||||||
$server = explode('.', Request::server('HTTP_HOST'));
|
$server = explode('.', Request::server('HTTP_HOST'));
|
||||||
$subdomain = $server[0];
|
$subdomain = $server[0];
|
||||||
|
|
||||||
if ($subdomain != 'app' && $subdomain != $account->subdomain) {
|
if (!in_array($subdomain, ['app', 'www']) && $subdomain != $account->subdomain) {
|
||||||
return View::make('invoices.deleted');
|
return View::make('invoices.deleted');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,18 +37,26 @@ class ReportController extends BaseController
|
|||||||
return View::make('reports.d3', $data);
|
return View::make('reports.d3', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function report()
|
public function showReports()
|
||||||
{
|
{
|
||||||
|
$action = Input::get('action');
|
||||||
|
|
||||||
if (Input::all()) {
|
if (Input::all()) {
|
||||||
$groupBy = Input::get('group_by');
|
$groupBy = Input::get('group_by');
|
||||||
$chartType = Input::get('chart_type');
|
$chartType = Input::get('chart_type');
|
||||||
|
$reportType = Input::get('report_type');
|
||||||
$startDate = Utils::toSqlDate(Input::get('start_date'), false);
|
$startDate = Utils::toSqlDate(Input::get('start_date'), false);
|
||||||
$endDate = Utils::toSqlDate(Input::get('end_date'), false);
|
$endDate = Utils::toSqlDate(Input::get('end_date'), false);
|
||||||
|
$enableReport = Input::get('enable_report') ? true : false;
|
||||||
|
$enableChart = Input::get('enable_chart') ? true : false;
|
||||||
} else {
|
} else {
|
||||||
$groupBy = 'MONTH';
|
$groupBy = 'MONTH';
|
||||||
$chartType = 'Bar';
|
$chartType = 'Bar';
|
||||||
|
$reportType = '';
|
||||||
$startDate = Utils::today(false)->modify('-3 month');
|
$startDate = Utils::today(false)->modify('-3 month');
|
||||||
$endDate = Utils::today(false);
|
$endDate = Utils::today(false);
|
||||||
|
$enableReport = true;
|
||||||
|
$enableChart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
|
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
|
||||||
@ -58,55 +66,142 @@ class ReportController extends BaseController
|
|||||||
$maxTotals = 0;
|
$maxTotals = 0;
|
||||||
$width = 10;
|
$width = 10;
|
||||||
|
|
||||||
|
$displayData = [];
|
||||||
|
$exportData = [];
|
||||||
|
$columns = [];
|
||||||
|
$reportTotals = [
|
||||||
|
'amount' => [],
|
||||||
|
'balance' => [],
|
||||||
|
'paid' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
if (Auth::user()->account->isPro()) {
|
if (Auth::user()->account->isPro()) {
|
||||||
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType) {
|
|
||||||
$records = DB::table($entityType.'s')
|
|
||||||
->select(DB::raw('sum(amount) as total, '.$groupBy.'('.$entityType.'_date) as '.$groupBy))
|
|
||||||
->where('account_id', '=', Auth::user()->account_id)
|
|
||||||
->where($entityType.'s.is_deleted', '=', false)
|
|
||||||
->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d'))
|
|
||||||
->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d'))
|
|
||||||
->groupBy($groupBy);
|
|
||||||
|
|
||||||
if ($entityType == ENTITY_INVOICE) {
|
if ($enableReport) {
|
||||||
$records->where('is_quote', '=', false)
|
$query = DB::table('invoices')
|
||||||
->where('is_recurring', '=', false);
|
->join('clients', 'clients.id', '=', 'invoices.client_id')
|
||||||
|
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
|
->where('invoices.account_id', '=', Auth::user()->account_id)
|
||||||
|
->where('invoices.is_deleted', '=', false)
|
||||||
|
->where('clients.is_deleted', '=', false)
|
||||||
|
->where('contacts.deleted_at', '=', null)
|
||||||
|
->where('invoices.invoice_date', '>=', $startDate->format('Y-m-d'))
|
||||||
|
->where('invoices.invoice_date', '<=', $endDate->format('Y-m-d'))
|
||||||
|
->where('invoices.is_quote', '=', false)
|
||||||
|
->where('invoices.is_recurring', '=', false)
|
||||||
|
->where('contacts.is_primary', '=', true);
|
||||||
|
|
||||||
|
$select = ['clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'clients.name as client_name', 'clients.public_id as client_public_id', 'invoices.public_id as invoice_public_id'];
|
||||||
|
|
||||||
|
if ($reportType) {
|
||||||
|
$query->groupBy('clients.id');
|
||||||
|
array_push($select, DB::raw('sum(invoices.amount) amount'), DB::raw('sum(invoices.balance) balance'), DB::raw('sum(invoices.amount - invoices.balance) paid'));
|
||||||
|
$columns = ['client', 'amount', 'paid', 'balance'];
|
||||||
|
} else {
|
||||||
|
array_push($select, 'invoices.invoice_number', 'invoices.amount', 'invoices.balance', 'invoices.invoice_date', DB::raw('(invoices.amount - invoices.balance) paid'));
|
||||||
|
$query->orderBy('invoices.id');
|
||||||
|
$columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'paid', 'balance'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$query->select($select);
|
||||||
|
$data = $query->get();
|
||||||
|
|
||||||
$totals = $records->lists('total');
|
foreach ($data as $record) {
|
||||||
$dates = $records->lists($groupBy);
|
// web display data
|
||||||
$data = array_combine($dates, $totals);
|
$displayRow = [link_to('/clients/'.$record->client_public_id, Utils::getClientDisplayName($record))];
|
||||||
|
if (!$reportType) {
|
||||||
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
|
array_push($displayRow,
|
||||||
$period = new DatePeriod($startDate, $interval, $endDate);
|
link_to('/invoices/'.$record->invoice_public_id, $record->invoice_number),
|
||||||
|
Utils::fromSqlDate($record->invoice_date, true)
|
||||||
$totals = [];
|
);
|
||||||
|
|
||||||
foreach ($period as $d) {
|
|
||||||
$dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n');
|
|
||||||
$date = $d->format($dateFormat);
|
|
||||||
$totals[] = isset($data[$date]) ? $data[$date] : 0;
|
|
||||||
|
|
||||||
if ($entityType == ENTITY_INVOICE) {
|
|
||||||
$labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F');
|
|
||||||
$label = $d->format($labelFormat);
|
|
||||||
$labels[] = $label;
|
|
||||||
}
|
}
|
||||||
|
array_push($displayRow,
|
||||||
|
Utils::formatMoney($record->amount, $record->currency_id),
|
||||||
|
Utils::formatMoney($record->paid, $record->currency_id),
|
||||||
|
Utils::formatMoney($record->balance, $record->currency_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
// export data
|
||||||
|
$exportRow = [trans('texts.client') => Utils::getClientDisplayName($record)];
|
||||||
|
if (!$reportType) {
|
||||||
|
$exportRow[trans('texts.invoice_number')] = $record->invoice_number;
|
||||||
|
$exportRow[trans('texts.invoice_date')] = Utils::fromSqlDate($record->invoice_date, true);
|
||||||
|
}
|
||||||
|
$exportRow[trans('texts.amount')] = Utils::formatMoney($record->amount, $record->currency_id);
|
||||||
|
$exportRow[trans('texts.paid')] = Utils::formatMoney($record->paid, $record->currency_id);
|
||||||
|
$exportRow[trans('texts.balance')] = Utils::formatMoney($record->balance, $record->currency_id);
|
||||||
|
|
||||||
|
$displayData[] = $displayRow;
|
||||||
|
$exportData[] = $exportRow;
|
||||||
|
|
||||||
|
$accountCurrencyId = Auth::user()->account->currency_id;
|
||||||
|
$currencyId = $record->currency_id ? $record->currency_id : ($accountCurrencyId ? $accountCurrencyId : DEFAULT_CURRENCY);
|
||||||
|
if (!isset($reportTotals['amount'][$currencyId])) {
|
||||||
|
$reportTotals['amount'][$currencyId] = 0;
|
||||||
|
$reportTotals['balance'][$currencyId] = 0;
|
||||||
|
$reportTotals['paid'][$currencyId] = 0;
|
||||||
|
}
|
||||||
|
$reportTotals['amount'][$currencyId] += $record->amount;
|
||||||
|
$reportTotals['paid'][$currencyId] += $record->paid;
|
||||||
|
$reportTotals['balance'][$currencyId] += $record->balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
$max = max($totals);
|
if ($action == 'export') {
|
||||||
|
self::export($exportData, $reportTotals);
|
||||||
if ($max > 0) {
|
|
||||||
$datasets[] = [
|
|
||||||
'totals' => $totals,
|
|
||||||
'colors' => $entityType == ENTITY_INVOICE ? '78,205,196' : ($entityType == ENTITY_CREDIT ? '199,244,100' : '255,107,107'),
|
|
||||||
];
|
|
||||||
$maxTotals = max($max, $maxTotals);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$width = (ceil($maxTotals / 100) * 100) / 10;
|
if ($enableChart) {
|
||||||
$width = max($width, 10);
|
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType) {
|
||||||
|
$records = DB::table($entityType.'s')
|
||||||
|
->select(DB::raw('sum(amount) as total, '.$groupBy.'('.$entityType.'_date) as '.$groupBy))
|
||||||
|
->where('account_id', '=', Auth::user()->account_id)
|
||||||
|
->where($entityType.'s.is_deleted', '=', false)
|
||||||
|
->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d'))
|
||||||
|
->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d'))
|
||||||
|
->groupBy($groupBy);
|
||||||
|
|
||||||
|
if ($entityType == ENTITY_INVOICE) {
|
||||||
|
$records->where('is_quote', '=', false)
|
||||||
|
->where('is_recurring', '=', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$totals = $records->lists('total');
|
||||||
|
$dates = $records->lists($groupBy);
|
||||||
|
$data = array_combine($dates, $totals);
|
||||||
|
|
||||||
|
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
|
||||||
|
$period = new DatePeriod($startDate, $interval, $endDate);
|
||||||
|
|
||||||
|
$totals = [];
|
||||||
|
|
||||||
|
foreach ($period as $d) {
|
||||||
|
$dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n');
|
||||||
|
$date = $d->format($dateFormat);
|
||||||
|
$totals[] = isset($data[$date]) ? $data[$date] : 0;
|
||||||
|
|
||||||
|
if ($entityType == ENTITY_INVOICE) {
|
||||||
|
$labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F');
|
||||||
|
$label = $d->format($labelFormat);
|
||||||
|
$labels[] = $label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$max = max($totals);
|
||||||
|
|
||||||
|
if ($max > 0) {
|
||||||
|
$datasets[] = [
|
||||||
|
'totals' => $totals,
|
||||||
|
'colors' => $entityType == ENTITY_INVOICE ? '78,205,196' : ($entityType == ENTITY_CREDIT ? '199,244,100' : '255,107,107'),
|
||||||
|
];
|
||||||
|
$maxTotals = max($max, $maxTotals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$width = (ceil($maxTotals / 100) * 100) / 10;
|
||||||
|
$width = max($width, 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$dateTypes = [
|
$dateTypes = [
|
||||||
@ -120,6 +215,11 @@ class ReportController extends BaseController
|
|||||||
'Line' => 'Line',
|
'Line' => 'Line',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$reportTypes = [
|
||||||
|
'' => '',
|
||||||
|
'Client' => trans('texts.client')
|
||||||
|
];
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'labels' => $labels,
|
'labels' => $labels,
|
||||||
'datasets' => $datasets,
|
'datasets' => $datasets,
|
||||||
@ -131,8 +231,35 @@ class ReportController extends BaseController
|
|||||||
'endDate' => $endDate->modify('-1'.$padding)->format(Session::get(SESSION_DATE_FORMAT)),
|
'endDate' => $endDate->modify('-1'.$padding)->format(Session::get(SESSION_DATE_FORMAT)),
|
||||||
'groupBy' => $groupBy,
|
'groupBy' => $groupBy,
|
||||||
'feature' => ACCOUNT_CHART_BUILDER,
|
'feature' => ACCOUNT_CHART_BUILDER,
|
||||||
|
'displayData' => $displayData,
|
||||||
|
'columns' => $columns,
|
||||||
|
'reportTotals' => $reportTotals,
|
||||||
|
'reportTypes' => $reportTypes,
|
||||||
|
'reportType' => $reportType,
|
||||||
|
'enableChart' => $enableChart,
|
||||||
|
'enableReport' => $enableReport,
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('reports.report_builder', $params);
|
return View::make('reports.chart_builder', $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function export($data, $totals)
|
||||||
|
{
|
||||||
|
$output = fopen('php://output', 'w') or Utils::fatalError();
|
||||||
|
header('Content-Type:application/csv');
|
||||||
|
header('Content-Disposition:attachment;filename=ninja-report.csv');
|
||||||
|
|
||||||
|
Utils::exportData($output, $data);
|
||||||
|
|
||||||
|
foreach (['amount', 'paid', 'balance'] as $type) {
|
||||||
|
$csv = trans("texts.{$type}") . ',';
|
||||||
|
foreach ($totals[$type] as $currencyId => $amount) {
|
||||||
|
$csv .= Utils::formatMoney($amount, $currencyId) . ',';
|
||||||
|
}
|
||||||
|
fwrite($output, $csv . "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($output);
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,17 @@ class DuplicateSubmissionCheck
|
|||||||
// Prevent users from submitting forms twice
|
// Prevent users from submitting forms twice
|
||||||
public function handle($request, Closure $next)
|
public function handle($request, Closure $next)
|
||||||
{
|
{
|
||||||
|
$path = $request->path();
|
||||||
|
|
||||||
|
if (strpos($path, 'charts_and_reports') !== false) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
if (in_array($request->method(), ['POST', 'PUT', 'DELETE'])) {
|
if (in_array($request->method(), ['POST', 'PUT', 'DELETE'])) {
|
||||||
$lastPage = session(SESSION_LAST_REQUEST_PAGE);
|
$lastPage = session(SESSION_LAST_REQUEST_PAGE);
|
||||||
$lastTime = session(SESSION_LAST_REQUEST_TIME);
|
$lastTime = session(SESSION_LAST_REQUEST_TIME);
|
||||||
|
|
||||||
if ($lastPage == $request->path() && (microtime(true) - $lastTime <= 1.5)) {
|
if ($lastPage == $path && (microtime(true) - $lastTime <= 1.5)) {
|
||||||
return redirect('/')->with('warning', trans('texts.duplicate_post'));
|
return redirect('/')->with('warning', trans('texts.duplicate_post'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,8 @@ class StartupCheck
|
|||||||
$count = Session::get(SESSION_COUNTER, 0);
|
$count = Session::get(SESSION_COUNTER, 0);
|
||||||
Session::put(SESSION_COUNTER, ++$count);
|
Session::put(SESSION_COUNTER, ++$count);
|
||||||
|
|
||||||
if (!Utils::startsWith($_SERVER['REQUEST_URI'], '/news_feed') && !Session::has('news_feed_id')) {
|
//if (!Utils::startsWith($_SERVER['REQUEST_URI'], '/news_feed') && !Session::has('news_feed_id')) {
|
||||||
|
if (true) {
|
||||||
$data = false;
|
$data = false;
|
||||||
if (Utils::isNinja()) {
|
if (Utils::isNinja()) {
|
||||||
$data = Utils::getNewsFeedResponse();
|
$data = Utils::getNewsFeedResponse();
|
||||||
@ -75,12 +76,12 @@ class StartupCheck
|
|||||||
$data = @json_decode($file);
|
$data = @json_decode($file);
|
||||||
}
|
}
|
||||||
if ($data) {
|
if ($data) {
|
||||||
if ($data->version != NINJA_VERSION) {
|
if (version_compare(NINJA_VERSION, $data->version, '<')) {
|
||||||
$params = [
|
$params = [
|
||||||
'user_version' => NINJA_VERSION,
|
'user_version' => NINJA_VERSION,
|
||||||
'latest_version' => $data->version,
|
'latest_version' => $data->version,
|
||||||
'releases_link' => link_to(RELEASES_URL, 'Invoice Ninja', ['target' => '_blank']),
|
'releases_link' => link_to(RELEASES_URL, 'Invoice Ninja', ['target' => '_blank']),
|
||||||
];
|
];
|
||||||
Session::put('news_feed_id', NEW_VERSION_AVAILABLE);
|
Session::put('news_feed_id', NEW_VERSION_AVAILABLE);
|
||||||
Session::put('news_feed_message', trans('texts.new_version_available', $params));
|
Session::put('news_feed_message', trans('texts.new_version_available', $params));
|
||||||
} else {
|
} else {
|
||||||
|
@ -112,8 +112,8 @@ Route::group(['middleware' => 'auth'], function() {
|
|||||||
Route::get('products/{product_id}/archive', 'ProductController@archive');
|
Route::get('products/{product_id}/archive', 'ProductController@archive');
|
||||||
|
|
||||||
Route::get('company/advanced_settings/data_visualizations', 'ReportController@d3');
|
Route::get('company/advanced_settings/data_visualizations', 'ReportController@d3');
|
||||||
Route::get('company/advanced_settings/chart_builder', 'ReportController@report');
|
Route::get('company/advanced_settings/charts_and_reports', 'ReportController@showReports');
|
||||||
Route::post('company/advanced_settings/chart_builder', 'ReportController@report');
|
Route::post('company/advanced_settings/charts_and_reports', 'ReportController@showReports');
|
||||||
|
|
||||||
Route::post('company/cancel_account', 'AccountController@cancelAccount');
|
Route::post('company/cancel_account', 'AccountController@cancelAccount');
|
||||||
Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData'));
|
Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData'));
|
||||||
@ -354,10 +354,11 @@ define('NINJA_GATEWAY_ID', GATEWAY_AUTHORIZE_NET);
|
|||||||
define('NINJA_GATEWAY_CONFIG', '');
|
define('NINJA_GATEWAY_CONFIG', '');
|
||||||
define('NINJA_WEB_URL', 'https://www.invoiceninja.com');
|
define('NINJA_WEB_URL', 'https://www.invoiceninja.com');
|
||||||
define('NINJA_APP_URL', 'https://app.invoiceninja.com');
|
define('NINJA_APP_URL', 'https://app.invoiceninja.com');
|
||||||
define('NINJA_VERSION', '1.7.2');
|
define('NINJA_VERSION', '2.0.0');
|
||||||
define('NINJA_DATE', '2000-01-01');
|
define('NINJA_DATE', '2000-01-01');
|
||||||
define('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com');
|
define('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com');
|
||||||
define('RELEASES_URL', 'https://github.com/hillelcoren/invoice-ninja/releases/');
|
define('RELEASES_URL', 'https://github.com/hillelcoren/invoice-ninja/releases/');
|
||||||
|
define('ZAPIER_URL', 'https://zapier.com/developer/invite/11276/85cf0ee4beae8e802c6c579eb4e351f1/');
|
||||||
|
|
||||||
define('COUNT_FREE_DESIGNS', 4);
|
define('COUNT_FREE_DESIGNS', 4);
|
||||||
define('PRODUCT_ONE_CLICK_INSTALL', 1);
|
define('PRODUCT_ONE_CLICK_INSTALL', 1);
|
||||||
|
@ -623,4 +623,17 @@ class Utils
|
|||||||
|
|
||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function exportData($output, $data)
|
||||||
|
{
|
||||||
|
if (count($data) > 0) {
|
||||||
|
fputcsv($output, array_keys($data[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data as $record) {
|
||||||
|
fputcsv($output, $record);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite($output, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'encrypt' => false,
|
'encrypt' => env('SESSION_ENCRYPT', false),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -109,7 +109,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'cookie' => 'laravel_session',
|
'cookie' => 'ninja_session',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -135,7 +135,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'domain' => null,
|
'domain' => env('SESSION_DOMAIN', null),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -148,6 +148,6 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'secure' => false,
|
'secure' => env('SESSION_SECURE', false),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
10
public/css/built.css
vendored
10
public/css/built.css
vendored
@ -3238,11 +3238,15 @@ div.checkbox > label {
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_length {
|
div.dataTables_length {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-top: 8px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_length label {
|
div.dataTables_length select {
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dataTables_length label {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
10
public/css/style.css
vendored
10
public/css/style.css
vendored
@ -854,11 +854,15 @@ div.checkbox > label {
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_length {
|
div.dataTables_length {
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-top: 8px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_length label {
|
div.dataTables_length select {
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dataTables_length label {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
10
readme.md
10
readme.md
@ -4,6 +4,16 @@
|
|||||||
|
|
||||||
If you'd like to use our code to sell your own invoicing app we have an affiliate program. Get in touch for more details.
|
If you'd like to use our code to sell your own invoicing app we have an affiliate program. Get in touch for more details.
|
||||||
|
|
||||||
|
### Introduction
|
||||||
|
|
||||||
|
To setup the site you can either use the [zip file](https://www.invoiceninja.com/knowledgebase/self-host/) (easier to run) or checkout the code from GitHub (easier to make changes).
|
||||||
|
|
||||||
|
For updates follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the code please use the [Google Group](https://groups.google.com/d/forum/invoiceninja).
|
||||||
|
|
||||||
|
If you'd like to translate the site please use [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) for the starter files.
|
||||||
|
|
||||||
|
Developed by [@hillelcoren](https://twitter.com/hillelcoren) | Designed by [kantorp-wegl.in](http://kantorp-wegl.in/).
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* Core application built using Laravel 5
|
* Core application built using Laravel 5
|
||||||
|
@ -637,5 +637,18 @@ return array(
|
|||||||
'www' => 'www',
|
'www' => 'www',
|
||||||
'logo' => 'Logo',
|
'logo' => 'Logo',
|
||||||
'subdomain' => 'Subdomain',
|
'subdomain' => 'Subdomain',
|
||||||
|
'provide_name_or_email' => 'Please provide a contact name or email',
|
||||||
|
'charts_and_reports' => 'Charts & Reports',
|
||||||
|
'chart' => 'Chart',
|
||||||
|
'report' => 'Report',
|
||||||
|
'group_by' => 'Group by',
|
||||||
|
'paid' => 'Paid',
|
||||||
|
'enable_report' => 'Report',
|
||||||
|
'enable_chart' => 'Chart',
|
||||||
|
'totals' => 'Totals',
|
||||||
|
'run' => 'Run',
|
||||||
|
'export' => 'Export',
|
||||||
|
'documentation' => 'Documentation',
|
||||||
|
'zapier' => 'Zapier <sup>Beta</sup>',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{!! HTML::nav_link('company/advanced_settings/invoice_settings', 'invoice_settings') !!}
|
{!! HTML::nav_link('company/advanced_settings/invoice_settings', 'invoice_settings') !!}
|
||||||
{!! HTML::nav_link('company/advanced_settings/invoice_design', 'invoice_design') !!}
|
{!! HTML::nav_link('company/advanced_settings/invoice_design', 'invoice_design') !!}
|
||||||
{!! HTML::nav_link('company/advanced_settings/email_templates', 'email_templates') !!}
|
{!! HTML::nav_link('company/advanced_settings/email_templates', 'email_templates') !!}
|
||||||
{!! HTML::nav_link('company/advanced_settings/chart_builder', 'chart_builder') !!}
|
{!! HTML::nav_link('company/advanced_settings/charts_and_reports', 'charts_and_reports') !!}
|
||||||
{!! HTML::nav_link('company/advanced_settings/user_management', 'users_and_tokens') !!}
|
{!! HTML::nav_link('company/advanced_settings/user_management', 'users_and_tokens') !!}
|
||||||
</ul>
|
</ul>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
{!! Button::normal(trans('texts.view_documentation'))->asLinkTo(NINJA_WEB_URL.'/knowledgebase/api-documentation/')->withAttributes(['target' => '_blank']) !!}
|
{!! Button::normal(trans('texts.documentation'))->asLinkTo(NINJA_WEB_URL.'/knowledgebase/api-documentation/')->withAttributes(['target' => '_blank']) !!}
|
||||||
|
{!! Button::normal(trans('texts.zapier'))->asLinkTo(ZAPIER_URL)->withAttributes(['target' => '_blank']) !!}
|
||||||
@if (Utils::isPro())
|
@if (Utils::isPro())
|
||||||
{!! Button::primary(trans('texts.add_token'))->asLinkTo('/tokens/create')->appendIcon(Icon::create('plus-sign')) !!}
|
{!! Button::primary(trans('texts.add_token'))->asLinkTo('/tokens/create')->appendIcon(Icon::create('plus-sign')) !!}
|
||||||
@endif
|
@endif
|
||||||
|
@ -215,7 +215,7 @@
|
|||||||
$(function() {
|
$(function() {
|
||||||
window.setTimeout(function() {
|
window.setTimeout(function() {
|
||||||
$(".alert-hide").fadeOut(500);
|
$(".alert-hide").fadeOut(500);
|
||||||
}, 3000);
|
}, 2000);
|
||||||
|
|
||||||
$('#search').focus(function(){
|
$('#search').focus(function(){
|
||||||
if (!window.hasOwnProperty('searchData')) {
|
if (!window.hasOwnProperty('searchData')) {
|
||||||
|
@ -473,7 +473,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer" style="margin-top: 0px; padding-top:0px;">
|
<div class="modal-footer" style="margin-top: 0px; padding-top:0px;">
|
||||||
<span class="error-block" id="emailError" style="display:none;float:left;font-weight:bold">{{ trans('texts.provide_email') }}</span><span> </span>
|
<span class="error-block" id="emailError" style="display:none;float:left;font-weight:bold">{{ trans('texts.provide_name_or_email') }}</span><span> </span>
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button>
|
||||||
<button type="button" class="btn btn-default" data-bind="click: $root.showMoreFields, text: $root.showMore() ? '{{ trans('texts.less_fields') }}' : '{{ trans('texts.more_fields') }}'"></button>
|
<button type="button" class="btn btn-default" data-bind="click: $root.showMoreFields, text: $root.showMore() ? '{{ trans('texts.less_fields') }}' : '{{ trans('texts.more_fields') }}'"></button>
|
||||||
<button id="clientDoneButton" type="button" class="btn btn-primary" data-bind="click: $root.clientFormComplete">{{ trans('texts.done') }}</button>
|
<button id="clientDoneButton" type="button" class="btn btn-primary" data-bind="click: $root.clientFormComplete">{{ trans('texts.done') }}</button>
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!! DropdownButton::normal(trans('texts.archive'))->withContents([
|
{!! DropdownButton::normal(trans('texts.archive'))->withContents([
|
||||||
['label' => trans('texts.archive_'.$entityType), 'url' => "javascript:submitForm('archive')"],
|
['label' => trans('texts.archive_'.$entityType), 'url' => 'javascript:submitForm("archive")'],
|
||||||
['label' => trans('texts.delete_'.$entityType), 'url' => "javascript:submitForm('delete')"],
|
['label' => trans('texts.delete_'.$entityType), 'url' => 'javascript:submitForm("delete")'],
|
||||||
])->withAttributes(['class'=>'archive'])->split() !!}
|
])->withAttributes(['class'=>'archive'])->split() !!}
|
||||||
|
|
||||||
<label for="trashed" style="font-weight:normal; margin-left: 10px;">
|
<label for="trashed" style="font-weight:normal; margin-left: 10px;">
|
||||||
|
206
resources/views/reports/chart_builder.blade.php
Normal file
206
resources/views/reports/chart_builder.blade.php
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
@extends('accounts.nav')
|
||||||
|
|
||||||
|
@section('head')
|
||||||
|
@parent
|
||||||
|
|
||||||
|
<script src="{!! asset('js/Chart.js') !!}" type="text/javascript"></script>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
@parent
|
||||||
|
@include('accounts.nav_advanced')
|
||||||
|
|
||||||
|
|
||||||
|
{!! Button::primary(trans('texts.data_visualizations'))
|
||||||
|
->asLinkTo('/company/advanced_settings/data_visualizations')
|
||||||
|
->withAttributes(['class' => 'pull-right'])
|
||||||
|
->appendIcon(Icon::create('globe')) !!}
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{!! trans('texts.settings') !!}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
|
||||||
|
{!! Former::open()->addClass('warn-on-exit') !!}
|
||||||
|
|
||||||
|
<div style="display:none">
|
||||||
|
{!! Former::text('action') !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!! Former::populateField('start_date', $startDate) !!}
|
||||||
|
{!! Former::populateField('end_date', $endDate) !!}
|
||||||
|
{!! Former::populateField('enable_report', intval($enableReport)) !!}
|
||||||
|
{!! Former::populateField('enable_chart', intval($enableChart)) !!}
|
||||||
|
|
||||||
|
{!! Former::text('start_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))
|
||||||
|
->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'start_date\')"></i>') !!}
|
||||||
|
{!! Former::text('end_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))
|
||||||
|
->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'end_date\')"></i>') !!}
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
{!! Former::checkbox('enable_report')->text(trans('texts.enable')) !!}
|
||||||
|
{!! Former::select('report_type')->options($reportTypes, $reportType)->label(trans('texts.group_by')) !!}
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
{!! Former::checkbox('enable_chart')->text(trans('texts.enable')) !!}
|
||||||
|
{!! Former::select('chart_type')->options($chartTypes, $chartType) !!}
|
||||||
|
{!! Former::select('group_by')->options($dateTypes, $groupBy) !!}
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
@if (Auth::user()->isPro())
|
||||||
|
{!! Former::actions(
|
||||||
|
Button::primary(trans('texts.export'))->withAttributes(array('onclick' => 'onExportClick()'))->appendIcon(Icon::create('export')),
|
||||||
|
Button::success(trans('texts.run'))->withAttributes(array('id' => 'submitButton'))->submit()->appendIcon(Icon::create('play'))
|
||||||
|
) !!}
|
||||||
|
@else
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('form.warn-on-exit').find('input, select').prop('disabled', true);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
{!! Former::close() !!}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-8">
|
||||||
|
|
||||||
|
@if ($enableReport)
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-striped invoice-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
@foreach ($columns as $column)
|
||||||
|
<th>
|
||||||
|
{{ trans("texts.{$column}") }}
|
||||||
|
</th>
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($displayData as $record)
|
||||||
|
<tr>
|
||||||
|
@foreach ($record as $field)
|
||||||
|
<td>
|
||||||
|
{!! $field !!}
|
||||||
|
</td>
|
||||||
|
@endforeach
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td><b>{{ trans('texts.totals') }}</b></td>
|
||||||
|
@if (!$reportType)
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
@endif
|
||||||
|
<td>
|
||||||
|
@foreach ($reportTotals['amount'] as $currencyId => $total)
|
||||||
|
<b>{{ Utils::formatMoney($total, $currencyId) }}</b><br/>
|
||||||
|
@endforeach
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@foreach ($reportTotals['paid'] as $currencyId => $total)
|
||||||
|
<b>{{ Utils::formatMoney($total, $currencyId) }}</b><br/>
|
||||||
|
@endforeach
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
@foreach ($reportTotals['balance'] as $currencyId => $total)
|
||||||
|
<b>{{ Utils::formatMoney($total, $currencyId) }}</b><br/>
|
||||||
|
@endforeach
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if ($enableChart)
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<canvas id="monthly-reports" width="700" height="400"></canvas>
|
||||||
|
<p> </p>
|
||||||
|
<div style="padding-bottom:8px">
|
||||||
|
<div style="float:left; height:22px; width:60px; background-color:rgba(78,205,196,.5); border: 1px solid rgba(78,205,196,1)"></div>
|
||||||
|
<div style="vertical-align: middle"> Invoices</div>
|
||||||
|
</div>
|
||||||
|
<div style="padding-bottom:8px; clear:both">
|
||||||
|
<div style="float:left; height:22px; width:60px; background-color:rgba(255,107,107,.5); border: 1px solid rgba(255,107,107,1)"></div>
|
||||||
|
<div style="vertical-align: middle"> Payments</div>
|
||||||
|
</div>
|
||||||
|
<div style="clear:both">
|
||||||
|
<div style="float:left; height:22px; width:60px; background-color:rgba(199,244,100,.5); border: 1px solid rgba(199,244,100,1)"></div>
|
||||||
|
<div style="vertical-align: middle"> Credits</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function onExportClick() {
|
||||||
|
$('#action').val('export');
|
||||||
|
$('#submitButton').click();
|
||||||
|
$('#action').val('');
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx = document.getElementById('monthly-reports').getContext('2d');
|
||||||
|
var chart = {
|
||||||
|
labels: {!! json_encode($labels) !!},
|
||||||
|
datasets: [
|
||||||
|
@foreach ($datasets as $dataset)
|
||||||
|
{
|
||||||
|
data: {!! json_encode($dataset['totals']) !!},
|
||||||
|
fillColor : "rgba({!! $dataset['colors'] !!},0.5)",
|
||||||
|
strokeColor : "rgba({!! $dataset['colors'] !!},1)",
|
||||||
|
},
|
||||||
|
@endforeach
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
scaleOverride: true,
|
||||||
|
scaleSteps: 10,
|
||||||
|
scaleStepWidth: {!! $scaleStepWidth !!},
|
||||||
|
scaleStartValue: 0,
|
||||||
|
scaleLabel : "<%=value%>",
|
||||||
|
};
|
||||||
|
|
||||||
|
new Chart(ctx).{!! $chartType !!}(chart, options);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('onReady')
|
||||||
|
|
||||||
|
$('#start_date, #end_date').datepicker({
|
||||||
|
autoclose: true,
|
||||||
|
todayHighlight: true,
|
||||||
|
keyboardNavigation: false
|
||||||
|
});
|
||||||
|
|
||||||
|
@stop
|
@ -32,10 +32,6 @@
|
|||||||
@parent
|
@parent
|
||||||
@include('accounts.nav_advanced')
|
@include('accounts.nav_advanced')
|
||||||
|
|
||||||
{!! Former::open() !!}
|
|
||||||
{!! Former::legend('data_visualizations') !!}
|
|
||||||
{!! Former::close() !!}
|
|
||||||
|
|
||||||
<div id="tooltip" class="hidden">
|
<div id="tooltip" class="hidden">
|
||||||
<p>
|
<p>
|
||||||
<strong><span id="tooltipTitle"></span></strong>
|
<strong><span id="tooltipTitle"></span></strong>
|
||||||
@ -48,7 +44,7 @@
|
|||||||
|
|
||||||
<form class="form-inline" role="form">
|
<form class="form-inline" role="form">
|
||||||
Group By
|
Group By
|
||||||
<select id="groupBySelect" class="form-control" onchange="update()">
|
<select id="groupBySelect" class="form-control" onchange="update()" style="background-color:white !important">
|
||||||
<option>Clients</option>
|
<option>Clients</option>
|
||||||
<option>Invoices</option>
|
<option>Invoices</option>
|
||||||
<option>Products</option>
|
<option>Products</option>
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
@extends('accounts.nav')
|
|
||||||
|
|
||||||
@section('head')
|
|
||||||
@parent
|
|
||||||
|
|
||||||
<script src="{!! asset('js/Chart.js') !!}" type="text/javascript"></script>
|
|
||||||
@stop
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
@parent
|
|
||||||
@include('accounts.nav_advanced')
|
|
||||||
|
|
||||||
|
|
||||||
{!! Button::primary(trans('texts.data_visualizations'))
|
|
||||||
->asLinkTo('/company/advanced_settings/data_visualizations')
|
|
||||||
->withAttributes(['class' => 'pull-right'])
|
|
||||||
->appendIcon(Icon::create('globe')) !!}
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
<p> </p>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-body">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-4">
|
|
||||||
|
|
||||||
{!! Former::open()->addClass('warn-on-exit') !!}
|
|
||||||
|
|
||||||
{!! Former::populateField('start_date', $startDate) !!}
|
|
||||||
{!! Former::populateField('end_date', $endDate) !!}
|
|
||||||
{!! Former::select('chart_type')->options($chartTypes, $chartType) !!}
|
|
||||||
{!! Former::select('group_by')->options($dateTypes, $groupBy) !!}
|
|
||||||
{!! Former::text('start_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))
|
|
||||||
->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'start_date\')"></i>') !!}
|
|
||||||
{!! Former::text('end_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))
|
|
||||||
->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'end_date\')"></i>') !!}
|
|
||||||
|
|
||||||
@if (Auth::user()->isPro())
|
|
||||||
{!! Former::actions( Button::primary('Generate')->submit() ) !!}
|
|
||||||
@else
|
|
||||||
<script>
|
|
||||||
$(function() {
|
|
||||||
$('form.warn-on-exit').find('input, select').prop('disabled', true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
{!! Former::close() !!}
|
|
||||||
|
|
||||||
<p> </p>
|
|
||||||
<div style="padding-bottom:8px">
|
|
||||||
<div style="float:left; height:22px; width:60px; background-color:rgba(78,205,196,.5); border: 1px solid rgba(78,205,196,1)"></div>
|
|
||||||
<div style="vertical-align: middle"> Invoices</div>
|
|
||||||
</div>
|
|
||||||
<div style="padding-bottom:8px; clear:both">
|
|
||||||
<div style="float:left; height:22px; width:60px; background-color:rgba(255,107,107,.5); border: 1px solid rgba(255,107,107,1)"></div>
|
|
||||||
<div style="vertical-align: middle"> Payments</div>
|
|
||||||
</div>
|
|
||||||
<div style="clear:both">
|
|
||||||
<div style="float:left; height:22px; width:60px; background-color:rgba(199,244,100,.5); border: 1px solid rgba(199,244,100,1)"></div>
|
|
||||||
<div style="vertical-align: middle"> Credits</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-8">
|
|
||||||
<canvas id="monthly-reports" width="772" height="400"></canvas>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
var ctx = document.getElementById('monthly-reports').getContext('2d');
|
|
||||||
var chart = {
|
|
||||||
labels: {!! json_encode($labels) !!},
|
|
||||||
datasets: [
|
|
||||||
@foreach ($datasets as $dataset)
|
|
||||||
{
|
|
||||||
data: {!! json_encode($dataset['totals']) !!},
|
|
||||||
fillColor : "rgba({!! $dataset['colors'] !!},0.5)",
|
|
||||||
strokeColor : "rgba({!! $dataset['colors'] !!},1)",
|
|
||||||
},
|
|
||||||
@endforeach
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
scaleOverride: true,
|
|
||||||
scaleSteps: 10,
|
|
||||||
scaleStepWidth: {!! $scaleStepWidth !!},
|
|
||||||
scaleStartValue: 0,
|
|
||||||
scaleLabel : "<%=formatMoney(value)%>",
|
|
||||||
};
|
|
||||||
|
|
||||||
new Chart(ctx).{!! $chartType !!}(chart, options);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@stop
|
|
||||||
|
|
||||||
|
|
||||||
@section('onReady')
|
|
||||||
|
|
||||||
$('#start_date, #end_date').datepicker({
|
|
||||||
autoclose: true,
|
|
||||||
todayHighlight: true,
|
|
||||||
keyboardNavigation: false
|
|
||||||
});
|
|
||||||
|
|
||||||
@stop
|
|
Loading…
Reference in New Issue
Block a user