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

Delete everything in prep for laravel 5.

This commit is contained in:
root 2015-03-12 10:43:47 +10:00
parent 2cdf6d517a
commit 872e9db581
1208 changed files with 0 additions and 328852 deletions

View File

@ -1,3 +0,0 @@
{
"directory": "./public/vendor"
}

1
.gitattributes vendored
View File

@ -1 +0,0 @@
* text=auto

24
.gitignore vendored
View File

@ -1,24 +0,0 @@
/app/config/staging
/app/config/development
/app/config/production
/app/config/fortrabbit
/app/config/ubuntu
/app/config/packages/anahkiasen/rocketeer/
/app/storage
/public/logo
/public/build
/public/packages
/public/vendor
/bootstrap/compiled.php
/bootstrap/environment.php
/vendor
/.DS_Store
/Thumbs.db
/ninja.sublime-project
/ninja.sublime-workspace
/tests/_log
.env.development.php
.env.php
.idea
.project
/nbproject/private/

View File

@ -1,124 +0,0 @@
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
process: function(src, filepath) {
var basepath = filepath.substring(7, filepath.lastIndexOf('/') + 1);
// Fix relative paths for css files
if(filepath.indexOf('.css', filepath.length - 4) !== -1) {
return src.replace(/(url\s*[\("']+)\s*([^'"\)]+)(['"\)]+;?)/gi, function(match, start, url, end, offset, string) {
if(url.indexOf('data:') === 0) {
// Skip data urls
return match;
} else if(url.indexOf('/') === 0) {
// Skip absolute urls
return match;
} else {
return start + basepath + url + end;
}
});
// Fix source maps locations
} else if(filepath.indexOf('.js', filepath.length - 4) !== -1) {
return src.replace(/(\/[*\/][#@]\s*sourceMappingURL=)([^\s]+)/gi, function(match, start, url, offset, string) {
if(url.indexOf('/') === 0) {
// Skip absolute urls
return match;
} else {
return start + basepath + url;
}
});
// Don't do anything for unknown file types
} else {
return src;
}
},
},
js: {
src: [
'public/vendor/jquery/dist/jquery.js',
'public/vendor/jquery-ui/jquery-ui.min.js',
'public/vendor/bootstrap/dist/js/bootstrap.min.js',
'public/vendor/datatables/media/js/jquery.dataTables.js',
'public/vendor/datatables-bootstrap3/BS3/assets/js/datatables.js',
'public/vendor/knockout.js/knockout.js',
'public/vendor/knockout-mapping/build/output/knockout.mapping-latest.js',
'public/vendor/knockout-sortable/build/knockout-sortable.min.js',
'public/vendor/underscore/underscore.js',
'public/vendor/bootstrap-datepicker/js/bootstrap-datepicker.js',
'public/vendor/typeahead.js/dist/typeahead.min.js',
'public/vendor/accounting/accounting.min.js',
'public/vendor/spectrum/spectrum.js',
'public/vendor/jspdf/dist/jspdf.min.js',
//'public/vendor/handsontable/dist/jquery.handsontable.full.min.js',
'public/js/lightbox.min.js',
'public/js/bootstrap-combobox.js',
'public/js/script.js',
],
dest: 'public/built.js',
nonull: true
},
js_public: {
src: [
/*
'public/js/simpleexpand.js',
'public/js/valign.js',
'public/js/bootstrap.min.js',
'public/js/simpleexpand.js',
*/
'public/vendor/bootstrap/dist/js/bootstrap.min.js',
],
dest: 'public/js/built.public.js',
nonull: true
},
css: {
src: [
'public/vendor/bootstrap/dist/css/bootstrap.min.css',
'public/vendor/datatables/media/css/jquery.dataTables.css',
'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css',
'public/vendor/font-awesome/css/font-awesome.min.css',
'public/vendor/bootstrap-datepicker/css/datepicker.css',
'public/vendor/spectrum/spectrum.css',
'public/css/bootstrap-combobox.css',
'public/css/typeahead.js-bootstrap.css',
'public/css/lightbox.css',
//'public/vendor/handsontable/dist/jquery.handsontable.full.css',
'public/css/style.css',
],
dest: 'public/built.css',
nonull: true,
options: {
process: false
}
},
css_public: {
src: [
'public/vendor/bootstrap/dist/css/bootstrap.min.css',
/*
'public/css/bootstrap.splash.css',
'public/css/splash.css',
*/
'public/vendor/datatables/media/css/jquery.dataTables.css',
'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css',
],
dest: 'public/built.public.css',
nonull: true,
options: {
process: false
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['concat']);
};

40
LICENSE
View File

@ -1,40 +0,0 @@
Attribution Assurance License
Copyright (c) 2014 by Hillel Coren
http://www.hillelcoren.com
All Rights Reserved
ATTRIBUTION ASSURANCE LICENSE (adapted from the original BSD license)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the conditions below are met.
These conditions require a modest attribution to InvoiceNinja.com. The hope
is that its promotional value may help justify the thousands of dollars in
otherwise billable time invested in writing this and other freely available,
open-source software.
1. Redistributions of source code, in whole or part and with or without
modification requires the express permission of the author and must prominently
display "Powered by InvoiceNinja" or the Invoice Ninja logo in verifiable form
with hyperlink to said site.
2. Neither the name nor any trademark of the Author may be used to
endorse or promote products derived from this software without specific
prior written permission.
3. Users are entirely responsible, to the exclusion of the Author and
any other persons, for compliance with (1) regulations set by owners or
administrators of employed equipment, (2) licensing terms of any other
software, and (3) local regulations regarding use, including those
regarding import, export, and use of encryption software.
THIS FREE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR OR ANY CONTRIBUTOR BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
EFFECTS OF UNAUTHORIZED OR MALICIOUS NETWORK ACCESS;
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

118
README.md
View File

@ -1,118 +0,0 @@
# Invoice Ninja
## Simple, Intuitive Invoicing
### [https://www.invoiceninja.com](https://www.invoiceninja.com)
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
Most online invoicing sites are expensive. They shouldn't be. The aim of this project is to provide a free, open-source alternative. Additionally, the hope is the codebase will serve as a sample site for Laravel as well as other JavaScript technologies.
To setup the site you can either use this [zip file](http://hillelcoren.com/invoice-ninja/self-hosting/) (easier to setup) or checkout the code from GitHub following the instructions below (easier to stay up to date). There's also a more detailed setup guide [available here](http://hillelcoren.com/invoice-ninja/laravel-ubuntu-virtualbox/).
For a WAMP/MAMP/LAMP setup you can one-click install using Softaculous's [AMPPS](http://www.ampps.com/). To deploy the app with [Docker](http://www.docker.com/) you can use [this project](https://github.com/rollbrettler/Dockerfiles/tree/master/invoice-ninja).
To connect 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
* Core application built using Laravel 4.1
* Invoice PDF generation directly in the browser
* Integrates with many payment providers
* Recurring invoices
* Tax rates and payment terms
* Multi-user support
* [Zapier](https://zapier.com/) integration
* [D3.js](http://d3js.org/) visualizations
### Contributors
* [Troels Liebe Bentsen](https://github.com/tlbdk)
### Steps to setup
If you plan on submitting changes it's best to [fork the repo](https://help.github.com/articles/fork-a-repo), otherwise you can just checkout the code.
git clone https://github.com/hillelcoren/invoice-ninja.git ninja
cd ninja
Install Laravel packages using Composer
Note: you may be prompted for your Github user/pass due to their API limits.
composer install
Install JavaScript and HTML packages using Bower. This is optional, it's only needed if you want to modify the JavaScript.
bower install
Create database user and a database for ninja
CREATE SCHEMA `ninja` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'ninja'@'localhost' IDENTIFIED BY 'ninja';
GRANT ALL PRIVILEGES ON `ninja`.* TO 'ninja'@'localhost';
FLUSH PRIVILEGES;
Add public/ to your web server root then load / to configure the application.
### Developer Notes
* The application requires PHP >= 5.4.0
* If you make any changes to the JavaScript files you need to run grunt to create the built files. See Gruntfile.js for more details.
* The lookup tables are cached in memory (ie, Currencies, Timezones, Languages, etc). If you add a record to the database you need to clear the cache by uncommenting Cache::flush() in app/routes.php.
* If you run into any composer errors try running composer dump-autoload.
### Ubuntu Notes
# Install php-mcrypt
apt-get install php5-mcrypt
sudo php5enmod mcrypt
# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
# Install Bower
sudo apt-get install npm nodejs-legacy
sudo npm install -g bower
sudo ln -s /usr/local/lib/node_modules/bower/bin/bower /usr/local/bin/bower
# Install Grunt (For development only)
npm install -g grunt-cli
### Frameworks/Libraries
* [laravel/laravel](https://github.com/laravel/laravel) - A PHP Framework For Web Artisans
* [twbs/bootstrap](https://github.com/twbs/bootstrap) - Sleek, intuitive, and powerful front-end framework for faster and easier web development.
* [patricktalmadge/bootstrapper](https://github.com/patricktalmadge/bootstrapper) - Laravel Twitter Bootstrap Bundle
* [danielfarrell/bootstrap-combobox](https://github.com/danielfarrell/bootstrap-combobox) - A combobox plugin
* [jquery/jquery](https://github.com/jquery/jquery) - jQuery JavaScript Library
* [eternicode/bootstrap-datepicker](https://github.com/eternicode/bootstrap-datepicker) - A datepicker for @twitter bootstrap
* [jquery/jquery-ui](https://github.com/jquery/jquery-ui) - The official jQuery user interface library
* [knockout/knockout](https://github.com/knockout/knockout) - Knockout makes it easier to create rich, responsive UIs with JavaScript
* [rniemeyer/knockout-sortable](https://github.com/rniemeyer/knockout-sortable) - A Knockout.js binding to connect observableArrays with jQuery UI sortable functionality
* [MrRio/jsPDF](https://github.com/MrRio/jsPDF) - Generate PDF files in JavaScript. HTML5 FTW.
* [FortAwesome/Font-Awesome](https://github.com/FortAwesome/Font-Awesome) - The iconic font designed for Bootstrap that works with twitter bootstrap
* [jasonlewis/basset](https://github.com/jasonlewis/basset) - A better asset management package for Laravel
* [Zizaco/confide](https://github.com/Zizaco/confide) - Confide is a authentication solution for Laravel 4
* [Anahkiasen/former](https://github.com/Anahkiasen/former) - A powerful form builder, for Laravel and other frameworks (stand-alone too)
* [barryvdh/laravel-debugbar](https://github.com/barryvdh/laravel-debugbar) - Laravel debugbar
* [DataTables/DataTables](https://github.com/DataTables/DataTables) - Tables plug-in for jQuery
* [Chumper/Datatable](https://github.com/Chumper/Datatable) - This is a laravel 4 package for the server and client side of datatables
* [omnipay/omnipay](https://github.com/omnipay/omnipay) - A framework agnostic, multi-gateway payment processing library for PHP 5.3+
* [Intervention/image](https://github.com/Intervention/image) - PHP Image Manipulation
* [webpatser/laravel-countries](https://github.com/webpatser/laravel-countries) - Almost ISO 3166_2, 3166_3, currency, Capital and more for all countries
* [briannesbitt/Carbon](https://github.com/briannesbitt/Carbon) - A simple API extension for DateTime with PHP 5.3+
* [thomaspark/bootswatch](https://github.com/thomaspark/bootswatch) - Themes for Bootstrap
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the canvas tag
* [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting
* [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt
* [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) - List of languages for Laravel4
* [calvinfroedge/PHP-Payments](https://github.com/calvinfroedge/PHP-Payments) - A uniform payments interface for PHP
* [bgrins/spectrum](https://github.com/bgrins/spectrum) - The No Hassle JavaScript Colorpicker
* [lokesh/lightbox2](https://github.com/lokesh/lightbox2/) - The original lightbox script

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

View File

@ -1,266 +0,0 @@
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
/*
##################################################################
WARNING: Please backup your database before running this script
##################################################################
Since the application was released a number of bugs have (inevitably) been found.
Although the bugs have always been fixed in some cases they've caused the client's
balance, paid to date and/or activity records to become inaccurate. This script will
check for errors and correct the data.
If you have any questions please email us at contact@invoiceninja.com
Usage:
php artisan ninja:check-data
Options:
--client_id:<value>
Limits the script to a single client
--fix=true
By default the script only checks for errors, adding this option
makes the script apply the fixes.
*/
class CheckData extends Command {
protected $name = 'ninja:check-data';
protected $description = 'Check/fix data';
public function fire()
{
$this->info(date('Y-m-d') . ' Running CheckData...');
$today = new DateTime();
if (!$this->option('client_id')) {
// update client deletion activities with the client's current balance
$activities = DB::table('activities')
->join('clients', 'clients.id', '=', 'activities.client_id')
->where('activities.activity_type_id', '=', ACTIVITY_TYPE_DELETE_CLIENT)
->where('activities.balance', '=', 0)
->where('clients.balance', '!=', 0)
->get(['activities.id', 'clients.balance']);
$this->info(count($activities) . ' delete client activities with zero balance');
if ($this->option('fix') == 'true') {
foreach ($activities as $activity) {
DB::table('activities')
->where('id', $activity->id)
->update(['balance' => $activity->balance]);
}
}
// update client paid_to_date value
$clients = DB::table('clients')
->join('payments', 'payments.client_id', '=', 'clients.id')
->join('invoices', 'invoices.id', '=', 'payments.invoice_id')
->where('payments.is_deleted', '=', 0)
->where('invoices.is_deleted', '=', 0)
->groupBy('clients.id')
->havingRaw('clients.paid_to_date != sum(payments.amount) and clients.paid_to_date != 999999999.9999')
->get(['clients.id', 'clients.paid_to_date', DB::raw('sum(payments.amount) as amount')]);
$this->info(count($clients) . ' clients with incorrect paid to date');
if ($this->option('fix') == 'true') {
foreach ($clients as $client) {
DB::table('clients')
->where('id', $client->id)
->update(['paid_to_date' => $client->amount]);
}
}
}
// find all clients where the balance doesn't equal the sum of the outstanding invoices
$clients = DB::table('clients')
->join('invoices', 'invoices.client_id', '=', 'clients.id')
->join('accounts', 'accounts.id', '=', 'clients.account_id');
if ($this->option('client_id')) {
$clients->where('clients.id', '=', $this->option('client_id'));
} else {
$clients->where('invoices.is_deleted', '=', 0)
->where('invoices.is_quote', '=', 0)
->where('invoices.is_recurring', '=', 0)
->havingRaw('abs(clients.balance - sum(invoices.balance)) > .01 and clients.balance != 999999999.9999');
}
$clients = $clients->groupBy('clients.id', 'clients.balance', 'clients.created_at')
->orderBy('clients.id', 'DESC')
->get(['clients.id', 'clients.balance', 'clients.paid_to_date']);
$this->info(count($clients) . ' clients with incorrect balance/activities');
foreach ($clients as $client) {
$this->info("=== Client:{$client->id} Balance:{$client->balance} ===");
$foundProblem = false;
$lastBalance = 0;
$clientFix = false;
$activities = DB::table('activities')
->where('client_id', '=', $client->id)
->orderBy('activities.id')
->get(['activities.id', 'activities.created_at', 'activities.activity_type_id', 'activities.message', 'activities.adjustment', 'activities.balance', 'activities.invoice_id']);
//$this->info(var_dump($activities));
foreach ($activities as $activity) {
$activityFix = false;
if ($activity->invoice_id) {
$invoice = DB::table('invoices')
->where('id', '=', $activity->invoice_id)
->first(['invoices.amount', 'invoices.is_recurring', 'invoices.is_quote', 'invoices.deleted_at', 'invoices.id', 'invoices.is_deleted']);
// Check if this invoice was once set as recurring invoice
if (!$invoice->is_recurring && DB::table('invoices')
->where('recurring_invoice_id', '=', $activity->invoice_id)
->first(['invoices.id'])) {
$invoice->is_recurring = 1;
// **Fix for enabling a recurring invoice to be set as non-recurring**
if ($this->option('fix') == 'true') {
DB::table('invoices')
->where('id', $invoice->id)
->update(['is_recurring' => 1]);
}
}
}
if ($activity->activity_type_id == ACTIVITY_TYPE_CREATE_INVOICE
|| $activity->activity_type_id == ACTIVITY_TYPE_CREATE_QUOTE) {
// Get original invoice amount
$update = DB::table('activities')
->where('invoice_id', '=', $activity->invoice_id)
->where('activity_type_id', '=', ACTIVITY_TYPE_UPDATE_INVOICE)
->orderBy('id')
->first(['json_backup']);
if ($update) {
$backup = json_decode($update->json_backup);
$invoice->amount = floatval($backup->amount);
}
$noAdjustment = $activity->activity_type_id == ACTIVITY_TYPE_CREATE_INVOICE
&& $activity->adjustment == 0
&& $invoice->amount > 0;
// **Fix for allowing converting a recurring invoice to a normal one without updating the balance**
if ($noAdjustment && !$invoice->is_quote && !$invoice->is_recurring) {
$this->info("No adjustment for new invoice:{$activity->invoice_id} amount:{$invoice->amount} isQuote:{$invoice->is_quote} isRecurring:{$invoice->is_recurring}");
$foundProblem = true;
$clientFix += $invoice->amount;
$activityFix = $invoice->amount;
// **Fix for updating balance when creating a quote or recurring invoice**
} elseif ($activity->adjustment != 0 && ($invoice->is_quote || $invoice->is_recurring)) {
$this->info("Incorrect adjustment for new invoice:{$activity->invoice_id} adjustment:{$activity->adjustment} isQuote:{$invoice->is_quote} isRecurring:{$invoice->is_recurring}");
$foundProblem = true;
$clientFix -= $activity->adjustment;
$activityFix = 0;
}
} elseif ($activity->activity_type_id == ACTIVITY_TYPE_DELETE_INVOICE) {
// **Fix for updating balance when deleting a recurring invoice**
if ($activity->adjustment != 0 && $invoice->is_recurring) {
$this->info("Incorrect adjustment for deleted invoice adjustment:{$activity->adjustment}");
$foundProblem = true;
if ($activity->balance != $lastBalance) {
$clientFix -= $activity->adjustment;
}
$activityFix = 0;
}
} elseif ($activity->activity_type_id == ACTIVITY_TYPE_ARCHIVE_INVOICE) {
// **Fix for updating balance when archiving an invoice**
if ($activity->adjustment != 0 && !$invoice->is_recurring) {
$this->info("Incorrect adjustment for archiving invoice adjustment:{$activity->adjustment}");
$foundProblem = true;
$activityFix = 0;
$clientFix += $activity->adjustment;
}
} elseif ($activity->activity_type_id == ACTIVITY_TYPE_UPDATE_INVOICE) {
// **Fix for updating balance when updating recurring invoice**
if ($activity->adjustment != 0 && $invoice->is_recurring) {
$this->info("Incorrect adjustment for updated recurring invoice adjustment:{$activity->adjustment}");
$foundProblem = true;
$clientFix -= $activity->adjustment;
$activityFix = 0;
}
} elseif ($activity->activity_type_id == ACTIVITY_TYPE_UPDATE_QUOTE) {
// **Fix for updating balance when updating a quote**
if ($activity->balance != $lastBalance) {
$this->info("Incorrect adjustment for updated quote adjustment:{$activity->adjustment}");
$foundProblem = true;
$clientFix += $lastBalance - $activity->balance;
$activityFix = 0;
}
} else if ($activity->activity_type_id == ACTIVITY_TYPE_DELETE_PAYMENT) {
// **Fix for delting payment after deleting invoice**
if ($activity->adjustment != 0 && $invoice->is_deleted && $activity->created_at > $invoice->deleted_at) {
$this->info("Incorrect adjustment for deleted payment adjustment:{$activity->adjustment}");
$foundProblem = true;
$activityFix = 0;
$clientFix -= $activity->adjustment;
}
}
if ($activityFix !== false || $clientFix !== false) {
$data = [
'balance' => $activity->balance + $clientFix
];
if ($activityFix !== false) {
$data['adjustment'] = $activityFix;
}
if ($this->option('fix') == 'true') {
DB::table('activities')
->where('id', $activity->id)
->update($data);
}
}
$lastBalance = $activity->balance;
}
if ($clientFix !== false) {
$balance = $activity->balance + $clientFix;
$data = ['balance' => $balance];
$this->info("Corrected balance:{$balance}");
if ($this->option('fix') == 'true') {
DB::table('clients')
->where('id', $client->id)
->update($data);
}
}
}
$this->info('Done');
}
protected function getArguments()
{
return array(
//array('example', InputArgument::REQUIRED, 'An example argument.'),
);
}
protected function getOptions()
{
return array(
array('fix', null, InputOption::VALUE_OPTIONAL, 'Fix data', null),
array('client_id', null, InputOption::VALUE_OPTIONAL, 'Client id', null),
);
}
}

View File

@ -1,88 +0,0 @@
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class CreateRandomData extends Command {
protected $name = 'ninja:create-data';
protected $description = 'Create random data';
public function fire()
{
$this->info(date('Y-m-d') . ' Running CreateRandomData...');
$user = User::first();
if (!$user) {
$this->error("Error: please create user account by logging in");
return;
}
$productNames = ['Arkansas', 'New York', 'Arizona', 'California', 'Colorado', 'Alabama', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'Alaska', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];
$clientNames = ['IBM', 'Nestle', 'Mitsubishi UFJ Financial', 'Vodafone', 'Eni', 'Procter & Gamble', 'Johnson & Johnson', 'American International Group', 'Banco Santander', 'BHP Billiton', 'Pfizer', 'Itaú Unibanco Holding', 'Ford Motor', 'BMW Group', 'Commonwealth Bank', 'EDF', 'Statoil', 'Google', 'Siemens', 'Novartis', 'Royal Bank of Canada', 'Sumitomo Mitsui Financial', 'Comcast', 'Sberbank', 'Goldman Sachs Group', 'Westpac Banking Group', 'Nippon Telegraph & Tel', 'Ping An Insurance Group', 'Banco Bradesco', 'Anheuser-Busch InBev', 'Bank of Communications', 'China Life Insurance', 'General Motors', 'Telefónica', 'MetLife', 'Honda Motor', 'Enel', 'BASF', 'Softbank', 'National Australia Bank', 'ANZ', 'ConocoPhillips', 'TD Bank Group', 'Intel', 'UBS', 'Hewlett-Packard', 'Coca-Cola', 'Cisco Systems', 'UnitedHealth Group', 'Boeing', 'Zurich Insurance Group', 'Hyundai Motor', 'Sanofi', 'Credit Agricole', 'United Technologies', 'Roche Holding', 'Munich Re', 'PepsiCo', 'Oracle', 'Bank of Nova Scotia'];
foreach ($productNames as $i => $value) {
$product = Product::createNew($user);
$product->id = $i+1;
$product->product_key = $value;
$product->save();
}
foreach ($clientNames as $i => $value) {
$client = Client::createNew($user);
$client->name = $value;
$client->save();
$contact = Contact::createNew($user);
$contact->email = "client@aol.com";
$contact->is_primary = 1;
$client->contacts()->save($contact);
$numInvoices = rand(1, 25);
if ($numInvoices == 4 || $numInvoices == 10 || $numInvoices == 25) {
// leave these
} else if ($numInvoices % 3 == 0) {
$numInvoices = 1;
} else if ($numInvoices > 10) {
$numInvoices = $numInvoices % 2;
}
$paidUp = rand(0, 1) == 1;
for ($j=1; $j<=$numInvoices; $j++) {
$price = rand(10, 1000);
if ($price < 900) {
$price = rand(10, 150);
}
$invoice = Invoice::createNew($user);
$invoice->invoice_number = $user->account->getNextInvoiceNumber();
$invoice->amount = $invoice->balance = $price;
$invoice->created_at = date('Y-m-d', strtotime(date("Y-m-d") . ' - ' . rand(1, 100) . ' days'));
$client->invoices()->save($invoice);
$productId = rand(0, 40);
if ($productId > 20) {
$productId = ($productId % 2) + rand(0, 2);
}
$invoiceItem = InvoiceItem::createNew($user);
$invoiceItem->product_id = $productId+1;
$invoiceItem->product_key = $productNames[$invoiceItem->product_id];
$invoiceItem->cost = $invoice->amount;
$invoiceItem->qty = 1;
$invoice->invoice_items()->save($invoiceItem);
if ($paidUp || rand(0,2) > 1) {
$payment = Payment::createNew($user);
$payment->invoice_id = $invoice->id;
$payment->amount = $invoice->amount;
$client->payments()->save($payment);
}
}
}
}
}

View File

@ -1,335 +0,0 @@
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use PHPBenchTime\Timer;
class ImportTimesheetData extends Command {
protected $name = 'ninja:import-timesheet-data';
protected $description = 'Import timesheet data';
public function fire() {
$this->info(date('Y-m-d') . ' Running ImportTimesheetData...');
// Seems we are using the console timezone
DB::statement("SET SESSION time_zone = '+00:00'");
// Get the Unix epoch
$unix_epoch = new DateTime('1970-01-01T00:00:01', new DateTimeZone("UTC"));
// Create some initial sources we can test with
$user = User::first();
if (!$user) {
$this->error("Error: please create user account by logging in");
return;
}
// TODO: Populate with own test data until test data has been created
// Truncate the tables
/*$this->info("Truncate tables");
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
DB::table('projects')->truncate();
DB::table('project_codes')->truncate();
DB::table('timesheet_event_sources')->truncate();
DB::table('timesheet_events')->truncate();
DB::statement('SET FOREIGN_KEY_CHECKS=1;'); */
if (!Project::find(1)) {
$this->info("Import old project codes");
$oldcodes = json_decode(file_get_contents("/home/tlb/git/itktime/codes.json"), true);
foreach ($oldcodes as $name => $options) {
$project = Project::createNew($user);
$project->name = $options['description'];
$project->save();
$code = ProjectCode::createNew($user);
$code->name = $name;
$project->codes()->save($code);
}
}
if (!TimesheetEventSource::find(1)) {
$this->info("Import old event sources");
$oldevent_sources = json_decode(file_get_contents("/home/tlb/git/itktime/employes.json"), true);
foreach ($oldevent_sources as $source) {
$event_source = TimesheetEventSource::createNew($user);
$event_source->name = $source['name'];
$event_source->url = $source['url'];
$event_source->owner = $source['owner'];
$event_source->type = 'ical';
//$event_source->from_date = new DateTime("2009-01-01");
$event_source->save();
}
}
// Add all URL's to Curl
$this->info("Download ICAL feeds");
$T = new Timer;
$T->start();
$T->lap("Get Event Sources");
$event_sources = TimesheetEventSource::all(); // TODO: Filter based on ical feeds
$T->lap("Get ICAL responses");
$urls = [];
$event_sources->map(function($item) use(&$urls) {
$urls[] = $item->url;
});
$icalresponses = TimesheetUtils::curlGetUrls($urls);
$T->lap("Fetch all codes so we can do a quick lookup");
$codes = array();
ProjectCode::all()->map(function($item) use(&$codes) {
$codes[$item->name] = $item;
});
$this->info("Start parsing ICAL files");
foreach ($event_sources as $i => $event_source) {
if (!is_array($icalresponses[$i])) {
$this->info("Find events in " . $event_source->name);
file_put_contents("/tmp/" . $event_source->name . ".ical", $icalresponses[$i]); // FIXME: Remove
$T->lap("Split on events for ".$event_source->name);
// Check if the file is complete
if(!preg_match("/^\s*BEGIN:VCALENDAR/", $icalresponses[$i]) || !preg_match("/END:VCALENDAR\s*$/", $icalresponses[$i])) {
$this->error("Missing start or end of ical file");
continue;
}
// Extract all events from ical file
if (preg_match_all('/BEGIN:VEVENT\r?\n(.+?)\r?\nEND:VEVENT/s', $icalresponses[$i], $icalmatches)) {
$this->info("Found ".(count($icalmatches[1])-1)." events");
$T->lap("Fetch all uids and last updated at so we can do a quick lookup to find out if the event needs to be updated in the database".$event_source->name);
$uids = [];
$org_deleted = []; // Create list of events we know are deleted on the source, but still have in the db
$event_source->events()->withTrashed()->get(['uid', 'org_updated_at', 'updated_data_at', 'org_deleted_at'])->map(function($item) use(&$uids, &$org_deleted) {
if($item->org_updated_at > $item->updated_data_at) {
$uids[$item->uid] = $item->org_updated_at;
} else {
$uids[$item->uid] = $item->updated_data_at;
}
if($item->org_deleted_at > '0000-00-00 00:00:00') {
$org_deleted[$item->uid] = $item->updated_data_at;
}
});
$deleted = $uids;
// Loop over all the found events
$T->lap("Parse events for ".$event_source->name);
foreach ($icalmatches[1] as $eventstr) {
//print "---\n";
//print $eventstr."\n";
//print "---\n";
//$this->info("Match event");
# Fix lines broken by 76 char limit
$eventstr = preg_replace('/\r?\n\s/s', '', $eventstr);
//$this->info("Parse data");
$data = TimesheetUtils::parseICALEvent($eventstr);
if ($data) {
// Extract code for summary so we only import events we use
list($codename, $tags, $title) = TimesheetUtils::parseEventSummary($data['summary']);
if ($codename != null) {
$event = TimesheetEvent::createNew($user);
// Copy data to new object
$event->uid = $data['uid'];
$event->summary = $title;
$event->org_data = $eventstr;
$event->org_code = $codename;
if(isset($data['description'])) {
$event->description = $data['description'];
}
$event->owner = $event_source->owner;
$event->timesheet_event_source_id = $event_source->id;
if (isset($codes[$codename])) {
$event->project_id = $codes[$codename]->project_id;
$event->project_code_id = $codes[$codename]->id;
}
if (isset($data['location'])) {
$event->location = $data['location'];
}
# Add RECURRENCE-ID to the UID to make sure the event is unique
if (isset($data['recurrence-id'])) {
$event->uid .= "::".$data['recurrence-id'];
}
//TODO: Add support for recurring event, make limit on number of events created : https://github.com/tplaner/When
// Bail on RRULE as we don't support that
if(isset($event['rrule'])) {
die("Recurring event not supported: {$event['summary']} - {$event['dtstart']}");
}
// Convert to DateTime objects
foreach (['dtstart', 'dtend', 'created', 'last-modified'] as $key) {
// Parse and create DataTime object from ICAL format
list($dt, $timezone) = TimesheetUtils::parseICALDate($data[$key]);
// Handle bad dates in created and last-modified
if ($dt == null || $dt < $unix_epoch) {
if ($key == 'created' || $key == 'last-modified') {
$dt = $unix_epoch; // Default to UNIX epoch
$event->import_warning = "Could not parse date for $key: '" . $data[$key] . "' so default to UNIX Epoc\n";
} else {
$event->import_error = "Could not parse date for $key: '" . $data[$key] . "' so default to UNIX Epoc\n";
// TODO: Bail on this event or write to error table
die("Could not parse date for $key: '" . $data[$key] . "'\n");
}
}
// Assign DateTime object to
switch ($key) {
case 'dtstart':
$event->start_date = $dt;
if($timezone) {
$event->org_start_date_timezone = $timezone;
}
break;
case 'dtend':
$event->end_date = $dt;
if($timezone) {
$event->org_end_date_timezone = $timezone;
}
break;
case 'created':
$event->org_created_at = $dt;
break;
case 'last-modified':
$event->org_updated_at = $dt;
break;
}
}
// Check that we are witin the range
if ($event_source->from_date != null) {
$from_date = new DateTime($event_source->from_date, new DateTimeZone('UTC'));
if ($from_date > $event->end_date) {
// Skip this event
echo "Skiped: $codename: $title\n";
continue;
}
}
// Calculate number of hours
$di = $event->end_date->diff($event->start_date);
$event->hours = $di->h + $di->i / 60;
// Check for events we already have
if (isset($uids[$event->uid])) {
// Remove from deleted list
unset($deleted[$event->uid]);
// See if the event has been updated compared to the one in the database
$db_event_org_updated_at = new DateTime($uids[$event->uid], new DateTimeZone('UTC'));
// Check if same or older version of new event then skip
if($event->org_updated_at <= $db_event_org_updated_at) {
// SKIP
// Updated version of the event
} else {
// Get the old event from the database
/* @var $db_event TimesheetEvent */
$db_event = $event_source->events()->where('uid', $event->uid)->firstOrFail();
$changes = $db_event->toChangesArray($event);
// Make sure it's more than the org_updated_at that has been changed
if (count($changes) > 1) {
// Check if we have manually changed the event in the database or used it in a timesheet
if ($db_event->manualedit || $db_event->timesheet) {
$this->info("Updated Data");
$db_event->updated_data = $event->org_data;
$db_event->updated_data_at = $event->org_updated_at;
// Update the db_event with the changes
} else {
$this->info("Updated Event");
foreach ($changes as $key => $value) {
if($value == null) {
unset($db_event->$key);
} else {
$db_event->$key = $value;
}
}
}
} else {
$this->info("Nothing Changed");
// Nothing has been changed so update the org_updated_at
$db_event->org_updated_at = $changes['org_updated_at'];
}
$db_event->save();
}
} else {
try {
$this->info("New event: " . $event->summary);
$event->save();
} catch (Exception $ex) {
echo "'" . $event->summary . "'\n";
var_dump($data);
echo $ex->getMessage();
echo $ex->getTraceAsString();
exit(0);
}
}
// Add new uid to know uids
$uids[$event->uid] = $event->org_updated_at;
}
}
}
// Delete events in database that no longer exists in the source
foreach($deleted as $uid => $lastupdated_date) {
// Skip we already marked this a deleted
if(isset($org_deleted[$uid])) {
unset($deleted[$uid]);
continue;
}
// Delete or update event in db
$db_event = $event_source->events()->where('uid', $uid)->firstOrFail();
if($db_event->timesheet_id === null && !$db_event->manualedit) {
// Hard delete if this event has not been assigned to a timesheet or have been manually edited
$db_event->forceDelete();
} else {
// Mark as deleted in source
$db_event->org_deleted_at = new DateTime('now', new DateTimeZone('UTC'));
$db_event->save();
}
}
$this->info("Deleted ".count($deleted). " events");
} else {
// TODO: Parse error
}
} else {
// TODO: Curl Error
}
}
foreach($T->end()['laps'] as $lap) {
echo number_format($lap['total'], 3)." : {$lap['name']}\n";
}
$this->info('Done');
}
protected function getArguments() {
return array(
);
}
protected function getOptions() {
return array(
);
}
}

View File

@ -1,24 +0,0 @@
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class ResetData extends Command {
protected $name = 'ninja:reset-data';
protected $description = 'Reset data';
public function fire()
{
$this->info(date('Y-m-d') . ' Running ResetData...');
if (!Utils::isNinjaDev()) {
return;
}
Artisan::call('migrate:reset');
Artisan::call('migrate');
Artisan::call('db:seed');
}
}

View File

@ -1,113 +0,0 @@
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use ninja\mailers\ContactMailer as Mailer;
class SendRecurringInvoices extends Command
{
protected $name = 'ninja:send-invoices';
protected $description = 'Send recurring invoices';
protected $mailer;
public function __construct(Mailer $mailer)
{
parent::__construct();
$this->mailer = $mailer;
}
public function fire()
{
$this->info(date('Y-m-d').' Running SendRecurringInvoices...');
$today = new DateTime();
$invoices = Invoice::with('account.timezone', 'invoice_items', 'client', 'user')
->whereRaw('is_deleted IS FALSE AND deleted_at IS NULL AND is_recurring IS TRUE AND start_date <= ? AND (end_date IS NULL OR end_date >= ?)', array($today, $today))->get();
$this->info(count($invoices).' recurring invoice(s) found');
foreach ($invoices as $recurInvoice) {
if ($recurInvoice->client->deleted_at) {
continue;
}
if (!$recurInvoice->user->confirmed) {
continue;
}
$this->info('Processing Invoice '.$recurInvoice->id.' - Should send '.($recurInvoice->shouldSendToday() ? 'YES' : 'NO'));
if (!$recurInvoice->shouldSendToday()) {
continue;
}
$invoice = Invoice::createNew($recurInvoice);
$invoice->client_id = $recurInvoice->client_id;
$invoice->recurring_invoice_id = $recurInvoice->id;
$invoice->invoice_number = 'R'.$recurInvoice->account->getNextInvoiceNumber();
$invoice->amount = $recurInvoice->amount;
$invoice->balance = $recurInvoice->amount;
$invoice->invoice_date = date_create()->format('Y-m-d');
$invoice->discount = $recurInvoice->discount;
$invoice->po_number = $recurInvoice->po_number;
$invoice->public_notes = $recurInvoice->public_notes;
$invoice->terms = $recurInvoice->terms;
$invoice->invoice_footer = $recurInvoice->invoice_footer;
$invoice->tax_name = $recurInvoice->tax_name;
$invoice->tax_rate = $recurInvoice->tax_rate;
$invoice->invoice_design_id = $recurInvoice->invoice_design_id;
$invoice->custom_value1 = $recurInvoice->custom_value1;
$invoice->custom_value2 = $recurInvoice->custom_value2;
$invoice->custom_taxes1 = $recurInvoice->custom_taxes1;
$invoice->custom_taxes2 = $recurInvoice->custom_taxes2;
$invoice->is_amount_discount = $recurInvoice->is_amount_discount;
if ($invoice->client->payment_terms) {
$invoice->due_date = date_create()->modify($invoice->client->payment_terms.' day')->format('Y-m-d');
}
$invoice->save();
foreach ($recurInvoice->invoice_items as $recurItem) {
$item = InvoiceItem::createNew($recurItem);
$item->product_id = $recurItem->product_id;
$item->qty = $recurItem->qty;
$item->cost = $recurItem->cost;
$item->notes = Utils::processVariables($recurItem->notes);
$item->product_key = Utils::processVariables($recurItem->product_key);
$item->tax_name = $recurItem->tax_name;
$item->tax_rate = $recurItem->tax_rate;
$invoice->invoice_items()->save($item);
}
foreach ($recurInvoice->invitations as $recurInvitation) {
$invitation = Invitation::createNew($recurInvitation);
$invitation->contact_id = $recurInvitation->contact_id;
$invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
$invoice->invitations()->save($invitation);
}
$this->mailer->sendInvoice($invoice);
$recurInvoice->last_sent_date = Carbon::now()->toDateTimeString();
$recurInvoice->save();
}
$this->info('Done');
}
protected function getArguments()
{
return array(
//array('example', InputArgument::REQUIRED, 'An example argument.'),
);
}
protected function getOptions()
{
return array(
//array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null),
);
}
}

View File

@ -1,225 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => true,
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => '',
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
| Command below will generate a random 32 character alphanumeric string
| cat /dev/random | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
*/
'key' => '',
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => array(
'Illuminate\Foundation\Providers\ArtisanServiceProvider',
'Illuminate\Auth\AuthServiceProvider',
'Illuminate\Cache\CacheServiceProvider',
'Illuminate\Foundation\Providers\CommandCreatorServiceProvider',
'Illuminate\Session\CommandsServiceProvider',
'Illuminate\Foundation\Providers\ComposerServiceProvider',
'Illuminate\Routing\ControllerServiceProvider',
'Illuminate\Cookie\CookieServiceProvider',
'Illuminate\Database\DatabaseServiceProvider',
'Illuminate\Encryption\EncryptionServiceProvider',
'Illuminate\Filesystem\FilesystemServiceProvider',
'Illuminate\Hashing\HashServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
'Illuminate\Foundation\Providers\KeyGeneratorServiceProvider',
'Illuminate\Log\LogServiceProvider',
'Illuminate\Mail\MailServiceProvider',
'Illuminate\Foundation\Providers\MaintenanceServiceProvider',
'Illuminate\Database\MigrationServiceProvider',
'Illuminate\Foundation\Providers\OptimizeServiceProvider',
'Illuminate\Pagination\PaginationServiceProvider',
'Illuminate\Foundation\Providers\PublisherServiceProvider',
'Illuminate\Queue\QueueServiceProvider',
'Illuminate\Redis\RedisServiceProvider',
'Illuminate\Auth\Reminders\ReminderServiceProvider',
'Illuminate\Foundation\Providers\RouteListServiceProvider',
'Illuminate\Database\SeedServiceProvider',
'Illuminate\Foundation\Providers\ServerServiceProvider',
'Illuminate\Session\SessionServiceProvider',
'Illuminate\Foundation\Providers\TinkerServiceProvider',
'Illuminate\Translation\TranslationServiceProvider',
'Illuminate\Validation\ValidationServiceProvider',
'Illuminate\View\ViewServiceProvider',
'Illuminate\Workbench\WorkbenchServiceProvider',
'Illuminate\Remote\RemoteServiceProvider',
'Bootstrapper\BootstrapperServiceProvider',
'Zizaco\Confide\ConfideServiceProvider',
'Former\FormerServiceProvider',
'Barryvdh\Debugbar\ServiceProvider',
'Chumper\Datatable\DatatableServiceProvider',
'Intervention\Image\ImageServiceProvider',
'Webpatser\Countries\CountriesServiceProvider',
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
),
/*
|--------------------------------------------------------------------------
| Service Provider Manifest
|--------------------------------------------------------------------------
|
| The service provider manifest is used by Laravel to lazy load service
| providers which are not needed for each request, as well to keep a
| list of all of the services. Here, you may set its storage spot.
|
*/
'manifest' => storage_path() . '/meta',
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => array(
'App' => 'Illuminate\Support\Facades\App',
'Artisan' => 'Illuminate\Support\Facades\Artisan',
'Auth' => 'Illuminate\Support\Facades\Auth',
'Blade' => 'Illuminate\Support\Facades\Blade',
'Cache' => 'Illuminate\Support\Facades\Cache',
'ClassLoader' => 'Illuminate\Support\ClassLoader',
'Config' => 'Illuminate\Support\Facades\Config',
'Controller' => 'Illuminate\Routing\Controller',
'Cookie' => 'Illuminate\Support\Facades\Cookie',
'Crypt' => 'Illuminate\Support\Facades\Crypt',
'DB' => 'Illuminate\Support\Facades\DB',
'Eloquent' => 'Illuminate\Database\Eloquent\Model',
'Event' => 'Illuminate\Support\Facades\Event',
'File' => 'Illuminate\Support\Facades\File',
//'Form' => 'Illuminate\Support\Facades\Form',
'Hash' => 'Illuminate\Support\Facades\Hash',
'HTML' => 'Illuminate\Support\Facades\HTML',
'Input' => 'Illuminate\Support\Facades\Input',
'Lang' => 'Illuminate\Support\Facades\Lang',
'Log' => 'Illuminate\Support\Facades\Log',
'Mail' => 'Illuminate\Support\Facades\Mail',
//'Paginator' => 'Illuminate\Support\Facades\Paginator',
'Password' => 'Illuminate\Support\Facades\Password',
'Queue' => 'Illuminate\Support\Facades\Queue',
'Redirect' => 'Illuminate\Support\Facades\Redirect',
'Redis' => 'Illuminate\Support\Facades\Redis',
'Request' => 'Illuminate\Support\Facades\Request',
'Response' => 'Illuminate\Support\Facades\Response',
'Route' => 'Illuminate\Support\Facades\Route',
'Schema' => 'Illuminate\Support\Facades\Schema',
'Seeder' => 'Illuminate\Database\Seeder',
'Session' => 'Illuminate\Support\Facades\Session',
'Str' => 'Illuminate\Support\Str',
'URL' => 'Illuminate\Support\Facades\URL',
'Validator' => 'Illuminate\Support\Facades\Validator',
'View' => 'Illuminate\Support\Facades\View',
'SSH' => 'Illuminate\Support\Facades\SSH',
'Alert' => 'Bootstrapper\Alert',
'Badge' => 'Bootstrapper\Badge',
'Breadcrumb' => 'Bootstrapper\Breadcrumb',
'Button' => 'Bootstrapper\Button',
'ButtonGroup' => 'Bootstrapper\ButtonGroup',
'ButtonToolbar' => 'Bootstrapper\ButtonToolbar',
'Carousel' => 'Bootstrapper\Carousel',
'DropdownButton' => 'Bootstrapper\DropdownButton',
'Form' => 'Bootstrapper\Form',
'Helpers' => 'Bootstrapper\Helpers',
'Icon' => 'Bootstrapper\Icon',
//'Image' => 'Bootstrapper\Image',
'Label' => 'Bootstrapper\Label',
'MediaObject' => 'Bootstrapper\MediaObject',
'Navbar' => 'Bootstrapper\Navbar',
'Navigation' => 'Bootstrapper\Navigation',
'Paginator' => 'Bootstrapper\Paginator',
'Progress' => 'Bootstrapper\Progress',
'Tabbable' => 'Bootstrapper\Tabbable',
'Table' => 'Bootstrapper\Table',
'Thumbnail' => 'Bootstrapper\Thumbnail',
'Typeahead' => 'Bootstrapper\Typeahead',
'Typography' => 'Bootstrapper\Typography',
'Confide' => 'Zizaco\Confide\ConfideFacade',
'Former' => 'Former\Facades\Former',
'Datatable' => 'Chumper\Datatable\Facades\DatatableFacade',
'Omnipay' => 'Omnipay\Omnipay',
'CreditCard' => 'Omnipay\Common\CreditCard',
'Image' => 'Intervention\Image\Facades\Image',
'Countries' => 'Webpatser\Countries\CountriesFacade',
'Carbon' => 'Carbon\Carbon',
'Rocketeer' => 'Rocketeer\Facades\Rocketeer',
),
);

View File

@ -1,71 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Authentication Driver
|--------------------------------------------------------------------------
|
| This option controls the authentication driver that will be utilized.
| This drivers manages the retrieval and authentication of the users
| attempting to get access to protected areas of your application.
|
| Supported: "database", "eloquent"
|
*/
'driver' => 'eloquent',
/*
|--------------------------------------------------------------------------
| Authentication Model
|--------------------------------------------------------------------------
|
| When using the "Eloquent" authentication driver, we need to know which
| Eloquent model should be used to retrieve your users. Of course, it
| is often just the "User" model but you may use whatever you like.
|
*/
'model' => 'User',
/*
|--------------------------------------------------------------------------
| Authentication Table
|--------------------------------------------------------------------------
|
| When using the "Database" authentication driver, we need to know which
| table should be used to retrieve your users. We have chosen a basic
| default value but you may easily change it to any table you like.
|
*/
'table' => 'users',
/*
|--------------------------------------------------------------------------
| Password Reminder Settings
|--------------------------------------------------------------------------
|
| Here you may set the settings for password reminders, including a view
| that should be used as your password reminder e-mail. You will also
| be able to set the name of the table that holds the reset tokens.
|
| The "expire" time is the number of minutes that the reminder should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);

View File

@ -1,89 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Cache Driver
|--------------------------------------------------------------------------
|
| This option controls the default cache "driver" that will be used when
| using the Caching library. Of course, you may use other drivers any
| time you wish. This is the default when another is not specified.
|
| Supported: "file", "database", "apc", "memcached", "redis", "array"
|
*/
'driver' => 'file',
/*
|--------------------------------------------------------------------------
| File Cache Location
|--------------------------------------------------------------------------
|
| When using the "file" cache driver, we need a location where the cache
| files may be stored. A sensible default has been specified, but you
| are free to change it to any other place on disk that you desire.
|
*/
'path' => storage_path().'/cache',
/*
|--------------------------------------------------------------------------
| Database Cache Connection
|--------------------------------------------------------------------------
|
| When using the "database" cache driver you may specify the connection
| that should be used to store the cached items. When this option is
| null the default database connection will be utilized for cache.
|
*/
'connection' => null,
/*
|--------------------------------------------------------------------------
| Database Cache Table
|--------------------------------------------------------------------------
|
| When using the "database" cache driver we need to know the table that
| should be used to store the cached items. A default table name has
| been provided but you're free to change it however you deem fit.
|
*/
'table' => 'cache',
/*
|--------------------------------------------------------------------------
| Memcached Servers
|--------------------------------------------------------------------------
|
| Now you may specify an array of your Memcached servers that should be
| used when utilizing the Memcached cache driver. All of the servers
| should contain a value for "host", "port", and "weight" options.
|
*/
'memcached' => array(
array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),
),
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => 'laravel',
);

View File

@ -1,18 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Additional Compiled Classes
|--------------------------------------------------------------------------
|
| Here you may specify additional classes to include in the compiled file
| generated by the `artisan optimize` command. These should be classes
| that are included on basically every request into the application.
|
*/
);

View File

@ -1,124 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| PDO Fetch Style
|--------------------------------------------------------------------------
|
| By default, database results will be returned as instances of the PHP
| stdClass object; however, you may desire to retrieve records in an
| array format for simplicity. Here you can tweak the fetch style.
|
*/
'fetch' => PDO::FETCH_CLASS,
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => 'mysql',
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => array(
'sqlite' => array(
'driver' => 'sqlite',
'database' => __DIR__.'/../database/production.sqlite',
'prefix' => '',
),
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'ninja',
'username' => 'ninja',
'password' => 'ninja',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
'pgsql' => array(
'driver' => 'pgsql',
'host' => 'localhost',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
),
'sqlsrv' => array(
'driver' => 'sqlsrv',
'host' => 'localhost',
'database' => 'database',
'username' => 'root',
'password' => '',
'prefix' => '',
),
),
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk have not actually be run in the databases.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => array(
'cluster' => false,
'default' => array(
'host' => '127.0.0.1',
'port' => 6379,
'database' => 0,
),
),
);

View File

@ -1,18 +0,0 @@
<?php
return array(
'connections' => array(
'mysql' => array(
'driver' => 'mysql',
'host' => getenv('DEVELOPMENT_DB_HOST'),
'database' => getenv('DEVELOPMENT_DB_NAME'),
'username' => getenv('DEVELOPMENT_DB_USERNAME'),
'password' => getenv('DEVELOPMENT_DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
),
);

View File

@ -1,9 +0,0 @@
<?php
return array(
'debug' => true,
'manifest' => 'gs://invoice-ninja/meta',
);

View File

@ -1,7 +0,0 @@
<?php
return array(
'driver' => 'memcached',
);

View File

@ -1,19 +0,0 @@
<?php
return array(
'connections' => array(
'mysql' => array(
'driver' => 'mysql',
'unix_socket' => getenv('PRODUCTION_CLOUD_SQL_INSTANCE'),
'host' => '',
'database' => getenv('PRODUCTION_DB_NAME'),
'username' => getenv('PRODUCTION_DB_USERNAME'),
'password' => getenv('PRODUCTION_DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
),
);

View File

@ -1,7 +0,0 @@
<?php
return array(
'driver' => 'memcached',
);

View File

@ -1,124 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail"
|
*/
'driver' => 'smtp',
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Postmark mail service, which will provide reliable delivery.
|
*/
'host' => '',
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to delivery e-mails to
| users of your application. Like the host we have set this value to
| stay compatible with the Postmark e-mail application by default.
|
*/
'port' => 587,
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => array('address' => 'contact@invoiceninja.com', 'name' => 'Invoice Ninja'),
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => 'tls',
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => '',
/*
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/
'password' => '',
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/
'pretend' => false,
);

View File

@ -1,14 +0,0 @@
<?php
return array(
// HTML markup and classes used by the "Nude" framework for icons
'icon' => array(
'tag' => 'i',
'set' => null,
'prefix' => 'icon',
),
);

View File

@ -1,14 +0,0 @@
<?php
return array(
// HTML markup and classes used by Bootstrap for icons
'icon' => array(
'tag' => 'i',
'set' => null,
'prefix' => 'icon',
),
);

View File

@ -1,26 +0,0 @@
<?php
return array(
// Map Former-supported viewports to Bootstrap 3 equivalents
'viewports' => array(
'large' => 'lg',
'medium' => 'md',
'small' => 'sm',
'mini' => 'xs',
),
// Width of labels for horizontal forms expressed as viewport => grid columns
'labelWidths' => array(
'large' => 4,
'small' => 4,
),
// HTML markup and classes used by Bootstrap 3 for icons
'icon' => array(
'tag' => 'span',
'set' => 'glyphicon',
'prefix' => 'glyphicon',
),
);

View File

@ -1,35 +0,0 @@
<?php
return array(
// Map Former-supported viewports to Foundation 3 equivalents
'viewports' => array(
'large' => '',
'medium' => null,
'small' => 'mobile-',
'mini' => null,
),
// Width of labels for horizontal forms expressed as viewport => grid columns
'labelWidths' => array(
'large' => 2,
'small' => 4,
),
// Classes to be applied to wrapped labels in horizontal forms
'wrappedLabelClasses' => array('right','inline'),
// HTML markup and classes used by Foundation 3 for icons
'icon' => array(
'tag' => 'i',
'set' => null,
'prefix' => 'fi',
),
);

View File

@ -1,36 +0,0 @@
<?php
return array(
// Map Former-supported viewports to Foundation 4 equivalents
// Foundation 4 also has an experimental "medium" breakpoint
// explained at http://foundation.zurb.com/docs/components/grid.html
'viewports' => array(
'large' => 'large',
'medium' => null,
'small' => 'small',
'mini' => null,
),
// Width of labels for horizontal forms expressed as viewport => grid columns
'labelWidths' => array(
'small' => 3,
),
// Classes to be applied to wrapped labels in horizontal forms
'wrappedLabelClasses' => array('right','inline'),
// HTML markup and classes used by Foundation 4 for icons
'icon' => array(
'tag' => 'i',
'set' => 'general',
'prefix' => 'foundicon',
),
);

View File

@ -1,59 +0,0 @@
<?php return array(
// Markup
////////////////////////////////////////////////////////////////////
// Whether labels should be automatically computed from name
'automatic_label' => true,
// The default form type
'default_form_type' => 'horizontal',
// The framework to be used by Former
'framework' => 'TwitterBootstrap3',
// Validation
////////////////////////////////////////////////////////////////////
// Whether Former should fetch errors from Session
'fetch_errors' => true,
// Whether Former should try to apply Validator rules as attributes
'live_validation' => true,
// Whether Former should automatically fetch error messages and
// display them next to the matching fields
'error_messages' => true,
// Checkables
////////////////////////////////////////////////////////////////////
// Whether checkboxes should always be present in the POST data,
// no matter if you checked them or not
'push_checkboxes' => false,
// The value a checkbox will have in the POST array if unchecked
'unchecked_value' => 0,
// Required fields
////////////////////////////////////////////////////////////////////
// The class to be added to required fields
'required_class' => 'required',
// A facultative text to append to the labels of required fields
'required_text' => '', //'<sup>*</sup>',
// Translations
////////////////////////////////////////////////////////////////////
// Where Former should look for translations
'translate_from' => 'texts',
// An array of attributes to automatically translate
'translatable' => array(
'help', 'inlineHelp', 'blockHelp',
'placeholder', 'data_placeholder',
'label'
),
);

View File

@ -1,19 +0,0 @@
<?php
return array(
// The default gateway to use
'default' => 'paypal',
// Add in each gateway here
'gateways' => array(
'paypal' => array(
'driver' => 'Paypal_Express',
'options' => array(
'solutionType' => '',
'landingPage' => '',
'headerImageUrl' => ''
)
)
)
);

View File

@ -1,117 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Login Throttle
|--------------------------------------------------------------------------
|
| Defines how many login failed tries may be done within
| the 'throttle_time_period', which is in minutes.
|
*/
'throttle_limit' => 9,
'throttle_time_period' => 2,
/*
|--------------------------------------------------------------------------
| Login Throttle Field
|--------------------------------------------------------------------------
|
| Login throttle is done using the remote ip address
| and a provided credential. Email and username are likely values.
|
| Default: email
|
*/
'login_cache_field' => 'email',
/*
|--------------------------------------------------------------------------
| Form Views
|--------------------------------------------------------------------------
|
| The VIEWS used to render forms with Confide methods:
| makeLoginForm, makeSignupForm, makeForgotPasswordForm
| and makeResetPasswordForm.
|
| By default, the out of the box confide views are used
| but you can create your own forms and replace the view
| names here. For example
|
| // To use app/views/user/signup.blade.php:
|
| 'signup_form' => 'user.signup'
|
|
*/
'login_form' => 'users.login',
'signup_form' => 'confide::signup',
'forgot_password_form' => 'users.forgot_password',
'reset_password_form' => 'users.reset_password',
/*
|--------------------------------------------------------------------------
| Email Views
|--------------------------------------------------------------------------
|
| The VIEWS used to email messages for some Confide events:
|
| By default, the out of the box confide views are used
| but you can create your own forms and replace the view
| names here. For example
|
| // To use app/views/email/confirmation.blade.php:
|
| 'email_account_confirmation' => 'email.confirmation'
|
|
*/
'email_reset_password' => 'emails.passwordreset_html', // with $user and $token.
'email_account_confirmation' => 'emails.confirm_html', // with $user
/*
|--------------------------------------------------------------------------
| Signup (create) Cache
|--------------------------------------------------------------------------
|
| By default you will only can only register once every 2 hours
| (120 minutes) because you are not able to receive a registration
| email more often then that.
|
| You can adjust that limitation here, set to 0 for no caching.
| Time is in minutes.
|
|
*/
'signup_cache' => 0,
/*
|--------------------------------------------------------------------------
| Signup E-mail and confirmation (true or false)
|--------------------------------------------------------------------------
|
| By default a signup e-mail will be send by the system, however if you
| do not want this to happen, change the line below in false and handle
| the confirmation using another technique, for example by using the IPN
| from a payment-processor. Very usefull for websites offering products.
|
| signup_email:
| is for the transport of the email, true or false
| If you want to use an IPN to trigger the email, then set it to false
|
| signup_confirm:
| is to decide of a member needs to be confirmed before he is able to login
| so when you set this to true, then a member has to be confirmed before
| he is able to login, so if you want to use an IPN for confirmation, be
| sure that the ipn process also changes the confirmed flag in the member
| table, otherwise they will not be able to login after the payment.
|
*/
'signup_email' => false,
'signup_confirm' => false,
);

View File

@ -1,78 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Queue Driver
|--------------------------------------------------------------------------
|
| The Laravel queue API supports a variety of back-ends via an unified
| API, giving you convenient access to each back-end using the same
| syntax for each one. Here you may set the default queue driver.
|
| Supported: "sync", "beanstalkd", "sqs", "iron"
|
*/
'default' => 'sync',
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
*/
'connections' => array(
'sync' => array(
'driver' => 'sync',
),
'beanstalkd' => array(
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
),
'sqs' => array(
'driver' => 'sqs',
'key' => 'your-public-key',
'secret' => 'your-secret-key',
'queue' => 'your-queue-url',
'region' => 'us-east-1',
),
'iron' => array(
'driver' => 'iron',
'project' => 'your-project-id',
'token' => 'your-token',
'queue' => 'your-queue-name',
),
),
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => array(
'database' => 'mysql', 'table' => 'failed_jobs',
),
);

View File

@ -1,59 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Remote Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify the default connection that will be used for SSH
| operations. This name should correspond to a connection name below
| in the server list. Each connection will be manually accessible.
|
*/
'default' => 'production',
/*
|--------------------------------------------------------------------------
| Remote Server Connections
|--------------------------------------------------------------------------
|
| These are the servers that will be accessible via the SSH task runner
| facilities of Laravel. This feature radically simplifies executing
| tasks on your servers, such as deploying out these applications.
|
*/
'connections' => array(
'production' => array(
'host' => '',
'username' => '',
'password' => '',
'key' => '',
'keyphrase' => '',
'root' => '/var/www',
),
),
/*
|--------------------------------------------------------------------------
| Remote Server Groups
|--------------------------------------------------------------------------
|
| Here you may list connections under a single group name, which allows
| you to easily access all of the servers at once using a short name
| that is extremely easy to remember, such as "web" or "database".
|
*/
'groups' => array(
'web' => array('production')
),
);

View File

@ -1,141 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "native", "cookie", "database", "apc",
| "memcached", "redis", "array"
|
*/
'driver' => 'native',
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire when the browser closes, set it to zero.
|
*/
'lifetime' => 120,
'expire_on_close' => false,
/*
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path().'/sessions',
/*
|--------------------------------------------------------------------------
| Session Database Connection
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the database
| connection that should be used to manage your sessions. This should
| correspond to a connection in your "database" configuration file.
|
*/
'connection' => null,
/*
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions',
/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => array(2, 100),
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
'cookie' => 'laravel_session',
/*
|--------------------------------------------------------------------------
| Session Cookie Path
|--------------------------------------------------------------------------
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/',
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => null,
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you if it can not be done securely.
|
*/
'secure' => false,
);

View File

@ -1,20 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Cache Driver
|--------------------------------------------------------------------------
|
| This option controls the default cache "driver" that will be used when
| using the Caching library. Of course, you may use other drivers any
| time you wish. This is the default when another is not specified.
|
| Supported: "file", "database", "apc", "memcached", "redis", "array"
|
*/
'driver' => 'array',
);

View File

@ -1,21 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "native", "cookie", "database", "apc",
| "memcached", "redis", "array"
|
*/
'driver' => 'array',
);

View File

@ -1,31 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => array(__DIR__.'/../views'),
/*
|--------------------------------------------------------------------------
| Pagination View
|--------------------------------------------------------------------------
|
| This view will be used to render the pagination link output, and can
| be easily customized here to show any view you like. A clean view
| compatible with Twitter's Bootstrap is given to you by default.
|
*/
'pagination' => 'pagination::bootstrap3',
);

View File

@ -1,31 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Workbench Author Name
|--------------------------------------------------------------------------
|
| When you create new packages via the Artisan "workbench" command your
| name is needed to generate the composer.json file for your package.
| You may specify it now so it is used for all of your workbenches.
|
*/
'name' => '',
/*
|--------------------------------------------------------------------------
| Workbench Author E-Mail Address
|--------------------------------------------------------------------------
|
| Like the option above, your e-mail address is used when generating new
| workbench packages. The e-mail is placed in your composer.json file
| automatically after the package is created by the workbench tool.
|
*/
'email' => '',
);

View File

@ -1,715 +0,0 @@
<?php
use ninja\repositories\AccountRepository;
use ninja\mailers\UserMailer;
use ninja\mailers\ContactMailer;
class AccountController extends \BaseController
{
protected $accountRepo;
protected $userMailer;
protected $contactMailer;
public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer)
{
parent::__construct();
$this->accountRepo = $accountRepo;
$this->userMailer = $userMailer;
$this->contactMailer = $contactMailer;
}
public function demo()
{
$demoAccountId = Utils::getDemoAccountId();
if (!$demoAccountId) {
return Redirect::to('/');
}
$account = Account::find($demoAccountId);
$user = $account->users()->first();
Auth::login($user, true);
return Redirect::to('invoices/create');
}
public function getStarted()
{
if (Auth::check()) {
return Redirect::to('invoices/create');
} elseif (!Utils::isNinja() && Account::count() > 0) {
return Redirect::to('/login');
}
$user = false;
$guestKey = Input::get('guest_key');
if ($guestKey) {
$user = User::where('password', '=', $guestKey)->first();
if ($user && $user->registered) {
return Redirect::to('/');
}
}
if (!$user) {
$account = $this->accountRepo->create();
$user = $account->users()->first();
Session::forget(RECENTLY_VIEWED);
}
Auth::login($user, true);
Event::fire('user.login');
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
}
public function enableProPlan()
{
$invitation = $this->accountRepo->enableProPlan();
/*
if ($invoice)
{
$this->contactMailer->sendInvoice($invoice);
}
*/
return $invitation->invitation_key;
}
public function setTrashVisible($entityType, $visible)
{
Session::put("show_trash:{$entityType}", $visible == 'true');
if ($entityType == 'user') {
return Redirect::to('company/'.ACCOUNT_ADVANCED_SETTINGS.'/'.ACCOUNT_USER_MANAGEMENT);
} elseif ($entityType == 'token') {
return Redirect::to('company/'.ACCOUNT_ADVANCED_SETTINGS.'/'.ACCOUNT_TOKEN_MANAGEMENT);
} else {
return Redirect::to("{$entityType}s");
}
}
public function getSearchData()
{
$data = $this->accountRepo->getSearchData();
return Response::json($data);
}
public function showSection($section = ACCOUNT_DETAILS, $subSection = false)
{
if ($section == ACCOUNT_DETAILS) {
$data = [
'account' => Account::with('users')->findOrFail(Auth::user()->account_id),
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'sizes' => Size::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'timezones' => Timezone::remember(DEFAULT_QUERY_CACHE)->orderBy('location')->get(),
'dateFormats' => DateFormat::remember(DEFAULT_QUERY_CACHE)->get(),
'datetimeFormats' => DatetimeFormat::remember(DEFAULT_QUERY_CACHE)->get(),
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'languages' => Language::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'showUser' => Auth::user()->id === Auth::user()->account->users()->first()->id,
];
return View::make('accounts.details', $data);
} elseif ($section == ACCOUNT_PAYMENTS) {
$account = Auth::user()->account;
$account->load('account_gateways');
$count = count($account->account_gateways);
if ($count == 0) {
return Redirect::to('gateways/create');
} else {
return View::make('accounts.payments', ['showAdd' => $count < 2]);
}
} elseif ($section == ACCOUNT_NOTIFICATIONS) {
$data = [
'account' => Account::with('users')->findOrFail(Auth::user()->account_id),
];
return View::make('accounts.notifications', $data);
} elseif ($section == ACCOUNT_IMPORT_EXPORT) {
return View::make('accounts.import_export');
} elseif ($section == ACCOUNT_ADVANCED_SETTINGS) {
$account = Auth::user()->account;
$data = [
'account' => $account,
'feature' => $subSection,
];
if ($subSection == ACCOUNT_INVOICE_DESIGN) {
$invoice = new stdClass();
$client = new stdClass();
$invoiceItem = new stdClass();
$client->name = 'Sample Client';
$client->address1 = '';
$client->city = '';
$client->state = '';
$client->postal_code = '';
$client->work_phone = '';
$client->work_email = '';
$invoice->invoice_number = Auth::user()->account->getNextInvoiceNumber();
$invoice->invoice_date = date_create()->format('Y-m-d');
$invoice->account = json_decode(Auth::user()->account->toJson());
$invoice->amount = $invoice->balance = 100;
$invoiceItem->cost = 100;
$invoiceItem->qty = 1;
$invoiceItem->notes = 'Notes';
$invoiceItem->product_key = 'Item';
$invoice->client = $client;
$invoice->invoice_items = [$invoiceItem];
$data['invoice'] = $invoice;
$data['invoiceDesigns'] = InvoiceDesign::remember(DEFAULT_QUERY_CACHE, 'invoice_designs_cache_'.Auth::user()->maxInvoiceDesignId())
->where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get();
} else if ($subSection == ACCOUNT_EMAIL_TEMPLATES) {
$data['invoiceEmail'] = $account->getEmailTemplate(ENTITY_INVOICE);
$data['quoteEmail'] = $account->getEmailTemplate(ENTITY_QUOTE);
$data['paymentEmail'] = $account->getEmailTemplate(ENTITY_PAYMENT);
$data['emailFooter'] = $account->getEmailFooter();
}
return View::make("accounts.{$subSection}", $data);
} elseif ($section == ACCOUNT_PRODUCTS) {
$data = [
'account' => Auth::user()->account,
];
return View::make('accounts.products', $data);
}
}
public function doSection($section = ACCOUNT_DETAILS, $subSection = false)
{
if ($section == ACCOUNT_DETAILS) {
return AccountController::saveDetails();
} elseif ($section == ACCOUNT_IMPORT_EXPORT) {
return AccountController::importFile();
} elseif ($section == ACCOUNT_MAP) {
return AccountController::mapFile();
} elseif ($section == ACCOUNT_NOTIFICATIONS) {
return AccountController::saveNotifications();
} elseif ($section == ACCOUNT_EXPORT) {
return AccountController::export();
} elseif ($section == ACCOUNT_ADVANCED_SETTINGS) {
if ($subSection == ACCOUNT_INVOICE_SETTINGS) {
return AccountController::saveInvoiceSettings();
} elseif ($subSection == ACCOUNT_INVOICE_DESIGN) {
return AccountController::saveInvoiceDesign();
} elseif ($subSection == ACCOUNT_EMAIL_TEMPLATES) {
return AccountController::saveEmailTemplates();
}
} elseif ($section == ACCOUNT_PRODUCTS) {
return AccountController::saveProducts();
}
}
private function saveEmailTemplates()
{
if (Auth::user()->account->isPro()) {
$account = Auth::user()->account;
$account->email_template_invoice = Input::get('email_template_invoice', $account->getEmailTemplate(ENTITY_INVOICE));
$account->email_template_quote = Input::get('email_template_quote', $account->getEmailTemplate(ENTITY_QUOTE));
$account->email_template_payment = Input::get('email_template_payment', $account->getEmailTemplate(ENTITY_PAYMENT));
$account->save();
Session::flash('message', trans('texts.updated_settings'));
}
return Redirect::to('company/advanced_settings/email_templates');
}
private function saveProducts()
{
$account = Auth::user()->account;
$account->fill_products = Input::get('fill_products') ? true : false;
$account->update_products = Input::get('update_products') ? true : false;
$account->save();
Session::flash('message', trans('texts.updated_settings'));
return Redirect::to('company/products');
}
private function saveInvoiceSettings()
{
if (Auth::user()->account->isPro()) {
$account = Auth::user()->account;
$account->custom_label1 = trim(Input::get('custom_label1'));
$account->custom_value1 = trim(Input::get('custom_value1'));
$account->custom_label2 = trim(Input::get('custom_label2'));
$account->custom_value2 = trim(Input::get('custom_value2'));
$account->custom_client_label1 = trim(Input::get('custom_client_label1'));
$account->custom_client_label2 = trim(Input::get('custom_client_label2'));
$account->custom_invoice_label1 = trim(Input::get('custom_invoice_label1'));
$account->custom_invoice_label2 = trim(Input::get('custom_invoice_label2'));
$account->custom_invoice_taxes1 = Input::get('custom_invoice_taxes1') ? true : false;
$account->custom_invoice_taxes2 = Input::get('custom_invoice_taxes2') ? true : false;
$account->invoice_number_prefix = Input::get('invoice_number_prefix');
$account->invoice_number_counter = Input::get('invoice_number_counter');
$account->quote_number_prefix = Input::get('quote_number_prefix');
$account->share_counter = Input::get('share_counter') ? true : false;
if (!$account->share_counter) {
$account->quote_number_counter = Input::get('quote_number_counter');
}
if (!$account->share_counter && $account->invoice_number_prefix == $account->quote_number_prefix) {
Session::flash('error', trans('texts.invalid_counter'));
return Redirect::to('company/advanced_settings/invoice_settings')->withInput();
} else {
$account->save();
Session::flash('message', trans('texts.updated_settings'));
}
}
return Redirect::to('company/advanced_settings/invoice_settings');
}
private function saveInvoiceDesign()
{
if (Auth::user()->account->isPro()) {
$account = Auth::user()->account;
$account->hide_quantity = Input::get('hide_quantity') ? true : false;
$account->hide_paid_to_date = Input::get('hide_paid_to_date') ? true : false;
$account->primary_color = Input::get('primary_color');
$account->secondary_color = Input::get('secondary_color');
$account->invoice_design_id = Input::get('invoice_design_id');
$account->save();
Session::flash('message', trans('texts.updated_settings'));
}
return Redirect::to('company/advanced_settings/invoice_design');
}
private function export()
{
$output = fopen('php://output', 'w') or Utils::fatalError();
header('Content-Type:application/csv');
header('Content-Disposition:attachment;filename=export.csv');
$clients = Client::scope()->get();
AccountController::exportData($output, $clients->toArray());
$contacts = Contact::scope()->get();
AccountController::exportData($output, $contacts->toArray());
$invoices = Invoice::scope()->get();
AccountController::exportData($output, $invoices->toArray());
$invoiceItems = InvoiceItem::scope()->get();
AccountController::exportData($output, $invoiceItems->toArray());
$payments = Payment::scope()->get();
AccountController::exportData($output, $payments->toArray());
$credits = Credit::scope()->get();
AccountController::exportData($output, $credits->toArray());
fclose($output);
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()
{
$data = Session::get('data');
Session::forget('data');
$map = Input::get('map');
$count = 0;
$hasHeaders = Input::get('header_checkbox');
$countries = Country::remember(DEFAULT_QUERY_CACHE)->get();
$countryMap = [];
foreach ($countries as $country) {
$countryMap[strtolower($country->name)] = $country->id;
}
foreach ($data as $row) {
if ($hasHeaders) {
$hasHeaders = false;
continue;
}
$client = Client::createNew();
$contact = Contact::createNew();
$contact->is_primary = true;
$contact->send_invoice = true;
$count++;
foreach ($row as $index => $value) {
$field = $map[$index];
$value = trim($value);
if ($field == Client::$fieldName && !$client->name) {
$client->name = $value;
} elseif ($field == Client::$fieldPhone && !$client->work_phone) {
$client->work_phone = $value;
} elseif ($field == Client::$fieldAddress1 && !$client->address1) {
$client->address1 = $value;
} elseif ($field == Client::$fieldAddress2 && !$client->address2) {
$client->address2 = $value;
} elseif ($field == Client::$fieldCity && !$client->city) {
$client->city = $value;
} elseif ($field == Client::$fieldState && !$client->state) {
$client->state = $value;
} elseif ($field == Client::$fieldPostalCode && !$client->postal_code) {
$client->postal_code = $value;
} elseif ($field == Client::$fieldCountry && !$client->country_id) {
$value = strtolower($value);
$client->country_id = isset($countryMap[$value]) ? $countryMap[$value] : null;
} elseif ($field == Client::$fieldNotes && !$client->private_notes) {
$client->private_notes = $value;
} elseif ($field == Contact::$fieldFirstName && !$contact->first_name) {
$contact->first_name = $value;
} elseif ($field == Contact::$fieldLastName && !$contact->last_name) {
$contact->last_name = $value;
} elseif ($field == Contact::$fieldPhone && !$contact->phone) {
$contact->phone = $value;
} elseif ($field == Contact::$fieldEmail && !$contact->email) {
$contact->email = strtolower($value);
}
}
$client->save();
$client->contacts()->save($contact);
Activity::createClient($client, false);
}
$message = Utils::pluralize('created_client', $count);
Session::flash('message', $message);
return Redirect::to('clients');
}
private function mapFile()
{
$file = Input::file('file');
if ($file == null) {
Session::flash('error', trans('texts.select_file'));
return Redirect::to('company/import_export');
}
$name = $file->getRealPath();
require_once app_path().'/includes/parsecsv.lib.php';
$csv = new parseCSV();
$csv->heading = false;
$csv->auto($name);
if (count($csv->data) + Client::scope()->count() > Auth::user()->getMaxNumClients()) {
$message = trans('texts.limit_clients', ['count' => Auth::user()->getMaxNumClients()]);
Session::flash('error', $message);
return Redirect::to('company/import_export');
}
Session::put('data', $csv->data);
$headers = false;
$hasHeaders = false;
$mapped = array();
$columns = array('',
Client::$fieldName,
Client::$fieldPhone,
Client::$fieldAddress1,
Client::$fieldAddress2,
Client::$fieldCity,
Client::$fieldState,
Client::$fieldPostalCode,
Client::$fieldCountry,
Client::$fieldNotes,
Contact::$fieldFirstName,
Contact::$fieldLastName,
Contact::$fieldPhone,
Contact::$fieldEmail,
);
if (count($csv->data) > 0) {
$headers = $csv->data[0];
foreach ($headers as $title) {
if (strpos(strtolower($title), 'name') > 0) {
$hasHeaders = true;
break;
}
}
for ($i = 0; $i<count($headers); $i++) {
$title = strtolower($headers[$i]);
$mapped[$i] = '';
if ($hasHeaders) {
$map = array(
'first' => Contact::$fieldFirstName,
'last' => Contact::$fieldLastName,
'email' => Contact::$fieldEmail,
'mobile' => Contact::$fieldPhone,
'phone' => Client::$fieldPhone,
'name|organization' => Client::$fieldName,
'street|address|address1' => Client::$fieldAddress1,
'street2|address2' => Client::$fieldAddress2,
'city' => Client::$fieldCity,
'state|province' => Client::$fieldState,
'zip|postal|code' => Client::$fieldPostalCode,
'country' => Client::$fieldCountry,
'note' => Client::$fieldNotes,
);
foreach ($map as $search => $column) {
foreach (explode("|", $search) as $string) {
if (strpos($title, 'sec') === 0) {
continue;
}
if (strpos($title, $string) !== false) {
$mapped[$i] = $column;
break(2);
}
}
}
}
}
}
$data = array(
'data' => $csv->data,
'headers' => $headers,
'hasHeaders' => $hasHeaders,
'columns' => $columns,
'mapped' => $mapped,
);
return View::make('accounts.import_map', $data);
}
private function saveNotifications()
{
$account = Auth::user()->account;
$account->invoice_terms = Input::get('invoice_terms');
$account->invoice_footer = Input::get('invoice_footer');
$account->email_footer = Input::get('email_footer');
$account->save();
$user = Auth::user();
$user->notify_sent = Input::get('notify_sent');
$user->notify_viewed = Input::get('notify_viewed');
$user->notify_paid = Input::get('notify_paid');
$user->save();
Session::flash('message', trans('texts.updated_settings'));
return Redirect::to('company/notifications');
}
private function saveDetails()
{
$rules = array(
'name' => 'required',
);
$user = Auth::user()->account->users()->first();
if (Auth::user()->id === $user->id) {
$rules['email'] = 'email|required|unique:users,email,'.$user->id.',id';
}
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('company/details')
->withErrors($validator)
->withInput();
} else {
$account = Auth::user()->account;
$account->name = trim(Input::get('name'));
$account->id_number = trim(Input::get('id_number'));
$account->vat_number = trim(Input::get('vat_number'));
$account->work_email = trim(Input::get('work_email'));
$account->work_phone = trim(Input::get('work_phone'));
$account->address1 = trim(Input::get('address1'));
$account->address2 = trim(Input::get('address2'));
$account->city = trim(Input::get('city'));
$account->state = trim(Input::get('state'));
$account->postal_code = trim(Input::get('postal_code'));
$account->country_id = Input::get('country_id') ? Input::get('country_id') : null;
$account->size_id = Input::get('size_id') ? Input::get('size_id') : null;
$account->industry_id = Input::get('industry_id') ? Input::get('industry_id') : null;
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
$account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null;
$account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null;
$account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1; // US Dollar
$account->language_id = Input::get('language_id') ? Input::get('language_id') : 1; // English
$account->save();
if (Auth::user()->id === $user->id) {
$user->first_name = trim(Input::get('first_name'));
$user->last_name = trim(Input::get('last_name'));
$user->username = trim(Input::get('email'));
$user->email = trim(strtolower(Input::get('email')));
$user->phone = trim(Input::get('phone'));
$user->save();
}
/* Logo image file */
if ($file = Input::file('logo')) {
$path = Input::file('logo')->getRealPath();
File::delete('logo/'.$account->account_key.'.jpg');
$image = Image::make($path);
$mimeType = $file->getMimeType();
if ($image->width == 200 && $mimeType == 'image/jpeg') {
$file->move('logo/', $account->account_key . '.jpg');
} else {
$image->resize(200, 120, true, false);
Image::canvas($image->width, $image->height, '#FFFFFF')->insert($image)->save($account->getLogoPath());
}
//$image = Image::make($path)->resize(200, 120, true, false);
//Image::canvas($image->width, $image->height, '#FFFFFF')->insert($image)->save($account->getLogoPath());
}
Event::fire('user.refresh');
Session::flash('message', trans('texts.updated_settings'));
return Redirect::to('company/details');
}
}
public function removeLogo()
{
File::delete('logo/'.Auth::user()->account->account_key.'.jpg');
Session::flash('message', trans('texts.removed_logo'));
return Redirect::to('company/details');
}
public function checkEmail()
{
$email = User::withTrashed()->where('email', '=', Input::get('email'))->where('id', '<>', Auth::user()->id)->first();
if ($email) {
return "taken";
} else {
return "available";
}
}
public function submitSignup()
{
$rules = array(
'new_first_name' => 'required',
'new_last_name' => 'required',
'new_password' => 'required|min:6',
'new_email' => 'email|required|unique:users,email,'.Auth::user()->id.',id',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return '';
}
$user = Auth::user();
$user->first_name = trim(Input::get('new_first_name'));
$user->last_name = trim(Input::get('new_last_name'));
$user->email = trim(strtolower(Input::get('new_email')));
$user->username = $user->email;
$user->password = trim(Input::get('new_password'));
$user->password_confirmation = trim(Input::get('new_password'));
$user->registered = true;
$user->amend();
if (Utils::isNinja()) {
$this->userMailer->sendConfirmation($user);
} else {
$this->accountRepo->registerUser($user);
}
$activities = Activity::scope()->get();
foreach ($activities as $activity) {
$activity->message = str_replace('Guest', $user->getFullName(), $activity->message);
$activity->save();
}
if (Input::get('go_pro') == 'true') {
Session::set(REQUESTED_PRO_PLAN, true);
}
Session::set(SESSION_COUNTER, -1);
return "{$user->first_name} {$user->last_name}";
}
public function doRegister()
{
$affiliate = Affiliate::where('affiliate_key', '=', SELF_HOST_AFFILIATE_KEY)->first();
$license = new License();
$license->first_name = Input::get('first_name');
$license->last_name = Input::get('last_name');
$license->email = Input::get('email');
$license->transaction_reference = Request::getClientIp();
$license->license_key = Utils::generateLicense();
$license->affiliate_id = $affiliate->id;
$license->product_id = PRODUCT_SELF_HOST;
$license->is_claimed = 1;
$license->save();
return '';
}
public function cancelAccount()
{
if ($reason = trim(Input::get('reason'))) {
$email = Auth::user()->email;
$name = Auth::user()->getDisplayName();
$data = [
'text' => $reason,
];
$this->userMailer->sendTo(CONTACT_EMAIL, $email, $name, 'Invoice Ninja Feedback [Canceled Account]', 'contact', $data);
}
$account = Auth::user()->account;
$account->forceDelete();
Confide::logout();
return Redirect::to('/')->with('clearGuestKey', true);
}
}

View File

@ -1,292 +0,0 @@
<?php
/*
|--------------------------------------------------------------------------
| Confide Controller Template
|--------------------------------------------------------------------------
|
| This is the default Confide controller template for controlling user
| authentication. Feel free to change to your needs.
|
*/
use ninja\repositories\AccountRepository;
class AccountGatewayController extends BaseController
{
public function getDatatable()
{
$query = \DB::table('account_gateways')
->join('gateways', 'gateways.id', '=', 'account_gateways.gateway_id')
->where('account_gateways.deleted_at', '=', null)
->where('account_gateways.account_id', '=', \Auth::user()->account_id)
->select('account_gateways.public_id', 'gateways.name', 'account_gateways.deleted_at');
return Datatable::query($query)
->addColumn('name', function ($model) { return link_to('gateways/'.$model->public_id.'/edit', $model->name); })
->addColumn('dropdown', function ($model) {
$actions = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
if (!$model->deleted_at) {
$actions .= '<li><a href="'.URL::to('gateways/'.$model->public_id).'/edit">'.uctrans('texts.edit_gateway').'</a></li>
<li class="divider"></li>
<li><a href="javascript:deleteAccountGateway('.$model->public_id.')">'.uctrans('texts.delete_gateway').'</a></li>';
}
$actions .= '</ul>
</div>';
return $actions;
})
->orderColumns(['name'])
->make();
}
public function edit($publicId)
{
$accountGateway = AccountGateway::scope($publicId)->firstOrFail();
$config = $accountGateway->config;
$selectedCards = $accountGateway->accepted_credit_cards;
$configFields = json_decode($config);
foreach ($configFields as $configField => $value) {
$configFields->$configField = str_repeat('*', strlen($value));
}
$data = self::getViewModel($accountGateway);
$data['url'] = 'gateways/'.$publicId;
$data['method'] = 'PUT';
$data['title'] = trans('texts.edit_gateway') . ' - ' . $accountGateway->gateway->name;
$data['config'] = $configFields;
return View::make('accounts.account_gateway', $data);
}
public function update($publicId)
{
return $this->save($publicId);
}
public function store()
{
return $this->save();
}
/**
* Displays the form for account creation
*
*/
public function create()
{
$data = self::getViewModel();
$data['url'] = 'gateways';
$data['method'] = 'POST';
$data['title'] = trans('texts.add_gateway');
return View::make('accounts.account_gateway', $data);
}
private function getViewModel($accountGateway = false)
{
$selectedCards = $accountGateway ? $accountGateway->accepted_credit_cards : 0;
$account = Auth::user()->account;
$recommendedGateways = Gateway::remember(DEFAULT_QUERY_CACHE)
->where('recommended', '=', '1')
->orderBy('sort_order')
->get();
$recommendedGatewayArray = array();
foreach ($recommendedGateways as $recommendedGateway) {
$arrayItem = array(
'value' => $recommendedGateway->id,
'other' => 'false',
'data-imageUrl' => asset($recommendedGateway->getLogoUrl()),
'data-siteUrl' => $recommendedGateway->site_url,
);
$recommendedGatewayArray[$recommendedGateway->name] = $arrayItem;
}
$creditCardsArray = unserialize(CREDIT_CARDS);
$creditCards = [];
foreach ($creditCardsArray as $card => $name) {
if ($selectedCards > 0 && ($selectedCards & $card) == $card) {
$creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card']), 'checked' => 'checked'];
} else {
$creditCards[$name['text']] = ['value' => $card, 'data-imageUrl' => asset($name['card'])];
}
}
$otherItem = array(
'value' => 1000000,
'other' => 'true',
'data-imageUrl' => '',
'data-siteUrl' => '',
);
$recommendedGatewayArray['Other Options'] = $otherItem;
$account->load('account_gateways');
$currentGateways = $account->account_gateways;
$gateways = Gateway::where('payment_library_id', '=', 1)->orderBy('name');
$onlyPayPal = false;
if (!$accountGateway) {
if (count($currentGateways) > 0) {
$currentGateway = $currentGateways[0];
if ($currentGateway->isPayPal()) {
$gateways->where('id', '!=', GATEWAY_PAYPAL_EXPRESS);
} else {
$gateways->where('id', '=', GATEWAY_PAYPAL_EXPRESS);
$onlyPayPal = true;
}
}
}
$gateways = $gateways->get();
foreach ($gateways as $gateway) {
$paymentLibrary = $gateway->paymentlibrary;
$gateway->fields = $gateway->getFields();
if ($accountGateway && $accountGateway->gateway_id == $gateway->id) {
$accountGateway->fields = $gateway->fields;
}
}
$tokenBillingOptions = [];
for ($i=1; $i<=4; $i++) {
$tokenBillingOptions[$i] = trans("texts.token_billing_{$i}");
}
return [
'account' => $account,
'accountGateway' => $accountGateway,
'config' => false,
'gateways' => $gateways,
'recommendedGateways' => $recommendedGatewayArray,
'creditCardTypes' => $creditCards,
'tokenBillingOptions' => $tokenBillingOptions,
'showBreadcrumbs' => false,
'onlyPayPal' => $onlyPayPal,
'countGateways' => count($currentGateways)
];
}
public function delete()
{
$accountGatewayPublicId = Input::get('accountGatewayPublicId');
$gateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail();
$gateway->delete();
Session::flash('message', trans('texts.deleted_gateway'));
return Redirect::to('company/payments');
}
/**
* Stores new account
*
*/
public function save($accountGatewayPublicId = false)
{
$rules = array();
$recommendedId = Input::get('recommendedGateway_id');
$gatewayId = ($recommendedId == 1000000 ? Input::get('gateway_id') : $recommendedId);
if (!$gatewayId) {
Session::flash('error', trans('validation.required', ['attribute' => 'gateway']));
return Redirect::to('gateways/create')
->withInput();
}
$gateway = Gateway::findOrFail($gatewayId);
$paymentLibrary = $gateway->paymentlibrary;
$fields = $gateway->getFields();
foreach ($fields as $field => $details) {
if (!in_array($field, ['testMode', 'developerMode', 'headerImageUrl', 'solutionType', 'landingPage', 'brandName', 'logoImageUrl', 'borderColor'])) {
if (strtolower($gateway->name) == 'beanstream') {
if (in_array($field, ['merchant_id', 'passCode'])) {
$rules[$gateway->id.'_'.$field] = 'required';
}
} else {
$rules[$gateway->id.'_'.$field] = 'required';
}
}
}
$creditcards = Input::get('creditCardTypes');
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('gateways/create')
->withErrors($validator)
->withInput();
} else {
$account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id);
if ($accountGatewayPublicId) {
$accountGateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail();
} else {
$accountGateway = AccountGateway::createNew();
$accountGateway->gateway_id = $gatewayId;
}
$isMasked = false;
$config = new stdClass();
foreach ($fields as $field => $details) {
$value = trim(Input::get($gateway->id.'_'.$field));
if ($value && $value === str_repeat('*', strlen($value))) {
$isMasked = true;
}
$config->$field = $value;
}
$cardCount = 0;
if ($creditcards) {
foreach ($creditcards as $card => $value) {
$cardCount += intval($value);
}
}
// if the values haven't changed don't update the config
if ($isMasked && $accountGatewayPublicId) {
$accountGateway->accepted_credit_cards = $cardCount;
$accountGateway->save();
// if there's an existing config for this gateway update it
} elseif (!$isMasked && $accountGatewayPublicId && $accountGateway->gateway_id == $gatewayId) {
$accountGateway->accepted_credit_cards = $cardCount;
$accountGateway->config = json_encode($config);
$accountGateway->save();
// otherwise, create a new gateway config
} else {
$accountGateway->config = json_encode($config);
$accountGateway->accepted_credit_cards = $cardCount;
$account->account_gateways()->save($accountGateway);
}
if (Input::get('token_billing_type_id')) {
$account->token_billing_type_id = Input::get('token_billing_type_id');
$account->save();
}
if ($accountGatewayPublicId) {
$message = trans('texts.updated_gateway');
} else {
$message = trans('texts.created_gateway');
}
Session::flash('message', $message);
return Redirect::to('company/payments');
}
}
}

View File

@ -1,20 +0,0 @@
<?php
class ActivityController extends \BaseController
{
public function getDatatable($clientPublicId)
{
$query = DB::table('activities')
->join('clients', 'clients.id', '=', 'activities.client_id')
->where('clients.public_id', '=', $clientPublicId)
->where('activities.account_id', '=', Auth::user()->account_id)
->select('activities.id', 'activities.message', 'activities.created_at', 'clients.currency_id', 'activities.balance', 'activities.adjustment');
return Datatable::query($query)
->addColumn('id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
->addColumn('message', function ($model) { return Utils::decodeActivity($model->message); })
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::formatMoney($model->adjustment, $model->currency_id) : ''; })
->make();
}
}

View File

@ -1,171 +0,0 @@
<?php
use ninja\mailers\Mailer;
use ninja\repositories\AccountRepository;
class AppController extends BaseController
{
protected $accountRepo;
protected $mailer;
public function __construct(AccountRepository $accountRepo, Mailer $mailer)
{
parent::__construct();
$this->accountRepo = $accountRepo;
$this->mailer = $mailer;
}
public function showSetup()
{
if (Utils::isNinja() || Utils::isDatabaseSetup()) {
return Redirect::to('/');
}
return View::make('setup');
}
public function doSetup()
{
if (Utils::isNinja() || Utils::isDatabaseSetup()) {
return Redirect::to('/');
}
$valid = false;
$test = Input::get('test');
$app = Input::get('app');
$app['key'] = str_random(RANDOM_KEY_LENGTH);
$app['debug'] = false;
$database = Input::get('database');
$dbType = $database['default'];
$database['connections'] = [$dbType => $database['type']];
unset($database['type']);
$mail = Input::get('mail');
$email = $mail['username'];
$mail['from']['address'] = $email;
if ($test == 'mail') {
return self::testMail($mail);
}
$valid = self::testDatabase($database);
if ($test == 'db') {
return $valid === true ? 'Success' : $valid;
} elseif (!$valid) {
return Redirect::to('/setup')->withInput();
}
$content = "<?php return 'production';";
$fp = fopen(base_path()."/bootstrap/environment.php", 'w');
fwrite($fp, $content);
fclose($fp);
$configDir = app_path().'/config/production';
if (!file_exists($configDir)) {
mkdir($configDir);
}
foreach (['app' => $app, 'database' => $database, 'mail' => $mail] as $key => $config) {
$content = '<?php return '.var_export($config, true).';';
$fp = fopen(app_path()."/config/production/{$key}.php", 'w');
fwrite($fp, $content);
fclose($fp);
}
Artisan::call('migrate');
Artisan::call('db:seed');
$account = $this->accountRepo->create();
$user = $account->users()->first();
$user->first_name = trim(Input::get('first_name'));
$user->last_name = trim(Input::get('last_name'));
$user->email = trim(strtolower(Input::get('email')));
$user->username = $user->email;
$user->password = trim(Input::get('password'));
$user->password_confirmation = trim(Input::get('password'));
$user->registered = true;
$user->amend();
//Auth::login($user, true);
$this->accountRepo->registerUser($user);
return Redirect::to('/invoices/create');
}
private function testDatabase($database)
{
$dbType = $database['default'];
Config::set('database.default', $dbType);
foreach ($database['connections'][$dbType] as $key => $val) {
Config::set("database.connections.{$dbType}.{$key}", $val);
}
try {
$valid = DB::connection()->getDatabaseName() ? true : false;
} catch (Exception $e) {
return $e->getMessage();
}
return $valid;
}
private function testMail($mail)
{
$email = $mail['username'];
$fromName = $mail['from']['name'];
foreach ($mail as $key => $val) {
Config::set("mail.{$key}", $val);
}
Config::set('mail.from.address', $email);
Config::set('mail.from.name', $fromName);
$data = [
'text' => 'Test email',
];
try {
$this->mailer->sendTo($email, $email, $fromName, 'Test email', 'contact', $data);
return 'Sent';
} catch (Exception $e) {
return $e->getMessage();
}
}
public function install()
{
if (!Utils::isNinja() && !Utils::isDatabaseSetup()) {
try {
Artisan::call('migrate');
Artisan::call('db:seed');
} catch (Exception $e) {
Response::make($e->getMessage(), 500);
}
}
return Redirect::to('/');
}
public function update()
{
if (!Utils::isNinja()) {
try {
Artisan::call('migrate');
Cache::flush();
} catch (Exception $e) {
Response::make($e->getMessage(), 500);
}
}
return Redirect::to('/');
}
}

View File

@ -1,21 +0,0 @@
<?php
class BaseController extends Controller
{
/**
* Setup the layout used by the controller.
*
* @return void
*/
protected function setupLayout()
{
if (! is_null($this->layout)) {
$this->layout = View::make($this->layout);
}
}
public function __construct()
{
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
}
}

View File

@ -1,51 +0,0 @@
<?php
use ninja\repositories\ClientRepository;
class ClientApiController extends Controller
{
protected $clientRepo;
public function __construct(ClientRepository $clientRepo)
{
$this->clientRepo = $clientRepo;
}
public function ping()
{
$headers = Utils::getApiHeaders();
return Response::make('', 200, $headers);
}
public function index()
{
$clients = Client::scope()->with('contacts')->orderBy('created_at', 'desc')->get();
$clients = Utils::remapPublicIds($clients->toArray());
$response = json_encode($clients, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($clients));
return Response::make($response, 200, $headers);
}
public function store()
{
$data = Input::all();
$error = $this->clientRepo->getErrors($data);
if ($error) {
$headers = Utils::getApiHeaders();
return Response::make($error, 500, $headers);
} else {
$client = $this->clientRepo->save(false, $data, false);
$client->load('contacts');
$client = Utils::remapPublicIds($client->toArray());
$response = json_encode($client, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
}
}

View File

@ -1,278 +0,0 @@
<?php
use ninja\repositories\ClientRepository;
class ClientController extends \BaseController
{
protected $clientRepo;
public function __construct(ClientRepository $clientRepo)
{
parent::__construct();
$this->clientRepo = $clientRepo;
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return View::make('list', array(
'entityType' => ENTITY_CLIENT,
'title' => trans('texts.clients'),
'columns' => Utils::trans(['checkbox', 'client', 'contact', 'email', 'date_created', 'last_login', 'balance', 'action']),
));
}
public function getDatatable()
{
$clients = $this->clientRepo->find(Input::get('sSearch'));
return Datatable::query($clients)
->addColumn('checkbox', function ($model) { return '<input type="checkbox" name="ids[]" value="'.$model->public_id.'" '.Utils::getEntityRowClass($model).'>'; })
->addColumn('name', function ($model) { return link_to('clients/'.$model->public_id, $model->name); })
->addColumn('first_name', function ($model) { return link_to('clients/'.$model->public_id, $model->first_name.' '.$model->last_name); })
->addColumn('email', function ($model) { return link_to('clients/'.$model->public_id, $model->email); })
->addColumn('created_at', function ($model) { return Utils::timestampToDateString(strtotime($model->created_at)); })
->addColumn('last_login', function ($model) { return Utils::timestampToDateString(strtotime($model->last_login)); })
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
->addColumn('dropdown', function ($model) {
if ($model->is_deleted) {
return '<div style="height:38px"/>';
}
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
if (!$model->deleted_at || $model->deleted_at == '0000-00-00') {
$str .= '<li><a href="'.URL::to('clients/'.$model->public_id.'/edit').'">'.trans('texts.edit_client').'</a></li>
<li class="divider"></li>
<li><a href="'.URL::to('invoices/create/'.$model->public_id).'">'.trans('texts.new_invoice').'</a></li>
<li><a href="'.URL::to('payments/create/'.$model->public_id).'">'.trans('texts.new_payment').'</a></li>
<li><a href="'.URL::to('credits/create/'.$model->public_id).'">'.trans('texts.new_credit').'</a></li>
<li class="divider"></li>
<li><a href="javascript:archiveEntity('.$model->public_id.')">'.trans('texts.archive_client').'</a></li>';
} else {
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans('texts.restore_client').'</a></li>';
}
return $str.'<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans('texts.delete_client').'</a></li></ul>
</div>';
})
->make();
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
return $this->save();
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($publicId)
{
$client = Client::withTrashed()->scope($publicId)->with('contacts', 'size', 'industry')->firstOrFail();
Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT);
$actionLinks = [
[trans('texts.create_invoice'), URL::to('invoices/create/'.$client->public_id)],
[trans('texts.enter_payment'), URL::to('payments/create/'.$client->public_id)],
[trans('texts.enter_credit'), URL::to('credits/create/'.$client->public_id)],
];
if (Utils::isPro()) {
array_unshift($actionLinks, [trans('texts.create_quote'), URL::to('quotes/create/'.$client->public_id)]);
}
$data = array(
'actionLinks' => $actionLinks,
'showBreadcrumbs' => false,
'client' => $client,
'credit' => $client->getTotalCredit(),
'title' => trans('texts.view_client'),
'hasRecurringInvoices' => Invoice::scope()->where('is_recurring', '=', true)->whereClientId($client->id)->count() > 0,
'gatewayLink' => $client->getGatewayLink(),
);
return View::make('clients.show', $data);
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
if (Client::scope()->count() > Auth::user()->getMaxNumClients()) {
return View::make('error', ['hideHeader' => true, 'error' => "Sorry, you've exceeded the limit of ".Auth::user()->getMaxNumClients()." clients"]);
}
$data = [
'client' => null,
'method' => 'POST',
'url' => 'clients',
'title' => trans('texts.new_client'),
];
$data = array_merge($data, self::getViewModel());
return View::make('clients.edit', $data);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($publicId)
{
$client = Client::scope($publicId)->with('contacts')->firstOrFail();
$data = [
'client' => $client,
'method' => 'PUT',
'url' => 'clients/'.$publicId,
'title' => trans('texts.edit_client'),
];
$data = array_merge($data, self::getViewModel());
return View::make('clients.edit', $data);
}
private static function getViewModel()
{
return [
'sizes' => Size::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'customLabel1' => Auth::user()->account->custom_client_label1,
'customLabel2' => Auth::user()->account->custom_client_label2,
];
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($publicId)
{
return $this->save($publicId);
}
private function save($publicId = null)
{
$rules = array(
'email' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
$url = $publicId ? 'clients/'.$publicId.'/edit' : 'clients/create';
return Redirect::to($url)
->withErrors($validator)
->withInput(Input::except('password'));
} else {
if ($publicId) {
$client = Client::scope($publicId)->firstOrFail();
} else {
$client = Client::createNew();
}
$client->name = trim(Input::get('name'));
$client->id_number = trim(Input::get('id_number'));
$client->vat_number = trim(Input::get('vat_number'));
$client->work_phone = trim(Input::get('work_phone'));
$client->custom_value1 = trim(Input::get('custom_value1'));
$client->custom_value2 = trim(Input::get('custom_value2'));
$client->address1 = trim(Input::get('address1'));
$client->address2 = trim(Input::get('address2'));
$client->city = trim(Input::get('city'));
$client->state = trim(Input::get('state'));
$client->postal_code = trim(Input::get('postal_code'));
$client->country_id = Input::get('country_id') ?: null;
$client->private_notes = trim(Input::get('private_notes'));
$client->size_id = Input::get('size_id') ?: null;
$client->industry_id = Input::get('industry_id') ?: null;
$client->currency_id = Input::get('currency_id') ?: null;
$client->payment_terms = Input::get('payment_terms') ?: 0;
$client->website = trim(Input::get('website'));
$client->save();
$data = json_decode(Input::get('data'));
$contactIds = [];
$isPrimary = true;
foreach ($data->contacts as $contact) {
if (isset($contact->public_id) && $contact->public_id) {
$record = Contact::scope($contact->public_id)->firstOrFail();
} else {
$record = Contact::createNew();
}
$record->email = trim(strtolower($contact->email));
$record->first_name = trim($contact->first_name);
$record->last_name = trim($contact->last_name);
$record->phone = trim($contact->phone);
$record->is_primary = $isPrimary;
$isPrimary = false;
$client->contacts()->save($record);
$contactIds[] = $record->public_id;
}
foreach ($client->contacts as $contact) {
if (!in_array($contact->public_id, $contactIds)) {
$contact->delete();
}
}
if ($publicId) {
Session::flash('message', trans('texts.updated_client'));
} else {
Activity::createClient($client);
Session::flash('message', trans('texts.created_client'));
}
return Redirect::to('clients/'.$client->public_id);
}
}
public function bulk()
{
$action = Input::get('action');
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
$count = $this->clientRepo->bulk($ids, $action);
$message = Utils::pluralize($action.'d_client', $count);
Session::flash('message', $message);
if ($action == 'restore' && $count == 1) {
return Redirect::to('clients/'.$ids[0]);
} else {
return Redirect::to('clients');
}
}
}

View File

@ -1,149 +0,0 @@
<?php
use ninja\repositories\CreditRepository;
class CreditController extends \BaseController
{
protected $creditRepo;
public function __construct(CreditRepository $creditRepo)
{
parent::__construct();
$this->creditRepo = $creditRepo;
}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return View::make('list', array(
'entityType' => ENTITY_CREDIT,
'title' => trans('texts.credits'),
'columns' => Utils::trans(['checkbox', 'client', 'credit_amount', 'credit_balance', 'credit_date', 'private_notes', 'action']),
));
}
public function getDatatable($clientPublicId = null)
{
$credits = $this->creditRepo->find($clientPublicId, Input::get('sSearch'));
$table = Datatable::query($credits);
if (!$clientPublicId) {
$table->addColumn('checkbox', function ($model) { return '<input type="checkbox" name="ids[]" value="'.$model->public_id.'" '.Utils::getEntityRowClass($model).'>'; })
->addColumn('client_name', function ($model) { return link_to('clients/'.$model->client_public_id, Utils::getClientDisplayName($model)); });
}
return $table->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id).'<span '.Utils::getEntityRowClass($model).'/>'; })
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
->addColumn('credit_date', function ($model) { return Utils::fromSqlDate($model->credit_date); })
->addColumn('private_notes', function ($model) { return $model->private_notes; })
->addColumn('dropdown', function ($model) {
if ($model->is_deleted) {
return '<div style="height:38px"/>';
}
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
if (!$model->deleted_at || $model->deleted_at == '0000-00-00') {
$str .= '<li><a href="javascript:archiveEntity('.$model->public_id.')">'.trans('texts.archive_credit').'</a></li>';
} else {
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans('texts.restore_credit').'</a></li>';
}
return $str.'<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans('texts.delete_credit').'</a></li></ul>
</div>';
})
->make();
}
public function create($clientPublicId = 0)
{
$data = array(
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
//'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : $invoicePublicId,
'credit' => null,
'method' => 'POST',
'url' => 'credits',
'title' => trans('texts.new_credit'),
//'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
//'invoices' => Invoice::scope()->with('client', 'invoice_status')->orderBy('invoice_number')->get(),
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
return View::make('credits.edit', $data);
}
public function edit($publicId)
{
$credit = Credit::scope($publicId)->firstOrFail();
$credit->credit_date = Utils::fromSqlDate($credit->credit_date);
$data = array(
'client' => null,
'credit' => $credit,
'method' => 'PUT',
'url' => 'credits/'.$publicId,
'title' => 'Edit Credit',
//'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
return View::make('credit.edit', $data);
}
public function store()
{
return $this->save();
}
public function update($publicId)
{
return $this->save($publicId);
}
private function save($publicId = null)
{
$rules = array(
'client' => 'required',
'amount' => 'required|positive',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
$url = $publicId ? 'credits/'.$publicId.'/edit' : 'credits/create';
return Redirect::to($url)
->withErrors($validator)
->withInput();
} else {
$this->creditRepo->save($publicId, Input::all());
$message = trans('texts.created_credit');
Session::flash('message', $message);
return Redirect::to('clients/'.Input::get('client'));
}
}
public function bulk()
{
$action = Input::get('action');
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
$count = $this->creditRepo->bulk($ids, $action);
if ($count > 0) {
$message = Utils::pluralize($action.'d_credit', $count);
Session::flash('message', $message);
}
return Redirect::to('credits');
}
}

View File

@ -1,79 +0,0 @@
<?php
class DashboardController extends \BaseController
{
public function index()
{
// total_income, billed_clients, invoice_sent and active_clients
$select = DB::raw('COUNT(DISTINCT CASE WHEN invoices.id IS NOT NULL THEN clients.id ELSE null END) billed_clients,
SUM(CASE WHEN invoices.invoice_status_id >= '.INVOICE_STATUS_SENT.' THEN 1 ELSE 0 END) invoices_sent,
COUNT(DISTINCT clients.id) active_clients');
$metrics = DB::table('accounts')
->select($select)
->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')
->leftJoin('invoices', 'clients.id', '=', 'invoices.client_id')
->where('accounts.id', '=', Auth::user()->account_id)
->where('clients.is_deleted', '=', false)
->where('invoices.is_deleted', '=', false)
->where('invoices.is_recurring', '=', false)
->where('invoices.is_quote', '=', false)
->groupBy('accounts.id')
->first();
$select = DB::raw('SUM(clients.paid_to_date) as value, clients.currency_id as currency_id');
$paidToDate = DB::table('accounts')
->select($select)
->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')
->where('accounts.id', '=', Auth::user()->account_id)
->where('clients.is_deleted', '=', false)
->groupBy('accounts.id')
->groupBy(DB::raw('CASE WHEN clients.currency_id IS NULL THEN CASE WHEN accounts.currency_id IS NULL THEN 1 ELSE accounts.currency_id END ELSE clients.currency_id END'))
->get();
$select = DB::raw('AVG(invoices.amount) as invoice_avg, clients.currency_id as currency_id');
$averageInvoice = DB::table('accounts')
->select($select)
->leftJoin('clients', 'accounts.id', '=', 'clients.account_id')
->leftJoin('invoices', 'clients.id', '=', 'invoices.client_id')
->where('accounts.id', '=', Auth::user()->account_id)
->where('clients.is_deleted', '=', false)
->where('invoices.is_deleted', '=', false)
->groupBy('accounts.id')
->groupBy(DB::raw('CASE WHEN clients.currency_id IS NULL THEN CASE WHEN accounts.currency_id IS NULL THEN 1 ELSE accounts.currency_id END ELSE clients.currency_id END'))
->get();
$activities = Activity::where('activities.account_id', '=', Auth::user()->account_id)
->orderBy('created_at', 'desc')->take(6)->get();
$pastDue = Invoice::scope()
->where('due_date', '<', date('Y-m-d'))
->where('balance', '>', 0)
->where('is_recurring', '=', false)
->where('is_quote', '=', false)
->where('is_deleted', '=', false)
->orderBy('due_date', 'asc')->take(6)->get();
$upcoming = Invoice::scope()
->where('due_date', '>=', date('Y-m-d'))
->where('balance', '>', 0)
->where('is_recurring', '=', false)
->where('is_quote', '=', false)
->where('is_deleted', '=', false)
->orderBy('due_date', 'asc')->take(6)->get();
$data = [
'paidToDate' => $paidToDate,
'averageInvoice' => $averageInvoice,
'billedClients' => $metrics ? $metrics->billed_clients : 0,
'invoicesSent' => $metrics ? $metrics->invoices_sent : 0,
'activeClients' => $metrics ? $metrics->active_clients : 0,
'activities' => $activities,
'pastDue' => $pastDue,
'upcoming' => $upcoming,
];
return View::make('dashboard', $data);
}
}

View File

@ -1,68 +0,0 @@
<?php
use ninja\mailers\Mailer;
class HomeController extends BaseController
{
protected $mailer;
public function __construct(Mailer $mailer)
{
parent::__construct();
$this->mailer = $mailer;
}
public function showIndex()
{
if (!Utils::isDatabaseSetup()) {
return Redirect::to('/setup');
} elseif (Account::count() == 0) {
return Redirect::to('/invoice_now');
} else {
return Redirect::to('/login');
}
}
public function showTerms()
{
return View::make('public.terms', ['hideHeader' => true]);
}
public function invoiceNow()
{
if (Auth::check()) {
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
} else {
return View::make('public.header', ['invoiceNow' => true]);
}
}
public function newsFeed($userType, $version)
{
$response = Utils::getNewsFeedResponse($userType);
return Response::json($response);
}
public function hideMessage()
{
if (Auth::check() && Session::has('news_feed_id')) {
$newsFeedId = Session::get('news_feed_id');
if ($newsFeedId != NEW_VERSION_AVAILABLE && $newsFeedId > Auth::user()->news_feed_id) {
$user = Auth::user();
$user->news_feed_id = $newsFeedId;
$user->save();
}
Session::forget('news_feed_message');
}
return 'success';
}
public function logError()
{
return Utils::logError(Input::get('error'), 'JavaScript');
}
}

View File

@ -1,26 +0,0 @@
<?php
class IntegrationController extends Controller
{
public function subscribe()
{
$eventId = Utils::lookupEventId(trim(Input::get('event')));
if (!$eventId) {
return Response::json('', 500);
}
$subscription = Subscription::where('account_id', '=', Auth::user()->account_id)->where('event_id', '=', $eventId)->first();
if (!$subscription) {
$subscription = new Subscription();
$subscription->account_id = Auth::user()->account_id;
$subscription->event_id = $eventId;
}
$subscription->target_url = trim(Input::get('target_url'));
$subscription->save();
return Response::json('{"id":'.$subscription->id.'}', 201);
}
}

View File

@ -1,192 +0,0 @@
<?php
use ninja\repositories\InvoiceRepository;
use ninja\mailers\ContactMailer as Mailer;
class InvoiceApiController extends Controller
{
protected $invoiceRepo;
public function __construct(InvoiceRepository $invoiceRepo, Mailer $mailer)
{
$this->invoiceRepo = $invoiceRepo;
$this->mailer = $mailer;
}
public function index()
{
$invoices = Invoice::scope()->where('invoices.is_quote', '=', false)->orderBy('created_at', 'desc')->get();
$invoices = Utils::remapPublicIds($invoices->toArray());
$response = json_encode($invoices, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($invoices));
return Response::make($response, 200, $headers);
}
public function store()
{
$data = Input::all();
$error = null;
// check if the invoice number is set and unique
if (!isset($data['invoice_number'])) {
$data['invoice_number'] = Auth::user()->account->getNextInvoiceNumber();
} else {
$invoice = Invoice::scope()->where('invoice_number', '=', $data['invoice_number'])->first();
if ($invoice) {
$error = trans('validation.unique', ['attribute' => 'texts.invoice_number']);
}
}
// check the client id is set and exists
if (!isset($data['client_id'])) {
$error = trans('validation.required', ['attribute' => 'client_id']);
} else {
$client = Client::scope($data['client_id'])->first();
if (!$client) {
$error = trans('validation.not_in', ['attribute' => 'client_id']);
}
}
if ($error) {
$response = json_encode($error, JSON_PRETTY_PRINT);
} else {
$data = self::prepareData($data);
$invoice = $this->invoiceRepo->save(false, $data, false);
$invitation = Invitation::createNew();
$invitation->invoice_id = $invoice->id;
$invitation->contact_id = $client->contacts[0]->id;
$invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
$invitation->save();
// prepare the return data
$invoice->load('invoice_items');
$invoice = $invoice->toArray();
$invoice['link'] = $invitation->getLink();
unset($invoice['account']);
unset($invoice['client']);
$invoice = Utils::remapPublicIds($invoice);
$invoice['client_id'] = $client->public_id;
$response = json_encode($invoice, JSON_PRETTY_PRINT);
}
$headers = Utils::getApiHeaders();
return Response::make($response, $error ? 400 : 200, $headers);
}
private function prepareData($data)
{
$account = Auth::user()->account;
$account->loadLocalizationSettings();
// set defaults for optional fields
$fields = [
'discount' => 0,
'is_amount_discount' => false,
'terms' => '',
'invoice_footer' => '',
'public_notes' => '',
'po_number' => '',
'invoice_design_id' => $account->invoice_design_id,
'invoice_items' => [],
'custom_value1' => 0,
'custom_value2' => 0,
'custom_taxes1' => false,
'custom_taxes2' => false,
];
if (!isset($data['invoice_date'])) {
$fields['invoice_date_sql'] = date_create()->format('Y-m-d');
}
if (!isset($data['due_date'])) {
$fields['due_date_sql'] = false;
}
foreach ($fields as $key => $val) {
if (!isset($data[$key])) {
$data[$key] = $val;
}
}
// hardcode some fields
$fields = [
'is_recurring' => false
];
foreach ($fields as $key => $val) {
$data[$key] = $val;
}
// initialize the line items
if (isset($data['product_key']) || isset($data['cost']) || isset($data['notes']) || isset($data['qty'])) {
$data['invoice_items'] = [self::prepareItem($data)];
} else {
foreach ($data['invoice_items'] as $index => $item) {
$data['invoice_items'][$index] = self::prepareItem($item);
}
}
return $data;
}
private function prepareItem($item)
{
$fields = [
'cost' => 0,
'product_key' => '',
'notes' => '',
'qty' => 1
];
foreach ($fields as $key => $val) {
if (!isset($item[$key])) {
$item[$key] = $val;
}
}
// if only the product key is set we'll load the cost and notes
if ($item['product_key'] && (!$item['cost'] || !$item['notes'])) {
$product = Product::findProductByKey($item['product_key']);
if ($product) {
if (!$item['cost']) {
$item['cost'] = $product->cost;
}
if (!$item['notes']) {
$item['notes'] = $product->notes;
}
}
}
return $item;
}
public function emailInvoice()
{
$data = Input::all();
$error = null;
if (!isset($data['id'])) {
$error = trans('validation.required', ['attribute' => 'id']);
} else {
$invoice = Invoice::scope($data['id'])->first();
if (!$invoice) {
$error = trans('validation.not_in', ['attribute' => 'id']);
} else {
$this->mailer->sendInvoice($invoice);
}
}
if ($error) {
$response = json_encode($error, JSON_PRETTY_PRINT);
} else {
$response = json_encode(RESULT_SUCCESS, JSON_PRETTY_PRINT);
}
$headers = Utils::getApiHeaders();
return Response::make($response, $error ? 400 : 200, $headers);
}
}

View File

@ -1,542 +0,0 @@
<?php
use ninja\mailers\ContactMailer as Mailer;
use ninja\repositories\InvoiceRepository;
use ninja\repositories\ClientRepository;
use ninja\repositories\TaxRateRepository;
class InvoiceController extends \BaseController
{
protected $mailer;
protected $invoiceRepo;
protected $clientRepo;
protected $taxRateRepo;
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, TaxRateRepository $taxRateRepo)
{
parent::__construct();
$this->mailer = $mailer;
$this->invoiceRepo = $invoiceRepo;
$this->clientRepo = $clientRepo;
$this->taxRateRepo = $taxRateRepo;
}
public function index()
{
$data = [
'title' => trans('texts.invoices'),
'entityType' => ENTITY_INVOICE,
'columns' => Utils::trans(['checkbox', 'invoice_number', 'client', 'invoice_date', 'invoice_total', 'balance_due', 'due_date', 'status', 'action']),
];
$recurringInvoices = Invoice::scope()->where('is_recurring', '=', true);
if (Session::get('show_trash:invoice')) {
$recurringInvoices->withTrashed();
}
if ($recurringInvoices->count() > 0) {
$data['secEntityType'] = ENTITY_RECURRING_INVOICE;
$data['secColumns'] = Utils::trans(['checkbox', 'frequency', 'client', 'start_date', 'end_date', 'invoice_total', 'action']);
}
return View::make('list', $data);
}
public function clientIndex()
{
$invitationKey = Session::get('invitation_key');
if (!$invitationKey) {
return Redirect::to('/setup');
}
$invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first();
$color = $invitation->account->primary_color ? $invitation->account->primary_color : '#0b4d78';
$data = [
'color' => $color,
'hideLogo' => Session::get('white_label'),
'title' => trans('texts.invoices'),
'entityType' => ENTITY_INVOICE,
'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']),
];
return View::make('public_list', $data);
}
public function getDatatable($clientPublicId = null)
{
$accountId = Auth::user()->account_id;
$search = Input::get('sSearch');
return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_INVOICE, $search);
}
public function getClientDatatable()
{
//$accountId = Auth::user()->account_id;
$search = Input::get('sSearch');
$invitationKey = Session::get('invitation_key');
$invitation = Invitation::where('invitation_key', '=', $invitationKey)->first();
if (!$invitation || $invitation->is_deleted) {
return [];
}
$invoice = $invitation->invoice;
if (!$invoice || $invoice->is_deleted) {
return [];
}
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_INVOICE, $search);
}
public function getRecurringDatatable($clientPublicId = null)
{
$query = $this->invoiceRepo->getRecurringInvoices(Auth::user()->account_id, $clientPublicId, Input::get('sSearch'));
$table = Datatable::query($query);
if (!$clientPublicId) {
$table->addColumn('checkbox', function ($model) { return '<input type="checkbox" name="ids[]" value="'.$model->public_id.'" '.Utils::getEntityRowClass($model).'>'; });
}
$table->addColumn('frequency', function ($model) { return link_to('invoices/'.$model->public_id, $model->frequency); });
if (!$clientPublicId) {
$table->addColumn('client_name', function ($model) { return link_to('clients/'.$model->client_public_id, Utils::getClientDisplayName($model)); });
}
return $table->addColumn('start_date', function ($model) { return Utils::fromSqlDate($model->start_date); })
->addColumn('end_date', function ($model) { return Utils::fromSqlDate($model->end_date); })
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
->addColumn('dropdown', function ($model) {
if ($model->is_deleted) {
return '<div style="height:38px"/>';
}
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
if (!$model->deleted_at || $model->deleted_at == '0000-00-00') {
$str .= '<li><a href="'.URL::to('invoices/'.$model->public_id.'/edit').'">'.trans('texts.edit_invoice').'</a></li>
<li class="divider"></li>
<li><a href="javascript:archiveEntity('.$model->public_id.')">'.trans('texts.archive_invoice').'</a></li>
<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans('texts.delete_invoice').'</a></li>';
} else {
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans('texts.restore_invoice').'</a></li>';
}
return $str.'</ul>
</div>';
})
->make();
}
public function view($invitationKey)
{
$invitation = Invitation::where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
if (!$invoice || $invoice->is_deleted) {
return View::make('invoices.deleted');
}
$invoice->load('user', 'invoice_items', 'invoice_design', 'account.country', 'client.contacts', 'client.country');
$client = $invoice->client;
if (!$client || $client->is_deleted) {
return View::make('invoices.deleted');
}
if (!Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) {
Activity::viewInvoice($invitation);
Event::fire('invoice.viewed', $invoice);
}
Session::set($invitationKey, true);
Session::set('invitation_key', $invitationKey);
Session::set('white_label', $client->account->isWhiteLabel());
$client->account->loadLocalizationSettings();
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
$invoice->due_date = Utils::fromSqlDate($invoice->due_date);
$invoice->is_pro = $client->account->isPro();
$contact = $invitation->contact;
$contact->setVisible([
'first_name',
'last_name',
'email',
'phone', ]);
$data = array(
'isConverted' => $invoice->quote_invoice_id ? true : false,
'showBreadcrumbs' => false,
'hideLogo' => $client->account->isWhiteLabel(),
'invoice' => $invoice->hidePrivateFields(),
'invitation' => $invitation,
'invoiceLabels' => $client->account->getInvoiceLabels(),
'contact' => $contact,
'hasToken' => $client->getGatewayToken(),
'countGateways' => AccountGateway::scope(false, $client->account->id)->count(),
);
return View::make('invoices.view', $data);
}
public function edit($publicId, $clone = false)
{
$invoice = Invoice::scope($publicId)->withTrashed()->with('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items')->firstOrFail();
$entityType = $invoice->getEntityType();
$contactIds = DB::table('invitations')
->join('contacts', 'contacts.id', '=', 'invitations.contact_id')
->where('invitations.invoice_id', '=', $invoice->id)
->where('invitations.account_id', '=', Auth::user()->account_id)
->where('invitations.deleted_at', '=', null)
->select('contacts.public_id')->lists('public_id');
if ($clone) {
$invoice->id = null;
$invoice->invoice_number = Auth::user()->account->getNextInvoiceNumber($invoice->is_quote);
$invoice->balance = $invoice->amount;
$invoice->invoice_status_id = 0;
$invoice->invoice_date = date_create()->format('Y-m-d');
$method = 'POST';
$url = "{$entityType}s";
} else {
Utils::trackViewed($invoice->invoice_number.' - '.$invoice->client->getDisplayName(), $invoice->getEntityType());
$method = 'PUT';
$url = "{$entityType}s/{$publicId}";
}
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
$invoice->due_date = Utils::fromSqlDate($invoice->due_date);
$invoice->start_date = Utils::fromSqlDate($invoice->start_date);
$invoice->end_date = Utils::fromSqlDate($invoice->end_date);
$invoice->is_pro = Auth::user()->isPro();
$data = array(
'entityType' => $entityType,
'showBreadcrumbs' => $clone,
'account' => $invoice->account,
'invoice' => $invoice,
'data' => false,
'method' => $method,
'invitationContactIds' => $contactIds,
'url' => $url,
'title' => trans("texts.edit_{$entityType}"),
'client' => $invoice->client, );
$data = array_merge($data, self::getViewModel());
// Set the invitation link on the client's contacts
if (!$clone) {
$clients = $data['clients'];
foreach ($clients as $client) {
if ($client->id == $invoice->client->id) {
foreach ($invoice->invitations as $invitation) {
foreach ($client->contacts as $contact) {
if ($invitation->contact_id == $contact->id) {
$contact->invitation_link = $invitation->getLink();
}
}
}
break;
}
}
}
return View::make('invoices.edit', $data);
}
public function create($clientPublicId = 0)
{
$client = null;
$invoiceNumber = Auth::user()->account->getNextInvoiceNumber();
$account = Account::with('country')->findOrFail(Auth::user()->account_id);
if ($clientPublicId) {
$client = Client::scope($clientPublicId)->firstOrFail();
}
$data = array(
'entityType' => ENTITY_INVOICE,
'account' => $account,
'invoice' => null,
'data' => Input::old('data'),
'invoiceNumber' => $invoiceNumber,
'method' => 'POST',
'url' => 'invoices',
'title' => trans('texts.new_invoice'),
'client' => $client, );
$data = array_merge($data, self::getViewModel());
return View::make('invoices.edit', $data);
}
private static function getViewModel()
{
$recurringHelp = '';
foreach (preg_split("/((\r?\n)|(\r\n?))/", trans('texts.recurring_help')) as $line) {
$parts = explode("=>", $line);
if (count($parts) > 1) {
$line = $parts[0].' => '.Utils::processVariables($parts[0]);
$recurringHelp .= '<li>'.strip_tags($line).'</li>';
} else {
$recurringHelp .= $line;
}
}
return [
'account' => Auth::user()->account,
'products' => Product::scope()->orderBy('id')->get(array('product_key', 'notes', 'cost', 'qty')),
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'clients' => Client::scope()->with('contacts', 'country')->orderBy('name')->get(),
'taxRates' => TaxRate::scope()->orderBy('name')->get(),
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'sizes' => Size::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE, 'invoice_designs_cache_'.Auth::user()->maxInvoiceDesignId())
->where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get(),
'frequencies' => array(
1 => 'Weekly',
2 => 'Two weeks',
3 => 'Four weeks',
4 => 'Monthly',
5 => 'Three months',
6 => 'Six months',
7 => 'Annually',
),
'recurringHelp' => $recurringHelp
];
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
return InvoiceController::save();
}
private function save($publicId = null)
{
$action = Input::get('action');
$entityType = Input::get('entityType');
if (in_array($action, ['archive', 'delete', 'mark', 'restore'])) {
return InvoiceController::bulk($entityType);
}
$input = json_decode(Input::get('data'));
$invoice = $input->invoice;
if ($errors = $this->invoiceRepo->getErrors($invoice)) {
Session::flash('error', trans('texts.invoice_error'));
return Redirect::to("{$entityType}s/create")
->withInput()->withErrors($errors);
} else {
$this->taxRateRepo->save($input->tax_rates);
$clientData = (array) $invoice->client;
$client = $this->clientRepo->save($invoice->client->public_id, $clientData);
$invoiceData = (array) $invoice;
$invoiceData['client_id'] = $client->id;
$invoice = $this->invoiceRepo->save($publicId, $invoiceData, $entityType);
$account = Auth::user()->account;
if ($account->invoice_taxes != $input->invoice_taxes
|| $account->invoice_item_taxes != $input->invoice_item_taxes
|| $account->invoice_design_id != $input->invoice->invoice_design_id) {
$account->invoice_taxes = $input->invoice_taxes;
$account->invoice_item_taxes = $input->invoice_item_taxes;
$account->invoice_design_id = $input->invoice->invoice_design_id;
$account->save();
}
$client->load('contacts');
$sendInvoiceIds = [];
foreach ($client->contacts as $contact) {
if ($contact->send_invoice || count($client->contacts) == 1) {
$sendInvoiceIds[] = $contact->id;
}
}
foreach ($client->contacts as $contact) {
$invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first();
if (in_array($contact->id, $sendInvoiceIds) && !$invitation) {
$invitation = Invitation::createNew();
$invitation->invoice_id = $invoice->id;
$invitation->contact_id = $contact->id;
$invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
$invitation->save();
} elseif (!in_array($contact->id, $sendInvoiceIds) && $invitation) {
$invitation->delete();
}
}
$message = trans($publicId ? "texts.updated_{$entityType}" : "texts.created_{$entityType}");
if ($input->invoice->client->public_id == '-1') {
$message = $message.' '.trans('texts.and_created_client');
$url = URL::to('clients/'.$client->public_id);
Utils::trackViewed($client->getDisplayName(), ENTITY_CLIENT, $url);
}
if ($action == 'clone') {
return $this->cloneInvoice($publicId);
} elseif ($action == 'convert') {
return $this->convertQuote($publicId);
} elseif ($action == 'email') {
if (Auth::user()->confirmed && !Auth::user()->isDemo()) {
$message = trans("texts.emailed_{$entityType}");
$this->mailer->sendInvoice($invoice);
Session::flash('message', $message);
} else {
$errorMessage = trans(Auth::user()->registered ? 'texts.confirmation_required' : 'texts.registration_required');
Session::flash('error', $errorMessage);
Session::flash('message', $message);
}
} else {
Session::flash('message', $message);
}
$url = "{$entityType}s/".$invoice->public_id.'/edit';
return Redirect::to($url);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($publicId)
{
Session::reflash();
return Redirect::to('invoices/'.$publicId.'/edit');
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($publicId)
{
return InvoiceController::save($publicId);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function bulk($entityType = ENTITY_INVOICE)
{
$action = Input::get('action');
$statusId = Input::get('statusId', INVOICE_STATUS_SENT);
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
$count = $this->invoiceRepo->bulk($ids, $action, $statusId);
if ($count > 0) {
$key = $action == 'mark' ? "updated_{$entityType}" : "{$action}d_{$entityType}";
$message = Utils::pluralize($key, $count);
Session::flash('message', $message);
}
if ($action == 'restore' && $count == 1) {
return Redirect::to("{$entityType}s/".$ids[0]);
} else {
return Redirect::to("{$entityType}s");
}
}
public function convertQuote($publicId)
{
$invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail();
$clone = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
Session::flash('message', trans('texts.converted_to_invoice'));
return Redirect::to('invoices/'.$clone->public_id);
}
public function cloneInvoice($publicId)
{
/*
$invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail();
$clone = $this->invoiceRepo->cloneInvoice($invoice);
$entityType = $invoice->getEntityType();
Session::flash('message', trans('texts.cloned_invoice'));
return Redirect::to("{$entityType}s/" . $clone->public_id);
*/
return self::edit($publicId, true);
}
public function invoiceHistory($publicId)
{
$invoice = Invoice::withTrashed()->scope($publicId)->firstOrFail();
$invoice->load('user', 'invoice_items', 'account.country', 'client.contacts', 'client.country');
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
$invoice->due_date = Utils::fromSqlDate($invoice->due_date);
$invoice->is_pro = Auth::user()->isPro();
$invoice->is_quote = intval($invoice->is_quote);
$activityTypeId = $invoice->is_quote ? ACTIVITY_TYPE_UPDATE_QUOTE : ACTIVITY_TYPE_UPDATE_INVOICE;
$activities = Activity::scope(false, $invoice->account_id)
->where('activity_type_id', '=', $activityTypeId)
->where('invoice_id', '=', $invoice->id)
->orderBy('id', 'desc')
->get(['id', 'created_at', 'user_id', 'json_backup', 'message']);
$versionsJson = [];
$versionsSelect = [];
$lastId = false;
foreach ($activities as $activity) {
$backup = json_decode($activity->json_backup);
$backup->invoice_date = Utils::fromSqlDate($backup->invoice_date);
$backup->due_date = Utils::fromSqlDate($backup->due_date);
$backup->is_pro = Auth::user()->isPro();
$backup->is_quote = isset($backup->is_quote) && intval($backup->is_quote);
$backup->account = $invoice->account->toArray();
$versionsJson[$activity->id] = $backup;
$key = Utils::timestampToDateTimeString(strtotime($activity->created_at)) . ' - ' . Utils::decodeActivity($activity->message);
$versionsSelect[$lastId ? $lastId : 0] = $key;
$lastId = $activity->id;
}
$versionsSelect[$lastId] = Utils::timestampToDateTimeString(strtotime($invoice->created_at)) . ' - ' . $invoice->user->getDisplayName();
$data = [
'invoice' => $invoice,
'versionsJson' => json_encode($versionsJson),
'versionsSelect' => $versionsSelect,
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE, 'invoice_designs_cache_'.Auth::user()->maxInvoiceDesignId())->where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get(),
];
return View::make('invoices.history', $data);
}
}

View File

@ -1,36 +0,0 @@
<?php
use ninja\repositories\PaymentRepository;
class PaymentApiController extends Controller
{
protected $paymentRepo;
public function __construct(PaymentRepository $paymentRepo)
{
$this->paymentRepo = $paymentRepo;
}
public function index()
{
$payments = Payment::scope()->orderBy('created_at', 'desc')->get();
$payments = Utils::remapPublicIds($payments->toArray());
$response = json_encode($payments, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($payments));
return Response::make($response, 200, $headers);
}
/*
public function store()
{
$data = Input::all();
$invoice = $this->invoiceRepo->save(false, $data, false);
$response = json_encode($invoice, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
*/
}

View File

@ -1,748 +0,0 @@
<?php
use ninja\repositories\PaymentRepository;
use ninja\repositories\InvoiceRepository;
use ninja\repositories\AccountRepository;
use ninja\mailers\ContactMailer;
class PaymentController extends \BaseController
{
protected $creditRepo;
public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo, ContactMailer $contactMailer)
{
parent::__construct();
$this->paymentRepo = $paymentRepo;
$this->invoiceRepo = $invoiceRepo;
$this->accountRepo = $accountRepo;
$this->contactMailer = $contactMailer;
}
public function index()
{
return View::make('list', array(
'entityType' => ENTITY_PAYMENT,
'title' => trans('texts.payments'),
'columns' => Utils::trans(['checkbox', 'invoice', 'client', 'transaction_reference', 'method', 'payment_amount', 'payment_date', 'action']),
));
}
public function clientIndex()
{
$invitationKey = Session::get('invitation_key');
if (!$invitationKey) {
return Redirect::to('/setup');
}
$invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first();
$color = $invitation->account->primary_color ? $invitation->account->primary_color : '#0b4d78';
$data = [
'color' => $color,
'hideLogo' => Session::get('white_label'),
'entityType' => ENTITY_PAYMENT,
'title' => trans('texts.payments'),
'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date'])
];
return View::make('public_list', $data);
}
public function getDatatable($clientPublicId = null)
{
$payments = $this->paymentRepo->find($clientPublicId, Input::get('sSearch'));
$table = Datatable::query($payments);
if (!$clientPublicId) {
$table->addColumn('checkbox', function ($model) { return '<input type="checkbox" name="ids[]" value="'.$model->public_id.'" '.Utils::getEntityRowClass($model).'>'; });
}
$table->addColumn('invoice_number', function ($model) { return $model->invoice_public_id ? link_to('invoices/'.$model->invoice_public_id.'/edit', $model->invoice_number, ['class' => Utils::getEntityRowClass($model)]) : ''; });
if (!$clientPublicId) {
$table->addColumn('client_name', function ($model) { return link_to('clients/'.$model->client_public_id, Utils::getClientDisplayName($model)); });
}
$table->addColumn('transaction_reference', function ($model) { return $model->transaction_reference ? $model->transaction_reference : '<i>Manual entry</i>'; })
->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? '<i>Online payment</i>' : ''); });
return $table->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); })
->addColumn('dropdown', function ($model) {
if ($model->is_deleted || $model->invoice_is_deleted) {
return '<div style="height:38px"/>';
}
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
if (!$model->deleted_at || $model->deleted_at == '0000-00-00') {
$str .= '<li><a href="payments/'.$model->public_id.'/edit">'.trans('texts.edit_payment').'</a></li>
<li class="divider"></li>
<li><a href="javascript:archiveEntity('.$model->public_id.')">'.trans('texts.archive_payment').'</a></li>';
} else {
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans('texts.restore_payment').'</a></li>';
}
return $str.'<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans('texts.delete_payment').'</a></li></ul>
</div>';
})
->make();
}
public function getClientDatatable()
{
$search = Input::get('sSearch');
$invitationKey = Session::get('invitation_key');
$invitation = Invitation::where('invitation_key', '=', $invitationKey)->with('contact.client')->first();
if (!$invitation) {
return [];
}
$invoice = $invitation->invoice;
if (!$invoice || $invoice->is_deleted) {
return [];
}
$payments = $this->paymentRepo->findForContact($invitation->contact->id, Input::get('sSearch'));
return Datatable::query($payments)
->addColumn('invoice_number', function ($model) { return $model->invitation_key ? link_to('/view/'.$model->invitation_key, $model->invoice_number) : $model->invoice_number; })
->addColumn('transaction_reference', function ($model) { return $model->transaction_reference ? $model->transaction_reference : '<i>Manual entry</i>'; })
->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? '<i>Online payment</i>' : ''); })
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); })
->make();
}
public function create($clientPublicId = 0, $invoicePublicId = 0)
{
$data = array(
'clientPublicId' => Input::old('client') ? Input::old('client') : $clientPublicId,
'invoicePublicId' => Input::old('invoice') ? Input::old('invoice') : $invoicePublicId,
'invoice' => null,
'invoices' => Invoice::scope()->where('is_recurring', '=', false)->where('is_quote', '=', false)
->with('client', 'invoice_status')->orderBy('invoice_number')->get(),
'payment' => null,
'method' => 'POST',
'url' => "payments",
'title' => trans('texts.new_payment'),
//'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'paymentTypes' => PaymentType::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
return View::make('payments.edit', $data);
}
public function edit($publicId)
{
$payment = Payment::scope($publicId)->firstOrFail();
$payment->payment_date = Utils::fromSqlDate($payment->payment_date);
$data = array(
'client' => null,
'invoice' => null,
'invoices' => Invoice::scope()->where('is_recurring', '=', false)->where('is_quote', '=', false)
->with('client', 'invoice_status')->orderBy('invoice_number')->get(),
'payment' => $payment,
'method' => 'PUT',
'url' => 'payments/'.$publicId,
'title' => trans('texts.edit_payment'),
//'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'paymentTypes' => PaymentType::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), );
return View::make('payments.edit', $data);
}
private function createGateway($accountGateway)
{
$gateway = Omnipay::create($accountGateway->gateway->provider);
$config = json_decode($accountGateway->config);
/*
$gateway->setSolutionType("Sole");
$gateway->setLandingPage("Billing");
*/
foreach ($config as $key => $val) {
if (!$val) {
continue;
}
$function = "set".ucfirst($key);
$gateway->$function($val);
}
if (Utils::isNinjaDev()) {
$gateway->setTestMode(true);
}
return $gateway;
}
private function getLicensePaymentDetails($input, $affiliate)
{
$data = self::convertInputForOmnipay($input);
$card = new CreditCard($data);
return [
'amount' => $affiliate->price,
'card' => $card,
'currency' => 'USD',
'returnUrl' => URL::to('license_complete'),
'cancelUrl' => URL::to('/')
];
}
private function convertInputForOmnipay($input)
{
return [
'firstName' => $input['first_name'],
'lastName' => $input['last_name'],
'number' => $input['card_number'],
'expiryMonth' => $input['expiration_month'],
'expiryYear' => $input['expiration_year'],
'cvv' => $input['cvv'],
'billingAddress1' => $input['address1'],
'billingAddress2' => $input['address2'],
'billingCity' => $input['city'],
'billingState' => $input['state'],
'billingPostcode' => $input['postal_code'],
'shippingAddress1' => $input['address1'],
'shippingAddress2' => $input['address2'],
'shippingCity' => $input['city'],
'shippingState' => $input['state'],
'shippingPostcode' => $input['postal_code']
];
}
private function getPaymentDetails($invitation, $input = null)
{
$invoice = $invitation->invoice;
$key = $invoice->invoice_number.'_details';
$gateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'))->gateway;
$paymentLibrary = $gateway->paymentlibrary;
$currencyCode = $invoice->client->currency ? $invoice->client->currency->code : ($invoice->account->currency ? $invoice->account->currency->code : 'USD');
if ($input && $paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
$data = self::convertInputForOmnipay($input);
Session::put($key, $data);
} elseif ($input && $paymentLibrary->id == PAYMENT_LIBRARY_PHP_PAYMENTS) {
$input = Input::all();
$data = [
'first_name' => $input['first_name'],
'last_name' => $input['last_name'],
'cc_number' => $input['card_number'],
'cc_exp' => $input['expiration_month'].$input['expiration_year'],
'cc_code' => $input['cvv'],
'street' => $input['address1'],
'street2' => $input['address2'],
'city' => $input['city'],
'state' => $input['state'],
'postal_code' => $input['postal_code'],
'amt' => $invoice->balance,
'ship_to_street' => $input['address1'],
'ship_to_city' => $input['city'],
'ship_to_state' => $input['state'],
'ship_to_postal_code' => $input['postal_code'],
'currency_code' => $currencyCode,
];
switch ($gateway->id) {
case GATEWAY_BEANSTREAM:
$data['phone'] = $input['phone'];
$data['email'] = $input['email'];
$data['country'] = $input['country'];
$data['ship_to_country'] = $input['country'];
break;
case GATEWAY_BRAINTREE:
$data['ship_to_state'] = 'Ohio'; //$input['state'];
break;
}
if (strlen($data['cc_exp']) == 5) {
$data['cc_exp'] = '0'.$data['cc_exp'];
}
Session::put($key, $data);
return $data;
} elseif (Session::get($key)) {
$data = Session::get($key);
} else {
$data = [];
}
if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
$card = new CreditCard($data);
return [
'amount' => $invoice->balance,
'card' => $card,
'currency' => $currencyCode,
'returnUrl' => URL::to('complete'),
'cancelUrl' => $invitation->getLink(),
'description' => trans('texts.' . $invoice->getEntityType()) . " {$invoice->invoice_number}",
];
} else {
return $data;
}
}
public function show_payment($invitationKey)
{
// Handle token billing
if (Input::get('use_token') == 'true') {
return self::do_payment($invitationKey, false, true);
}
if (Input::has('use_paypal')) {
Session::put('payment_type', Input::get('use_paypal') == 'true' ? PAYMENT_TYPE_PAYPAL : PAYMENT_TYPE_CREDIT_CARD);
} elseif (!Session::has('payment_type')) {
Session::put('payment_type', PAYMENT_TYPE_ANY);
}
// For PayPal we redirect straight to their site
$usePayPal = false;
if ($usePayPal = Input::get('use_paypal')) {
$usePayPal = $usePayPal == 'true';
} else {
$invitation = Invitation::with('invoice.client.account', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$account = $invitation->invoice->client->account;
if (count($account->account_gateways) == 1 && $account->getGatewayByType(PAYMENT_TYPE_PAYPAL)) {
$usePayPal = true;
}
}
if ($usePayPal) {
if (Session::has('error')) {
Session::reflash();
return Redirect::to('view/'.$invitationKey);
} else {
return self::do_payment($invitationKey, false);
}
}
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
$client = $invoice->client;
$accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'));
$gateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'))->gateway;
$paymentLibrary = $gateway->paymentlibrary;
$acceptedCreditCardTypes = $accountGateway->getCreditcardTypes();
$data = [
'showBreadcrumbs' => false,
'url' => 'payment/'.$invitationKey,
'amount' => $invoice->balance,
'invoiceNumber' => $invoice->invoice_number,
'client' => $client,
'contact' => $invitation->contact,
'paymentLibrary' => $paymentLibrary,
'gateway' => $gateway,
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'currencyId' => $client->currency_id,
'account' => $client->account
];
return View::make('payments.payment', $data);
}
public function show_license_payment()
{
if (Input::has('return_url')) {
Session::set('return_url', Input::get('return_url'));
}
if (Input::has('affiliate_key')) {
if ($affiliate = Affiliate::where('affiliate_key', '=', Input::get('affiliate_key'))->first()) {
Session::set('affiliate_id', $affiliate->id);
}
}
Session::set('product_id', Input::get('product_id', PRODUCT_ONE_CLICK_INSTALL));
if (!Session::get('affiliate_id')) {
return Utils::fatalError();
}
if (Utils::isNinjaDev() && Input::has('test_mode')) {
Session::set('test_mode', Input::get('test_mode'));
}
$account = $this->accountRepo->getNinjaAccount();
$account->load('account_gateways.gateway');
$accountGateway = $account->getGatewayByType(Session::get('payment_type'));
$gateway = $accountGateway->gateway;
$paymentLibrary = $gateway->paymentlibrary;
$acceptedCreditCardTypes = $accountGateway->getCreditcardTypes();
$affiliate = Affiliate::find(Session::get('affiliate_id'));
$data = [
'showBreadcrumbs' => false,
'hideHeader' => true,
'url' => 'license',
'amount' => $affiliate->price,
'client' => false,
'contact' => false,
'paymentLibrary' => $paymentLibrary,
'gateway' => $gateway,
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'currencyId' => 1,
'paymentTitle' => $affiliate->payment_title,
'paymentSubtitle' => $affiliate->payment_subtitle,
];
return View::make('payments.payment', $data);
}
public function do_license_payment()
{
$testMode = Session::get('test_mode') === 'true';
$rules = array(
'first_name' => 'required',
'last_name' => 'required',
'card_number' => 'required',
'expiration_month' => 'required',
'expiration_year' => 'required',
'cvv' => 'required',
'address1' => 'required',
'city' => 'required',
'state' => 'required',
'postal_code' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('license')
->withErrors($validator);
}
$account = $this->accountRepo->getNinjaAccount();
$account->load('account_gateways.gateway');
$accountGateway = $account->getGatewayByType(PAYMENT_TYPE_CREDIT_CARD);
try {
$affiliate = Affiliate::find(Session::get('affiliate_id'));
if ($testMode) {
$ref = 'TEST_MODE';
} else {
$gateway = self::createGateway($accountGateway);
$details = self::getLicensePaymentDetails(Input::all(), $affiliate);
$response = $gateway->purchase($details)->send();
$ref = $response->getTransactionReference();
if (!$ref) {
Session::flash('error', $response->getMessage());
return Redirect::to('license')->withInput();
}
if (!$response->isSuccessful()) {
Session::flash('error', $response->getMessage());
Utils::logError($response->getMessage());
return Redirect::to('license')->withInput();
}
}
$licenseKey = Utils::generateLicense();
$license = new License();
$license->first_name = Input::get('first_name');
$license->last_name = Input::get('last_name');
$license->email = Input::get('email');
$license->transaction_reference = $ref;
$license->license_key = $licenseKey;
$license->affiliate_id = Session::get('affiliate_id');
$license->product_id = Session::get('product_id');
$license->save();
$data = [
'message' => $affiliate->payment_subtitle,
'license' => $licenseKey,
'hideHeader' => true,
];
$name = "{$license->first_name} {$license->last_name}";
$this->contactMailer->sendLicensePaymentConfirmation($name, $license->email, $affiliate->price, $license->license_key, $license->product_id);
if (Session::has('return_url')) {
return Redirect::away(Session::get('return_url')."?license_key={$license->license_key}&product_id=".Session::get('product_id'));
} else {
return View::make('public.license', $data);
}
} catch (\Exception $e) {
$errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage);
Utils::logError(Utils::getErrorString($e));
return Redirect::to('license')->withInput();
}
}
public function claim_license()
{
$licenseKey = Input::get('license_key');
$productId = Input::get('product_id', PRODUCT_ONE_CLICK_INSTALL);
$license = License::where('license_key', '=', $licenseKey)
->where('is_claimed', '=', false)
->where('product_id', '=', $productId)
->first();
if ($license) {
if ($license->transaction_reference != 'TEST_MODE') {
$license->is_claimed = true;
$license->save();
}
return $productId == PRODUCT_INVOICE_DESIGNS ? $_ENV['INVOICE_DESIGNS'] : 'valid';
} else {
return 'invalid';
}
}
public function do_payment($invitationKey, $onSite = true, $useToken = false)
{
$rules = array(
'first_name' => 'required',
'last_name' => 'required',
'card_number' => 'required',
'expiration_month' => 'required',
'expiration_year' => 'required',
'cvv' => 'required',
'address1' => 'required',
'city' => 'required',
'state' => 'required',
'postal_code' => 'required',
);
if ($onSite) {
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('payment/'.$invitationKey)
->withErrors($validator);
}
}
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
$client = $invoice->client;
$account = $client->account;
$accountGateway = $account->getGatewayByType(Session::get('payment_type'));
$paymentLibrary = $accountGateway->gateway->paymentlibrary;
if ($onSite) {
$client->address1 = trim(Input::get('address1'));
$client->address2 = trim(Input::get('address2'));
$client->city = trim(Input::get('city'));
$client->state = trim(Input::get('state'));
$client->postal_code = trim(Input::get('postal_code'));
$client->save();
}
try {
if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
$gateway = self::createGateway($accountGateway);
$details = self::getPaymentDetails($invitation, $useToken || !$onSite ? false : Input::all());
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
if ($useToken) {
$details['cardReference'] = $client->getGatewayToken();
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing')) {
$tokenResponse = $gateway->createCard($details)->send();
$cardReference = $tokenResponse->getCardReference();
$details['cardReference'] = $cardReference;
$token = AccountGatewayToken::where('client_id', '=', $client->id)
->where('account_gateway_id', '=', $accountGateway->id)->first();
if (!$token) {
$token = new AccountGatewayToken();
$token->account_id = $account->id;
$token->contact_id = $invitation->contact_id;
$token->account_gateway_id = $accountGateway->id;
$token->client_id = $client->id;
}
$token->token = $cardReference;
$token->save();
}
}
$response = $gateway->purchase($details)->send();
$ref = $response->getTransactionReference();
if (!$ref) {
Session::flash('error', $response->getMessage());
if ($onSite) {
return Redirect::to('payment/'.$invitationKey)->withInput();
} else {
return Redirect::to('view/'.$invitationKey);
}
}
if ($response->isSuccessful()) {
$payment = self::createPayment($invitation, $ref);
Session::flash('message', trans('texts.applied_payment'));
return Redirect::to('view/'.$payment->invitation->invitation_key);
} elseif ($response->isRedirect()) {
$invitation->transaction_reference = $ref;
$invitation->save();
Session::save();
$response->redirect();
} else {
Session::flash('error', $response->getMessage());
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->getMessage());
}
}
} catch (\Exception $e) {
$errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage."<p>".$e->getMessage());
Utils::logError(Utils::getErrorString($e));
if ($onSite) {
return Redirect::to('payment/'.$invitationKey)->withInput();
} else {
return Redirect::to('view/'.$invitationKey);
}
}
}
private function createPayment($invitation, $ref, $payerId = null)
{
$invoice = $invitation->invoice;
$accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'));
if ($invoice->account->account_key == NINJA_ACCOUNT_KEY) {
$account = Account::find($invoice->client->public_id);
$account->pro_plan_paid = date_create()->format('Y-m-d');
$account->save();
}
$payment = Payment::createNew($invitation);
$payment->invitation_id = $invitation->id;
$payment->account_gateway_id = $accountGateway->id;
$payment->invoice_id = $invoice->id;
$payment->amount = $invoice->balance;
$payment->client_id = $invoice->client_id;
$payment->contact_id = $invitation->contact_id;
$payment->transaction_reference = $ref;
$payment->payment_date = date_create()->format('Y-m-d');
if ($payerId) {
$payment->payer_id = $payerId;
}
$payment->save();
Event::fire('invoice.paid', $payment);
return $payment;
}
public function offsite_payment()
{
$payerId = Request::query('PayerID');
$token = Request::query('token');
$invitation = Invitation::with('invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('transaction_reference', '=', $token)->firstOrFail();
$invoice = $invitation->invoice;
$accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'));
$gateway = self::createGateway($accountGateway);
try {
$details = self::getPaymentDetails($invitation);
$response = $gateway->completePurchase($details)->send();
$ref = $response->getTransactionReference();
if ($response->isSuccessful()) {
$payment = self::createPayment($invitation, $ref, $payerId);
Session::flash('message', trans('texts.applied_payment'));
return Redirect::to('view/'.$invitation->invitation_key);
} else {
$errorMessage = trans('texts.payment_error')."\n\n".$response->getMessage();
Session::flash('error', $errorMessage);
Utils::logError($errorMessage);
return Redirect::to('view/'.$invitation->invitation_key);
}
} catch (\Exception $e) {
$errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage);
Utils::logError($errorMessage."\n\n".$e->getMessage());
return Redirect::to('view/'.$invitation->invitation_key);
}
}
public function store()
{
return $this->save();
}
public function update($publicId)
{
return $this->save($publicId);
}
private function save($publicId = null)
{
if (!$publicId && $errors = $this->paymentRepo->getErrors(Input::all())) {
$url = $publicId ? 'payments/'.$publicId.'/edit' : 'payments/create';
return Redirect::to($url)
->withErrors($errors)
->withInput();
} else {
$this->paymentRepo->save($publicId, Input::all());
if ($publicId) {
Session::flash('message', trans('texts.updated_payment'));
return Redirect::to('payments/');
} else {
Session::flash('message', trans('texts.created_payment'));
return Redirect::to('clients/'.Input::get('client'));
}
}
}
public function bulk()
{
$action = Input::get('action');
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
$count = $this->paymentRepo->bulk($ids, $action);
if ($count > 0) {
$message = Utils::pluralize($action.'d_payment', $count);
Session::flash('message', $message);
}
return Redirect::to('payments');
}
}

