mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merging: Bugfixed version of Vendor / Expense module #635
This commit is contained in:
commit
9287118cd0
2
.gitignore
vendored
2
.gitignore
vendored
@ -34,3 +34,5 @@ tests/_bootstrap.php
|
||||
|
||||
# composer stuff
|
||||
/c3.php
|
||||
|
||||
_ide_helper.php
|
22
app/Events/ExpenseWasArchived.php
Normal file
22
app/Events/ExpenseWasArchived.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ExpenseWasArchived extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $expense;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($expense)
|
||||
{
|
||||
$this->expense = $expense;
|
||||
}
|
||||
|
||||
}
|
21
app/Events/ExpenseWasCreated.php
Normal file
21
app/Events/ExpenseWasCreated.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ExpenseWasCreated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $expense;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($expense)
|
||||
{
|
||||
$this->expense = $expense;
|
||||
}
|
||||
}
|
23
app/Events/ExpenseWasDeleted.php
Normal file
23
app/Events/ExpenseWasDeleted.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ExpenseWasDeleted extends Event {
|
||||
// Expenses
|
||||
use SerializesModels;
|
||||
|
||||
public $expense;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($expense)
|
||||
{
|
||||
$this->expense = $expense;
|
||||
}
|
||||
|
||||
}
|
23
app/Events/ExpenseWasRestored.php
Normal file
23
app/Events/ExpenseWasRestored.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ExpenseWasRestored extends Event {
|
||||
// Expenses
|
||||
use SerializesModels;
|
||||
|
||||
public $expense;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($expense)
|
||||
{
|
||||
$this->expense = $expense;
|
||||
}
|
||||
|
||||
}
|
21
app/Events/ExpenseWasUpdated.php
Normal file
21
app/Events/ExpenseWasUpdated.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ExpenseWasUpdated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $expense;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($expense)
|
||||
{
|
||||
$this->expense = $expense;
|
||||
}
|
||||
}
|
22
app/Events/VendorWasArchived.php
Normal file
22
app/Events/VendorWasArchived.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasArchived extends Event
|
||||
{
|
||||
// vendor
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
22
app/Events/VendorWasCreated.php
Normal file
22
app/Events/VendorWasCreated.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasCreated extends Event
|
||||
{
|
||||
// vendor
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
22
app/Events/VendorWasDeleted.php
Normal file
22
app/Events/VendorWasDeleted.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasDeleted extends Event
|
||||
{
|
||||
// vendor
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
22
app/Events/VendorWasRestored.php
Normal file
22
app/Events/VendorWasRestored.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasRestored extends Event
|
||||
{
|
||||
// vendor
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
21
app/Events/VendorWasUpdated.php
Normal file
21
app/Events/VendorWasUpdated.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
// vendor
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasUpdated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ use App\Models\Account;
|
||||
use App\Models\Gateway;
|
||||
use App\Models\InvoiceDesign;
|
||||
use App\Models\TaxRate;
|
||||
use App\Models\PaymentTerm;
|
||||
use App\Ninja\Repositories\AccountRepository;
|
||||
use App\Ninja\Repositories\ReferralRepository;
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
@ -158,6 +159,8 @@ class AccountController extends BaseController
|
||||
return self::showProducts();
|
||||
} elseif ($section === ACCOUNT_TAX_RATES) {
|
||||
return self::showTaxRates();
|
||||
} elseif ($section === ACCOUNT_PAYMENT_TERMS) {
|
||||
return self::showPaymentTerms();
|
||||
} elseif ($section === ACCOUNT_SYSTEM_SETTINGS) {
|
||||
return self::showSystemSettings();
|
||||
} else {
|
||||
@ -313,6 +316,17 @@ class AccountController extends BaseController
|
||||
return View::make('accounts.tax_rates', $data);
|
||||
}
|
||||
|
||||
private function showPaymentTerms()
|
||||
{
|
||||
$data = [
|
||||
'account' => Auth::user()->account,
|
||||
'title' => trans('texts.payment_terms'),
|
||||
'taxRates' => PaymentTerm::scope()->get(['id', 'name', 'num_days']),
|
||||
];
|
||||
|
||||
return View::make('accounts.payment_terms', $data);
|
||||
}
|
||||
|
||||
private function showInvoiceDesign($section)
|
||||
{
|
||||
$account = Auth::user()->account->load('country');
|
||||
@ -322,13 +336,15 @@ class AccountController extends BaseController
|
||||
$invoiceItem = new stdClass();
|
||||
|
||||
$client->name = 'Sample Client';
|
||||
$client->address1 = '';
|
||||
$client->city = '';
|
||||
$client->state = '';
|
||||
$client->postal_code = '';
|
||||
$client->work_phone = '';
|
||||
$client->work_email = '';
|
||||
|
||||
$client->address1 = 'address 1';
|
||||
$client->city = ' city';
|
||||
$client->state = 'state';
|
||||
$client->postal_code = 'postal code';
|
||||
$client->work_phone = 'work phone';
|
||||
$client->work_email = 'work email';
|
||||
$client->id_number = 'cleint id';
|
||||
$client->vat_number = 'vat number';
|
||||
|
||||
$invoice->invoice_number = '0000';
|
||||
$invoice->invoice_date = Utils::fromSqlDate(date('Y-m-d'));
|
||||
$invoice->account = json_decode($account->toJson());
|
||||
@ -347,7 +363,7 @@ class AccountController extends BaseController
|
||||
|
||||
$invoice->client = $client;
|
||||
$invoice->invoice_items = [$invoiceItem];
|
||||
|
||||
|
||||
$data['account'] = $account;
|
||||
$data['invoice'] = $invoice;
|
||||
$data['invoiceLabels'] = json_decode($account->invoice_labels) ?: [];
|
||||
@ -355,7 +371,7 @@ class AccountController extends BaseController
|
||||
$data['invoiceDesigns'] = InvoiceDesign::getDesigns();
|
||||
$data['invoiceFonts'] = Cache::get('fonts');
|
||||
$data['section'] = $section;
|
||||
|
||||
|
||||
$design = false;
|
||||
foreach ($data['invoiceDesigns'] as $item) {
|
||||
if ($item->id == $account->invoice_design_id) {
|
||||
@ -444,6 +460,8 @@ class AccountController extends BaseController
|
||||
return AccountController::saveProducts();
|
||||
} elseif ($section === ACCOUNT_TAX_RATES) {
|
||||
return AccountController::saveTaxRates();
|
||||
} elseif ($section === ACCOUNT_PAYMENT_TERMS) {
|
||||
return AccountController::savePaymetTerms();
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,7 +713,7 @@ class AccountController extends BaseController
|
||||
$account->primary_color = Input::get('primary_color');
|
||||
$account->secondary_color = Input::get('secondary_color');
|
||||
$account->invoice_design_id = Input::get('invoice_design_id');
|
||||
|
||||
|
||||
if (Input::has('font_size')) {
|
||||
$account->font_size = intval(Input::get('font_size'));
|
||||
}
|
||||
|
@ -121,12 +121,15 @@ class BaseAPIController extends Controller
|
||||
} elseif ($include == 'clients') {
|
||||
$data[] = 'clients.contacts';
|
||||
$data[] = 'clients.user';
|
||||
} elseif ($include) {
|
||||
} elseif ($include == 'vendors') {
|
||||
$data[] = 'vendors.vendorcontacts';
|
||||
$data[] = 'vendors.user';
|
||||
}
|
||||
elseif ($include) {
|
||||
$data[] = $include;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,11 +6,14 @@ use View;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\VendorActivity;
|
||||
use App\Models\ExpenseActivity;
|
||||
|
||||
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,
|
||||
@ -68,6 +71,19 @@ class DashboardController extends BaseController
|
||||
->take(50)
|
||||
->get();
|
||||
|
||||
$vendoractivities = VendorActivity::where('vendor_activities.account_id', '=', Auth::user()->account_id)
|
||||
->with('vendor.vendorcontacts', 'user', 'account')
|
||||
->where('activity_type_id', '>', 0)
|
||||
->orderBy('created_at', 'desc')
|
||||
->take(50)
|
||||
->get();
|
||||
|
||||
$expenseactivities = ExpenseActivity::where('expense_activities.account_id', '=', Auth::user()->account_id)
|
||||
->where('activity_type_id', '>', 0)
|
||||
->orderBy('created_at', 'desc')
|
||||
->take(50)
|
||||
->get();
|
||||
|
||||
$pastDue = DB::table('invoices')
|
||||
->leftJoin('clients', 'clients.id', '=', 'invoices.client_id')
|
||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||
@ -141,6 +157,8 @@ class DashboardController extends BaseController
|
||||
'payments' => $payments,
|
||||
'title' => trans('texts.dashboard'),
|
||||
'hasQuotes' => $hasQuotes,
|
||||
'vendoractivities' => $vendoractivities,
|
||||
'expenseactivities' => $expenseactivities,
|
||||
];
|
||||
|
||||
return View::make('dashboard', $data);
|
||||
|
27
app/Http/Controllers/ExpenseActivityController.php
Normal file
27
app/Http/Controllers/ExpenseActivityController.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
// vendor
|
||||
use Auth;
|
||||
use DB;
|
||||
use Datatable;
|
||||
use Utils;
|
||||
use View;
|
||||
use App\Models\Expense;
|
||||
use App\Models\ExpenseActivity;
|
||||
use App\Services\ExpenseActivityService;
|
||||
|
||||
class ExpenseActivityController extends BaseController
|
||||
{
|
||||
protected $activityService;
|
||||
|
||||
public function __construct(ExpenseActivityService $activityService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->activityService = $activityService;
|
||||
}
|
||||
|
||||
public function getDatatable($vendorPublicId)
|
||||
{
|
||||
return $this->activityService->getDatatable($vendorPublicId);
|
||||
}
|
||||
}
|
244
app/Http/Controllers/ExpenseApiController.php
Normal file
244
app/Http/Controllers/ExpenseApiController.php
Normal file
@ -0,0 +1,244 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Debugbar;
|
||||
use DB;
|
||||
use Auth;
|
||||
use Datatable;
|
||||
use Utils;
|
||||
use View;
|
||||
use URL;
|
||||
use Validator;
|
||||
use Input;
|
||||
use Session;
|
||||
use Redirect;
|
||||
use Cache;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Client;
|
||||
use App\Services\ExpenseService;
|
||||
use App\Ninja\Repositories\ExpenseRepository;
|
||||
use App\Http\Requests\CreateExpenseRequest;
|
||||
use App\Http\Requests\UpdateExpenseRequest;
|
||||
|
||||
class ExpenseApiController extends BaseController
|
||||
{
|
||||
// Expenses
|
||||
protected $expenseRepo;
|
||||
protected $expenseService;
|
||||
|
||||
public function __construct(ExpenseRepository $expenseRepo, ExpenseService $expenseService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->expenseRepo = $expenseRepo;
|
||||
$this->expenseService = $expenseService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('list', array(
|
||||
'entityType' => ENTITY_EXPENSE,
|
||||
'title' => trans('texts.expenses'),
|
||||
'sortCol' => '1',
|
||||
'columns' => Utils::trans([
|
||||
'checkbox',
|
||||
'vendor',
|
||||
'expense_amount',
|
||||
'expense_date',
|
||||
'public_notes',
|
||||
'is_invoiced',
|
||||
'should_be_invoiced',
|
||||
''
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
||||
public function getDatatable($expensePublicId = null)
|
||||
{
|
||||
return $this->expenseService->getDatatable($expensePublicId, Input::get('sSearch'));
|
||||
}
|
||||
|
||||
public function getDatatableVendor($vendorPublicId = null)
|
||||
{
|
||||
return $this->expenseService->getDatatableVendor($vendorPublicId);
|
||||
}
|
||||
|
||||
public function create($vendorPublicId = 0)
|
||||
{
|
||||
if($vendorPublicId != 0) {
|
||||
$vendor = Vendor::scope($vendorPublicId)->with('vendorcontacts')->firstOrFail();
|
||||
} else {
|
||||
$vendor = null;
|
||||
}
|
||||
$data = array(
|
||||
'vendorPublicId' => Input::old('vendor') ? Input::old('vendor') : $vendorPublicId,
|
||||
'expense' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'expenses',
|
||||
'title' => trans('texts.new_expense'),
|
||||
'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(),
|
||||
'vendor' => $vendor,
|
||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||
'clientPublicId' => null,
|
||||
);
|
||||
|
||||
$data = array_merge($data, self::getViewModel());
|
||||
|
||||
return View::make('expenses.edit', $data);
|
||||
}
|
||||
|
||||
public function edit($publicId)
|
||||
{
|
||||
$expense = Expense::scope($publicId)->firstOrFail();
|
||||
$expense->expense_date = Utils::fromSqlDate($expense->expense_date);
|
||||
|
||||
$data = array(
|
||||
'vendor' => null,
|
||||
'expense' => $expense,
|
||||
'method' => 'PUT',
|
||||
'url' => 'expenses/'.$publicId,
|
||||
'title' => 'Edit Expense',
|
||||
'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(),
|
||||
'vendorPublicId' => $expense->vendor_id,
|
||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||
'clientPublicId' => $expense->invoice_client_id,
|
||||
);
|
||||
|
||||
$data = array_merge($data, self::getViewModel());
|
||||
|
||||
if (Auth::user()->account->isNinjaAccount()) {
|
||||
if ($account = Account::whereId($client->public_id)->first()) {
|
||||
$data['proPlanPaid'] = $account['pro_plan_paid'];
|
||||
}
|
||||
}
|
||||
|
||||
return View::make('expenses.edit', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update(UpdateExpenseRequest $request)
|
||||
{
|
||||
$client = $this->expenseRepo->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.updated_expense'));
|
||||
|
||||
return redirect()->to('expenses');
|
||||
}
|
||||
|
||||
public function store(CreateExpenseRequest $request)
|
||||
{
|
||||
$expense = $this->expenseRepo->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_expense'));
|
||||
|
||||
return redirect()->to('expenses');
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
|
||||
switch($action)
|
||||
{
|
||||
case 'invoice':
|
||||
$expenses = Expense::scope($ids)->get();
|
||||
$clientPublicId = null;
|
||||
$data = [];
|
||||
|
||||
// Validate that either all expenses do not have a client or if there is a client, it is the same client
|
||||
foreach ($expenses as $expense)
|
||||
{
|
||||
if ($expense->client_id) {
|
||||
if (!$clientPublicId) {
|
||||
$clientPublicId = $expense->client_id;
|
||||
} else if ($clientPublicId != $expense->client_id) {
|
||||
Session::flash('error', trans('texts.expense_error_multiple_clients'));
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
}
|
||||
|
||||
if ($expense->invoice_id) {
|
||||
Session::flash('error', trans('texts.expense_error_invoiced'));
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
|
||||
if ($expense->should_be_invoiced == 0) {
|
||||
Session::flash('error', trans('texts.expense_error_should_not_be_invoiced'));
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
|
||||
$account = Auth::user()->account;
|
||||
$data[] = [
|
||||
'publicId' => $expense->public_id,
|
||||
'description' => $expense->public_notes,
|
||||
'qty' => 1,
|
||||
'cost' => $expense->amount,
|
||||
];
|
||||
}
|
||||
|
||||
return Redirect::to("invoices/create/{$clientPublicId}")->with('expenses', $data);
|
||||
break;
|
||||
|
||||
default:
|
||||
$count = $this->expenseService->bulk($ids, $action);
|
||||
}
|
||||
|
||||
if ($count > 0) {
|
||||
$message = Utils::pluralize($action.'d_expense', $count);
|
||||
Session::flash('message', $message);
|
||||
}
|
||||
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
|
||||
private static function getViewModel()
|
||||
{
|
||||
return [
|
||||
'data' => Input::old('data'),
|
||||
'account' => Auth::user()->account,
|
||||
'sizes' => Cache::get('sizes'),
|
||||
'paymentTerms' => Cache::get('paymentTerms'),
|
||||
'industries' => Cache::get('industries'),
|
||||
'currencies' => Cache::get('currencies'),
|
||||
'languages' => Cache::get('languages'),
|
||||
'countries' => Cache::get('countries'),
|
||||
'customLabel1' => Auth::user()->account->custom_vendor_label1,
|
||||
'customLabel2' => Auth::user()->account->custom_vendor_label2,
|
||||
];
|
||||
}
|
||||
|
||||
public function show($publicId)
|
||||
{
|
||||
$expense = Expense::withTrashed()->scope($publicId)->firstOrFail();
|
||||
|
||||
if($expense) {
|
||||
Utils::trackViewed($expense->getDisplayName(), 'expense');
|
||||
}
|
||||
|
||||
$actionLinks = [
|
||||
['label' => trans('texts.new_expense'), 'url' => '/expenses/create/']
|
||||
];
|
||||
|
||||
$data = array(
|
||||
'actionLinks' => $actionLinks,
|
||||
'showBreadcrumbs' => false,
|
||||
'expense' => $expense,
|
||||
'credit' =>0,
|
||||
'vendor' => $expense->vendor,
|
||||
'title' => trans('texts.view_expense',['expense' => $expense->public_id]),
|
||||
);
|
||||
|
||||
return View::make('expenses.show', $data);
|
||||
}
|
||||
}
|
239
app/Http/Controllers/ExpenseController.php
Normal file
239
app/Http/Controllers/ExpenseController.php
Normal file
@ -0,0 +1,239 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Debugbar;
|
||||
use DB;
|
||||
use Auth;
|
||||
use Datatable;
|
||||
use Utils;
|
||||
use View;
|
||||
use URL;
|
||||
use Validator;
|
||||
use Input;
|
||||
use Session;
|
||||
use Redirect;
|
||||
use Cache;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Client;
|
||||
use App\Services\ExpenseService;
|
||||
use App\Ninja\Repositories\ExpenseRepository;
|
||||
use App\Http\Requests\CreateExpenseRequest;
|
||||
use App\Http\Requests\UpdateExpenseRequest;
|
||||
|
||||
class ExpenseController extends BaseController
|
||||
{
|
||||
// Expenses
|
||||
protected $expenseRepo;
|
||||
protected $expenseService;
|
||||
|
||||
public function __construct(ExpenseRepository $expenseRepo, ExpenseService $expenseService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->expenseRepo = $expenseRepo;
|
||||
$this->expenseService = $expenseService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('list', array(
|
||||
'entityType' => ENTITY_EXPENSE,
|
||||
'title' => trans('texts.expenses'),
|
||||
'sortCol' => '1',
|
||||
'columns' => Utils::trans([
|
||||
'checkbox',
|
||||
'vendor',
|
||||
'expense_amount',
|
||||
'expense_date',
|
||||
'public_notes',
|
||||
'is_invoiced',
|
||||
'should_be_invoiced',
|
||||
''
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
||||
public function getDatatable($expensePublicId = null)
|
||||
{
|
||||
return $this->expenseService->getDatatable($expensePublicId, Input::get('sSearch'));
|
||||
}
|
||||
|
||||
public function create($vendorPublicId = 0)
|
||||
{
|
||||
if($vendorPublicId != 0) {
|
||||
$vendor = Vendor::scope($vendorPublicId)->with('vendorcontacts')->firstOrFail();
|
||||
} else {
|
||||
$vendor = null;
|
||||
}
|
||||
$data = array(
|
||||
'vendorPublicId' => Input::old('vendor') ? Input::old('vendor') : $vendorPublicId,
|
||||
'expense' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'expenses',
|
||||
'title' => trans('texts.new_expense'),
|
||||
'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(),
|
||||
'vendor' => $vendor,
|
||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||
'clientPublicId' => null,
|
||||
);
|
||||
|
||||
$data = array_merge($data, self::getViewModel());
|
||||
|
||||
return View::make('expenses.edit', $data);
|
||||
}
|
||||
|
||||
public function edit($publicId)
|
||||
{
|
||||
$expense = Expense::scope($publicId)->firstOrFail();
|
||||
$expense->expense_date = Utils::fromSqlDate($expense->expense_date);
|
||||
|
||||
$data = array(
|
||||
'vendor' => null,
|
||||
'expense' => $expense,
|
||||
'method' => 'PUT',
|
||||
'url' => 'expenses/'.$publicId,
|
||||
'title' => 'Edit Expense',
|
||||
'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(),
|
||||
'vendorPublicId' => $expense->vendor_id,
|
||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||
'clientPublicId' => $expense->invoice_client_id,
|
||||
);
|
||||
|
||||
$data = array_merge($data, self::getViewModel());
|
||||
|
||||
if (Auth::user()->account->isNinjaAccount()) {
|
||||
if ($account = Account::whereId($client->public_id)->first()) {
|
||||
$data['proPlanPaid'] = $account['pro_plan_paid'];
|
||||
}
|
||||
}
|
||||
|
||||
return View::make('expenses.edit', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update(UpdateExpenseRequest $request)
|
||||
{
|
||||
$client = $this->expenseRepo->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.updated_expense'));
|
||||
|
||||
return redirect()->to('expenses');
|
||||
}
|
||||
|
||||
public function store(CreateExpenseRequest $request)
|
||||
{
|
||||
$expense = $this->expenseRepo->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_expense'));
|
||||
|
||||
return redirect()->to('expenses');
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
|
||||
switch($action)
|
||||
{
|
||||
case 'invoice':
|
||||
$expenses = Expense::scope($ids)->get();
|
||||
$clientPublicId = null;
|
||||
$data = [];
|
||||
|
||||
// Validate that either all expenses do not have a client or if there is a client, it is the same client
|
||||
foreach ($expenses as $expense)
|
||||
{
|
||||
if ($expense->client_id) {
|
||||
if (!$clientPublicId) {
|
||||
$clientPublicId = $expense->client_id;
|
||||
} else if ($clientPublicId != $expense->client_id) {
|
||||
Session::flash('error', trans('texts.expense_error_multiple_clients'));
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
}
|
||||
|
||||
if ($expense->invoice_id) {
|
||||
Session::flash('error', trans('texts.expense_error_invoiced'));
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
|
||||
if ($expense->should_be_invoiced == 0) {
|
||||
Session::flash('error', trans('texts.expense_error_should_not_be_invoiced'));
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
|
||||
$account = Auth::user()->account;
|
||||
$data[] = [
|
||||
'publicId' => $expense->public_id,
|
||||
'description' => $expense->public_notes,
|
||||
'qty' => 1,
|
||||
'cost' => $expense->amount,
|
||||
];
|
||||
}
|
||||
|
||||
return Redirect::to("invoices/create/{$clientPublicId}")->with('expenses', $data);
|
||||
break;
|
||||
|
||||
default:
|
||||
$count = $this->expenseService->bulk($ids, $action);
|
||||
}
|
||||
|
||||
if ($count > 0) {
|
||||
$message = Utils::pluralize($action.'d_expense', $count);
|
||||
Session::flash('message', $message);
|
||||
}
|
||||
|
||||
return Redirect::to('expenses');
|
||||
}
|
||||
|
||||
private static function getViewModel()
|
||||
{
|
||||
return [
|
||||
'data' => Input::old('data'),
|
||||
'account' => Auth::user()->account,
|
||||
'sizes' => Cache::get('sizes'),
|
||||
'paymentTerms' => Cache::get('paymentTerms'),
|
||||
'industries' => Cache::get('industries'),
|
||||
'currencies' => Cache::get('currencies'),
|
||||
'languages' => Cache::get('languages'),
|
||||
'countries' => Cache::get('countries'),
|
||||
'customLabel1' => Auth::user()->account->custom_vendor_label1,
|
||||
'customLabel2' => Auth::user()->account->custom_vendor_label2,
|
||||
];
|
||||
}
|
||||
|
||||
public function show($publicId)
|
||||
{
|
||||
$expense = Expense::withTrashed()->scope($publicId)->firstOrFail();
|
||||
|
||||
if($expense) {
|
||||
Utils::trackViewed($expense->getDisplayName(), 'expense');
|
||||
}
|
||||
|
||||
$actionLinks = [
|
||||
['label' => trans('texts.new_expense'), 'url' => '/expenses/create/']
|
||||
];
|
||||
|
||||
$data = array(
|
||||
'actionLinks' => $actionLinks,
|
||||
'showBreadcrumbs' => false,
|
||||
'expense' => $expense,
|
||||
'credit' =>0,
|
||||
'vendor' => $expense->vendor,
|
||||
'title' => trans('texts.view_expense',['expense' => $expense->public_id]),
|
||||
);
|
||||
|
||||
return View::make('expenses.show', $data);
|
||||
}
|
||||
}
|
@ -13,6 +13,8 @@ use App\Models\Credit;
|
||||
use App\Models\Task;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorContact;
|
||||
|
||||
class ExportController extends BaseController
|
||||
{
|
||||
@ -155,6 +157,25 @@ class ExportController extends BaseController
|
||||
->get();
|
||||
}
|
||||
|
||||
|
||||
if ($request->input(ENTITY_VENDOR)) {
|
||||
$data['clients'] = Vendor::scope()
|
||||
->with('user', 'vendorcontacts', 'country')
|
||||
->withTrashed()
|
||||
->where('is_deleted', '=', false)
|
||||
->get();
|
||||
|
||||
$data['vendor_contacts'] = VendorContact::scope()
|
||||
->with('user', 'vendor.contacts')
|
||||
->withTrashed()
|
||||
->get();
|
||||
/*
|
||||
$data['expenses'] = Credit::scope()
|
||||
->with('user', 'client.contacts')
|
||||
->get();
|
||||
*/
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -319,6 +319,7 @@ class InvoiceController extends BaseController
|
||||
'recurringDueDateHelp' => $recurringDueDateHelp,
|
||||
'invoiceLabels' => Auth::user()->account->getInvoiceLabels(),
|
||||
'tasks' => Session::get('tasks') ? json_encode(Session::get('tasks')) : null,
|
||||
'expenses' => Session::get('expenses') ? json_encode(Session::get('expenses')) : null,
|
||||
];
|
||||
|
||||
}
|
||||
|
103
app/Http/Controllers/PaymentTermController.php
Normal file
103
app/Http/Controllers/PaymentTermController.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Str;
|
||||
use DB;
|
||||
use Datatable;
|
||||
use Utils;
|
||||
use URL;
|
||||
use View;
|
||||
use Input;
|
||||
use Session;
|
||||
use Redirect;
|
||||
|
||||
use App\Models\PaymentTerm;
|
||||
use App\Ninja\Repositories\VendorRepository;
|
||||
use App\Services\PaymentService;
|
||||
use App\Services\PaymentTermService;
|
||||
|
||||
class PaymentTermController extends BaseController
|
||||
{
|
||||
protected $paymentTermService;
|
||||
|
||||
public function __construct(PaymentTermService $paymentTermService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->paymentTermService = $paymentTermService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return Redirect::to('settings/' . ACCOUNT_PAYMENT_TERMS);
|
||||
}
|
||||
|
||||
public function getDatatable()
|
||||
{
|
||||
return $this->paymentTermService->getDatatable();
|
||||
}
|
||||
|
||||
public function edit($publicId)
|
||||
{
|
||||
$data = [
|
||||
'paymentTerm' => PaymentTerm::scope($publicId)->firstOrFail(),
|
||||
'method' => 'PUT',
|
||||
'url' => 'payment_terms/'.$publicId,
|
||||
'title' => trans('texts.edit_payment_term'),
|
||||
];
|
||||
|
||||
return View::make('accounts.payment_term', $data);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$data = [
|
||||
'paymentTerm' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'payment_terms',
|
||||
'title' => trans('texts.create_payment_term'),
|
||||
];
|
||||
|
||||
return View::make('accounts.payment_term', $data);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
public function update($publicId)
|
||||
{
|
||||
return $this->save($publicId);
|
||||
}
|
||||
|
||||
private function save($publicId = false)
|
||||
{
|
||||
if ($publicId) {
|
||||
$paymentTerm = PaymentTerm::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
$paymentTerm = PaymentTerm::createNew();
|
||||
}
|
||||
|
||||
$paymentTerm->name = trim(Input::get('name'));
|
||||
$paymentTerm->num_days = Utils::parseInt(Input::get('num_days'));
|
||||
$paymentTerm->save();
|
||||
|
||||
$message = $publicId ? trans('texts.updated_payment_term') : trans('texts.created_payment_term');
|
||||
Session::flash('message', $message);
|
||||
|
||||
return Redirect::to('settings/' . ACCOUNT_PAYMENT_TERMS);
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('bulk_action');
|
||||
$ids = Input::get('bulk_public_id');
|
||||
$count = $this->paymentTermService->bulk($ids, $action);
|
||||
|
||||
Session::flash('message', trans('texts.archived_payment_term'));
|
||||
|
||||
return Redirect::to('settings/' . ACCOUNT_PAYMENT_TERMS);
|
||||
}
|
||||
|
||||
}
|
198
app/Http/Controllers/PublicVendorController.php
Normal file
198
app/Http/Controllers/PublicVendorController.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
// vendor
|
||||
use Auth;
|
||||
use DB;
|
||||
use Input;
|
||||
use Utils;
|
||||
use Datatable;
|
||||
use App\Models\VendorInvitation;
|
||||
use App\Ninja\Repositories\VendorActivityRepository;
|
||||
|
||||
class PublicVendorController extends BaseController
|
||||
{
|
||||
private $activityRepo;
|
||||
private $vendor;
|
||||
|
||||
public function __construct(VendorActivityRepository $activityRepo)
|
||||
{
|
||||
$this->activityRepo = $activityRepo;
|
||||
$this->vendor = $activityRepo->vendor;
|
||||
}
|
||||
|
||||
public function dashboard()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return $this->returnError();
|
||||
}
|
||||
|
||||
$account = $invitation->account;
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'account' => $account,
|
||||
'client' => $this->vendor,
|
||||
'hideLogo' => $account->isWhiteLabel(),
|
||||
'clientViewCSS' => $account->clientViewCSS(),
|
||||
];
|
||||
|
||||
return response()->view('invited.dashboard', $data);
|
||||
}
|
||||
|
||||
public function activityDatatable()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$query = $this->activityRepo->findByClientId($invoice->client_id);
|
||||
$query->where('vendor_activities.adjustment', '!=', 0);
|
||||
|
||||
return Datatable::query($query)
|
||||
->addColumn('vendor_activities.id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
||||
->addColumn('activity_type_id', function ($model) {
|
||||
$data = [
|
||||
'client' => Utils::getClientDisplayName($model),
|
||||
'user' => $model->is_system ? ('<i>' . trans('texts.system') . '</i>') : ($model->user_first_name . ' ' . $model->user_last_name),
|
||||
'invoice' => trans('texts.invoice') . ' ' . $model->invoice,
|
||||
'contact' => Utils::getClientDisplayName($model),
|
||||
'payment' => trans('texts.payment') . ($model->payment ? ' ' . $model->payment : ''),
|
||||
];
|
||||
|
||||
return trans("texts.activity_{$model->activity_type_id}", $data);
|
||||
})
|
||||
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); })
|
||||
->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id, $model->country_id) : ''; })
|
||||
->make();
|
||||
}
|
||||
|
||||
public function invoiceIndex()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return $this->returnError();
|
||||
}
|
||||
$account = $invitation->account;
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'hideLogo' => $account->isWhiteLabel(),
|
||||
'clientViewCSS' => $account->clientViewCSS(),
|
||||
'title' => trans('texts.invoices'),
|
||||
'entityType' => ENTITY_INVOICE,
|
||||
'columns' => Utils::trans(['invoice_number', 'invoice_date', 'invoice_total', 'balance_due', 'due_date']),
|
||||
];
|
||||
|
||||
return response()->view('public_list', $data);
|
||||
}
|
||||
|
||||
public function invoiceDatatable()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_INVOICE, Input::get('sSearch'));
|
||||
}
|
||||
|
||||
|
||||
public function paymentIndex()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return $this->returnError();
|
||||
}
|
||||
$account = $invitation->account;
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'hideLogo' => $account->isWhiteLabel(),
|
||||
'clientViewCSS' => $account->clientViewCSS(),
|
||||
'entityType' => ENTITY_PAYMENT,
|
||||
'title' => trans('texts.payments'),
|
||||
'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date'])
|
||||
];
|
||||
|
||||
return response()->view('public_list', $data);
|
||||
}
|
||||
|
||||
public function paymentDatatable()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return false;
|
||||
}
|
||||
$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, $model->country_id); })
|
||||
->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); })
|
||||
->make();
|
||||
}
|
||||
|
||||
public function quoteIndex()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return $this->returnError();
|
||||
}
|
||||
$account = $invitation->account;
|
||||
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
|
||||
|
||||
$data = [
|
||||
'color' => $color,
|
||||
'hideLogo' => $account->isWhiteLabel(),
|
||||
'clientViewCSS' => $account->clientViewCSS(),
|
||||
'title' => trans('texts.quotes'),
|
||||
'entityType' => ENTITY_QUOTE,
|
||||
'columns' => Utils::trans(['quote_number', 'quote_date', 'quote_total', 'due_date']),
|
||||
];
|
||||
|
||||
return response()->view('public_list', $data);
|
||||
}
|
||||
|
||||
|
||||
public function quoteDatatable()
|
||||
{
|
||||
if (!$invitation = $this->getInvitation()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->invoiceRepo->getClientDatatable($invitation->contact_id, ENTITY_QUOTE, Input::get('sSearch'));
|
||||
}
|
||||
|
||||
private function returnError()
|
||||
{
|
||||
return response()->view('error', [
|
||||
'error' => trans('texts.invoice_not_found'),
|
||||
'hideHeader' => true,
|
||||
'clientViewCSS' => $account->clientViewCSS(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function getInvitation()
|
||||
{
|
||||
$invitationKey = session('invitation_key');
|
||||
|
||||
if (!$invitationKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$invitation = VendorInvitation::where('invitation_key', '=', $invitationKey)->first();
|
||||
|
||||
if (!$invitation || $invitation->is_deleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
if (!$invoice || $invoice->is_deleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $invitation;
|
||||
}
|
||||
|
||||
}
|
27
app/Http/Controllers/VendorActivityController.php
Normal file
27
app/Http/Controllers/VendorActivityController.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
// vendor
|
||||
use Auth;
|
||||
use DB;
|
||||
use Datatable;
|
||||
use Utils;
|
||||
use View;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorActivity;
|
||||
use App\Services\VendorActivityService;
|
||||
|
||||
class VendorActivityController extends BaseController
|
||||
{
|
||||
protected $activityService;
|
||||
|
||||
public function __construct(VendorActivityService $activityService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->activityService = $activityService;
|
||||
}
|
||||
|
||||
public function getDatatable($vendorPublicId)
|
||||
{
|
||||
return $this->activityService->getDatatable($vendorPublicId);
|
||||
}
|
||||
}
|
94
app/Http/Controllers/VendorApiController.php
Normal file
94
app/Http/Controllers/VendorApiController.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
// vendor
|
||||
use Utils;
|
||||
use Response;
|
||||
use Input;
|
||||
use Auth;
|
||||
use App\Models\Vendor;
|
||||
use App\Ninja\Repositories\VendorRepository;
|
||||
use App\Http\Requests\CreateVendorRequest;
|
||||
use App\Http\Controllers\BaseAPIController;
|
||||
use App\Ninja\Transformers\VendorTransformer;
|
||||
|
||||
class VendorApiController extends BaseAPIController
|
||||
{
|
||||
protected $vendorRepo;
|
||||
|
||||
public function __construct(VendorRepository $vendorRepo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->vendorRepo = $vendorRepo;
|
||||
}
|
||||
|
||||
public function ping()
|
||||
{
|
||||
$headers = Utils::getApiHeaders();
|
||||
|
||||
return Response::make('', 200, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @SWG\Get(
|
||||
* path="/vendors",
|
||||
* summary="List of vendors",
|
||||
* tags={"vendor"},
|
||||
* @SWG\Response(
|
||||
* response=200,
|
||||
* description="A list with vendors",
|
||||
* @SWG\Schema(type="array", @SWG\Items(ref="#/definitions/Vendor"))
|
||||
* ),
|
||||
* @SWG\Response(
|
||||
* response="default",
|
||||
* description="an ""unexpected"" error"
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$vendors = Vendor::scope()
|
||||
->with($this->getIncluded())
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate();
|
||||
|
||||
$transformer = new VendorTransformer(Auth::user()->account, Input::get('serializer'));
|
||||
$paginator = Vendor::scope()->paginate();
|
||||
$data = $this->createCollection($vendors, $transformer, ENTITY_VENDOR, $paginator);
|
||||
|
||||
return $this->response($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @SWG\Post(
|
||||
* path="/vendors",
|
||||
* tags={"vendor"},
|
||||
* summary="Create a vendor",
|
||||
* @SWG\Parameter(
|
||||
* in="body",
|
||||
* name="body",
|
||||
* @SWG\Schema(ref="#/definitions/Vendor")
|
||||
* ),
|
||||
* @SWG\Response(
|
||||
* response=200,
|
||||
* description="New vendor",
|
||||
* @SWG\Schema(type="object", @SWG\Items(ref="#/definitions/Vendor"))
|
||||
* ),
|
||||
* @SWG\Response(
|
||||
* response="default",
|
||||
* description="an ""unexpected"" error"
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function store(CreateVendorRequest $request)
|
||||
{
|
||||
$vendor = $this->vendorRepo->save($request->input());
|
||||
|
||||
$vendor = Vendor::scope($vendor->public_id)
|
||||
->with('country', 'vendorcontacts', 'industry', 'size', 'currency')
|
||||
->first();
|
||||
|
||||
$transformer = new VendorTransformer(Auth::user()->account, Input::get('serializer'));
|
||||
$data = $this->createItem($vendor, $transformer, ENTITY_VENDOR);
|
||||
return $this->response($data);
|
||||
}
|
||||
}
|
212
app/Http/Controllers/VendorController.php
Normal file
212
app/Http/Controllers/VendorController.php
Normal file
@ -0,0 +1,212 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Datatable;
|
||||
use Utils;
|
||||
use View;
|
||||
use URL;
|
||||
use Validator;
|
||||
use Input;
|
||||
use Session;
|
||||
use Redirect;
|
||||
use Cache;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Account;
|
||||
use App\Models\VendorContact;
|
||||
use App\Models\Size;
|
||||
use App\Models\PaymentTerm;
|
||||
use App\Models\Industry;
|
||||
use App\Models\Currency;
|
||||
use App\Models\Country;
|
||||
use App\Ninja\Repositories\VendorRepository;
|
||||
use App\Services\VendorService;
|
||||
|
||||
use App\Http\Requests\CreateVendorRequest;
|
||||
use App\Http\Requests\UpdateVendorRequest;
|
||||
// vendor
|
||||
class VendorController extends BaseController
|
||||
{
|
||||
protected $vendorService;
|
||||
protected $vendorRepo;
|
||||
|
||||
public function __construct(VendorRepository $vendorRepo, VendorService $vendorService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->vendorRepo = $vendorRepo;
|
||||
$this->vendorService = $vendorService;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('list', array(
|
||||
'entityType' => 'vendor',
|
||||
'title' => trans('texts.vendors'),
|
||||
'sortCol' => '4',
|
||||
'columns' => Utils::trans([
|
||||
'checkbox',
|
||||
'vendor',
|
||||
'contact',
|
||||
'email',
|
||||
'date_created',
|
||||
'balance',
|
||||
''
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
||||
public function getDatatable()
|
||||
{
|
||||
return $this->vendorService->getDatatable(Input::get('sSearch'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function store(CreateVendorRequest $request)
|
||||
{
|
||||
$vendor = $this->vendorService->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_vendor'));
|
||||
|
||||
return redirect()->to($vendor->getRoute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function show($publicId)
|
||||
{
|
||||
$vendor = Vendor::withTrashed()->scope($publicId)->with('vendorcontacts', 'size', 'industry')->firstOrFail();
|
||||
Utils::trackViewed($vendor->getDisplayName(), 'vendor');
|
||||
|
||||
$actionLinks = [
|
||||
['label' => trans('texts.new_vendor'), 'url' => '/vendors/create/' . $vendor->public_id]
|
||||
];
|
||||
|
||||
$data = array(
|
||||
'actionLinks' => $actionLinks,
|
||||
'showBreadcrumbs' => false,
|
||||
'vendor' => $vendor,
|
||||
'totalexpense' => $vendor->getTotalExpense(),
|
||||
'title' => trans('texts.view_vendor'),
|
||||
'hasRecurringInvoices' => false,
|
||||
'hasQuotes' => false,
|
||||
'hasTasks' => false,
|
||||
);
|
||||
|
||||
return View::make('vendors.show', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if (Vendor::scope()->count() > Auth::user()->getMaxNumVendors()) {
|
||||
return View::make('error', ['hideHeader' => true, 'error' => "Sorry, you've exceeded the limit of ".Auth::user()->getMaxNumVendors()." vendors"]);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'vendor' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'vendors',
|
||||
'title' => trans('texts.new_vendor'),
|
||||
];
|
||||
|
||||
$data = array_merge($data, self::getViewModel());
|
||||
|
||||
return View::make('vendors.edit', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function edit($publicId)
|
||||
{
|
||||
$vendor = Vendor::scope($publicId)->with('vendorcontacts')->firstOrFail();
|
||||
$data = [
|
||||
'vendor' => $vendor,
|
||||
'method' => 'PUT',
|
||||
'url' => 'vendors/'.$publicId,
|
||||
'title' => trans('texts.edit_vendor'),
|
||||
];
|
||||
|
||||
$data = array_merge($data, self::getViewModel());
|
||||
|
||||
if (Auth::user()->account->isNinjaAccount()) {
|
||||
if ($account = Account::whereId($vendor->public_id)->first()) {
|
||||
$data['proPlanPaid'] = $account['pro_plan_paid'];
|
||||
}
|
||||
}
|
||||
|
||||
return View::make('vendors.edit', $data);
|
||||
}
|
||||
|
||||
private static function getViewModel()
|
||||
{
|
||||
return [
|
||||
'data' => Input::old('data'),
|
||||
'account' => Auth::user()->account,
|
||||
'sizes' => Cache::get('sizes'),
|
||||
//'paymentTerms' => Cache::get('paymentTerms'),
|
||||
'paymentTerms' => PaymentTerm::get(),
|
||||
'industries' => Cache::get('industries'),
|
||||
'currencies' => Cache::get('currencies'),
|
||||
'languages' => Cache::get('languages'),
|
||||
'countries' => Cache::get('countries'),
|
||||
'customLabel1' => Auth::user()->account->custom_vendor_label1,
|
||||
'customLabel2' => Auth::user()->account->custom_vendor_label2,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update(UpdateVendorRequest $request)
|
||||
{
|
||||
$vendor = $this->vendorService->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.updated_vendor'));
|
||||
|
||||
return redirect()->to($vendor->getRoute());
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
$count = $this->vendorService->bulk($ids, $action);
|
||||
|
||||
$message = Utils::pluralize($action.'d_vendor', $count);
|
||||
Session::flash('message', $message);
|
||||
|
||||
if ($action == 'restore' && $count == 1) {
|
||||
return Redirect::to('vendors/' . Utils::getFirst($ids));
|
||||
} else {
|
||||
return Redirect::to('vendors');
|
||||
}
|
||||
}
|
||||
}
|
30
app/Http/Requests/CreateExpenseRequest.php
Normal file
30
app/Http/Requests/CreateExpenseRequest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class CreateExpenseRequest extends Request
|
||||
{
|
||||
// Expenses
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'amount' => 'required|positive',
|
||||
];
|
||||
}
|
||||
}
|
30
app/Http/Requests/CreatePaymentTermRequest.php
Normal file
30
app/Http/Requests/CreatePaymentTermRequest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class CreatePaymentTermRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'num_days' => 'required',
|
||||
'name' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
44
app/Http/Requests/CreateVendorRequest.php
Normal file
44
app/Http/Requests/CreateVendorRequest.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
// vendor
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class CreateVendorRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'vendorcontacts' => 'valid_contacts',
|
||||
];
|
||||
}
|
||||
|
||||
public function validator($factory)
|
||||
{
|
||||
// support submiting the form with a single contact record
|
||||
$input = $this->input();
|
||||
if (isset($input['vendor_contact'])) {
|
||||
$input['vendor_contacts'] = [$input['vendor_contact']];
|
||||
unset($input['vendor_contact']);
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
return $factory->make(
|
||||
$this->input(), $this->container->call([$this, 'rules']), $this->messages()
|
||||
);
|
||||
}
|
||||
}
|
32
app/Http/Requests/UpdateExpenseRequest.php
Normal file
32
app/Http/Requests/UpdateExpenseRequest.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
|
||||
class UpdateExpenseRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'amount' => 'required|positive',
|
||||
'public_notes' => 'required',
|
||||
'expense_date' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
use App\Models\Invoice;
|
||||
|
||||
class UpdatePaymentRequest extends Request
|
||||
{
|
||||
@ -24,5 +23,6 @@ class UpdatePaymentRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
return [];
|
||||
|
||||
}
|
||||
}
|
||||
|
30
app/Http/Requests/UpdatePaymentTermRequest.php
Normal file
30
app/Http/Requests/UpdatePaymentTermRequest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class UpdateExpenseRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'amount' => 'required|positive',
|
||||
];
|
||||
|
||||
}
|
||||
}
|
29
app/Http/Requests/UpdateVendorRequest.php
Normal file
29
app/Http/Requests/UpdateVendorRequest.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
// vendor
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class UpdateVendorRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'vendor_contacts' => 'valid_contacts',
|
||||
];
|
||||
}
|
||||
}
|
@ -119,6 +119,11 @@ Route::group(['middleware' => 'auth'], function() {
|
||||
Route::get('settings/{section?}', 'AccountController@showSection');
|
||||
Route::post('settings/{section?}', 'AccountController@doSection');
|
||||
|
||||
// Payment term
|
||||
Route::get('api/payment_terms', array('as'=>'api.payment_terms', 'uses'=>'PaymentTermController@getDatatable'));
|
||||
Route::resource('payment_terms', 'PaymentTermController');
|
||||
Route::post('payment_terms/bulk', 'PaymentTermController@bulk');
|
||||
|
||||
Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData'));
|
||||
Route::post('user/setTheme', 'UserController@setTheme');
|
||||
Route::post('remove_logo', 'AccountController@removeLogo');
|
||||
@ -181,6 +186,21 @@ Route::group(['middleware' => 'auth'], function() {
|
||||
|
||||
get('/resend_confirmation', 'AccountController@resendConfirmation');
|
||||
post('/update_setup', 'AppController@updateSetup');
|
||||
|
||||
|
||||
// vendor
|
||||
Route::resource('vendors', 'VendorController');
|
||||
Route::get('api/vendor', array('as'=>'api.vendors', 'uses'=>'VendorController@getDatatable'));
|
||||
Route::get('api/vendoractivities/{vendor_id?}', array('as'=>'api.vendoractivities', 'uses'=>'VendorActivityController@getDatatable'));
|
||||
Route::post('vendors/bulk', 'VendorController@bulk');
|
||||
|
||||
// Expense
|
||||
Route::resource('expenses', 'ExpenseController');
|
||||
Route::get('expenses/create/{vendor_id?}', 'ExpenseController@create');
|
||||
Route::get('api/expense', array('as'=>'api.expenses', 'uses'=>'ExpenseApiController@getDatatable'));
|
||||
Route::get('api/expenseVendor/{id}', array('as'=>'api.expense', 'uses'=>'ExpenseApiController@getDatatableVendor'));
|
||||
Route::get('api/expenseactivities/{expense_id?}', array('as'=>'api.expenseactivities', 'uses'=>'ExpenseActivityController@getDatatable'));
|
||||
Route::post('expenses/bulk', 'ExpenseController@bulk');
|
||||
});
|
||||
|
||||
// Route groups for API
|
||||
@ -202,6 +222,12 @@ Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
|
||||
Route::post('hooks', 'IntegrationController@subscribe');
|
||||
Route::post('email_invoice', 'InvoiceApiController@emailInvoice');
|
||||
Route::get('user_accounts','AccountApiController@getUserAccounts');
|
||||
|
||||
// Vendor
|
||||
Route::resource('vendors', 'VendorApiController');
|
||||
|
||||
//Expense
|
||||
Route::resource('expenses', 'ExpenseApiController');
|
||||
});
|
||||
|
||||
// Redirects for legacy links
|
||||
@ -242,6 +268,7 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('ENV_STAGING', 'staging');
|
||||
|
||||
define('RECENTLY_VIEWED', 'RECENTLY_VIEWED');
|
||||
|
||||
define('ENTITY_CLIENT', 'client');
|
||||
define('ENTITY_CONTACT', 'contact');
|
||||
define('ENTITY_INVOICE', 'invoice');
|
||||
@ -258,9 +285,15 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('ENTITY_TAX_RATE', 'tax_rate');
|
||||
define('ENTITY_PRODUCT', 'product');
|
||||
define('ENTITY_ACTIVITY', 'activity');
|
||||
define('ENTITY_VENDOR','vendor');
|
||||
define('ENTITY_VENDOR_ACTIVITY','vendor_activity');
|
||||
define('ENTITY_EXPENSE', 'expense');
|
||||
define('ENTITY_PAYMENT_TERM','payment_term');
|
||||
define('ENTITY_EXPENSE_ACTIVITY','expense_activity');
|
||||
|
||||
define('PERSON_CONTACT', 'contact');
|
||||
define('PERSON_USER', 'user');
|
||||
define('PERSON_VENDOR_CONTACT','vendorcontact');
|
||||
|
||||
define('BASIC_SETTINGS', 'basic_settings');
|
||||
define('ADVANCED_SETTINGS', 'advanced_settings');
|
||||
@ -287,6 +320,7 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('ACCOUNT_API_TOKENS', 'api_tokens');
|
||||
define('ACCOUNT_CUSTOMIZE_DESIGN', 'customize_design');
|
||||
define('ACCOUNT_SYSTEM_SETTINGS', 'system_settings');
|
||||
define('ACCOUNT_PAYMENT_TERMS','payment_terms');
|
||||
|
||||
define('ACTION_RESTORE', 'restore');
|
||||
define('ACTION_ARCHIVE', 'archive');
|
||||
@ -327,6 +361,18 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('ACTIVITY_TYPE_RESTORE_CREDIT', 28);
|
||||
define('ACTIVITY_TYPE_APPROVE_QUOTE', 29);
|
||||
|
||||
// Vendors
|
||||
define('ACTIVITY_TYPE_CREATE_VENDOR', 30);
|
||||
define('ACTIVITY_TYPE_ARCHIVE_VENDOR', 31);
|
||||
define('ACTIVITY_TYPE_DELETE_VENDOR', 32);
|
||||
define('ACTIVITY_TYPE_RESTORE_VENDOR', 33);
|
||||
|
||||
// expenses
|
||||
define('ACTIVITY_TYPE_CREATE_EXPENSE', 34);
|
||||
define('ACTIVITY_TYPE_ARCHIVE_EXPENSE', 35);
|
||||
define('ACTIVITY_TYPE_DELETE_EXPENSE', 36);
|
||||
define('ACTIVITY_TYPE_RESTORE_EXPENSE', 37);
|
||||
|
||||
define('DEFAULT_INVOICE_NUMBER', '0001');
|
||||
define('RECENTLY_VIEWED_LIMIT', 8);
|
||||
define('LOGGED_ERROR_LIMIT', 100);
|
||||
@ -358,6 +404,10 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('LEGACY_CUTOFF', 57800);
|
||||
define('ERROR_DELAY', 3);
|
||||
|
||||
define('MAX_NUM_VENDORS', 100);
|
||||
define('MAX_NUM_VENDORS_PRO', 20000);
|
||||
define('MAX_NUM_VENDORS_LEGACY', 500);
|
||||
|
||||
define('INVOICE_STATUS_DRAFT', 1);
|
||||
define('INVOICE_STATUS_SENT', 2);
|
||||
define('INVOICE_STATUS_VIEWED', 3);
|
||||
@ -430,6 +480,7 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('EVENT_CREATE_INVOICE', 2);
|
||||
define('EVENT_CREATE_QUOTE', 3);
|
||||
define('EVENT_CREATE_PAYMENT', 4);
|
||||
define('EVENT_CREATE_VENDOR',5);
|
||||
|
||||
define('REQUESTED_PRO_PLAN', 'REQUESTED_PRO_PLAN');
|
||||
define('DEMO_ACCOUNT_ID', 'DEMO_ACCOUNT_ID');
|
||||
|
@ -142,7 +142,7 @@ class Utils
|
||||
$history = Session::get(RECENTLY_VIEWED);
|
||||
$last = $history[0];
|
||||
$penultimate = count($history) > 1 ? $history[1] : $last;
|
||||
|
||||
|
||||
return Request::url() == $last->url ? $penultimate->url : $last->url;
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ class Utils
|
||||
$data = Cache::get($type)->filter(function($item) use ($id) {
|
||||
return $item->id == $id;
|
||||
});
|
||||
|
||||
|
||||
return $data->first();
|
||||
}
|
||||
|
||||
@ -349,7 +349,7 @@ class Utils
|
||||
if (!$date) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$dateTime = new DateTime($date);
|
||||
$timestamp = $dateTime->getTimestamp();
|
||||
$format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT);
|
||||
@ -473,7 +473,7 @@ class Utils
|
||||
}
|
||||
|
||||
array_unshift($data, $object);
|
||||
|
||||
|
||||
if (isset($counts[Auth::user()->account_id]) && $counts[Auth::user()->account_id] > RECENTLY_VIEWED_LIMIT) {
|
||||
array_pop($data);
|
||||
}
|
||||
@ -582,6 +582,17 @@ class Utils
|
||||
}
|
||||
}
|
||||
|
||||
public static function getVendorDisplayName($model)
|
||||
{
|
||||
if(is_null($model))
|
||||
return '';
|
||||
|
||||
if($model->vendor_name)
|
||||
return $model->vendor_name;
|
||||
|
||||
return 'No vendor name';
|
||||
}
|
||||
|
||||
public static function getPersonDisplayName($firstName, $lastName, $email)
|
||||
{
|
||||
if ($firstName || $lastName) {
|
||||
@ -613,7 +624,9 @@ class Utils
|
||||
return EVENT_CREATE_QUOTE;
|
||||
} elseif ($eventName == 'create_payment') {
|
||||
return EVENT_CREATE_PAYMENT;
|
||||
} else {
|
||||
} elseif ($eventName == 'create_vendor') {
|
||||
return EVENT_CREATE_VENDOR;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -671,7 +684,7 @@ class Utils
|
||||
if ($publicId) {
|
||||
$data['id'] = $publicId;
|
||||
}
|
||||
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@ -717,7 +730,7 @@ class Utils
|
||||
$str .= 'ENTITY_DELETED ';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($model->deleted_at && $model->deleted_at != '0000-00-00') {
|
||||
$str .= 'ENTITY_ARCHIVED ';
|
||||
}
|
||||
@ -737,7 +750,7 @@ class Utils
|
||||
|
||||
fwrite($output, "\n");
|
||||
}
|
||||
|
||||
|
||||
public static function getFirst($values)
|
||||
{
|
||||
if (is_array($values)) {
|
||||
@ -902,7 +915,7 @@ class Utils
|
||||
if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
|
||||
$url = "http://" . $url;
|
||||
}
|
||||
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
57
app/Listeners/ExpenseActivityListener.php
Normal file
57
app/Listeners/ExpenseActivityListener.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use App\Events\ExpenseWasCreated;
|
||||
use App\Events\ExpenseWasDeleted;
|
||||
use App\Events\ExpenseWasArchived;
|
||||
use App\Events\ExpenseWasRestored;
|
||||
use App\Ninja\Repositories\ActivityRepository;
|
||||
use App\Ninja\Repositories\ExpenseActivityRepository;
|
||||
|
||||
class ExpenseActivityListener
|
||||
{
|
||||
protected $activityRepo;
|
||||
|
||||
public function __construct(ExpenseActivityRepository $activityRepo)
|
||||
{
|
||||
$this->activityRepo = $activityRepo;
|
||||
}
|
||||
|
||||
// Expenses
|
||||
public function createdExpense(ExpenseWasCreated $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->expense,
|
||||
ACTIVITY_TYPE_CREATE_EXPENSE
|
||||
);
|
||||
}
|
||||
|
||||
public function deletedExpense(ExpenseWasDeleted $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->expense,
|
||||
ACTIVITY_TYPE_DELETE_EXPENSE
|
||||
);
|
||||
}
|
||||
|
||||
public function archivedExpense(ExpenseWasArchived $event)
|
||||
{
|
||||
/*
|
||||
if ($event->client->is_deleted) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
$this->activityRepo->create(
|
||||
$event->expense,
|
||||
ACTIVITY_TYPE_ARCHIVE_EXPENSE
|
||||
);
|
||||
}
|
||||
|
||||
public function restoredExpense(ExpenseWasRestored $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->expense,
|
||||
ACTIVITY_TYPE_RESTORE_EXPENSE
|
||||
);
|
||||
}
|
||||
}
|
25
app/Listeners/ExpenseListener.php
Normal file
25
app/Listeners/ExpenseListener.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use Carbon;
|
||||
use App\Models\Expense;
|
||||
use App\Events\PaymentWasDeleted;
|
||||
use App\Events\InvoiceWasDeleted;
|
||||
use App\Ninja\Repositories\ExpenseRepository;
|
||||
|
||||
class ExpenseListener
|
||||
{
|
||||
// Expenses
|
||||
protected $expenseRepo;
|
||||
|
||||
public function __construct(ExpenseRepository $expenseRepo)
|
||||
{
|
||||
$this->expenseRepo = $expenseRepo;
|
||||
}
|
||||
|
||||
public function deletedInvoice(InvoiceWasDeleted $event)
|
||||
{
|
||||
// Release any tasks associated with the deleted invoice
|
||||
Expense::where('invoice_id', '=', $event->invoice->id)
|
||||
->update(['invoice_id' => null]);
|
||||
}
|
||||
}
|
@ -9,6 +9,9 @@ use App\Events\InvoiceWasCreated;
|
||||
use App\Events\CreditWasCreated;
|
||||
use App\Events\PaymentWasCreated;
|
||||
|
||||
use App\Events\VendorWasCreated;
|
||||
use App\Events\ExpenseWasCreated;
|
||||
|
||||
class SubscriptionListener
|
||||
{
|
||||
public function createdClient(ClientWasCreated $event)
|
||||
@ -44,4 +47,15 @@ class SubscriptionListener
|
||||
Utils::notifyZapier($subscription, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
public function createdVendor(VendorWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_VENDOR, $event->vendor);
|
||||
}
|
||||
|
||||
public function createdExpense(ExpenseWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_EXPENSE, $event->expense);
|
||||
}
|
||||
|
||||
}
|
||||
|
55
app/Listeners/VendorActivityListener.php
Normal file
55
app/Listeners/VendorActivityListener.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php namespace app\Listeners;
|
||||
// vendor
|
||||
use App\Events\VendorWasCreated;
|
||||
use App\Events\VendorWasDeleted;
|
||||
use App\Events\VendorWasArchived;
|
||||
use App\Events\VendorWasRestored;
|
||||
use App\Ninja\Repositories\ActivityRepository;
|
||||
use App\Ninja\Repositories\VendorActivityRepository;
|
||||
|
||||
class VendorActivityListener
|
||||
{
|
||||
protected $activityRepo;
|
||||
|
||||
public function __construct(VendorActivityRepository $activityRepo)
|
||||
{
|
||||
$this->activityRepo = $activityRepo;
|
||||
}
|
||||
|
||||
// Vendors
|
||||
public function createdVendor(VendorWasCreated $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->vendor,
|
||||
ACTIVITY_TYPE_CREATE_VENDOR
|
||||
);
|
||||
}
|
||||
|
||||
public function deletedVendor(VendorWasDeleted $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->vendor,
|
||||
ACTIVITY_TYPE_DELETE_VENDOR
|
||||
);
|
||||
}
|
||||
|
||||
public function archivedVendor(VendorWasArchived $event)
|
||||
{
|
||||
if ($event->vendor->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activityRepo->create(
|
||||
$event->vendor,
|
||||
ACTIVITY_TYPE_ARCHIVE_VENDOR
|
||||
);
|
||||
}
|
||||
|
||||
public function restoredVendor(VendorWasRestored $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->vendor,
|
||||
ACTIVITY_TYPE_RESTORE_VENDOR
|
||||
);
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ class Account extends Eloquent
|
||||
ACCOUNT_PRODUCTS,
|
||||
ACCOUNT_NOTIFICATIONS,
|
||||
ACCOUNT_IMPORT_EXPORT,
|
||||
ACCOUNT_PAYMENT_TERMS,
|
||||
];
|
||||
|
||||
public static $advancedSettings = [
|
||||
|
101
app/Models/Expense.php
Normal file
101
app/Models/Expense.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Events\ExpenseWasCreated;
|
||||
use App\Events\ExpenseWasUpdated;
|
||||
use App\Events\ExpenseWasDeleted;
|
||||
|
||||
class Expense extends EntityModel
|
||||
{
|
||||
// Expenses
|
||||
use SoftDeletes;
|
||||
use PresentableTrait;
|
||||
|
||||
protected $dates = ['deleted_at','expense_date'];
|
||||
protected $presenter = 'App\Ninja\Presenters\ExpensePresenter';
|
||||
|
||||
protected $fillable = [
|
||||
'amount',
|
||||
'amount_cur',
|
||||
'exchange_rate',
|
||||
'private_notes',
|
||||
'public_notes',
|
||||
];
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Account');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Models\User');
|
||||
}
|
||||
|
||||
public function vendor()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Vendor')->withTrashed();
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
if($this->expense_number)
|
||||
return $this->expense_number;
|
||||
|
||||
return $this->public_id;
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getRoute()
|
||||
{
|
||||
return "/expenses/{$this->public_id}";
|
||||
}
|
||||
|
||||
public function getEntityType()
|
||||
{
|
||||
return ENTITY_EXPENSE;
|
||||
}
|
||||
|
||||
public function apply($amount)
|
||||
{
|
||||
if ($amount > $this->balance) {
|
||||
$applied = $this->balance;
|
||||
$this->balance = 0;
|
||||
} else {
|
||||
$applied = $amount;
|
||||
$this->balance = $this->balance - $amount;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
|
||||
return $applied;
|
||||
}
|
||||
}
|
||||
|
||||
Expense::creating(function ($expense) {
|
||||
$expense->setNullValues();
|
||||
});
|
||||
|
||||
Expense::created(function ($expense) {
|
||||
event(new ExpenseWasCreated($expense));
|
||||
});
|
||||
|
||||
Expense::updating(function ($expense) {
|
||||
$expense->setNullValues();
|
||||
});
|
||||
|
||||
Expense::updated(function ($expense) {
|
||||
event(new ExpenseWasUpdated($expense));
|
||||
});
|
||||
|
||||
Expense::deleting(function ($expense) {
|
||||
$expense->setNullValues();
|
||||
});
|
||||
|
||||
Expense::deleted(function ($expense) {
|
||||
event(new ExpenseWasDeleted($expense));
|
||||
});
|
63
app/Models/ExpenseActivity.php
Normal file
63
app/Models/ExpenseActivity.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Auth;
|
||||
use Eloquent;
|
||||
use Utils;
|
||||
use Session;
|
||||
use Request;
|
||||
use Carbon;
|
||||
|
||||
class ExpenseActivity extends Eloquent {
|
||||
// Expenses
|
||||
public $timestamps = true;
|
||||
|
||||
public function scopeScope($query)
|
||||
{
|
||||
return $query->whereAccountId(Auth::user()->account_id);
|
||||
}
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Account');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Models\User')->withTrashed();
|
||||
}
|
||||
|
||||
public function vendor()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Vendor')->withTrashed();
|
||||
}
|
||||
|
||||
public function expense()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Expense')->withTrashed();
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
$activityTypeId = $this->activity_type_id;
|
||||
$account = $this->account;
|
||||
$vendor = $this->vendor;
|
||||
$user = $this->user;
|
||||
$contactId = $this->contact_id;
|
||||
$isSystem = $this->is_system;
|
||||
$expense = $this->expense;
|
||||
|
||||
if($expense)
|
||||
{
|
||||
$route = link_to($expense->getRoute(), $expense->getDisplayName());
|
||||
} else {
|
||||
$route ='no expense id';
|
||||
}
|
||||
|
||||
$data = [
|
||||
'expense' => $route,
|
||||
'user' => $isSystem ? '<i>' . trans('texts.system') . '</i>' : $user->getDisplayName(),
|
||||
];
|
||||
|
||||
return trans("texts.activity_{$activityTypeId}", $data);
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
'is_recurring' => 'boolean',
|
||||
'has_tasks' => 'boolean',
|
||||
'auto_bill' => 'boolean',
|
||||
'has_expenses' => 'boolean',
|
||||
];
|
||||
|
||||
// used for custom invoice numbers
|
||||
@ -82,7 +83,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->is_recurring ? trans('texts.recurring') : $this->invoice_number;
|
||||
return $this->is_recurring ? trans('texts.recurring') : $this->invoice_number;
|
||||
}
|
||||
|
||||
public function affectsBalance()
|
||||
@ -136,7 +137,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
|
||||
return ($this->amount - $this->balance);
|
||||
}
|
||||
|
||||
|
||||
public function trashed()
|
||||
{
|
||||
if ($this->client && $this->client->trashed()) {
|
||||
@ -212,7 +213,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
|
||||
$invitation->markSent($messageId);
|
||||
|
||||
// if the user marks it as sent rather than acually sending it
|
||||
// if the user marks it as sent rather than acually sending it
|
||||
// then we won't track it in the activity log
|
||||
if (!$notify) {
|
||||
return;
|
||||
@ -375,6 +376,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
'has_tasks',
|
||||
'custom_text_value1',
|
||||
'custom_text_value2',
|
||||
'has_expenses',
|
||||
]);
|
||||
|
||||
$this->client->setVisible([
|
||||
@ -468,7 +470,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
// Fix for months with less than 31 days
|
||||
$transformerConfig = new \Recurr\Transformer\ArrayTransformerConfig();
|
||||
$transformerConfig->enableLastDayOfMonthFix();
|
||||
|
||||
|
||||
$transformer = new \Recurr\Transformer\ArrayTransformer();
|
||||
$transformer->setConfig($transformerConfig);
|
||||
$dates = $transformer->transform($rule);
|
||||
@ -494,7 +496,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
if (count($schedule) < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return $schedule[1]->getStart();
|
||||
}
|
||||
|
||||
@ -651,7 +653,7 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
if (!$nextSendDate = $this->getNextSendDate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return $this->account->getDateTime() >= $nextSendDate;
|
||||
}
|
||||
*/
|
||||
|
@ -1,8 +1,17 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Eloquent;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class PaymentTerm extends Eloquent
|
||||
class PaymentTerm extends EntityModel
|
||||
{
|
||||
public $timestamps = false;
|
||||
use SoftDeletes;
|
||||
|
||||
public $timestamps = true;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
public function getEntityType()
|
||||
{
|
||||
return ENTITY_PAYMENT_TERM;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -153,6 +153,20 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
return MAX_NUM_CLIENTS;
|
||||
}
|
||||
|
||||
public function getMaxNumVendors()
|
||||
{
|
||||
if ($this->isPro()) {
|
||||
return MAX_NUM_VENDORS_PRO;
|
||||
}
|
||||
|
||||
if ($this->id < LEGACY_CUTOFF) {
|
||||
return MAX_NUM_VENDORS_LEGACY;
|
||||
}
|
||||
|
||||
return MAX_NUM_VENDORS;
|
||||
}
|
||||
|
||||
|
||||
public function getRememberToken()
|
||||
{
|
||||
return $this->remember_token;
|
||||
|
248
app/Models/Vendor.php
Normal file
248
app/Models/Vendor.php
Normal file
@ -0,0 +1,248 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Utils;
|
||||
use DB;
|
||||
use Carbon;
|
||||
use App\Events\VendorWasCreated;
|
||||
use App\Events\VendorWasUpdated;
|
||||
use Laracasts\Presenter\PresentableTrait;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Vendor extends EntityModel
|
||||
{
|
||||
use PresentableTrait;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $presenter = 'App\Ninja\Presenters\VendorPresenter';
|
||||
protected $dates = ['deleted_at'];
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'id_number',
|
||||
'vat_number',
|
||||
'work_phone',
|
||||
'custom_value1',
|
||||
'custom_value2',
|
||||
'address1',
|
||||
'address2',
|
||||
'city',
|
||||
'state',
|
||||
'postal_code',
|
||||
'country_id',
|
||||
'private_notes',
|
||||
'size_id',
|
||||
'industry_id',
|
||||
'currency_id',
|
||||
'language_id',
|
||||
'payment_terms',
|
||||
'website',
|
||||
];
|
||||
|
||||
public static $fieldName = 'name';
|
||||
public static $fieldPhone = 'work_phone';
|
||||
public static $fieldAddress1 = 'address1';
|
||||
public static $fieldAddress2 = 'address2';
|
||||
public static $fieldCity = 'city';
|
||||
public static $fieldState = 'state';
|
||||
public static $fieldPostalCode = 'postal_code';
|
||||
public static $fieldNotes = 'notes';
|
||||
public static $fieldCountry = 'country';
|
||||
|
||||
public static function getImportColumns()
|
||||
{
|
||||
return [
|
||||
Vendor::$fieldName,
|
||||
Vendor::$fieldPhone,
|
||||
Vendor::$fieldAddress1,
|
||||
Vendor::$fieldAddress2,
|
||||
Vendor::$fieldCity,
|
||||
Vendor::$fieldState,
|
||||
Vendor::$fieldPostalCode,
|
||||
Vendor::$fieldCountry,
|
||||
Vendor::$fieldNotes,
|
||||
VendorContact::$fieldFirstName,
|
||||
VendorContact::$fieldLastName,
|
||||
VendorContact::$fieldPhone,
|
||||
VendorContact::$fieldEmail,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getImportMap()
|
||||
{
|
||||
return [
|
||||
'first' => 'first_name',
|
||||
'last' => 'last_name',
|
||||
'email' => 'email',
|
||||
'mobile|phone' => 'phone',
|
||||
'name|organization' => 'name',
|
||||
'street2|address2' => 'address2',
|
||||
'street|address|address1' => 'address1',
|
||||
'city' => 'city',
|
||||
'state|province' => 'state',
|
||||
'zip|postal|code' => 'postal_code',
|
||||
'country' => 'country',
|
||||
'note' => 'notes',
|
||||
];
|
||||
}
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Account');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Models\User');
|
||||
}
|
||||
|
||||
public function payments()
|
||||
{
|
||||
return $this->hasMany('App\Models\Payment');
|
||||
}
|
||||
|
||||
public function vendorContacts()
|
||||
{
|
||||
return $this->hasMany('App\Models\VendorContact');
|
||||
}
|
||||
|
||||
public function country()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Country');
|
||||
}
|
||||
|
||||
public function currency()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Currency');
|
||||
}
|
||||
|
||||
public function language()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Language');
|
||||
}
|
||||
|
||||
public function size()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Size');
|
||||
}
|
||||
|
||||
public function industry()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Industry');
|
||||
}
|
||||
|
||||
public function addVendorContact($data, $isPrimary = false)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if ($publicId && $publicId != '-1') {
|
||||
$contact = VendorContact::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
$contact = VendorContact::createNew();
|
||||
}
|
||||
|
||||
$contact->fill($data);
|
||||
$contact->is_primary = $isPrimary;
|
||||
|
||||
return $this->vendorContacts()->save($contact);
|
||||
}
|
||||
|
||||
public function getRoute()
|
||||
{
|
||||
return "/vendors/{$this->public_id}";
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getCityState()
|
||||
{
|
||||
$swap = $this->country && $this->country->swap_postal_code;
|
||||
return Utils::cityStateZip($this->city, $this->state, $this->postal_code, $swap);
|
||||
}
|
||||
|
||||
public function getEntityType()
|
||||
{
|
||||
return 'vendor';
|
||||
}
|
||||
|
||||
public function hasAddress()
|
||||
{
|
||||
$fields = [
|
||||
'address1',
|
||||
'address2',
|
||||
'city',
|
||||
'state',
|
||||
'postal_code',
|
||||
'country_id',
|
||||
];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if ($this->$field) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDateCreated()
|
||||
{
|
||||
if ($this->created_at == '0000-00-00 00:00:00') {
|
||||
return '---';
|
||||
} else {
|
||||
return $this->created_at->format('m/d/y h:i a');
|
||||
}
|
||||
}
|
||||
|
||||
public function getCurrencyId()
|
||||
{
|
||||
if ($this->currency_id) {
|
||||
return $this->currency_id;
|
||||
}
|
||||
|
||||
if (!$this->account) {
|
||||
$this->load('account');
|
||||
}
|
||||
|
||||
return $this->account->currency_id ?: DEFAULT_CURRENCY;
|
||||
}
|
||||
|
||||
public function getTotalExpense()
|
||||
{
|
||||
return DB::table('expenses')
|
||||
->where('vendor_id', '=', $this->id)
|
||||
->whereNull('deleted_at')
|
||||
->sum('amount');
|
||||
}
|
||||
}
|
||||
|
||||
Vendor::creating(function ($vendor) {
|
||||
$vendor->setNullValues();
|
||||
});
|
||||
|
||||
Vendor::created(function ($vendor) {
|
||||
event(new VendorWasCreated($vendor));
|
||||
});
|
||||
|
||||
Vendor::updating(function ($vendor) {
|
||||
$vendor->setNullValues();
|
||||
});
|
||||
|
||||
Vendor::updated(function ($vendor) {
|
||||
event(new VendorWasUpdated($vendor));
|
||||
});
|
||||
|
||||
|
||||
Vendor::deleting(function ($vendor) {
|
||||
$vendor->setNullValues();
|
||||
});
|
||||
|
||||
Vendor::deleted(function ($vendor) {
|
||||
event(new VendorWasDeleted($vendor));
|
||||
});
|
61
app/Models/VendorActivity.php
Normal file
61
app/Models/VendorActivity.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php namespace App\Models;
|
||||
// vendor
|
||||
use Auth;
|
||||
use Eloquent;
|
||||
use Utils;
|
||||
use Session;
|
||||
use Request;
|
||||
use Carbon;
|
||||
|
||||
class VendorActivity extends Eloquent {
|
||||
|
||||
public $timestamps = true;
|
||||
|
||||
public function scopeScope($query)
|
||||
{
|
||||
return $query->whereAccountId(Auth::user()->account_id);
|
||||
}
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Account');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Models\User')->withTrashed();
|
||||
}
|
||||
|
||||
public function vendorContact()
|
||||
{
|
||||
return $this->belongsTo('App\Models\VendorContact')->withTrashed();
|
||||
}
|
||||
|
||||
public function vendor()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Vendor')->withTrashed();
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
$activityTypeId = $this->activity_type_id;
|
||||
$account = $this->account;
|
||||
$vendor = $this->vendor;
|
||||
$user = $this->user;
|
||||
$contactId = $this->contact_id;
|
||||
$isSystem = $this->is_system;
|
||||
|
||||
if($vendor) {
|
||||
$route = $vendor->getRoute();
|
||||
|
||||
$data = [
|
||||
'vendor' => link_to($route, $vendor->getDisplayName()),
|
||||
'user' => $isSystem ? '<i>' . trans('texts.system') . '</i>' : $user->getDisplayName(),
|
||||
'vendorcontact' => $contactId ? $vendor->getDisplayName() : $user->getDisplayName(),
|
||||
];
|
||||
} else {
|
||||
return trans("texts.invalid_activity");
|
||||
}
|
||||
return trans("texts.activity_{$activityTypeId}", $data);
|
||||
}
|
||||
}
|
68
app/Models/VendorContact.php
Normal file
68
app/Models/VendorContact.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php namespace App\Models;
|
||||
// vendor
|
||||
use HTML;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class VendorContact extends EntityModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
protected $table = 'vendor_contacts';
|
||||
|
||||
protected $fillable = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'phone',
|
||||
'send_invoice',
|
||||
];
|
||||
|
||||
public static $fieldFirstName = 'first_name';
|
||||
public static $fieldLastName = 'last_name';
|
||||
public static $fieldEmail = 'email';
|
||||
public static $fieldPhone = 'phone';
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Account');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Models\User');
|
||||
}
|
||||
|
||||
public function vendor()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Vendor')->withTrashed();
|
||||
}
|
||||
|
||||
public function getPersonType()
|
||||
{
|
||||
return PERSON_VENDOR_CONTACT;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->getDisplayName();
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
if ($this->getFullName()) {
|
||||
return $this->getFullName();
|
||||
} else {
|
||||
return $this->email;
|
||||
}
|
||||
}
|
||||
|
||||
public function getFullName()
|
||||
{
|
||||
if ($this->first_name || $this->last_name) {
|
||||
return $this->first_name.' '.$this->last_name;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
90
app/Models/VendorInvitation.php
Normal file
90
app/Models/VendorInvitation.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Utils;
|
||||
use Carbon;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
// vendor
|
||||
class VendorInvitation extends EntityModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
public function vendorContact()
|
||||
{
|
||||
return $this->belongsTo('App\Models\VendorContact')->withTrashed();
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Models\User')->withTrashed();
|
||||
}
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Account');
|
||||
}
|
||||
|
||||
public function getLink($type = 'view')
|
||||
{
|
||||
if (!$this->account) {
|
||||
$this->load('account');
|
||||
}
|
||||
|
||||
$url = SITE_URL;
|
||||
$iframe_url = $this->account->iframe_url;
|
||||
|
||||
if ($this->account->isPro()) {
|
||||
if ($iframe_url) {
|
||||
return "{$iframe_url}/?{$this->invitation_key}";
|
||||
} elseif ($this->account->subdomain) {
|
||||
$url = Utils::replaceSubdomain($url, $this->account->subdomain);
|
||||
}
|
||||
}
|
||||
|
||||
return "{$url}/{$type}/{$this->invitation_key}";
|
||||
}
|
||||
|
||||
public function getStatus()
|
||||
{
|
||||
$hasValue = false;
|
||||
$parts = [];
|
||||
$statuses = $this->message_id ? ['sent', 'opened', 'viewed'] : ['sent', 'viewed'];
|
||||
|
||||
foreach ($statuses as $status) {
|
||||
$field = "{$status}_date";
|
||||
$date = '';
|
||||
if ($this->$field && $this->field != '0000-00-00 00:00:00') {
|
||||
$date = Utils::dateToString($this->$field);
|
||||
$hasValue = true;
|
||||
}
|
||||
$parts[] = trans('texts.invitation_status.' . $status) . ': ' . $date;
|
||||
}
|
||||
|
||||
return $hasValue ? implode($parts, '<br/>') : false;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->invitation_key;
|
||||
}
|
||||
|
||||
public function markSent($messageId = null)
|
||||
{
|
||||
$this->message_id = $messageId;
|
||||
$this->email_error = null;
|
||||
$this->sent_date = Carbon::now()->toDateTimeString();
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function markViewed()
|
||||
{
|
||||
//$invoice = $this->invoice;
|
||||
//$client = $invoice->client;
|
||||
|
||||
$this->viewed_date = Carbon::now()->toDateTimeString();
|
||||
$this->save();
|
||||
|
||||
//$invoice->markViewed();
|
||||
//$client->markLoggedIn();
|
||||
}
|
||||
}
|
@ -87,4 +87,11 @@ class BaseTransformer extends TransformerAbstract
|
||||
return isset($this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber])? $this->maps[ENTITY_INVOICE.'_'.ENTITY_CLIENT][$invoiceNumber] : null;
|
||||
}
|
||||
|
||||
|
||||
protected function getVendorId($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
return isset($this->maps[ENTITY_VENDOR][$name]) ? $this->maps[ENTITY_VENDOR][$name] : null;
|
||||
}
|
||||
|
||||
}
|
35
app/Ninja/Import/CSV/VendorTransformer.php
Normal file
35
app/Ninja/Import/CSV/VendorTransformer.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php namespace App\Ninja\Import\CSV;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if (isset($data->name) && $this->hasVendor($data->name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $this->getString($data, 'name'),
|
||||
'work_phone' => $this->getString($data, 'work_phone'),
|
||||
'address1' => $this->getString($data, 'address1'),
|
||||
'city' => $this->getString($data, 'city'),
|
||||
'state' => $this->getString($data, 'state'),
|
||||
'postal_code' => $this->getString($data, 'postal_code'),
|
||||
'private_notes' => $this->getString($data, 'notes'),
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $this->getString($data, 'first_name'),
|
||||
'last_name' => $this->getString($data, 'last_name'),
|
||||
'email' => $this->getString($data, 'email'),
|
||||
'phone' => $this->getString($data, 'phone'),
|
||||
],
|
||||
],
|
||||
'country_id' => isset($data->country) ? $this->getCountryId($data->country) : null,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
36
app/Ninja/Import/FreshBooks/VendorTransformer.php
Normal file
36
app/Ninja/Import/FreshBooks/VendorTransformer.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php namespace App\Ninja\Import\FreshBooks;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->organization)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->organization,
|
||||
'work_phone' => $data->busphone,
|
||||
'address1' => $data->street,
|
||||
'address2' => $data->street2,
|
||||
'city' => $data->city,
|
||||
'state' => $data->province,
|
||||
'postal_code' => $data->postalcode,
|
||||
'private_notes' => $data->notes,
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $data->firstname,
|
||||
'last_name' => $data->lastname,
|
||||
'email' => $data->email,
|
||||
'phone' => $data->mobphone ?: $data->homephone,
|
||||
],
|
||||
],
|
||||
'country_id' => $this->getCountryId($data->country),
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
24
app/Ninja/Import/Harvest/VendorContactTransformer.php
Normal file
24
app/Ninja/Import/Harvest/VendorContactTransformer.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php namespace App\Ninja\Import\Harvest;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorContactTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ( ! $this->hasVendor($data->vendor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'vendor_id' => $this->getVendorId($data->vendor),
|
||||
'first_name' => $data->first_name,
|
||||
'last_name' => $data->last_name,
|
||||
'email' => $data->email,
|
||||
'phone' => $data->office_phone ?: $data->mobile_phone,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
20
app/Ninja/Import/Harvest/VendorTransformer.php
Normal file
20
app/Ninja/Import/Harvest/VendorTransformer.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php namespace App\Ninja\Import\Harvest;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->vendor_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->vendor_name,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
35
app/Ninja/Import/Hiveage/VendorTransformer.php
Normal file
35
app/Ninja/Import/Hiveage/VendorTransformer.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php namespace App\Ninja\Import\Hiveage;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->name,
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $this->getFirstName($data->primary_contact),
|
||||
'last_name' => $this->getLastName($data->primary_contactk),
|
||||
'email' => $data->business_email,
|
||||
],
|
||||
],
|
||||
'address1' => $data->address_1,
|
||||
'address2' => $data->address_2,
|
||||
'city' => $data->city,
|
||||
'state' => $data->state_name,
|
||||
'postal_code' => $data->zip_code,
|
||||
'work_phone' => $data->phone,
|
||||
'website' => $data->website,
|
||||
'country_id' => $this->getCountryId($data->country),
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
34
app/Ninja/Import/Invoiceable/VendorTransformer.php
Normal file
34
app/Ninja/Import/Invoiceable/VendorTransformer.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php namespace App\Ninja\Import\Invoiceable;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->vendor_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->vendor_name,
|
||||
'work_phone' => $data->tel,
|
||||
'website' => $data->website,
|
||||
'address1' => $data->address,
|
||||
'city' => $data->city,
|
||||
'state' => $data->state,
|
||||
'postal_code' => $data->postcode,
|
||||
'country_id' => $this->getCountryIdBy2($data->country),
|
||||
'private_notes' => $data->notes,
|
||||
'contacts' => [
|
||||
[
|
||||
'email' => $data->email,
|
||||
'phone' => $data->mobile,
|
||||
],
|
||||
],
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
35
app/Ninja/Import/Nutcache/VendorTransformer.php
Normal file
35
app/Ninja/Import/Nutcache/VendorTransformer.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php namespace App\Ninja\Import\Nutcache;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->name,
|
||||
'city' => isset($data->city) ? $data->city : '',
|
||||
'state' => isset($data->city) ? $data->stateprovince : '',
|
||||
'id_number' => isset($data->registration_number) ? $data->registration_number : '',
|
||||
'postal_code' => isset($data->postalzip_code) ? $data->postalzip_code : '',
|
||||
'private_notes' => isset($data->notes) ? $data->notes : '',
|
||||
'work_phone' => isset($data->phone) ? $data->phone : '',
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => isset($data->contact_name) ? $this->getFirstName($data->contact_name) : '',
|
||||
'last_name' => isset($data->contact_name) ? $this->getLastName($data->contact_name) : '',
|
||||
'email' => $data->email,
|
||||
'phone' => isset($data->mobile) ? $data->mobile : '',
|
||||
],
|
||||
],
|
||||
'country_id' => isset($data->country) ? $this->getCountryId($data->country) : null,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
28
app/Ninja/Import/Ronin/VendorTransformer.php
Normal file
28
app/Ninja/Import/Ronin/VendorTransformer.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php namespace App\Ninja\Import\Ronin;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->company)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->company,
|
||||
'work_phone' => $data->phone,
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $this->getFirstName($data->name),
|
||||
'last_name' => $this->getLastName($data->name),
|
||||
'email' => $data->email,
|
||||
],
|
||||
],
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
38
app/Ninja/Import/Wave/VendorTransformer.php
Normal file
38
app/Ninja/Import/Wave/VendorTransformer.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php namespace App\Ninja\Import\Wave;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->customer_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->customer_name,
|
||||
'id_number' => $data->account_number,
|
||||
'work_phone' => $data->phone,
|
||||
'website' => $data->website,
|
||||
'address1' => $data->address_line_1,
|
||||
'address2' => $data->address_line_2,
|
||||
'city' => $data->city,
|
||||
'state' => $data->provincestate,
|
||||
'postal_code' => $data->postal_codezip_code,
|
||||
'private_notes' => $data->delivery_instructions,
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $data->contact_first_name,
|
||||
'last_name' => $data->contact_last_name,
|
||||
'email' => $data->email,
|
||||
'phone' => $data->mobile,
|
||||
],
|
||||
],
|
||||
'country_id' => $this->getCountryId($data->country),
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
37
app/Ninja/Import/Zoho/VendorTransformer.php
Normal file
37
app/Ninja/Import/Zoho/VendorTransformer.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php namespace App\Ninja\Import\Zoho;
|
||||
|
||||
use App\Ninja\Import\BaseTransformer;
|
||||
use League\Fractal\Resource\Item;
|
||||
// vendor
|
||||
class VendorTransformer extends BaseTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
if ($this->hasVendor($data->customer_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Item($data, function ($data) {
|
||||
return [
|
||||
'name' => $data->customer_name,
|
||||
'id_number' => $data->customer_id,
|
||||
'work_phone' => $data->phonek,
|
||||
'address1' => $data->billing_address,
|
||||
'city' => $data->billing_city,
|
||||
'state' => $data->billing_state,
|
||||
'postal_code' => $data->billing_code,
|
||||
'private_notes' => $data->notes,
|
||||
'website' => $data->website,
|
||||
'contacts' => [
|
||||
[
|
||||
'first_name' => $data->first_name,
|
||||
'last_name' => $data->last_name,
|
||||
'email' => $data->emailid,
|
||||
'phone' => $data->mobilephone,
|
||||
],
|
||||
],
|
||||
'country_id' => $this->getCountryId($data->billing_country),
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
152
app/Ninja/Mailers/VendorContactMailer.php
Normal file
152
app/Ninja/Mailers/VendorContactMailer.php
Normal file
@ -0,0 +1,152 @@
|
||||
<?php namespace App\Ninja\Mailers;
|
||||
|
||||
use HTML;
|
||||
use Utils;
|
||||
use Event;
|
||||
use URL;
|
||||
use Auth;
|
||||
// vendor
|
||||
use App\Models\VendorActivity;
|
||||
use App\Models\Gateway;
|
||||
|
||||
class VendorContactMailer extends Mailer
|
||||
{
|
||||
public static $variableFields = [
|
||||
'footer',
|
||||
'account',
|
||||
'vendor',
|
||||
'amount',
|
||||
'contact',
|
||||
'firstName',
|
||||
'viewLink',
|
||||
'viewButton',
|
||||
'paymentLink',
|
||||
'paymentButton',
|
||||
];
|
||||
|
||||
private function sendInvitation($invitation, $invoice, $body, $subject, $pdfString)
|
||||
{
|
||||
$vendor = $invoice->vendor;
|
||||
$account = $invoice->account;
|
||||
|
||||
if (Auth::check()) {
|
||||
$user = Auth::user();
|
||||
} else {
|
||||
$user = $invitation->user;
|
||||
if ($invitation->user->trashed()) {
|
||||
$user = $account->users()->orderBy('id')->first();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$user->email || !$user->registered) {
|
||||
return trans('texts.email_errors.user_unregistered');
|
||||
} elseif (!$user->confirmed) {
|
||||
return trans('texts.email_errors.user_unconfirmed');
|
||||
} elseif (!$invitation->contact->email) {
|
||||
return trans('texts.email_errors.invalid_contact_email');
|
||||
} elseif ($invitation->contact->trashed()) {
|
||||
return trans('texts.email_errors.inactive_contact');
|
||||
}
|
||||
|
||||
$variables = [
|
||||
'account' => $account,
|
||||
'vendor' => $vendor,
|
||||
'invitation' => $invitation
|
||||
];
|
||||
|
||||
$data = [
|
||||
'body' => $this->processVariables($body, $variables),
|
||||
'link' => $invitation->getLink(),
|
||||
'entityType' => $invoice->getEntityType(),
|
||||
'invitation' => $invitation,
|
||||
'account' => $account,
|
||||
'vendor' => $vendor,
|
||||
'invoice' => $invoice,
|
||||
];
|
||||
|
||||
if ($account->attatchPDF()) {
|
||||
$data['pdfString'] = $pdfString;
|
||||
$data['pdfFileName'] = $invoice->getFileName();
|
||||
}
|
||||
|
||||
$subject = $this->processVariables($subject, $variables);
|
||||
$fromEmail = $user->email;
|
||||
|
||||
if ($account->email_design_id == EMAIL_DESIGN_PLAIN) {
|
||||
$view = ENTITY_INVOICE;
|
||||
} else {
|
||||
$view = 'design' . ($account->email_design_id - 1);
|
||||
}
|
||||
|
||||
$response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, $view, $data);
|
||||
|
||||
if ($response === true) {
|
||||
return true;
|
||||
} else {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
public function sendLicensePaymentConfirmation($name, $email, $amount, $license, $productId)
|
||||
{
|
||||
$view = 'license_confirmation';
|
||||
$subject = trans('texts.payment_subject');
|
||||
|
||||
if ($productId == PRODUCT_ONE_CLICK_INSTALL) {
|
||||
$license = "Softaculous install license: $license";
|
||||
} elseif ($productId == PRODUCT_INVOICE_DESIGNS) {
|
||||
$license = "Invoice designs license: $license";
|
||||
} elseif ($productId == PRODUCT_WHITE_LABEL) {
|
||||
$license = "White label license: $license";
|
||||
}
|
||||
|
||||
$data = [
|
||||
'vendor' => $name,
|
||||
'amount' => Utils::formatMoney($amount, DEFAULT_CURRENCY, DEFAULT_COUNTRY),
|
||||
'license' => $license
|
||||
];
|
||||
|
||||
$this->sendTo($email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
|
||||
}
|
||||
|
||||
private function processVariables($template, $data)
|
||||
{
|
||||
$account = $data['account'];
|
||||
$vendor = $data['vendor'];
|
||||
$invitation = $data['invitation'];
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
$variables = [
|
||||
'$footer' => $account->getEmailFooter(),
|
||||
'$vendor' => $vendor->getDisplayName(),
|
||||
'$account' => $account->getDisplayName(),
|
||||
'$contact' => $invitation->contact->getDisplayName(),
|
||||
'$firstName' => $invitation->contact->first_name,
|
||||
'$amount' => $account->formatMoney($data['amount'], $vendor),
|
||||
'$invoice' => $invoice->invoice_number,
|
||||
'$quote' => $invoice->invoice_number,
|
||||
'$link' => $invitation->getLink(),
|
||||
'$dueDate' => $account->formatDate($invoice->due_date),
|
||||
'$viewLink' => $invitation->getLink(),
|
||||
'$viewButton' => HTML::emailViewButton($invitation->getLink(), $invoice->getEntityType()),
|
||||
'$paymentLink' => $invitation->getLink('payment'),
|
||||
'$paymentButton' => HTML::emailPaymentButton($invitation->getLink('payment')),
|
||||
'$customClient1' => $account->custom_vendor_label1,
|
||||
'$customClient2' => $account->custom_vendor_label2,
|
||||
'$customInvoice1' => $account->custom_invoice_text_label1,
|
||||
'$customInvoice2' => $account->custom_invoice_text_label2,
|
||||
];
|
||||
|
||||
// Add variables for available payment types
|
||||
foreach (Gateway::$paymentTypes as $type) {
|
||||
$camelType = Gateway::getPaymentTypeName($type);
|
||||
$type = Utils::toSnakeCase($camelType);
|
||||
$variables["\${$camelType}Link"] = $invitation->getLink() . "/{$type}";
|
||||
$variables["\${$camelType}Button"] = HTML::emailPaymentButton($invitation->getLink('payment') . "/{$type}");
|
||||
}
|
||||
|
||||
$str = str_replace(array_keys($variables), array_values($variables), $template);
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
18
app/Ninja/Presenters/ExpensePresenter.php
Normal file
18
app/Ninja/Presenters/ExpensePresenter.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php namespace App\Ninja\Presenters;
|
||||
|
||||
use Utils;
|
||||
use Laracasts\Presenter\Presenter;
|
||||
|
||||
class ExpensePresenter extends Presenter {
|
||||
|
||||
// Expenses
|
||||
public function vendor()
|
||||
{
|
||||
return $this->entity->vendor ? $this->entity->vendor->getDisplayName() : '';
|
||||
}
|
||||
|
||||
public function expense_date()
|
||||
{
|
||||
return Utils::fromSqlDate($this->entity->expense_date);
|
||||
}
|
||||
}
|
12
app/Ninja/Presenters/VendorPresenter.php
Normal file
12
app/Ninja/Presenters/VendorPresenter.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php namespace App\Ninja\Presenters;
|
||||
|
||||
use Utils;
|
||||
use Laracasts\Presenter\Presenter;
|
||||
// vendor
|
||||
class VendorPresenter extends Presenter {
|
||||
|
||||
public function country()
|
||||
{
|
||||
return $this->entity->country ? $this->entity->country->name : '';
|
||||
}
|
||||
}
|
65
app/Ninja/Repositories/ExpenseActivityRepository.php
Normal file
65
app/Ninja/Repositories/ExpenseActivityRepository.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use DB;
|
||||
use Auth;
|
||||
use Utils;
|
||||
use Request;
|
||||
use App\Models\EntityModel;
|
||||
use App\Models\ExpenseActivity;
|
||||
use App\Models\Expense;
|
||||
|
||||
class ExpenseActivityRepository
|
||||
{
|
||||
// Expenses
|
||||
public function create(Expense $entity, $activityTypeId)
|
||||
{
|
||||
// init activity and copy over context
|
||||
$activity = self::getBlank($entity);
|
||||
|
||||
// Fill with our information
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
$activity->contact_id = $entity->contact_id;
|
||||
$activity->activity_type_id = $activityTypeId;
|
||||
$activity->message = $activity->getMessage();
|
||||
$activity->expense_id = $entity->id;
|
||||
$activity->save();
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
private function getBlank($entity)
|
||||
{
|
||||
$activity = new ExpenseActivity();
|
||||
|
||||
if (Auth::check() && Auth::user()->account_id == $entity->account_id) {
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->account_id = Auth::user()->account_id;
|
||||
} else {
|
||||
$activity->user_id = $entity->user_id;
|
||||
$activity->account_id = $entity->account_id;
|
||||
}
|
||||
|
||||
$activity->token_id = session('token_id');
|
||||
$activity->ip = Request::getClientIp();
|
||||
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
|
||||
public function findByExpenseId($expenseId)
|
||||
{
|
||||
return DB::table('expense_activities')
|
||||
->join('accounts', 'accounts.id', '=', 'expense_activities.account_id')
|
||||
->join('users', 'users.id', '=', 'expense_activities.user_id')
|
||||
->join('expenses','expenses.public_id', '=', 'expense_activities.expense_id')
|
||||
->where('expense_activities.expense_id', '=', $expenseId)
|
||||
->select('*',
|
||||
'users.first_name as user_first_name',
|
||||
'users.last_name as user_last_name',
|
||||
'users.email as user_email',
|
||||
'expenses.amount'
|
||||
);
|
||||
|
||||
}
|
||||
}
|
160
app/Ninja/Repositories/ExpenseRepository.php
Normal file
160
app/Ninja/Repositories/ExpenseRepository.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use DB;
|
||||
use Utils;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Vendor;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
use Session;
|
||||
|
||||
class ExpenseRepository extends BaseRepository
|
||||
{
|
||||
// Expenses
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Expense';
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
return Expense::scope()
|
||||
->with('user')
|
||||
->withTrashed()
|
||||
->where('is_deleted', '=', false)
|
||||
->get();
|
||||
}
|
||||
|
||||
public function findVendor($vendorPublicId)
|
||||
{
|
||||
$accountid = \Auth::user()->account_id;
|
||||
$query = DB::table('expenses')
|
||||
->join('accounts', 'accounts.id', '=', 'expenses.account_id')
|
||||
->where('expenses.account_id', '=', $accountid)
|
||||
->where('expenses.vendor_id','=',$vendorPublicId)
|
||||
->select('expenses.id',
|
||||
'expenses.expense_date',
|
||||
'expenses.amount',
|
||||
'expenses.public_notes',
|
||||
'expenses.public_id',
|
||||
'expenses.deleted_at','expenses.is_invoiced','expenses.should_be_invoiced','expenses.created_at');
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function find($filter = null)
|
||||
{
|
||||
$accountid = \Auth::user()->account_id;
|
||||
$query = DB::table('expenses')
|
||||
->join('accounts', 'accounts.id', '=', 'expenses.account_id')
|
||||
->leftjoin('vendors','vendors.public_id','=', 'expenses.vendor_id')
|
||||
->where('expenses.account_id', '=', $accountid)
|
||||
->select('expenses.account_id',
|
||||
'expenses.amount',
|
||||
'expenses.amount_cur',
|
||||
'expenses.currency_id',
|
||||
'expenses.deleted_at',
|
||||
'expenses.exchange_rate',
|
||||
'expenses.expense_date',
|
||||
'expenses.id',
|
||||
'expenses.is_deleted',
|
||||
'expenses.is_invoiced',
|
||||
'expenses.private_notes',
|
||||
'expenses.public_id',
|
||||
'expenses.public_notes',
|
||||
'expenses.should_be_invoiced',
|
||||
'expenses.vendor_id',
|
||||
'vendors.name as vendor_name',
|
||||
'vendors.public_id as vendor_public_id');
|
||||
|
||||
$showTrashed = \Session::get('show_trash:expense');
|
||||
|
||||
if (!$showTrashed) {
|
||||
$query->where('expenses.deleted_at', '=', null);
|
||||
}
|
||||
|
||||
if ($filter) {
|
||||
$query->where(function ($query) use ($filter) {
|
||||
$query->where('expenses.public_notes', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($input)
|
||||
{
|
||||
$publicId = isset($input['public_id']) ? $input['public_id'] : false;
|
||||
|
||||
if ($publicId) {
|
||||
$expense = Expense::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
$expense = Expense::createNew();
|
||||
}
|
||||
|
||||
// First auto fill
|
||||
$expense->fill($input);
|
||||
|
||||
// We can have an expense without a vendor
|
||||
if(isset($input['vendor'])) {
|
||||
$expense->vendor_id = $input['vendor'];
|
||||
}
|
||||
|
||||
$expense->expense_date = Utils::toSqlDate($input['expense_date']);
|
||||
$expense->amount = Utils::parseFloat($input['amount']);
|
||||
|
||||
if(isset($input['amount_cur']))
|
||||
$expense->amount_cur = Utils::parseFloat($input['amount_cur']);
|
||||
|
||||
$expense->private_notes = trim($input['private_notes']);
|
||||
$expense->public_notes = trim($input['public_notes']);
|
||||
|
||||
if(isset($input['exchange_rate']))
|
||||
$expense->exchange_rate = Utils::parseFloat($input['exchange_rate']);
|
||||
else
|
||||
$expense->exchange_rate = 100;
|
||||
|
||||
if($expense->exchange_rate == 0)
|
||||
$expense->exchange_rate = 100;
|
||||
|
||||
// set the currency
|
||||
if(isset($input['currency_id']))
|
||||
$expense->currency_id = $input['currency_id'];
|
||||
|
||||
if($expense->currency_id == 0)
|
||||
$expense->currency_id = Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY);
|
||||
|
||||
// Calculate the amount cur
|
||||
$expense->amount_cur = ($expense->amount / 100) * $expense->exchange_rate;
|
||||
|
||||
$expense->should_be_invoiced = isset($input['should_be_invoiced']) ? true : false;
|
||||
if(isset($input['client'])) {
|
||||
$expense->invoice_client_id = $input['client'];
|
||||
}
|
||||
$expense->save();
|
||||
|
||||
return $expense;
|
||||
}
|
||||
|
||||
public function bulk($ids, $action)
|
||||
{
|
||||
$expenses = Expense::withTrashed()->scope($ids)->get();
|
||||
|
||||
foreach ($expenses as $expense) {
|
||||
if ($action == 'restore') {
|
||||
$expense->restore();
|
||||
|
||||
$expense->is_deleted = false;
|
||||
$expense->save();
|
||||
} else {
|
||||
if ($action == 'delete') {
|
||||
$expense->is_deleted = true;
|
||||
$expense->save();
|
||||
}
|
||||
|
||||
$expense->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return count($tasks);
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@ use App\Models\InvoiceItem;
|
||||
use App\Models\Invitation;
|
||||
use App\Models\Product;
|
||||
use App\Models\Task;
|
||||
use App\Models\Expense;
|
||||
use App\Services\PaymentService;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
|
||||
@ -177,7 +178,7 @@ class InvoiceRepository extends BaseRepository
|
||||
$table->addColumn('balance', function ($model) {
|
||||
return $model->partial > 0 ?
|
||||
trans('texts.partial_remaining', [
|
||||
'partial' => Utils::formatMoney($model->partial, $model->currency_id, $model->country_id),
|
||||
'partial' => Utils::formatMoney($model->partial, $model->currency_id, $model->country_id),
|
||||
'balance' => Utils::formatMoney($model->balance, $model->currency_id, $model->country_id)
|
||||
]) :
|
||||
Utils::formatMoney($model->balance, $model->currency_id, $model->country_id);
|
||||
@ -206,6 +207,9 @@ class InvoiceRepository extends BaseRepository
|
||||
if (isset($data['has_tasks']) && filter_var($data['has_tasks'], FILTER_VALIDATE_BOOLEAN)) {
|
||||
$invoice->has_tasks = true;
|
||||
}
|
||||
if (isset($data['has_expenses']) && filter_var($data['has_expenses'], FILTER_VALIDATE_BOOLEAN)) {
|
||||
$invoice->has_expenses = true;
|
||||
}
|
||||
} else {
|
||||
$invoice = Invoice::scope($publicId)->firstOrFail();
|
||||
}
|
||||
@ -276,7 +280,7 @@ class InvoiceRepository extends BaseRepository
|
||||
if (isset($data['po_number'])) {
|
||||
$invoice->po_number = trim($data['po_number']);
|
||||
}
|
||||
|
||||
|
||||
$invoice->invoice_design_id = isset($data['invoice_design_id']) ? $data['invoice_design_id'] : $account->invoice_design_id;
|
||||
|
||||
if (isset($data['tax_name']) && isset($data['tax_rate']) && $data['tax_name']) {
|
||||
@ -398,6 +402,14 @@ class InvoiceRepository extends BaseRepository
|
||||
$task->save();
|
||||
}
|
||||
|
||||
if (isset($item['expense_public_id']) && $item['expense_public_id']) {
|
||||
$expense = Expense::scope($item['expense_public_id'])->where('invoice_id', '=', null)->firstOrFail();
|
||||
$expense->invoice_id = $invoice->id;
|
||||
$expense->invoice_client_id = $invoice->client_id;
|
||||
$expense->is_invoiced = true;
|
||||
$expense->save();
|
||||
}
|
||||
|
||||
if ($item['product_key']) {
|
||||
$productKey = trim($item['product_key']);
|
||||
if (\Auth::user()->account->update_products && ! strtotime($productKey)) {
|
||||
@ -406,7 +418,10 @@ class InvoiceRepository extends BaseRepository
|
||||
$product = Product::createNew();
|
||||
$product->product_key = trim($item['product_key']);
|
||||
}
|
||||
|
||||
$product->notes = $invoice->has_tasks ? '' : $item['notes'];
|
||||
$product->notes = $invoice->has_expenses ? '' : $item['notes'];
|
||||
|
||||
$product->cost = $item['cost'];
|
||||
$product->save();
|
||||
}
|
||||
@ -642,7 +657,7 @@ class InvoiceRepository extends BaseRepository
|
||||
public function findNeedingReminding($account)
|
||||
{
|
||||
$dates = [];
|
||||
|
||||
|
||||
for ($i=1; $i<=3; $i++) {
|
||||
if ($date = $account->getReminderDate($i)) {
|
||||
$field = $account->{"field_reminder{$i}"} == REMINDER_FIELD_DUE_DATE ? 'due_date' : 'invoice_date';
|
||||
|
22
app/Ninja/Repositories/PaymentTermRepository.php
Normal file
22
app/Ninja/Repositories/PaymentTermRepository.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use DB;
|
||||
use Utils;
|
||||
use App\Models\PaymentTerm;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
|
||||
class PaymentTermRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\PaymentTerm';
|
||||
}
|
||||
|
||||
public function find($accountId = 0)
|
||||
{
|
||||
return DB::table('payment_terms')
|
||||
//->where('payment_terms.account_id', '=', $accountId)
|
||||
->where('payment_terms.deleted_at', '=', null)
|
||||
->select('payment_terms.public_id', 'payment_terms.name', 'payment_terms.num_days', 'payment_terms.deleted_at');
|
||||
}
|
||||
}
|
101
app/Ninja/Repositories/VendorActivityRepository.php
Normal file
101
app/Ninja/Repositories/VendorActivityRepository.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
// vendor
|
||||
use DB;
|
||||
use Auth;
|
||||
use Utils;
|
||||
use Request;
|
||||
use App\Models\VendorActivity;
|
||||
use App\Models\Vendor;
|
||||
|
||||
class VendorActivityRepository
|
||||
{
|
||||
private $vendor;
|
||||
|
||||
public function create($entity, $activityTypeId, $balanceChange = 0, $paidToDateChange = 0, $altEntity = null)
|
||||
{
|
||||
if ($entity instanceof Vendor) {
|
||||
$vendor = $entity;
|
||||
} elseif ($entity instanceof Invitation) {
|
||||
$vendor = $entity->invoice->vendor;
|
||||
} else {
|
||||
$vendor = $entity->vendor;
|
||||
}
|
||||
|
||||
$this->vendor = $vendor;
|
||||
|
||||
// init activity and copy over context
|
||||
$activity = self::getBlank($altEntity ?: $vendor);
|
||||
$activity = Utils::copyContext($activity, $entity);
|
||||
$activity = Utils::copyContext($activity, $altEntity);
|
||||
|
||||
$activity->vendor_id = $vendor->id;
|
||||
$activity->activity_type_id = $activityTypeId;
|
||||
$activity->adjustment = $balanceChange;
|
||||
$activity->balance = $vendor->balance + $balanceChange;
|
||||
|
||||
$keyField = $entity->getKeyField();
|
||||
$activity->$keyField = $entity->id;
|
||||
|
||||
$activity->ip = Request::getClientIp();
|
||||
$activity->save();
|
||||
|
||||
$vendor->updateBalances($balanceChange, $paidToDateChange);
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
private function getBlank($entity)
|
||||
{
|
||||
$activity = new VendorActivity();
|
||||
|
||||
if (Auth::check() && Auth::user()->account_id == $entity->account_id) {
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->account_id = Auth::user()->account_id;
|
||||
} else {
|
||||
$activity->user_id = $entity->user_id;
|
||||
$activity->account_id = $entity->account_id;
|
||||
|
||||
if ( ! $entity instanceof Invitation) {
|
||||
$activity->is_system = true;
|
||||
}
|
||||
}
|
||||
|
||||
$activity->token_id = session('token_id');
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
public function findByVendorId($vendorId)
|
||||
{
|
||||
return DB::table('vendor_activities')
|
||||
->join('accounts', 'accounts.id', '=', 'vendor_activities.account_id')
|
||||
->join('users', 'users.id', '=', 'vendor_activities.user_id')
|
||||
->join('vendors', 'vendors.id', '=', 'vendor_activities.vendor_id')
|
||||
->leftJoin('vendor_contacts', 'vendor_contacts.vendor_id', '=', 'vendors.id')
|
||||
->where('vendors.id', '=', $vendorId)
|
||||
->where('vendor_contacts.is_primary', '=', 1)
|
||||
->whereNull('vendor_contacts.deleted_at')
|
||||
->select(
|
||||
DB::raw('COALESCE(vendors.currency_id, accounts.currency_id) currency_id'),
|
||||
DB::raw('COALESCE(vendors.country_id, accounts.country_id) country_id'),
|
||||
'vendor_activities.id',
|
||||
'vendor_activities.created_at',
|
||||
'vendor_activities.contact_id',
|
||||
'vendor_activities.activity_type_id',
|
||||
'vendor_activities.is_system',
|
||||
'vendor_activities.balance',
|
||||
'vendor_activities.adjustment',
|
||||
'users.first_name as user_first_name',
|
||||
'users.last_name as user_last_name',
|
||||
'users.email as user_email',
|
||||
'vendors.name as vendor_name',
|
||||
'vendors.public_id as vendor_public_id',
|
||||
'vendor_contacts.id as contact',
|
||||
'vendor_contacts.first_name as first_name',
|
||||
'vendor_contacts.last_name as last_name',
|
||||
'vendor_contacts.email as email'
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
}
|
26
app/Ninja/Repositories/VendorContactRepository.php
Normal file
26
app/Ninja/Repositories/VendorContactRepository.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorContact;
|
||||
// vendor
|
||||
class VendorContactRepository extends BaseRepository
|
||||
{
|
||||
public function save($data)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if (!$publicId || $publicId == '-1') {
|
||||
$contact = VendorContact::createNew();
|
||||
//$contact->send_invoice = true;
|
||||
$contact->vendor_id = $data['vendor_id'];
|
||||
$contact->is_primary = VendorContact::scope()->where('vendor_id', '=', $contact->vendor_id)->count() == 0;
|
||||
} else {
|
||||
$contact = VendorContact::scope($publicId)->firstOrFail();
|
||||
}
|
||||
|
||||
$contact->fill($data);
|
||||
$contact->save();
|
||||
|
||||
return $contact;
|
||||
}
|
||||
}
|
91
app/Ninja/Repositories/VendorRepository.php
Normal file
91
app/Ninja/Repositories/VendorRepository.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use DB;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorContact;
|
||||
use App\Models\Activity;
|
||||
// vendor
|
||||
class VendorRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Vendor';
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
return Vendor::scope()
|
||||
->with('user', 'vendorcontacts', 'country')
|
||||
->withTrashed()
|
||||
->where('is_deleted', '=', false)
|
||||
->get();
|
||||
}
|
||||
|
||||
public function find($filter = null)
|
||||
{
|
||||
$query = DB::table('vendors')
|
||||
->join('accounts', 'accounts.id', '=', 'vendors.account_id')
|
||||
->join('vendor_contacts', 'vendor_contacts.vendor_id', '=', 'vendors.id')
|
||||
->where('vendors.account_id', '=', \Auth::user()->account_id)
|
||||
->where('vendor_contacts.is_primary', '=', true)
|
||||
->where('vendor_contacts.deleted_at', '=', null)
|
||||
->select(
|
||||
DB::raw('COALESCE(vendors.currency_id, accounts.currency_id) currency_id'),
|
||||
DB::raw('COALESCE(vendors.country_id, accounts.country_id) country_id'),
|
||||
'vendors.public_id',
|
||||
'vendors.name',
|
||||
'vendor_contacts.first_name',
|
||||
'vendor_contacts.last_name',
|
||||
'vendors.balance',
|
||||
'vendors.created_at',
|
||||
'vendors.work_phone',
|
||||
'vendor_contacts.email',
|
||||
'vendors.deleted_at',
|
||||
'vendors.is_deleted'
|
||||
);
|
||||
|
||||
if (!\Session::get('show_trash:vendor')) {
|
||||
$query->where('vendors.deleted_at', '=', null);
|
||||
}
|
||||
|
||||
if ($filter) {
|
||||
$query->where(function ($query) use ($filter) {
|
||||
$query->where('vendors.name', 'like', '%'.$filter.'%')
|
||||
->orWhere('vendor_contacts.first_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('vendor_contacts.last_name', 'like', '%'.$filter.'%')
|
||||
->orWhere('vendor_contacts.email', 'like', '%'.$filter.'%');
|
||||
});
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if (!$publicId || $publicId == '-1') {
|
||||
$vendor = Vendor::createNew();
|
||||
} else {
|
||||
$vendor = Vendor::scope($publicId)->with('vendorcontacts')->firstOrFail();
|
||||
}
|
||||
|
||||
$vendor->fill($data);
|
||||
$vendor->save();
|
||||
|
||||
if ( ! isset($data['vendorcontact']) && ! isset($data['vendorcontacts'])) {
|
||||
return $vendor;
|
||||
}
|
||||
|
||||
$first = true;
|
||||
$vendorcontacts = isset($data['vendorcontact']) ? [$data['vendorcontact']] : $data['vendorcontacts'];
|
||||
|
||||
foreach ($vendorcontacts as $vendorcontact) {
|
||||
$vendorcontact = $vendor->addVendorContact($vendorcontact, $first);
|
||||
$first = false;
|
||||
}
|
||||
|
||||
return $vendor;
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ class InvoiceTransformer extends EntityTransformer
|
||||
'invoice_items',
|
||||
'payments'
|
||||
];
|
||||
|
||||
|
||||
public function includeInvoiceItems(Invoice $invoice)
|
||||
{
|
||||
$transformer = new InvoiceItemTransformer($this->account, $this->serializer);
|
||||
@ -77,6 +77,7 @@ class InvoiceTransformer extends EntityTransformer
|
||||
'custom_value2' => (float) $invoice->custom_value2,
|
||||
'custom_taxes1' => (bool) $invoice->custom_taxes1,
|
||||
'custom_taxes2' => (bool) $invoice->custom_taxes2,
|
||||
'has_expenses' => (bool) $invoice->has_expenses,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
app/Ninja/Transformers/VendorContactTransformer.php
Normal file
24
app/Ninja/Transformers/VendorContactTransformer.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php namespace App\Ninja\Transformers;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Models\VendorContact;
|
||||
use League\Fractal;
|
||||
// vendor
|
||||
class VendorContactTransformer extends EntityTransformer
|
||||
{
|
||||
public function transform(VendorContact $contact)
|
||||
{
|
||||
return [
|
||||
'id' => (int) $contact->public_id,
|
||||
'first_name' => $contact->first_name,
|
||||
'last_name' => $contact->last_name,
|
||||
'email' => $contact->email,
|
||||
'updated_at' => $this->getTimestamp($contact->updated_at),
|
||||
'archived_at' => $this->getTimestamp($contact->deleted_at),
|
||||
'is_primary' => (bool) $contact->is_primary,
|
||||
'phone' => $contact->phone,
|
||||
'last_login' => $contact->last_login,
|
||||
'account_key' => $this->account->account_key,
|
||||
];
|
||||
}
|
||||
}
|
92
app/Ninja/Transformers/VendorTransformer.php
Normal file
92
app/Ninja/Transformers/VendorTransformer.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php namespace App\Ninja\Transformers;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Contact;
|
||||
use League\Fractal;
|
||||
|
||||
// vendor
|
||||
/**
|
||||
* @SWG\Definition(definition="Vendor", @SWG\Xml(name="Vendor"))
|
||||
*/
|
||||
|
||||
class VendorTransformer extends EntityTransformer
|
||||
{
|
||||
/**
|
||||
* @SWG\Property(property="id", type="integer", example=1, readOnly=true)
|
||||
* @SWG\Property(property="balance", type="float", example=10, readOnly=true)
|
||||
* @SWG\Property(property="paid_to_date", type="float", example=10, readOnly=true)
|
||||
* @SWG\Property(property="user_id", type="integer", example=1)
|
||||
* @SWG\Property(property="account_key", type="string", example="123456")
|
||||
* @SWG\Property(property="updated_at", type="timestamp", example="")
|
||||
* @SWG\Property(property="archived_at", type="timestamp", example="1451160233")
|
||||
* @SWG\Property(property="address1", type="string", example="10 Main St.")
|
||||
* @SWG\Property(property="address2", type="string", example="1st Floor")
|
||||
* @SWG\Property(property="city", type="string", example="New York")
|
||||
* @SWG\Property(property="state", type="string", example="NY")
|
||||
* @SWG\Property(property="postal_code", type="string", example=10010)
|
||||
* @SWG\Property(property="country_id", type="integer", example=840)
|
||||
* @SWG\Property(property="work_phone", type="string", example="(212) 555-1212")
|
||||
* @SWG\Property(property="private_notes", type="string", example="Notes...")
|
||||
* @SWG\Property(property="last_login", type="date-time", example="2016-01-01 12:10:00")
|
||||
* @SWG\Property(property="website", type="string", example="http://www.example.com")
|
||||
* @SWG\Property(property="industry_id", type="integer", example=1)
|
||||
* @SWG\Property(property="size_id", type="integer", example=1)
|
||||
* @SWG\Property(property="is_deleted", type="boolean", example=false)
|
||||
* @SWG\Property(property="payment_terms", type="", example=30)
|
||||
* @SWG\Property(property="custom_value1", type="string", example="Value")
|
||||
* @SWG\Property(property="custom_value2", type="string", example="Value")
|
||||
* @SWG\Property(property="vat_number", type="string", example="123456")
|
||||
* @SWG\Property(property="id_number", type="string", example="123456")
|
||||
* @SWG\Property(property="language_id", type="integer", example=1)
|
||||
*/
|
||||
|
||||
protected $availableIncludes = [
|
||||
'contacts',
|
||||
'invoices',
|
||||
];
|
||||
|
||||
public function includeContacts(Vendor $vendor)
|
||||
{
|
||||
$transformer = new ContactTransformer($this->account, $this->serializer);
|
||||
return $this->includeCollection($vendor->contacts, $transformer, ENTITY_CONTACT);
|
||||
}
|
||||
|
||||
public function includeInvoices(Vendor $vendor)
|
||||
{
|
||||
$transformer = new InvoiceTransformer($this->account, $this->serializer);
|
||||
return $this->includeCollection($vendor->invoices, $transformer, ENTITY_INVOICE);
|
||||
}
|
||||
|
||||
public function transform(Vendor $vendor)
|
||||
{
|
||||
return [
|
||||
'id' => (int) $vendor->public_id,
|
||||
'name' => $vendor->name,
|
||||
'balance' => (float) $vendor->balance,
|
||||
'paid_to_date' => (float) $vendor->paid_to_date,
|
||||
'user_id' => (int) $vendor->user->public_id + 1,
|
||||
'account_key' => $this->account->account_key,
|
||||
'updated_at' => $this->getTimestamp($vendor->updated_at),
|
||||
'archived_at' => $this->getTimestamp($vendor->deleted_at),
|
||||
'address1' => $vendor->address1,
|
||||
'address2' => $vendor->address2,
|
||||
'city' => $vendor->city,
|
||||
'state' => $vendor->state,
|
||||
'postal_code' => $vendor->postal_code,
|
||||
'country_id' => (int) $vendor->country_id,
|
||||
'work_phone' => $vendor->work_phone,
|
||||
'private_notes' => $vendor->private_notes,
|
||||
'last_login' => $vendor->last_login,
|
||||
'website' => $vendor->website,
|
||||
'industry_id' => (int) $vendor->industry_id,
|
||||
'size_id' => (int) $vendor->size_id,
|
||||
'is_deleted' => (bool) $vendor->is_deleted,
|
||||
'payment_terms' => (int) $vendor->payment_terms,
|
||||
'vat_number' => $vendor->vat_number,
|
||||
'id_number' => $vendor->id_number,
|
||||
'language_id' => (int) $vendor->language_id,
|
||||
'currency_id' => (int) $vendor->currency_id
|
||||
];
|
||||
}
|
||||
}
|
@ -53,7 +53,11 @@ class AppServiceProvider extends ServiceProvider {
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="'.URL::to('credits').'">'.trans("texts.credits").'</a></li>
|
||||
<li><a href="'.URL::to('credits/create').'">'.trans("texts.new_credit").'</a></li>';
|
||||
}
|
||||
} else if ($type == ENTITY_EXPENSE) {
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="'.URL::to('vendors').'">'.trans("texts.vendors").'</a></li>
|
||||
<li><a href="'.URL::to('vendors/create').'">'.trans("texts.new_vendor").'</a></li>';
|
||||
}
|
||||
|
||||
$str .= '</ul>
|
||||
</li>';
|
||||
|
@ -138,6 +138,36 @@ class EventServiceProvider extends ServiceProvider {
|
||||
'App\Listeners\HandleUserSettingsChanged',
|
||||
],
|
||||
|
||||
// vendor events
|
||||
'App\Events\VendorWasCreated' => [
|
||||
'App\Listeners\VendorActivityListener@createdVendor',
|
||||
'App\Listeners\SubscriptionListener@createdVendor',
|
||||
],
|
||||
'App\Events\VendorWasArchived' => [
|
||||
'App\Listeners\VendorActivityListener@archivedVendor',
|
||||
],
|
||||
'App\Events\VendorWasDeleted' => [
|
||||
'App\Listeners\VendorActivityListener@deletedVendor',
|
||||
],
|
||||
'App\Events\VendorWasRestored' => [
|
||||
'App\Listeners\VendorActivityListener@restoredVendor',
|
||||
],
|
||||
|
||||
// Expense events
|
||||
'App\Events\ExpenseWasCreated' => [
|
||||
'App\Listeners\ExpenseActivityListener@createdExpense',
|
||||
'App\Listeners\SubscriptionListener@createdExpense',
|
||||
],
|
||||
'App\Events\ExpenseWasArchived' => [
|
||||
'App\Listeners\ExpenseActivityListener@archivedExpense',
|
||||
],
|
||||
'App\Events\ExpenseWasDeleted' => [
|
||||
'App\Listeners\ExpenseActivityListener@deletedExpense',
|
||||
],
|
||||
'App\Events\ExpenseWasRestored' => [
|
||||
'App\Listeners\ExpenseActivityListener@restoredExpense',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
|
62
app/Services/ExpenseActivityService.php
Normal file
62
app/Services/ExpenseActivityService.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php namespace App\Services;
|
||||
|
||||
use Utils;
|
||||
use App\Models\Expense;
|
||||
use App\Services\BaseService;
|
||||
use App\Ninja\Repositories\ExpenseActivityRepository;
|
||||
|
||||
class ExpenseActivityService extends BaseService
|
||||
{
|
||||
protected $activityRepo;
|
||||
protected $datatableService;
|
||||
|
||||
public function __construct(ExpenseActivityRepository $activityRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->activityRepo = $activityRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
public function getDatatable($expensePublicId = null)
|
||||
{
|
||||
$expenseId = Expense::getPrivateId($expensePublicId);
|
||||
|
||||
$query = $this->activityRepo->findByExpenseId($expenseId);
|
||||
|
||||
return $this->createDatatable(ENTITY_EXPENSE_ACTIVITY, $query);
|
||||
}
|
||||
|
||||
protected function getDatatableColumns($entityType, $hideExpense)
|
||||
{
|
||||
return [
|
||||
[
|
||||
'expense_activities.id',
|
||||
function ($model) {
|
||||
return Utils::timestampToDateTimeString(strtotime($model->created_at));
|
||||
}
|
||||
],
|
||||
[
|
||||
'activity_type_id',
|
||||
function ($model) {
|
||||
$data = [
|
||||
'expense' => link_to('/expenses/' . $model->public_id, trans('texts.view_expense',['expense' => $model->public_id])),
|
||||
'user' => $model->is_system ? '<i>' . trans('texts.system') . '</i>' : Utils::getPersonDisplayName($model->user_first_name, $model->user_last_name, $model->user_email),
|
||||
];
|
||||
|
||||
return trans("texts.activity_{$model->activity_type_id}", $data);
|
||||
}
|
||||
],
|
||||
[
|
||||
'amount',
|
||||
function ($model) {
|
||||
return Utils::formatMoney($model->amount);
|
||||
}
|
||||
],
|
||||
[
|
||||
'expense_date',
|
||||
function ($model) {
|
||||
return Utils::fromSqlDate($model->expense_date);
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
188
app/Services/ExpenseService.php
Normal file
188
app/Services/ExpenseService.php
Normal file
@ -0,0 +1,188 @@
|
||||
<?php namespace App\Services;
|
||||
|
||||
use DB;
|
||||
use Utils;
|
||||
use URL;
|
||||
use App\Services\BaseService;
|
||||
use App\Ninja\Repositories\ExpenseRepository;
|
||||
|
||||
|
||||
class ExpenseService extends BaseService
|
||||
{
|
||||
// Expenses
|
||||
protected $expenseRepo;
|
||||
protected $datatableService;
|
||||
|
||||
public function __construct(ExpenseRepository $expenseRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->expenseRepo = $expenseRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
protected function getRepo()
|
||||
{
|
||||
return $this->expenseRepo;
|
||||
}
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
return $this->expenseRepo->save($data);
|
||||
}
|
||||
|
||||
public function getDatatable($search)
|
||||
{
|
||||
$query = $this->expenseRepo->find($search);
|
||||
|
||||
return $this->createDatatable(ENTITY_EXPENSE, $query);
|
||||
}
|
||||
|
||||
public function getDatatableVendor($vendorPublicId)
|
||||
{
|
||||
$query = $this->expenseRepo->findVendor($vendorPublicId);
|
||||
return $this->datatableService->createDatatable(ENTITY_EXPENSE,
|
||||
$query,
|
||||
$this->getDatatableColumnsVendor(ENTITY_EXPENSE,false),
|
||||
$this->getDatatableActionsVendor(ENTITY_EXPENSE),
|
||||
false);
|
||||
}
|
||||
|
||||
protected function getDatatableColumns($entityType, $hideClient)
|
||||
{
|
||||
return [
|
||||
[
|
||||
'vendor_name',
|
||||
function ($model)
|
||||
{
|
||||
if($model->vendor_public_id) {
|
||||
return link_to("vendors/{$model->vendor_public_id}", $model->vendor_name);
|
||||
} else {
|
||||
return 'No vendor' ;
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'amount',
|
||||
function ($model) {
|
||||
return Utils::formatMoney($model->amount, false, false);
|
||||
}
|
||||
],
|
||||
[
|
||||
'expense_date',
|
||||
function ($model) {
|
||||
return Utils::fromSqlDate($model->expense_date);
|
||||
}
|
||||
],
|
||||
[
|
||||
'public_notes',
|
||||
function ($model) {
|
||||
return $model->public_notes != null ? $model->public_notes : '';
|
||||
}
|
||||
],
|
||||
[
|
||||
'is_invoiced',
|
||||
function ($model) {
|
||||
return $model->is_invoiced ? trans('texts.yes') : trans('texts.no');
|
||||
}
|
||||
],
|
||||
[
|
||||
'should_be_invoiced',
|
||||
function ($model) {
|
||||
return $model->should_be_invoiced ? trans('texts.yes') : trans('texts.no');
|
||||
}
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getDatatableColumnsVendor($entityType, $hideClient)
|
||||
{
|
||||
return [
|
||||
/*
|
||||
[
|
||||
'expenses.id',
|
||||
function ($model) {
|
||||
return Utils::timestampToDateTimeString(strtotime($model->created_at));
|
||||
}
|
||||
],*/
|
||||
[
|
||||
'expense_date',
|
||||
function ($model) {
|
||||
return $model->expense_date;
|
||||
}
|
||||
],
|
||||
[
|
||||
'amount',
|
||||
function ($model) {
|
||||
return Utils::formatMoney($model->amount, false, false);
|
||||
}
|
||||
],
|
||||
[
|
||||
'public_notes',
|
||||
function ($model) {
|
||||
return $model->public_notes != null ? $model->public_notes : '';
|
||||
}
|
||||
],
|
||||
[
|
||||
'is_invoiced',
|
||||
function ($model) {
|
||||
return $model->is_invoiced ? trans('texts.yes') : trans('texts.no');
|
||||
}
|
||||
],
|
||||
[
|
||||
'should_be_invoiced',
|
||||
function ($model) {
|
||||
return $model->should_be_invoiced ? trans('texts.yes') : trans('texts.no');
|
||||
}
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getDatatableActions($entityType)
|
||||
{
|
||||
return [
|
||||
[
|
||||
trans('texts.invoice_expense'),
|
||||
function ($model) {
|
||||
return URL::to("expense/invoice/{$model->public_id}") . '?client=1';
|
||||
}
|
||||
],
|
||||
[
|
||||
trans('texts.view'),
|
||||
function ($model) {
|
||||
return URL::to("expenses/{$model->public_id}") ;
|
||||
}
|
||||
],
|
||||
[
|
||||
trans('texts.edit'),
|
||||
function ($model) {
|
||||
return URL::to("expenses/{$model->public_id}/edit") ;
|
||||
}
|
||||
],
|
||||
|
||||
];
|
||||
}
|
||||
protected function getDatatableActionsVendor($entityType)
|
||||
{
|
||||
return [
|
||||
[
|
||||
trans('texts.invoice_expense'),
|
||||
function ($model) {
|
||||
return URL::to("expense/invoice/{$model->public_id}") . '?client=1';
|
||||
}
|
||||
],
|
||||
[
|
||||
trans('texts.view'),
|
||||
function ($model) {
|
||||
return URL::to("expenses/{$model->public_id}") ;
|
||||
}
|
||||
],
|
||||
[
|
||||
trans('texts.edit'),
|
||||
function ($model) {
|
||||
return URL::to("expenses/{$model->public_id}/edit") ;
|
||||
}
|
||||
],
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
}
|
60
app/Services/PaymentTermService.php
Normal file
60
app/Services/PaymentTermService.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php namespace App\Services;
|
||||
|
||||
use URL;
|
||||
use Auth;
|
||||
use App\Services\BaseService;
|
||||
use App\Ninja\Repositories\PaymentTermRepository;
|
||||
|
||||
class PaymentTermService extends BaseService
|
||||
{
|
||||
protected $paymentTermRepo;
|
||||
protected $datatableService;
|
||||
|
||||
public function __construct(PaymentTermRepository $paymentTermRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->paymentTermRepo = $paymentTermRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
protected function getRepo()
|
||||
{
|
||||
return $this->paymentTermRepo;
|
||||
}
|
||||
|
||||
public function getDatatable($accountId = 0)
|
||||
{
|
||||
$query = $this->paymentTermRepo->find();
|
||||
|
||||
return $this->createDatatable(ENTITY_PAYMENT_TERM, $query, false);
|
||||
}
|
||||
|
||||
protected function getDatatableColumns($entityType, $hideClient)
|
||||
{
|
||||
return [
|
||||
[
|
||||
'name',
|
||||
function ($model) {
|
||||
return link_to("payment_terms/{$model->public_id}/edit", $model->name);
|
||||
}
|
||||
],
|
||||
[
|
||||
'days',
|
||||
function ($model) {
|
||||
return $model->num_days;
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
protected function getDatatableActions($entityType)
|
||||
{
|
||||
return [
|
||||
[
|
||||
uctrans('texts.edit_payment_terms'),
|
||||
function ($model) {
|
||||
return URL::to("payment_terms/{$model->public_id}/edit");
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
64
app/Services/VendorActivityService.php
Normal file
64
app/Services/VendorActivityService.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php namespace App\Services;
|
||||
// vendor
|
||||
use Utils;
|
||||
use App\Models\Vendor;
|
||||
use App\Services\BaseService;
|
||||
use App\Ninja\Repositories\VendorActivityRepository;
|
||||
|
||||
class VendorActivityService extends BaseService
|
||||
{
|
||||
protected $activityRepo;
|
||||
protected $datatableService;
|
||||
|
||||
public function __construct(VendorActivityRepository $activityRepo, DatatableService $datatableService)
|
||||
{
|
||||
$this->activityRepo = $activityRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
public function getDatatable($vendorPublicId = null)
|
||||
{
|
||||
$vendorId = Vendor::getPrivateId($vendorPublicId);
|
||||
|
||||
$query = $this->activityRepo->findByVendorId($vendorId);
|
||||
|
||||
return $this->createDatatable(ENTITY_ACTIVITY, $query);
|
||||
}
|
||||
|
||||
protected function getDatatableColumns($entityType, $hideVendor)
|
||||
{
|
||||
return [
|
||||
[
|
||||
'vendor_activities.id',
|
||||
function ($model) {
|
||||
return Utils::timestampToDateTimeString(strtotime($model->created_at));
|
||||
}
|
||||
],
|
||||
[
|
||||
'activity_type_id',
|
||||
function ($model) {
|
||||
$data = [
|
||||
'vendor' => link_to('/vendors/' . $model->vendor_public_id, Utils::getVendorDisplayName($model)),
|
||||
'user' => $model->is_system ? '<i>' . trans('texts.system') . '</i>' : Utils::getPersonDisplayName($model->user_first_name, $model->user_last_name, $model->user_email),
|
||||
'contact' => $model->contact_id ? link_to('/vendors/' . $model->vendor_public_id, Utils::getVendorDisplayName($model)) : Utils::getPersonDisplayName($model->user_first_name, $model->user_last_name, $model->user_email),
|
||||
'balance' => Utils::formatMoney($model->balance, $model->currency_id, $model->country_id)
|
||||
];
|
||||
|
||||
return trans("texts.activity_{$model->activity_type_id}", $data);
|
||||
}
|
||||
],
|
||||
[
|
||||
'balance',
|
||||
function ($model) {
|
||||
return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id);
|
||||
}
|
||||
],
|
||||
[
|
||||
'adjustment',
|
||||
function ($model) {
|
||||
return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id, $model->country_id) : '';
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
97
app/Services/VendorService.php
Normal file
97
app/Services/VendorService.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php namespace App\Services;
|
||||
|
||||
use Utils;
|
||||
use URL;
|
||||
use Auth;
|
||||
use App\Services\BaseService;
|
||||
use App\Ninja\Repositories\VendorRepository;
|
||||
use App\Ninja\Repositories\NinjaRepository;
|
||||
|
||||
class VendorService extends BaseService
|
||||
{
|
||||
protected $vendorRepo;
|
||||
protected $datatableService;
|
||||
|
||||
public function __construct(VendorRepository $vendorRepo, DatatableService $datatableService, NinjaRepository $ninjaRepo)
|
||||
{
|
||||
$this->vendorRepo = $vendorRepo;
|
||||
$this->ninjaRepo = $ninjaRepo;
|
||||
$this->datatableService = $datatableService;
|
||||
}
|
||||
|
||||
protected function getRepo()
|
||||
{
|
||||
return $this->vendorRepo;
|
||||
}
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
if (Auth::user()->account->isNinjaAccount() && isset($data['pro_plan_paid'])) {
|
||||
$this->ninjaRepo->updateProPlanPaid($data['public_id'], $data['pro_plan_paid']);
|
||||
}
|
||||
|
||||
return $this->vendorRepo->save($data);
|
||||
}
|
||||
|
||||
public function getDatatable($search)
|
||||
{
|
||||
$query = $this->vendorRepo->find($search);
|
||||
|
||||
return $this->createDatatable(ENTITY_VENDOR, $query);
|
||||
}
|
||||
|
||||
protected function getDatatableColumns($entityType, $hideVendor)
|
||||
{
|
||||
return [
|
||||
[
|
||||
'name',
|
||||
function ($model) {
|
||||
return link_to("vendors/{$model->public_id}", $model->name ?: '');
|
||||
}
|
||||
],
|
||||
[
|
||||
'first_name',
|
||||
function ($model) {
|
||||
return link_to("vendors/{$model->public_id}", $model->first_name.' '.$model->last_name);
|
||||
}
|
||||
],
|
||||
[
|
||||
'email',
|
||||
function ($model) {
|
||||
return link_to("vendors/{$model->public_id}", $model->email ?: '');
|
||||
}
|
||||
],
|
||||
[
|
||||
'vendors.created_at',
|
||||
function ($model) {
|
||||
return Utils::timestampToDateString(strtotime($model->created_at));
|
||||
}
|
||||
],
|
||||
[
|
||||
'balance',
|
||||
function ($model) {
|
||||
return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id);
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
protected function getDatatableActions($entityType)
|
||||
{
|
||||
return [
|
||||
[
|
||||
trans('texts.edit_vendor'),
|
||||
function ($model) {
|
||||
return URL::to("vendors/{$model->public_id}/edit");
|
||||
}
|
||||
],
|
||||
[],
|
||||
[
|
||||
trans('texts.enter_expense'),
|
||||
function ($model) {
|
||||
return URL::to("expenses/create/{$model->public_id}");
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
"omnipay/omnipay": "~2.3.0",
|
||||
"intervention/image": "dev-master",
|
||||
"webpatser/laravel-countries": "dev-master",
|
||||
"barryvdh/laravel-ide-helper": "2.0.x",
|
||||
"barryvdh/laravel-ide-helper": "^2.1",
|
||||
"doctrine/dbal": "2.5.x",
|
||||
"jsanc623/phpbenchtime": "2.x",
|
||||
"lokielse/omnipay-alipay": "dev-master",
|
||||
|
323
composer.lock
generated
323
composer.lock
generated
@ -4,8 +4,8 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "f3b07ee34ed5086cd684a7207fd3617e",
|
||||
"content-hash": "7305e2f5d6864894aeb23ac91f3e1fe7",
|
||||
"hash": "67f1ec18911e60b4f0babd8991278fda",
|
||||
"content-hash": "862c124e81438b922db1afe626149ec0",
|
||||
"packages": [
|
||||
{
|
||||
"name": "agmscode/omnipay-agms",
|
||||
@ -123,12 +123,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/alfaproject/omnipay-skrill.git",
|
||||
"reference": "2fa2ba8083fd5289366660f8de1b46b5f49ac052"
|
||||
"reference": "41a7a03c5b90d496720e288bebc157d898837ccd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/alfaproject/omnipay-skrill/zipball/2fa2ba8083fd5289366660f8de1b46b5f49ac052",
|
||||
"reference": "2fa2ba8083fd5289366660f8de1b46b5f49ac052",
|
||||
"url": "https://api.github.com/repos/alfaproject/omnipay-skrill/zipball/41a7a03c5b90d496720e288bebc157d898837ccd",
|
||||
"reference": "41a7a03c5b90d496720e288bebc157d898837ccd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -169,7 +169,7 @@
|
||||
"payment",
|
||||
"skrill"
|
||||
],
|
||||
"time": "2014-02-25 13:40:07"
|
||||
"time": "2016-01-13 16:33:07"
|
||||
},
|
||||
{
|
||||
"name": "anahkiasen/former",
|
||||
@ -379,22 +379,22 @@
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-ide-helper",
|
||||
"version": "v2.0.6",
|
||||
"version": "v2.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-ide-helper.git",
|
||||
"reference": "037386153630a7515a1542f29410d8c267651689"
|
||||
"reference": "d82e8f191fb043a0f8cbf2de64fd3027bfa4f772"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/037386153630a7515a1542f29410d8c267651689",
|
||||
"reference": "037386153630a7515a1542f29410d8c267651689",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/d82e8f191fb043a0f8cbf2de64fd3027bfa4f772",
|
||||
"reference": "d82e8f191fb043a0f8cbf2de64fd3027bfa4f772",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/console": "5.0.x|5.1.x",
|
||||
"illuminate/filesystem": "5.0.x|5.1.x",
|
||||
"illuminate/support": "5.0.x|5.1.x",
|
||||
"illuminate/console": "5.0.x|5.1.x|5.2.x",
|
||||
"illuminate/filesystem": "5.0.x|5.1.x|5.2.x",
|
||||
"illuminate/support": "5.0.x|5.1.x|5.2.x",
|
||||
"php": ">=5.4.0",
|
||||
"phpdocumentor/reflection-docblock": "2.0.4",
|
||||
"symfony/class-loader": "~2.3"
|
||||
@ -408,7 +408,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
"dev-master": "2.1-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -438,7 +438,7 @@
|
||||
"phpstorm",
|
||||
"sublime"
|
||||
],
|
||||
"time": "2015-06-25 08:58:59"
|
||||
"time": "2015-12-21 19:48:06"
|
||||
},
|
||||
{
|
||||
"name": "cardgate/omnipay-cardgate",
|
||||
@ -1272,33 +1272,33 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "v1.5.4",
|
||||
"version": "v1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136"
|
||||
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/47cdc76ceb95cc591d9c79a36dc3794975b5d136",
|
||||
"reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6",
|
||||
"reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
"php": "~5.5|~7.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": ">2.2,<2.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": ">=3.7",
|
||||
"phpunit/phpunit": "~4.8|~5.0",
|
||||
"predis/predis": "~1.0",
|
||||
"satooshi/php-coveralls": "~0.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.5.x-dev"
|
||||
"dev-master": "1.6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1338,7 +1338,7 @@
|
||||
"cache",
|
||||
"caching"
|
||||
],
|
||||
"time": "2015-12-19 05:03:47"
|
||||
"time": "2015-12-31 16:37:02"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
@ -1481,16 +1481,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "v2.5.3",
|
||||
"version": "v2.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "2fbcea96eae34a53183377cdbb0b9bec33974648"
|
||||
"reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/2fbcea96eae34a53183377cdbb0b9bec33974648",
|
||||
"reference": "2fbcea96eae34a53183377cdbb0b9bec33974648",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
|
||||
"reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1548,7 +1548,7 @@
|
||||
"persistence",
|
||||
"queryobject"
|
||||
],
|
||||
"time": "2015-12-25 16:28:24"
|
||||
"time": "2016-01-05 22:11:12"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
@ -2254,12 +2254,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Intervention/image.git",
|
||||
"reference": "e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70"
|
||||
"reference": "86dfe2f2a95aa9eed58faf1cc1dae6534a6ce931"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Intervention/image/zipball/e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70",
|
||||
"reference": "e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70",
|
||||
"url": "https://api.github.com/repos/Intervention/image/zipball/86dfe2f2a95aa9eed58faf1cc1dae6534a6ce931",
|
||||
"reference": "86dfe2f2a95aa9eed58faf1cc1dae6534a6ce931",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2308,7 +2308,7 @@
|
||||
"thumbnail",
|
||||
"watermark"
|
||||
],
|
||||
"time": "2015-12-04 17:09:36"
|
||||
"time": "2016-01-10 11:20:02"
|
||||
},
|
||||
{
|
||||
"name": "ircmaxell/password-compat",
|
||||
@ -3463,12 +3463,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/meebio/omnipay-secure-trading.git",
|
||||
"reference": "42f97ee5ad1d28605550d816fc1893919e19e502"
|
||||
"reference": "992224a3c8dd834ee18f6f253a77ecb4c87c1c1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/meebio/omnipay-secure-trading/zipball/42f97ee5ad1d28605550d816fc1893919e19e502",
|
||||
"reference": "42f97ee5ad1d28605550d816fc1893919e19e502",
|
||||
"url": "https://api.github.com/repos/meebio/omnipay-secure-trading/zipball/992224a3c8dd834ee18f6f253a77ecb4c87c1c1a",
|
||||
"reference": "992224a3c8dd834ee18f6f253a77ecb4c87c1c1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3513,7 +3513,7 @@
|
||||
"secure trading",
|
||||
"securetrading"
|
||||
],
|
||||
"time": "2015-12-01 10:03:20"
|
||||
"time": "2016-01-05 09:26:36"
|
||||
},
|
||||
{
|
||||
"name": "mfauveau/omnipay-pacnet",
|
||||
@ -4363,16 +4363,16 @@
|
||||
},
|
||||
{
|
||||
"name": "omnipay/firstdata",
|
||||
"version": "v2.2.0",
|
||||
"version": "v2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/omnipay-firstdata.git",
|
||||
"reference": "0853bba0ee313f5557eb1c696d3ce5538dbd4aca"
|
||||
"reference": "e33826821db88d90886cad6c81a29452d3cf91a2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-firstdata/zipball/0853bba0ee313f5557eb1c696d3ce5538dbd4aca",
|
||||
"reference": "0853bba0ee313f5557eb1c696d3ce5538dbd4aca",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-firstdata/zipball/e33826821db88d90886cad6c81a29452d3cf91a2",
|
||||
"reference": "e33826821db88d90886cad6c81a29452d3cf91a2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4417,7 +4417,7 @@
|
||||
"pay",
|
||||
"payment"
|
||||
],
|
||||
"time": "2015-07-28 17:50:44"
|
||||
"time": "2016-01-14 06:24:28"
|
||||
},
|
||||
{
|
||||
"name": "omnipay/gocardless",
|
||||
@ -5112,16 +5112,16 @@
|
||||
},
|
||||
{
|
||||
"name": "omnipay/paypal",
|
||||
"version": "2.5.0",
|
||||
"version": "v2.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/omnipay-paypal.git",
|
||||
"reference": "67efe5a927dec13fc7520e29bc44f15fd3a728e9"
|
||||
"reference": "b546d24241725061d44e60516f0fbce202336963"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/67efe5a927dec13fc7520e29bc44f15fd3a728e9",
|
||||
"reference": "67efe5a927dec13fc7520e29bc44f15fd3a728e9",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/b546d24241725061d44e60516f0fbce202336963",
|
||||
"reference": "b546d24241725061d44e60516f0fbce202336963",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5166,20 +5166,20 @@
|
||||
"paypal",
|
||||
"purchase"
|
||||
],
|
||||
"time": "2015-11-11 21:48:00"
|
||||
"time": "2016-01-13 07:03:27"
|
||||
},
|
||||
{
|
||||
"name": "omnipay/pin",
|
||||
"version": "v2.1.0",
|
||||
"version": "v2.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/omnipay/pin.git",
|
||||
"reference": "04e778e9689882d4c40419263014068b69b93168"
|
||||
"url": "https://github.com/thephpleague/omnipay-pin.git",
|
||||
"reference": "c2252e41f3674267b2bbe79eaeec73b6b1e4ee58"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/omnipay/pin/zipball/04e778e9689882d4c40419263014068b69b93168",
|
||||
"reference": "04e778e9689882d4c40419263014068b69b93168",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-pin/zipball/c2252e41f3674267b2bbe79eaeec73b6b1e4ee58",
|
||||
"reference": "c2252e41f3674267b2bbe79eaeec73b6b1e4ee58",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5210,11 +5210,11 @@
|
||||
},
|
||||
{
|
||||
"name": "Omnipay Contributors",
|
||||
"homepage": "https://github.com/omnipay/pin/contributors"
|
||||
"homepage": "https://github.com/thephpleague/omnipay-pin/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Pin Payments driver for the Omnipay payment processing library",
|
||||
"homepage": "https://github.com/omnipay/pin",
|
||||
"homepage": "https://github.com/thephpleague/omnipay-pin",
|
||||
"keywords": [
|
||||
"gateway",
|
||||
"merchant",
|
||||
@ -5223,20 +5223,20 @@
|
||||
"payment",
|
||||
"pin"
|
||||
],
|
||||
"time": "2014-04-14 11:26:15"
|
||||
"time": "2016-01-13 07:00:17"
|
||||
},
|
||||
{
|
||||
"name": "omnipay/sagepay",
|
||||
"version": "v2.2.0",
|
||||
"version": "2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/omnipay-sagepay.git",
|
||||
"reference": "899507095428fa54276ba5ca89f11fd7f8fd78ab"
|
||||
"reference": "4208d23b33b2f8a59176e44ad22d304c461ecb62"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/899507095428fa54276ba5ca89f11fd7f8fd78ab",
|
||||
"reference": "899507095428fa54276ba5ca89f11fd7f8fd78ab",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-sagepay/zipball/4208d23b33b2f8a59176e44ad22d304c461ecb62",
|
||||
"reference": "4208d23b33b2f8a59176e44ad22d304c461ecb62",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5282,7 +5282,7 @@
|
||||
"sage pay",
|
||||
"sagepay"
|
||||
],
|
||||
"time": "2015-04-02 17:46:20"
|
||||
"time": "2016-01-12 12:43:31"
|
||||
},
|
||||
{
|
||||
"name": "omnipay/securepay",
|
||||
@ -5343,16 +5343,16 @@
|
||||
},
|
||||
{
|
||||
"name": "omnipay/stripe",
|
||||
"version": "v2.3.0",
|
||||
"version": "v2.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/omnipay-stripe.git",
|
||||
"reference": "54b816a5e95e34c988d71fb805b0232cfd7c1ce5"
|
||||
"reference": "6c4cef5b5168a58476eef6fa73b7875e15c94b6f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-stripe/zipball/54b816a5e95e34c988d71fb805b0232cfd7c1ce5",
|
||||
"reference": "54b816a5e95e34c988d71fb805b0232cfd7c1ce5",
|
||||
"url": "https://api.github.com/repos/thephpleague/omnipay-stripe/zipball/6c4cef5b5168a58476eef6fa73b7875e15c94b6f",
|
||||
"reference": "6c4cef5b5168a58476eef6fa73b7875e15c94b6f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -5396,7 +5396,7 @@
|
||||
"payment",
|
||||
"stripe"
|
||||
],
|
||||
"time": "2015-11-10 16:17:35"
|
||||
"time": "2016-01-13 04:00:45"
|
||||
},
|
||||
{
|
||||
"name": "omnipay/targetpay",
|
||||
@ -5512,6 +5512,54 @@
|
||||
],
|
||||
"time": "2014-09-17 00:37:18"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "1.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/dd8998b7c846f6909f4e7a5f67fabebfc412a4f7",
|
||||
"reference": "dd8998b7c846f6909f4e7a5f67fabebfc412a4f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/random.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com"
|
||||
}
|
||||
],
|
||||
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||
"keywords": [
|
||||
"csprng",
|
||||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2016-01-06 13:31:20"
|
||||
},
|
||||
{
|
||||
"name": "patricktalmadge/bootstrapper",
|
||||
"version": "5.5.3",
|
||||
@ -6058,16 +6106,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/class-loader.git",
|
||||
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c"
|
||||
"reference": "98e9089a428ed0e39423b67352c57ef5910a3269"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
|
||||
"reference": "ec74b0a279cf3a9bd36172b3e3061591d380ce6c",
|
||||
"url": "https://api.github.com/repos/symfony/class-loader/zipball/98e9089a428ed0e39423b67352c57ef5910a3269",
|
||||
"reference": "98e9089a428ed0e39423b67352c57ef5910a3269",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6106,11 +6154,11 @@
|
||||
],
|
||||
"description": "Symfony ClassLoader Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-12-05 17:37:59"
|
||||
"time": "2016-01-03 15:33:41"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/Console",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -6168,16 +6216,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/css-selector.git",
|
||||
"reference": "eaa3320e32f09a01dc432c6efbe8051aee59cfef"
|
||||
"reference": "ac06d8173bd80790536c0a4a634a7d705b91f54f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/eaa3320e32f09a01dc432c6efbe8051aee59cfef",
|
||||
"reference": "eaa3320e32f09a01dc432c6efbe8051aee59cfef",
|
||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/ac06d8173bd80790536c0a4a634a7d705b91f54f",
|
||||
"reference": "ac06d8173bd80790536c0a4a634a7d705b91f54f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6217,11 +6265,11 @@
|
||||
],
|
||||
"description": "Symfony CssSelector Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-12-05 17:37:59"
|
||||
"time": "2016-01-03 15:33:41"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/Debug",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -6282,16 +6330,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc"
|
||||
"reference": "ee278f7c851533e58ca307f66305ccb9188aceda"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc",
|
||||
"reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ee278f7c851533e58ca307f66305ccb9188aceda",
|
||||
"reference": "ee278f7c851533e58ca307f66305ccb9188aceda",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6338,20 +6386,20 @@
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-10-30 20:15:42"
|
||||
"time": "2016-01-13 10:28:07"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc"
|
||||
"reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/a7ad724530a764d70c168d321ac226ba3d2f10fc",
|
||||
"reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/637b64d0ee10f44ae98dbad651b1ecdf35a11e8c",
|
||||
"reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6387,11 +6435,11 @@
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-12-22 10:25:57"
|
||||
"time": "2016-01-13 10:28:07"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/Finder",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -6441,7 +6489,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/HttpFoundation",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -6495,17 +6543,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/HttpKernel",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6"
|
||||
"reference": "cdd991d304fed833514dc44d6aafcf19397c26cb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
|
||||
"reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/cdd991d304fed833514dc44d6aafcf19397c26cb",
|
||||
"reference": "cdd991d304fed833514dc44d6aafcf19397c26cb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6569,7 +6617,7 @@
|
||||
],
|
||||
"description": "Symfony HttpKernel Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-11-23 11:37:53"
|
||||
"time": "2016-01-14 10:11:16"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php56",
|
||||
@ -6681,7 +6729,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/Process",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -6731,7 +6779,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/Routing",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -6800,20 +6848,21 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/security-core",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/Security/Core",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/security-core.git",
|
||||
"reference": "05f58bb3814e8a853332dc448e3b7addaa87679c"
|
||||
"reference": "813cf2aaacccbbe1a4705aef8d4ac0d79d993a76"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/security-core/zipball/05f58bb3814e8a853332dc448e3b7addaa87679c",
|
||||
"reference": "05f58bb3814e8a853332dc448e3b7addaa87679c",
|
||||
"url": "https://api.github.com/repos/symfony/security-core/zipball/813cf2aaacccbbe1a4705aef8d4ac0d79d993a76",
|
||||
"reference": "813cf2aaacccbbe1a4705aef8d4ac0d79d993a76",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"paragonie/random_compat": "~1.0",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
@ -6860,11 +6909,11 @@
|
||||
],
|
||||
"description": "Symfony Security Component - Core Library",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-07-22 10:08:40"
|
||||
"time": "2016-01-14 09:04:34"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/Translation",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -6923,7 +6972,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v2.6.12",
|
||||
"version": "v2.6.13",
|
||||
"target-dir": "Symfony/Component/VarDumper",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@ -7030,16 +7079,16 @@
|
||||
},
|
||||
{
|
||||
"name": "true/punycode",
|
||||
"version": "v2.0.1",
|
||||
"version": "v2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/true/php-punycode.git",
|
||||
"reference": "b672918d992b84f8016bbe353a42516928393c63"
|
||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/true/php-punycode/zipball/b672918d992b84f8016bbe353a42516928393c63",
|
||||
"reference": "b672918d992b84f8016bbe353a42516928393c63",
|
||||
"url": "https://api.github.com/repos/true/php-punycode/zipball/74fa01d4de396c40e239794123b3874cb594a30c",
|
||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7072,7 +7121,7 @@
|
||||
"idna",
|
||||
"punycode"
|
||||
],
|
||||
"time": "2015-09-01 14:53:31"
|
||||
"time": "2016-01-07 17:12:58"
|
||||
},
|
||||
{
|
||||
"name": "twbs/bootstrap",
|
||||
@ -7347,16 +7396,16 @@
|
||||
},
|
||||
{
|
||||
"name": "zircote/swagger-php",
|
||||
"version": "2.0.4",
|
||||
"version": "2.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/zircote/swagger-php.git",
|
||||
"reference": "be5d96e56c23cbe52c5bc5e267851323d95c57cd"
|
||||
"reference": "c19af4edcc13c00e82fabeee926335b1fe1d92e9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/be5d96e56c23cbe52c5bc5e267851323d95c57cd",
|
||||
"reference": "be5d96e56c23cbe52c5bc5e267851323d95c57cd",
|
||||
"url": "https://api.github.com/repos/zircote/swagger-php/zipball/c19af4edcc13c00e82fabeee926335b1fe1d92e9",
|
||||
"reference": "c19af4edcc13c00e82fabeee926335b1fe1d92e9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7403,7 +7452,7 @@
|
||||
"rest",
|
||||
"service discovery"
|
||||
],
|
||||
"time": "2015-11-13 13:50:11"
|
||||
"time": "2016-01-15 09:39:28"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@ -7593,16 +7642,16 @@
|
||||
},
|
||||
{
|
||||
"name": "facebook/webdriver",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/php-webdriver.git",
|
||||
"reference": "518a9e0635e69777f07e41619cdf5d82fae284b6"
|
||||
"reference": "1c98108ba3eb435b681655764de11502a0653705"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/518a9e0635e69777f07e41619cdf5d82fae284b6",
|
||||
"reference": "518a9e0635e69777f07e41619cdf5d82fae284b6",
|
||||
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/1c98108ba3eb435b681655764de11502a0653705",
|
||||
"reference": "1c98108ba3eb435b681655764de11502a0653705",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7632,7 +7681,7 @@
|
||||
"selenium",
|
||||
"webdriver"
|
||||
],
|
||||
"time": "2015-12-08 17:04:30"
|
||||
"time": "2015-12-31 15:58:49"
|
||||
},
|
||||
{
|
||||
"name": "fzaninotto/faker",
|
||||
@ -7722,16 +7771,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpspec/phpspec",
|
||||
"version": "2.4.0",
|
||||
"version": "2.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/phpspec.git",
|
||||
"reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358"
|
||||
"reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/1d3938e6d9ffb1bd4805ea8ddac62ea48767f358",
|
||||
"reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358",
|
||||
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/5528ce1e93a1efa090c9404aba3395c329b4e6ed",
|
||||
"reference": "5528ce1e93a1efa090c9404aba3395c329b4e6ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7796,7 +7845,7 @@
|
||||
"testing",
|
||||
"tests"
|
||||
],
|
||||
"time": "2015-11-29 02:03:49"
|
||||
"time": "2016-01-01 10:17:54"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
@ -8599,16 +8648,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/browser-kit",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/browser-kit.git",
|
||||
"reference": "dd2cfb20fabd4efca14cf3b2345d40b3dd5e9aca"
|
||||
"reference": "a93dffaf763182acad12a4c42c7efc372899891e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/dd2cfb20fabd4efca14cf3b2345d40b3dd5e9aca",
|
||||
"reference": "dd2cfb20fabd4efca14cf3b2345d40b3dd5e9aca",
|
||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/a93dffaf763182acad12a4c42c7efc372899891e",
|
||||
"reference": "a93dffaf763182acad12a4c42c7efc372899891e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -8652,20 +8701,20 @@
|
||||
],
|
||||
"description": "Symfony BrowserKit Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-12-26 13:37:56"
|
||||
"time": "2016-01-12 17:46:01"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dom-crawler",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dom-crawler.git",
|
||||
"reference": "a2712aff8b250d9601ad6bd23a2ff82a12730e8e"
|
||||
"reference": "650d37aacb1fa0dcc24cced483169852b3a0594e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/a2712aff8b250d9601ad6bd23a2ff82a12730e8e",
|
||||
"reference": "a2712aff8b250d9601ad6bd23a2ff82a12730e8e",
|
||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/650d37aacb1fa0dcc24cced483169852b3a0594e",
|
||||
"reference": "650d37aacb1fa0dcc24cced483169852b3a0594e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -8708,7 +8757,7 @@
|
||||
],
|
||||
"description": "Symfony DomCrawler Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-12-23 17:16:29"
|
||||
"time": "2016-01-03 15:33:41"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
@ -8771,16 +8820,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.8.1",
|
||||
"version": "v2.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966"
|
||||
"reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
|
||||
"reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/34c8a4b51e751e7ea869b8262f883d008a2b81b8",
|
||||
"reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -8816,7 +8865,7 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-12-26 13:37:56"
|
||||
"time": "2016-01-13 10:28:07"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
@ -161,6 +161,8 @@ return [
|
||||
'App\Providers\ConfigServiceProvider',
|
||||
'App\Providers\EventServiceProvider',
|
||||
'App\Providers\RouteServiceProvider',
|
||||
|
||||
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
|
||||
],
|
||||
|
||||
/*
|
||||
|
@ -89,7 +89,7 @@ return array(
|
||||
'files' => false, // Show the included files
|
||||
'config' => false, // Display config settings
|
||||
'auth' => false, // Display Laravel authentication status
|
||||
'session' => false, // Display session data in a separate tab
|
||||
'session' => true, // Display session data in a separate tab
|
||||
),
|
||||
|
||||
/*
|
||||
|
1
database/.gitignore
vendored
1
database/.gitignore
vendored
@ -1 +1,2 @@
|
||||
*.sqlite
|
||||
*-komodoproject
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
// vendor
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateVendorsTable extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('vendors');
|
||||
Schema::create('vendors', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->integer('user_id', false, true);
|
||||
$table->integer('account_id', false, true);
|
||||
$table->integer('currency_id',false, true)->nullable();
|
||||
$table->string('name')->nullable();
|
||||
$table->string('address1');
|
||||
$table->string('address2');
|
||||
$table->string('city');
|
||||
$table->string('state');
|
||||
$table->string('postal_code');
|
||||
$table->unsignedInteger('country_id')->nullable();
|
||||
$table->string('work_phone');
|
||||
$table->text('private_notes');
|
||||
$table->decimal('balance',13,2);
|
||||
$table->string('website');
|
||||
$table->integer('industry_id')->nullable();
|
||||
$table->integer('size_id')->nullable();
|
||||
$table->tinyInteger('is_deleted')->default(0);
|
||||
$table->integer('payment_terms')->nullable();
|
||||
$table->integer('public_id')->default(0);
|
||||
$table->string('custom_value1')->nullable();
|
||||
$table->string('custom_value2')->nullable();
|
||||
$table->string('vat_number')->nullable();
|
||||
$table->string('id_number')->nullable();
|
||||
$table->integer('language_id', false, true)->nullable();
|
||||
});
|
||||
|
||||
// add relations
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('vendors');
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// vendor
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateVendorcontactsTable extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('vendor_contacts');
|
||||
Schema::create('vendor_contacts', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('account_id');
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('vendor_id')->index();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->boolean('is_primary')->default(0);
|
||||
//$table->boolean('send_invoice')->default(0);
|
||||
$table->string('first_name')->nullable();
|
||||
$table->string('last_name')->nullable();
|
||||
$table->string('email')->nullable();
|
||||
$table->string('phone')->nullable();
|
||||
$table->timestamp('last_login')->nullable();
|
||||
|
||||
$table->foreign('vendor_id')->references('id')->on('vendors')->onDelete('cascade');
|
||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
|
||||
|
||||
$table->unsignedInteger('public_id')->nullable();
|
||||
$table->unique( array('account_id','public_id') );
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('vendor_contacts');
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
// vendor
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateTableVendorInvitations extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('vendor_invitations');
|
||||
Schema::create('vendor_invitations', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('account_id');
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('contact_id');
|
||||
//$table->unsignedInteger('invoice_id')->index();
|
||||
$table->string('invitation_key')->index()->unique();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->string('transaction_reference')->nullable();
|
||||
$table->timestamp('sent_date')->nullable();
|
||||
$table->timestamp('viewed_date')->nullable();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
|
||||
$table->foreign('contact_id')->references('id')->on('vendor_contacts')->onDelete('cascade');
|
||||
//$table->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
|
||||
|
||||
$table->unsignedInteger('public_id')->index();
|
||||
$table->unique( array('account_id','public_id') );
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('vendor_invitations', function(Blueprint $table)
|
||||
{
|
||||
//
|
||||
});
|
||||
|
||||
Schema::dropIfExists('vendor_invitations');
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
// vendor
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateTableVendorActivities extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('vendor_activities');
|
||||
Schema::create('vendor_activities', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unsignedInteger('account_id');
|
||||
$table->unsignedInteger('vendor_id');
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('contact_id')->nullable();
|
||||
$table->unsignedInteger('payment_id')->nullable();
|
||||
//$table->unsignedInteger('invoice_id')->nullable();
|
||||
$table->unsignedInteger('credit_id')->nullable();
|
||||
$table->unsignedInteger('invitation_id')->nullable();
|
||||
|
||||
$table->text('message')->nullable();
|
||||
$table->text('json_backup')->nullable();
|
||||
$table->integer('activity_type_id');
|
||||
$table->decimal('adjustment', 13, 2)->nullable();
|
||||
$table->decimal('balance', 13, 2)->nullable();
|
||||
$table->unsignedInteger('token_id')->nullable();
|
||||
$table->string('ip')->nullable();
|
||||
$table->boolean('is_system')->default(0);
|
||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||
$table->foreign('vendor_id')->references('id')->on('vendors')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('vendor_activities', function(Blueprint $table)
|
||||
{
|
||||
//
|
||||
});
|
||||
|
||||
Schema::dropIfExists('vendor_activities');
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateExpensesTable extends Migration
|
||||
{
|
||||
// Expenses model
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('expenses');
|
||||
Schema::create('expenses', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->unsignedInteger('account_id')->index();
|
||||
$table->unsignedInteger('vendor_id')->nullable();
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('invoice_id')->nullable();
|
||||
$table->unsignedInteger('invoice_client_id')->nullable();
|
||||
$table->boolean('is_deleted')->default(false);
|
||||
$table->decimal('amount', 13, 2);
|
||||
$table->decimal('amount_cur', 13, 2);
|
||||
$table->decimal('exchange_rate', 13, 2);
|
||||
$table->date('expense_date')->nullable();
|
||||
$table->text('private_notes');
|
||||
$table->text('public_notes');
|
||||
$table->integer('currency_id',false, true)->nullable();
|
||||
$table->boolean('is_invoiced')->default(false);
|
||||
$table->boolean('should_be_invoiced')->default(true);
|
||||
|
||||
// Relations
|
||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||
|
||||
// Indexes
|
||||
$table->unsignedInteger('public_id')->index();
|
||||
$table->unique( array('account_id','public_id') );
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('expenses');
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateExpenseActivitiesTable extends Migration {
|
||||
|
||||
// Expenses model
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('expense_activities');
|
||||
Schema::create('expense_activities', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unsignedInteger('account_id');
|
||||
$table->unsignedInteger('vendor_id');
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('contact_id')->nullable();
|
||||
$table->unsignedInteger('expense_id');
|
||||
$table->unsignedInteger('invitation_id')->nullable();
|
||||
$table->text('message')->nullable();
|
||||
$table->text('json_backup')->nullable();
|
||||
$table->integer('activity_type_id');
|
||||
$table->decimal('adjustment', 13, 2)->nullable();
|
||||
$table->decimal('balance', 13, 2)->nullable();
|
||||
$table->unsignedInteger('token_id')->nullable();
|
||||
$table->string('ip')->nullable();
|
||||
$table->boolean('is_system')->default(0);
|
||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||
$table->foreign('vendor_id')->references('id')->on('vendors')->onDelete('cascade');
|
||||
$table->foreign('expense_id')->references('id')->on('expenses')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('expense_activities');
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddFieldsToPaymentterms extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('payment_terms', function(Blueprint $table)
|
||||
{
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->integer('user_id', false, true);
|
||||
$table->integer('account_id', false, true);
|
||||
$table->integer('public_id')->default(0);
|
||||
});
|
||||
|
||||
// Update public id
|
||||
$paymentTerms = DB::table('payment_terms')
|
||||
->where('public_id', '=',0)
|
||||
->select('id', 'public_id')
|
||||
->get();
|
||||
$i = 1;
|
||||
foreach ($paymentTerms as $pTerm) {
|
||||
$data = ['public_id' => $i];
|
||||
|
||||
DB::table('paymet_terms')->where('id', $pTerm->id)->update($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('payment_terms', function(Blueprint $table)
|
||||
{
|
||||
//
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddInvoicesHasExpenses extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('invoices', function(Blueprint $table)
|
||||
{
|
||||
$table->boolean('has_expenses')->default(false);
|
||||
});
|
||||
|
||||
$invoices = DB::table('invoices')
|
||||
->join('expenses', 'expenses.invoice_id', '=', 'invoices.id')
|
||||
->selectRaw('DISTINCT invoices.id')
|
||||
->get();
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
DB::table('invoices')
|
||||
->where('id', $invoice->id)
|
||||
->update(['has_tasks' => true]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('invoices', function(Blueprint $table)
|
||||
{
|
||||
$table->dropColumn('has_expenses');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
43
invoiceninja.komodoproject
Normal file
43
invoiceninja.komodoproject
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Komodo Project File - DO NOT EDIT -->
|
||||
<project id="63a1b237-cbd6-48f9-bac1-8e5d85debff7" kpf_version="5" name="invoiceninja.komodoproject">
|
||||
<preference-set idref="63a1b237-cbd6-48f9-bac1-8e5d85debff7" id="project" preftype="project">
|
||||
<preference-set id="Invocations">
|
||||
<preference-set id="Project">
|
||||
<string id="cookieparams"></string>
|
||||
<string relative="path" id="cwd"></string>
|
||||
<string id="documentRoot"></string>
|
||||
<string id="executable-params"></string>
|
||||
<string id="filename"></string>
|
||||
<string id="getparams"></string>
|
||||
<string id="language">PHP</string>
|
||||
<string id="mpostparams"></string>
|
||||
<string id="params"></string>
|
||||
<string id="postparams"></string>
|
||||
<string id="posttype">application/x-www-form-urlencoded</string>
|
||||
<string id="request-method">GET</string>
|
||||
<boolean id="show-dialog">1</boolean>
|
||||
<boolean id="sim-cgi">0</boolean>
|
||||
<boolean id="use-console">0</boolean>
|
||||
<string id="userCGIEnvironment"></string>
|
||||
<string id="userEnvironment"></string>
|
||||
</preference-set>
|
||||
</preference-set>
|
||||
<string id="currentInvocationLanguage">PHP</string>
|
||||
<string id="defaultDateFormat">%25d/%25m/%25Y %25H:%25M:%25S</string>
|
||||
<boolean id="genericLinter:PHP">1</boolean>
|
||||
<string relative="path" id="import_dirname"></string>
|
||||
<string id="jshint_linter_chooser">default</string>
|
||||
<string id="jslint_linter_chooser">default</string>
|
||||
<string id="language">PHP</string>
|
||||
<string id="lastInvocation">Project</string>
|
||||
<string id="last_local_directory">None</string>
|
||||
<string id="last_remote_directory">None</string>
|
||||
<string id="lessDefaultInterpreter">None</string>
|
||||
<string id="phpDefaultInterpreter">c:\wamp\bin\php\php5.6.15\php.exe</string>
|
||||
<string relative="path" id="phpExtraPaths">vendor;C:/webdev/invoiceninja/app</string>
|
||||
<long id="prefs_version">1</long>
|
||||
<string id="sassDefaultInterpreter">None</string>
|
||||
<string id="scssDefaultInterpreter">None</string>
|
||||
</preference-set>
|
||||
</project>
|
@ -30298,6 +30298,17 @@ function getClientDisplayName(client)
|
||||
return '';
|
||||
}
|
||||
|
||||
function getVendorDisplayName(vendor)
|
||||
{
|
||||
var contact = vendor.contacts ? vendor.vendorcontacts[0] : false;
|
||||
if (vendor.name) {
|
||||
return vendor.name;
|
||||
} else if (contact) {
|
||||
return getContactDisplayName(contact);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function populateInvoiceComboboxes(clientId, invoiceId) {
|
||||
var clientMap = {};
|
||||
var invoiceMap = {};
|
||||
|
@ -256,6 +256,14 @@ return array(
|
||||
'deleted_credits' => 'Successfully deleted :count credits',
|
||||
'imported_file' => 'Successfully imported file',
|
||||
|
||||
'updated_vendor' => 'Successfully updated vendor',
|
||||
'created_vendor' => 'Successfully created vendor',
|
||||
'archived_vendor' => 'Successfully archived vendor',
|
||||
'archived_vendors' => 'Successfully archived :count vendors',
|
||||
'deleted_vendor' => 'Successfully deleted vendor',
|
||||
'deleted_vendors' => 'Successfully deleted :count vendors',
|
||||
|
||||
|
||||
// Emails
|
||||
'confirmation_subject' => 'Invoice Ninja Account Confirmation',
|
||||
'confirmation_header' => 'Account Confirmation',
|
||||
@ -884,6 +892,14 @@ return array(
|
||||
'activity_27' => ':user restored payment :payment',
|
||||
'activity_28' => ':user restored :credit credit',
|
||||
'activity_29' => ':contact approved quote :quote',
|
||||
'activity_30' => ':user created :vendor',
|
||||
'activity_31' => ':user created :vendor',
|
||||
'activity_32' => ':user created :vendor',
|
||||
'activity_33' => ':user created :vendor',
|
||||
'activity_34' => ':user created expense :expense',
|
||||
'activity_35' => ':user created :vendor',
|
||||
'activity_36' => ':user created :vendor',
|
||||
'activity_37' => ':user created :vendor',
|
||||
|
||||
'payment' => 'Payment',
|
||||
'system' => 'System',
|
||||
@ -997,6 +1013,54 @@ return array(
|
||||
'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.',
|
||||
'white_label_purchase_link' => 'Purchase a white label license',
|
||||
|
||||
// Expense / vendor
|
||||
'expense' => 'Expense',
|
||||
'expenses' => 'Expenses',
|
||||
'new_expense' => 'Create expense',
|
||||
'vendors' => 'Vendors',
|
||||
'new_vendor' => 'Create vendor',
|
||||
'payment_terms_net' => 'Net',
|
||||
'vendor' => 'Vendor',
|
||||
'edit_vendor' => 'Edit vendor',
|
||||
'archive_vendor' => 'Archive vendor',
|
||||
'delete_vendor' => 'Delete vendor',
|
||||
'view_vendor' => 'View vendor',
|
||||
|
||||
// Expenses
|
||||
'expense_amount' => 'Expense amount',
|
||||
'expense_balance' => 'Expense balance',
|
||||
'expense_date' => 'Expense date',
|
||||
'expense_exchange_rate_100' => 'The amount for 100 in company currency',
|
||||
'expense_should_be_invoiced' => 'Should this expense be invoiced?',
|
||||
'public_notes' => 'Public notes',
|
||||
'expense_amount_in_cur' => 'Expense amount in curency',
|
||||
'is_invoiced' => 'Is invoiced',
|
||||
'expense_is_not_invoiced' => 'Expense not invoiced',
|
||||
'expense_is_invoiced' => 'Expense invoiced',
|
||||
'yes' => 'Yes',
|
||||
'no' => 'No',
|
||||
'should_be_invoiced' => 'Should be invoiced',
|
||||
'view_expense' => 'View expense # :expense',
|
||||
'edit_expense' => 'Edit expense',
|
||||
'archive_expense' => 'Archive expense',
|
||||
'delete_expense' => 'Delete expense',
|
||||
'view_expense_num' => 'Expense # :expense',
|
||||
'updated_expense' => 'Expense updated',
|
||||
'enter_expense' => 'Enter expense',
|
||||
'view' => 'View',
|
||||
'restore_expense' => 'Restore expense',
|
||||
'invoice_expense' => 'Invoice',
|
||||
'expense_error_multiple_clients' =>'The expenses can\'t belong to different clients',
|
||||
'expense_error_invoiced' => 'Expense have already been invoiced',
|
||||
'expense_error_should_not_be_invoiced' => 'Expense maked not to be invoiced',
|
||||
|
||||
// Payment terms
|
||||
'num_days' => 'Number of days',
|
||||
'create_payment_term' => 'Create payment term',
|
||||
'edit_payment_terms' => 'Edit payment term',
|
||||
'edit_payment_term' => 'Edit payment term',
|
||||
'archive_payment_term' => 'Archive payment term',
|
||||
|
||||
// recurring due dates
|
||||
'recurring_due_dates' => 'Recurring Invoice Due Dates',
|
||||
'recurring_due_date_help' => '<p>Automatically sets a due date for the invoice.</p>
|
||||
|
47
resources/views/accounts/payment_term.blade.php
Normal file
47
resources/views/accounts/payment_term.blade.php
Normal file
@ -0,0 +1,47 @@
|
||||
@extends('header')
|
||||
|
||||
@section('content')
|
||||
@parent
|
||||
|
||||
@include('accounts.nav', ['selected' => ACCOUNT_PAYMENT_TERMS])
|
||||
|
||||
{!! Former::open($url)->method($method)
|
||||
->rules([
|
||||
'name' => 'required',
|
||||
'num_days' => 'required'
|
||||
])
|
||||
->addClass('warn-on-exit') !!}
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! $title !!}</h3>
|
||||
</div>
|
||||
<div class="panel-body form-padding-right">
|
||||
|
||||
@if ($paymentTerm)
|
||||
{{ Former::populate($paymentTerm) }}
|
||||
@endif
|
||||
|
||||
{!! Former::text('name')->label('texts.name') !!}
|
||||
{!! Former::text('num_days')->label('texts.num_days') !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!! Former::actions(
|
||||
Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/settings/payment_terms'))->appendIcon(Icon::create('remove-circle')),
|
||||
Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))
|
||||
) !!}
|
||||
|
||||
{!! Former::close() !!}
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(function() {
|
||||
$('#name').focus();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
@stop
|
33
resources/views/accounts/payment_terms.blade.php
Normal file
33
resources/views/accounts/payment_terms.blade.php
Normal file
@ -0,0 +1,33 @@
|
||||
@extends('header')
|
||||
|
||||
@section('content')
|
||||
@parent
|
||||
|
||||
@include('accounts.nav', ['selected' => ACCOUNT_PAYMENT_TERMS])
|
||||
|
||||
{!! Button::primary(trans('texts.create_payment_term'))
|
||||
->asLinkTo(URL::to('/payment_terms/create'))
|
||||
->withAttributes(['class' => 'pull-right'])
|
||||
->appendIcon(Icon::create('plus-sign')) !!}
|
||||
|
||||
@include('partials.bulk_form', ['entityType' => ENTITY_PAYMENT_TERM])
|
||||
|
||||
{!! Datatable::table()
|
||||
->addColumn(
|
||||
trans('texts.name'),
|
||||
trans('texts.num_days'),
|
||||
trans('texts.action'))
|
||||
->setUrl(url('api/payment_terms/'))
|
||||
->setOptions('sPaginationType', 'bootstrap')
|
||||
->setOptions('bFilter', false)
|
||||
->setOptions('bAutoWidth', false)
|
||||
->setOptions('aoColumns', [[ "sWidth"=> "40%" ], [ "sWidth"=> "40%" ], ["sWidth"=> "20%"]])
|
||||
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[2]]])
|
||||
->render('datatable') !!}
|
||||
|
||||
<script>
|
||||
window.onDatatableReady = actionListHandler;
|
||||
</script>
|
||||
|
||||
|
||||
@stop
|
@ -84,6 +84,18 @@
|
||||
{!! $activity->getMessage() !!}
|
||||
</li>
|
||||
@endforeach
|
||||
@foreach ($vendoractivities as $activity)
|
||||
<li class="list-group-item">
|
||||
<span style="color:#888;font-style:italic">{{ Utils::timestampToDateString(strtotime($activity->created_at)) }}:</span>
|
||||
{!! $activity->getMessage() !!}
|
||||
</li>
|
||||
@endforeach
|
||||
@foreach ($expenseactivities as $activity)
|
||||
<li class="list-group-item">
|
||||
<span style="color:#888;font-style:italic">{{ Utils::timestampToDateString(strtotime($activity->created_at)) }}:</span>
|
||||
{!! $activity->getMessage() !!}
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
97
resources/views/expenses/edit.blade.php
Normal file
97
resources/views/expenses/edit.blade.php
Normal file
@ -0,0 +1,97 @@
|
||||
@extends('header')
|
||||
|
||||
@section('content')
|
||||
|
||||
{!! Former::open($url)->addClass('col-md-10 col-md-offset-1 warn-on-exit')->method($method)->rules(array(
|
||||
'public_notes' => 'required',
|
||||
'amount' => 'required',
|
||||
'expense_date' => 'required',
|
||||
)) !!}
|
||||
|
||||
@if ($expense)
|
||||
{!! Former::populate($expense) !!}
|
||||
{!! Former::hidden('public_id') !!}
|
||||
@endif
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
{!! Former::select('vendor')->addOption('', '')->addGroupClass('client-select') !!}
|
||||
{!! Former::text('expense_date')
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))
|
||||
->addGroupClass('expense_date')->label(trans('texts.expense_date'))
|
||||
->append('<i class="glyphicon glyphicon-calendar"></i>') !!}
|
||||
{!! Former::text('amount')->label(trans('texts.expense_amount')) !!}
|
||||
{!! Former::text('amount_cur')->label(trans('texts.expense_amount_in_cur')) !!}
|
||||
{!! Former::select('currency_id')->addOption('','')
|
||||
->placeholder($account->currency ? $account->currency->name : '')
|
||||
->fromQuery($currencies, 'name', 'id') !!}
|
||||
{!! Former::text('exchange_rate')->append(trans('texts.expense_exchange_rate_100')) !!}
|
||||
{!! Former::textarea('private_notes') !!}
|
||||
{!! Former::textarea('public_notes') !!}
|
||||
{!! Former::checkbox('should_be_invoiced') !!}
|
||||
{!! Former::select('client')->addOption('', '')->addGroupClass('client-select') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<center class="buttons">
|
||||
{!! Button::normal(trans('texts.cancel'))->large()->asLinkTo(URL::to('/dashboard'))->appendIcon(Icon::create('remove-circle')) !!}
|
||||
{!! Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk')) !!}
|
||||
</center>
|
||||
|
||||
{!! Former::close() !!}
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
var vendors = {!! $vendors !!};
|
||||
var clients = {!! $clients !!};
|
||||
|
||||
$(function() {
|
||||
|
||||
var $vendorSelect = $('select#vendor');
|
||||
for (var i = 0; i < vendors.length; i++) {
|
||||
var vendor = vendors[i];
|
||||
$vendorSelect.append(new Option(getVendorDisplayName(vendor), vendor.public_id));
|
||||
}
|
||||
|
||||
if ({{ $vendorPublicId ? 'true' : 'false' }}) {
|
||||
$vendorSelect.val({{ $vendorPublicId }});
|
||||
}
|
||||
|
||||
$vendorSelect.combobox();
|
||||
|
||||
$('#currency_id').combobox();
|
||||
$('#expense_date').datepicker('update', new Date());
|
||||
|
||||
@if (!$vendorPublicId)
|
||||
$('.vendor-select input.form-control').focus();
|
||||
@else
|
||||
$('#amount').focus();
|
||||
@endif
|
||||
|
||||
$('.expense_date .input-group-addon').click(function() {
|
||||
toggleDatePicker('expense_date');
|
||||
});
|
||||
|
||||
|
||||
var $clientSelect = $('select#client');
|
||||
for (var i=0; i<clients.length; i++) {
|
||||
var client = clients[i];
|
||||
$clientSelect.append(new Option(getClientDisplayName(client), client.public_id));
|
||||
}
|
||||
|
||||
if ({{ $clientPublicId ? 'true' : 'false' }}) {
|
||||
$clientSelect.val({{ $clientPublicId }});
|
||||
}
|
||||
|
||||
$clientSelect.combobox();
|
||||
});
|
||||
|
||||
</script>
|
||||
@stop
|
122
resources/views/expenses/show.blade.php
Normal file
122
resources/views/expenses/show.blade.php
Normal file
@ -0,0 +1,122 @@
|
||||
@extends('header')
|
||||
|
||||
@section('head')
|
||||
@parent
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
<div class="pull-right">
|
||||
{!! Former::open('expenses/bulk')->addClass('mainForm') !!}
|
||||
<div style="display:none">
|
||||
{!! Former::text('action') !!}
|
||||
{!! Former::text('public_id')->value($expense->public_id) !!}
|
||||
</div>
|
||||
|
||||
@if ($expense->trashed())
|
||||
{!! Button::primary(trans('texts.restore_expense'))->withAttributes(['onclick' => 'onRestoreClick()']) !!}
|
||||
@else
|
||||
{!! DropdownButton::normal(trans('texts.edit_expense'))
|
||||
->withAttributes(['class'=>'normalDropDown'])
|
||||
->withContents([
|
||||
['label' => trans('texts.archive_expense'), 'url' => "javascript:onArchiveClick()"],
|
||||
['label' => trans('texts.delete_expense'), 'url' => "javascript:onDeleteClick()"],
|
||||
]
|
||||
)->split() !!}
|
||||
|
||||
{!! DropdownButton::primary(trans('texts.new_expense'))
|
||||
->withAttributes(['class'=>'primaryDropDown'])
|
||||
->withContents($actionLinks)->split() !!}
|
||||
@endif
|
||||
{!! Former::close() !!}
|
||||
|
||||
</div>
|
||||
|
||||
<h2>{{ trans('texts.view_expense_num', ['expense' => $expense->public_id]) }}</h2>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-3">
|
||||
<h3>{{ trans('texts.details') }}</h3>
|
||||
|
||||
<p>{{ $expense->public_notes }}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<h3>{{ trans('texts.standing') }}
|
||||
<table class="table" style="width:100%">
|
||||
<tr>
|
||||
<td><small>{{ trans('texts.expense_date') }}</small></td>
|
||||
<td style="text-align: right">{{ Utils::fromSqlDate($expense->expense_date) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><small>{{ trans('texts.expense_amount') }}</small></td>
|
||||
<td style="text-align: right">{{ Utils::formatMoney($expense->amount) }}</td>
|
||||
</tr>
|
||||
@if ($credit > 0)
|
||||
<tr>
|
||||
<td><small>{{ trans('texts.expense_amount_cur') }}</small></td>
|
||||
<td style="text-align: right">{{ Utils::formatMoney($$expense->amount_cur, $expense->curency_id) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs nav-justified">
|
||||
{!! HTML::tab_link('#activity', trans('texts.activity'), true) !!}
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="activity">
|
||||
{!! Datatable::table()
|
||||
->addColumn(
|
||||
trans('texts.expense_date'),
|
||||
trans('texts.message'),
|
||||
trans('texts.amount'),
|
||||
trans('texts.public_notes'))
|
||||
->setUrl(url('api/expenseactivities/'. $expense->public_id))
|
||||
->setOptions('sPaginationType', 'bootstrap')
|
||||
->setOptions('bFilter', false)
|
||||
->setOptions('aaSorting', [['0', 'desc']])
|
||||
->render('datatable') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var loadedTabs = {};
|
||||
|
||||
$(function() {
|
||||
$('.normalDropDown:not(.dropdown-toggle)').click(function() {
|
||||
window.location = '{{ URL::to('expenses/' . $expense->public_id . '/edit') }}';
|
||||
});
|
||||
$('.primaryDropDown:not(.dropdown-toggle)').click(function() {
|
||||
window.location = '{{ URL::to('expenses/create/' . $expense->public_id ) }}';
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function onArchiveClick() {
|
||||
$('#action').val('archive');
|
||||
$('.mainForm').submit();
|
||||
}
|
||||
|
||||
function onRestoreClick() {
|
||||
$('#action').val('restore');
|
||||
$('.mainForm').submit();
|
||||
}
|
||||
|
||||
function onDeleteClick() {
|
||||
if (confirm("{!! trans('texts.are_you_sure') !!}")) {
|
||||
$('#action').val('delete');
|
||||
$('.mainForm').submit();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@stop
|
@ -375,6 +375,7 @@
|
||||
{!! HTML::menu_link('task') !!}
|
||||
{!! HTML::menu_link('invoice') !!}
|
||||
{!! HTML::menu_link('payment') !!}
|
||||
{!! HTML::menu_link('expense') !!}
|
||||
</ul>
|
||||
|
||||
<div class="navbar-form navbar-right">
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user