mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 20:52:56 +01:00
Added support for Zapier
This commit is contained in:
parent
f5f87319b2
commit
9feb616f1b
@ -20,6 +20,7 @@ Site design by [kantorp-wegl.in](http://kantorp-wegl.in/)
|
||||
* Integrates with many payment providers
|
||||
* Recurring invoices
|
||||
* Tax rates and payment terms
|
||||
* Multi-user support
|
||||
|
||||
### Steps to setup
|
||||
|
||||
|
@ -379,6 +379,7 @@ class AccountController extends \BaseController {
|
||||
$client = Client::createNew();
|
||||
$contact = Contact::createNew();
|
||||
$contact->is_primary = true;
|
||||
$contact->send_invoice = true;
|
||||
$count++;
|
||||
|
||||
foreach ($row as $index => $value)
|
||||
@ -443,7 +444,7 @@ class AccountController extends \BaseController {
|
||||
|
||||
$client->save();
|
||||
$client->contacts()->save($contact);
|
||||
Activity::createClient($client);
|
||||
Activity::createClient($client, false);
|
||||
}
|
||||
|
||||
$message = Utils::pluralize('created_client', $count);
|
||||
@ -470,7 +471,7 @@ class AccountController extends \BaseController {
|
||||
|
||||
if (count($csv->data) + Client::scope()->count() > Auth::user()->getMaxNumClients())
|
||||
{
|
||||
$message = Utils::pluralize('limit_clients', Auth::user()->getMaxNumClients());
|
||||
$message = trans('texts.limit_clients', ['count' => Auth::user()->getMaxNumClients()]);
|
||||
Session::flash('error', $message);
|
||||
return Redirect::to('company/import_export');
|
||||
}
|
||||
|
@ -17,6 +17,6 @@ class BaseController extends Controller {
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
|
||||
$this->beforeFilter('csrf', array('on' => array('post', 'delete', 'put')));
|
||||
}
|
||||
}
|
@ -3,58 +3,46 @@
|
||||
use ninja\repositories\ClientRepository;
|
||||
use Client;
|
||||
|
||||
class ClientApiController extends \BaseController {
|
||||
class ClientApiController extends Controller {
|
||||
|
||||
protected $clientRepo;
|
||||
|
||||
public function __construct(ClientRepository $clientRepo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->clientRepo = $clientRepo;
|
||||
}
|
||||
|
||||
public function ping()
|
||||
{
|
||||
$headers = Utils::getApiHeaders();
|
||||
return Response::make('', 200, $headers);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$clients = Client::scope()->get();
|
||||
|
||||
/*
|
||||
$response = [
|
||||
'status' => 200,
|
||||
'error' => false,
|
||||
'clients' => $clients->toArray()
|
||||
];
|
||||
*/
|
||||
if (!Utils::isPro()) {
|
||||
Redirect::to('/');
|
||||
}
|
||||
|
||||
$response = json_encode($clients->toArray(), JSON_PRETTY_PRINT);
|
||||
$headers = [
|
||||
'Content-Type' => 'application/json',
|
||||
'Access-Control-Allow-Origin' => '*',
|
||||
'Access-Control-Allow-Methods' => 'GET',
|
||||
//'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
|
||||
//'Access-Control-Allow-Credentials' => 'true',
|
||||
//'X-Total-Count' => 0
|
||||
//'X-Rate-Limit-Limit' - The number of allowed requests in the current period
|
||||
//'X-Rate-Limit-Remaining' - The number of remaining requests in the current period
|
||||
//'X-Rate-Limit-Reset' - The number of seconds left in the current period,
|
||||
];
|
||||
$clients = Client::scope()->with('contacts')->orderBy('created_at', 'desc')->get();
|
||||
$clients = Utils::remapPublicIds($clients->toArray());
|
||||
|
||||
/*
|
||||
200 OK - Response to a successful GET, PUT, PATCH or DELETE. Can also be used for a POST that doesn't result in a creation.
|
||||
201 Created - Response to a POST that results in a creation. Should be combined with a Location header pointing to the location of the new resource
|
||||
204 No Content - Response to a successful request that won't be returning a body (like a DELETE request)
|
||||
304 Not Modified - Used when HTTP caching headers are in play
|
||||
400 Bad Request - The request is malformed, such as if the body does not parse
|
||||
401 Unauthorized - When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser
|
||||
403 Forbidden - When authentication succeeded but authenticated user doesn't have access to the resource
|
||||
404 Not Found - When a non-existent resource is requested
|
||||
405 Method Not Allowed - When an HTTP method is being requested that isn't allowed for the authenticated user
|
||||
410 Gone - Indicates that the resource at this end point is no longer available. Useful as a blanket response for old API versions
|
||||
415 Unsupported Media Type - If incorrect content type was provided as part of the request
|
||||
422 Unprocessable Entity - Used for validation errors
|
||||
429 Too Many Requests - When a request is rejected due to rate limiting
|
||||
*/
|
||||
$response = json_encode($clients, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders(count($clients));
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
if (!Utils::isPro()) {
|
||||
Redirect::to('/');
|
||||
}
|
||||
|
||||
$data = Input::all();
|
||||
$client = $this->clientRepo->save(false, $data, false);
|
||||
|
||||
$response = json_encode($client, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders();
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
}
|
29
app/controllers/IntegrationController.php
Normal file
29
app/controllers/IntegrationController.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class IntegrationController extends Controller {
|
||||
|
||||
public function subscribe()
|
||||
{
|
||||
$eventId = Utils::lookupEventId(trim(Input::get('event')));
|
||||
|
||||
if (!$eventId)
|
||||
{
|
||||
return Response::json('', 500);
|
||||
}
|
||||
|
||||
$subscription = Subscription::where('account_id', '=', Auth::user()->account_id)->where('event_id', '=', $eventId)->first();
|
||||
|
||||
if (!$subscription)
|
||||
{
|
||||
$subscription = new Subscription;
|
||||
$subscription->account_id = Auth::user()->account_id;
|
||||
$subscription->event_id = $eventId;
|
||||
}
|
||||
|
||||
$subscription->target_url = trim(Input::get('target_url'));
|
||||
$subscription->save();
|
||||
|
||||
return Response::json('{"id":'.$subscription->id.'}', 201);
|
||||
}
|
||||
|
||||
}
|
40
app/controllers/InvoiceApiController.php
Normal file
40
app/controllers/InvoiceApiController.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use ninja\repositories\InvoiceRepository;
|
||||
use Invoice;
|
||||
|
||||
class InvoiceApiController extends Controller {
|
||||
|
||||
protected $invoiceRepo;
|
||||
|
||||
public function __construct(InvoiceRepository $invoiceRepo)
|
||||
{
|
||||
$this->invoiceRepo = $invoiceRepo;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if (!Utils::isPro()) {
|
||||
Redirect::to('/');
|
||||
}
|
||||
|
||||
$invoices = Invoice::scope()->where('invoices.is_quote', '=', false)->orderBy('created_at', 'desc')->get();
|
||||
$invoices = Utils::remapPublicIds($invoices->toArray());
|
||||
|
||||
$response = json_encode($invoices, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders(count($invoices));
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
|
||||
/*
|
||||
public function store()
|
||||
{
|
||||
$data = Input::all();
|
||||
$invoice = $this->invoiceRepo->save(false, $data, false);
|
||||
|
||||
$response = json_encode($invoice, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders();
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
*/
|
||||
}
|
40
app/controllers/PaymentApiController.php
Normal file
40
app/controllers/PaymentApiController.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use ninja\repositories\PaymentRepository;
|
||||
use Payment;
|
||||
|
||||
class PaymentApiController extends Controller {
|
||||
|
||||
protected $paymentRepo;
|
||||
|
||||
public function __construct(PaymentRepository $paymentRepo)
|
||||
{
|
||||
$this->paymentRepo = $paymentRepo;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if (!Utils::isPro()) {
|
||||
Redirect::to('/');
|
||||
}
|
||||
|
||||
$payments = Payment::scope()->orderBy('created_at', 'desc')->get();
|
||||
$payments = Utils::remapPublicIds($payments->toArray());
|
||||
|
||||
$response = json_encode($payments, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders(count($payments));
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
|
||||
/*
|
||||
public function store()
|
||||
{
|
||||
$data = Input::all();
|
||||
$invoice = $this->invoiceRepo->save(false, $data, false);
|
||||
|
||||
$response = json_encode($invoice, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders();
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
*/
|
||||
}
|
40
app/controllers/QuoteApiController.php
Normal file
40
app/controllers/QuoteApiController.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use ninja\repositories\InvoiceRepository;
|
||||
use Invoice;
|
||||
|
||||
class QuoteApiController extends Controller {
|
||||
|
||||
protected $invoiceRepo;
|
||||
|
||||
public function __construct(InvoiceRepository $invoiceRepo)
|
||||
{
|
||||
$this->invoiceRepo = $invoiceRepo;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
if (!Utils::isPro()) {
|
||||
Redirect::to('/');
|
||||
}
|
||||
|
||||
$invoices = Invoice::scope()->where('invoices.is_quote', '=', true)->orderBy('created_at', 'desc')->get();
|
||||
$invoices = Utils::remapPublicIds($invoices->toArray());
|
||||
|
||||
$response = json_encode($invoices, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders(count($invoices));
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
|
||||
/*
|
||||
public function store()
|
||||
{
|
||||
$data = Input::all();
|
||||
$invoice = $this->invoiceRepo->save(false, $data, false);
|
||||
|
||||
$response = json_encode($invoice, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders();
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
*/
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddZapierSupport extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('subscriptions', function($table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('account_id')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->unsignedInteger('event_id')->nullable();
|
||||
$table->string('target_url');
|
||||
|
||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||
$table->unique( ['account_id', 'event_id'] );
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('subscriptions');
|
||||
}
|
||||
|
||||
}
|
@ -119,11 +119,11 @@ Route::filter('csrf', function()
|
||||
{
|
||||
$token = Request::ajax() ? Request::header('X-CSRF-Token') : Input::get('_token');
|
||||
|
||||
if (Session::token() != $token)
|
||||
{
|
||||
Session::flash('warning', trans('texts.session_expired'));
|
||||
if (Session::token() != $token)
|
||||
{
|
||||
Session::flash('warning', trans('texts.session_expired'));
|
||||
|
||||
return Redirect::to('/');
|
||||
//throw new Illuminate\Session\TokenMismatchException;
|
||||
}
|
||||
return Redirect::to('/');
|
||||
//throw new Illuminate\Session\TokenMismatchException;
|
||||
}
|
||||
});
|
@ -463,4 +463,76 @@ class Utils
|
||||
}
|
||||
return join('-', $parts);
|
||||
}
|
||||
|
||||
public static function lookupEventId($eventName)
|
||||
{
|
||||
if ($eventName == 'create_client') {
|
||||
return EVENT_CREATE_CLIENT;
|
||||
} else if ($eventName == 'create_invoice') {
|
||||
return EVENT_CREATE_INVOICE;
|
||||
} else if ($eventName == 'create_quote') {
|
||||
return EVENT_CREATE_QUOTE;
|
||||
} else if ($eventName == 'create_payment') {
|
||||
return EVENT_CREATE_PAYMENT;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function notifyZapier($subscription, $data) {
|
||||
$curl = curl_init();
|
||||
|
||||
$jsonEncodedData = json_encode($data->toJson());
|
||||
$opts = [
|
||||
CURLOPT_URL => $subscription->target_url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||
CURLOPT_POST => 1,
|
||||
CURLOPT_POSTFIELDS => $jsonEncodedData,
|
||||
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Content-Length: ' . strlen($jsonEncodedData)]
|
||||
];
|
||||
|
||||
curl_setopt_array($curl, $opts);
|
||||
|
||||
$result = curl_exec($curl);
|
||||
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
if ($status == 410)
|
||||
{
|
||||
$subscription->delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static function remapPublicIds($data) {
|
||||
foreach ($data as $index => $record) {
|
||||
if (!isset($data[$index]['public_id'])) {
|
||||
continue;
|
||||
}
|
||||
$data[$index]['id'] = $data[$index]['public_id'];
|
||||
unset($data[$index]['public_id']);
|
||||
|
||||
foreach ($record as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
$data[$index][$key] = Utils::remapPublicIds($val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function getApiHeaders($count = 0) {
|
||||
return [
|
||||
'Content-Type' => 'application/json',
|
||||
//'Access-Control-Allow-Origin' => '*',
|
||||
//'Access-Control-Allow-Methods' => 'GET',
|
||||
//'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
|
||||
//'Access-Control-Allow-Credentials' => 'true',
|
||||
'X-Total-Count' => $count,
|
||||
//'X-Rate-Limit-Limit' - The number of allowed requests in the current period
|
||||
//'X-Rate-Limit-Remaining' - The number of remaining requests in the current period
|
||||
//'X-Rate-Limit-Reset' - The number of seconds left in the current period,
|
||||
];
|
||||
}
|
||||
}
|
@ -248,4 +248,8 @@ class Account extends Eloquent
|
||||
return $interval->y == 0;
|
||||
}
|
||||
|
||||
public function getSubscription($eventId)
|
||||
{
|
||||
return Subscription::where('account_id', '=', $this->id)->where('event_id', '=', $eventId)->first();
|
||||
}
|
||||
}
|
@ -67,13 +67,18 @@ class Activity extends Eloquent
|
||||
return $activity;
|
||||
}
|
||||
|
||||
public static function createClient($client)
|
||||
public static function createClient($client, $notify = true)
|
||||
{
|
||||
$activity = Activity::getBlank();
|
||||
$activity->client_id = $client->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CLIENT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'created', $client);
|
||||
$activity->save();
|
||||
|
||||
if ($notify)
|
||||
{
|
||||
Activity::checkSubscriptions(EVENT_CREATE_CLIENT, $client);
|
||||
}
|
||||
}
|
||||
|
||||
public static function updateClient($client)
|
||||
@ -129,6 +134,8 @@ class Activity extends Eloquent
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $adjustment;
|
||||
$activity->save();
|
||||
|
||||
Activity::checkSubscriptions($invoice->is_quote ? EVENT_CREATE_QUOTE : EVENT_CREATE_INVOICE, $invoice);
|
||||
}
|
||||
|
||||
public static function archiveInvoice($invoice)
|
||||
@ -290,6 +297,8 @@ class Activity extends Eloquent
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $payment->amount * -1;
|
||||
$activity->save();
|
||||
|
||||
Activity::checkSubscriptions(EVENT_CREATE_PAYMENT, $payment);
|
||||
}
|
||||
|
||||
public static function updatePayment($payment)
|
||||
@ -429,4 +438,14 @@ class Activity extends Eloquent
|
||||
$activity->balance = $credit->client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
private static function checkSubscriptions($event, $data)
|
||||
{
|
||||
$subscription = Auth::user()->account->getSubscription($event);
|
||||
|
||||
if ($subscription)
|
||||
{
|
||||
Utils::notifyZapier($subscription, $data);
|
||||
}
|
||||
}
|
||||
}
|
7
app/models/Subscription.php
Normal file
7
app/models/Subscription.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
class Subscription extends Eloquent
|
||||
{
|
||||
public $timestamps = true;
|
||||
protected $softDelete = true;
|
||||
}
|
@ -51,7 +51,7 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAuthIdentifier()
|
||||
{
|
||||
{
|
||||
return $this->getKey();
|
||||
}
|
||||
|
||||
@ -173,5 +173,5 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
|
||||
public function getRememberTokenName()
|
||||
{
|
||||
return 'remember_token';
|
||||
}
|
||||
}
|
||||
}
|
@ -32,13 +32,22 @@ class ClientRepository
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($publicId, $data)
|
||||
{
|
||||
if ($publicId == "-1")
|
||||
public function save($publicId, $data, $notify = true)
|
||||
{
|
||||
$contact = isset($data['contacts']) ? (array)$data['contacts'][0] : (isset($data['contact']) ? $data['contact'] : []);
|
||||
$validator = \Validator::make($contact, ['email' => 'required|email']);
|
||||
if ($validator->fails()) {
|
||||
dd($validator->messages());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$publicId || $publicId == "-1")
|
||||
{
|
||||
$client = Client::createNew();
|
||||
$client->currency_id = 1;
|
||||
$contact = Contact::createNew();
|
||||
$contact->is_primary = true;
|
||||
$contact->send_invoice = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -46,66 +55,128 @@ class ClientRepository
|
||||
$contact = $client->contacts()->where('is_primary', '=', true)->firstOrFail();
|
||||
}
|
||||
|
||||
if (isset($data['name'])) {
|
||||
$client->name = trim($data['name']);
|
||||
}
|
||||
if (isset($data['work_phone'])) {
|
||||
$client->work_phone = trim($data['work_phone']);
|
||||
}
|
||||
if (isset($data['custom_value1'])) {
|
||||
$client->custom_value1 = trim($data['custom_value1']);
|
||||
}
|
||||
if (isset($data['custom_value2'])) {
|
||||
$client->custom_value2 = trim($data['custom_value2']);
|
||||
}
|
||||
if (isset($data['address1'])) {
|
||||
$client->address1 = trim($data['address1']);
|
||||
}
|
||||
if (isset($data['address2'])) {
|
||||
$client->address2 = trim($data['address2']);
|
||||
}
|
||||
if (isset($data['city'])) {
|
||||
$client->city = trim($data['city']);
|
||||
}
|
||||
if (isset($data['state'])) {
|
||||
$client->state = trim($data['state']);
|
||||
}
|
||||
if (isset($data['postal_code'])) {
|
||||
$client->postal_code = trim($data['postal_code']);
|
||||
}
|
||||
if (isset($data['country_id'])) {
|
||||
$client->country_id = $data['country_id'] ? $data['country_id'] : null;
|
||||
}
|
||||
if (isset($data['private_notes'])) {
|
||||
$client->private_notes = trim($data['private_notes']);
|
||||
}
|
||||
if (isset($data['size_id'])) {
|
||||
$client->size_id = $data['size_id'] ? $data['size_id'] : null;
|
||||
}
|
||||
if (isset($data['industry_id'])) {
|
||||
$client->industry_id = $data['industry_id'] ? $data['industry_id'] : null;
|
||||
}
|
||||
if (isset($data['currency_id'])) {
|
||||
$client->currency_id = $data['currency_id'] ? $data['currency_id'] : 1;
|
||||
}
|
||||
if (isset($data['payment_terms'])) {
|
||||
$client->payment_terms = $data['payment_terms'];
|
||||
}
|
||||
if (isset($data['website'])) {
|
||||
$client->website = trim($data['website']);
|
||||
}
|
||||
|
||||
$client->name = trim($data['name']);
|
||||
$client->work_phone = trim($data['work_phone']);
|
||||
$client->custom_value1 = trim($data['custom_value1']);
|
||||
$client->custom_value2 = trim($data['custom_value2']);
|
||||
$client->address1 = trim($data['address1']);
|
||||
$client->address2 = trim($data['address2']);
|
||||
$client->city = trim($data['city']);
|
||||
$client->state = trim($data['state']);
|
||||
$client->postal_code = trim($data['postal_code']);
|
||||
$client->country_id = $data['country_id'] ? $data['country_id'] : null;
|
||||
$client->private_notes = trim($data['private_notes']);
|
||||
$client->size_id = $data['size_id'] ? $data['size_id'] : null;
|
||||
$client->industry_id = $data['industry_id'] ? $data['industry_id'] : null;
|
||||
$client->currency_id = $data['currency_id'] ? $data['currency_id'] : 1;
|
||||
$client->payment_terms = $data['payment_terms'];
|
||||
$client->website = trim($data['website']);
|
||||
$client->save();
|
||||
|
||||
$isPrimary = true;
|
||||
$contactIds = [];
|
||||
|
||||
foreach ($data['contacts'] as $record)
|
||||
if (isset($data['contact']))
|
||||
{
|
||||
$record = (array) $record;
|
||||
|
||||
if ($publicId != "-1" && isset($record['public_id']) && $record['public_id'])
|
||||
{
|
||||
$contact = Contact::scope($record['public_id'])->firstOrFail();
|
||||
$info = $data['contact'];
|
||||
if (isset($info['email'])) {
|
||||
$contact->email = trim(strtolower($info['email']));
|
||||
}
|
||||
else
|
||||
{
|
||||
$contact = Contact::createNew();
|
||||
if (isset($info['first_name'])) {
|
||||
$contact->first_name = trim($info['first_name']);
|
||||
}
|
||||
|
||||
$contact->email = trim(strtolower($record['email']));
|
||||
$contact->first_name = trim($record['first_name']);
|
||||
$contact->last_name = trim($record['last_name']);
|
||||
$contact->phone = trim($record['phone']);
|
||||
$contact->is_primary = $isPrimary;
|
||||
$contact->send_invoice = $record['send_invoice'];
|
||||
$isPrimary = false;
|
||||
|
||||
if (isset($info['last_name'])) {
|
||||
$contact->last_name = trim($info['last_name']);
|
||||
}
|
||||
if (isset($info['phone'])) {
|
||||
$contact->phone = trim($info['phone']);
|
||||
}
|
||||
$contact->is_primary = true;
|
||||
$contact->send_invoice = true;
|
||||
$client->contacts()->save($contact);
|
||||
$contactIds[] = $contact->public_id;
|
||||
}
|
||||
|
||||
foreach ($client->contacts as $contact)
|
||||
else
|
||||
{
|
||||
if (!in_array($contact->public_id, $contactIds))
|
||||
{
|
||||
$contact->delete();
|
||||
foreach ($data['contacts'] as $record)
|
||||
{
|
||||
$record = (array) $record;
|
||||
|
||||
if ($publicId != "-1" && isset($record['public_id']) && $record['public_id'])
|
||||
{
|
||||
$contact = Contact::scope($record['public_id'])->firstOrFail();
|
||||
}
|
||||
else
|
||||
{
|
||||
$contact = Contact::createNew();
|
||||
}
|
||||
|
||||
if (isset($record['email'])) {
|
||||
$contact->email = trim(strtolower($record['email']));
|
||||
}
|
||||
if (isset($record['first_name'])) {
|
||||
$contact->first_name = trim($record['first_name']);
|
||||
}
|
||||
if (isset($record['last_name'])) {
|
||||
$contact->last_name = trim($record['last_name']);
|
||||
}
|
||||
if (isset($record['phone'])) {
|
||||
$contact->phone = trim($record['phone']);
|
||||
}
|
||||
$contact->is_primary = $isPrimary;
|
||||
$contact->send_invoice = isset($record['send_invoice']) ? $record['send_invoice'] : true;
|
||||
$isPrimary = false;
|
||||
|
||||
$client->contacts()->save($contact);
|
||||
$contactIds[] = $contact->public_id;
|
||||
}
|
||||
|
||||
foreach ($client->contacts as $contact)
|
||||
{
|
||||
if (!in_array($contact->public_id, $contactIds))
|
||||
{
|
||||
$contact->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$client->save();
|
||||
|
||||
if ($publicId == "-1")
|
||||
if (!$publicId || $publicId == "-1")
|
||||
{
|
||||
\Activity::createClient($client);
|
||||
\Activity::createClient($client, $notify);
|
||||
}
|
||||
|
||||
return $client;
|
||||
|
@ -154,30 +154,30 @@ class InvoiceRepository
|
||||
{
|
||||
$contact = (array) $input->client->contacts[0];
|
||||
$rules = ['email' => 'required|email'];
|
||||
$validator = \Validator::make($contact, $rules);
|
||||
$validator = \Validator::make($contact, $rules);
|
||||
|
||||
if ($validator->fails())
|
||||
{
|
||||
return $validator;
|
||||
}
|
||||
if ($validator->fails())
|
||||
{
|
||||
return $validator;
|
||||
}
|
||||
|
||||
$invoice = (array) $input;
|
||||
$invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null;
|
||||
$rules = ['invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id];
|
||||
$invoice = (array) $input;
|
||||
$invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null;
|
||||
$rules = ['invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id];
|
||||
|
||||
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date'])
|
||||
{
|
||||
$rules['end_date'] = 'after:' . $invoice['start_date'];
|
||||
}
|
||||
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date'])
|
||||
{
|
||||
$rules['end_date'] = 'after:' . $invoice['start_date'];
|
||||
}
|
||||
|
||||
$validator = \Validator::make($invoice, $rules);
|
||||
$validator = \Validator::make($invoice, $rules);
|
||||
|
||||
if ($validator->fails())
|
||||
{
|
||||
return $validator;
|
||||
}
|
||||
if ($validator->fails())
|
||||
{
|
||||
return $validator;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function save($publicId, $data, $entityType)
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Routes
|
||||
@ -22,6 +23,7 @@
|
||||
//dd(gethostname());
|
||||
//Log::error('test');
|
||||
|
||||
|
||||
Route::get('/', 'HomeController@showIndex');
|
||||
Route::get('/rocksteady', 'HomeController@showIndex');
|
||||
Route::get('/about', 'HomeController@showAboutUs');
|
||||
@ -123,12 +125,20 @@ Route::group(array('before' => 'auth'), function()
|
||||
Route::post('credits/bulk', 'CreditController@bulk');
|
||||
});
|
||||
|
||||
// Route group for API versioning
|
||||
// Route group for API
|
||||
Route::group(array('prefix' => 'api/v1', 'before' => 'auth.basic'), function()
|
||||
{
|
||||
Route::resource('clients', 'ClientApiController');
|
||||
Route::resource('ping', 'ClientApiController@ping');
|
||||
Route::resource('clients', 'ClientApiController');
|
||||
Route::resource('invoices', 'InvoiceApiController');
|
||||
Route::resource('quotes', 'QuoteApiController');
|
||||
Route::resource('payments', 'PaymentApiController');
|
||||
});
|
||||
|
||||
Route::group(array('before' => 'auth.basic'), function()
|
||||
{
|
||||
Route::post('api/hooks', 'IntegrationController@subscribe');
|
||||
});
|
||||
|
||||
define('CONTACT_EMAIL', 'contact@invoiceninja.com');
|
||||
define('CONTACT_NAME', 'Invoice Ninja');
|
||||
@ -215,12 +225,17 @@ define('GATEWAY_PAYPAL_EXPRESS', 17);
|
||||
define('GATEWAY_BEANSTREAM', 29);
|
||||
define('GATEWAY_PSIGATE', 30);
|
||||
|
||||
define('EVENT_CREATE_CLIENT', 1);
|
||||
define('EVENT_CREATE_INVOICE', 2);
|
||||
define('EVENT_CREATE_QUOTE', 3);
|
||||
define('EVENT_CREATE_PAYMENT', 4);
|
||||
|
||||
define('REQUESTED_PRO_PLAN', 'REQUESTED_PRO_PLAN');
|
||||
define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h');
|
||||
define('NINJA_GATEWAY_ID', GATEWAY_AUTHORIZE_NET);
|
||||
define('NINJA_GATEWAY_CONFIG', '{"apiLoginId":"626vWcD5","transactionKey":"4bn26TgL9r4Br4qJ","testMode":"","developerMode":""}');
|
||||
define('NINJA_URL', 'https://www.invoiceninja.com');
|
||||
define('NINJA_VERSION', '1.3.0');
|
||||
define('NINJA_VERSION', '1.3.1');
|
||||
|
||||
define('PRO_PLAN_PRICE', 50);
|
||||
define('LICENSE_PRICE', 30);
|
||||
@ -380,3 +395,5 @@ if (Auth::check() && Auth::user()->id === 1)
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
@ -63,6 +63,10 @@ App::error(function(Exception $exception, $code)
|
||||
Utils::logError($exception . ' ' . $code);
|
||||
return Response::view('error', ['hideHeader' => true, 'error' => "A {$code} error occurred."], $code);
|
||||
}
|
||||
else if (Utils::isNinjaDev())
|
||||
{
|
||||
return "{$exception->getFile()}:{$exception->getLine()} => {$exception->getMessage()}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
|
@ -57,7 +57,7 @@
|
||||
'password_confirmation' => 'required',
|
||||
)); }}
|
||||
|
||||
<h2 class="form-signin-heading">Set Passord</h2><p/>
|
||||
<h2 class="form-signin-heading">Set Password</h2><p/>
|
||||
<input type="hidden" name="token" value="{{{ $token }}}">
|
||||
|
||||
<p>
|
||||
|
@ -32,6 +32,14 @@ if (!function_exists('gethostname')) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fortrabbit HTTP AUTH CODE
|
||||
if (!empty($_SERVER['REMOTE_USER'])) {
|
||||
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(
|
||||
':',
|
||||
base64_decode(substr($_SERVER['REMOTE_USER'], 6))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
594
composer.lock
generated
594
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -5,4 +5,7 @@
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [L]
|
||||
|
||||
RewriteCond %{HTTP:Authorization} .
|
||||
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
|
||||
</IfModule>
|
Loading…
Reference in New Issue
Block a user