View File

@ -1,96 +0,0 @@
<?php
class ProductController extends \BaseController
{
public function getDatatable()
{
$query = DB::table('products')
->where('products.account_id', '=', Auth::user()->account_id)
->where('products.deleted_at', '=', null)
->select('products.public_id', 'products.product_key', 'products.notes', 'products.cost');
return Datatable::query($query)
->addColumn('product_key', function ($model) { return link_to('products/'.$model->public_id.'/edit', $model->product_key); })
->addColumn('notes', function ($model) { return nl2br(Str::limit($model->notes, 100)); })
->addColumn('cost', function ($model) { return Utils::formatMoney($model->cost); })
->addColumn('dropdown', function ($model) {
return '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="'.URL::to('products/'.$model->public_id).'/edit">'.uctrans('texts.edit_product').'</a></li>
<li class="divider"></li>
<li><a href="'.URL::to('products/'.$model->public_id).'/archive">'.uctrans('texts.archive_product').'</a></li>
</ul>
</div>';
})
->orderColumns(['cost', 'product_key', 'cost'])
->make();
}
public function edit($publicId)
{
$data = [
'showBreadcrumbs' => false,
'product' => Product::scope($publicId)->firstOrFail(),
'method' => 'PUT',
'url' => 'products/'.$publicId,
'title' => trans('texts.edit_product'),
];
return View::make('accounts.product', $data);
}
public function create()
{
$data = [
'showBreadcrumbs' => false,
'product' => null,
'method' => 'POST',
'url' => 'products',
'title' => trans('texts.create_product'),
];
return View::make('accounts.product', $data);
}
public function store()
{
return $this->save();
}
public function update($publicId)
{
return $this->save($publicId);
}
private function save($productPublicId = false)
{
if ($productPublicId) {
$product = Product::scope($productPublicId)->firstOrFail();
} else {
$product = Product::createNew();
}
$product->product_key = trim(Input::get('product_key'));
$product->notes = trim(Input::get('notes'));
$product->cost = trim(Input::get('cost'));
$product->save();
$message = $productPublicId ? trans('texts.updated_product') : trans('texts.created_product');
Session::flash('message', $message);
return Redirect::to('company/products');
}
public function archive($publicId)
{
$product = Product::scope($publicId)->firstOrFail();
$product->delete();
Session::flash('message', trans('texts.archived_product'));
return Redirect::to('company/products');
}
}

