mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
solve merge conflits
This commit is contained in:
commit
db97fa9c95
@ -21,5 +21,8 @@ MAIL_FROM_NAME
|
||||
MAIL_PASSWORD
|
||||
|
||||
PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address'
|
||||
LOG=single
|
||||
|
||||
LOG=single
|
||||
GOOGLE_CLIENT_ID
|
||||
GOOGLE_CLIENT_SECRET
|
||||
GOOGLE_OAUTH_REDIRECT=http://ninja.dev/auth/google
|
@ -1,7 +1,6 @@
|
||||
<?php namespace App\Commands;
|
||||
<?php namespace app\Commands;
|
||||
|
||||
abstract class Command {
|
||||
|
||||
//
|
||||
abstract class Command
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ class CheckData extends Command {
|
||||
$activities = DB::table('activities')
|
||||
->where('client_id', '=', $client->id)
|
||||
->orderBy('activities.id')
|
||||
->get(['activities.id', 'activities.created_at', 'activities.activity_type_id', 'activities.message', 'activities.adjustment', 'activities.balance', 'activities.invoice_id']);
|
||||
->get(['activities.id', 'activities.created_at', 'activities.activity_type_id', 'activities.adjustment', 'activities.balance', 'activities.invoice_id']);
|
||||
//$this->info(var_dump($activities));
|
||||
|
||||
foreach ($activities as $activity) {
|
||||
@ -235,7 +235,6 @@ class CheckData extends Command {
|
||||
'updated_at' => new Carbon,
|
||||
'account_id' => $client->account_id,
|
||||
'client_id' => $client->id,
|
||||
'message' => 'Corrected client balance',
|
||||
'adjustment' => $client->actual_balance - $activity->balance,
|
||||
'balance' => $client->actual_balance,
|
||||
]);
|
||||
|
@ -1,88 +0,0 @@
|
||||
<?php namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
class CreateRandomData extends Command {
|
||||
|
||||
protected $name = 'ninja:create-data';
|
||||
protected $description = 'Create random data';
|
||||
|
||||
public function fire()
|
||||
{
|
||||
$this->info(date('Y-m-d') . ' Running CreateRandomData...');
|
||||
|
||||
$user = User::first();
|
||||
|
||||
if (!$user) {
|
||||
$this->error("Error: please create user account by logging in");
|
||||
return;
|
||||
}
|
||||
|
||||
$productNames = ['Arkansas', 'New York', 'Arizona', 'California', 'Colorado', 'Alabama', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'Alaska', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];
|
||||
$clientNames = ['IBM', 'Nestle', 'Mitsubishi UFJ Financial', 'Vodafone', 'Eni', 'Procter & Gamble', 'Johnson & Johnson', 'American International Group', 'Banco Santander', 'BHP Billiton', 'Pfizer', 'Itaú Unibanco Holding', 'Ford Motor', 'BMW Group', 'Commonwealth Bank', 'EDF', 'Statoil', 'Google', 'Siemens', 'Novartis', 'Royal Bank of Canada', 'Sumitomo Mitsui Financial', 'Comcast', 'Sberbank', 'Goldman Sachs Group', 'Westpac Banking Group', 'Nippon Telegraph & Tel', 'Ping An Insurance Group', 'Banco Bradesco', 'Anheuser-Busch InBev', 'Bank of Communications', 'China Life Insurance', 'General Motors', 'Telefónica', 'MetLife', 'Honda Motor', 'Enel', 'BASF', 'Softbank', 'National Australia Bank', 'ANZ', 'ConocoPhillips', 'TD Bank Group', 'Intel', 'UBS', 'Hewlett-Packard', 'Coca-Cola', 'Cisco Systems', 'UnitedHealth Group', 'Boeing', 'Zurich Insurance Group', 'Hyundai Motor', 'Sanofi', 'Credit Agricole', 'United Technologies', 'Roche Holding', 'Munich Re', 'PepsiCo', 'Oracle', 'Bank of Nova Scotia'];
|
||||
|
||||
foreach ($productNames as $i => $value) {
|
||||
$product = Product::createNew($user);
|
||||
$product->id = $i+1;
|
||||
$product->product_key = $value;
|
||||
$product->save();
|
||||
}
|
||||
|
||||
foreach ($clientNames as $i => $value) {
|
||||
$client = Client::createNew($user);
|
||||
$client->name = $value;
|
||||
$client->save();
|
||||
|
||||
$contact = Contact::createNew($user);
|
||||
$contact->email = "client@aol.com";
|
||||
$contact->is_primary = 1;
|
||||
$client->contacts()->save($contact);
|
||||
|
||||
$numInvoices = rand(1, 25);
|
||||
if ($numInvoices == 4 || $numInvoices == 10 || $numInvoices == 25) {
|
||||
// leave these
|
||||
} else if ($numInvoices % 3 == 0) {
|
||||
$numInvoices = 1;
|
||||
} else if ($numInvoices > 10) {
|
||||
$numInvoices = $numInvoices % 2;
|
||||
}
|
||||
|
||||
$paidUp = rand(0, 1) == 1;
|
||||
|
||||
for ($j=1; $j<=$numInvoices; $j++) {
|
||||
|
||||
$price = rand(10, 1000);
|
||||
if ($price < 900) {
|
||||
$price = rand(10, 150);
|
||||
}
|
||||
|
||||
$invoice = Invoice::createNew($user);
|
||||
$invoice->invoice_number = $user->account->getNextInvoiceNumber($invoice);
|
||||
$invoice->amount = $invoice->balance = $price;
|
||||
$invoice->created_at = date('Y-m-d', strtotime(date("Y-m-d") . ' - ' . rand(1, 100) . ' days'));
|
||||
$client->invoices()->save($invoice);
|
||||
|
||||
$productId = rand(0, 40);
|
||||
if ($productId > 20) {
|
||||
$productId = ($productId % 2) + rand(0, 2);
|
||||
}
|
||||
|
||||
$invoiceItem = InvoiceItem::createNew($user);
|
||||
$invoiceItem->product_id = $productId+1;
|
||||
$invoiceItem->product_key = $productNames[$invoiceItem->product_id];
|
||||
$invoiceItem->cost = $invoice->amount;
|
||||
$invoiceItem->qty = 1;
|
||||
$invoice->invoice_items()->save($invoiceItem);
|
||||
|
||||
if ($paidUp || rand(0,2) > 1) {
|
||||
$payment = Payment::createNew($user);
|
||||
$payment->invoice_id = $invoice->id;
|
||||
$payment->amount = $invoice->amount;
|
||||
$client->payments()->save($payment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected $commands = [
|
||||
'App\Console\Commands\SendRecurringInvoices',
|
||||
'App\Console\Commands\CreateRandomData',
|
||||
'App\Console\Commands\ResetData',
|
||||
'App\Console\Commands\CheckData',
|
||||
'App\Console\Commands\SendRenewalInvoices',
|
||||
|
21
app/Events/ClientWasArchived.php
Normal file
21
app/Events/ClientWasArchived.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ClientWasArchived extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $client;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
}
|
21
app/Events/ClientWasCreated.php
Normal file
21
app/Events/ClientWasCreated.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ClientWasCreated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $client;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
}
|
21
app/Events/ClientWasDeleted.php
Normal file
21
app/Events/ClientWasDeleted.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ClientWasDeleted extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $client;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
}
|
21
app/Events/ClientWasRestored.php
Normal file
21
app/Events/ClientWasRestored.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ClientWasRestored extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $client;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
}
|
21
app/Events/ClientWasUpdated.php
Normal file
21
app/Events/ClientWasUpdated.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ClientWasUpdated extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public $client;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($client)
|
||||
{
|
||||
$this->client = $client;
|
||||
}
|
||||
}
|
23
app/Events/CreditWasArchived.php
Normal file
23
app/Events/CreditWasArchived.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CreditWasArchived extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $credit;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($credit)
|
||||
{
|
||||
$this->credit = $credit;
|
||||
}
|
||||
|
||||
}
|
23
app/Events/CreditWasCreated.php
Normal file
23
app/Events/CreditWasCreated.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CreditWasCreated extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $credit;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($credit)
|
||||
{
|
||||
$this->credit = $credit;
|
||||
}
|
||||
|
||||
}
|
23
app/Events/CreditWasDeleted.php
Normal file
23
app/Events/CreditWasDeleted.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CreditWasDeleted extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $credit;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($credit)
|
||||
{
|
||||
$this->credit = $credit;
|
||||
}
|
||||
|
||||
}
|
23
app/Events/CreditWasRestored.php
Normal file
23
app/Events/CreditWasRestored.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class CreditWasRestored extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $credit;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($credit)
|
||||
{
|
||||
$this->credit = $credit;
|
||||
}
|
||||
|
||||
}
|
23
app/Events/InvoiceInvitationWasEmailed.php
Normal file
23
app/Events/InvoiceInvitationWasEmailed.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceInvitationWasEmailed extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $invitation;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invitation)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
}
|
||||
|
||||
}
|
25
app/Events/InvoiceInvitationWasViewed.php
Normal file
25
app/Events/InvoiceInvitationWasViewed.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceInvitationWasViewed extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $invoice;
|
||||
public $invitation;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invoice, $invitation)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
$this->invitation = $invitation;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/InvoiceWasArchived.php
Normal file
22
app/Events/InvoiceWasArchived.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceWasArchived extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $invoice;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invoice)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
}
|
||||
|
||||
}
|
@ -4,10 +4,9 @@ use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceSent extends Event {
|
||||
class InvoiceWasCreated extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $invoice;
|
||||
|
||||
/**
|
@ -4,10 +4,9 @@ use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceViewed extends Event {
|
||||
class InvoiceWasDeleted extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $invoice;
|
||||
|
||||
/**
|
||||
@ -15,9 +14,9 @@ class InvoiceViewed extends Event {
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invoice)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
}
|
||||
public function __construct($invoice)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/InvoiceWasEmailed.php
Normal file
22
app/Events/InvoiceWasEmailed.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceWasEmailed extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $invoice;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invoice)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
}
|
||||
|
||||
}
|
25
app/Events/InvoiceWasRestored.php
Normal file
25
app/Events/InvoiceWasRestored.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoiceWasRestored extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $invoice;
|
||||
public $fromDeleted;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invoice, $fromDeleted)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
$this->fromDeleted = $fromDeleted;
|
||||
}
|
||||
|
||||
}
|
@ -4,10 +4,9 @@ use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteApproved extends Event {
|
||||
class InvoiceWasUpdated extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $invoice;
|
||||
|
||||
/**
|
@ -4,10 +4,9 @@ use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class InvoicePaid extends Event {
|
||||
class PaymentWasArchived extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $payment;
|
||||
|
||||
/**
|
22
app/Events/PaymentWasCreated.php
Normal file
22
app/Events/PaymentWasCreated.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class PaymentWasCreated extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $payment;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($payment)
|
||||
{
|
||||
$this->payment = $payment;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/PaymentWasDeleted.php
Normal file
22
app/Events/PaymentWasDeleted.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class PaymentWasDeleted extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $payment;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($payment)
|
||||
{
|
||||
$this->payment = $payment;
|
||||
}
|
||||
|
||||
}
|
25
app/Events/PaymentWasRestored.php
Normal file
25
app/Events/PaymentWasRestored.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class PaymentWasRestored extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $payment;
|
||||
public $fromDeleted;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($payment, $fromDeleted)
|
||||
{
|
||||
$this->payment = $payment;
|
||||
$this->fromDeleted = $fromDeleted;
|
||||
}
|
||||
|
||||
}
|
25
app/Events/QuoteInvitationWasApproved.php
Normal file
25
app/Events/QuoteInvitationWasApproved.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteInvitationWasApproved extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $quote;
|
||||
public $invitation;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote, $invitation)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
$this->invitation = $invitation;
|
||||
}
|
||||
|
||||
}
|
23
app/Events/QuoteInvitationWasEmailed.php
Normal file
23
app/Events/QuoteInvitationWasEmailed.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteInvitationWasEmailed extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $invitation;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($invitation)
|
||||
{
|
||||
$this->invitation = $invitation;
|
||||
}
|
||||
|
||||
}
|
25
app/Events/QuoteInvitationWasViewed.php
Normal file
25
app/Events/QuoteInvitationWasViewed.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteInvitationWasViewed extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
public $quote;
|
||||
public $invitation;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote, $invitation)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
$this->invitation = $invitation;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/QuoteWasArchived.php
Normal file
22
app/Events/QuoteWasArchived.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteWasArchived extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $quote;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/QuoteWasCreated.php
Normal file
22
app/Events/QuoteWasCreated.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteWasCreated extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $quote;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/QuoteWasDeleted.php
Normal file
22
app/Events/QuoteWasDeleted.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteWasDeleted extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $quote;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/QuoteWasEmailed.php
Normal file
22
app/Events/QuoteWasEmailed.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteWasEmailed extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $quote;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/QuoteWasRestored.php
Normal file
22
app/Events/QuoteWasRestored.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteWasRestored extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $quote;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
}
|
||||
|
||||
}
|
22
app/Events/QuoteWasUpdated.php
Normal file
22
app/Events/QuoteWasUpdated.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class QuoteWasUpdated extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
public $quote;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($quote)
|
||||
{
|
||||
$this->quote = $quote;
|
||||
}
|
||||
|
||||
}
|
40
app/Http/Controllers/AccountApiController.php
Normal file
40
app/Http/Controllers/AccountApiController.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Utils;
|
||||
use Response;
|
||||
use Input;
|
||||
use App\Models\Client;
|
||||
use App\Models\Account;
|
||||
use App\Ninja\Repositories\AccountRepository;
|
||||
|
||||
use League\Fractal;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Manager;
|
||||
use App\Ninja\Serializers\ArraySerializer;
|
||||
use App\Ninja\Transformers\AccountTransformer;
|
||||
|
||||
class AccountApiController extends Controller
|
||||
{
|
||||
protected $accountRepo;
|
||||
|
||||
public function __construct(AccountRepository $accountRepo)
|
||||
{
|
||||
$this->accountRepo = $accountRepo;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
|
||||
$account = Auth::user()->account->load('users');
|
||||
$resource = new Item($account, new AccountTransformer, 'account');
|
||||
|
||||
$response = $manager->createData($resource)->toArray();
|
||||
$response = json_encode($response, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders();
|
||||
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ use App\Models\Industry;
|
||||
use App\Models\InvoiceDesign;
|
||||
use App\Models\TaxRate;
|
||||
use App\Ninja\Repositories\AccountRepository;
|
||||
use App\Ninja\Repositories\ReferralRepository;
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
use App\Ninja\Mailers\ContactMailer;
|
||||
use App\Events\UserSignedUp;
|
||||
@ -45,19 +46,23 @@ use App\Events\UserLoggedIn;
|
||||
use App\Events\UserSettingsChanged;
|
||||
use App\Services\AuthService;
|
||||
|
||||
use App\Commands\CreateClient;
|
||||
|
||||
class AccountController extends BaseController
|
||||
{
|
||||
protected $accountRepo;
|
||||
protected $userMailer;
|
||||
protected $contactMailer;
|
||||
protected $referralRepository;
|
||||
|
||||
public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer)
|
||||
public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer, ReferralRepository $referralRepository)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->accountRepo = $accountRepo;
|
||||
$this->userMailer = $userMailer;
|
||||
$this->contactMailer = $contactMailer;
|
||||
$this->referralRepository = $referralRepository;
|
||||
}
|
||||
|
||||
public function demo()
|
||||
@ -221,13 +226,14 @@ class AccountController extends BaseController
|
||||
foreach (AuthService::$providers as $provider) {
|
||||
$oauthLoginUrls[] = ['label' => $provider, 'url' => '/auth/' . strtolower($provider)];
|
||||
}
|
||||
|
||||
|
||||
$data = [
|
||||
'account' => Account::with('users')->findOrFail(Auth::user()->account_id),
|
||||
'title' => trans('texts.user_details'),
|
||||
'user' => Auth::user(),
|
||||
'oauthProviderName' => AuthService::getProviderName(Auth::user()->oauth_provider_id),
|
||||
'oauthLoginUrls' => $oauthLoginUrls,
|
||||
'referralCounts' => $this->referralRepository->getCounts(Auth::user()->id),
|
||||
];
|
||||
|
||||
return View::make('accounts.user_details', $data);
|
||||
@ -519,8 +525,10 @@ class AccountController extends BaseController
|
||||
$account->invoice_number_counter = Input::get('invoice_number_counter');
|
||||
$account->quote_number_prefix = Input::get('quote_number_prefix');
|
||||
$account->share_counter = Input::get('share_counter') ? true : false;
|
||||
|
||||
$account->pdf_email_attachment = Input::get('pdf_email_attachment') ? true : false;
|
||||
$account->invoice_terms = Input::get('invoice_terms');
|
||||
$account->invoice_footer = Input::get('invoice_footer');
|
||||
$account->quote_terms = Input::get('quote_terms');
|
||||
|
||||
if (Input::has('recurring_hour')) {
|
||||
$account->recurring_hour = Input::get('recurring_hour');
|
||||
@ -637,49 +645,56 @@ class AccountController extends BaseController
|
||||
continue;
|
||||
}
|
||||
|
||||
$client = Client::createNew();
|
||||
$contact = Contact::createNew();
|
||||
$contact->is_primary = true;
|
||||
$contact->send_invoice = true;
|
||||
$count++;
|
||||
$data = [
|
||||
'contacts' => [[]]
|
||||
];
|
||||
|
||||
foreach ($row as $index => $value) {
|
||||
$field = $map[$index];
|
||||
$value = trim($value);
|
||||
if ( ! $value = trim($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($field == Client::$fieldName && !$client->name) {
|
||||
$client->name = $value;
|
||||
} elseif ($field == Client::$fieldPhone && !$client->work_phone) {
|
||||
$client->work_phone = $value;
|
||||
} elseif ($field == Client::$fieldAddress1 && !$client->address1) {
|
||||
$client->address1 = $value;
|
||||
} elseif ($field == Client::$fieldAddress2 && !$client->address2) {
|
||||
$client->address2 = $value;
|
||||
} elseif ($field == Client::$fieldCity && !$client->city) {
|
||||
$client->city = $value;
|
||||
} elseif ($field == Client::$fieldState && !$client->state) {
|
||||
$client->state = $value;
|
||||
} elseif ($field == Client::$fieldPostalCode && !$client->postal_code) {
|
||||
$client->postal_code = $value;
|
||||
} elseif ($field == Client::$fieldCountry && !$client->country_id) {
|
||||
if ($field == Client::$fieldName) {
|
||||
$data['name'] = $value;
|
||||
} elseif ($field == Client::$fieldPhone) {
|
||||
$data['work_phone'] = $value;
|
||||
} elseif ($field == Client::$fieldAddress1) {
|
||||
$data['address1'] = $value;
|
||||
} elseif ($field == Client::$fieldAddress2) {
|
||||
$data['address2'] = $value;
|
||||
} elseif ($field == Client::$fieldCity) {
|
||||
$data['city'] = $value;
|
||||
} elseif ($field == Client::$fieldState) {
|
||||
$data['state'] = $value;
|
||||
} elseif ($field == Client::$fieldPostalCode) {
|
||||
$data['postal_code'] = $value;
|
||||
} elseif ($field == Client::$fieldCountry) {
|
||||
$value = strtolower($value);
|
||||
$client->country_id = isset($countryMap[$value]) ? $countryMap[$value] : null;
|
||||
} elseif ($field == Client::$fieldNotes && !$client->private_notes) {
|
||||
$client->private_notes = $value;
|
||||
} elseif ($field == Contact::$fieldFirstName && !$contact->first_name) {
|
||||
$contact->first_name = $value;
|
||||
} elseif ($field == Contact::$fieldLastName && !$contact->last_name) {
|
||||
$contact->last_name = $value;
|
||||
} elseif ($field == Contact::$fieldPhone && !$contact->phone) {
|
||||
$contact->phone = $value;
|
||||
} elseif ($field == Contact::$fieldEmail && !$contact->email) {
|
||||
$contact->email = strtolower($value);
|
||||
$data['country_id'] = isset($countryMap[$value]) ? $countryMap[$value] : null;
|
||||
} elseif ($field == Client::$fieldNotes) {
|
||||
$data['private_notes'] = $value;
|
||||
} elseif ($field == Contact::$fieldFirstName) {
|
||||
$data['contacts'][0]['first_name'] = $value;
|
||||
} elseif ($field == Contact::$fieldLastName) {
|
||||
$data['contacts'][0]['last_name'] = $value;
|
||||
} elseif ($field == Contact::$fieldPhone) {
|
||||
$data['contacts'][0]['phone'] = $value;
|
||||
} elseif ($field == Contact::$fieldEmail) {
|
||||
$data['contacts'][0]['email'] = strtolower($value);
|
||||
}
|
||||
}
|
||||
|
||||
$client->save();
|
||||
$client->contacts()->save($contact);
|
||||
Activity::createClient($client, false);
|
||||
$rules = [
|
||||
'contacts' => 'valid_contacts',
|
||||
];
|
||||
$validator = Validator::make($data, $rules);
|
||||
if ($validator->fails()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->dispatch(new CreateClient($data));
|
||||
$count++;
|
||||
}
|
||||
|
||||
$message = Utils::pluralize('created_client', $count);
|
||||
@ -792,12 +807,6 @@ class AccountController extends BaseController
|
||||
|
||||
private function saveNotifications()
|
||||
{
|
||||
$account = Auth::user()->account;
|
||||
$account->invoice_terms = Input::get('invoice_terms');
|
||||
$account->invoice_footer = Input::get('invoice_footer');
|
||||
$account->email_footer = Input::get('email_footer');
|
||||
$account->save();
|
||||
|
||||
$user = Auth::user();
|
||||
$user->notify_sent = Input::get('notify_sent');
|
||||
$user->notify_viewed = Input::get('notify_viewed');
|
||||
@ -838,6 +847,7 @@ class AccountController extends BaseController
|
||||
$account->country_id = Input::get('country_id') ? Input::get('country_id') : null;
|
||||
$account->size_id = Input::get('size_id') ? Input::get('size_id') : null;
|
||||
$account->industry_id = Input::get('industry_id') ? Input::get('industry_id') : null;
|
||||
$account->email_footer = Input::get('email_footer');
|
||||
$account->save();
|
||||
|
||||
/* Logo image file */
|
||||
|
@ -60,20 +60,17 @@ class AccountGatewayController extends BaseController
|
||||
public function edit($publicId)
|
||||
{
|
||||
$accountGateway = AccountGateway::scope($publicId)->firstOrFail();
|
||||
$config = $accountGateway->config;
|
||||
$selectedCards = $accountGateway->accepted_credit_cards;
|
||||
|
||||
$configFields = json_decode($config);
|
||||
|
||||
foreach ($configFields as $configField => $value) {
|
||||
$configFields->$configField = str_repeat('*', strlen($value));
|
||||
$config = $accountGateway->getConfig();
|
||||
|
||||
foreach ($config as $field => $value) {
|
||||
$config->$field = str_repeat('*', strlen($value));
|
||||
}
|
||||
|
||||
$data = self::getViewModel($accountGateway);
|
||||
$data['url'] = 'gateways/'.$publicId;
|
||||
$data['method'] = 'PUT';
|
||||
$data['title'] = trans('texts.edit_gateway') . ' - ' . $accountGateway->gateway->name;
|
||||
$data['config'] = $configFields;
|
||||
$data['config'] = $config;
|
||||
$data['hiddenFields'] = Gateway::$hiddenFields;
|
||||
$data['paymentTypeId'] = $accountGateway->getPaymentType();
|
||||
$data['selectGateways'] = Gateway::where('id', '=', $accountGateway->gateway_id)->get();
|
||||
@ -237,7 +234,7 @@ class AccountGatewayController extends BaseController
|
||||
|
||||
if ($accountGatewayPublicId) {
|
||||
$accountGateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail();
|
||||
$oldConfig = json_decode($accountGateway->config);
|
||||
$oldConfig = $accountGateway->getConfig();
|
||||
} else {
|
||||
$accountGateway = AccountGateway::createNew();
|
||||
$accountGateway->gateway_id = $gatewayId;
|
||||
@ -267,7 +264,7 @@ class AccountGatewayController extends BaseController
|
||||
$accountGateway->accepted_credit_cards = $cardCount;
|
||||
$accountGateway->show_address = Input::get('show_address') ? true : false;
|
||||
$accountGateway->update_address = Input::get('update_address') ? true : false;
|
||||
$accountGateway->config = json_encode($config);
|
||||
$accountGateway->setConfig($config);
|
||||
|
||||
if ($accountGatewayPublicId) {
|
||||
$accountGateway->save();
|
||||
|
@ -5,20 +5,46 @@ use DB;
|
||||
use Datatable;
|
||||
use Utils;
|
||||
use View;
|
||||
use App\Models\Client;
|
||||
use App\Models\Activity;
|
||||
use App\Ninja\Repositories\ActivityRepository;
|
||||
|
||||
class ActivityController extends BaseController
|
||||
{
|
||||
protected $activityRepo;
|
||||
|
||||
public function __construct(ActivityRepository $activityRepo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->activityRepo = $activityRepo;
|
||||
}
|
||||
|
||||
public function getDatatable($clientPublicId)
|
||||
{
|
||||
$query = DB::table('activities')
|
||||
->join('clients', 'clients.id', '=', 'activities.client_id')
|
||||
->where('clients.public_id', '=', $clientPublicId)
|
||||
->where('activities.account_id', '=', Auth::user()->account_id)
|
||||
->select('activities.id', 'activities.message', 'activities.created_at', 'clients.currency_id', 'activities.balance', 'activities.adjustment');
|
||||
$clientId = Client::getPrivateId($clientPublicId);
|
||||
|
||||
if ( ! $clientId) {
|
||||
app()->abort(404);
|
||||
}
|
||||
|
||||
$query = $this->activityRepo->findByClientId($clientId);
|
||||
|
||||
return Datatable::query($query)
|
||||
->addColumn('activities.id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
||||
->addColumn('message', function ($model) { return Utils::decodeActivity($model->message); })
|
||||
->addColumn('activity_type_id', function ($model) {
|
||||
$data = [
|
||||
'client' => link_to('/clients/' . $model->client_public_id, Utils::getClientDisplayName($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('/clients/' . $model->client_public_id, Utils::getClientDisplayName($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)
|
||||
];
|
||||
|
||||
return trans("texts.activity_{$model->activity_type_id}", $data);
|
||||
})
|
||||
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||
->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id) : ''; })
|
||||
->make();
|
||||
|
@ -189,6 +189,7 @@ class AppController extends BaseController
|
||||
Artisan::call('db:seed', array('--force' => true, '--class' => 'PaymentLibrariesSeeder'));
|
||||
Artisan::call('optimize', array('--force' => true));
|
||||
Cache::flush();
|
||||
Session::flush();
|
||||
Event::fire(new UserSettingsChanged());
|
||||
Session::flash('message', trans('texts.processed_updates'));
|
||||
} catch (Exception $e) {
|
||||
|
@ -97,8 +97,14 @@ class AuthController extends Controller {
|
||||
} else {
|
||||
$users = $this->accountRepo->loadAccounts(Auth::user()->id);
|
||||
}
|
||||
|
||||
Session::put(SESSION_USER_ACCOUNTS, $users);
|
||||
|
||||
if ($request->create_token) {
|
||||
if ( ! env(API_SECRET) || $request->api_secret !== env(API_SECRET)) {
|
||||
return 'Invalid secret';
|
||||
}
|
||||
return $this->accountRepo->createToken($request->token_name);
|
||||
}
|
||||
} elseif ($user) {
|
||||
$user->failed_logins = $user->failed_logins + 1;
|
||||
$user->save();
|
||||
|
@ -1,7 +1,11 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Bus\DispatchesCommands;
|
||||
|
||||
class BaseController extends Controller
|
||||
{
|
||||
use DispatchesCommands;
|
||||
|
||||
/**
|
||||
* Setup the layout used by the controller.
|
||||
*
|
||||
|
@ -5,6 +5,7 @@ use Response;
|
||||
use Input;
|
||||
use App\Models\Client;
|
||||
use App\Ninja\Repositories\ClientRepository;
|
||||
use App\Http\Requests\CreateClientRequest;
|
||||
|
||||
class ClientApiController extends Controller
|
||||
{
|
||||
@ -36,23 +37,15 @@ class ClientApiController extends Controller
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
|
||||
public function store()
|
||||
public function store(CreateClientRequest $request)
|
||||
{
|
||||
$data = Input::all();
|
||||
$error = $this->clientRepo->getErrors($data);
|
||||
$client = $this->clientRepo->save($request->input());
|
||||
|
||||
if ($error) {
|
||||
$headers = Utils::getApiHeaders();
|
||||
$client = Client::scope($client->public_id)->with('country', 'contacts', 'industry', 'size', 'currency')->first();
|
||||
$client = Utils::remapPublicIds([$client]);
|
||||
$response = json_encode($client, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders();
|
||||
|
||||
return Response::make($error, 500, $headers);
|
||||
} else {
|
||||
$client = $this->clientRepo->save(isset($data['id']) ? $data['id'] : false, $data, false);
|
||||
$client = Client::scope($client->public_id)->with('country', 'contacts', 'industry', 'size', 'currency')->first();
|
||||
$client = Utils::remapPublicIds([$client]);
|
||||
$response = json_encode($client, JSON_PRETTY_PRINT);
|
||||
$headers = Utils::getApiHeaders();
|
||||
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
return Response::make($response, 200, $headers);
|
||||
}
|
||||
}
|
||||
|
@ -21,18 +21,23 @@ use App\Models\Industry;
|
||||
use App\Models\Currency;
|
||||
use App\Models\Country;
|
||||
use App\Models\Task;
|
||||
|
||||
use App\Ninja\Repositories\ClientRepository;
|
||||
use App\Services\ClientService;
|
||||
|
||||
use App\Http\Requests\CreateClientRequest;
|
||||
use App\Http\Requests\UpdateClientRequest;
|
||||
|
||||
class ClientController extends BaseController
|
||||
{
|
||||
protected $clientService;
|
||||
protected $clientRepo;
|
||||
|
||||
public function __construct(ClientRepository $clientRepo)
|
||||
public function __construct(ClientRepository $clientRepo, ClientService $clientService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->clientRepo = $clientRepo;
|
||||
$this->clientService = $clientService;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,9 +68,6 @@ class ClientController extends BaseController
|
||||
->addColumn('last_login', function ($model) { return Utils::timestampToDateString(strtotime($model->last_login)); })
|
||||
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||
->addColumn('dropdown', function ($model) {
|
||||
if ($model->is_deleted) {
|
||||
return '<div style="height:38px"/>';
|
||||
}
|
||||
|
||||
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
@ -92,7 +94,11 @@ class ClientController extends BaseController
|
||||
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans('texts.restore_client').'</a></li>';
|
||||
}
|
||||
|
||||
return $str.'<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans('texts.delete_client').'</a></li></ul>
|
||||
if ($model->is_deleted) {
|
||||
return $str. '</ul></div>';
|
||||
}
|
||||
|
||||
return $str.'<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans('texts.delete_client').'</a></li></ul>
|
||||
</div>';
|
||||
})
|
||||
->make();
|
||||
@ -103,9 +109,13 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function store()
|
||||
public function store(CreateClientRequest $request)
|
||||
{
|
||||
return $this->save();
|
||||
$client = $this->clientService->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_client'));
|
||||
|
||||
return redirect()->to($client->getRoute());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -194,6 +204,7 @@ class ClientController extends BaseController
|
||||
private static function getViewModel()
|
||||
{
|
||||
return [
|
||||
'data' => Input::old('data'),
|
||||
'account' => Auth::user()->account,
|
||||
'sizes' => Cache::get('sizes'),
|
||||
'paymentTerms' => Cache::get('paymentTerms'),
|
||||
@ -212,105 +223,20 @@ class ClientController extends BaseController
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update($publicId)
|
||||
public function update(UpdateClientRequest $request)
|
||||
{
|
||||
return $this->save($publicId);
|
||||
}
|
||||
|
||||
private function save($publicId = null)
|
||||
{
|
||||
$rules = array(
|
||||
'email' => 'email|required_without:first_name',
|
||||
'first_name' => 'required_without:email',
|
||||
);
|
||||
$validator = Validator::make(Input::all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$url = $publicId ? 'clients/'.$publicId.'/edit' : 'clients/create';
|
||||
|
||||
return Redirect::to($url)
|
||||
->withErrors($validator)
|
||||
->withInput(Input::except('password'));
|
||||
} else {
|
||||
if ($publicId) {
|
||||
$client = Client::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
$client = Client::createNew();
|
||||
}
|
||||
|
||||
$client->name = trim(Input::get('name'));
|
||||
$client->id_number = trim(Input::get('id_number'));
|
||||
$client->vat_number = trim(Input::get('vat_number'));
|
||||
$client->work_phone = trim(Input::get('work_phone'));
|
||||
$client->custom_value1 = trim(Input::get('custom_value1'));
|
||||
$client->custom_value2 = trim(Input::get('custom_value2'));
|
||||
$client->address1 = trim(Input::get('address1'));
|
||||
$client->address2 = trim(Input::get('address2'));
|
||||
$client->city = trim(Input::get('city'));
|
||||
$client->state = trim(Input::get('state'));
|
||||
$client->postal_code = trim(Input::get('postal_code'));
|
||||
$client->country_id = Input::get('country_id') ?: null;
|
||||
$client->private_notes = trim(Input::get('private_notes'));
|
||||
$client->size_id = Input::get('size_id') ?: null;
|
||||
$client->industry_id = Input::get('industry_id') ?: null;
|
||||
$client->currency_id = Input::get('currency_id') ?: null;
|
||||
$client->language_id = Input::get('language_id') ?: null;
|
||||
$client->payment_terms = Input::get('payment_terms') ?: 0;
|
||||
$client->website = trim(Input::get('website'));
|
||||
|
||||
if (Input::has('invoice_number_counter')) {
|
||||
$client->invoice_number_counter = (int) Input::get('invoice_number_counter');
|
||||
}
|
||||
if (Input::has('quote_number_counter')) {
|
||||
$client->invoice_number_counter = (int) Input::get('quote_number_counter');
|
||||
}
|
||||
|
||||
$client->save();
|
||||
|
||||
$data = json_decode(Input::get('data'));
|
||||
$contactIds = [];
|
||||
$isPrimary = true;
|
||||
|
||||
foreach ($data->contacts as $contact) {
|
||||
if (isset($contact->public_id) && $contact->public_id) {
|
||||
$record = Contact::scope($contact->public_id)->firstOrFail();
|
||||
} else {
|
||||
$record = Contact::createNew();
|
||||
}
|
||||
|
||||
$record->email = trim($contact->email);
|
||||
$record->first_name = trim($contact->first_name);
|
||||
$record->last_name = trim($contact->last_name);
|
||||
$record->phone = trim($contact->phone);
|
||||
$record->is_primary = $isPrimary;
|
||||
$isPrimary = false;
|
||||
|
||||
$client->contacts()->save($record);
|
||||
$contactIds[] = $record->public_id;
|
||||
}
|
||||
|
||||
foreach ($client->contacts as $contact) {
|
||||
if (!in_array($contact->public_id, $contactIds)) {
|
||||
$contact->delete();
|
||||
}
|
||||
}
|
||||
|
||||
if ($publicId) {
|
||||
Session::flash('message', trans('texts.updated_client'));
|
||||
} else {
|
||||
Activity::createClient($client);
|
||||
Session::flash('message', trans('texts.created_client'));
|
||||
}
|
||||
|
||||
return Redirect::to('clients/'.$client->public_id);
|
||||
}
|
||||
$client = $this->clientService->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.updated_client'));
|
||||
|
||||
return redirect()->to($client->getRoute());
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$count = $this->clientRepo->bulk($ids, $action);
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
$count = $this->clientService->bulk($ids, $action);
|
||||
|
||||
$message = Utils::pluralize($action.'d_client', $count);
|
||||
Session::flash('message', $message);
|
||||
|
@ -8,18 +8,21 @@ use Utils;
|
||||
use View;
|
||||
use Validator;
|
||||
use App\Models\Client;
|
||||
|
||||
use App\Services\CreditService;
|
||||
use App\Ninja\Repositories\CreditRepository;
|
||||
use App\Http\Requests\CreateCreditRequest;
|
||||
|
||||
class CreditController extends BaseController
|
||||
{
|
||||
protected $creditRepo;
|
||||
protected $CreditService;
|
||||
|
||||
public function __construct(CreditRepository $creditRepo)
|
||||
public function __construct(CreditRepository $creditRepo, CreditService $creditService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->creditRepo = $creditRepo;
|
||||
$this->creditService = $creditService;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,46 +109,20 @@ class CreditController extends BaseController
|
||||
return View::make('credit.edit', $data);
|
||||
}
|
||||
|
||||
public function store()
|
||||
public function store(CreateCreditRequest $request)
|
||||
{
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
public function update($publicId)
|
||||
{
|
||||
return $this->save($publicId);
|
||||
}
|
||||
|
||||
private function save($publicId = null)
|
||||
{
|
||||
$rules = array(
|
||||
'client' => 'required',
|
||||
'amount' => 'required|positive',
|
||||
);
|
||||
|
||||
$validator = Validator::make(Input::all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$url = $publicId ? 'credits/'.$publicId.'/edit' : 'credits/create';
|
||||
|
||||
return Redirect::to($url)
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
} else {
|
||||
$this->creditRepo->save($publicId, Input::all());
|
||||
|
||||
$message = trans('texts.created_credit');
|
||||
Session::flash('message', $message);
|
||||
|
||||
return Redirect::to('clients/'.Input::get('client'));
|
||||
}
|
||||
$credit = $this->creditRepo->save($request->input());
|
||||
|
||||
Session::flash('message', trans('texts.created_credit'));
|
||||
|
||||
return redirect()->to($credit->client->getRoute());
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$count = $this->creditRepo->bulk($ids, $action);
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
$count = $this->creditService->bulk($ids, $action);
|
||||
|
||||
if ($count > 0) {
|
||||
$message = Utils::pluralize($action.'d_credit', $count);
|
||||
|
@ -62,6 +62,7 @@ class DashboardController extends BaseController
|
||||
->get();
|
||||
|
||||
$activities = Activity::where('activities.account_id', '=', Auth::user()->account_id)
|
||||
->with('client.contacts', 'user', 'invoice', 'payment', 'credit')
|
||||
->where('activity_type_id', '>', 0)
|
||||
->orderBy('created_at', 'desc')
|
||||
->take(50)
|
||||
|
@ -58,7 +58,11 @@ class InvoiceApiController extends Controller
|
||||
{
|
||||
$data = Input::all();
|
||||
$error = null;
|
||||
|
||||
|
||||
if (isset($data['id']) || isset($data['public_id'])) {
|
||||
die("We don't yet support updating invoices");
|
||||
}
|
||||
|
||||
if (isset($data['email'])) {
|
||||
$client = Client::scope()->whereHas('contacts', function($query) use ($data) {
|
||||
$query->where('email', '=', $data['email']);
|
||||
@ -78,7 +82,7 @@ class InvoiceApiController extends Controller
|
||||
}
|
||||
$error = $this->clientRepo->getErrors($clientData);
|
||||
if (!$error) {
|
||||
$client = $this->clientRepo->save(false, $clientData, false);
|
||||
$client = $this->clientRepo->save($clientData);
|
||||
}
|
||||
}
|
||||
} else if (isset($data['client_id'])) {
|
||||
@ -108,7 +112,7 @@ class InvoiceApiController extends Controller
|
||||
} else {
|
||||
$data = self::prepareData($data, $client);
|
||||
$data['client_id'] = $client->id;
|
||||
$invoice = $this->invoiceRepo->save(false, $data, false);
|
||||
$invoice = $this->invoiceRepo->save($data);
|
||||
|
||||
if (!isset($data['id'])) {
|
||||
$invitation = Invitation::createNew();
|
||||
|
@ -14,7 +14,6 @@ use Datatable;
|
||||
use Request;
|
||||
use DropdownButton;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Invitation;
|
||||
use App\Models\Client;
|
||||
use App\Models\Account;
|
||||
use App\Models\Product;
|
||||
@ -31,21 +30,27 @@ use App\Models\Gateway;
|
||||
use App\Ninja\Mailers\ContactMailer as Mailer;
|
||||
use App\Ninja\Repositories\InvoiceRepository;
|
||||
use App\Ninja\Repositories\ClientRepository;
|
||||
use App\Events\InvoiceViewed;
|
||||
use App\Events\InvoiceInvitationWasViewed;
|
||||
use App\Events\QuoteInvitationWasViewed;
|
||||
|
||||
use App\Services\InvoiceService;
|
||||
use App\Http\Requests\SaveInvoiceRequest;
|
||||
|
||||
class InvoiceController extends BaseController
|
||||
{
|
||||
protected $mailer;
|
||||
protected $invoiceRepo;
|
||||
protected $clientRepo;
|
||||
protected $invoiceService;
|
||||
|
||||
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo)
|
||||
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->mailer = $mailer;
|
||||
$this->invoiceRepo = $invoiceRepo;
|
||||
$this->clientRepo = $clientRepo;
|
||||
$this->invoiceService = $invoiceService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
@ -53,24 +58,20 @@ class InvoiceController extends BaseController
|
||||
$data = [
|
||||
'title' => trans('texts.invoices'),
|
||||
'entityType' => ENTITY_INVOICE,
|
||||
'columns' => Utils::trans(['checkbox', 'invoice_number', 'client', 'invoice_date', 'invoice_total', 'balance_due', 'due_date', 'status', 'action']),
|
||||
'columns' => Utils::trans([
|
||||
'checkbox',
|
||||
'invoice_number',
|
||||
'client',
|
||||
'invoice_date',
|
||||
'invoice_total',
|
||||
'balance_due',
|
||||
'due_date',
|
||||
'status',
|
||||
'action'
|
||||
]),
|
||||
];
|
||||
|
||||
$recurringInvoices = Invoice::scope()->where('is_recurring', '=', true);
|
||||
|
||||
if (Session::get('show_trash:invoice')) {
|
||||
$recurringInvoices->withTrashed();
|
||||
} else {
|
||||
$recurringInvoices->join('clients', 'clients.id', '=', 'invoices.client_id')
|
||||
->where('clients.deleted_at', '=', null);
|
||||
}
|
||||
|
||||
if ($recurringInvoices->count() > 0) {
|
||||
$data['secEntityType'] = ENTITY_RECURRING_INVOICE;
|
||||
$data['secColumns'] = Utils::trans(['checkbox', 'frequency', 'client', 'start_date', 'end_date', 'invoice_total', 'action']);
|
||||
}
|
||||
|
||||
return View::make('list', $data);
|
||||
return response()->view('list', $data);
|
||||
}
|
||||
|
||||
public function getDatatable($clientPublicId = null)
|
||||
@ -100,9 +101,6 @@ class InvoiceController extends BaseController
|
||||
->addColumn('end_date', function ($model) { return Utils::fromSqlDate($model->end_date); })
|
||||
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||
->addColumn('dropdown', function ($model) {
|
||||
if ($model->is_deleted) {
|
||||
return '<div style="height:38px"/>';
|
||||
}
|
||||
|
||||
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
@ -147,12 +145,15 @@ class InvoiceController extends BaseController
|
||||
}
|
||||
|
||||
if (!Input::has('phantomjs') && !Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) {
|
||||
Activity::viewInvoice($invitation);
|
||||
Event::fire(new InvoiceViewed($invoice));
|
||||
if ($invoice->is_quote) {
|
||||
event(new QuoteInvitationWasViewed($invoice, $invitation));
|
||||
} else {
|
||||
event(new InvoiceInvitationWasViewed($invoice, $invitation));
|
||||
}
|
||||
}
|
||||
|
||||
Session::set($invitationKey, true); // track this invitation has been seen
|
||||
Session::set('invitation_key', $invitationKey); // track current invitation
|
||||
Session::put($invitationKey, true); // track this invitation has been seen
|
||||
Session::put('invitation_key', $invitationKey); // track current invitation
|
||||
|
||||
$account->loadLocalizationSettings($client);
|
||||
|
||||
@ -245,7 +246,7 @@ class InvoiceController extends BaseController
|
||||
->select('contacts.public_id')->lists('public_id');
|
||||
|
||||
if ($clone) {
|
||||
$invoice->id = null;
|
||||
$invoice->id = $invoice->public_id = null;
|
||||
$invoice->invoice_number = $account->getNextInvoiceNumber($invoice);
|
||||
$invoice->balance = $invoice->amount;
|
||||
$invoice->invoice_status_id = 0;
|
||||
@ -347,13 +348,16 @@ class InvoiceController extends BaseController
|
||||
public function create($clientPublicId = 0, $isRecurring = false)
|
||||
{
|
||||
$account = Auth::user()->account;
|
||||
$entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE;
|
||||
$clientId = null;
|
||||
|
||||
if ($clientPublicId) {
|
||||
$clientId = Client::getPrivateId($clientPublicId);
|
||||
}
|
||||
$entityType = $isRecurring ? ENTITY_RECURRING_INVOICE : ENTITY_INVOICE;
|
||||
$invoice = $account->createInvoice($entityType, $clientId);
|
||||
|
||||
$invoice = $account->createInvoice($entityType, $clientId);
|
||||
$invoice->public_id = 0;
|
||||
|
||||
$data = [
|
||||
'entityType' => $invoice->getEntityType(),
|
||||
'invoice' => $invoice,
|
||||
@ -418,50 +422,62 @@ class InvoiceController extends BaseController
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function store()
|
||||
{
|
||||
return InvoiceController::save();
|
||||
}
|
||||
|
||||
private function save($publicId = null)
|
||||
public function store(SaveInvoiceRequest $request)
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$entityType = Input::get('entityType');
|
||||
$input = json_decode(Input::get('data'));
|
||||
|
||||
if (in_array($action, ['archive', 'delete', 'mark', 'restore'])) {
|
||||
return InvoiceController::bulk($entityType);
|
||||
$invoice = $this->invoiceService->save($request->input());
|
||||
$entityType = $invoice->getEntityType();
|
||||
$message = trans("texts.created_{$entityType}");
|
||||
|
||||
// check if we created a new client with the invoice
|
||||
// TODO: replace with HistoryListener
|
||||
$input = $request->input();
|
||||
$clientPublicId = isset($input['client']['public_id']) ? $input['client']['public_id'] : false;
|
||||
if ($clientPublicId == '-1') {
|
||||
$message = $message.' '.trans('texts.and_created_client');
|
||||
$trackUrl = URL::to('clients/' . $invoice->client->public_id);
|
||||
Utils::trackViewed($invoice->client->getDisplayName(), ENTITY_CLIENT, $trackUrl);
|
||||
}
|
||||
|
||||
if ($errors = $this->invoiceRepo->getErrors($input->invoice)) {
|
||||
Session::flash('error', trans('texts.invoice_error'));
|
||||
$url = "{$entityType}s/" . ($publicId ?: 'create');
|
||||
return Redirect::to($url)->withInput()->withErrors($errors);
|
||||
} else {
|
||||
$invoice = $this->saveInvoice($publicId, $input, $entityType);
|
||||
$url = "{$entityType}s/".$invoice->public_id.'/edit';
|
||||
$message = trans($publicId ? "texts.updated_{$entityType}" : "texts.created_{$entityType}");
|
||||
Session::flash('message', $message);
|
||||
|
||||
// check if we created a new client with the invoice
|
||||
if ($input->invoice->client->public_id == '-1') {
|
||||
$message = $message.' '.trans('texts.and_created_client');
|
||||
$trackUrl = URL::to('clients/'.$invoice->client->public_id);
|
||||
Utils::trackViewed($invoice->client->getDisplayName(), ENTITY_CLIENT, $trackUrl);
|
||||
}
|
||||
|
||||
if ($action == 'clone') {
|
||||
return $this->cloneInvoice($publicId);
|
||||
} elseif ($action == 'convert') {
|
||||
return $this->convertQuote($publicId);
|
||||
} elseif ($action == 'email') {
|
||||
return $this->emailInvoice($invoice, Input::get('pdfupload'));
|
||||
}
|
||||
|
||||
Session::flash('message', $message);
|
||||
return Redirect::to($url);
|
||||
if ($action == 'email') {
|
||||
return $this->emailInvoice($invoice, Input::get('pdfupload'));
|
||||
}
|
||||
|
||||
return redirect()->to($invoice->getRoute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update(SaveInvoiceRequest $request)
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$entityType = Input::get('entityType');
|
||||
|
||||
$invoice = $this->invoiceService->save($request->input());
|
||||
$entityType = $invoice->getEntityType();
|
||||
$message = trans("texts.updated_{$entityType}");
|
||||
Session::flash('message', $message);
|
||||
|
||||
if ($action == 'clone') {
|
||||
return $this->cloneInvoice($invoice->public_id);
|
||||
} elseif ($action == 'convert') {
|
||||
return $this->convertQuote($invoice->public_id);
|
||||
} elseif ($action == 'email') {
|
||||
return $this->emailInvoice($invoice, Input::get('pdfupload'));
|
||||
}
|
||||
|
||||
return redirect()->to($invoice->getRoute());
|
||||
}
|
||||
|
||||
|
||||
private function emailInvoice($invoice, $pdfUpload)
|
||||
{
|
||||
$entityType = $invoice->getEntityType();
|
||||
@ -512,43 +528,6 @@ class InvoiceController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
private function saveInvoice($publicId, $input, $entityType)
|
||||
{
|
||||
$invoice = $input->invoice;
|
||||
|
||||
$clientData = (array) $invoice->client;
|
||||
$client = $this->clientRepo->save($invoice->client->public_id, $clientData);
|
||||
|
||||
$invoiceData = (array) $invoice;
|
||||
$invoiceData['client_id'] = $client->id;
|
||||
$invoice = $this->invoiceRepo->save($publicId, $invoiceData, $entityType);
|
||||
|
||||
$client->load('contacts');
|
||||
$sendInvoiceIds = [];
|
||||
|
||||
foreach ($client->contacts as $contact) {
|
||||
if ($contact->send_invoice || count($client->contacts) == 1) {
|
||||
$sendInvoiceIds[] = $contact->id;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($client->contacts as $contact) {
|
||||
$invitation = Invitation::scope()->whereContactId($contact->id)->whereInvoiceId($invoice->id)->first();
|
||||
|
||||
if (in_array($contact->id, $sendInvoiceIds) && !$invitation) {
|
||||
$invitation = Invitation::createNew();
|
||||
$invitation->invoice_id = $invoice->id;
|
||||
$invitation->contact_id = $contact->id;
|
||||
$invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
|
||||
$invitation->save();
|
||||
} elseif (!in_array($contact->id, $sendInvoiceIds) && $invitation) {
|
||||
$invitation->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
@ -562,17 +541,6 @@ class InvoiceController extends BaseController
|
||||
return Redirect::to("invoices/{$publicId}/edit");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update($publicId)
|
||||
{
|
||||
return InvoiceController::save($publicId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
@ -581,13 +549,12 @@ class InvoiceController extends BaseController
|
||||
*/
|
||||
public function bulk($entityType = ENTITY_INVOICE)
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$statusId = Input::get('statusId', INVOICE_STATUS_SENT);
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$count = $this->invoiceRepo->bulk($ids, $action, $statusId);
|
||||
$action = Input::get('bulk_action') ?: Input::get('action');;
|
||||
$ids = Input::get('bulk_public_id') ?: (Input::get('public_id') ?: Input::get('ids'));
|
||||
$count = $this->invoiceService->bulk($ids, $action);
|
||||
|
||||
if ($count > 0) {
|
||||
$key = $action == 'mark' ? "updated_{$entityType}" : "{$action}d_{$entityType}";
|
||||
$key = $action == 'markSent' ? "updated_{$entityType}" : "{$action}d_{$entityType}";
|
||||
$message = Utils::pluralize($key, $count);
|
||||
Session::flash('message', $message);
|
||||
}
|
||||
@ -602,7 +569,7 @@ class InvoiceController extends BaseController
|
||||
public function convertQuote($publicId)
|
||||
{
|
||||
$invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail();
|
||||
$clone = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
|
||||
$clone = $this->invoiceService->approveQuote($invoice);
|
||||
|
||||
Session::flash('message', trans('texts.converted_to_invoice'));
|
||||
return Redirect::to('invoices/'.$clone->public_id);
|
||||
@ -610,15 +577,6 @@ class InvoiceController extends BaseController
|
||||
|
||||
public function cloneInvoice($publicId)
|
||||
{
|
||||
/*
|
||||
$invoice = Invoice::with('invoice_items')->scope($publicId)->firstOrFail();
|
||||
$clone = $this->invoiceRepo->cloneInvoice($invoice);
|
||||
$entityType = $invoice->getEntityType();
|
||||
|
||||
Session::flash('message', trans('texts.cloned_invoice'));
|
||||
return Redirect::to("{$entityType}s/" . $clone->public_id);
|
||||
*/
|
||||
|
||||
return self::edit($publicId, true);
|
||||
}
|
||||
|
||||
@ -636,7 +594,7 @@ class InvoiceController extends BaseController
|
||||
->where('activity_type_id', '=', $activityTypeId)
|
||||
->where('invoice_id', '=', $invoice->id)
|
||||
->orderBy('id', 'desc')
|
||||
->get(['id', 'created_at', 'user_id', 'json_backup', 'message']);
|
||||
->get(['id', 'created_at', 'user_id', 'json_backup']);
|
||||
|
||||
$versionsJson = [];
|
||||
$versionsSelect = [];
|
||||
@ -651,7 +609,7 @@ class InvoiceController extends BaseController
|
||||
$backup->account = $invoice->account->toArray();
|
||||
|
||||
$versionsJson[$activity->id] = $backup;
|
||||
$key = Utils::timestampToDateTimeString(strtotime($activity->created_at)) . ' - ' . Utils::decodeActivity($activity->message);
|
||||
$key = Utils::timestampToDateTimeString(strtotime($activity->created_at)) . ' - ' . $activity->user->getDisplayName();
|
||||
$versionsSelect[$lastId ? $lastId : 0] = $key;
|
||||
$lastId = $activity->id;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class PaymentApiController extends Controller
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$payment = $this->paymentRepo->save(false, $data);
|
||||
$payment = $this->paymentRepo->save($data);
|
||||
$payment = Payment::scope($payment->public_id)->with('client', 'contact', 'user', 'invoice')->first();
|
||||
|
||||
$payment = Utils::remapPublicIds([$payment]);
|
||||
|
@ -25,6 +25,9 @@ use App\Ninja\Repositories\AccountRepository;
|
||||
use App\Ninja\Mailers\ContactMailer;
|
||||
use App\Services\PaymentService;
|
||||
|
||||
use App\Http\Requests\CreatePaymentRequest;
|
||||
use App\Http\Requests\UpdatePaymentRequest;
|
||||
|
||||
class PaymentController extends BaseController
|
||||
{
|
||||
public function __construct(PaymentRepository $paymentRepo, InvoiceRepository $invoiceRepo, AccountRepository $accountRepo, ContactMailer $contactMailer, PaymentService $paymentService)
|
||||
@ -68,7 +71,7 @@ class PaymentController extends BaseController
|
||||
return $table->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||
->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); })
|
||||
->addColumn('dropdown', function ($model) {
|
||||
if ($model->is_deleted || $model->invoice_is_deleted) {
|
||||
if ($model->invoice_is_deleted) {
|
||||
return '<div style="height:38px"/>';
|
||||
}
|
||||
|
||||
@ -86,6 +89,10 @@ class PaymentController extends BaseController
|
||||
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans('texts.restore_payment').'</a></li>';
|
||||
}
|
||||
|
||||
if ($model->is_deleted) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
return $str.'<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans('texts.delete_payment').'</a></li></ul>
|
||||
</div>';
|
||||
})
|
||||
@ -175,7 +182,9 @@ class PaymentController extends BaseController
|
||||
|
||||
// Handle offsite payments
|
||||
if ($useToken || $paymentType != PAYMENT_TYPE_CREDIT_CARD
|
||||
|| $gateway->id == GATEWAY_EWAY || $gateway->id == GATEWAY_TWO_CHECKOUT) {
|
||||
|| $gateway->id == GATEWAY_EWAY
|
||||
|| $gateway->id == GATEWAY_TWO_CHECKOUT
|
||||
|| $gateway->id == GATEWAY_PAYFAST) {
|
||||
if (Session::has('error')) {
|
||||
Session::reflash();
|
||||
return Redirect::to('view/'.$invitationKey);
|
||||
@ -442,6 +451,8 @@ class PaymentController extends BaseController
|
||||
$ref = $response->getData()['AccessCode'];
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_TWO_CHECKOUT) {
|
||||
$ref = $response->getData()['cart_order_id'];
|
||||
} elseif ($accountGateway->gateway_id == GATEWAY_PAYFAST) {
|
||||
$ref = $response->getData()['m_payment_id'];
|
||||
} else {
|
||||
$ref = $response->getTransactionReference();
|
||||
}
|
||||
@ -540,49 +551,36 @@ class PaymentController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
public function store()
|
||||
public function store(CreatePaymentRequest $request)
|
||||
{
|
||||
return $this->save();
|
||||
}
|
||||
$input = $request->input();
|
||||
$payment = $this->paymentRepo->save($input);
|
||||
|
||||
public function update($publicId)
|
||||
{
|
||||
return $this->save($publicId);
|
||||
}
|
||||
|
||||
private function save($publicId = null)
|
||||
{
|
||||
if (!$publicId && $errors = $this->paymentRepo->getErrors(Input::all())) {
|
||||
$url = $publicId ? 'payments/'.$publicId.'/edit' : 'payments/create';
|
||||
|
||||
return Redirect::to($url)
|
||||
->withErrors($errors)
|
||||
->withInput();
|
||||
if (Input::get('email_receipt')) {
|
||||
$this->contactMailer->sendPaymentConfirmation($payment);
|
||||
Session::flash('message', trans('texts.created_payment_emailed_client'));
|
||||
} else {
|
||||
$payment = $this->paymentRepo->save($publicId, Input::all());
|
||||
|
||||
if ($publicId) {
|
||||
Session::flash('message', trans('texts.updated_payment'));
|
||||
|
||||
return Redirect::to('payments/');
|
||||
} else {
|
||||
if (Input::get('email_receipt')) {
|
||||
$this->contactMailer->sendPaymentConfirmation($payment);
|
||||
Session::flash('message', trans('texts.created_payment_emailed_client'));
|
||||
} else {
|
||||
Session::flash('message', trans('texts.created_payment'));
|
||||
}
|
||||
|
||||
return Redirect::to('clients/'.Input::get('client'));
|
||||
}
|
||||
Session::flash('message', trans('texts.created_payment'));
|
||||
}
|
||||
|
||||
return redirect()->to($payment->client->getRoute());
|
||||
}
|
||||
|
||||
public function update(UpdatePaymentRequest $request)
|
||||
{
|
||||
$input = $request->input();
|
||||
$payment = $this->paymentRepo->save($input);
|
||||
|
||||
Session::flash('message', trans('texts.updated_payment'));
|
||||
|
||||
return redirect()->to($payment->getRoute());
|
||||
}
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$count = $this->paymentRepo->bulk($ids, $action);
|
||||
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
|
||||
$count = $this->paymentService->bulk($ids, $action);
|
||||
|
||||
if ($count > 0) {
|
||||
$message = Utils::pluralize($action.'d_payment', $count);
|
||||
|
@ -8,16 +8,18 @@ use Datatable;
|
||||
use App\Models\Invitation;
|
||||
use App\Ninja\Repositories\InvoiceRepository;
|
||||
use App\Ninja\Repositories\PaymentRepository;
|
||||
use App\Ninja\Repositories\ActivityRepository;
|
||||
|
||||
class PublicClientController extends BaseController
|
||||
{
|
||||
private $invoiceRepo;
|
||||
private $paymentRepo;
|
||||
|
||||
public function __construct(InvoiceRepository $invoiceRepo, PaymentRepository $paymentRepo)
|
||||
public function __construct(InvoiceRepository $invoiceRepo, PaymentRepository $paymentRepo, ActivityRepository $activityRepo)
|
||||
{
|
||||
$this->invoiceRepo = $invoiceRepo;
|
||||
$this->paymentRepo = $paymentRepo;
|
||||
$this->activityRepo = $activityRepo;
|
||||
}
|
||||
|
||||
public function dashboard()
|
||||
@ -47,15 +49,22 @@ class PublicClientController extends BaseController
|
||||
}
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
$query = DB::table('activities')
|
||||
->join('clients', 'clients.id', '=', 'activities.client_id')
|
||||
->where('activities.client_id', '=', $invoice->client_id)
|
||||
->where('activities.adjustment', '!=', 0)
|
||||
->select('activities.id', 'activities.message', 'activities.created_at', 'clients.currency_id', 'activities.balance', 'activities.adjustment');
|
||||
$query = $this->activityRepo->findByClientId($invoice->client_id);
|
||||
$query->where('activities.adjustment', '!=', 0);
|
||||
|
||||
return Datatable::query($query)
|
||||
->addColumn('activities.id', function ($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
||||
->addColumn('message', function ($model) { return strip_tags(Utils::decodeActivity($model->message)); })
|
||||
->addColumn('message', function ($model) {
|
||||
$data = [
|
||||
'client' => Utils::getClientDisplayName($model),
|
||||
'user' => $model->is_system ? ('<i>' . trans('texts.system') . '</i>') : ($model->user_first_name . ' ' . $model->user_last_name),
|
||||
'invoice' => trans('texts.invoice') . ' ' . $model->invoice,
|
||||
'contact' => Utils::getClientDisplayName($model),
|
||||
'payment' => trans('texts.payment') . ($model->payment ? ' ' . $model->payment : ''),
|
||||
];
|
||||
|
||||
return trans("texts.activity_{$model->activity_type_id}", $data);
|
||||
})
|
||||
->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||
->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id) : ''; })
|
||||
->make();
|
||||
|
@ -24,24 +24,24 @@ use App\Models\Invoice;
|
||||
use App\Ninja\Mailers\ContactMailer as Mailer;
|
||||
use App\Ninja\Repositories\InvoiceRepository;
|
||||
use App\Ninja\Repositories\ClientRepository;
|
||||
use App\Ninja\Repositories\TaxRateRepository;
|
||||
use App\Events\QuoteApproved;
|
||||
use App\Events\QuoteInvitationWasApproved;
|
||||
use App\Services\InvoiceService;
|
||||
|
||||
class QuoteController extends BaseController
|
||||
{
|
||||
protected $mailer;
|
||||
protected $invoiceRepo;
|
||||
protected $clientRepo;
|
||||
protected $taxRateRepo;
|
||||
protected $invoiceService;
|
||||
|
||||
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, TaxRateRepository $taxRateRepo)
|
||||
public function __construct(Mailer $mailer, InvoiceRepository $invoiceRepo, ClientRepository $clientRepo, InvoiceService $invoiceService)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->mailer = $mailer;
|
||||
$this->invoiceRepo = $invoiceRepo;
|
||||
$this->clientRepo = $clientRepo;
|
||||
$this->taxRateRepo = $taxRateRepo;
|
||||
$this->invoiceService = $invoiceService;
|
||||
}
|
||||
|
||||
public function index()
|
||||
@ -53,18 +53,19 @@ class QuoteController extends BaseController
|
||||
$data = [
|
||||
'title' => trans('texts.quotes'),
|
||||
'entityType' => ENTITY_QUOTE,
|
||||
'columns' => Utils::trans(['checkbox', 'quote_number', 'client', 'quote_date', 'quote_total', 'valid_until', 'status', 'action']),
|
||||
'columns' => Utils::trans([
|
||||
'checkbox',
|
||||
'quote_number',
|
||||
'client',
|
||||
'quote_date',
|
||||
'quote_total',
|
||||
'valid_until',
|
||||
'status',
|
||||
'action'
|
||||
]),
|
||||
];
|
||||
|
||||
/*
|
||||
if (Invoice::scope()->where('is_recurring', '=', true)->count() > 0)
|
||||
{
|
||||
$data['secEntityType'] = ENTITY_RECURRING_INVOICE;
|
||||
$data['secColumns'] = Utils::trans(['checkbox', 'frequency', 'client', 'start_date', 'end_date', 'quote_total', 'action']);
|
||||
}
|
||||
*/
|
||||
|
||||
return View::make('list', $data);
|
||||
return response()->view('list', $data);
|
||||
}
|
||||
|
||||
public function getDatatable($clientPublicId = null)
|
||||
@ -87,7 +88,8 @@ class QuoteController extends BaseController
|
||||
$clientId = Client::getPrivateId($clientPublicId);
|
||||
}
|
||||
$invoice = $account->createInvoice(ENTITY_QUOTE, $clientId);
|
||||
|
||||
$invoice->public_id = 0;
|
||||
|
||||
$data = [
|
||||
'entityType' => $invoice->getEntityType(),
|
||||
'invoice' => $invoice,
|
||||
@ -123,22 +125,21 @@ class QuoteController extends BaseController
|
||||
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$action = Input::get('bulk_action') ?: Input::get('action');;
|
||||
|
||||
if ($action == 'convert') {
|
||||
$invoice = Invoice::with('invoice_items')->scope(Input::get('id'))->firstOrFail();
|
||||
$clone = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
|
||||
$clone = $this->invoiceService->approveQuote($invoice);
|
||||
|
||||
Session::flash('message', trans('texts.converted_to_invoice'));
|
||||
return Redirect::to('invoices/'.$clone->public_id);
|
||||
}
|
||||
|
||||
$statusId = Input::get('statusId');
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$count = $this->invoiceRepo->bulk($ids, $action, $statusId);
|
||||
|
||||
$ids = Input::get('bulk_public_id') ?: (Input::get('public_id') ?: Input::get('ids'));
|
||||
$count = $this->invoiceService->bulk($ids, $action);
|
||||
|
||||
if ($count > 0) {
|
||||
$key = $action == 'mark' ? "updated_quote" : "{$action}d_quote";
|
||||
$key = $action == 'markSent' ? "updated_quote" : "{$action}d_quote";
|
||||
$message = Utils::pluralize($key, $count);
|
||||
Session::flash('message', $message);
|
||||
}
|
||||
@ -155,19 +156,8 @@ class QuoteController extends BaseController
|
||||
$invitation = Invitation::with('invoice.invoice_items', 'invoice.invitations')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
if ($invoice->is_quote && !$invoice->quote_invoice_id) {
|
||||
Event::fire(new QuoteApproved($invoice));
|
||||
Activity::approveQuote($invitation);
|
||||
|
||||
$invoice = $this->invoiceRepo->cloneInvoice($invoice, $invoice->id);
|
||||
Session::flash('message', trans('texts.converted_to_invoice'));
|
||||
|
||||
foreach ($invoice->invitations as $invitationClone) {
|
||||
if ($invitation->contact_id == $invitationClone->contact_id) {
|
||||
$invitationKey = $invitationClone->invitation_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
$invitationKey = $this->invoiceService->approveQuote($invoice, $invitation);
|
||||
Session::flash('message', trans('texts.converted_to_invoice'));
|
||||
|
||||
return Redirect::to("view/{$invitationKey}");
|
||||
}
|
||||
|
36
app/Http/Controllers/RecurringInvoiceController.php
Normal file
36
app/Http/Controllers/RecurringInvoiceController.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php namespace App\Http\Controllers;
|
||||
|
||||
use Utils;
|
||||
use App\Ninja\Repositories\InvoiceRepository;
|
||||
|
||||
class RecurringInvoiceController extends BaseController
|
||||
{
|
||||
protected $invoiceRepo;
|
||||
|
||||
public function __construct(InvoiceRepository $invoiceRepo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->invoiceRepo = $invoiceRepo;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data = [
|
||||
'title' => trans('texts.recurring_invoices'),
|
||||
'entityType' => ENTITY_RECURRING_INVOICE,
|
||||
'columns' => Utils::trans([
|
||||
'checkbox',
|
||||
'frequency',
|
||||
'client',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'invoice_total',
|
||||
'action'
|
||||
])
|
||||
];
|
||||
|
||||
return response()->view('list', $data);
|
||||
}
|
||||
|
||||
}
|
@ -156,7 +156,7 @@ class TaskController extends BaseController
|
||||
*/
|
||||
public function edit($publicId)
|
||||
{
|
||||
$task = Task::scope($publicId)->with('client', 'invoice')->firstOrFail();
|
||||
$task = Task::scope($publicId)->with('client', 'invoice')->withTrashed()->firstOrFail();
|
||||
|
||||
$actions = [];
|
||||
if ($task->invoice) {
|
||||
@ -240,7 +240,7 @@ class TaskController extends BaseController
|
||||
public function bulk()
|
||||
{
|
||||
$action = Input::get('action');
|
||||
$ids = Input::get('id') ? Input::get('id') : Input::get('ids');
|
||||
$ids = Input::get('public_id') ?: (Input::get('id') ?: Input::get('ids'));
|
||||
|
||||
if ($action == 'stop') {
|
||||
$this->taskRepo->save($ids, ['action' => $action]);
|
||||
|
@ -145,13 +145,9 @@ class TokenController extends BaseController
|
||||
if ($tokenPublicId) {
|
||||
$token->name = trim(Input::get('name'));
|
||||
} else {
|
||||
$lastToken = AccountToken::withTrashed()->where('account_id', '=', Auth::user()->account_id)
|
||||
->orderBy('public_id', 'DESC')->first();
|
||||
|
||||
$token = AccountToken::createNew();
|
||||
$token->name = trim(Input::get('name'));
|
||||
$token->token = str_random(RANDOM_KEY_LENGTH);
|
||||
$token->public_id = $lastToken ? $lastToken->public_id + 1 : 1;
|
||||
}
|
||||
|
||||
$token->save();
|
||||
|
@ -34,6 +34,12 @@ class VerifyCsrfToken extends BaseVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->is('login')) {
|
||||
if (env(API_SECRET) && $request->api_secret === env(API_SECRET)) {
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::handle($request, $next);
|
||||
}
|
||||
|
||||
|
44
app/Http/Requests/CreateClientRequest.php
Normal file
44
app/Http/Requests/CreateClientRequest.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class CreateClientRequest 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 [
|
||||
'contacts' => 'valid_contacts',
|
||||
];
|
||||
}
|
||||
|
||||
public function validator($factory)
|
||||
{
|
||||
// support submiting the form with a single client record
|
||||
$input = $this->input();
|
||||
if (isset($input['contact'])) {
|
||||
$input['contacts'] = [$input['contact']];
|
||||
unset($input['contact']);
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
return $factory->make(
|
||||
$this->input(), $this->container->call([$this, 'rules']), $this->messages()
|
||||
);
|
||||
}
|
||||
}
|
30
app/Http/Requests/CreateCreditRequest.php
Normal file
30
app/Http/Requests/CreateCreditRequest.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class CreateCreditRequest 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 [
|
||||
'client' => 'required',
|
||||
'amount' => 'required|positive',
|
||||
];
|
||||
}
|
||||
}
|
44
app/Http/Requests/CreatePaymentRequest.php
Normal file
44
app/Http/Requests/CreatePaymentRequest.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
use App\Models\Invoice;
|
||||
|
||||
class CreatePaymentRequest 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()
|
||||
{
|
||||
$input = $this->input();
|
||||
$rules = array(
|
||||
'client' => 'required',
|
||||
'invoice' => 'required',
|
||||
'amount' => 'required',
|
||||
);
|
||||
|
||||
if ($input['payment_type_id'] == PAYMENT_TYPE_CREDIT) {
|
||||
$rules['payment_type_id'] = 'has_credit:'.$input['client'].','.$input['amount'];
|
||||
}
|
||||
|
||||
if (isset($input['invoice']) && $input['invoice']) {
|
||||
$invoice = Invoice::scope($input['invoice'])->firstOrFail();
|
||||
$rules['amount'] .= "|less_than:{$invoice->balance}";
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
44
app/Http/Requests/SaveInvoiceRequest.php
Normal file
44
app/Http/Requests/SaveInvoiceRequest.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
use App\Models\Invoice;
|
||||
|
||||
class SaveInvoiceRequest 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()
|
||||
{
|
||||
$publicId = Request::get('public_id');
|
||||
$invoiceId = $publicId ? Invoice::getPrivateId($publicId) : '';
|
||||
|
||||
$rules = [
|
||||
'client.contacts' => 'valid_contacts',
|
||||
'invoice_number' => 'required|unique:invoices,invoice_number,'.$invoiceId.',id,account_id,'.Auth::user()->account_id,
|
||||
'discount' => 'positive',
|
||||
];
|
||||
|
||||
/* There's a problem parsing the dates
|
||||
if (Request::get('is_recurring') && Request::get('start_date') && Request::get('end_date')) {
|
||||
$rules['end_date'] = 'after' . Request::get('start_date');
|
||||
}
|
||||
*/
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
29
app/Http/Requests/UpdateClientRequest.php
Normal file
29
app/Http/Requests/UpdateClientRequest.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
|
||||
class UpdateClientRequest 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 [
|
||||
'contacts' => 'valid_contacts',
|
||||
];
|
||||
}
|
||||
}
|
28
app/Http/Requests/UpdatePaymentRequest.php
Normal file
28
app/Http/Requests/UpdatePaymentRequest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php namespace app\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Illuminate\Validation\Factory;
|
||||
use App\Models\Invoice;
|
||||
|
||||
class UpdatePaymentRequest 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 [];
|
||||
}
|
||||
}
|
@ -155,8 +155,10 @@ Route::group(['middleware' => 'auth'], function() {
|
||||
Route::get('api/invoices/{client_id?}', array('as'=>'api.invoices', 'uses'=>'InvoiceController@getDatatable'));
|
||||
Route::get('invoices/create/{client_id?}', 'InvoiceController@create');
|
||||
Route::get('recurring_invoices/create/{client_id?}', 'InvoiceController@createRecurring');
|
||||
Route::get('recurring_invoices', 'RecurringInvoiceController@index');
|
||||
Route::get('invoices/{public_id}/clone', 'InvoiceController@cloneInvoice');
|
||||
Route::post('invoices/bulk', 'InvoiceController@bulk');
|
||||
Route::post('recurring_invoices/bulk', 'InvoiceController@bulk');
|
||||
|
||||
Route::get('quotes/create/{client_id?}', 'QuoteController@create');
|
||||
Route::get('quotes/{public_id}/clone', 'InvoiceController@cloneInvoice');
|
||||
@ -188,6 +190,7 @@ Route::group(['middleware' => 'auth'], function() {
|
||||
Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
|
||||
{
|
||||
Route::resource('ping', 'ClientApiController@ping');
|
||||
Route::get('accounts', 'AccountApiController@index');
|
||||
Route::resource('clients', 'ClientApiController');
|
||||
Route::get('quotes/{client_id?}', 'QuoteApiController@index');
|
||||
Route::resource('quotes', 'QuoteApiController');
|
||||
@ -274,6 +277,9 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('ACCOUNT_API_TOKENS', 'api_tokens');
|
||||
define('ACCOUNT_CUSTOMIZE_DESIGN', 'customize_design');
|
||||
|
||||
define('ACTION_RESTORE', 'restore');
|
||||
define('ACTION_ARCHIVE', 'archive');
|
||||
define('ACTION_DELETE', 'delete');
|
||||
|
||||
define('ACTIVITY_TYPE_CREATE_CLIENT', 1);
|
||||
define('ACTIVITY_TYPE_ARCHIVE_CLIENT', 2);
|
||||
@ -287,12 +293,12 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('ACTIVITY_TYPE_DELETE_INVOICE', 9);
|
||||
|
||||
define('ACTIVITY_TYPE_CREATE_PAYMENT', 10);
|
||||
define('ACTIVITY_TYPE_UPDATE_PAYMENT', 11);
|
||||
//define('ACTIVITY_TYPE_UPDATE_PAYMENT', 11);
|
||||
define('ACTIVITY_TYPE_ARCHIVE_PAYMENT', 12);
|
||||
define('ACTIVITY_TYPE_DELETE_PAYMENT', 13);
|
||||
|
||||
define('ACTIVITY_TYPE_CREATE_CREDIT', 14);
|
||||
define('ACTIVITY_TYPE_UPDATE_CREDIT', 15);
|
||||
//define('ACTIVITY_TYPE_UPDATE_CREDIT', 15);
|
||||
define('ACTIVITY_TYPE_ARCHIVE_CREDIT', 16);
|
||||
define('ACTIVITY_TYPE_DELETE_CREDIT', 17);
|
||||
|
||||
@ -376,6 +382,7 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('GATEWAY_AUTHORIZE_NET', 1);
|
||||
define('GATEWAY_EWAY', 4);
|
||||
define('GATEWAY_AUTHORIZE_NET_SIM', 2);
|
||||
define('GATEWAY_PAYFAST', 13);
|
||||
define('GATEWAY_PAYPAL_EXPRESS', 17);
|
||||
define('GATEWAY_PAYPAL_PRO', 18);
|
||||
define('GATEWAY_STRIPE', 23);
|
||||
@ -399,7 +406,7 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('NINJA_GATEWAY_CONFIG', 'NINJA_GATEWAY_CONFIG');
|
||||
define('NINJA_WEB_URL', 'https://www.invoiceninja.com');
|
||||
define('NINJA_APP_URL', 'https://app.invoiceninja.com');
|
||||
define('NINJA_VERSION', '2.4.3');
|
||||
define('NINJA_VERSION', '2.4.5');
|
||||
define('NINJA_DATE', '2000-01-01');
|
||||
|
||||
define('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com');
|
||||
@ -409,7 +416,8 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('PDFMAKE_DOCS', 'http://pdfmake.org/playground.html');
|
||||
define('PHANTOMJS_CLOUD', 'http://api.phantomjscloud.com/single/browser/v1/');
|
||||
define('PHP_DATE_FORMATS', 'http://php.net/manual/en/function.date.php');
|
||||
define('REFERRAL_PROGRAM_URL', false);
|
||||
define('GITTER_ROOM', 'hillelcoren/invoice-ninja');
|
||||
define('REFERRAL_PROGRAM_URL', 'https://www.invoiceninja.com/affiliates/');
|
||||
|
||||
define('COUNT_FREE_DESIGNS', 4);
|
||||
define('COUNT_FREE_DESIGNS_SELF_HOST', 5); // include the custom design
|
||||
@ -431,6 +439,7 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
|
||||
define('TEST_USERNAME', 'user@example.com');
|
||||
define('TEST_PASSWORD', 'password');
|
||||
define('API_SECRET', 'API_SECRET');
|
||||
|
||||
define('TOKEN_BILLING_DISABLED', 1);
|
||||
define('TOKEN_BILLING_OPT_IN', 2);
|
||||
|
@ -65,6 +65,25 @@ class Utils
|
||||
return isset($_ENV['NINJA_DEV']) && $_ENV['NINJA_DEV'] == 'true';
|
||||
}
|
||||
|
||||
public static function isOAuthEnabled()
|
||||
{
|
||||
$providers = [
|
||||
SOCIAL_GOOGLE,
|
||||
SOCIAL_FACEBOOK,
|
||||
SOCIAL_GITHUB,
|
||||
SOCIAL_LINKEDIN
|
||||
];
|
||||
|
||||
foreach ($providers as $provider) {
|
||||
$key = strtoupper($provider) . '_CLIENT_ID';
|
||||
if (isset($_ENV[$key]) && $_ENV[$key]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function allowNewAccounts()
|
||||
{
|
||||
return Utils::isNinja() || Auth::check();
|
||||
@ -496,32 +515,15 @@ class Utils
|
||||
}
|
||||
}
|
||||
|
||||
public static function encodeActivity($person = null, $action, $entity = null, $otherPerson = null)
|
||||
public static function getPersonDisplayName($firstName, $lastName, $email)
|
||||
{
|
||||
$person = $person ? $person->getDisplayName() : '<i>System</i>';
|
||||
$entity = $entity ? $entity->getActivityKey() : '';
|
||||
$otherPerson = $otherPerson ? 'to '.$otherPerson->getDisplayName() : '';
|
||||
$token = Session::get('token_id') ? ' ('.trans('texts.token').')' : '';
|
||||
|
||||
return trim("$person $token $action $entity $otherPerson");
|
||||
}
|
||||
|
||||
public static function decodeActivity($message)
|
||||
{
|
||||
$pattern = '/\[([\w]*):([\d]*):(.*)\]/i';
|
||||
preg_match($pattern, $message, $matches);
|
||||
|
||||
if (count($matches) > 0) {
|
||||
$match = $matches[0];
|
||||
$type = $matches[1];
|
||||
$publicId = $matches[2];
|
||||
$name = $matches[3];
|
||||
|
||||
$link = link_to($type.'s/'.$publicId, $name);
|
||||
$message = str_replace($match, "$type $link", $message);
|
||||
if ($firstName || $lastName) {
|
||||
return $firstName.' '.$lastName;
|
||||
} elseif ($email) {
|
||||
return $email;
|
||||
} else {
|
||||
return trans('texts.guest');
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
public static function generateLicense()
|
||||
@ -598,7 +600,7 @@ class Utils
|
||||
foreach ($data as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
if ($key == 'account' || isset($mapped[$key])) {
|
||||
unset($data[$key]);
|
||||
// do nothing
|
||||
} else {
|
||||
$mapped[$key] = true;
|
||||
$data[$key] = Utils::hideIds($val, $mapped);
|
||||
@ -795,4 +797,43 @@ class Utils
|
||||
$adjustment = Utils::formatMoney($adjustment, $currencyId);
|
||||
return "<h4><div class=\"label label-{$class}\">$adjustment</div></h4>";
|
||||
}
|
||||
|
||||
public static function copyContext($entity1, $entity2)
|
||||
{
|
||||
if (!$entity2) {
|
||||
return $entity1;
|
||||
}
|
||||
|
||||
$fields = [
|
||||
'contact_id',
|
||||
'payment_id',
|
||||
'invoice_id',
|
||||
'credit_id',
|
||||
'invitation_id'
|
||||
];
|
||||
|
||||
$fields1 = $entity1->getAttributes();
|
||||
$fields2 = $entity2->getAttributes();
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (isset($fields2[$field]) && $fields2[$field]) {
|
||||
$entity1->$field = $entity2->$field;
|
||||
}
|
||||
}
|
||||
|
||||
return $entity1;
|
||||
}
|
||||
|
||||
public static function withinPastYear($date)
|
||||
{
|
||||
if (!$date || $date == '0000-00-00') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$today = new DateTime('now');
|
||||
$datePaid = DateTime::createFromFormat('Y-m-d', $date);
|
||||
$interval = $today->diff($date);
|
||||
|
||||
return $interval->y == 0;
|
||||
}
|
||||
}
|
||||
|
335
app/Listeners/ActivityListener.php
Normal file
335
app/Listeners/ActivityListener.php
Normal file
@ -0,0 +1,335 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Events\ClientWasCreated;
|
||||
use App\Events\ClientWasDeleted;
|
||||
use App\Events\ClientWasArchived;
|
||||
use App\Events\ClientWasRestored;
|
||||
use App\Events\InvoiceWasCreated;
|
||||
use App\Events\InvoiceWasUpdated;
|
||||
use App\Events\InvoiceWasDeleted;
|
||||
use App\Events\InvoiceWasArchived;
|
||||
use App\Events\InvoiceWasRestored;
|
||||
use App\Events\InvoiceInvitationWasEmailed;
|
||||
use App\Events\InvoiceInvitationWasViewed;
|
||||
use App\Events\QuoteWasCreated;
|
||||
use App\Events\QuoteWasUpdated;
|
||||
use App\Events\QuoteWasDeleted;
|
||||
use App\Events\QuoteWasArchived;
|
||||
use App\Events\QuoteWasRestored;
|
||||
use App\Events\QuoteInvitationWasEmailed;
|
||||
use App\Events\QuoteInvitationWasViewed;
|
||||
use App\Events\QuoteInvitationWasApproved;
|
||||
use App\Events\PaymentWasCreated;
|
||||
use App\Events\PaymentWasDeleted;
|
||||
use App\Events\PaymentWasArchived;
|
||||
use App\Events\PaymentWasRestored;
|
||||
use App\Events\CreditWasCreated;
|
||||
use App\Events\CreditWasDeleted;
|
||||
use App\Events\CreditWasArchived;
|
||||
use App\Events\CreditWasRestored;
|
||||
use App\Ninja\Repositories\ActivityRepository;
|
||||
|
||||
class ActivityListener
|
||||
{
|
||||
protected $activityRepo;
|
||||
|
||||
public function __construct(ActivityRepository $activityRepo)
|
||||
{
|
||||
$this->activityRepo = $activityRepo;
|
||||
}
|
||||
|
||||
// Clients
|
||||
public function createdClient(ClientWasCreated $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->client,
|
||||
ACTIVITY_TYPE_CREATE_CLIENT
|
||||
);
|
||||
}
|
||||
|
||||
public function deletedClient(ClientWasDeleted $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->client,
|
||||
ACTIVITY_TYPE_DELETE_CLIENT
|
||||
);
|
||||
}
|
||||
|
||||
public function archivedClient(ClientWasArchived $event)
|
||||
{
|
||||
if ($event->client->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activityRepo->create(
|
||||
$event->client,
|
||||
ACTIVITY_TYPE_ARCHIVE_CLIENT
|
||||
);
|
||||
}
|
||||
|
||||
public function restoredClient(ClientWasRestored $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->client,
|
||||
ACTIVITY_TYPE_RESTORE_CLIENT
|
||||
);
|
||||
}
|
||||
|
||||
// Invoices
|
||||
public function createdInvoice(InvoiceWasCreated $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->invoice,
|
||||
ACTIVITY_TYPE_CREATE_INVOICE,
|
||||
$event->invoice->getAdjustment()
|
||||
);
|
||||
}
|
||||
|
||||
public function updatedInvoice(InvoiceWasUpdated $event)
|
||||
{
|
||||
if (! $event->invoice->isChanged()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$backupInvoice = Invoice::with('invoice_items', 'client.account', 'client.contacts')->find($event->invoice->id);
|
||||
|
||||
$activity = $this->activityRepo->create(
|
||||
$event->invoice,
|
||||
ACTIVITY_TYPE_UPDATE_INVOICE,
|
||||
$event->invoice->getAdjustment()
|
||||
);
|
||||
|
||||
$activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON();
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public function deletedInvoice(InvoiceWasDeleted $event)
|
||||
{
|
||||
$invoice = $event->invoice;
|
||||
|
||||
$this->activityRepo->create(
|
||||
$invoice,
|
||||
ACTIVITY_TYPE_DELETE_INVOICE,
|
||||
$invoice->affectsBalance() ? $invoice->balance * -1 : 0,
|
||||
$invoice->affectsBalance() ? $invoice->getAmountPaid() * -1 : 0
|
||||
);
|
||||
}
|
||||
|
||||
public function archivedInvoice(InvoiceWasArchived $event)
|
||||
{
|
||||
if ($event->invoice->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activityRepo->create(
|
||||
$event->invoice,
|
||||
ACTIVITY_TYPE_ARCHIVE_INVOICE
|
||||
);
|
||||
}
|
||||
|
||||
public function restoredInvoice(InvoiceWasRestored $event)
|
||||
{
|
||||
$invoice = $event->invoice;
|
||||
|
||||
$this->activityRepo->create(
|
||||
$invoice,
|
||||
ACTIVITY_TYPE_RESTORE_INVOICE,
|
||||
$invoice->affectsBalance() && $event->fromDeleted ? $invoice->balance : 0,
|
||||
$invoice->affectsBalance() && $event->fromDeleted ? $invoice->getAmountPaid() : 0
|
||||
);
|
||||
}
|
||||
|
||||
public function emailedInvoice(InvoiceInvitationWasEmailed $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->invitation->invoice,
|
||||
ACTIVITY_TYPE_EMAIL_INVOICE,
|
||||
false,
|
||||
false,
|
||||
$event->invitation
|
||||
);
|
||||
}
|
||||
|
||||
public function viewedInvoice(InvoiceInvitationWasViewed $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->invoice,
|
||||
ACTIVITY_TYPE_VIEW_INVOICE,
|
||||
false,
|
||||
false,
|
||||
$event->invitation
|
||||
);
|
||||
}
|
||||
|
||||
// Quotes
|
||||
public function createdQuote(QuoteWasCreated $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->quote,
|
||||
ACTIVITY_TYPE_CREATE_QUOTE
|
||||
);
|
||||
}
|
||||
|
||||
public function updatedQuote(QuoteWasUpdated $event)
|
||||
{
|
||||
if (! $event->quote->isChanged()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$backupQuote = Invoice::with('invoice_items', 'client.account', 'client.contacts')->find($event->quote->id);
|
||||
|
||||
$activity = $this->activityRepo->create(
|
||||
$event->quote,
|
||||
ACTIVITY_TYPE_UPDATE_QUOTE
|
||||
);
|
||||
|
||||
$activity->json_backup = $backupQuote->hidePrivateFields()->toJSON();
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public function deletedQuote(QuoteWasDeleted $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->quote,
|
||||
ACTIVITY_TYPE_DELETE_QUOTE
|
||||
);
|
||||
}
|
||||
|
||||
public function archivedQuote(QuoteWasArchived $event)
|
||||
{
|
||||
if ($event->quote->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activityRepo->create(
|
||||
$event->quote,
|
||||
ACTIVITY_TYPE_ARCHIVE_QUOTE
|
||||
);
|
||||
}
|
||||
|
||||
public function restoredQuote(QuoteWasRestored $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->quote,
|
||||
ACTIVITY_TYPE_RESTORE_QUOTE
|
||||
);
|
||||
}
|
||||
|
||||
public function emailedQuote(QuoteInvitationWasEmailed $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->invitation->invoice,
|
||||
ACTIVITY_TYPE_EMAIL_QUOTE,
|
||||
false,
|
||||
false,
|
||||
$event->invitation
|
||||
);
|
||||
}
|
||||
|
||||
public function viewedQuote(QuoteInvitationWasViewed $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->quote,
|
||||
ACTIVITY_TYPE_VIEW_QUOTE,
|
||||
false,
|
||||
false,
|
||||
$event->invitation
|
||||
);
|
||||
}
|
||||
|
||||
public function approvedQuote(QuoteInvitationWasApproved $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->quote,
|
||||
ACTIVITY_TYPE_APPROVE_QUOTE,
|
||||
false,
|
||||
false,
|
||||
$event->invitation
|
||||
);
|
||||
}
|
||||
|
||||
// Credits
|
||||
public function createdCredit(CreditWasCreated $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->credit,
|
||||
ACTIVITY_TYPE_CREATE_CREDIT
|
||||
);
|
||||
}
|
||||
|
||||
public function deletedCredit(CreditWasDeleted $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->credit,
|
||||
ACTIVITY_TYPE_DELETE_CREDIT
|
||||
);
|
||||
}
|
||||
|
||||
public function archivedCredit(CreditWasArchived $event)
|
||||
{
|
||||
if ($event->credit->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activityRepo->create(
|
||||
$event->credit,
|
||||
ACTIVITY_TYPE_ARCHIVE_CREDIT
|
||||
);
|
||||
}
|
||||
|
||||
public function restoredCredit(CreditWasRestored $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->credit,
|
||||
ACTIVITY_TYPE_RESTORE_CREDIT
|
||||
);
|
||||
}
|
||||
|
||||
// Payments
|
||||
public function createdPayment(PaymentWasCreated $event)
|
||||
{
|
||||
$this->activityRepo->create(
|
||||
$event->payment,
|
||||
ACTIVITY_TYPE_CREATE_PAYMENT,
|
||||
$event->payment->amount * -1,
|
||||
$event->payment->amount
|
||||
);
|
||||
}
|
||||
|
||||
public function deletedPayment(PaymentWasDeleted $event)
|
||||
{
|
||||
$payment = $event->payment;
|
||||
|
||||
$this->activityRepo->create(
|
||||
$payment,
|
||||
ACTIVITY_TYPE_DELETE_PAYMENT,
|
||||
$payment->amount,
|
||||
$payment->amount * -1
|
||||
);
|
||||
}
|
||||
|
||||
public function archivedPayment(PaymentWasArchived $event)
|
||||
{
|
||||
if ($event->payment->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->activityRepo->create(
|
||||
$event->payment,
|
||||
ACTIVITY_TYPE_ARCHIVE_PAYMENT
|
||||
);
|
||||
}
|
||||
|
||||
public function restoredPayment(PaymentWasRestored $event)
|
||||
{
|
||||
$payment = $event->payment;
|
||||
|
||||
$this->activityRepo->create(
|
||||
$payment,
|
||||
ACTIVITY_TYPE_RESTORE_PAYMENT,
|
||||
$event->fromDeleted ? $payment->amount * -1 : 0,
|
||||
$event->fromDeleted ? $payment->amount : 0
|
||||
);
|
||||
}
|
||||
}
|
33
app/Listeners/CreditListener.php
Normal file
33
app/Listeners/CreditListener.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use Carbon;
|
||||
use App\Models\Credit;
|
||||
use App\Events\PaymentWasDeleted;
|
||||
use App\Ninja\Repositories\CreditRepository;
|
||||
|
||||
class CreditListener
|
||||
{
|
||||
protected $creditRepo;
|
||||
|
||||
public function __construct(CreditRepository $creditRepo)
|
||||
{
|
||||
$this->creditRepo = $creditRepo;
|
||||
}
|
||||
|
||||
public function deletedPayment(PaymentWasDeleted $event)
|
||||
{
|
||||
$payment = $event->payment;
|
||||
|
||||
// if the payment was from a credit we need to refund the credit
|
||||
if ($payment->payment_type_id != PAYMENT_TYPE_CREDIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
$credit = Credit::createNew();
|
||||
$credit->client_id = $payment->client_id;
|
||||
$credit->credit_date = Carbon::now()->toDateTimeString();
|
||||
$credit->balance = $credit->amount = $payment->amount;
|
||||
$credit->private_notes = $payment->transaction_reference;
|
||||
$credit->save();
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php namespace App\Listeners;
|
||||
|
||||
use App\Events\InvoicePaid;
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
use App\Ninja\Mailers\ContactMailer;
|
||||
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
|
||||
class HandleInvoicePaid {
|
||||
|
||||
protected $userMailer;
|
||||
protected $contactMailer;
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserMailer $userMailer, ContactMailer $contactMailer)
|
||||
{
|
||||
$this->userMailer = $userMailer;
|
||||
$this->contactMailer = $contactMailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param InvoicePaid $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(InvoicePaid $event)
|
||||
{
|
||||
$payment = $event->payment;
|
||||
$invoice = $payment->invoice;
|
||||
|
||||
$this->contactMailer->sendPaymentConfirmation($payment);
|
||||
|
||||
foreach ($invoice->account->users as $user)
|
||||
{
|
||||
if ($user->{'notify_paid'})
|
||||
{
|
||||
$this->userMailer->sendNotification($user, $invoice, 'paid', $payment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<?php namespace App\Listeners;
|
||||
|
||||
use App\Events\InvoiceSent;
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
|
||||
class HandleInvoiceSent {
|
||||
|
||||
protected $userMailer;
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserMailer $userMailer)
|
||||
{
|
||||
$this->userMailer = $userMailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param InvoiceSent $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(InvoiceSent $event)
|
||||
{
|
||||
$invoice = $event->invoice;
|
||||
|
||||
foreach ($invoice->account->users as $user)
|
||||
{
|
||||
if ($user->{'notify_sent'})
|
||||
{
|
||||
$this->userMailer->sendNotification($user, $invoice, 'sent');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<?php namespace App\Listeners;
|
||||
|
||||
use App\Events\InvoiceViewed;
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
|
||||
class HandleInvoiceViewed {
|
||||
|
||||
protected $userMailer;
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserMailer $userMailer)
|
||||
{
|
||||
$this->userMailer = $userMailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param InvoiceViewed $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(InvoiceViewed $event)
|
||||
{
|
||||
$invoice = $event->invoice;
|
||||
|
||||
foreach ($invoice->account->users as $user)
|
||||
{
|
||||
if ($user->{'notify_viewed'})
|
||||
{
|
||||
$this->userMailer->sendNotification($user, $invoice, 'viewed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<?php namespace App\Listeners;
|
||||
|
||||
use App\Events\QuoteApproved;
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
|
||||
class HandleQuoteApproved {
|
||||
|
||||
protected $userMailer;
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserMailer $userMailer)
|
||||
{
|
||||
$this->userMailer = $userMailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param QuoteApproved $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(QuoteApproved $event)
|
||||
{
|
||||
$invoice = $event->invoice;
|
||||
|
||||
foreach ($invoice->account->users as $user)
|
||||
{
|
||||
if ($user->{'notify_approved'})
|
||||
{
|
||||
$this->userMailer->sendNotification($user, $invoice, 'approved');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -41,12 +41,6 @@ class HandleUserSignedUp
|
||||
$this->accountRepo->registerNinjaUser($user);
|
||||
}
|
||||
|
||||
$activities = Activity::scope()->get();
|
||||
foreach ($activities as $activity) {
|
||||
$activity->message = str_replace('Guest', $user->getFullName(), $activity->message);
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
session([SESSION_COUNTER => -1]);
|
||||
}
|
||||
}
|
||||
|
58
app/Listeners/InvoiceListener.php
Normal file
58
app/Listeners/InvoiceListener.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use App\Events\InvoiceWasEmailed;
|
||||
use App\Events\InvoiceWasUpdated;
|
||||
use App\Events\PaymentWasCreated;
|
||||
use App\Events\PaymentWasDeleted;
|
||||
use App\Events\PaymentWasRestored;
|
||||
use App\Events\InvoiceInvitationWasViewed;
|
||||
|
||||
class InvoiceListener
|
||||
{
|
||||
public function createdPayment(PaymentWasCreated $event)
|
||||
{
|
||||
$payment = $event->payment;
|
||||
$invoice = $payment->invoice;
|
||||
$adjustment = $payment->amount * -1;
|
||||
$partial = max(0, $invoice->partial - $payment->amount);
|
||||
|
||||
$invoice->updateBalances($adjustment, $partial);
|
||||
$invoice->updatePaidStatus();
|
||||
}
|
||||
|
||||
public function updatedInvoice(InvoiceWasUpdated $event)
|
||||
{
|
||||
$invoice = $event->invoice;
|
||||
$invoice->updatePaidStatus();
|
||||
}
|
||||
|
||||
public function viewedInvoice(InvoiceInvitationWasViewed $event)
|
||||
{
|
||||
$invitation = $event->invitation;
|
||||
$invitation->markViewed();
|
||||
}
|
||||
|
||||
public function deletedPayment(PaymentWasDeleted $event)
|
||||
{
|
||||
$payment = $event->payment;
|
||||
$invoice = $payment->invoice;
|
||||
$adjustment = $payment->amount;
|
||||
|
||||
$invoice->updateBalances($adjustment);
|
||||
$invoice->updatePaidStatus();
|
||||
}
|
||||
|
||||
public function restoredPayment(PaymentWasRestored $event)
|
||||
{
|
||||
if ( ! $event->fromDeleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment = $event->payment;
|
||||
$invoice = $payment->invoice;
|
||||
$adjustment = $payment->amount * -1;
|
||||
|
||||
$invoice->updateBalances($adjustment);
|
||||
$invoice->updatePaidStatus();
|
||||
}
|
||||
}
|
71
app/Listeners/NotificationListener.php
Normal file
71
app/Listeners/NotificationListener.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
use App\Ninja\Mailers\ContactMailer;
|
||||
|
||||
use App\Events\InvoiceWasEmailed;
|
||||
use App\Events\QuoteWasEmailed;
|
||||
use App\Events\InvoiceInvitationWasViewed;
|
||||
use App\Events\QuoteInvitationWasViewed;
|
||||
use App\Events\QuoteInvitationWasApproved;
|
||||
use App\Events\PaymentWasCreated;
|
||||
|
||||
class NotificationListener
|
||||
{
|
||||
protected $userMailer;
|
||||
protected $contactMailer;
|
||||
|
||||
public function __construct(UserMailer $userMailer, ContactMailer $contactMailer)
|
||||
{
|
||||
$this->userMailer = $userMailer;
|
||||
$this->contactMailer = $contactMailer;
|
||||
}
|
||||
|
||||
private function sendEmails($invoice, $type, $payment = null)
|
||||
{
|
||||
foreach ($invoice->account->users as $user)
|
||||
{
|
||||
if ($user->{"notify_{$type}"})
|
||||
{
|
||||
$this->userMailer->sendNotification($user, $invoice, $type, $payment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function emailedInvoice(InvoiceWasEmailed $event)
|
||||
{
|
||||
$this->sendEmails($event->invoice, 'sent');
|
||||
}
|
||||
|
||||
public function emailedQuote(QuoteWasEmailed $event)
|
||||
{
|
||||
$this->sendEmails($event->quote, 'sent');
|
||||
}
|
||||
|
||||
public function viewedInvoice(InvoiceInvitationWasViewed $event)
|
||||
{
|
||||
$this->sendEmails($event->invoice, 'viewed');
|
||||
}
|
||||
|
||||
public function viewedQuote(QuoteInvitationWasViewed $event)
|
||||
{
|
||||
$this->sendEmails($event->quote, 'viewed');
|
||||
}
|
||||
|
||||
public function approvedQuote(QuoteInvitationWasApproved $event)
|
||||
{
|
||||
$this->sendEmails($event->quote, 'approved');
|
||||
}
|
||||
|
||||
public function createdPayment(PaymentWasCreated $event)
|
||||
{
|
||||
// only send emails for online payments
|
||||
if ( ! $event->payment->account_gateway_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->contactMailer->sendPaymentConfirmation($event->payment);
|
||||
$this->sendEmails($event->payment->invoice, 'paid', $event->payment);
|
||||
}
|
||||
|
||||
}
|
15
app/Listeners/QuoteListener.php
Normal file
15
app/Listeners/QuoteListener.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use Carbon;
|
||||
use App\Events\QuoteWasEmailed;
|
||||
use App\Events\QuoteInvitationWasViewed;
|
||||
use App\Events\QuoteInvitationWasEmailed;
|
||||
|
||||
class QuoteListener
|
||||
{
|
||||
public function viewedQuote(QuoteInvitationWasViewed $event)
|
||||
{
|
||||
$invitation = $event->invitation;
|
||||
$invitation->markViewed();
|
||||
}
|
||||
}
|
47
app/Listeners/SubscriptionListener.php
Normal file
47
app/Listeners/SubscriptionListener.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use Auth;
|
||||
use Utils;
|
||||
|
||||
use App\Events\ClientWasCreated;
|
||||
use App\Events\QuoteWasCreated;
|
||||
use App\Events\InvoiceWasCreated;
|
||||
use App\Events\CreditWasCreated;
|
||||
use App\Events\PaymentWasCreated;
|
||||
|
||||
class SubscriptionListener
|
||||
{
|
||||
public function createdClient(ClientWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_CLIENT, $event->client);
|
||||
}
|
||||
|
||||
public function createdQuote(QuoteWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_QUOTE, $event->quote);
|
||||
}
|
||||
|
||||
public function createdPayment(PaymentWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_PAYMENT, $event->payment);
|
||||
}
|
||||
|
||||
public function createdCredit(CreditWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_CREDIT, $event->credit);
|
||||
}
|
||||
|
||||
public function createdInvoice(InvoiceWasCreated $event)
|
||||
{
|
||||
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_INVOICE, $event->invoice);
|
||||
}
|
||||
|
||||
private function checkSubscriptions($activityTypeId, $entity)
|
||||
{
|
||||
$subscription = $entity->account->getSubscription($activityTypeId);
|
||||
|
||||
if ($subscription) {
|
||||
Utils::notifyZapier($subscription, $entity);
|
||||
}
|
||||
}
|
||||
}
|
14
app/Listeners/TaskListener.php
Normal file
14
app/Listeners/TaskListener.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php namespace app\Listeners;
|
||||
|
||||
use App\Models\Task;
|
||||
use App\Events\InvoiceWasDeleted;
|
||||
|
||||
class TaskListener
|
||||
{
|
||||
public function deletedInvoice(InvoiceWasDeleted $event)
|
||||
{
|
||||
// Release any tasks associated with the deleted invoice
|
||||
Task::where('invoice_id', '=', $event->invoice->id)
|
||||
->update(['invoice_id' => null]);
|
||||
}
|
||||
}
|
@ -251,7 +251,7 @@ class Account extends Eloquent
|
||||
$invoice->start_date = Utils::today();
|
||||
$invoice->invoice_design_id = $this->invoice_design_id;
|
||||
$invoice->client_id = $clientId;
|
||||
|
||||
|
||||
if ($entityType === ENTITY_RECURRING_INVOICE) {
|
||||
$invoice->invoice_number = microtime(true);
|
||||
$invoice->is_recurring = true;
|
||||
@ -316,7 +316,7 @@ class Account extends Eloquent
|
||||
|
||||
$pattern = str_replace($search, $replace, $pattern);
|
||||
|
||||
if ($invoice->client->id) {
|
||||
if ($invoice->client_id) {
|
||||
$pattern = $this->getClientInvoiceNumber($pattern, $invoice);
|
||||
}
|
||||
|
||||
@ -330,13 +330,11 @@ class Account extends Eloquent
|
||||
}
|
||||
|
||||
$search = [
|
||||
//'{$clientId}',
|
||||
'{$custom1}',
|
||||
'{$custom2}',
|
||||
];
|
||||
|
||||
$replace = [
|
||||
//str_pad($client->public_id, 3, '0', STR_PAD_LEFT),
|
||||
$invoice->client->custom_value1,
|
||||
$invoice->client->custom_value2,
|
||||
];
|
||||
@ -344,17 +342,6 @@ class Account extends Eloquent
|
||||
return str_replace($search, $replace, $pattern);
|
||||
}
|
||||
|
||||
// if we're using a pattern we don't know the next number until a client
|
||||
// is selected, to support this the default value is blank
|
||||
public function getDefaultInvoiceNumber($invoice = false)
|
||||
{
|
||||
if ($this->hasClientNumberPattern($invoice)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getNextInvoiceNumber($invoice);
|
||||
}
|
||||
|
||||
public function getCounter($isQuote)
|
||||
{
|
||||
return $isQuote && !$this->share_counter ? $this->quote_number_counter : $this->invoice_number_counter;
|
||||
@ -372,7 +359,7 @@ class Account extends Eloquent
|
||||
|
||||
// confirm the invoice number isn't already taken
|
||||
do {
|
||||
$number = $prefix.str_pad($counter, 4, "0", STR_PAD_LEFT);
|
||||
$number = $prefix.str_pad($counter, 4, '0', STR_PAD_LEFT);
|
||||
$check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
|
||||
$counter++;
|
||||
$counterOffset++;
|
||||
@ -503,17 +490,11 @@ class Account extends Eloquent
|
||||
|
||||
$datePaid = $this->pro_plan_paid;
|
||||
|
||||
if (!$datePaid || $datePaid == '0000-00-00') {
|
||||
return false;
|
||||
} elseif ($datePaid == NINJA_DATE) {
|
||||
if ($datePaid == NINJA_DATE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$today = new DateTime('now');
|
||||
$datePaid = DateTime::createFromFormat('Y-m-d', $datePaid);
|
||||
$interval = $today->diff($datePaid);
|
||||
|
||||
return $interval->y == 0;
|
||||
return Utils::withinPastYear($datePaid);
|
||||
}
|
||||
|
||||
public function isWhiteLabel()
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Crypt;
|
||||
use App\Models\Gateway;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
@ -27,16 +28,29 @@ class AccountGateway extends EntityModel
|
||||
return $arrayOfImages;
|
||||
}
|
||||
|
||||
public function getPaymentType() {
|
||||
public function getPaymentType()
|
||||
{
|
||||
return Gateway::getPaymentType($this->gateway_id);
|
||||
}
|
||||
|
||||
public function isPaymentType($type) {
|
||||
public function isPaymentType($type)
|
||||
{
|
||||
return $this->getPaymentType() == $type;
|
||||
}
|
||||
|
||||
public function isGateway($gatewayId) {
|
||||
public function isGateway($gatewayId)
|
||||
{
|
||||
return $this->gateway_id == $gatewayId;
|
||||
}
|
||||
|
||||
public function setConfig($config)
|
||||
{
|
||||
$this->config = Crypt::encrypt(json_encode($config));
|
||||
}
|
||||
|
||||
public function getConfig()
|
||||
{
|
||||
return json_decode(Crypt::decrypt($this->config));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,480 +23,60 @@ class Activity extends Eloquent
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Models\User');
|
||||
return $this->belongsTo('App\Models\User')->withTrashed();
|
||||
}
|
||||
|
||||
private static function getBlank($entity = false)
|
||||
public function contact()
|
||||
{
|
||||
$activity = new Activity();
|
||||
|
||||
if ($entity) {
|
||||
$activity->user_id = $entity instanceof User ? $entity->id : $entity->user_id;
|
||||
$activity->account_id = $entity->account_id;
|
||||
} elseif (Auth::check()) {
|
||||
$activity->user_id = Auth::user()->id;
|
||||
$activity->account_id = Auth::user()->account_id;
|
||||
} else {
|
||||
Utils::fatalError();
|
||||
}
|
||||
|
||||
$activity->token_id = Session::get('token_id', null);
|
||||
$activity->ip = Request::getClientIp();
|
||||
|
||||
return $activity;
|
||||
return $this->belongsTo('App\Models\Contact')->withTrashed();
|
||||
}
|
||||
|
||||
public static function createClient($client, $notify = true)
|
||||
public function client()
|
||||
{
|
||||
$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);
|
||||
}
|
||||
return $this->belongsTo('App\Models\Client')->withTrashed();
|
||||
}
|
||||
|
||||
public static function updateClient($client)
|
||||
public function invoice()
|
||||
{
|
||||
if ($client->isBeingDeleted()) {
|
||||
$activity = Activity::getBlank();
|
||||
$activity->client_id = $client->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_DELETE_CLIENT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'deleted', $client);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
return $this->belongsTo('App\Models\Invoice')->withTrashed();
|
||||
}
|
||||
|
||||
public static function archiveClient($client)
|
||||
public function credit()
|
||||
{
|
||||
if (!$client->is_deleted) {
|
||||
$activity = Activity::getBlank();
|
||||
$activity->client_id = $client->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_CLIENT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'archived', $client);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
return $this->belongsTo('App\Models\Credit')->withTrashed();
|
||||
}
|
||||
|
||||
public static function restoreClient($client)
|
||||
public function payment()
|
||||
{
|
||||
$activity = Activity::getBlank();
|
||||
$activity->client_id = $client->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_RESTORE_CLIENT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'restored', $client);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->save();
|
||||
return $this->belongsTo('App\Models\Payment')->withTrashed();
|
||||
}
|
||||
|
||||
public static function createInvoice($invoice)
|
||||
public static function calcMessage($activityTypeId, $client, $user, $invoice, $contactId, $payment, $credit, $isSystem)
|
||||
{
|
||||
if (Auth::check()) {
|
||||
$message = Utils::encodeActivity(Auth::user(), 'created', $invoice);
|
||||
} else {
|
||||
$message = Utils::encodeActivity(null, 'created', $invoice);
|
||||
}
|
||||
$data = [
|
||||
'client' => link_to($client->getRoute(), $client->getDisplayName()),
|
||||
'user' => $isSystem ? '<i>' . trans('texts.system') . '</i>' : $user->getDisplayName(),
|
||||
'invoice' => $invoice ? link_to($invoice->getRoute(), $invoice->getDisplayName()) : null,
|
||||
'quote' => $invoice ? link_to($invoice->getRoute(), $invoice->getDisplayName()) : null,
|
||||
'contact' => $contactId ? $client->getDisplayName() : $user->getDisplayName(),
|
||||
'payment' => $payment ? $payment->transaction_reference : null,
|
||||
'credit' => $credit ? Utils::formatMoney($credit->amount, $client->currency_id) : null,
|
||||
];
|
||||
|
||||
$adjustment = 0;
|
||||
$client = $invoice->client;
|
||||
if (!$invoice->is_quote && !$invoice->is_recurring) {
|
||||
$adjustment = $invoice->amount;
|
||||
$client->balance = $client->balance + $adjustment;
|
||||
$client->save();
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank($invoice);
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_CREATE_QUOTE : ACTIVITY_TYPE_CREATE_INVOICE;
|
||||
$activity->message = $message;
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $adjustment;
|
||||
$activity->save();
|
||||
|
||||
Activity::checkSubscriptions($invoice->is_quote ? EVENT_CREATE_QUOTE : EVENT_CREATE_INVOICE, $invoice);
|
||||
return trans("texts.activity_{$activityTypeId}", $data);
|
||||
}
|
||||
|
||||
public static function archiveInvoice($invoice)
|
||||
public function getMessage()
|
||||
{
|
||||
if (!$invoice->is_deleted) {
|
||||
$activity = Activity::getBlank();
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_ARCHIVE_QUOTE : ACTIVITY_TYPE_ARCHIVE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'archived', $invoice);
|
||||
$activity->balance = $invoice->client->balance;
|
||||
|
||||
$activity->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function restoreInvoice($invoice)
|
||||
{
|
||||
$activity = Activity::getBlank();
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_RESTORE_QUOTE : ACTIVITY_TYPE_RESTORE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'restored', $invoice);
|
||||
$activity->balance = $invoice->client->balance;
|
||||
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function emailInvoice($invitation)
|
||||
{
|
||||
$invoice = $invitation->invoice;
|
||||
$client = $invoice->client;
|
||||
|
||||
if (!$invoice->isSent()) {
|
||||
$invoice->invoice_status_id = INVOICE_STATUS_SENT;
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank($invitation);
|
||||
$activity->client_id = $invitation->invoice->client_id;
|
||||
$activity->invoice_id = $invitation->invoice_id;
|
||||
$activity->contact_id = $invitation->contact_id;
|
||||
$activity->activity_type_id = $invitation->invoice ? ACTIVITY_TYPE_EMAIL_QUOTE : ACTIVITY_TYPE_EMAIL_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::check() ? Auth::user() : null, 'emailed', $invitation->invoice, $invitation->contact);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function updateInvoice($invoice)
|
||||
{
|
||||
$client = $invoice->client;
|
||||
|
||||
if ($invoice->isBeingDeleted()) {
|
||||
$adjustment = 0;
|
||||
if (!$invoice->is_quote && !$invoice->is_recurring) {
|
||||
$adjustment = $invoice->balance * -1;
|
||||
$client->balance = $client->balance - $invoice->balance;
|
||||
$client->paid_to_date = $client->paid_to_date - ($invoice->amount - $invoice->balance);
|
||||
$client->save();
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank();
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_DELETE_QUOTE : ACTIVITY_TYPE_DELETE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'deleted', $invoice);
|
||||
$activity->balance = $invoice->client->balance;
|
||||
$activity->adjustment = $adjustment;
|
||||
$activity->save();
|
||||
|
||||
// Release any tasks associated with the deleted invoice
|
||||
Task::where('invoice_id', '=', $invoice->id)
|
||||
->update(['invoice_id' => null]);
|
||||
} else {
|
||||
$diff = floatval($invoice->amount) - floatval($invoice->getOriginal('amount'));
|
||||
|
||||
$fieldChanged = false;
|
||||
foreach (['invoice_number', 'po_number', 'invoice_date', 'due_date', 'terms', 'public_notes', 'invoice_footer', 'partial'] as $field) {
|
||||
if ($invoice->$field != $invoice->getOriginal($field)) {
|
||||
$fieldChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($diff != 0 || $fieldChanged) {
|
||||
$backupInvoice = Invoice::with('invoice_items', 'client.account', 'client.contacts')->find($invoice->id);
|
||||
|
||||
if ($diff != 0 && !$invoice->is_quote && !$invoice->is_recurring) {
|
||||
$client->balance = $client->balance + $diff;
|
||||
$client->save();
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank($invoice);
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_UPDATE_QUOTE : ACTIVITY_TYPE_UPDATE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'updated', $invoice);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $invoice->is_quote || $invoice->is_recurring ? 0 : $diff;
|
||||
$activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON();
|
||||
$activity->save();
|
||||
|
||||
if ($invoice->isPaid() && $invoice->balance > 0) {
|
||||
$invoice->invoice_status_id = INVOICE_STATUS_PARTIAL;
|
||||
} elseif ($invoice->invoice_status_id && $invoice->balance == 0) {
|
||||
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function viewInvoice($invitation)
|
||||
{
|
||||
if (Session::get($invitation->invitation_key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Session::put($invitation->invitation_key, true);
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
if (!$invoice->isViewed()) {
|
||||
$invoice->invoice_status_id = INVOICE_STATUS_VIEWED;
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
$now = Carbon::now()->toDateTimeString();
|
||||
|
||||
$invitation->viewed_date = $now;
|
||||
$invitation->save();
|
||||
|
||||
$client = $invoice->client;
|
||||
$client->last_login = $now;
|
||||
$client->save();
|
||||
|
||||
$activity = Activity::getBlank($invitation);
|
||||
$activity->client_id = $invitation->invoice->client_id;
|
||||
$activity->invitation_id = $invitation->id;
|
||||
$activity->contact_id = $invitation->contact_id;
|
||||
$activity->invoice_id = $invitation->invoice_id;
|
||||
$activity->activity_type_id = $invitation->invoice->is_quote ? ACTIVITY_TYPE_VIEW_QUOTE : ACTIVITY_TYPE_VIEW_INVOICE;
|
||||
$activity->message = Utils::encodeActivity($invitation->contact, 'viewed', $invitation->invoice);
|
||||
$activity->balance = $invitation->invoice->client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function approveQuote($invitation) {
|
||||
|
||||
$activity = Activity::getBlank($invitation);
|
||||
$activity->client_id = $invitation->invoice->client_id;
|
||||
$activity->invitation_id = $invitation->id;
|
||||
$activity->contact_id = $invitation->contact_id;
|
||||
$activity->invoice_id = $invitation->invoice_id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_APPROVE_QUOTE;
|
||||
$activity->message = Utils::encodeActivity($invitation->contact, 'approved', $invitation->invoice);
|
||||
$activity->balance = $invitation->invoice->client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function createPayment($payment)
|
||||
{
|
||||
$client = $payment->client;
|
||||
$client->balance = $client->balance - $payment->amount;
|
||||
$client->paid_to_date = $client->paid_to_date + $payment->amount;
|
||||
$client->save();
|
||||
|
||||
if ($payment->contact_id) {
|
||||
$activity = Activity::getBlank($client);
|
||||
$activity->contact_id = $payment->contact_id;
|
||||
$activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered '.$payment->getName().' for ', $payment->invoice);
|
||||
} else {
|
||||
$activity = Activity::getBlank($client);
|
||||
$message = $payment->payment_type_id == PAYMENT_TYPE_CREDIT ? 'applied credit for ' : 'entered '.$payment->getName().' for ';
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), $message, $payment->invoice);
|
||||
}
|
||||
|
||||
$activity->payment_id = $payment->id;
|
||||
|
||||
if ($payment->invoice_id) {
|
||||
$activity->invoice_id = $payment->invoice_id;
|
||||
|
||||
$invoice = $payment->invoice;
|
||||
$invoice->balance = $invoice->balance - $payment->amount;
|
||||
$invoice->invoice_status_id = ($invoice->balance > 0) ? INVOICE_STATUS_PARTIAL : INVOICE_STATUS_PAID;
|
||||
if ($invoice->partial > 0) {
|
||||
$invoice->partial = max(0, $invoice->partial - $payment->amount);
|
||||
}
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
$activity->payment_id = $payment->id;
|
||||
$activity->client_id = $payment->client_id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_PAYMENT;
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $payment->amount * -1;
|
||||
$activity->save();
|
||||
|
||||
Activity::checkSubscriptions(EVENT_CREATE_PAYMENT, $payment);
|
||||
}
|
||||
|
||||
public static function updatePayment($payment)
|
||||
{
|
||||
if ($payment->isBeingDeleted()) {
|
||||
$client = $payment->client;
|
||||
$client->balance = $client->balance + $payment->amount;
|
||||
$client->paid_to_date = $client->paid_to_date - $payment->amount;
|
||||
$client->save();
|
||||
|
||||
$invoice = $payment->invoice;
|
||||
$invoice->balance = $invoice->balance + $payment->amount;
|
||||
if ($invoice->isPaid() && $invoice->balance > 0) {
|
||||
$invoice->invoice_status_id = ($invoice->balance == $invoice->amount ? INVOICE_STATUS_DRAFT : INVOICE_STATUS_PARTIAL);
|
||||
}
|
||||
$invoice->save();
|
||||
|
||||
// deleting a payment from credit creates a new credit
|
||||
if ($payment->payment_type_id == PAYMENT_TYPE_CREDIT) {
|
||||
$credit = Credit::createNew();
|
||||
$credit->client_id = $client->id;
|
||||
$credit->credit_date = Carbon::now()->toDateTimeString();
|
||||
$credit->balance = $credit->amount = $payment->amount;
|
||||
$credit->private_notes = $payment->transaction_reference;
|
||||
$credit->save();
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank();
|
||||
$activity->payment_id = $payment->id;
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_DELETE_PAYMENT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'deleted '.$payment->getName());
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $payment->amount;
|
||||
$activity->save();
|
||||
} else {
|
||||
/*
|
||||
$diff = floatval($invoice->amount) - floatval($invoice->getOriginal('amount'));
|
||||
|
||||
if ($diff == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$client = $invoice->client;
|
||||
$client->balance = $client->balance + $diff;
|
||||
$client->save();
|
||||
|
||||
$activity = Activity::getBlank($invoice);
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_UPDATE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'updated', $invoice);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $diff;
|
||||
$activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON();
|
||||
$activity->save();
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public static function archivePayment($payment)
|
||||
{
|
||||
if ($payment->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$client = $payment->client;
|
||||
$invoice = $payment->invoice;
|
||||
|
||||
$activity = Activity::getBlank();
|
||||
$activity->payment_id = $payment->id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->client_id = $client->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_PAYMENT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'archived '.$payment->getName());
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = 0;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function restorePayment($payment)
|
||||
{
|
||||
$client = $payment->client;
|
||||
$invoice = $payment->invoice;
|
||||
|
||||
$activity = Activity::getBlank();
|
||||
$activity->payment_id = $payment->id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->client_id = $client->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_RESTORE_PAYMENT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'restored '.$payment->getName());
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = 0;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function createCredit($credit)
|
||||
{
|
||||
$activity = Activity::getBlank();
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'entered '.Utils::formatMoney($credit->amount, $credit->client->getCurrencyId()).' credit');
|
||||
$activity->credit_id = $credit->id;
|
||||
$activity->client_id = $credit->client_id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
|
||||
$activity->balance = $credit->client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function updateCredit($credit)
|
||||
{
|
||||
if ($credit->isBeingDeleted()) {
|
||||
$activity = Activity::getBlank();
|
||||
$activity->credit_id = $credit->id;
|
||||
$activity->client_id = $credit->client_id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_DELETE_CREDIT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'deleted '.Utils::formatMoney($credit->balance, $credit->client->getCurrencyId()).' credit');
|
||||
$activity->balance = $credit->client->balance;
|
||||
$activity->save();
|
||||
} else {
|
||||
/*
|
||||
$diff = floatval($invoice->amount) - floatval($invoice->getOriginal('amount'));
|
||||
|
||||
if ($diff == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$client = $invoice->client;
|
||||
$client->balance = $client->balance + $diff;
|
||||
$client->save();
|
||||
|
||||
$activity = Activity::getBlank($invoice);
|
||||
$activity->client_id = $invoice->client_id;
|
||||
$activity->invoice_id = $invoice->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_UPDATE_INVOICE;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'updated', $invoice);
|
||||
$activity->balance = $client->balance;
|
||||
$activity->adjustment = $diff;
|
||||
$activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON();
|
||||
$activity->save();
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public static function archiveCredit($credit)
|
||||
{
|
||||
if ($credit->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$activity = Activity::getBlank();
|
||||
$activity->client_id = $credit->client_id;
|
||||
$activity->credit_id = $credit->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_ARCHIVE_CREDIT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'archived '.Utils::formatMoney($credit->balance, $credit->client->getCurrencyId()).' credit');
|
||||
$activity->balance = $credit->client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
public static function restoreCredit($credit)
|
||||
{
|
||||
$activity = Activity::getBlank();
|
||||
$activity->client_id = $credit->client_id;
|
||||
$activity->credit_id = $credit->id;
|
||||
$activity->activity_type_id = ACTIVITY_TYPE_RESTORE_CREDIT;
|
||||
$activity->message = Utils::encodeActivity(Auth::user(), 'restored '.Utils::formatMoney($credit->balance, $credit->client->getCurrencyId()).' credit');
|
||||
$activity->balance = $credit->client->balance;
|
||||
$activity->save();
|
||||
}
|
||||
|
||||
private static function checkSubscriptions($event, $data)
|
||||
{
|
||||
if (!Auth::check()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$subscription = Auth::user()->account->getSubscription($event);
|
||||
|
||||
if ($subscription) {
|
||||
Utils::notifyZapier($subscription, $data);
|
||||
}
|
||||
return static::calcMessage(
|
||||
$this->activity_type_id,
|
||||
$this->client,
|
||||
$this->user,
|
||||
$this->invoice,
|
||||
$this->contact_id,
|
||||
$this->payment,
|
||||
$this->credit,
|
||||
$this->is_system
|
||||
);
|
||||
}
|
||||
}
|
||||
|
6
app/Models/BalanceAffecting.php
Normal file
6
app/Models/BalanceAffecting.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
interface BalanceAffecting
|
||||
{
|
||||
public function getAdjustment();
|
||||
}
|
@ -2,7 +2,9 @@
|
||||
|
||||
use Utils;
|
||||
use DB;
|
||||
|
||||
use Carbon;
|
||||
use App\Events\ClientWasCreated;
|
||||
use App\Events\ClientWasUpdated;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Client extends EntityModel
|
||||
@ -10,6 +12,28 @@ class Client extends EntityModel
|
||||
use SoftDeletes;
|
||||
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 = 'Client - Name';
|
||||
public static $fieldPhone = 'Client - Phone';
|
||||
public static $fieldAddress1 = 'Client - Street';
|
||||
@ -70,6 +94,40 @@ class Client extends EntityModel
|
||||
return $this->belongsTo('App\Models\Industry');
|
||||
}
|
||||
|
||||
public function addContact($data, $isPrimary = false)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if ($publicId && $publicId != '-1') {
|
||||
$contact = Contact::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
$contact = Contact::createNew();
|
||||
$contact->send_invoice = true;
|
||||
}
|
||||
|
||||
$contact->fill($data);
|
||||
$contact->is_primary = $isPrimary;
|
||||
|
||||
return $this->contacts()->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 "/clients/{$this->public_id}";
|
||||
}
|
||||
|
||||
public function getTotalCredit()
|
||||
{
|
||||
return DB::table('credits')
|
||||
@ -89,8 +147,11 @@ class Client extends EntityModel
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
$contact = $this->contacts()->first();
|
||||
if ( ! count($this->contacts)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$contact = $this->contacts[0];
|
||||
return $contact->getDisplayName();
|
||||
}
|
||||
|
||||
@ -178,24 +239,26 @@ class Client extends EntityModel
|
||||
{
|
||||
return $isQuote ? $this->quote_number_counter : $this->invoice_number_counter;
|
||||
}
|
||||
|
||||
public function markLoggedIn()
|
||||
{
|
||||
$this->last_login = Carbon::now()->toDateTimeString();
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Client::created(function($client)
|
||||
{
|
||||
Activity::createClient($client);
|
||||
Client::creating(function ($client) {
|
||||
$client->setNullValues();
|
||||
});
|
||||
|
||||
Client::created(function ($client) {
|
||||
event(new ClientWasCreated($client));
|
||||
});
|
||||
*/
|
||||
|
||||
Client::updating(function ($client) {
|
||||
Activity::updateClient($client);
|
||||
$client->setNullValues();
|
||||
});
|
||||
|
||||
Client::deleting(function ($client) {
|
||||
Activity::archiveClient($client);
|
||||
Client::updated(function ($client) {
|
||||
event(new ClientWasUpdated($client));
|
||||
});
|
||||
|
||||
/*Client::restoring(function ($client) {
|
||||
Activity::restoreClient($client);
|
||||
});
|
||||
*/
|
@ -9,6 +9,14 @@ class Contact extends EntityModel
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
protected $fillable = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'phone',
|
||||
'send_invoice',
|
||||
];
|
||||
|
||||
public static $fieldFirstName = 'Contact - First Name';
|
||||
public static $fieldLastName = 'Contact - Last Name';
|
||||
public static $fieldEmail = 'Contact - Email';
|
||||
|
@ -1,12 +1,19 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Events\CreditWasCreated;
|
||||
|
||||
|
||||
class Credit extends EntityModel
|
||||
{
|
||||
use SoftDeletes;
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Account');
|
||||
}
|
||||
|
||||
public function invoice()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Invoice')->withTrashed();
|
||||
@ -43,18 +50,10 @@ class Credit extends EntityModel
|
||||
}
|
||||
}
|
||||
|
||||
Credit::creating(function ($credit) {
|
||||
|
||||
});
|
||||
|
||||
Credit::created(function ($credit) {
|
||||
Activity::createCredit($credit);
|
||||
});
|
||||
|
||||
Credit::updating(function ($credit) {
|
||||
Activity::updateCredit($credit);
|
||||
});
|
||||
|
||||
Credit::deleting(function ($credit) {
|
||||
Activity::archiveCredit($credit);
|
||||
});
|
||||
|
||||
Credit::restoring(function ($credit) {
|
||||
Activity::restoreCredit($credit);
|
||||
});
|
||||
event(new CreditWasCreated($credit));
|
||||
});
|
@ -24,7 +24,10 @@ class EntityModel extends Eloquent
|
||||
Utils::fatalError();
|
||||
}
|
||||
|
||||
$lastEntity = $className::withTrashed()->scope(false, $entity->account_id)->orderBy('public_id', 'DESC')->first();
|
||||
$lastEntity = $className::withTrashed()
|
||||
->scope(false, $entity->account_id)
|
||||
->orderBy('public_id', 'DESC')
|
||||
->first();
|
||||
|
||||
if ($lastEntity) {
|
||||
$entity->public_id = $lastEntity->public_id + 1;
|
||||
@ -39,7 +42,7 @@ class EntityModel extends Eloquent
|
||||
{
|
||||
$className = get_called_class();
|
||||
|
||||
return $className::scope($publicId)->pluck('id');
|
||||
return $className::scope($publicId)->withTrashed()->pluck('id');
|
||||
}
|
||||
|
||||
public function getActivityKey()
|
||||
@ -112,8 +115,21 @@ class EntityModel extends Eloquent
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function isBeingDeleted()
|
||||
public function setNullValues()
|
||||
{
|
||||
return $this->is_deleted && !$this->getOriginal('is_deleted');
|
||||
foreach ($this->fillable as $field) {
|
||||
if (strstr($field, '_id') && !$this->$field) {
|
||||
$this->$field = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// converts "App\Models\Client" to "client_id"
|
||||
public function getKeyField()
|
||||
{
|
||||
$class = get_class($this);
|
||||
$parts = explode('\\', $class);
|
||||
$name = $parts[count($parts)-1];
|
||||
return strtolower($name) . '_id';
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Utils;
|
||||
use Carbon;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Invitation extends EntityModel
|
||||
@ -72,4 +73,23 @@ class Invitation extends EntityModel
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,17 @@
|
||||
|
||||
use Utils;
|
||||
use DateTime;
|
||||
use App\Models\BalanceAffecting;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Invoice extends EntityModel
|
||||
use App\Events\QuoteWasCreated;
|
||||
use App\Events\QuoteWasUpdated;
|
||||
use App\Events\InvoiceWasCreated;
|
||||
use App\Events\InvoiceWasUpdated;
|
||||
use App\Events\InvoiceInvitationWasEmailed;
|
||||
use App\Events\QuoteInvitationWasEmailed;
|
||||
|
||||
class Invoice extends EntityModel implements BalanceAffecting
|
||||
{
|
||||
use SoftDeletes {
|
||||
SoftDeletes::trashed as parentTrashed;
|
||||
@ -26,6 +34,69 @@ class Invoice extends EntityModel
|
||||
'year',
|
||||
'date:',
|
||||
];
|
||||
|
||||
public function getRoute()
|
||||
{
|
||||
$entityType = $this->getEntityType();
|
||||
return "/{$entityType}s/{$this->public_id}/edit";
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->is_recurring ? trans('texts.recurring') : $this->invoice_number;
|
||||
}
|
||||
|
||||
public function affectsBalance()
|
||||
{
|
||||
return !$this->is_quote && !$this->is_recurring;
|
||||
}
|
||||
|
||||
public function getAdjustment()
|
||||
{
|
||||
if (!$this->affectsBalance()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->getRawAdjustment();
|
||||
}
|
||||
|
||||
private function getRawAdjustment()
|
||||
{
|
||||
return floatval($this->amount) - floatval($this->getOriginal('amount'));
|
||||
}
|
||||
|
||||
public function isChanged()
|
||||
{
|
||||
if ($this->getRawAdjustment() != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'invoice_number',
|
||||
'po_number',
|
||||
'invoice_date',
|
||||
'due_date',
|
||||
'terms',
|
||||
'public_notes',
|
||||
'invoice_footer',
|
||||
'partial'
|
||||
] as $field) {
|
||||
if ($this->$field != $this->getOriginal($field)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAmountPaid()
|
||||
{
|
||||
if ($this->is_quote || $this->is_recurring) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($this->amount - $this->balance);
|
||||
}
|
||||
|
||||
public function trashed()
|
||||
{
|
||||
@ -81,6 +152,69 @@ class Invoice extends EntityModel
|
||||
return $this->hasMany('App\Models\Invitation')->orderBy('invitations.contact_id');
|
||||
}
|
||||
|
||||
public function markInvitationsSent($notify = false)
|
||||
{
|
||||
foreach ($this->invitations as $invitation) {
|
||||
$this->markInvitationSent($invitation, false, $notify);
|
||||
}
|
||||
}
|
||||
|
||||
public function markInvitationSent($invitation, $messageId = false, $notify = true)
|
||||
{
|
||||
if (!$this->isSent()) {
|
||||
$this->invoice_status_id = INVOICE_STATUS_SENT;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
$invitation->markSent($messageId);
|
||||
|
||||
// if the user marks it as sent rather than acually sending it
|
||||
// then we won't track it in the activity log
|
||||
if (!$notify) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->is_quote) {
|
||||
event(new QuoteInvitationWasEmailed($invitation));
|
||||
} else {
|
||||
event(new InvoiceInvitationWasEmailed($invitation));
|
||||
}
|
||||
}
|
||||
|
||||
public function markViewed()
|
||||
{
|
||||
if (!$this->isViewed()) {
|
||||
$this->invoice_status_id = INVOICE_STATUS_VIEWED;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePaidStatus()
|
||||
{
|
||||
if ($this->isPaid() && $this->balance > 0) {
|
||||
$this->invoice_status_id = ($this->balance == $this->amount ? INVOICE_STATUS_SENT : INVOICE_STATUS_PARTIAL);
|
||||
$this->save();
|
||||
} elseif ($this->invoice_status_id && $this->amount > 0 && $this->balance == 0 && $this->invoice_status_id != INVOICE_STATUS_PAID) {
|
||||
$this->invoice_status_id = INVOICE_STATUS_PAID;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function updateBalances($balanceAdjustment, $partial = 0)
|
||||
{
|
||||
if ($this->is_deleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->balance = $this->balance + $balanceAdjustment;
|
||||
|
||||
if ($this->partial > 0) {
|
||||
$this->partial = $partial;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->is_recurring ? trans('texts.recurring') : $this->invoice_number;
|
||||
@ -458,17 +592,17 @@ Invoice::creating(function ($invoice) {
|
||||
});
|
||||
|
||||
Invoice::created(function ($invoice) {
|
||||
Activity::createInvoice($invoice);
|
||||
if ($invoice->is_quote) {
|
||||
event(new QuoteWasCreated($invoice));
|
||||
} else {
|
||||
event(new InvoiceWasCreated($invoice));
|
||||
}
|
||||
});
|
||||
|
||||
Invoice::updating(function ($invoice) {
|
||||
Activity::updateInvoice($invoice);
|
||||
});
|
||||
|
||||
Invoice::deleting(function ($invoice) {
|
||||
Activity::archiveInvoice($invoice);
|
||||
});
|
||||
|
||||
Invoice::restoring(function ($invoice) {
|
||||
Activity::restoreInvoice($invoice);
|
||||
if ($invoice->is_quote) {
|
||||
event(new QuoteWasUpdated($invoice));
|
||||
} else {
|
||||
event(new InvoiceWasUpdated($invoice));
|
||||
}
|
||||
});
|
@ -1,6 +1,7 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Events\PaymentWasCreated;
|
||||
|
||||
class Payment extends EntityModel
|
||||
{
|
||||
@ -37,6 +38,11 @@ class Payment extends EntityModel
|
||||
return $this->belongsTo('App\Models\Contact');
|
||||
}
|
||||
|
||||
public function getRoute()
|
||||
{
|
||||
return "/payments/{$this->public_id}/edit";
|
||||
}
|
||||
|
||||
public function getAmount()
|
||||
{
|
||||
return Utils::formatMoney($this->amount, $this->client->getCurrencyId());
|
||||
@ -53,18 +59,10 @@ class Payment extends EntityModel
|
||||
}
|
||||
}
|
||||
|
||||
Payment::creating(function ($payment) {
|
||||
|
||||
});
|
||||
|
||||
Payment::created(function ($payment) {
|
||||
Activity::createPayment($payment);
|
||||
});
|
||||
|
||||
Payment::updating(function ($payment) {
|
||||
Activity::updatePayment($payment);
|
||||
});
|
||||
|
||||
Payment::deleting(function ($payment) {
|
||||
Activity::archivePayment($payment);
|
||||
});
|
||||
|
||||
Payment::restoring(function ($payment) {
|
||||
Activity::restorePayment($payment);
|
||||
});
|
||||
event(new PaymentWasCreated($payment));
|
||||
});
|
@ -82,20 +82,4 @@ class Task extends EntityModel
|
||||
{
|
||||
return round($this->getDuration() / (60 * 60), 2);
|
||||
}
|
||||
}
|
||||
|
||||
Task::created(function ($task) {
|
||||
//Activity::createTask($task);
|
||||
});
|
||||
|
||||
Task::updating(function ($task) {
|
||||
//Activity::updateTask($task);
|
||||
});
|
||||
|
||||
Task::deleting(function ($task) {
|
||||
//Activity::archiveTask($task);
|
||||
});
|
||||
|
||||
Task::restoring(function ($task) {
|
||||
//Activity::restoreTask($task);
|
||||
});
|
||||
}
|
@ -9,7 +9,9 @@ use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Gateway;
|
||||
use App\Events\InvoiceSent;
|
||||
|
||||
use App\Events\InvoiceWasEmailed;
|
||||
use App\Events\QuoteWasEmailed;
|
||||
|
||||
class ContactMailer extends Mailer
|
||||
{
|
||||
@ -44,7 +46,11 @@ class ContactMailer extends Mailer
|
||||
$account->loadLocalizationSettings();
|
||||
|
||||
if ($sent === true) {
|
||||
Event::fire(new InvoiceSent($invoice));
|
||||
if ($invoice->is_quote) {
|
||||
event(new QuoteWasEmailed($invoice));
|
||||
} else {
|
||||
event(new InvoiceWasEmailed($invoice));
|
||||
}
|
||||
}
|
||||
|
||||
return $sent ?: trans('texts.email_error');
|
||||
@ -94,10 +100,10 @@ class ContactMailer extends Mailer
|
||||
|
||||
$subject = $this->processVariables($subject, $variables);
|
||||
$fromEmail = $user->email;
|
||||
|
||||
$response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, ENTITY_INVOICE, $data);
|
||||
|
||||
if ($response === true) {
|
||||
Activity::emailInvoice($invitation);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -50,16 +50,16 @@ class Mailer
|
||||
{
|
||||
if (isset($data['invitation'])) {
|
||||
$invitation = $data['invitation'];
|
||||
|
||||
$invoice = $invitation->invoice;
|
||||
$messageId = false;
|
||||
|
||||
// Track the Postmark message id
|
||||
if (isset($_ENV['POSTMARK_API_TOKEN']) && $response) {
|
||||
$json = $response->json();
|
||||
$invitation->message_id = $json['MessageID'];
|
||||
$messageId = $json['MessageID'];
|
||||
}
|
||||
|
||||
$invitation->email_error = null;
|
||||
$invitation->sent_date = \Carbon::now()->toDateTimeString();
|
||||
$invitation->save();
|
||||
|
||||
$invoice->markInvitationSent($invitation, $messageId);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -18,6 +18,7 @@ use App\Models\Contact;
|
||||
use App\Models\Account;
|
||||
use App\Models\User;
|
||||
use App\Models\UserAccount;
|
||||
use App\Models\AccountToken;
|
||||
|
||||
class AccountRepository
|
||||
{
|
||||
@ -198,7 +199,7 @@ class AccountRepository
|
||||
$accountGateway->user_id = $user->id;
|
||||
$accountGateway->gateway_id = NINJA_GATEWAY_ID;
|
||||
$accountGateway->public_id = 1;
|
||||
$accountGateway->config = env(NINJA_GATEWAY_CONFIG);
|
||||
$accountGateway->setConfig(json_decode(env(NINJA_GATEWAY_CONFIG)));
|
||||
$account->account_gateways()->save($accountGateway);
|
||||
}
|
||||
|
||||
@ -455,4 +456,14 @@ class AccountRepository
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
public function createToken($name)
|
||||
{
|
||||
$token = AccountToken::createNew();
|
||||
$token->name = trim($name) ?: 'TOKEN';
|
||||
$token->token = str_random(RANDOM_KEY_LENGTH);
|
||||
$token->save();
|
||||
|
||||
return $token->token;
|
||||
}
|
||||
}
|
||||
|
102
app/Ninja/Repositories/ActivityRepository.php
Normal file
102
app/Ninja/Repositories/ActivityRepository.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use DB;
|
||||
use Auth;
|
||||
use Utils;
|
||||
use Request;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Client;
|
||||
|
||||
class ActivityRepository
|
||||
{
|
||||
public function create($entity, $activityTypeId, $balanceChange = 0, $paidToDateChange = 0, $altEntity = null)
|
||||
{
|
||||
if ($entity instanceof Client) {
|
||||
$client = $entity;
|
||||
} elseif ($entity instanceof Invitation) {
|
||||
$client = $entity->invoice->client;
|
||||
} else {
|
||||
$client = $entity->client;
|
||||
}
|
||||
|
||||
// init activity and copy over context
|
||||
$activity = self::getBlank($altEntity ?: $client);
|
||||
$activity = Utils::copyContext($activity, $entity);
|
||||
$activity = Utils::copyContext($activity, $altEntity);
|
||||
|
||||
$activity->client_id = $client->id;
|
||||
$activity->activity_type_id = $activityTypeId;
|
||||
$activity->adjustment = $balanceChange;
|
||||
$activity->balance = $client->balance + $balanceChange;
|
||||
|
||||
$keyField = $entity->getKeyField();
|
||||
$activity->$keyField = $entity->id;
|
||||
|
||||
$activity->ip = Request::getClientIp();
|
||||
$activity->save();
|
||||
|
||||
$client->updateBalances($balanceChange, $paidToDateChange);
|
||||
|
||||
return $activity;
|
||||
}
|
||||
|
||||
private function getBlank($entity)
|
||||
{
|
||||
$activity = new Activity();
|
||||
|
||||
if (Auth::check()) {
|
||||
$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 findByClientId($clientId)
|
||||
{
|
||||
return DB::table('activities')
|
||||
->join('users', 'users.id', '=', 'activities.user_id')
|
||||
->join('clients', 'clients.id', '=', 'activities.client_id')
|
||||
->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||
->leftJoin('invoices', 'invoices.id', '=', 'activities.invoice_id')
|
||||
->leftJoin('payments', 'payments.id', '=', 'activities.payment_id')
|
||||
->leftJoin('credits', 'credits.id', '=', 'activities.credit_id')
|
||||
->where('activities.client_id', '=', $clientId)
|
||||
->where('contacts.is_primary', '=', 1)
|
||||
->whereNull('contacts.deleted_at')
|
||||
->select(
|
||||
'activities.id',
|
||||
'activities.created_at',
|
||||
'activities.contact_id',
|
||||
'activities.activity_type_id',
|
||||
'activities.is_system',
|
||||
'clients.currency_id',
|
||||
'activities.balance',
|
||||
'activities.adjustment',
|
||||
'users.first_name as user_first_name',
|
||||
'users.last_name as user_last_name',
|
||||
'users.email as user_email',
|
||||
'invoices.invoice_number as invoice',
|
||||
'invoices.public_id as invoice_public_id',
|
||||
'invoices.is_recurring',
|
||||
'clients.currency_id',
|
||||
'clients.name as client_name',
|
||||
'clients.public_id as client_public_id',
|
||||
'contacts.id as contact',
|
||||
'contacts.first_name as first_name',
|
||||
'contacts.last_name as last_name',
|
||||
'contacts.email as email',
|
||||
'payments.transaction_reference as payment',
|
||||
'credits.amount as credit');
|
||||
}
|
||||
|
||||
}
|
64
app/Ninja/Repositories/BaseRepository.php
Normal file
64
app/Ninja/Repositories/BaseRepository.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
class BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getInstance()
|
||||
{
|
||||
$className = $this->getClassName();
|
||||
return new $className();
|
||||
}
|
||||
|
||||
private function getEventClass($entity, $type)
|
||||
{
|
||||
return 'App\Events\\' . ucfirst($entity->getEntityType()) . 'Was' . $type;
|
||||
}
|
||||
|
||||
public function archive($entity)
|
||||
{
|
||||
$entity->delete();
|
||||
|
||||
$className = $this->getEventClass($entity, 'Archived');
|
||||
event(new $className($entity));
|
||||
}
|
||||
|
||||
public function restore($entity)
|
||||
{
|
||||
$fromDeleted = false;
|
||||
$entity->restore();
|
||||
|
||||
if ($entity->is_deleted) {
|
||||
$fromDeleted = true;
|
||||
$entity->is_deleted = false;
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
$className = $this->getEventClass($entity, 'Restored');
|
||||
event(new $className($entity, $fromDeleted));
|
||||
}
|
||||
|
||||
public function delete($entity)
|
||||
{
|
||||
$entity->is_deleted = true;
|
||||
$entity->save();
|
||||
|
||||
$entity->delete();
|
||||
|
||||
$className = $this->getEventClass($entity, 'Deleted');
|
||||
event(new $className($entity));
|
||||
}
|
||||
|
||||
public function findByPublicIds($ids)
|
||||
{
|
||||
return $this->getInstance()->scope($ids)->get();
|
||||
}
|
||||
|
||||
public function findByPublicIdsWithTrashed($ids)
|
||||
{
|
||||
return $this->getInstance()->scope($ids)->withTrashed()->get();
|
||||
}
|
||||
}
|
@ -1,11 +1,17 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
use App\Models\Client;
|
||||
use App\Models\Contact;
|
||||
use App\Models\Activity;
|
||||
|
||||
class ClientRepository
|
||||
class ClientRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Client';
|
||||
}
|
||||
|
||||
public function find($filter = null)
|
||||
{
|
||||
$query = \DB::table('clients')
|
||||
@ -30,179 +36,36 @@ class ClientRepository
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getErrors($data)
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
$contact = isset($data['contacts']) ? (array) $data['contacts'][0] : (isset($data['contact']) ? $data['contact'] : []);
|
||||
$validator = \Validator::make($contact, [
|
||||
'email' => 'email|required_without:first_name',
|
||||
'first_name' => 'required_without:email',
|
||||
]);
|
||||
if ($validator->fails()) {
|
||||
return $validator->messages();
|
||||
}
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function save($publicId, $data, $notify = true)
|
||||
{
|
||||
if (!$publicId || $publicId == "-1") {
|
||||
if (!$publicId || $publicId == '-1') {
|
||||
$client = Client::createNew();
|
||||
$contact = Contact::createNew();
|
||||
$contact->is_primary = true;
|
||||
$contact->send_invoice = true;
|
||||
} else {
|
||||
$client = Client::scope($publicId)->with('contacts')->firstOrFail();
|
||||
$contact = $client->contacts()->where('is_primary', '=', true)->firstOrFail();
|
||||
}
|
||||
|
||||
if (isset($data['name'])) {
|
||||
$client->name = trim($data['name']);
|
||||
}
|
||||
if (isset($data['id_number'])) {
|
||||
$client->id_number = trim($data['id_number']);
|
||||
}
|
||||
if (isset($data['vat_number'])) {
|
||||
$client->vat_number = trim($data['vat_number']);
|
||||
}
|
||||
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'] : null;
|
||||
}
|
||||
if (isset($data['language_id'])) {
|
||||
$client->language_id = $data['language_id'] ? $data['language_id'] : null;
|
||||
}
|
||||
if (isset($data['payment_terms'])) {
|
||||
$client->payment_terms = $data['payment_terms'];
|
||||
}
|
||||
if (isset($data['website'])) {
|
||||
$client->website = trim($data['website']);
|
||||
}
|
||||
|
||||
$client->fill($data);
|
||||
$client->save();
|
||||
|
||||
$isPrimary = true;
|
||||
$first = true;
|
||||
$contacts = isset($data['contact']) ? [$data['contact']] : $data['contacts'];
|
||||
$contactIds = [];
|
||||
|
||||
if (isset($data['contact'])) {
|
||||
$info = $data['contact'];
|
||||
if (isset($info['email'])) {
|
||||
$contact->email = trim($info['email']);
|
||||
}
|
||||
if (isset($info['first_name'])) {
|
||||
$contact->first_name = trim($info['first_name']);
|
||||
}
|
||||
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);
|
||||
} else {
|
||||
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($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();
|
||||
}
|
||||
}
|
||||
foreach ($data['contacts'] as $contact) {
|
||||
$contact = $client->addContact($contact, $first);
|
||||
$contactIds[] = $contact->public_id;
|
||||
$first = false;
|
||||
}
|
||||
|
||||
$client->save();
|
||||
|
||||
if (!$publicId || $publicId == "-1") {
|
||||
Activity::createClient($client, $notify);
|
||||
foreach ($client->contacts as $contact) {
|
||||
if (!in_array($contact->public_id, $contactIds)) {
|
||||
$contact->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
public function bulk($ids, $action)
|
||||
{
|
||||
$clients = Client::withTrashed()->scope($ids)->get();
|
||||
|
||||
foreach ($clients as $client) {
|
||||
if ($action == 'restore') {
|
||||
$client->restore();
|
||||
|
||||
$client->is_deleted = false;
|
||||
$client->save();
|
||||
} else {
|
||||
if ($action == 'delete') {
|
||||
$client->is_deleted = true;
|
||||
$client->save();
|
||||
}
|
||||
|
||||
$client->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return count($clients);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,17 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use Utils;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Client;
|
||||
use Utils;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
|
||||
class CreditRepository
|
||||
class CreditRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Credit';
|
||||
}
|
||||
|
||||
public function find($clientPublicId = null, $filter = null)
|
||||
{
|
||||
$query = \DB::table('credits')
|
||||
@ -33,8 +39,10 @@ class CreditRepository
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function save($publicId = null, $input)
|
||||
public function save($input)
|
||||
{
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
if ($publicId) {
|
||||
$credit = Credit::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
@ -50,28 +58,4 @@ class CreditRepository
|
||||
|
||||
return $credit;
|
||||
}
|
||||
|
||||
public function bulk($ids, $action)
|
||||
{
|
||||
if (!$ids) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$credits = Credit::withTrashed()->scope($ids)->get();
|
||||
|
||||
foreach ($credits as $credit) {
|
||||
if ($action == 'restore') {
|
||||
$credit->restore();
|
||||
} else {
|
||||
if ($action == 'delete') {
|
||||
$credit->is_deleted = true;
|
||||
$credit->save();
|
||||
}
|
||||
|
||||
$credit->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return count($credits);
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,15 @@ use App\Models\Invitation;
|
||||
use App\Models\Product;
|
||||
use App\Models\Task;
|
||||
use App\Services\PaymentService;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
|
||||
class InvoiceRepository
|
||||
class InvoiceRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Invoice';
|
||||
}
|
||||
|
||||
public function __construct(PaymentService $paymentService)
|
||||
{
|
||||
$this->paymentService = $paymentService;
|
||||
@ -145,10 +151,6 @@ class InvoiceRepository
|
||||
->addColumn('invoice_status_name', function ($model) { return $model->quote_invoice_id ? link_to("invoices/{$model->quote_invoice_id}/edit", trans('texts.converted')) : self::getStatusLabel($model->invoice_status_id, $model->invoice_status_name); })
|
||||
->addColumn('dropdown', function ($model) use ($entityType) {
|
||||
|
||||
if ($model->is_deleted) {
|
||||
return '<div style="height:38px"/>';
|
||||
}
|
||||
|
||||
$str = '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
'.trans('texts.select').' <span class="caret"></span>
|
||||
@ -182,11 +184,14 @@ class InvoiceRepository
|
||||
}
|
||||
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="javascript:archiveEntity('.$model->public_id.')">'.trans("texts.archive_{$entityType}").'</a></li>
|
||||
<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans("texts.delete_{$entityType}").'</a></li>';
|
||||
<li><a href="javascript:archiveEntity('.$model->public_id.')">'.trans("texts.archive_{$entityType}").'</a></li>';
|
||||
|
||||
} else {
|
||||
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans("texts.restore_{$entityType}").'</a></li>
|
||||
<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans("texts.delete_{$entityType}").'</a></li>';
|
||||
$str .= '<li><a href="javascript:restoreEntity('.$model->public_id.')">'.trans("texts.restore_{$entityType}").'</a></li>';
|
||||
}
|
||||
|
||||
if (!$model->is_deleted) {
|
||||
$str .= '<li><a href="javascript:deleteEntity('.$model->public_id.')">'.trans("texts.delete_{$entityType}").'</a></li>';
|
||||
}
|
||||
|
||||
return $str.'</ul>
|
||||
@ -214,57 +219,30 @@ class InvoiceRepository
|
||||
}
|
||||
return "<h4><div class=\"label label-{$class}\">$label</div></h4>";
|
||||
}
|
||||
|
||||
public function getErrors($input)
|
||||
{
|
||||
$contact = (array) $input->client->contacts[0];
|
||||
$rules = [
|
||||
'email' => 'email|required_without:first_name',
|
||||
'first_name' => 'required_without:email',
|
||||
];
|
||||
$validator = \Validator::make($contact, $rules);
|
||||
|
||||
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,
|
||||
'discount' => 'positive',
|
||||
];
|
||||
|
||||
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date']) {
|
||||
$rules['end_date'] = 'after:'.$invoice['start_date'];
|
||||
}
|
||||
|
||||
$validator = \Validator::make($invoice, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $validator;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function save($publicId, $data, $entityType)
|
||||
|
||||
public function save($data)
|
||||
{
|
||||
$account = \Auth::user()->account;
|
||||
$publicId = isset($data['public_id']) ? $data['public_id'] : false;
|
||||
|
||||
$isNew = !$publicId || $publicId == '-1';
|
||||
|
||||
if ($publicId) {
|
||||
$invoice = Invoice::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
if ($data['is_recurring']) {
|
||||
if ($isNew) {
|
||||
$entityType = ENTITY_INVOICE;
|
||||
if (isset($data['is_recurring']) && $data['is_recurring']) {
|
||||
$entityType = ENTITY_RECURRING_INVOICE;
|
||||
} elseif (isset($data['is_quote']) && $data['is_quote']) {
|
||||
$entityType = ENTITY_QUOTE;
|
||||
}
|
||||
$invoice = $account->createInvoice($entityType, $data['client_id']);
|
||||
} else {
|
||||
$invoice = Invoice::scope($publicId)->firstOrFail();
|
||||
}
|
||||
|
||||
if ((isset($data['set_default_terms']) && $data['set_default_terms'])
|
||||
|| (isset($data['set_default_footer']) && $data['set_default_footer'])) {
|
||||
if (isset($data['set_default_terms']) && $data['set_default_terms']) {
|
||||
$account->invoice_terms = trim($data['terms']);
|
||||
$account->{"{$entityType}_terms"} = trim($data['terms']);
|
||||
}
|
||||
if (isset($data['set_default_footer']) && $data['set_default_footer']) {
|
||||
$account->invoice_footer = trim($data['invoice_footer']);
|
||||
@ -280,7 +258,7 @@ class InvoiceRepository
|
||||
$invoice->is_amount_discount = $data['is_amount_discount'] ? true : false;
|
||||
$invoice->partial = round(Utils::parseFloat($data['partial']), 2);
|
||||
$invoice->invoice_date = isset($data['invoice_date_sql']) ? $data['invoice_date_sql'] : Utils::toSqlDate($data['invoice_date']);
|
||||
$invoice->has_tasks = isset($data['has_tasks']) ? $data['has_tasks'] : false;
|
||||
$invoice->has_tasks = isset($data['has_tasks']) ? ($data['has_tasks'] ? true : false) : false;
|
||||
|
||||
if ($invoice->is_recurring) {
|
||||
if ($invoice->start_date && $invoice->start_date != Utils::toSqlDate($data['start_date'])) {
|
||||
@ -362,12 +340,20 @@ class InvoiceRepository
|
||||
$total *= (100 - $invoice->discount) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
$invoice->custom_value1 = round($data['custom_value1'], 2);
|
||||
$invoice->custom_value2 = round($data['custom_value2'], 2);
|
||||
$invoice->custom_taxes1 = $data['custom_taxes1'] ? true : false;
|
||||
$invoice->custom_taxes2 = $data['custom_taxes2'] ? true : false;
|
||||
|
||||
|
||||
if (isset($data['custom_value1'])) {
|
||||
$invoice->custom_value1 = round($data['custom_value1'], 2);
|
||||
if ($isNew) {
|
||||
$invoice->custom_taxes1 = $account->custom_invoice_taxes1 ?: false;
|
||||
}
|
||||
}
|
||||
if (isset($data['custom_value2'])) {
|
||||
$invoice->custom_value2 = round($data['custom_value2'], 2);
|
||||
if ($isNew) {
|
||||
$invoice->custom_taxes2 = $account->custom_invoice_taxes2 ?: false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data['custom_text_value1'])) {
|
||||
$invoice->custom_text_value1 = trim($data['custom_text_value1']);
|
||||
}
|
||||
@ -543,31 +529,9 @@ class InvoiceRepository
|
||||
return $clone;
|
||||
}
|
||||
|
||||
public function bulk($ids, $action, $statusId = false)
|
||||
public function markSent($invoice)
|
||||
{
|
||||
if (!$ids) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$invoices = Invoice::withTrashed()->scope($ids)->get();
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
if ($action == 'mark') {
|
||||
$invoice->invoice_status_id = $statusId;
|
||||
$invoice->save();
|
||||
} elseif ($action == 'restore') {
|
||||
$invoice->restore();
|
||||
} else {
|
||||
if ($action == 'delete') {
|
||||
$invoice->is_deleted = true;
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
$invoice->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return count($invoices);
|
||||
$invoice->markInvitationsSent();
|
||||
}
|
||||
|
||||
public function findInvoiceByInvitation($invitationKey)
|
||||
@ -637,10 +601,10 @@ class InvoiceRepository
|
||||
$invoice->tax_name = $recurInvoice->tax_name;
|
||||
$invoice->tax_rate = $recurInvoice->tax_rate;
|
||||
$invoice->invoice_design_id = $recurInvoice->invoice_design_id;
|
||||
$invoice->custom_value1 = $recurInvoice->custom_value1;
|
||||
$invoice->custom_value2 = $recurInvoice->custom_value2;
|
||||
$invoice->custom_taxes1 = $recurInvoice->custom_taxes1;
|
||||
$invoice->custom_taxes2 = $recurInvoice->custom_taxes2;
|
||||
$invoice->custom_value1 = $recurInvoice->custom_value1 ?: 0;
|
||||
$invoice->custom_value2 = $recurInvoice->custom_value2 ?: 0;
|
||||
$invoice->custom_taxes1 = $recurInvoice->custom_taxes1 ?: 0;
|
||||
$invoice->custom_taxes2 = $recurInvoice->custom_taxes2 ?: 0;
|
||||
$invoice->custom_text_value1 = $recurInvoice->custom_text_value1;
|
||||
$invoice->custom_text_value2 = $recurInvoice->custom_text_value2;
|
||||
$invoice->is_amount_discount = $recurInvoice->is_amount_discount;
|
||||
|
@ -1,13 +1,19 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use Utils;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Client;
|
||||
use Utils;
|
||||
use App\Ninja\Repositories\BaseRepository;
|
||||
|
||||
class PaymentRepository
|
||||
class PaymentRepository extends BaseRepository
|
||||
{
|
||||
public function getClassName()
|
||||
{
|
||||
return 'App\Models\Payment';
|
||||
}
|
||||
|
||||
public function find($clientPublicId = null, $filter = null)
|
||||
{
|
||||
$query = \DB::table('payments')
|
||||
@ -21,11 +27,29 @@ class PaymentRepository
|
||||
->where('clients.deleted_at', '=', null)
|
||||
->where('contacts.is_primary', '=', true)
|
||||
->where('contacts.deleted_at', '=', null)
|
||||
->select('payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'payment_types.name as payment_type', 'payments.account_gateway_id', 'payments.deleted_at', 'payments.is_deleted', 'invoices.is_deleted as invoice_is_deleted', 'gateways.name as gateway_name');
|
||||
->where('invoices.deleted_at', '=', null)
|
||||
->select('payments.public_id',
|
||||
'payments.transaction_reference',
|
||||
'clients.name as client_name',
|
||||
'clients.public_id as client_public_id',
|
||||
'payments.amount',
|
||||
'payments.payment_date',
|
||||
'invoices.public_id as invoice_public_id',
|
||||
'invoices.invoice_number',
|
||||
'clients.currency_id',
|
||||
'contacts.first_name',
|
||||
'contacts.last_name',
|
||||
'contacts.email',
|
||||
'payment_types.name as payment_type',
|
||||
'payments.account_gateway_id',
|
||||
'payments.deleted_at',
|
||||
'payments.is_deleted',
|
||||
'invoices.is_deleted as invoice_is_deleted',
|
||||
'gateways.name as gateway_name'
|
||||
);
|
||||
|
||||
if (!\Session::get('show_trash:payment')) {
|
||||
$query->where('payments.deleted_at', '=', null)
|
||||
->where('invoices.deleted_at', '=', null);
|
||||
$query->where('payments.deleted_at', '=', null);
|
||||
}
|
||||
|
||||
if ($clientPublicId) {
|
||||
@ -68,34 +92,10 @@ class PaymentRepository
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getErrors($input)
|
||||
{
|
||||
$rules = array(
|
||||
'client' => 'required',
|
||||
'invoice' => 'required',
|
||||
'amount' => 'required',
|
||||
);
|
||||
|
||||
if ($input['payment_type_id'] == PAYMENT_TYPE_CREDIT) {
|
||||
$rules['payment_type_id'] = 'has_credit:'.$input['client'].','.$input['amount'];
|
||||
}
|
||||
|
||||
if (isset($input['invoice']) && $input['invoice']) {
|
||||
$invoice = Invoice::scope($input['invoice'])->firstOrFail();
|
||||
$rules['amount'] .= "|less_than:{$invoice->balance}";
|
||||
}
|
||||
|
||||
$validator = \Validator::make($input, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $validator;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function save($publicId = null, $input)
|
||||
public function save($input)
|
||||
{
|
||||
$publicId = isset($input['public_id']) ? $input['public_id'] : false;
|
||||
|
||||
if ($publicId) {
|
||||
$payment = Payment::scope($publicId)->firstOrFail();
|
||||
} else {
|
||||
@ -146,27 +146,23 @@ class PaymentRepository
|
||||
return $payment;
|
||||
}
|
||||
|
||||
public function bulk($ids, $action)
|
||||
public function delete($payment)
|
||||
{
|
||||
if (!$ids) {
|
||||
return 0;
|
||||
if ($payment->invoice->is_deleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$payments = Payment::withTrashed()->scope($ids)->get();
|
||||
|
||||
foreach ($payments as $payment) {
|
||||
if ($action == 'restore') {
|
||||
$payment->restore();
|
||||
} else {
|
||||
if ($action == 'delete') {
|
||||
$payment->is_deleted = true;
|
||||
$payment->save();
|
||||
}
|
||||
|
||||
$payment->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return count($payments);
|
||||
parent::delete($payment);
|
||||
}
|
||||
|
||||
public function restore($payment)
|
||||
{
|
||||
if ($payment->invoice->is_deleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parent::restore($payment);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
31
app/Ninja/Repositories/ReferralRepository.php
Normal file
31
app/Ninja/Repositories/ReferralRepository.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php namespace App\Ninja\Repositories;
|
||||
|
||||
use DB;
|
||||
use Utils;
|
||||
|
||||
class ReferralRepository
|
||||
{
|
||||
public function getCounts($userId)
|
||||
{
|
||||
$accounts = DB::table('accounts')
|
||||
->where('referral_user_id', $userId)
|
||||
->get(['id', 'pro_plan_paid']);
|
||||
|
||||
$counts = [
|
||||
'free' => 0,
|
||||
'pro' => 0
|
||||
];
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$counts['free']++;
|
||||
if (Utils::withinPastYear($account->pro_plan_paid)) {
|
||||
$counts['pro']++;
|
||||
}
|
||||
}
|
||||
|
||||
return $counts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
16
app/Ninja/Serializers/ArraySerializer.php
Normal file
16
app/Ninja/Serializers/ArraySerializer.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php namespace App\Ninja\Serializers;
|
||||
|
||||
use League\Fractal\Serializer\ArraySerializer as FractalArraySerializer;
|
||||
|
||||
class ArraySerializer extends FractalArraySerializer
|
||||
{
|
||||
public function collection($resourceKey, array $data)
|
||||
{
|
||||
return ($resourceKey && $resourceKey !== 'data') ? array($resourceKey => $data) : $data;
|
||||
}
|
||||
|
||||
public function item($resourceKey, array $data)
|
||||
{
|
||||
return ($resourceKey && $resourceKey !== 'data') ? array($resourceKey => $data) : $data;
|
||||
}
|
||||
}
|
27
app/Ninja/Transformers/AccountTransformer.php
Normal file
27
app/Ninja/Transformers/AccountTransformer.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php namespace App\Ninja\Transformers;
|
||||
|
||||
use App\Models\Account;
|
||||
use League\Fractal;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
class AccountTransformer extends TransformerAbstract
|
||||
{
|
||||
protected $defaultIncludes = [
|
||||
'users'
|
||||
];
|
||||
|
||||
public function includeUsers($account)
|
||||
{
|
||||
$users = $account->users;
|
||||
|
||||
return $this->collection($users, new UserTransformer);
|
||||
}
|
||||
|
||||
public function transform(Account $account)
|
||||
{
|
||||
return [
|
||||
'id' => (int) $account->id,
|
||||
'name' => $account->name,
|
||||
];
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user