mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 21:14:35 -04:00
Vendor management
This commit is contained in:
parent
d3ee8ed813
commit
dba3a39559
21
app/Events/VendorWasArchived.php
Normal file
21
app/Events/VendorWasArchived.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasArchived extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
21
app/Events/VendorWasCreated.php
Normal file
21
app/Events/VendorWasCreated.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasCreated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
21
app/Events/VendorWasDeleted.php
Normal file
21
app/Events/VendorWasDeleted.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasDeleted extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $vendor;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($vendor)
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
}
|
||||
}
|
21
app/Events/VendorWasRestored.php
Normal file
21
app/Events/VendorWasRestored.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class VendorWasRestored extends Event
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
211
app/Http/Controllers/VendorController.php
Normal file
211
app/Http/Controllers/VendorController.php
Normal file
@ -0,0 +1,211 @@
|
||||
<?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;
|
||||
|
||||
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',
|
||||
//'last_login',
|
||||
'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_expense'), 'url' => '/expenses/create/'.$vendor->public_id]
|
||||
];
|
||||
|
||||
$data = array(
|
||||
'actionLinks' => $actionLinks,
|
||||
'showBreadcrumbs' => false,
|
||||
'vendor' => $vendor,
|
||||
'credit' => $vendor->getTotalCredit(),
|
||||
'title' => trans('texts.view_vendor'),
|
||||
'hasRecurringInvoices' => false,
|
||||
'hasQuotes' => false,
|
||||
'hasTasks' => false,
|
||||
'gatewayLink' => $vendor->getGatewayLink(),
|
||||
);
|
||||
|
||||
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'),
|
||||
'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');
|
||||
}
|
||||
}
|
||||
}
|
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;
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
||||
}
|
@ -181,6 +181,14 @@ 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');
|
||||
|
||||
});
|
||||
|
||||
// Route groups for API
|
||||
@ -202,6 +210,8 @@ 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');
|
||||
});
|
||||
|
||||
// Redirects for legacy links
|
||||
@ -258,10 +268,13 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('ENTITY_TAX_RATE', 'tax_rate');
|
||||
define('ENTITY_PRODUCT', 'product');
|
||||
define('ENTITY_ACTIVITY', 'activity');
|
||||
|
||||
define('ENTITY_VENDOR','vendor');
|
||||
define('ENTITY_EXPENSE', 'expense');
|
||||
|
||||
define('PERSON_CONTACT', 'contact');
|
||||
define('PERSON_USER', 'user');
|
||||
|
||||
define('PERSON_VENDOR_CONTACT','vendorcontact');
|
||||
|
||||
define('BASIC_SETTINGS', 'basic_settings');
|
||||
define('ADVANCED_SETTINGS', 'advanced_settings');
|
||||
|
||||
@ -327,6 +340,12 @@ 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);
|
||||
|
||||
define('DEFAULT_INVOICE_NUMBER', '0001');
|
||||
define('RECENTLY_VIEWED_LIMIT', 8);
|
||||
define('LOGGED_ERROR_LIMIT', 100);
|
||||
@ -356,6 +375,11 @@ 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);
|
||||
@ -426,6 +450,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');
|
||||
|
@ -574,6 +574,11 @@ class Utils
|
||||
}
|
||||
}
|
||||
|
||||
public static function getVendorDisplayName($model)
|
||||
{
|
||||
return $model->getDisplayName();
|
||||
}
|
||||
|
||||
public static function getPersonDisplayName($firstName, $lastName, $email)
|
||||
{
|
||||
if ($firstName || $lastName) {
|
||||
@ -605,7 +610,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;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ use App\Events\InvoiceWasCreated;
|
||||
use App\Events\CreditWasCreated;
|
||||
use App\Events\PaymentWasCreated;
|
||||
|
||||
use App\Events\VendorWasCreated;
|
||||
|
||||
class SubscriptionListener
|
||||
{
|
||||
public function createdClient(ClientWasCreated $event)
|
||||
@ -44,4 +46,9 @@ class SubscriptionListener
|
||||
Utils::notifyZapier($subscription, $entity);
|
||||
}
|
||||
}
|
||||
|
||||
public function createdVendor(VendorWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_VENDOR, $event->vendor);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
302
app/Models/Vendor.php
Normal file
302
app/Models/Vendor.php
Normal file
@ -0,0 +1,302 @@
|
||||
<?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->send_invoice = true;
|
||||
}
|
||||
|
||||
$contact->fill($data);
|
||||
$contact->is_primary = $isPrimary;
|
||||
|
||||
return $this->vendorContacts()->save($contact);
|
||||
}
|
||||
|
||||
public function updateBalances($balanceAdjustment, $paidToDateAdjustment)
|
||||
{
|
||||
if ($balanceAdjustment === 0 && $paidToDateAdjustment === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->balance = $this->balance + $balanceAdjustment;
|
||||
$this->paid_to_date = $this->paid_to_date + $paidToDateAdjustment;
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function getRoute()
|
||||
{
|
||||
return "/vendors/{$this->public_id}";
|
||||
}
|
||||
|
||||
|
||||
public function getTotalCredit()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
if ($this->name) {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
if ( ! count($this->contacts)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$contact = $this->contacts[0];
|
||||
return $contact->getDisplayName();
|
||||
}
|
||||
|
||||
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 getGatewayToken()
|
||||
{
|
||||
$this->account->load('account_gateways');
|
||||
|
||||
if (!count($this->account->account_gateways)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$accountGateway = $this->account->getGatewayConfig(GATEWAY_STRIPE);
|
||||
|
||||
if (!$accountGateway) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$token = AccountGatewayToken::where('vendor_id', '=', $this->id)->where('account_gateway_id', '=', $accountGateway->id)->first();
|
||||
|
||||
return $token ? $token->token : false;
|
||||
}
|
||||
|
||||
public function getGatewayLink()
|
||||
{
|
||||
$token = $this->getGatewayToken();
|
||||
return $token ? "https://dashboard.stripe.com/customers/{$token}" : false;
|
||||
}
|
||||
|
||||
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 getCounter($isQuote)
|
||||
{
|
||||
return $isQuote ? $this->quote_number_counter : $this->invoice_number_counter;
|
||||
}
|
||||
*/
|
||||
|
||||
public function markLoggedIn()
|
||||
{
|
||||
//$this->last_login = Carbon::now()->toDateTimeString();
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
});
|
||||
|
56
app/Models/VendorActivity.php
Normal file
56
app/Models/VendorActivity.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
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;
|
||||
|
||||
$data = [
|
||||
'vendor' => link_to($vendor->getRoute(), $vendor->getDisplayName()),
|
||||
'user' => $isSystem ? '<i>' . trans('texts.system') . '</i>' : $user->getDisplayName(),
|
||||
'vendorcontact' => $contactId ? $vendor->getDisplayName() : $user->getDisplayName(),
|
||||
];
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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),
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
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;
|
||||
|
||||
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', '=', 'activities.account_id')
|
||||
->join('users', 'users.id', '=', 'activities.user_id')
|
||||
->join('vendors', 'vendors.id', '=', '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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
102
app/Ninja/Repositories/VendorRepository.php
Normal file
102
app/Ninja/Repositories/VendorRepository.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use DB;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorContact;
|
||||
use App\Models\Activity;
|
||||
|
||||
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.last_login',
|
||||
'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['vendor_contact']) && ! isset($data['vendor_contacts'])) {
|
||||
return $vendor;
|
||||
}
|
||||
|
||||
|
||||
$first = true;
|
||||
$vendorcontacts = isset($data['vendor_contact']) ? [$data['vendor_contact']] : $data['vendor_contacts'];
|
||||
$vendorcontactIds = [];
|
||||
|
||||
foreach ($vendorcontacts as $vendorcontact) {
|
||||
$vendorcontact = $vendor->addVendorContact($vendorcontact, $first);
|
||||
$vendorcontactIds[] = $vendorcontact->public_id;
|
||||
$first = false;
|
||||
}
|
||||
|
||||
foreach ($vendor->vendorcontacts as $vendorcontact) {
|
||||
if (!in_array($vendorcontact->public_id, $vendorcontactIds)) {
|
||||
$vendorcontact->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $vendor;
|
||||
}
|
||||
}
|
@ -53,11 +53,8 @@ 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 == 'expense'){
|
||||
} else if ($type == ENTITY_EXPENSE) {
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="'.URL::to('expenses').'">'.trans("texts.expenses").'</a></li>
|
||||
<li><a href="'.URL::to('expensesn/create').'">'.trans("texts.new_expense").'</a></li>
|
||||
<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>';
|
||||
}
|
||||
|
@ -137,6 +137,21 @@ 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',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
|
67
app/Services/VendorActivityService.php
Normal file
67
app/Services/VendorActivityService.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php namespace App\Services;
|
||||
|
||||
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),
|
||||
'invoice' => $model->invoice ? link_to('/invoices/' . $model->invoice_public_id, $model->is_recurring ? trans('texts.recurring_invoice') : $model->invoice) : null,
|
||||
'quote' => $model->invoice ? link_to('/quotes/' . $model->invoice_public_id, $model->invoice) : null,
|
||||
'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),
|
||||
'payment' => $model->payment ?: '',
|
||||
'credit' => Utils::formatMoney($model->credit, $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) : '';
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
103
app/Services/VendorService.php
Normal file
103
app/Services/VendorService.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?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));
|
||||
}
|
||||
],
|
||||
/*[
|
||||
'last_login',
|
||||
function ($model) {
|
||||
return Utils::timestampToDateString(strtotime($model->last_login));
|
||||
}
|
||||
],*/
|
||||
[
|
||||
'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}");
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
46
composer.lock
generated
46
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"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",
|
||||
"hash": "71b1d7519dd65f8e028c1c417354606d",
|
||||
"content-hash": "7305e2f5d6864894aeb23ac91f3e1fe7",
|
||||
"packages": [
|
||||
{
|
||||
@ -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",
|
||||
@ -2254,12 +2254,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Intervention/image.git",
|
||||
"reference": "e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70"
|
||||
"reference": "9f29360b8ab94585cb9e80cf9045abd5b85feb89"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Intervention/image/zipball/e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70",
|
||||
"reference": "e6acb1609ce89f2c1ec7864fbbda0a20a3eeca70",
|
||||
"url": "https://api.github.com/repos/Intervention/image/zipball/9f29360b8ab94585cb9e80cf9045abd5b85feb89",
|
||||
"reference": "9f29360b8ab94585cb9e80cf9045abd5b85feb89",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2308,7 +2308,7 @@
|
||||
"thumbnail",
|
||||
"watermark"
|
||||
],
|
||||
"time": "2015-12-04 17:09:36"
|
||||
"time": "2016-01-02 19:15:13"
|
||||
},
|
||||
{
|
||||
"name": "ircmaxell/password-compat",
|
||||
@ -7593,16 +7593,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 +7632,7 @@
|
||||
"selenium",
|
||||
"webdriver"
|
||||
],
|
||||
"time": "2015-12-08 17:04:30"
|
||||
"time": "2015-12-31 15:58:49"
|
||||
},
|
||||
{
|
||||
"name": "fzaninotto/faker",
|
||||
@ -7722,16 +7722,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 +7796,7 @@
|
||||
"testing",
|
||||
"tests"
|
||||
],
|
||||
"time": "2015-11-29 02:03:49"
|
||||
"time": "2016-01-01 10:17:54"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
|
@ -27,7 +27,7 @@ class CreateVendorsTable extends Migration {
|
||||
$table->string('city');
|
||||
$table->string('state');
|
||||
$table->string('postal_code');
|
||||
$table->integer('country_id',false, true);
|
||||
$table->integer('country_id')->default(0);
|
||||
$table->string('work_phone');
|
||||
$table->text('private_notes');
|
||||
$table->decimal('balance',13,2);
|
||||
@ -36,11 +36,11 @@ class CreateVendorsTable extends Migration {
|
||||
//$table->dateTime('last_login');
|
||||
|
||||
$table->string('website');
|
||||
$table->integer('industry_id',false, true);
|
||||
$table->integer('size_id');
|
||||
$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',false, true);
|
||||
$table->integer('public_id')->default(0);
|
||||
$table->string('custom_value1')->nullable();
|
||||
$table->string('custom_value2')->nullable();
|
||||
$table->string('vat_number')->nullable();
|
||||
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
}
|
@ -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',
|
||||
@ -997,5 +1005,16 @@ 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
|
||||
'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',
|
||||
);
|
||||
|
@ -374,7 +374,7 @@
|
||||
{!! HTML::menu_link('task') !!}
|
||||
{!! HTML::menu_link('invoice') !!}
|
||||
{!! HTML::menu_link('payment') !!}
|
||||
{!! HTML::menu_link('expense') !!}
|
||||
{!! HTML::menu_link('expense') !!}
|
||||
</ul>
|
||||
|
||||
<div class="navbar-form navbar-right">
|
||||
|
Loading…
x
Reference in New Issue
Block a user