View File

@ -1,36 +0,0 @@
<?php
use ninja\repositories\InvoiceRepository;
class QuoteApiController extends Controller
{
protected $invoiceRepo;
public function __construct(InvoiceRepository $invoiceRepo)
{
$this->invoiceRepo = $invoiceRepo;
}
public function index()
{
$invoices = Invoice::scope()->where('invoices.is_quote', '=', true)->orderBy('created_at', 'desc')->get();
$invoices = Utils::remapPublicIds($invoices->toArray());
$response = json_encode($invoices, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders(count($invoices));
return Response::make($response, 200, $headers);
}
/*
public function store()
{
$data = Input::all();
$invoice = $this->invoiceRepo->save(false, $data, false);
$response = json_encode($invoice, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
*/
}

View File

@ -1,187 +0,0 @@
<?php
use ninja\mailers\ContactMailer as Mailer;
use ninja\repositories\InvoiceRepository;
use ninja\repositories\ClientRepository;
use ninja\repositories\TaxRateRepository;
class QuoteController extends \BaseController
{
protected $mailer;
protected $invoiceRepo;
protected $clientRepo;
protected $taxRateRepo;
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, TaxRateRepository $taxRateRepo)
{
parent::__construct();
$this->mailer = $mailer;
$this->invoiceRepo = $invoiceRepo;
$this->clientRepo = $clientRepo;
$this->taxRateRepo = $taxRateRepo;
}
public function index()
{
if (!Utils::isPro()) {
return Redirect::to('/invoices/create');
}
$data = [
'title' => trans('texts.quotes'),
'entityType' => ENTITY_QUOTE,
'columns' => Utils::trans(['checkbox', 'quote_number', 'client', 'quote_date', 'quote_total', 'due_date', 'status', 'action']),
];
/*
if (Invoice::scope()->where('is_recurring', '=', true)->count() > 0)
{
$data['secEntityType'] = ENTITY_RECURRING_INVOICE;
$data['secColumns'] = Utils::trans(['checkbox', 'frequency', 'client', 'start_date', 'end_date', 'quote_total', 'action']);
}
*/
return View::make('list', $data);
}
public function clientIndex()
{
$invitationKey = Session::get('invitation_key');
if (!$invitationKey) {
return Redirect::to('/setup');
}
$invitation = Invitation::with('account')->where('invitation_key', '=', $invitationKey)->first();
$color = $invitation->account->primary_color ? $invitation->account->primary_color : '#0b4d78';
$data = [
'color' => $color,
'hideLogo' => Session::get('white_label'),
'title' => trans('texts.quotes'),
'entityType' => ENTITY_QUOTE,
'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']),
];
return View::make('public_list', $data);
}
public function getDatatable($clientPublicId = null)
{
$accountId = Auth::user()->account_id;
$search = Input::get('sSearch');
return $this->invoiceRepo->getDatatable($accountId, $clientPublicId, ENTITY_QUOTE, $search);
}
public function getClientDatatable()
{
$search = Input::get('sSearch');
$invitationKey = Session::get('invitation_key');
$invitation = Invitation::where('invitation_key', '=', $invitationKey)->first();
if (!$invitation || $invitation->is_deleted) {
return [];
}
$invoice = $invitation->invoice;
if (!$invoice || $invoice->is_deleted) {
return [];
}
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, $search);
}
public function create($clientPublicId = 0)
{
if (!Utils::isPro()) {
return Redirect::to('/invoices/create');
}
$client = null;
$invoiceNumber = Auth::user()->account->getNextInvoiceNumber(true);
$account = Account::with('country')->findOrFail(Auth::user()->account_id);
if ($clientPublicId) {
$client = Client::scope($clientPublicId)->firstOrFail();
}
$data = array(
'account' => $account,
'invoice' => null,
'data' => Input::old('data'),
'invoiceNumber' => $invoiceNumber,
'method' => 'POST',
'url' => 'invoices',
'title' => trans('texts.new_quote'),
'client' => $client, );
$data = array_merge($data, self::getViewModel());
return View::make('invoices.edit', $data);
}
private static function getViewModel()
{
return [
'entityType' => ENTITY_QUOTE,
'account' => Auth::user()->account,
'products' => Product::scope()->orderBy('id')->get(array('product_key', 'notes', 'cost', 'qty')),
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'clients' => Client::scope()->with('contacts', 'country')->orderBy('name')->get(),
'taxRates' => TaxRate::scope()->orderBy('name')->get(),
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'sizes' => Size::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE, 'invoice_designs_cache_'.Auth::user()->maxInvoiceDesignId())
->where('id', '<=', Auth::user()->maxInvoiceDesignId())->orderBy('id')->get(),
'invoiceLabels' => Auth::user()->account->getInvoiceLabels()
];
}
public function bulk()
{
$action = Input::get('action');
if ($action == 'convert') {
$invoice = Invoice::with('invoice_items')->scope(Input::get('id'))->firstOrFail();
$clone = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
Session::flash('message', trans('texts.converted_to_invoice'));
return Redirect::to('invoices/'.$clone->public_id);
}
$statusId = Input::get('statusId');
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
$count = $this->invoiceRepo->bulk($ids, $action, $statusId);
if ($count > 0) {
$key = $action == 'mark' ? "updated_quote" : "{$action}d_quote";
$message = Utils::pluralize($key, $count);
Session::flash('message', $message);
}
return Redirect::to('quotes');
}
public function approve($invitationKey)
{
$invitation = Invitation::with('invoice.invoice_items', 'invoice.invitations')->where('invitation_key', '=', $invitationKey)->firstOrFail();
$invoice = $invitation->invoice;
if ($invoice->is_quote && !$invoice->quote_invoice_id) {
Activity::approveQuote($invitation);
$invoice = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
Session::flash('message', trans('texts.converted_to_invoice'));
foreach ($invoice->invitations as $invitationClone) {
if ($invitation->contact_id == $invitationClone->contact_id) {
$invitationKey = $invitationClone->invitation_key;
}
}
}
return Redirect::to("view/{$invitationKey}");
}
}

View File

@ -1,127 +0,0 @@
<?php
class ReportController extends \BaseController
{
public function d3()
{
$message = '';
if (Auth::user()->account->isPro()) {
$account = Account::where('id', '=', Auth::user()->account->id)->with(['clients.invoices.invoice_items', 'clients.contacts'])->first();
$account = $account->hideFieldsForViz();
$clients = $account->clients->toJson();
} elseif (isset($_ENV['DATA_VIZ_SAMPLE'])) {
$clients = $_ENV['DATA_VIZ_SAMPLE'];
$message = trans('texts.sample_data');
} else {
$clients = '[]';
}
$data = [
'feature' => ACCOUNT_DATA_VISUALIZATIONS,
'clients' => $clients,
'message' => $message,
];
return View::make('reports.d3', $data);
}
public function report()
{
if (Input::all()) {
$groupBy = Input::get('group_by');
$chartType = Input::get('chart_type');
$startDate = Utils::toSqlDate(Input::get('start_date'), false);
$endDate = Utils::toSqlDate(Input::get('end_date'), false);
} else {
$groupBy = 'MONTH';
$chartType = 'Bar';
$startDate = Utils::today(false)->modify('-3 month');
$endDate = Utils::today(false);
}
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
$endDate->modify('+1 '.$padding);
$datasets = [];
$labels = [];
$maxTotals = 0;
$width = 10;
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) {
$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 = [
'DAYOFYEAR' => 'Daily',
'WEEK' => 'Weekly',
'MONTH' => 'Monthly',
];
$chartTypes = [
'Bar' => 'Bar',
'Line' => 'Line',
];
$params = [
'labels' => $labels,
'datasets' => $datasets,
'scaleStepWidth' => $width,
'dateTypes' => $dateTypes,
'chartTypes' => $chartTypes,
'chartType' => $chartType,
'startDate' => $startDate->format(Session::get(SESSION_DATE_FORMAT)),
'endDate' => $endDate->modify('-1'.$padding)->format(Session::get(SESSION_DATE_FORMAT)),
'groupBy' => $groupBy,
'feature' => ACCOUNT_CHART_BUILDER,
];
return View::make('reports.report_builder', $params);
}
}

View File

@ -1,93 +0,0 @@
<?php
class TimesheetController extends \BaseController {
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$data = [
'showBreadcrumbs' => false,
'timesheet' => [
'timesheet_number' => 1
]
];
return View::make('timesheets.edit', $data);
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
}

View File

@ -1,161 +0,0 @@
<?php
/*
|--------------------------------------------------------------------------
| Confide Controller Template
|--------------------------------------------------------------------------
|
| This is the default Confide controller template for controlling user
| authentication. Feel free to change to your needs.
|
*/
use ninja\repositories\AccountRepository;
class TokenController extends BaseController
{
public function getDatatable()
{
$query = DB::table('account_tokens')
->where('account_tokens.account_id', '=', Auth::user()->account_id);
if (!Session::get('show_trash:token')) {
$query->where('account_tokens.deleted_at', '=', null);
}
$query->select('account_tokens.public_id', 'account_tokens.name', 'account_tokens.token', 'account_tokens.public_id', 'account_tokens.deleted_at');
return Datatable::query($query)
->addColumn('name', function ($model) { return link_to('tokens/'.$model->public_id.'/edit', $model->name); })
->addColumn('token', function ($model) { return $model->token; })
->addColumn('dropdown', function ($model) {
$actions = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
if (!$model->deleted_at) {
$actions .= '<li><a href="'.URL::to('tokens/'.$model->public_id).'/edit">'.uctrans('texts.edit_token').'</a></li>
<li class="divider"></li>
<li><a href="javascript:deleteToken('.$model->public_id.')">'.uctrans('texts.delete_token').'</a></li>';
}
$actions .= '</ul>
</div>';
return $actions;
})
->orderColumns(['name', 'token'])
->make();
}
public function edit($publicId)
{
$token = AccountToken::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $publicId)->firstOrFail();
$data = [
'showBreadcrumbs' => false,
'token' => $token,
'method' => 'PUT',
'url' => 'tokens/'.$publicId,
'title' => trans('texts.edit_token'),
];
return View::make('accounts.token', $data);
}
public function update($publicId)
{
return $this->save($publicId);
}
public function store()
{
return $this->save();
}
/**
* Displays the form for account creation
*
*/
public function create()
{
if (!Auth::user()->confirmed) {
Session::flash('error', trans('texts.register_to_add_user'));
return Redirect::to('company/advanced_settings/user_management');
}
$data = [
'showBreadcrumbs' => false,
'token' => null,
'method' => 'POST',
'url' => 'tokens',
'title' => trans('texts.add_token'),
];
return View::make('accounts.token', $data);
}
public function delete()
{
$tokenPublicId = Input::get('tokenPublicId');
$token = AccountToken::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $tokenPublicId)->firstOrFail();
$token->delete();
Session::flash('message', trans('texts.deleted_token'));
return Redirect::to('company/advanced_settings/token_management');
}
/**
* Stores new account
*
*/
public function save($tokenPublicId = false)
{
if (Auth::user()->account->isPro()) {
$rules = [
'name' => 'required',
];
if ($tokenPublicId) {
$token = AccountToken::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $tokenPublicId)->firstOrFail();
}
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to($tokenPublicId ? 'tokens/edit' : 'tokens/create')->withInput()->withErrors($validator);
}
if ($tokenPublicId) {
$token->name = trim(Input::get('name'));
} else {
$lastToken = AccountToken::withTrashed()->where('account_id', '=', Auth::user()->account_id)
->orderBy('public_id', 'DESC')->first();
$token = AccountToken::createNew();
$token->name = trim(Input::get('name'));
$token->token = str_random(RANDOM_KEY_LENGTH);
$token->public_id = $lastToken ? $lastToken->public_id + 1 : 1;
}
$token->save();
if ($tokenPublicId) {
$message = trans('texts.updated_token');
} else {
$message = trans('texts.created_token');
}
Session::flash('message', $message);
}
return Redirect::to('company/advanced_settings/token_management');
}
}

View File

@ -1,507 +0,0 @@
<?php
/*
|--------------------------------------------------------------------------
| Confide Controller Template
|--------------------------------------------------------------------------
|
| This is the default Confide controller template for controlling user
| authentication. Feel free to change to your needs.
|
*/
use ninja\repositories\AccountRepository;
use ninja\mailers\ContactMailer;
use ninja\mailers\UserMailer;
class UserController extends BaseController
{
protected $accountRepo;
protected $contactMailer;
protected $userMailer;
public function __construct(AccountRepository $accountRepo, ContactMailer $contactMailer, UserMailer $userMailer)
{
parent::__construct();
$this->accountRepo = $accountRepo;
$this->contactMailer = $contactMailer;
$this->userMailer = $userMailer;
}
public function getDatatable()
{
$query = DB::table('users')
->where('users.account_id', '=', Auth::user()->account_id);
if (!Session::get('show_trash:user')) {
$query->where('users.deleted_at', '=', null);
}
$query->where('users.public_id', '>', 0)
->select('users.public_id', 'users.first_name', 'users.last_name', 'users.email', 'users.confirmed', 'users.public_id', 'users.deleted_at');
return Datatable::query($query)
->addColumn('first_name', function ($model) { return link_to('users/'.$model->public_id.'/edit', $model->first_name.' '.$model->last_name); })
->addColumn('email', function ($model) { return $model->email; })
->addColumn('confirmed', function ($model) { return $model->deleted_at ? trans('texts.deleted') : ($model->confirmed ? trans('texts.active') : trans('texts.pending')); })
->addColumn('dropdown', function ($model) {
$actions = '<div class="btn-group tr-action" style="visibility:hidden;">
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
'.trans('texts.select').' <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
if ($model->deleted_at) {
$actions .= '<li><a href="'.URL::to('restore_user/'.$model->public_id).'">'.uctrans('texts.restore_user').'</a></li>';
} else {
$actions .= '<li><a href="'.URL::to('users/'.$model->public_id).'/edit">'.uctrans('texts.edit_user').'</a></li>';
if (!$model->confirmed) {
$actions .= '<li><a href="'.URL::to('send_confirmation/'.$model->public_id).'">'.uctrans('texts.send_invite').'</a></li>';
}
$actions .= '<li class="divider"></li>
<li><a href="javascript:deleteUser('.$model->public_id.')">'.uctrans('texts.delete_user').'</a></li>';
}
$actions .= '</ul>
</div>';
return $actions;
})
->orderColumns(['first_name', 'email', 'confirmed'])
->make();
}
public function setTheme()
{
$user = User::find(Auth::user()->id);
$user->theme_id = Input::get('theme_id');
$user->save();
return Redirect::to(Input::get('path'));
}
public function forcePDFJS()
{
$user = Auth::user();
$user->force_pdfjs = true;
$user->save();
Session::flash('message', trans('texts.confide.updated_settings'));
return Redirect::to('/dashboard');
}
public function edit($publicId)
{
$user = User::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $publicId)->firstOrFail();
$data = [
'showBreadcrumbs' => false,
'user' => $user,
'method' => 'PUT',
'url' => 'users/'.$publicId,
'title' => trans('texts.edit_user'),
];
return View::make('users.edit', $data);
}
public function update($publicId)
{
return $this->save($publicId);
}
public function store()
{
return $this->save();
}
/**
* Displays the form for account creation
*
*/
public function create()
{
if (!Auth::user()->confirmed) {
Session::flash('error', trans('texts.register_to_add_user'));
return Redirect::to('company/advanced_settings/user_management');
}
if (Utils::isNinja()) {
$count = User::where('account_id', '=', Auth::user()->account_id)->count();
if ($count >= MAX_NUM_USERS) {
Session::flash('error', trans('texts.limit_users'));
return Redirect::to('company/advanced_settings/user_management');
}
}
$data = [
'showBreadcrumbs' => false,
'user' => null,
'method' => 'POST',
'url' => 'users',
'title' => trans('texts.add_user'),
];
return View::make('users.edit', $data);
}
public function delete()
{
$userPublicId = Input::get('userPublicId');
$user = User::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $userPublicId)->firstOrFail();
$user->delete();
Session::flash('message', trans('texts.deleted_user'));
return Redirect::to('company/advanced_settings/user_management');
}
public function restoreUser($userPublicId)
{
$user = User::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $userPublicId)
->withTrashed()->firstOrFail();
$user->restore();
Session::flash('message', trans('texts.restored_user'));
return Redirect::to('company/advanced_settings/user_management');
}
/**
* Stores new account
*
*/
public function save($userPublicId = false)
{
if (Auth::user()->account->isPro()) {
$rules = [
'first_name' => 'required',
'last_name' => 'required',
];
if ($userPublicId) {
$user = User::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $userPublicId)->firstOrFail();
$rules['email'] = 'required|email|unique:users,email,'.$user->id.',id';
} else {
$rules['email'] = 'required|email|unique:users';
}
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to($userPublicId ? 'users/edit' : 'users/create')->withInput()->withErrors($validator);
}
if ($userPublicId) {
$user->first_name = trim(Input::get('first_name'));
$user->last_name = trim(Input::get('last_name'));
$user->username = trim(Input::get('email'));
$user->email = trim(Input::get('email'));
} else {
$lastUser = User::withTrashed()->where('account_id', '=', Auth::user()->account_id)
->orderBy('public_id', 'DESC')->first();
$user = new User();
$user->account_id = Auth::user()->account_id;
$user->first_name = trim(Input::get('first_name'));
$user->last_name = trim(Input::get('last_name'));
$user->username = trim(Input::get('email'));
$user->email = trim(Input::get('email'));
$user->registered = true;
$user->password = str_random(RANDOM_KEY_LENGTH);
$user->password_confirmation = $user->password;
$user->public_id = $lastUser->public_id + 1;
}
$user->save();
if (!$user->confirmed) {
$this->userMailer->sendConfirmation($user, Auth::user());
$message = trans('texts.sent_invite');
} else {
$message = trans('texts.updated_user');
}
Session::flash('message', $message);
}
return Redirect::to('company/advanced_settings/user_management');
}
public function sendConfirmation($userPublicId)
{
$user = User::where('account_id', '=', Auth::user()->account_id)
->where('public_id', '=', $userPublicId)->firstOrFail();
$this->userMailer->sendConfirmation($user, Auth::user());
Session::flash('message', trans('texts.sent_invite'));
return Redirect::to('company/advanced_settings/user_management');
}
/**
* Displays the login form
*
*/
public function login()
{
if (Confide::user()) {
Event::fire('user.login');
Session::reflash();
return Redirect::to('/dashboard');
/*
$invoice = Invoice::scope()->orderBy('id', 'desc')->first();
if ($invoice)
{
return Redirect::to('/invoices/' . $invoice->public_id);
}
else
{
return Redirect::to('/dashboard');
}
*/
} else {
return View::make(Config::get('confide::login_form'));
}
}
/**
* Attempt to do login
*
*/
public function do_login()
{
$input = array(
'email' => Input::get('login_email'), // May be the username too
'username' => Input::get('login_email'), // so we have to pass both
'password' => Input::get('login_password'),
'remember' => true,
);
// If you wish to only allow login from confirmed users, call logAttempt
// with the second parameter as true.
// logAttempt will check if the 'email' perhaps is the username.
// Get the value from the config file instead of changing the controller
if (Input::get('login_email') && Confide::logAttempt($input, false)) {
Event::fire('user.login');
// Redirect the user to the URL they were trying to access before
// caught by the authentication filter IE Redirect::guest('user/login').
// Otherwise fallback to '/'
// Fix pull #145
return Redirect::intended('/dashboard'); // change it to '/admin', '/dashboard' or something
} else {
//$user = new User;
// Check if there was too many login attempts
if (Confide::isThrottled($input)) {
$err_msg = trans('texts.confide.too_many_attempts');
}
/*
elseif( $user->checkUserExists( $input ) and ! $user->isConfirmed( $input ) )
{
$err_msg = Lang::get('confide::confide.alerts.not_confirmed');
}
*/
else {
$err_msg = trans('texts.confide.wrong_credentials');
}
return Redirect::action('UserController@login')
->withInput(Input::except('login_password'))
->with('error', $err_msg);
}
}
/**
* Attempt to confirm account with code
*
* @param string $code
*/
public function confirm($code)
{
if (Confide::confirm($code)) {
$notice_msg = trans('texts.confide.confirmation');
$user = User::where('confirmation_code', '=', $code)->get()->first();
$user->confirmation_code = '';
$user->save();
if ($user->public_id) {
Auth::login($user);
return Redirect::to('user/reset');
} else {
if (Session::has(REQUESTED_PRO_PLAN)) {
Session::forget(REQUESTED_PRO_PLAN);
$invitation = $this->accountRepo->enableProPlan();
return Redirect::to($invitation->getLink());
} else {
return Redirect::action('UserController@login')->with('message', $notice_msg);
}
}
} else {
$error_msg = trans('texts.confide.wrong_confirmation');
return Redirect::action('UserController@login')->with('error', $error_msg);
}
}
/**
* Displays the forgot password form
*
*/
public function forgot_password()
{
return View::make(Config::get('confide::forgot_password_form'));
}
/**
* Attempt to send change password link to the given email
*
*/
public function do_forgot_password()
{
Confide::forgotPassword(Input::get('email'));
$notice_msg = trans('texts.confide.password_forgot');
return Redirect::action('UserController@login')
->with('notice', $notice_msg);
/*
if( Confide::forgotPassword( Input::get( 'email' ) ) )
{
$notice_msg = Lang::get('confide::confide.alerts.password_forgot');
return Redirect::action('UserController@login')
->with( 'notice', $notice_msg );
}
else
{
$error_msg = Lang::get('confide::confide.alerts.wrong_password_forgot');
return Redirect::action('UserController@forgot_password')
->withInput()
->with( 'error', $error_msg );
}
*/
}
/**
* Shows the change password form with the given token
*
*/
public function reset_password($token = false)
{
return View::make(Config::get('confide::reset_password_form'))
->with('token', $token);
}
/**
* Attempt change password of the user
*
*/
public function do_reset_password()
{
if (Auth::check()) {
$rules = [
'password' => 'required|between:4,11|confirmed',
'password_confirmation' => 'between:4,11',
];
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('user/reset')->withInput()->withErrors($validator);
}
$user = Auth::user();
$user->password = Input::get('password');
$user->save();
Session::flash('message', trans('texts.confide.password_reset'));
return Redirect::to('/dashboard');
} else {
$input = array(
'token' => Input::get('token'),
'password' => Input::get('password'),
'password_confirmation' => Input::get('password_confirmation'),
);
// By passing an array with the token, password and confirmation
if (Confide::resetPassword($input)) {
$notice_msg = trans('texts.confide.password_reset');
return Redirect::action('UserController@login')
->with('notice', $notice_msg);
} else {
$error_msg = trans('texts.confide.wrong_password_reset');
return Redirect::action('UserController@reset_password', array('token' => $input['token']))
->withInput()
->with('error', $error_msg);
}
}
}
/**
* Log the user out of the application.
*
*/
public function logout()
{
if (Auth::check()) {
if (!Auth::user()->registered) {
$account = Auth::user()->account;
$account->forceDelete();
}
}
Session::forget('news_feed_id');
Session::forget('news_feed_message');
Confide::logout();
return Redirect::to('/')->with('clearGuestKey', true);
}
public function changePassword()
{
// check the current password is correct
if (!Auth::validate([
'email' => Auth::user()->email,
'password' => Input::get('current_password')
])) {
return trans('texts.password_error_incorrect');
}
// validate the new password
$password = Input::get('new_password');
$confirm = Input::get('confirm_password');
if (strlen($password) < 6 || $password != $confirm) {
return trans('texts.password_error_invalid');
}
// save the new password
$user = Auth::user();
$user->password = $password;
$user->save();
return RESULT_SUCCESS;
}
}

View File

@ -1,550 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
class ConfideSetupUsersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::dropIfExists('payment_terms');
Schema::dropIfExists('themes');
Schema::dropIfExists('credits');
Schema::dropIfExists('activities');
Schema::dropIfExists('invitations');
Schema::dropIfExists('payments');
Schema::dropIfExists('account_gateways');
Schema::dropIfExists('invoice_items');
Schema::dropIfExists('products');
Schema::dropIfExists('tax_rates');
Schema::dropIfExists('contacts');
Schema::dropIfExists('invoices');
Schema::dropIfExists('password_reminders');
Schema::dropIfExists('clients');
Schema::dropIfExists('users');
Schema::dropIfExists('accounts');
Schema::dropIfExists('currencies');
Schema::dropIfExists('invoice_statuses');
Schema::dropIfExists('countries');
Schema::dropIfExists('timezones');
Schema::dropIfExists('frequencies');
Schema::dropIfExists('date_formats');
Schema::dropIfExists('datetime_formats');
Schema::dropIfExists('sizes');
Schema::dropIfExists('industries');
Schema::dropIfExists('gateways');
Schema::dropIfExists('payment_types');
Schema::create('countries', function($table)
{
$table->increments('id');
$table->string('capital', 255)->nullable();
$table->string('citizenship', 255)->nullable();
$table->string('country_code', 3)->default('');
$table->string('currency', 255)->nullable();
$table->string('currency_code', 255)->nullable();
$table->string('currency_sub_unit', 255)->nullable();
$table->string('full_name', 255)->nullable();
$table->string('iso_3166_2', 2)->default('');
$table->string('iso_3166_3', 3)->default('');
$table->string('name', 255)->default('');
$table->string('region_code', 3)->default('');
$table->string('sub_region_code', 3)->default('');
$table->boolean('eea')->default(0);
});
Schema::create('themes', function($t)
{
$t->increments('id');
$t->string('name');
});
Schema::create('payment_types', function($t)
{
$t->increments('id');
$t->string('name');
});
Schema::create('payment_terms', function($t)
{
$t->increments('id');
$t->integer('num_days');
$t->string('name');
});
Schema::create('timezones', function($t)
{
$t->increments('id');
$t->string('name');
$t->string('location');
});
Schema::create('date_formats', function($t)
{
$t->increments('id');
$t->string('format');
$t->string('picker_format');
$t->string('label');
});
Schema::create('datetime_formats', function($t)
{
$t->increments('id');
$t->string('format');
$t->string('label');
});
Schema::create('currencies', function($t)
{
$t->increments('id');
$t->string('name');
$t->string('symbol');
$t->string('precision');
$t->string('thousand_separator');
$t->string('decimal_separator');
$t->string('code');
});
Schema::create('sizes', function($t)
{
$t->increments('id');
$t->string('name');
});
Schema::create('industries', function($t)
{
$t->increments('id');
$t->string('name');
});
Schema::create('accounts', function($t)
{
$t->increments('id');
$t->unsignedInteger('timezone_id')->nullable();
$t->unsignedInteger('date_format_id')->nullable();
$t->unsignedInteger('datetime_format_id')->nullable();
$t->unsignedInteger('currency_id')->nullable();
$t->timestamps();
$t->softDeletes();
$t->string('name')->nullable();
$t->string('ip');
$t->string('account_key')->unique();
$t->timestamp('last_login')->nullable();
$t->string('address1')->nullable();
$t->string('address2')->nullable();
$t->string('city')->nullable();
$t->string('state')->nullable();
$t->string('postal_code')->nullable();
$t->unsignedInteger('country_id')->nullable();
$t->text('invoice_terms')->nullable();
$t->text('email_footer')->nullable();
$t->unsignedInteger('industry_id')->nullable();
$t->unsignedInteger('size_id')->nullable();
$t->boolean('invoice_taxes')->default(true);
$t->boolean('invoice_item_taxes')->default(false);
$t->foreign('timezone_id')->references('id')->on('timezones');
$t->foreign('date_format_id')->references('id')->on('date_formats');
$t->foreign('datetime_format_id')->references('id')->on('datetime_formats');
$t->foreign('country_id')->references('id')->on('countries');
$t->foreign('currency_id')->references('id')->on('currencies');
$t->foreign('industry_id')->references('id')->on('industries');
$t->foreign('size_id')->references('id')->on('sizes');
});
Schema::create('gateways', function($t)
{
$t->increments('id');
$t->timestamps();
$t->string('name');
$t->string('provider');
$t->boolean('visible')->default(true);
});
Schema::create('users', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id')->index();
$t->timestamps();
$t->softDeletes();
$t->string('first_name')->nullable();
$t->string('last_name')->nullable();
$t->string('phone')->nullable();
$t->string('username')->unique();
$t->string('email')->nullable();
$t->string('password');
$t->string('confirmation_code');
$t->boolean('registered')->default(false);
$t->boolean('confirmed')->default(false);
$t->integer('theme_id')->nullable();
$t->boolean('notify_sent')->default(true);
$t->boolean('notify_viewed')->default(false);
$t->boolean('notify_paid')->default(true);
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->unsignedInteger('public_id')->nullable();
$t->unique( array('account_id','public_id') );
});
Schema::create('account_gateways', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('gateway_id');
$t->timestamps();
$t->softDeletes();
$t->text('config');
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('gateway_id')->references('id')->on('gateways');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->unsignedInteger('public_id')->index();
$t->unique( array('account_id','public_id') );
});
Schema::create('password_reminders', function($t)
{
$t->string('email');
$t->timestamps();
$t->string('token');
});
Schema::create('clients', function($t)
{
$t->increments('id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('currency_id')->nullable();
$t->timestamps();
$t->softDeletes();
$t->string('name')->nullable();
$t->string('address1')->nullable();
$t->string('address2')->nullable();
$t->string('city')->nullable();
$t->string('state')->nullable();
$t->string('postal_code')->nullable();
$t->unsignedInteger('country_id')->nullable();
$t->string('work_phone')->nullable();
$t->text('private_notes')->nullable();
$t->decimal('balance', 13, 2)->nullable();
$t->decimal('paid_to_date', 13, 2)->nullable();
$t->timestamp('last_login')->nullable();
$t->string('website')->nullable();
$t->unsignedInteger('industry_id')->nullable();
$t->unsignedInteger('size_id')->nullable();
$t->boolean('is_deleted')->default(false);
$t->integer('payment_terms')->nullable();
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->foreign('country_id')->references('id')->on('countries');
$t->foreign('industry_id')->references('id')->on('industries');
$t->foreign('size_id')->references('id')->on('sizes');
$t->foreign('currency_id')->references('id')->on('currencies');
$t->unsignedInteger('public_id')->index();
$t->unique( array('account_id','public_id') );
});
Schema::create('contacts', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('client_id')->index();
$t->timestamps();
$t->softDeletes();
$t->boolean('is_primary')->default(0);
$t->boolean('send_invoice')->default(0);
$t->string('first_name')->nullable();
$t->string('last_name')->nullable();
$t->string('email')->nullable();
$t->string('phone')->nullable();
$t->timestamp('last_login')->nullable();
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->unsignedInteger('public_id')->nullable();
$t->unique( array('account_id','public_id') );
});
Schema::create('invoice_statuses', function($t)
{
$t->increments('id');
$t->string('name');
});
Schema::create('frequencies', function($t)
{
$t->increments('id');
$t->string('name');
});
Schema::create('invoices', function($t)
{
$t->increments('id');
$t->unsignedInteger('client_id')->index();
$t->unsignedInteger('user_id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('invoice_status_id')->default(1);
$t->timestamps();
$t->softDeletes();
$t->string('invoice_number');
$t->float('discount');
$t->string('po_number');
$t->date('invoice_date')->nullable();
$t->date('due_date')->nullable();
$t->text('terms');
$t->text('public_notes');
$t->boolean('is_deleted')->default(false);
$t->boolean('is_recurring');
$t->unsignedInteger('frequency_id');
$t->date('start_date')->nullable();
$t->date('end_date')->nullable();
$t->timestamp('last_sent_date')->nullable();
$t->unsignedInteger('recurring_invoice_id')->index()->nullable();
$t->string('tax_name');
$t->decimal('tax_rate', 13, 2);
$t->decimal('amount', 13, 2);
$t->decimal('balance', 13, 2);
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->foreign('invoice_status_id')->references('id')->on('invoice_statuses');
$t->foreign('recurring_invoice_id')->references('id')->on('invoices')->onDelete('cascade');
$t->unsignedInteger('public_id')->index();
$t->unique( array('account_id','public_id') );
$t->unique( array('account_id','invoice_number') );
});
Schema::create('invitations', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('contact_id');
$t->unsignedInteger('invoice_id')->index();
$t->string('invitation_key')->index()->unique();
$t->timestamps();
$t->softDeletes();
$t->string('transaction_reference')->nullable();
$t->timestamp('sent_date');
$t->timestamp('viewed_date');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
$t->unsignedInteger('public_id')->index();
$t->unique( array('account_id','public_id') );
});
Schema::create('tax_rates', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('user_id');
$t->timestamps();
$t->softDeletes();
$t->string('name');
$t->decimal('rate', 13, 2);
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->unsignedInteger('public_id');
$t->unique( array('account_id','public_id') );
});
Schema::create('products', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('user_id');
$t->timestamps();
$t->softDeletes();
$t->string('product_key');
$t->text('notes');
$t->decimal('cost', 13, 2);
$t->decimal('qty', 13, 2)->nullable();
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->unsignedInteger('public_id');
$t->unique( array('account_id','public_id') );
});
Schema::create('invoice_items', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('invoice_id')->index();
$t->unsignedInteger('product_id')->nullable();
$t->timestamps();
$t->softDeletes();
$t->string('product_key');
$t->text('notes');
$t->decimal('cost', 13, 2);
$t->decimal('qty', 13, 2)->nullable();
$t->string('tax_name')->nullable();
$t->decimal('tax_rate', 13, 2)->nullable();
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
$t->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->unsignedInteger('public_id');
$t->unique( array('account_id','public_id') );
});
Schema::create('payments', function($t)
{
$t->increments('id');
$t->unsignedInteger('invoice_id')->nullable();
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('client_id')->index();
$t->unsignedInteger('contact_id')->nullable();
$t->unsignedInteger('invitation_id')->nullable();
$t->unsignedInteger('user_id')->nullable();
$t->unsignedInteger('account_gateway_id')->nullable();
$t->unsignedInteger('payment_type_id')->nullable();
$t->timestamps();
$t->softDeletes();
$t->boolean('is_deleted')->default(false);
$t->decimal('amount', 13, 2);
$t->date('payment_date')->nullable();
$t->string('transaction_reference')->nullable();
$t->string('payer_id')->nullable();
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$t->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$t->foreign('account_gateway_id')->references('id')->on('account_gateways')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->foreign('payment_type_id')->references('id')->on('payment_types');
$t->unsignedInteger('public_id')->index();
$t->unique( array('account_id','public_id') );
});
Schema::create('credits', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('client_id')->index();
$t->unsignedInteger('user_id');
$t->timestamps();
$t->softDeletes();
$t->boolean('is_deleted')->default(false);
$t->decimal('amount', 13, 2);
$t->decimal('balance', 13, 2);
$t->date('credit_date')->nullable();
$t->string('credit_number')->nullable();
$t->text('private_notes');
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->unsignedInteger('public_id')->index();
$t->unique( array('account_id','public_id') );
});
Schema::create('activities', function($t)
{
$t->increments('id');
$t->timestamps();
$t->unsignedInteger('account_id');
$t->unsignedInteger('client_id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('contact_id')->nullable();
$t->unsignedInteger('payment_id')->nullable();
$t->unsignedInteger('invoice_id')->nullable();
$t->unsignedInteger('credit_id')->nullable();
$t->unsignedInteger('invitation_id')->nullable();
$t->text('message')->nullable();
$t->text('json_backup')->nullable();
$t->integer('activity_type_id');
$t->decimal('adjustment', 13, 2)->nullable();
$t->decimal('balance', 13, 2)->nullable();
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('payment_terms');
Schema::dropIfExists('themes');
Schema::dropIfExists('credits');
Schema::dropIfExists('activities');
Schema::dropIfExists('invitations');
Schema::dropIfExists('payments');
Schema::dropIfExists('account_gateways');
Schema::dropIfExists('invoice_items');
Schema::dropIfExists('products');
Schema::dropIfExists('tax_rates');
Schema::dropIfExists('contacts');
Schema::dropIfExists('invoices');
Schema::dropIfExists('password_reminders');
Schema::dropIfExists('clients');
Schema::dropIfExists('users');
Schema::dropIfExists('accounts');
Schema::dropIfExists('currencies');
Schema::dropIfExists('invoice_statuses');
Schema::dropIfExists('countries');
Schema::dropIfExists('timezones');
Schema::dropIfExists('frequencies');
Schema::dropIfExists('date_formats');
Schema::dropIfExists('datetime_formats');
Schema::dropIfExists('sizes');
Schema::dropIfExists('industries');
Schema::dropIfExists('gateways');
Schema::dropIfExists('payment_types');
}
}

View File

@ -1,47 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
class SetupCountriesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// Creates the users table
/*
Schema::create('countries', function($table)
{
$table->integer('id')->index();
$table->string('capital', 255)->nullable();
$table->string('citizenship', 255)->nullable();
$table->string('country_code', 3)->default('');
$table->string('currency', 255)->nullable();
$table->string('currency_code', 255)->nullable();
$table->string('currency_sub_unit', 255)->nullable();
$table->string('full_name', 255)->nullable();
$table->string('iso_3166_2', 2)->default('');
$table->string('iso_3166_3', 3)->default('');
$table->string('name', 255)->default('');
$table->string('region_code', 3)->default('');
$table->string('sub_region_code', 3)->default('');
$table->boolean('eea')->default(0);
$table->primary('id');
});
*/
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//Schema::drop('countries');
}
}

View File

@ -1,32 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCascaseDrops extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoices', function($table)
{
$table->dropForeign('invoices_account_id_foreign');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}

View File

@ -1,72 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSupportForInvoiceDesigns extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('invoice_designs', function($table)
{
$table->increments('id');
$table->string('name');
});
DB::table('invoice_designs')->insert(['name' => 'Clean']);
DB::table('invoice_designs')->insert(['name' => 'Bold']);
DB::table('invoice_designs')->insert(['name' => 'Modern']);
DB::table('invoice_designs')->insert(['name' => 'Plain']);
Schema::table('invoices', function($table)
{
$table->unsignedInteger('invoice_design_id')->default(1);
});
Schema::table('accounts', function($table)
{
$table->unsignedInteger('invoice_design_id')->default(1);
});
DB::table('invoices')->update(['invoice_design_id' => 1]);
DB::table('accounts')->update(['invoice_design_id' => 1]);
Schema::table('invoices', function($table)
{
$table->foreign('invoice_design_id')->references('id')->on('invoice_designs');
});
Schema::table('accounts', function($table)
{
$table->foreign('invoice_design_id')->references('id')->on('invoice_designs');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function($table)
{
$table->dropForeign('invoices_invoice_design_id_foreign');
$table->dropColumn('invoice_design_id');
});
Schema::table('accounts', function($table)
{
$table->dropForeign('accounts_invoice_design_id_foreign');
$table->dropColumn('invoice_design_id');
});
Schema::dropIfExists('invoice_designs');
}
}

View File

@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddPhoneToAccount extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->string('work_phone')->nullable();
$table->string('work_email')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('work_phone');
$table->dropColumn('work_email');
});
}
}

View File

@ -1,60 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddLanguageSupport extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('languages', function($table)
{
$table->increments('id');
$table->string('name');
$table->string('locale');
});
DB::table('languages')->insert(['name' => 'English', 'locale' => 'en']);
DB::table('languages')->insert(['name' => 'Italian', 'locale' => 'it']);
DB::table('languages')->insert(['name' => 'German', 'locale' => 'de']);
DB::table('languages')->insert(['name' => 'French', 'locale' => 'fr']);
DB::table('languages')->insert(['name' => 'Brazilian Portuguese', 'locale' => 'pt_BR']);
DB::table('languages')->insert(['name' => 'Dutch', 'locale' => 'nl']);
DB::table('languages')->insert(['name' => 'Spanish', 'locale' => 'es']);
DB::table('languages')->insert(['name' => 'Norwegian', 'locale' => 'nb_NO']);
Schema::table('accounts', function($table)
{
$table->unsignedInteger('language_id')->default(1);
});
DB::table('accounts')->update(['language_id' => 1]);
Schema::table('accounts', function($table)
{
$table->foreign('language_id')->references('id')->on('languages');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropForeign('accounts_language_id_foreign');
$table->dropColumn('language_id');
});
Schema::drop('languages');
}
}

View File

@ -1,58 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePaymentLibraries extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::dropIfExists('payment_libraries');
Schema::create('payment_libraries', function($t)
{
$t->increments('id');
$t->timestamps();
$t->string('name');
$t->boolean('visible')->default(true);
});
Schema::table('gateways', function($table)
{
$table->unsignedInteger('payment_library_id')->default(1);
});
DB::table('gateways')->update(['payment_library_id' => 1]);
Schema::table('gateways', function($table)
{
$table->foreign('payment_library_id')->references('id')->on('payment_libraries')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
if (Schema::hasColumn('gateways', 'payment_library_id'))
{
Schema::table('gateways', function($table)
{
$table->dropForeign('gateways_payment_library_id_foreign');
$table->dropColumn('payment_library_id');
});
}
Schema::dropIfExists('payment_libraries');
}
}

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class EnableForcingJspdf extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function($table)
{
$table->boolean('force_pdfjs')->default(false);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function($table)
{
$table->dropColumn('force_pdfjs');
});
}
}

View File

@ -1,49 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSortAndRecommendedToGateways extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('gateways', function($table)
{
$table->unsignedInteger('sort_order')->default(10000);
$table->boolean('recommended')->default(0);
$table->string('site_url', 200)->nullable();
});
}
public function down()
{
if (Schema::hasColumn('gateways', 'sort_order'))
{
Schema::table('gateways', function($table)
{
$table->dropColumn('sort_order');
});
}
if (Schema::hasColumn('gateways', 'recommended'))
{
Schema::table('gateways', function($table)
{
$table->dropColumn('recommended');
});
}
if (Schema::hasColumn('gateways', 'site_url'))
{
Schema::table('gateways', function($table)
{
$table->dropColumn('site_url');
});
}
}
}

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddProPlan extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->date('pro_plan_paid')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('pro_plan_paid');
});
}
}

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddRememberToken extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function($table)
{
$table->string('remember_token', 100)->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function($table)
{
$table->dropColumn('remember_token');
});
}
}

View File

@ -1,60 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCustomFields extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->string('custom_label1')->nullable();
$table->string('custom_value1')->nullable();
$table->string('custom_label2')->nullable();
$table->string('custom_value2')->nullable();
$table->string('custom_client_label1')->nullable();
$table->string('custom_client_label2')->nullable();
});
Schema::table('clients', function($table)
{
$table->string('custom_value1')->nullable();
$table->string('custom_value2')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('custom_label1');
$table->dropColumn('custom_value1');
$table->dropColumn('custom_label2');
$table->dropColumn('custom_value2');
$table->dropColumn('custom_client_label1');
$table->dropColumn('custom_client_label2');
});
Schema::table('clients', function($table)
{
$table->dropColumn('custom_value1');
$table->dropColumn('custom_value2');
});
}
}

View File

@ -1,39 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddProductsSettings extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->boolean('fill_products')->default(true);
$table->boolean('update_products')->default(true);
});
DB::table('accounts')->update(['fill_products' => true]);
DB::table('accounts')->update(['update_products' => true]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('fill_products');
$table->dropColumn('update_products');
});
}
}

View File

@ -1,42 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddAdvancedSettings extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->string('primary_color')->nullable();
$table->string('secondary_color')->nullable();
});
Schema::table('payments', function($table)
{
$table->dropForeign('payments_invoice_id_foreign');
$table->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('primary_color');
$table->dropColumn('secondary_color');
});
}
}

View File

@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddQuotes extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoices', function($table)
{
$table->boolean('is_quote')->default(0);
$table->unsignedInteger('quote_id')->nullable();
$table->unsignedInteger('quote_invoice_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function($table)
{
$table->dropColumn('is_quote');
$table->dropColumn('quote_id');
$table->dropColumn('quote_invoice_id');
});
}
}

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddAcceptedCreditCardsToAccountGateways extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('account_gateways', function($table)
{
$table->unsignedInteger('accepted_credit_cards')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('account_gateways', function($table)
{
$table->dropColumn('accepted_credit_cards');
});
}
}

View File

@ -1,58 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class OneClickInstall extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('affiliates', function($table)
{
$table->increments('id');
$table->timestamps();
$table->softDeletes();
$table->string('name');
$table->string('affiliate_key')->unique();
$table->text('payment_title');
$table->text('payment_subtitle');
});
Schema::create('licenses', function($table)
{
$table->increments('id');
$table->timestamps();
$table->softDeletes();
$table->unsignedInteger('affiliate_id');
$table->string('first_name');
$table->string('last_name');
$table->string('email');
$table->string('license_key')->unique();
$table->boolean('is_claimed');
$table->string('transaction_reference');
$table->foreign('affiliate_id')->references('id')->on('affiliates');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('licenses');
Schema::dropIfExists('affiliates');
}
}

View File

@ -1,66 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class SupportHidingQuantity extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->boolean('hide_quantity')->default(0);
$table->boolean('hide_paid_to_date')->default(0);
$table->string('custom_invoice_label1')->nullable();
$table->string('custom_invoice_label2')->nullable();
$table->boolean('custom_invoice_taxes1')->nullable();
$table->boolean('custom_invoice_taxes2')->nullable();
});
Schema::table('invoices', function($table)
{
$table->decimal('custom_value1', 13, 2)->default(0);
$table->decimal('custom_value2', 13, 2)->default(0);
$table->boolean('custom_taxes1')->default(0);
$table->boolean('custom_taxes2')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('hide_quantity');
$table->dropColumn('hide_paid_to_date');
$table->dropColumn('custom_invoice_label1');
$table->dropColumn('custom_invoice_label2');
$table->dropColumn('custom_invoice_taxes1');
$table->dropColumn('custom_invoice_taxes2');
});
Schema::table('invoices', function($table)
{
$table->dropColumn('custom_value1');
$table->dropColumn('custom_value2');
$table->dropColumn('custom_taxes1');
$table->dropColumn('custom_taxes2');
});
}
}

View File

@ -1,42 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddZapierSupport extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('subscriptions', function($table)
{
$table->increments('id');
$table->unsignedInteger('account_id')->nullable();
$table->timestamps();
$table->softDeletes();
$table->unsignedInteger('event_id')->nullable();
$table->string('target_url');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->unique( ['account_id', 'event_id'] );
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('subscriptions');
}
}

View File

@ -1,43 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCompanyVatNumber extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->string('vat_number')->nullable();
});
Schema::table('clients', function($table)
{
$table->string('vat_number')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('vat_number');
});
Schema::table('clients', function($table)
{
$table->dropColumn('vat_number');
});
}
}

View File

@ -1,46 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class TrackLastSeenMessage extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function($table)
{
$table->unsignedInteger('news_feed_id')->nullable();
});
if (DB::table('payment_libraries')->count() > 0) {
DB::table('gateways')->update(['recommended' => 0]);
DB::table('gateways')->insert([
'name' => 'moolah',
'provider' => 'AuthorizeNet_AIM',
'sort_order' => 1,
'recommended' => 1,
'site_url' => 'https://invoiceninja.mymoolah.com/',
'payment_library_id' => 1
]);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function($table)
{
$table->dropColumn('news_feed_id');
});
}
}

View File

@ -1,152 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddTimesheets extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('projects', function($t) {
$t->increments('id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('client_id')->nullable();
$t->timestamps();
$t->softDeletes();
$t->string('name');
$t->string('description');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->foreign('account_id')->references('id')->on('accounts');
$t->unique( array('account_id','name') );
});
Schema::create('project_codes', function($t) {
$t->increments('id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('project_id');
$t->timestamps();
$t->softDeletes();
$t->string('name');
$t->string('description');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->foreign('account_id')->references('id')->on('accounts');
$t->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');
$t->unique( array('account_id','name') );
});
Schema::create('timesheets', function($t) {
$t->increments('id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('account_id')->index();
$t->timestamps();
$t->softDeletes();
$t->dateTime('start_date');
$t->dateTime('end_date');
$t->float('discount');
$t->decimal('hours');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->foreign('account_id')->references('id')->on('accounts');
$t->unsignedInteger('public_id');
$t->unique( array('account_id','public_id') );
});
Schema::create('timesheet_event_sources', function($t) {
$t->increments('id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('account_id')->index();
$t->timestamps();
$t->softDeletes();
$t->string('owner');
$t->string('name');
$t->string('url');
$t->enum('type', array('ical', 'googlejson'));
$t->dateTime('from_date')->nullable();
$t->dateTime('to_date')->nullable();
$t->foreign('account_id')->references('id')->on('accounts');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
Schema::create('timesheet_events', function($t) {
$t->increments('id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('timesheet_event_source_id');
$t->unsignedInteger('timesheet_id')->nullable()->index();
$t->unsignedInteger('project_id')->nullable()->index();
$t->unsignedInteger('project_code_id')->nullable()->index();
$t->timestamps();
$t->softDeletes();
// Basic fields
$t->string('uid');
$t->string('summary');
$t->text('description');
$t->string('location');
$t->string('owner');
$t->dateTime('start_date');
$t->dateTime('end_date');
# Calculated values
$t->decimal('hours');
$t->float('discount');
$t->boolean('manualedit');
// Original data
$t->string('org_code');
$t->timeStamp('org_created_at');
$t->timeStamp('org_updated_at');
$t->timeStamp('org_deleted_at')->default('0000-00-00T00:00:00');
$t->string('org_start_date_timezone')->nullable();
$t->string('org_end_date_timezone')->nullable();
$t->text('org_data');
// Error and merge handling
$t->string('import_error')->nullable();
$t->string('import_warning')->nullable();
$t->text('updated_data')->nullable();
$t->timeStamp('updated_data_at')->default('0000-00-00T00:00:00');
$t->foreign('account_id')->references('id')->on('accounts');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->foreign('timesheet_event_source_id')->references('id')->on('timesheet_event_sources')->onDelete('cascade');
$t->unique( array('timesheet_event_source_id', 'uid') );
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('timesheet_events');
Schema::drop('timesheet_event_sources');
Schema::drop('timesheets');
Schema::drop('project_codes');
Schema::drop('projects');
}
}

View File

@ -1,519 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddInvoiceDesignTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoice_designs', function($table)
{
$table->text('javascript')->nullable();
});
Schema::table('accounts', function($table)
{
$table->text('invoice_design')->nullable();
});
DB::table('invoice_designs')->where('id', 1)->update([
'javascript' => "var GlobalY=0;//Y position of line at current page
var client = invoice.client;
var account = invoice.account;
var currencyId = client.currency_id;
layout.headerRight = 550;
layout.rowHeight = 15;
doc.setFontSize(9);
if (invoice.image)
{
var left = layout.headerRight - invoice.imageWidth;
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
}
if (!invoice.is_pro && logoImages.imageLogo1)
{
pageHeight=820;
y=pageHeight-logoImages.imageLogoHeight1;
doc.addImage(logoImages.imageLogo1, 'JPEG', layout.marginLeft, y, logoImages.imageLogoWidth1, logoImages.imageLogoHeight1);
}
doc.setFontSize(9);
SetPdfColor('LightBlue', doc, 'primary');
displayAccount(doc, invoice, 220, layout.accountTop, layout);
SetPdfColor('LightBlue', doc, 'primary');
doc.setFontSize('11');
doc.text(50, layout.headerTop, (invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase());
SetPdfColor('Black',doc); //set black color
doc.setFontSize(9);
var invoiceHeight = displayInvoice(doc, invoice, 50, 170, layout);
var clientHeight = displayClient(doc, invoice, 220, 170, layout);
var detailsHeight = Math.max(invoiceHeight, clientHeight);
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (3 * layout.rowHeight));
doc.setLineWidth(0.3);
doc.setDrawColor(200,200,200);
doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + 6, layout.marginRight + layout.tablePadding, layout.headerTop + 6);
doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + detailsHeight + 14, layout.marginRight + layout.tablePadding, layout.headerTop + detailsHeight + 14);
doc.setFontSize(10);
doc.setFontType('bold');
displayInvoiceHeader(doc, invoice, layout);
var y = displayInvoiceItems(doc, invoice, layout);
doc.setFontSize(9);
doc.setFontType('bold');
GlobalY=GlobalY+25;
doc.setLineWidth(0.3);
doc.setDrawColor(241,241,241);
doc.setFillColor(241,241,241);
var x1 = layout.marginLeft - 12;
var y1 = GlobalY-layout.tablePadding;
var w2 = 510 + 24;
var h2 = doc.internal.getFontSize()*3+layout.tablePadding*2;
if (invoice.discount) {
h2 += doc.internal.getFontSize()*2;
}
if (invoice.tax_amount) {
h2 += doc.internal.getFontSize()*2;
}
//doc.rect(x1, y1, w2, h2, 'FD');
doc.setFontSize(9);
displayNotesAndTerms(doc, layout, invoice, y);
y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
doc.setFontSize(10);
Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());
doc.text(TmpMsgX, y, Msg);
SetPdfColor('LightBlue', doc, 'primary');
AmountText = formatMoney(invoice.balance_amount, currencyId);
headerLeft=layout.headerRight+400;
var AmountX = layout.lineTotalRight - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());
doc.text(AmountX, y, AmountText);"
]);
DB::table('invoice_designs')->where('id', 2)->update([
'javascript' => " var GlobalY=0;//Y position of line at current page
var client = invoice.client;
var account = invoice.account;
var currencyId = client.currency_id;
layout.headerRight = 150;
layout.rowHeight = 15;
layout.headerTop = 125;
layout.tableTop = 300;
doc.setLineWidth(0.5);
if (NINJA.primaryColor) {
setDocHexFill(doc, NINJA.primaryColor);
setDocHexDraw(doc, NINJA.primaryColor);
} else {
doc.setFillColor(46,43,43);
}
var x1 =0;
var y1 = 0;
var w2 = 595;
var h2 = 100;
doc.rect(x1, y1, w2, h2, 'FD');
if (invoice.image)
{
var left = layout.headerRight - invoice.imageWidth;
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
}
doc.setLineWidth(0.5);
if (NINJA.primaryColor) {
setDocHexFill(doc, NINJA.primaryColor);
setDocHexDraw(doc, NINJA.primaryColor);
} else {
doc.setFillColor(46,43,43);
doc.setDrawColor(46,43,43);
}
// return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour
var x1 = 0;//tableLeft-tablePadding ;
var y1 = 750;
var w2 = 596;
var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;
doc.rect(x1, y1, w2, h2, 'FD');
if (!invoice.is_pro && logoImages.imageLogo2)
{
pageHeight=820;
var left = 250;//headerRight ;
y=pageHeight-logoImages.imageLogoHeight2;
var headerRight=370;
var left = headerRight - logoImages.imageLogoWidth2;
doc.addImage(logoImages.imageLogo2, 'JPEG', left, y, logoImages.imageLogoWidth2, logoImages.imageLogoHeight2);
}
doc.setFontSize(7);
doc.setFontType('bold');
SetPdfColor('White',doc);
displayAccount(doc, invoice, 300, layout.accountTop, layout);
var y = layout.accountTop;
var left = layout.marginLeft;
var headerY = layout.headerTop;
SetPdfColor('GrayLogo',doc); //set black color
doc.setFontSize(7);
//show left column
SetPdfColor('Black',doc); //set black color
doc.setFontType('normal');
//publish filled box
doc.setDrawColor(200,200,200);
if (NINJA.secondaryColor) {
setDocHexFill(doc, NINJA.secondaryColor);
} else {
doc.setFillColor(54,164,152);
}
GlobalY=190;
doc.setLineWidth(0.5);
var BlockLenght=220;
var x1 =595-BlockLenght;
var y1 = GlobalY-12;
var w2 = BlockLenght;
var h2 = getInvoiceDetailsHeight(invoice, layout) + layout.tablePadding + 2;
doc.rect(x1, y1, w2, h2, 'FD');
SetPdfColor('SomeGreen', doc, 'secondary');
doc.setFontSize('14');
doc.setFontType('bold');
doc.text(50, GlobalY, (invoice.is_quote ? invoiceLabels.your_quote : invoiceLabels.your_invoice).toUpperCase());
var z=GlobalY;
z=z+30;
doc.setFontSize('8');
SetPdfColor('Black',doc);
var clientHeight = displayClient(doc, invoice, layout.marginLeft, z, layout);
layout.tableTop += Math.max(0, clientHeight - 75);
marginLeft2=395;
//publish left side information
SetPdfColor('White',doc);
doc.setFontSize('8');
var detailsHeight = displayInvoice(doc, invoice, marginLeft2, z-25, layout) + 75;
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));
y=z+60;
x = GlobalY + 100;
doc.setFontType('bold');
doc.setFontSize(12);
doc.setFontType('bold');
SetPdfColor('Black',doc);
displayInvoiceHeader(doc, invoice, layout);
var y = displayInvoiceItems(doc, invoice, layout);
doc.setLineWidth(0.3);
displayNotesAndTerms(doc, layout, invoice, y);
y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
doc.setFontType('bold');
doc.setFontSize(12);
x += doc.internal.getFontSize()*4;
Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());
doc.text(TmpMsgX, y, Msg);
//SetPdfColor('LightBlue',doc);
AmountText = formatMoney(invoice.balance_amount , currencyId);
headerLeft=layout.headerRight+400;
var AmountX = headerLeft - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());
SetPdfColor('SomeGreen', doc, 'secondary');
doc.text(AmountX, y, AmountText);"
]);
DB::table('invoice_designs')->where('id', 3)->update([
'javascript' => " var client = invoice.client;
var account = invoice.account;
var currencyId = client.currency_id;
layout.headerRight = 400;
layout.rowHeight = 15;
doc.setFontSize(7);
// add header
doc.setLineWidth(0.5);
if (NINJA.primaryColor) {
setDocHexFill(doc, NINJA.primaryColor);
setDocHexDraw(doc, NINJA.primaryColor);
} else {
doc.setDrawColor(242,101,34);
doc.setFillColor(242,101,34);
}
var x1 =0;
var y1 = 0;
var w2 = 595;
var h2 = Math.max(110, getInvoiceDetailsHeight(invoice, layout) + 30);
doc.rect(x1, y1, w2, h2, 'FD');
SetPdfColor('White',doc);
//second column
doc.setFontType('bold');
var name = invoice.account.name;
if (name) {
doc.setFontSize('30');
doc.setFontType('bold');
doc.text(40, 50, name);
}
if (invoice.image)
{
y=130;
var left = layout.headerRight - invoice.imageWidth;
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, y);
}
// add footer
doc.setLineWidth(0.5);
if (NINJA.primaryColor) {
setDocHexFill(doc, NINJA.primaryColor);
setDocHexDraw(doc, NINJA.primaryColor);
} else {
doc.setDrawColor(242,101,34);
doc.setFillColor(242,101,34);
}
var x1 = 0;//tableLeft-tablePadding ;
var y1 = 750;
var w2 = 596;
var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;
doc.rect(x1, y1, w2, h2, 'FD');
if (!invoice.is_pro && logoImages.imageLogo3)
{
pageHeight=820;
// var left = 25;//250;//headerRight ;
y=pageHeight-logoImages.imageLogoHeight3;
//var headerRight=370;
//var left = headerRight - invoice.imageLogoWidth3;
doc.addImage(logoImages.imageLogo3, 'JPEG', 40, y, logoImages.imageLogoWidth3, logoImages.imageLogoHeight3);
}
doc.setFontSize(10);
var marginLeft = 340;
displayAccount(doc, invoice, marginLeft, 780, layout);
SetPdfColor('White',doc);
doc.setFontSize('8');
var detailsHeight = displayInvoice(doc, invoice, layout.headerRight, layout.accountTop-10, layout);
layout.headerTop = Math.max(layout.headerTop, detailsHeight + 50);
layout.tableTop = Math.max(layout.tableTop, detailsHeight + 150);
SetPdfColor('Black',doc); //set black color
doc.setFontSize(7);
doc.setFontType('normal');
displayClient(doc, invoice, layout.headerRight, layout.headerTop, layout);
SetPdfColor('White',doc);
doc.setFontType('bold');
doc.setLineWidth(0.3);
if (NINJA.secondaryColor) {
setDocHexFill(doc, NINJA.secondaryColor);
setDocHexDraw(doc, NINJA.secondaryColor);
} else {
doc.setDrawColor(63,60,60);
doc.setFillColor(63,60,60);
}
var left = layout.marginLeft - layout.tablePadding;
var top = layout.tableTop - layout.tablePadding;
var width = layout.marginRight - (2 * layout.tablePadding);
var height = 20;
doc.rect(left, top, width, height, 'FD');
displayInvoiceHeader(doc, invoice, layout);
SetPdfColor('Black',doc);
var y = displayInvoiceItems(doc, invoice, layout);
var height1 = displayNotesAndTerms(doc, layout, invoice, y);
var height2 = displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
y += Math.max(height1, height2);
var left = layout.marginLeft - layout.tablePadding;
var top = y - layout.tablePadding;
var width = layout.marginRight - (2 * layout.tablePadding);
var height = 20;
if (NINJA.secondaryColor) {
setDocHexFill(doc, NINJA.secondaryColor);
setDocHexDraw(doc, NINJA.secondaryColor);
} else {
doc.setDrawColor(63,60,60);
doc.setFillColor(63,60,60);
}
doc.rect(left, top, width, height, 'FD');
doc.setFontType('bold');
SetPdfColor('White', doc);
doc.setFontSize(12);
var label = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
var labelX = layout.unitCostRight-(doc.getStringUnitWidth(label) * doc.internal.getFontSize());
doc.text(labelX, y+2, label);
doc.setFontType('normal');
var amount = formatMoney(invoice.balance_amount , currencyId);
headerLeft=layout.headerRight+400;
var amountX = layout.lineTotalRight - (doc.getStringUnitWidth(amount) * doc.internal.getFontSize());
doc.text(amountX, y+2, amount);"
]);
DB::table('invoice_designs')->where('id', 4)->update([
'javascript' => " var client = invoice.client;
var account = invoice.account;
var currencyId = client.currency_id;
layout.accountTop += 25;
layout.headerTop += 25;
layout.tableTop += 25;
if (invoice.image)
{
var left = layout.headerRight - invoice.imageWidth;
doc.addImage(invoice.image, 'JPEG', left, 50);
}
/* table header */
doc.setDrawColor(200,200,200);
doc.setFillColor(230,230,230);
var detailsHeight = getInvoiceDetailsHeight(invoice, layout);
var left = layout.headerLeft - layout.tablePadding;
var top = layout.headerTop + detailsHeight - layout.rowHeight - layout.tablePadding;
var width = layout.headerRight - layout.headerLeft + (2 * layout.tablePadding);
var height = layout.rowHeight + 1;
doc.rect(left, top, width, height, 'FD');
doc.setFontSize(10);
doc.setFontType('normal');
displayAccount(doc, invoice, layout.marginLeft, layout.accountTop, layout);
displayClient(doc, invoice, layout.marginLeft, layout.headerTop, layout);
displayInvoice(doc, invoice, layout.headerLeft, layout.headerTop, layout, layout.headerRight);
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));
var headerY = layout.headerTop;
var total = 0;
doc.setDrawColor(200,200,200);
doc.setFillColor(230,230,230);
var left = layout.marginLeft - layout.tablePadding;
var top = layout.tableTop - layout.tablePadding;
var width = layout.headerRight - layout.marginLeft + (2 * layout.tablePadding);
var height = layout.rowHeight + 2;
doc.rect(left, top, width, height, 'FD');
displayInvoiceHeader(doc, invoice, layout);
var y = displayInvoiceItems(doc, invoice, layout);
doc.setFontSize(10);
displayNotesAndTerms(doc, layout, invoice, y+20);
y += displaySubtotals(doc, layout, invoice, y+20, 480) + 20;
doc.setDrawColor(200,200,200);
doc.setFillColor(230,230,230);
var left = layout.footerLeft - layout.tablePadding;
var top = y - layout.tablePadding;
var width = layout.headerRight - layout.footerLeft + (2 * layout.tablePadding);
var height = layout.rowHeight + 2;
doc.rect(left, top, width, height, 'FD');
doc.setFontType('bold');
doc.text(layout.footerLeft, y, invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due);
total = formatMoney(invoice.balance_amount, currencyId);
var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
doc.text(totalX, y, total);
if (!invoice.is_pro) {
doc.setFontType('normal');
doc.text(layout.marginLeft, 790, 'Created by InvoiceNinja.com');
}"
]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoice_designs', function($table)
{
$table->dropColumn('javascript');
});
Schema::table('accounts', function($table)
{
$table->dropColumn('invoice_design');
});
}
}

View File

@ -1,63 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddInvoiceNumberSettings extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->text('invoice_number_prefix')->nullable();
$table->integer('invoice_number_counter')->default(1)->nullable();
$table->text('quote_number_prefix')->nullable();
$table->integer('quote_number_counter')->default(1)->nullable();
$table->boolean('share_counter')->default(true);
});
// set initial counter value for accounts with invoices
$accounts = DB::table('accounts')->lists('id');
foreach ($accounts as $accountId) {
$invoiceNumbers = DB::table('invoices')->where('account_id', $accountId)->lists('invoice_number');
$max = 0;
foreach ($invoiceNumbers as $invoiceNumber) {
$number = intval(preg_replace('/[^0-9]/', '', $invoiceNumber));
$max = max($max, $number);
}
DB::table('accounts')->where('id', $accountId)->update(['invoice_number_counter' => ++$max]);
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('invoice_number_prefix');
$table->dropColumn('invoice_number_counter');
$table->dropColumn('quote_number_prefix');
$table->dropColumn('quote_number_counter');
$table->dropColumn('share_counter');
});
}
}

View File

@ -1,29 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddDanishTranslation extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
DB::table('languages')->insert(['name' => 'Danish', 'locale' => 'da']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$language = Language::whereLocale('da')->first();
$language->delete();
}
}

View File

@ -1,44 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddAffiliatePrice extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('affiliates', function($table)
{
$table->decimal('price', 7, 2)->nullable();
});
Schema::table('licenses', function($table)
{
$table->unsignedInteger('product_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('affiliates', function($table)
{
$table->dropColumn('price');
});
Schema::table('licenses', function($table)
{
$table->dropColumn('product_id');
});
}
}

View File

@ -1,43 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCompanyIdNumber extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->string('id_number')->nullable();
});
Schema::table('clients', function($table)
{
$table->string('id_number')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('id_number');
});
Schema::table('clients', function($table)
{
$table->dropColumn('id_number');
});
}
}

View File

@ -1,31 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AllowNullClientCurrency extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('clients', function($table)
{
//DB::statement('ALTER TABLE `clients` MODIFY `currency_id` INTEGER UNSIGNED NULL;');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddDiscountType extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoices', function($table)
{
$table->boolean('is_amount_discount')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function($table)
{
$table->dropColumn('is_amount_discount');
});
}
}

View File

@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddEmailTemplates extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->text('email_template_invoice')->nullable();
$table->text('email_template_quote')->nullable();
$table->text('email_template_payment')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('email_template_invoice');
$table->dropColumn('email_template_quote');
$table->dropColumn('email_template_payment');
});
}
}

View File

@ -1,56 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class SupportTokenBilling extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->smallInteger('token_billing_type_id')->default(TOKEN_BILLING_OPT_IN);
});
Schema::create('account_gateway_tokens', function($table)
{
$table->increments('id');
$table->unsignedInteger('account_id');
$table->unsignedInteger('contact_id');
$table->unsignedInteger('account_gateway_id');
$table->unsignedInteger('client_id');
$table->string('token');
$table->timestamps();
$table->softDeletes();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$table->foreign('account_gateway_id')->references('id')->on('account_gateways')->onDelete('cascade');
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
});
DB::table('accounts')->update(['token_billing_type_id' => TOKEN_BILLING_OPT_IN]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('token_billing_type_id');
});
Schema::drop('account_gateway_tokens');
}
}

View File

@ -1,44 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddInvoiceFooter extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accounts', function($table)
{
$table->text('invoice_footer')->nullable();
});
Schema::table('invoices', function($table)
{
$table->text('invoice_footer')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropColumn('invoice_footer');
});
Schema::table('invoices', function($table)
{
$table->dropColumn('invoice_footer');
});
}
}

View File

@ -1,54 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddTokens extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('account_tokens', function($table)
{
$table->increments('id');
$table->unsignedInteger('account_id')->index();
$table->unsignedInteger('user_id');
$table->timestamps();
$table->softDeletes();
$table->string('name')->nullable();
$table->string('token')->unique();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedInteger('public_id')->nullable();
$table->unique(['account_id', 'public_id']);
});
Schema::table('activities', function($table)
{
$table->unsignedInteger('token_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('account_tokens');
Schema::table('activities', function($table)
{
$table->dropColumn('token_id');
});
}
}

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddIpToActivity extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('activities', function($table)
{
$table->string('ip')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('activities', function($table)
{
$table->dropColumn('ip');
});
}
}

Some files were not shown because too many files have changed in this diff Show More