mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-31 19:34:35 -04:00
Expense and Vendors (#3226)
* add expenses, vendors and vendor_contacts along with factories and test data * padding out vendors, expenses * Minor fixes * Add Expense and Company TransformerS
This commit is contained in:
parent
27d06a2ae1
commit
84642bf035
@ -241,7 +241,6 @@ class CreateTestData extends Command
|
|||||||
'company_id' => $company->id
|
'company_id' => $company->id
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
factory(\App\Models\ClientContact::class, 1)->create([
|
factory(\App\Models\ClientContact::class, 1)->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'client_id' => $client->id,
|
'client_id' => $client->id,
|
||||||
@ -262,9 +261,53 @@ class CreateTestData extends Command
|
|||||||
for ($x=0; $x<$y; $x++) {
|
for ($x=0; $x<$y; $x++) {
|
||||||
$this->createInvoice($client);
|
$this->createInvoice($client);
|
||||||
$this->createQuote($client);
|
$this->createQuote($client);
|
||||||
|
$this->createExpense($client);
|
||||||
|
$this->createVendor($client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function createExpense($client)
|
||||||
|
{
|
||||||
|
|
||||||
|
factory(\App\Models\Expense::class, rand(10, 50))->create([
|
||||||
|
'user_id' => $client->user->id,
|
||||||
|
'client_id' => $client->id,
|
||||||
|
'company_id' => $client->company->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createVendor($client)
|
||||||
|
{
|
||||||
|
|
||||||
|
$vendor = factory(\App\Models\Vendor::class)->create([
|
||||||
|
'user_id' => $client->user->id,
|
||||||
|
'company_id' => $client->company->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
factory(\App\Models\VendorContact::class, 1)->create([
|
||||||
|
'user_id' => $client->user->id,
|
||||||
|
'vendor_id' => $vendor->id,
|
||||||
|
'company_id' => $client->company->id,
|
||||||
|
'is_primary' => 1
|
||||||
|
]);
|
||||||
|
|
||||||
|
factory(\App\Models\VendorContact::class, rand(1, 50))->create([
|
||||||
|
'user_id' => $client->user->id,
|
||||||
|
'vendor_id' => $vendor->id,
|
||||||
|
'company_id' => $client->company->id,
|
||||||
|
'is_primary' => 0
|
||||||
|
]);
|
||||||
|
|
||||||
|
factory(\App\Models\Vendor::class, rand(10, 50))->create([
|
||||||
|
'user_id' => $client->user->id,
|
||||||
|
'company_id' => $client->company->id
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private function createInvoice($client)
|
private function createInvoice($client)
|
||||||
{
|
{
|
||||||
$faker = \Faker\Factory::create();
|
$faker = \Faker\Factory::create();
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace App\DataMapper;
|
namespace App\DataMapper;
|
||||||
|
|
||||||
use Parsedown;
|
use League\CommonMark\CommonMarkConverter;
|
||||||
|
|
||||||
class EmailTemplateDefaults
|
class EmailTemplateDefaults
|
||||||
{
|
{
|
||||||
@ -23,7 +23,14 @@ class EmailTemplateDefaults
|
|||||||
|
|
||||||
public static function emailInvoiceTemplate()
|
public static function emailInvoiceTemplate()
|
||||||
{
|
{
|
||||||
return Parsedown::instance()->line(self::transformText('invoice_message'));
|
$converter = new CommonMarkConverter([
|
||||||
|
'html_input' => 'strip',
|
||||||
|
'allow_unsafe_links' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $converter->convertToHtml(self::transformText('invoice_message'));
|
||||||
|
|
||||||
|
//return Parsedown::instance()->line(self::transformText('invoice_message'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailQuoteSubject()
|
public static function emailQuoteSubject()
|
||||||
@ -35,7 +42,13 @@ class EmailTemplateDefaults
|
|||||||
|
|
||||||
public static function emailQuoteTemplate()
|
public static function emailQuoteTemplate()
|
||||||
{
|
{
|
||||||
return Parsedown::instance()->line(self::transformText('quote_message'));
|
$converter = new CommonMarkConverter([
|
||||||
|
'html_input' => 'strip',
|
||||||
|
'allow_unsafe_links' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $converter->convertToHtml(self::transformText('quote_message'));
|
||||||
|
//return Parsedown::instance()->line(self::transformText('quote_message'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailPaymentSubject()
|
public static function emailPaymentSubject()
|
||||||
@ -56,7 +69,7 @@ class EmailTemplateDefaults
|
|||||||
|
|
||||||
public static function emailReminder1Template()
|
public static function emailReminder1Template()
|
||||||
{
|
{
|
||||||
return Parsedown::instance()->line('First Email Reminder Text');
|
// return Parsedown::instance()->line('First Email Reminder Text');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailReminder2Subject()
|
public static function emailReminder2Subject()
|
||||||
@ -67,7 +80,7 @@ class EmailTemplateDefaults
|
|||||||
|
|
||||||
public static function emailReminder2Template()
|
public static function emailReminder2Template()
|
||||||
{
|
{
|
||||||
return Parsedown::instance()->line('Second Email Reminder Text');
|
// return Parsedown::instance()->line('Second Email Reminder Text');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailReminder3Subject()
|
public static function emailReminder3Subject()
|
||||||
@ -78,7 +91,7 @@ class EmailTemplateDefaults
|
|||||||
|
|
||||||
public static function emailReminder3Template()
|
public static function emailReminder3Template()
|
||||||
{
|
{
|
||||||
return Parsedown::instance()->line('Third Email Reminder Text');
|
// return Parsedown::instance()->line('Third Email Reminder Text');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function emailReminderEndlessSubject()
|
public static function emailReminderEndlessSubject()
|
||||||
|
39
app/Factory/ExpenseFactory.php
Normal file
39
app/Factory/ExpenseFactory.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Factory;
|
||||||
|
|
||||||
|
use App\DataMapper\ClientSettings;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\Models\Expense;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class ExpenseFactory
|
||||||
|
{
|
||||||
|
public static function create(int $company_id, int $user_id) :Expense
|
||||||
|
{
|
||||||
|
$expense = new Expense();
|
||||||
|
$expense->user_id = $user_id;
|
||||||
|
$expense->company_id = $company_id;
|
||||||
|
$expense->is_deleted = false;
|
||||||
|
$expense->should_be_invoiced = false;
|
||||||
|
$expense->tax_name1 = '';
|
||||||
|
$expense->tax_rate1 = 0;
|
||||||
|
$expense->tax_name2 = '';
|
||||||
|
$expense->tax_rate2 = 0;
|
||||||
|
$expense->tax_name3 = '';
|
||||||
|
$expense->tax_rate3 = 0;
|
||||||
|
$expense->expense_date = null;
|
||||||
|
$expense->payment_date = null;
|
||||||
|
|
||||||
|
return $expense;
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,8 @@ class InvoiceFactory
|
|||||||
$invoice->tax_rate1 = 0;
|
$invoice->tax_rate1 = 0;
|
||||||
$invoice->tax_name2 = '';
|
$invoice->tax_name2 = '';
|
||||||
$invoice->tax_rate2 = 0;
|
$invoice->tax_rate2 = 0;
|
||||||
|
$invoice->tax_name3 = '';
|
||||||
|
$invoice->tax_rate3 = 0;
|
||||||
$invoice->custom_value1 = 0;
|
$invoice->custom_value1 = 0;
|
||||||
$invoice->custom_value2 = 0;
|
$invoice->custom_value2 = 0;
|
||||||
$invoice->custom_value3 = 0;
|
$invoice->custom_value3 = 0;
|
||||||
|
28
app/Factory/VendorContactFactory.php
Normal file
28
app/Factory/VendorContactFactory.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Factory;
|
||||||
|
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
|
||||||
|
class VendorContactFactory
|
||||||
|
{
|
||||||
|
public static function create(int $company_id, int $user_id) :VendorContact
|
||||||
|
{
|
||||||
|
$vendor_contact = new VendorContact;
|
||||||
|
$vendor_contact->first_name = "";
|
||||||
|
$vendor_contact->user_id = $user_id;
|
||||||
|
$vendor_contact->company_id = $company_id;
|
||||||
|
$vendor_contact->id = 0;
|
||||||
|
|
||||||
|
return $vendor_contact;
|
||||||
|
}
|
||||||
|
}
|
37
app/Factory/VendorFactory.php
Normal file
37
app/Factory/VendorFactory.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Factory;
|
||||||
|
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class VendorFactory
|
||||||
|
{
|
||||||
|
public static function create(int $company_id, int $user_id) :Vendor
|
||||||
|
{
|
||||||
|
$vendor = new Vendor;
|
||||||
|
$vendor->company_id = $company_id;
|
||||||
|
$vendor->user_id = $user_id;
|
||||||
|
$vendor->name = '';
|
||||||
|
$vendor->website = '';
|
||||||
|
$vendor->private_notes = '';
|
||||||
|
$vendor->balance = 0;
|
||||||
|
$vendor->paid_to_date = 0;
|
||||||
|
$vendor->country_id = 4;
|
||||||
|
$vendor->is_deleted = 0;
|
||||||
|
|
||||||
|
$vendor_contact = VendorContactFactory::create($company_id, $user_id);
|
||||||
|
$vendor->contacts->add($vendor_contact);
|
||||||
|
|
||||||
|
return $vendor;
|
||||||
|
}
|
||||||
|
}
|
196
app/Filters/VendorFilters.php
Normal file
196
app/Filters/VendorFilters.php
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Gate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VendorFilters
|
||||||
|
*/
|
||||||
|
class VendorFilters extends QueryFilters
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by balance
|
||||||
|
*
|
||||||
|
* @param string $balance
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
|
public function balance(string $balance): Builder
|
||||||
|
{
|
||||||
|
$parts = $this->split($balance);
|
||||||
|
|
||||||
|
return $this->builder->where('balance', $parts->operator, $parts->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter between balances
|
||||||
|
*
|
||||||
|
* @param string balance
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
|
public function between_balance(string $balance): Builder
|
||||||
|
{
|
||||||
|
$parts = explode(":", $balance);
|
||||||
|
|
||||||
|
return $this->builder->whereBetween('balance', [$parts[0], $parts[1]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter based on search text
|
||||||
|
*
|
||||||
|
* @param string query filter
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
* @deprecated
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function filter(string $filter = '') : Builder
|
||||||
|
{
|
||||||
|
if (strlen($filter) == 0) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->where(function ($query) use ($filter) {
|
||||||
|
$query->where('vendors.name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendors.id_number', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendor_contacts.first_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendor_contacts.last_name', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendor_contacts.email', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendors.custom_value1', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendors.custom_value2', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendors.custom_value3', 'like', '%'.$filter.'%')
|
||||||
|
->orWhere('vendors.custom_value4', 'like', '%'.$filter.'%');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the list based on the status
|
||||||
|
* archived, active, deleted
|
||||||
|
*
|
||||||
|
* @param string filter
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
|
public function status(string $filter = '') : Builder
|
||||||
|
{
|
||||||
|
if (strlen($filter) == 0) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = 'vendors';
|
||||||
|
$filters = explode(',', $filter);
|
||||||
|
|
||||||
|
return $this->builder->where(function ($query) use ($filters, $table) {
|
||||||
|
$query->whereNull($table . '.id');
|
||||||
|
|
||||||
|
if (in_array(parent::STATUS_ACTIVE, $filters)) {
|
||||||
|
$query->orWhereNull($table . '.deleted_at');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array(parent::STATUS_ARCHIVED, $filters)) {
|
||||||
|
$query->orWhere(function ($query) use ($table) {
|
||||||
|
$query->whereNotNull($table . '.deleted_at');
|
||||||
|
|
||||||
|
if (! in_array($table, ['users'])) {
|
||||||
|
$query->where($table . '.is_deleted', '=', 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array(parent::STATUS_DELETED, $filters)) {
|
||||||
|
$query->orWhere($table . '.is_deleted', '=', 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the list based on $sort
|
||||||
|
*
|
||||||
|
* @param string sort formatted as column|asc
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
|
public function sort(string $sort) : Builder
|
||||||
|
{
|
||||||
|
$sort_col = explode("|", $sort);
|
||||||
|
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base query
|
||||||
|
*
|
||||||
|
* @param int company_id
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public function baseQuery(int $company_id, User $user) : Builder
|
||||||
|
{
|
||||||
|
$query = DB::table('vendors')
|
||||||
|
->join('companies', 'companies.id', '=', 'vendors.company_id')
|
||||||
|
->join('vendor_contacts', 'vendor_contacts.vendor_id', '=', 'vendors.id')
|
||||||
|
->where('vendors.company_id', '=', $company_id)
|
||||||
|
->where('vendor_contacts.is_primary', '=', true)
|
||||||
|
->where('vendor_contacts.deleted_at', '=', null)
|
||||||
|
//->whereRaw('(vendors.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices
|
||||||
|
->select(
|
||||||
|
// DB::raw('COALESCE(vendors.currency_id, companies.currency_id) currency_id'),
|
||||||
|
DB::raw('COALESCE(vendors.country_id, companies.country_id) country_id'),
|
||||||
|
DB::raw("CONCAT(COALESCE(vendor_contacts.first_name, ''), ' ', COALESCE(vendor_contacts.last_name, '')) contact"),
|
||||||
|
'vendors.id',
|
||||||
|
'vendors.name',
|
||||||
|
'vendors.private_notes',
|
||||||
|
'vendor_contacts.first_name',
|
||||||
|
'vendor_contacts.last_name',
|
||||||
|
'vendors.custom_value1',
|
||||||
|
'vendors.custom_value2',
|
||||||
|
'vendors.custom_value3',
|
||||||
|
'vendors.custom_value4',
|
||||||
|
'vendors.balance',
|
||||||
|
'vendors.last_login',
|
||||||
|
'vendors.created_at',
|
||||||
|
'vendors.created_at as vendor_created_at',
|
||||||
|
'vendor_contacts.phone',
|
||||||
|
'vendor_contacts.email',
|
||||||
|
'vendors.deleted_at',
|
||||||
|
'vendors.is_deleted',
|
||||||
|
'vendors.user_id',
|
||||||
|
'vendors.id_number',
|
||||||
|
'vendors.settings'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the user does not have permissions to view all invoices
|
||||||
|
* limit the user to only the invoices they have created
|
||||||
|
*/
|
||||||
|
if (Gate::denies('view-list', Vendor::class)) {
|
||||||
|
$query->where('vendors.user_id', '=', $user->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the query by the users company ID
|
||||||
|
*
|
||||||
|
* @param $company_id The company Id
|
||||||
|
* @return Illuminate\Database\Query\Builder
|
||||||
|
*/
|
||||||
|
public function entityFilter()
|
||||||
|
{
|
||||||
|
|
||||||
|
//return $this->builder->whereCompanyId(auth()->user()->company()->id);
|
||||||
|
return $this->builder->company();
|
||||||
|
}
|
||||||
|
}
|
@ -86,6 +86,8 @@ class BaseController extends Controller
|
|||||||
//'company.payments',
|
//'company.payments',
|
||||||
'company.payments.paymentables',
|
'company.payments.paymentables',
|
||||||
'company.quotes',
|
'company.quotes',
|
||||||
|
'company.vendors',
|
||||||
|
'company.expenses',
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
$include = [
|
$include = [
|
||||||
|
510
app/Http/Controllers/ExpenseController.php
Normal file
510
app/Http/Controllers/ExpenseController.php
Normal file
@ -0,0 +1,510 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Filters\VendorFilters;
|
||||||
|
use App\Jobs\Entity\ActionEntity;
|
||||||
|
use App\Jobs\Util\ProcessBulk;
|
||||||
|
use App\Jobs\Util\UploadAvatar;
|
||||||
|
use App\Models\Country;
|
||||||
|
use App\Models\Currency;
|
||||||
|
use App\Models\Size;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Repositories\BaseRepository;
|
||||||
|
use App\Transformers\VendorTransformer;
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VendorController
|
||||||
|
* @package App\Http\Controllers
|
||||||
|
* @covers App\Http\Controllers\VendorController
|
||||||
|
*/
|
||||||
|
class VendorController extends BaseController
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
use Uploadable;
|
||||||
|
use BulkOptions;
|
||||||
|
|
||||||
|
protected $entity_type = Vendor::class;
|
||||||
|
|
||||||
|
protected $entity_transformer = VendorTransformer::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Vendorepository
|
||||||
|
*/
|
||||||
|
protected $vendor_repo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VendorController constructor.
|
||||||
|
* @param VendorRepository $vendorRepo
|
||||||
|
*/
|
||||||
|
public function __construct(VendorRepository $vendor_repo)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->vendor_repo = $vendor_repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors",
|
||||||
|
* operationId="getVendors",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Gets a list of vendors",
|
||||||
|
* description="Lists vendors, search and filters allow fine grained lists to be generated.
|
||||||
|
|
||||||
|
Query parameters can be added to performed more fine grained filtering of the vendors, these are handled by the VendorFilters class which defines the methods available",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="A list of vendors",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function index(VendorFilters $filters)
|
||||||
|
{
|
||||||
|
$vendors = Vendor::filter($filters);
|
||||||
|
|
||||||
|
return $this->listResponse($vendors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors/{id}",
|
||||||
|
* operationId="showVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Shows a client",
|
||||||
|
* description="Displays a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the vendor object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function show(ShowVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors/{id}/edit",
|
||||||
|
* operationId="editVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Shows a client for editting",
|
||||||
|
* description="Displays a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function edit(EditVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param App\Models\Vendor $vendor
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/vendors/{id}",
|
||||||
|
* operationId="updateVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Updates a client",
|
||||||
|
* description="Handles the updating of a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function update(UpdateVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
if($request->entityIsDeleted($vendor))
|
||||||
|
return $request->disallowUpdate();
|
||||||
|
|
||||||
|
$vendor = $this->client_repo->save($request->all(), $vendor);
|
||||||
|
|
||||||
|
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
|
||||||
|
|
||||||
|
return $this->itemResponse($vendor->fresh());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors/create",
|
||||||
|
* operationId="getVendorsCreate",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Gets a new blank client object",
|
||||||
|
* description="Returns a blank object with default values",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="A blank client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function create(CreateVendorRequest $request)
|
||||||
|
{
|
||||||
|
$vendor = VendorFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||||
|
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/vendors",
|
||||||
|
* operationId="storeVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Adds a client",
|
||||||
|
* description="Adds an client to a company",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the saved client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function store(StoreVendorRequest $request)
|
||||||
|
{
|
||||||
|
$vendor = $this->client_repo->save($request->all(), VendorFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||||
|
|
||||||
|
$vendor->load('contacts', 'primary_contact');
|
||||||
|
|
||||||
|
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
|
||||||
|
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/v1/vendors/{id}",
|
||||||
|
* operationId="deleteVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Deletes a client",
|
||||||
|
* description="Handles the deletion of a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns a HTTP status",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function destroy(DestroyVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
//may not need these destroy routes as we are using actions to 'archive/delete'
|
||||||
|
$vendor->delete();
|
||||||
|
|
||||||
|
return response()->json([], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform bulk actions on the list view
|
||||||
|
*
|
||||||
|
* @param BulkVendorRequest $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/vendors/bulk",
|
||||||
|
* operationId="bulkVendors",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Performs bulk actions on an array of vendors",
|
||||||
|
* description="",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* description="User credentials",
|
||||||
|
* required=true,
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="array",
|
||||||
|
* @OA\Items(
|
||||||
|
* type="integer",
|
||||||
|
* description="Array of hashed IDs to be bulk 'actioned",
|
||||||
|
* example="[0,1,2,3]",
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="The Vendor User response",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function bulk()
|
||||||
|
{
|
||||||
|
$action = request()->input('action');
|
||||||
|
|
||||||
|
$ids = request()->input('ids');
|
||||||
|
$vendors = Vendor::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
|
$vendors->each(function ($vendor, $key) use ($action) {
|
||||||
|
if (auth()->user()->can('edit', $vendor)) {
|
||||||
|
$this->client_repo->{$action}($vendor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->listResponse(Vendor::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a client statement
|
||||||
|
*
|
||||||
|
* @return [type] [description]
|
||||||
|
*/
|
||||||
|
public function statement()
|
||||||
|
{
|
||||||
|
//todo
|
||||||
|
}
|
||||||
|
}
|
@ -71,7 +71,7 @@ class SendingController extends Controller
|
|||||||
|
|
||||||
$send_logs = false;
|
$send_logs = false;
|
||||||
|
|
||||||
if($request->has('send_logs'));
|
if($request->has('send_logs'))
|
||||||
$send_logs = $request->input('send_logs');
|
$send_logs = $request->input('send_logs');
|
||||||
|
|
||||||
Mail::to(config('ninja.contact.ninja_official_contact'))
|
Mail::to(config('ninja.contact.ninja_official_contact'))
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Parsedown;
|
use League\CommonMark\CommonMarkConverter;
|
||||||
|
|
||||||
class TemplateController extends BaseController
|
class TemplateController extends BaseController
|
||||||
{
|
{
|
||||||
@ -106,9 +106,14 @@ class TemplateController extends BaseController
|
|||||||
$subject = request()->input('subject');
|
$subject = request()->input('subject');
|
||||||
$body = request()->input('body');
|
$body = request()->input('body');
|
||||||
|
|
||||||
|
$converter = new CommonMarkConverter([
|
||||||
|
'html_input' => 'strip',
|
||||||
|
'allow_unsafe_links' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'subject' => request()->input('subject'),
|
'subject' => request()->input('subject'),
|
||||||
'body' => Parsedown::instance()->text(request()->input('body')),
|
'body' => $converter->convertToHtml(request()->input('body')),
|
||||||
];
|
];
|
||||||
|
|
||||||
return response()->json($data, 200);
|
return response()->json($data, 200);
|
||||||
|
509
app/Http/Controllers/VendorController.php
Normal file
509
app/Http/Controllers/VendorController.php
Normal file
@ -0,0 +1,509 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Filters\VendorFilters;
|
||||||
|
use App\Jobs\Entity\ActionEntity;
|
||||||
|
use App\Jobs\Util\ProcessBulk;
|
||||||
|
use App\Jobs\Util\UploadAvatar;
|
||||||
|
use App\Models\Country;
|
||||||
|
use App\Models\Currency;
|
||||||
|
use App\Models\Size;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Repositories\BaseRepository;
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\Utils\Traits\Uploadable;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VendorController
|
||||||
|
* @package App\Http\Controllers
|
||||||
|
* @covers App\Http\Controllers\VendorController
|
||||||
|
*/
|
||||||
|
class VendorController extends BaseController
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
use Uploadable;
|
||||||
|
use BulkOptions;
|
||||||
|
|
||||||
|
protected $entity_type = Vendor::class;
|
||||||
|
|
||||||
|
protected $entity_transformer = VendorTransformer::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Vendorepository
|
||||||
|
*/
|
||||||
|
protected $vendor_repo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VendorController constructor.
|
||||||
|
* @param VendorRepository $vendorRepo
|
||||||
|
*/
|
||||||
|
public function __construct(VendorRepository $vendor_repo)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->vendor_repo = $vendor_repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors",
|
||||||
|
* operationId="getVendors",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Gets a list of vendors",
|
||||||
|
* description="Lists vendors, search and filters allow fine grained lists to be generated.
|
||||||
|
|
||||||
|
Query parameters can be added to performed more fine grained filtering of the vendors, these are handled by the VendorFilters class which defines the methods available",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="A list of vendors",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function index(VendorFilters $filters)
|
||||||
|
{
|
||||||
|
$vendors = Vendor::filter($filters);
|
||||||
|
|
||||||
|
return $this->listResponse($vendors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors/{id}",
|
||||||
|
* operationId="showVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Shows a client",
|
||||||
|
* description="Displays a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the vendor object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function show(ShowVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors/{id}/edit",
|
||||||
|
* operationId="editVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Shows a client for editting",
|
||||||
|
* description="Displays a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function edit(EditVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param App\Models\Vendor $vendor
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Put(
|
||||||
|
* path="/api/v1/vendors/{id}",
|
||||||
|
* operationId="updateVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Updates a client",
|
||||||
|
* description="Handles the updating of a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function update(UpdateVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
if($request->entityIsDeleted($vendor))
|
||||||
|
return $request->disallowUpdate();
|
||||||
|
|
||||||
|
$vendor = $this->client_repo->save($request->all(), $vendor);
|
||||||
|
|
||||||
|
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
|
||||||
|
|
||||||
|
return $this->itemResponse($vendor->fresh());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Get(
|
||||||
|
* path="/api/v1/vendors/create",
|
||||||
|
* operationId="getVendorsCreate",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Gets a new blank client object",
|
||||||
|
* description="Returns a blank object with default values",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="A blank client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function create(CreateVendorRequest $request)
|
||||||
|
{
|
||||||
|
$vendor = VendorFactory::create(auth()->user()->company()->id, auth()->user()->id);
|
||||||
|
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/vendors",
|
||||||
|
* operationId="storeVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Adds a client",
|
||||||
|
* description="Adds an client to a company",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns the saved client object",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function store(StoreVendorRequest $request)
|
||||||
|
{
|
||||||
|
$vendor = $this->client_repo->save($request->all(), VendorFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||||
|
|
||||||
|
$vendor->load('contacts', 'primary_contact');
|
||||||
|
|
||||||
|
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
|
||||||
|
|
||||||
|
return $this->itemResponse($vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Delete(
|
||||||
|
* path="/api/v1/vendors/{id}",
|
||||||
|
* operationId="deleteVendor",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Deletes a client",
|
||||||
|
* description="Handles the deletion of a client by id",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* description="The Vendor Hashed ID",
|
||||||
|
* example="D2J234DFA",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="string",
|
||||||
|
* format="string",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Returns a HTTP status",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
*
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function destroy(DestroyVendorRequest $request, Vendor $vendor)
|
||||||
|
{
|
||||||
|
//may not need these destroy routes as we are using actions to 'archive/delete'
|
||||||
|
$vendor->delete();
|
||||||
|
|
||||||
|
return response()->json([], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform bulk actions on the list view
|
||||||
|
*
|
||||||
|
* @param BulkVendorRequest $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @OA\Post(
|
||||||
|
* path="/api/v1/vendors/bulk",
|
||||||
|
* operationId="bulkVendors",
|
||||||
|
* tags={"vendors"},
|
||||||
|
* summary="Performs bulk actions on an array of vendors",
|
||||||
|
* description="",
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||||
|
* @OA\Parameter(ref="#/components/parameters/index"),
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* description="User credentials",
|
||||||
|
* required=true,
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="array",
|
||||||
|
* @OA\Items(
|
||||||
|
* type="integer",
|
||||||
|
* description="Array of hashed IDs to be bulk 'actioned",
|
||||||
|
* example="[0,1,2,3]",
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="The Vendor User response",
|
||||||
|
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||||
|
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Vendor"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=422,
|
||||||
|
* description="Validation error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response="default",
|
||||||
|
* description="Unexpected Error",
|
||||||
|
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function bulk()
|
||||||
|
{
|
||||||
|
$action = request()->input('action');
|
||||||
|
|
||||||
|
$ids = request()->input('ids');
|
||||||
|
$vendors = Vendor::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
|
$vendors->each(function ($vendor, $key) use ($action) {
|
||||||
|
if (auth()->user()->can('edit', $vendor)) {
|
||||||
|
$this->client_repo->{$action}($vendor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->listResponse(Vendor::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a client statement
|
||||||
|
*
|
||||||
|
* @return [type] [description]
|
||||||
|
*/
|
||||||
|
public function statement()
|
||||||
|
{
|
||||||
|
//todo
|
||||||
|
}
|
||||||
|
}
|
47
app/Http/Requests/Vendor/BulkVendorRequest.php
vendored
Normal file
47
app/Http/Requests/Vendor/BulkVendorRequest.php
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Vendor;
|
||||||
|
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
|
||||||
|
class BulkVendorRequest extends FormRequest
|
||||||
|
{
|
||||||
|
use BulkOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
if (!$this->has('action')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->action, $this->getBulkOptions(), true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return auth()->user()->can(auth()->user()->isAdmin(), Vendor::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
$rules = $this->getGlobalRules();
|
||||||
|
|
||||||
|
/** We don't require IDs on bulk storing. */
|
||||||
|
if ($this->action !== self::$STORE_METHOD) {
|
||||||
|
$rules['ids'] = ['required'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
}
|
29
app/Http/Requests/Vendor/CreateVendorRequest.php
vendored
Normal file
29
app/Http/Requests/Vendor/CreateVendorRequest.php
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Vendor;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
|
||||||
|
class CreateVendorRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('create', Vendor::class);
|
||||||
|
}
|
||||||
|
}
|
29
app/Http/Requests/Vendor/DestroyVendorRequest.php
vendored
Normal file
29
app/Http/Requests/Vendor/DestroyVendorRequest.php
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Vendor;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
|
||||||
|
class DestroyVendorRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->vendor);
|
||||||
|
}
|
||||||
|
}
|
39
app/Http/Requests/Vendor/EditVendorRequest.php
vendored
Normal file
39
app/Http/Requests/Vendor/EditVendorRequest.php
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Vendor;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
|
||||||
|
class EditVendorRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public function prepareForValidation()
|
||||||
|
// {
|
||||||
|
// $input = $this->all();
|
||||||
|
|
||||||
|
// //$input['id'] = $this->encodePrimaryKey($input['id']);
|
||||||
|
|
||||||
|
// $this->replace($input);
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
29
app/Http/Requests/Vendor/ShowVendorRequest.php
vendored
Normal file
29
app/Http/Requests/Vendor/ShowVendorRequest.php
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Vendor;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
|
||||||
|
class ShowVendorRequest extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('view', $this->vendor);
|
||||||
|
}
|
||||||
|
}
|
79
app/Http/Requests/Vendor/StoreVendorRequest.php
vendored
Normal file
79
app/Http/Requests/Vendor/StoreVendorRequest.php
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Vendor;
|
||||||
|
|
||||||
|
use App\DataMapper\VendorSettings;
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Http\ValidationRules\ValidVendorGroupSettingsRule;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class StoreVendorRequest extends Request
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('create', Vendor::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Ensure we have a client name, and that all emails are unique*/
|
||||||
|
//$rules['name'] = 'required|min:1';
|
||||||
|
$rules['id_number'] = 'unique:vendors,id_number,' . $this->id . ',id,company_id,' . $this->company_id;
|
||||||
|
//$rules['settings'] = new ValidVendorGroupSettingsRule();
|
||||||
|
$rules['contacts.*.email'] = 'nullable|distinct';
|
||||||
|
|
||||||
|
$contacts = request('contacts');
|
||||||
|
|
||||||
|
if (is_array($contacts)) {
|
||||||
|
for ($i = 0; $i < count($contacts); $i++) {
|
||||||
|
|
||||||
|
//$rules['contacts.' . $i . '.email'] = 'nullable|email|distinct';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function prepareForValidation()
|
||||||
|
{
|
||||||
|
$input = $this->all();
|
||||||
|
|
||||||
|
if (!isset($input['settings'])) {
|
||||||
|
$input['settings'] = VendorSettings::defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$this->replace($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||||
|
//'required' => trans('validation.required', ['attribute' => 'email']),
|
||||||
|
'contacts.*.email.required' => ctrans('validation.email', ['attribute' => 'email']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
73
app/Http/Requests/Vendor/UpdateVendorRequest.php
vendored
Normal file
73
app/Http/Requests/Vendor/UpdateVendorRequest.php
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\Requests\Vendor;
|
||||||
|
|
||||||
|
use App\Http\Requests\Request;
|
||||||
|
use App\Http\ValidationRules\IsDeletedRule;
|
||||||
|
use App\Http\ValidationRules\ValidVendorGroupSettingsRule;
|
||||||
|
use App\Utils\Traits\ChecksEntityStatus;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class UpdateVendorRequest extends Request
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
use ChecksEntityStatus;
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function authorize() : bool
|
||||||
|
{
|
||||||
|
return auth()->user()->can('edit', $this->vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
/* Ensure we have a client name, and that all emails are unique*/
|
||||||
|
|
||||||
|
$rules['country_id'] = 'integer|nullable';
|
||||||
|
//$rules['id_number'] = 'unique:clients,id_number,,id,company_id,' . auth()->user()->company()->id;
|
||||||
|
$rules['id_number'] = 'unique:clients,id_number,' . $this->id . ',id,company_id,' . $this->company_id;
|
||||||
|
$rules['contacts.*.email'] = 'nullable|distinct';
|
||||||
|
|
||||||
|
$contacts = request('contacts');
|
||||||
|
|
||||||
|
if (is_array($contacts)) {
|
||||||
|
// for ($i = 0; $i < count($contacts); $i++) {
|
||||||
|
// // $rules['contacts.' . $i . '.email'] = 'nullable|email|unique:client_contacts,email,' . isset($contacts[$i]['id'].',company_id,'.$this->company_id);
|
||||||
|
// //$rules['contacts.' . $i . '.email'] = 'nullable|email';
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
||||||
|
'email' => ctrans('validation.email', ['attribute' => 'email']),
|
||||||
|
'name.required' => ctrans('validation.required', ['attribute' => 'name']),
|
||||||
|
'required' => ctrans('validation.required', ['attribute' => 'email']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepareForValidation()
|
||||||
|
{
|
||||||
|
$input = $this->all();
|
||||||
|
|
||||||
|
$this->replace($input);
|
||||||
|
}
|
||||||
|
}
|
@ -114,6 +114,14 @@ class Company extends BaseModel
|
|||||||
return $this->hasMany(Client::class)->withTrashed();
|
return $this->hasMany(Client::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function vendors()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Vendor::class)->withTrashed();
|
||||||
|
}
|
||||||
|
|
||||||
public function activities()
|
public function activities()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Activity::class);
|
return $this->hasMany(Activity::class);
|
||||||
|
@ -13,26 +13,51 @@ namespace App\Models;
|
|||||||
|
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Expense extends BaseModel
|
class Expense extends BaseModel
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $guarded = [
|
protected $fillable = [
|
||||||
'id',
|
'client_id',
|
||||||
|
'vendor_id',
|
||||||
|
'expense_currency_id',
|
||||||
|
'expense_date',
|
||||||
|
'invoice_currency_id',
|
||||||
|
'amount',
|
||||||
|
'foreign_amount',
|
||||||
|
'exchange_rate',
|
||||||
|
'private_notes',
|
||||||
|
'public_notes',
|
||||||
|
'bank_id',
|
||||||
|
'transaction_id',
|
||||||
|
'expense_category_id',
|
||||||
|
'tax_rate1',
|
||||||
|
'tax_name1',
|
||||||
|
'tax_rate2',
|
||||||
|
'tax_name2',
|
||||||
|
'tax_rate3',
|
||||||
|
'tax_name3',
|
||||||
|
'payment_date',
|
||||||
|
'payment_type_id',
|
||||||
|
'transaction_reference',
|
||||||
|
'invoice_documents',
|
||||||
|
'should_be_invoiced',
|
||||||
|
'custom_value1',
|
||||||
|
'custom_value2',
|
||||||
|
'custom_value3',
|
||||||
|
'custom_value4',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $appends = ['expense_id'];
|
|
||||||
|
|
||||||
public function getRouteKeyName()
|
protected $casts = [
|
||||||
{
|
'is_deleted' => 'boolean',
|
||||||
return 'expense_id';
|
'updated_at' => 'timestamp',
|
||||||
}
|
'created_at' => 'timestamp',
|
||||||
|
'deleted_at' => 'timestamp',
|
||||||
|
];
|
||||||
|
|
||||||
public function getExpenseIdAttribute()
|
|
||||||
{
|
|
||||||
return $this->encodePrimaryKey($this->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function documents()
|
public function documents()
|
||||||
{
|
{
|
||||||
|
34
app/Models/ExpenseCategory.php
Normal file
34
app/Models/ExpenseCategory.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class ExpenseCategory extends BaseModel
|
||||||
|
{
|
||||||
|
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||||
|
*/
|
||||||
|
public function expense()
|
||||||
|
{
|
||||||
|
return $this->belongsTo('App\Models\Expense');
|
||||||
|
}
|
||||||
|
}
|
73
app/Models/Vendor.php
Normal file
73
app/Models/Vendor.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Vendor extends BaseModel
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
'id_number',
|
||||||
|
'vat_number',
|
||||||
|
'work_phone',
|
||||||
|
'address1',
|
||||||
|
'address2',
|
||||||
|
'city',
|
||||||
|
'state',
|
||||||
|
'postal_code',
|
||||||
|
'country_id',
|
||||||
|
'private_notes',
|
||||||
|
'currency_id',
|
||||||
|
'website',
|
||||||
|
'transaction_name',
|
||||||
|
'custom_value1',
|
||||||
|
'custom_value2',
|
||||||
|
'custom_value3',
|
||||||
|
'custom_value4',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'country_id' => 'string',
|
||||||
|
'currency_id' => 'string',
|
||||||
|
'is_deleted' => 'boolean',
|
||||||
|
'updated_at' => 'timestamp',
|
||||||
|
'created_at' => 'timestamp',
|
||||||
|
'deleted_at' => 'timestamp',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function documents()
|
||||||
|
{
|
||||||
|
return $this->morphMany(Document::class, 'documentable');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function assigned_user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'assigned_user_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function contacts()
|
||||||
|
{
|
||||||
|
return $this->hasMany(VendorContact::class)->orderBy('is_primary', 'desc');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function activities()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Activity::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
135
app/Models/VendorContact.php
Normal file
135
app/Models/VendorContact.php
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\Language;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\ClientContactResetPassword as ResetPasswordNotification;
|
||||||
|
use App\Notifications\ClientContactResetPassword;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Hashids\Hashids;
|
||||||
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
use Illuminate\Contracts\Translation\HasLocalePreference;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Laracasts\Presenter\PresentableTrait;
|
||||||
|
|
||||||
|
class VendorContact extends Authenticatable implements HasLocalePreference
|
||||||
|
{
|
||||||
|
use Notifiable;
|
||||||
|
use MakesHash;
|
||||||
|
use PresentableTrait;
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
|
/* Used to authenticate a vendor */
|
||||||
|
protected $guard = 'vendor';
|
||||||
|
|
||||||
|
/* Allow microtime timestamps */
|
||||||
|
protected $dateFormat = 'Y-m-d H:i:s.u';
|
||||||
|
|
||||||
|
protected $dates = [
|
||||||
|
'deleted_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $appends = [
|
||||||
|
'hashed_id'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $with = [
|
||||||
|
'vendor',
|
||||||
|
'company'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'updated_at' => 'timestamp',
|
||||||
|
'created_at' => 'timestamp',
|
||||||
|
'deleted_at' => 'timestamp',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'first_name',
|
||||||
|
'last_name',
|
||||||
|
'phone',
|
||||||
|
'custom_value1',
|
||||||
|
'custom_value2',
|
||||||
|
'custom_value3',
|
||||||
|
'custom_value4',
|
||||||
|
'email',
|
||||||
|
'is_primary',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function getHashedIdAttribute()
|
||||||
|
{
|
||||||
|
return $this->encodePrimaryKey($this->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContactIdAttribute()
|
||||||
|
{
|
||||||
|
return $this->encodePrimaryKey($this->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function vendor()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Vendor::class)->withTrashed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function primary_contact()
|
||||||
|
{
|
||||||
|
return $this->where('is_primary', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function company()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Company::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class)->withTrashed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendPasswordResetNotification($token)
|
||||||
|
{
|
||||||
|
$this->notify(new ClientContactResetPassword($token));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function preferredLocale()
|
||||||
|
{
|
||||||
|
$languages = Cache::get('languages');
|
||||||
|
|
||||||
|
return $languages->filter(function ($item) {
|
||||||
|
return $item->id == $this->client->getSetting('language_id');
|
||||||
|
})->first()->locale;
|
||||||
|
|
||||||
|
//$lang = Language::find($this->client->getSetting('language_id'));
|
||||||
|
|
||||||
|
//return $lang->locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the model for a bound value.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return \Illuminate\Database\Eloquent\Model|null
|
||||||
|
*/
|
||||||
|
public function resolveRouteBinding($value)
|
||||||
|
{
|
||||||
|
return $this
|
||||||
|
->withTrashed()
|
||||||
|
->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
||||||
|
}
|
||||||
|
}
|
33
app/Policies/ExpensePolicy.php
Normal file
33
app/Policies/ExpensePolicy.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ExpensePolicy
|
||||||
|
* @package App\Policies
|
||||||
|
*/
|
||||||
|
class ExpensePolicy extends EntityPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Checks if the user has create permissions
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function create(User $user) : bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() || $user->hasPermission('create_expense') || $user->hasPermission('create_all');
|
||||||
|
}
|
||||||
|
}
|
33
app/Policies/VendorPolicy.php
Normal file
33
app/Policies/VendorPolicy.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VendorPolicy
|
||||||
|
* @package App\Policies
|
||||||
|
*/
|
||||||
|
class VendorPolicy extends EntityPolicy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Checks if the user has create permissions
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function create(User $user) : bool
|
||||||
|
{
|
||||||
|
return $user->isAdmin() || $user->hasPermission('create_vendor') || $user->hasPermission('create_all');
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ use App\Models\Activity;
|
|||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CompanyGateway;
|
use App\Models\CompanyGateway;
|
||||||
|
use App\Models\Expense;
|
||||||
use App\Models\GroupSetting;
|
use App\Models\GroupSetting;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
@ -24,10 +25,12 @@ use App\Models\RecurringInvoice;
|
|||||||
use App\Models\RecurringQuote;
|
use App\Models\RecurringQuote;
|
||||||
use App\Models\TaxRate;
|
use App\Models\TaxRate;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Models\Vendor;
|
||||||
use App\Policies\ActivityPolicy;
|
use App\Policies\ActivityPolicy;
|
||||||
use App\Policies\ClientPolicy;
|
use App\Policies\ClientPolicy;
|
||||||
use App\Policies\CompanyGatewayPolicy;
|
use App\Policies\CompanyGatewayPolicy;
|
||||||
use App\Policies\CompanyPolicy;
|
use App\Policies\CompanyPolicy;
|
||||||
|
use App\Policies\ExpensePolicy;
|
||||||
use App\Policies\GroupSettingPolicy;
|
use App\Policies\GroupSettingPolicy;
|
||||||
use App\Policies\InvoicePolicy;
|
use App\Policies\InvoicePolicy;
|
||||||
use App\Policies\PaymentPolicy;
|
use App\Policies\PaymentPolicy;
|
||||||
@ -37,6 +40,7 @@ use App\Policies\RecurringInvoicePolicy;
|
|||||||
use App\Policies\RecurringQuotePolicy;
|
use App\Policies\RecurringQuotePolicy;
|
||||||
use App\Policies\TaxRatePolicy;
|
use App\Policies\TaxRatePolicy;
|
||||||
use App\Policies\UserPolicy;
|
use App\Policies\UserPolicy;
|
||||||
|
use App\Policies\VendorPolicy;
|
||||||
use Auth;
|
use Auth;
|
||||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
@ -62,6 +66,8 @@ class AuthServiceProvider extends ServiceProvider
|
|||||||
GroupSetting::class => GroupSettingPolicy::class,
|
GroupSetting::class => GroupSettingPolicy::class,
|
||||||
CompanyGateway::class => CompanyGatewayPolicy::class,
|
CompanyGateway::class => CompanyGatewayPolicy::class,
|
||||||
TaxRate::class => TaxRatePolicy::class,
|
TaxRate::class => TaxRatePolicy::class,
|
||||||
|
Vendor::class => VendorPolicy::class,
|
||||||
|
Expense::class => ExpensePolicy::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,7 +72,6 @@ class InvoiceRepository extends BaseRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isset($data['invitations'])) {
|
if (isset($data['invitations'])) {
|
||||||
$invitations = collect($data['invitations']);
|
$invitations = collect($data['invitations']);
|
||||||
|
|
||||||
@ -81,7 +80,6 @@ class InvoiceRepository extends BaseRepository
|
|||||||
InvoiceInvitation::destroy($invitation);
|
InvoiceInvitation::destroy($invitation);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
foreach ($data['invitations'] as $invitation) {
|
foreach ($data['invitations'] as $invitation) {
|
||||||
$inv = false;
|
$inv = false;
|
||||||
|
|
||||||
@ -96,6 +94,7 @@ class InvoiceRepository extends BaseRepository
|
|||||||
$new_invitation->invoice_id = $invoice->id;
|
$new_invitation->invoice_id = $invoice->id;
|
||||||
$new_invitation->client_contact_id = $this->decodePrimaryKey($invitation['client_contact_id']);
|
$new_invitation->client_contact_id = $this->decodePrimaryKey($invitation['client_contact_id']);
|
||||||
$new_invitation->save();
|
$new_invitation->save();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
76
app/Repositories/VendorContactRepository.php
Normal file
76
app/Repositories/VendorContactRepository.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Repositories;
|
||||||
|
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VendorContactRepository
|
||||||
|
*/
|
||||||
|
class VendorContactRepository extends BaseRepository
|
||||||
|
{
|
||||||
|
public function save($contacts, Vendor $vendor) : void
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Convert array to collection */
|
||||||
|
$contacts = collect($contacts);
|
||||||
|
|
||||||
|
/* Get array of IDs which have been removed from the contacts array and soft delete each contact */
|
||||||
|
collect($vendor->contacts->pluck('id'))->diff($contacts->pluck('id'))->each(function ($contact) {
|
||||||
|
VendorContact::destroy($contact);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->is_primary = true;
|
||||||
|
/* Set first record to primary - always */
|
||||||
|
$contacts = $contacts->sortByDesc('is_primary')->map(function ($contact) {
|
||||||
|
$contact['is_primary'] = $this->is_primary;
|
||||||
|
$this->is_primary = false;
|
||||||
|
return $contact;
|
||||||
|
});
|
||||||
|
|
||||||
|
//loop and update/create contacts
|
||||||
|
$contacts->each(function ($contact) use ($vendor) {
|
||||||
|
$update_contact = null;
|
||||||
|
|
||||||
|
if (isset($contact['id'])) {
|
||||||
|
$update_contact = VendorContact::find($this->decodePrimaryKey($contact['id']));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$update_contact) {
|
||||||
|
$update_contact = new VendorContact;
|
||||||
|
$update_contact->vendor_id = $vendor->id;
|
||||||
|
$update_contact->company_id = $vendor->company_id;
|
||||||
|
$update_contact->user_id = $vendor->user_id;
|
||||||
|
$update_contact->contact_key = Str::random(40);
|
||||||
|
}
|
||||||
|
|
||||||
|
$update_contact->fill($contact);
|
||||||
|
|
||||||
|
$update_contact->save();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//always made sure we have one blank contact to maintain state
|
||||||
|
if ($contacts->count() == 0) {
|
||||||
|
$new_contact = new VendorContact;
|
||||||
|
$new_contact->vendor_id = $vendor->id;
|
||||||
|
$new_contact->company_id = $vendor->company_id;
|
||||||
|
$new_contact->user_id = $vendor->user_id;
|
||||||
|
$new_contact->contact_key = Str::random(40);
|
||||||
|
$new_contact->is_primary = true;
|
||||||
|
$new_contact->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
95
app/Repositories/VendorRepository.php
Normal file
95
app/Repositories/VendorRepository.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Repositories;
|
||||||
|
|
||||||
|
use App\Factory\VendorFactory;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Repositories\VSendorContactRepository;
|
||||||
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VendorRepository
|
||||||
|
*/
|
||||||
|
class VendorRepository extends BaseRepository
|
||||||
|
{
|
||||||
|
use GeneratesCounter;
|
||||||
|
/**
|
||||||
|
* @var vendorContactRepository
|
||||||
|
*/
|
||||||
|
protected $contact_repo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vendorController constructor.
|
||||||
|
* @param vendorContactRepository $contact_repo
|
||||||
|
*/
|
||||||
|
public function __construct(VendorContactRepository $contact_repo)
|
||||||
|
{
|
||||||
|
$this->contact_repo = $contact_repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the class name.
|
||||||
|
*
|
||||||
|
* @return string The class name.
|
||||||
|
*/
|
||||||
|
public function getClassName()
|
||||||
|
{
|
||||||
|
return Vendor::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the vendor and its contacts
|
||||||
|
*
|
||||||
|
* @param array $data The data
|
||||||
|
* @param \App\Models\vendor $vendor The vendor
|
||||||
|
*
|
||||||
|
* @return vendor|\App\Models\vendor|null vendor Object
|
||||||
|
*/
|
||||||
|
public function save(array $data, Vendor $vendor) : ?Vendor
|
||||||
|
{
|
||||||
|
$vendor->fill($data);
|
||||||
|
|
||||||
|
$vendor->save();
|
||||||
|
|
||||||
|
if ($vendor->id_number == "" || !$vendor->id_number) {
|
||||||
|
$vendor->id_number = $this->getNextVendorNumber($vendor);
|
||||||
|
} //todo write tests for this and make sure that custom vendor numbers also works as expected from here
|
||||||
|
|
||||||
|
$vendor->save();
|
||||||
|
|
||||||
|
if (isset($data['contacts'])) {
|
||||||
|
$contacts = $this->contact_repo->save($data['contacts'], $vendor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($data['name'])) {
|
||||||
|
$data['name'] = $vendor->present()->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $vendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store vendors in bulk.
|
||||||
|
*
|
||||||
|
* @param array $vendor
|
||||||
|
* @return vendor|null
|
||||||
|
*/
|
||||||
|
public function create($vendor): ?Vendor
|
||||||
|
{
|
||||||
|
return $this->save(
|
||||||
|
$vendor,
|
||||||
|
VendorFactory::create(auth()->user()->company()->id, auth()->user()->id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ use App\Models\Client;
|
|||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CompanyGateway;
|
use App\Models\CompanyGateway;
|
||||||
use App\Models\CompanyUser;
|
use App\Models\CompanyUser;
|
||||||
|
use App\Models\Expense;
|
||||||
use App\Models\GroupSetting;
|
use App\Models\GroupSetting;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
@ -53,6 +54,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'timezone',
|
'timezone',
|
||||||
'language',
|
'language',
|
||||||
'expenses',
|
'expenses',
|
||||||
|
'vendors',
|
||||||
'payments',
|
'payments',
|
||||||
'company_user',
|
'company_user',
|
||||||
'groups',
|
'groups',
|
||||||
@ -137,6 +139,20 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
return $this->includeCollection($company->clients, $transformer, Client::class);
|
return $this->includeCollection($company->clients, $transformer, Client::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function includeExpenses(Company $company)
|
||||||
|
{
|
||||||
|
$transformer = new ExpenseTransformer($this->serializer);
|
||||||
|
|
||||||
|
return $this->includeCollection($company->expenses, $transformer, Expense::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function includeVendors(Company $company)
|
||||||
|
{
|
||||||
|
$transformer = new VendorTransformer($this->serializer);
|
||||||
|
|
||||||
|
return $this->includeCollection($company->vendors, $transformer, Vendor::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function includeGroups(Company $company)
|
public function includeGroups(Company $company)
|
||||||
{
|
{
|
||||||
$transformer = new GroupSettingTransformer($this->serializer);
|
$transformer = new GroupSettingTransformer($this->serializer);
|
||||||
|
80
app/Transformers/ExpenseTransformer.php
Normal file
80
app/Transformers/ExpenseTransformer.php
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Transformers;
|
||||||
|
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class ExpenseTransformer
|
||||||
|
*/
|
||||||
|
class ExpenseTransformer extends EntityTransformer
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
protected $defaultIncludes = [
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $availableIncludes = [
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Expense $expense
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function transform(Expense $expense)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->encodePrimaryKey($expense->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($expense->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($expense->assigned_user_id),
|
||||||
|
'vendor_id' => $this->encodePrimaryKey($expense->vendor_id),
|
||||||
|
'invoice_id' => $this->encodePrimaryKey($expense->invoice_id),
|
||||||
|
'client_id' => $this->encodePrimaryKey($expense->client_id),
|
||||||
|
'bank_id' => (string)$expense->bank_id ?: '',
|
||||||
|
'invoice_currency_id' => (string)$expense->invoice_currency_id ?: '',
|
||||||
|
'expense_currency_id' => (string)$expense->expense_currency_id ?: '',
|
||||||
|
'invoice_category_id' => (string)$expense->invoice_category_id ?: '',
|
||||||
|
'payment_type_id' => (string)$expense->payment_type_id ?: '',
|
||||||
|
'recurring_expense_id' => (string)$expense->recurring_expense_id ?: '',
|
||||||
|
'is_deleted' => (bool) $expense->is_deleted,
|
||||||
|
'should_be_invoiced' => (bool) $expense->should_be_invoiced,
|
||||||
|
'invoice_documents' => (bool) $expense->invoice_documents,
|
||||||
|
'amount' => (float)$expense->amount ?: 0,
|
||||||
|
'foreign_amount' => (float)$expense->foreign_amount ?: 0,
|
||||||
|
'exchange_rate' => (float)$expense->exchange_rate ?: 0,
|
||||||
|
'tax_name1' => $expense->tax_name1 ? $expense->tax_name1 : '',
|
||||||
|
'tax_rate1' => (float) $expense->tax_rate1,
|
||||||
|
'tax_name2' => $expense->tax_name2 ? $expense->tax_name2 : '',
|
||||||
|
'tax_rate2' => (float) $expense->tax_rate2,
|
||||||
|
'tax_name3' => $expense->tax_name3 ? $expense->tax_name3 : '',
|
||||||
|
'tax_rate3' => (float) $expense->tax_rate3,
|
||||||
|
'private_notes' => (string) $expense->private_notes ?: '',
|
||||||
|
'public_notes' => (string) $expense->public_notes ?: '',
|
||||||
|
'transaction_reference' => (string) $expense->transaction_reference ?: '',
|
||||||
|
'transaction_id' => (string) $expense->transaction_id ?: '',
|
||||||
|
'expense_date' => $expense->expense_date ?: '',
|
||||||
|
'payment_date' => $expense->payment_date ?: '',
|
||||||
|
'custom_value1' => $expense->custom_value1 ?: '',
|
||||||
|
'custom_value2' => $expense->custom_value2 ?: '',
|
||||||
|
'custom_value3' => $expense->custom_value3 ?: '',
|
||||||
|
'custom_value4' => $expense->custom_value4 ?: '',
|
||||||
|
'updated_at' => $expense->updated_at,
|
||||||
|
'archived_at' => $expense->deleted_at,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
47
app/Transformers/VendorContactTransformer.php
Normal file
47
app/Transformers/VendorContactTransformer.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Transformers;
|
||||||
|
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VendorContactTransformer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class VendorContactTransformer extends EntityTransformer
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
/**
|
||||||
|
* @param ClientContact $vendor
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function transform(VendorContact $vendor)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->encodePrimaryKey($vendor->id),
|
||||||
|
'first_name' => $vendor->first_name ?: '',
|
||||||
|
'last_name' => $vendor->last_name ?: '',
|
||||||
|
'email' => $vendor->email ?: '',
|
||||||
|
'updated_at' => $vendor->updated_at,
|
||||||
|
'archived_at' => $vendor->deleted_at,
|
||||||
|
'is_primary' => (bool) $vendor->is_primary,
|
||||||
|
'phone' => $vendor->phone ?: '',
|
||||||
|
'custom_value1' => $vendor->custom_value1 ?: '',
|
||||||
|
'custom_value2' => $vendor->custom_value2 ?: '',
|
||||||
|
'custom_value3' => $vendor->custom_value3 ?: '',
|
||||||
|
'custom_value4' => $vendor->custom_value4 ?: '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
98
app/Transformers/VendorTransformer.php
Normal file
98
app/Transformers/VendorTransformer.php
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Transformers;
|
||||||
|
|
||||||
|
use App\Models\Activity;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\VendorContact;
|
||||||
|
use App\Models\VendorGatewayToken;
|
||||||
|
use App\Transformers\ActivityTransformer;
|
||||||
|
use App\Transformers\VendorGatewayTokenTransformer;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class VendorTransformer
|
||||||
|
*/
|
||||||
|
class VendorTransformer extends EntityTransformer
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
protected $defaultIncludes = [
|
||||||
|
'contacts',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $availableIncludes = [
|
||||||
|
'activities',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Vendor $vendor
|
||||||
|
*
|
||||||
|
* @return \League\Fractal\Resource\Collection
|
||||||
|
*/
|
||||||
|
public function includeActivities(Vendor $vendor)
|
||||||
|
{
|
||||||
|
$transformer = new ActivityTransformer($this->serializer);
|
||||||
|
|
||||||
|
return $this->includeCollection($vendor->activities, $transformer, Activity::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Vendor $vendor
|
||||||
|
*
|
||||||
|
* @return \League\Fractal\Resource\Collection
|
||||||
|
*/
|
||||||
|
public function includeContacts(Vendor $vendor)
|
||||||
|
{
|
||||||
|
$transformer = new VendorContactTransformer($this->serializer);
|
||||||
|
|
||||||
|
return $this->includeCollection($vendor->contacts, $transformer, VendorContact::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Vendor $vendor
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function transform(Vendor $vendor)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->encodePrimaryKey($vendor->id),
|
||||||
|
'user_id' => $this->encodePrimaryKey($vendor->user_id),
|
||||||
|
'assigned_user_id' => $this->encodePrimaryKey($vendor->assigned_user_id),
|
||||||
|
'name' => $vendor->name ?: '',
|
||||||
|
'website' => $vendor->website ?: '',
|
||||||
|
'private_notes' => $vendor->private_notes ?: '',
|
||||||
|
'last_login' => (int)$vendor->last_login,
|
||||||
|
'address1' => $vendor->address1 ?: '',
|
||||||
|
'address2' => $vendor->address2 ?: '',
|
||||||
|
'phone' => $vendor->phone ?: '',
|
||||||
|
'city' => $vendor->city ?: '',
|
||||||
|
'state' => $vendor->state ?: '',
|
||||||
|
'postal_code' => $vendor->postal_code ?: '',
|
||||||
|
'country_id' => (string)$vendor->country_id ?: '',
|
||||||
|
'custom_value1' => $vendor->custom_value1 ?: '',
|
||||||
|
'custom_value2' => $vendor->custom_value2 ?: '',
|
||||||
|
'custom_value3' => $vendor->custom_value3 ?: '',
|
||||||
|
'custom_value4' => $vendor->custom_value4 ?: '',
|
||||||
|
'is_deleted' => (bool) $vendor->is_deleted,
|
||||||
|
'vat_number' => $vendor->vat_number ?: '',
|
||||||
|
'id_number' => $vendor->id_number ?: '',
|
||||||
|
'updated_at' => $vendor->updated_at,
|
||||||
|
'archived_at' => $vendor->deleted_at,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ namespace App\Utils\Traits;
|
|||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use League\CommonMark\CommonMarkConverter;
|
||||||
use Parsedown;
|
use Parsedown;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,7 +85,14 @@ trait InvoiceEmailBuilder
|
|||||||
|
|
||||||
//process markdown
|
//process markdown
|
||||||
if ($is_markdown) {
|
if ($is_markdown) {
|
||||||
$data = Parsedown::instance()->line($data);
|
//$data = Parsedown::instance()->line($data);
|
||||||
|
|
||||||
|
$converter = new CommonMarkConverter([
|
||||||
|
'html_input' => 'strip',
|
||||||
|
'allow_unsafe_links' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data = $converter->convertToHtml($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
22
database/factories/ExpenseFactory.php
Normal file
22
database/factories/ExpenseFactory.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\DataMapper\ClientSettings;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\Factory\InvoiceItemFactory;
|
||||||
|
use Faker\Generator as Faker;
|
||||||
|
|
||||||
|
$factory->define(App\Models\Expense::class, function (Faker $faker) {
|
||||||
|
return [
|
||||||
|
'amount' => $faker->numberBetween(1,10),
|
||||||
|
'custom_value1' => $faker->text(10),
|
||||||
|
'custom_value2' => $faker->text(10),
|
||||||
|
'custom_value3' => $faker->text(10),
|
||||||
|
'custom_value4' => $faker->text(10),
|
||||||
|
'exchange_rate' => $faker->randomFloat(2,0,1),
|
||||||
|
'expense_date' => $faker->date(),
|
||||||
|
'is_deleted' => false,
|
||||||
|
'public_notes' => $faker->text(50),
|
||||||
|
'private_notes' => $faker->text(50),
|
||||||
|
'transaction_reference' => $faker->text(5),
|
||||||
|
];
|
||||||
|
});
|
24
database/factories/VendorContactFactory.php
Normal file
24
database/factories/VendorContactFactory.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Faker\Generator as Faker;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Model Factories
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This directory should contain each of the model factory definitions for
|
||||||
|
| your application. Factories provide a convenient way to generate new
|
||||||
|
| model instances for testing / seeding your application's database.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
$factory->define(App\Models\VendorContact::class, function (Faker $faker) {
|
||||||
|
return [
|
||||||
|
'first_name' => $faker->firstName,
|
||||||
|
'last_name' => $faker->lastName,
|
||||||
|
'phone' => $faker->phoneNumber,
|
||||||
|
'email' => $faker->unique()->safeEmail,
|
||||||
|
];
|
||||||
|
|
||||||
|
});
|
23
database/factories/VendorFactory.php
Normal file
23
database/factories/VendorFactory.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Faker\Generator as Faker;
|
||||||
|
|
||||||
|
$factory->define(App\Models\Vendor::class, function (Faker $faker) {
|
||||||
|
return [
|
||||||
|
'name' => $faker->name(),
|
||||||
|
'website' => $faker->url,
|
||||||
|
'private_notes' => $faker->text(200),
|
||||||
|
'vat_number' => $faker->text(25),
|
||||||
|
'id_number' => $faker->text(20),
|
||||||
|
'custom_value1' => $faker->text(20),
|
||||||
|
'custom_value2' => $faker->text(20),
|
||||||
|
'custom_value3' => $faker->text(20),
|
||||||
|
'custom_value4' => $faker->text(20),
|
||||||
|
'address1' => $faker->buildingNumber,
|
||||||
|
'address2' => $faker->streetAddress,
|
||||||
|
'city' => $faker->city,
|
||||||
|
'state' => $faker->state,
|
||||||
|
'postal_code' => $faker->postcode,
|
||||||
|
'country_id' => 4,
|
||||||
|
];
|
||||||
|
});
|
@ -1222,6 +1222,122 @@ class CreateUsersTable extends Migration
|
|||||||
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::create('vendors', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->timestamps(6);
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unsignedInteger('user_id');
|
||||||
|
$table->unsignedInteger('assigned_user_id');
|
||||||
|
$table->unsignedInteger('company_id');
|
||||||
|
$table->unsignedInteger('currency_id')->nullable();
|
||||||
|
$table->string('name')->nullable();
|
||||||
|
$table->string('address1');
|
||||||
|
$table->string('address2');
|
||||||
|
$table->string('city');
|
||||||
|
$table->string('state');
|
||||||
|
$table->string('postal_code');
|
||||||
|
$table->unsignedInteger('country_id')->nullable();
|
||||||
|
$table->string('work_phone');
|
||||||
|
$table->text('private_notes');
|
||||||
|
$table->string('website');
|
||||||
|
$table->tinyInteger('is_deleted')->default(0);
|
||||||
|
$table->string('vat_number')->nullable();
|
||||||
|
$table->string('transaction_name')->nullable();
|
||||||
|
$table->string('id_number')->nullable();
|
||||||
|
|
||||||
|
$table->string('custom_value1')->nullable();
|
||||||
|
$table->string('custom_value2')->nullable();
|
||||||
|
$table->string('custom_value3')->nullable();
|
||||||
|
$table->string('custom_value4')->nullable();
|
||||||
|
|
||||||
|
|
||||||
|
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
$table->foreign('country_id')->references('id')->on('countries');
|
||||||
|
$table->foreign('currency_id')->references('id')->on('currencies');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('vendor_contacts', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->unsignedInteger('company_id');
|
||||||
|
$table->unsignedInteger('user_id');
|
||||||
|
$table->unsignedInteger('vendor_id')->index();
|
||||||
|
$table->timestamps(6);
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
$table->boolean('is_primary')->default(0);
|
||||||
|
$table->string('first_name')->nullable();
|
||||||
|
$table->string('last_name')->nullable();
|
||||||
|
$table->string('email')->nullable();
|
||||||
|
$table->string('phone')->nullable();
|
||||||
|
|
||||||
|
$table->string('custom_value1')->nullable();
|
||||||
|
$table->string('custom_value2')->nullable();
|
||||||
|
$table->string('custom_value3')->nullable();
|
||||||
|
$table->string('custom_value4')->nullable();
|
||||||
|
|
||||||
|
$table->foreign('vendor_id')->references('id')->on('vendors')->onDelete('cascade');
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('expense_categories', function ($table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->unsignedInteger('user_id');
|
||||||
|
$table->unsignedInteger('company_id')->index();
|
||||||
|
$table->timestamps(6);
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->string('name')->nullable();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('expenses', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->timestamps(6);
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
$table->unsignedInteger('company_id')->index();
|
||||||
|
$table->unsignedInteger('vendor_id')->nullable();
|
||||||
|
$table->unsignedInteger('user_id');
|
||||||
|
$table->unsignedInteger('assigned_user_id');
|
||||||
|
$table->unsignedInteger('invoice_id')->nullable();
|
||||||
|
$table->unsignedInteger('client_id')->nullable();
|
||||||
|
$table->unsignedInteger('bank_id')->nullable();
|
||||||
|
$table->unsignedInteger('invoice_currency_id')->nullable(false);
|
||||||
|
$table->unsignedInteger('expense_currency_id')->nullable(false);
|
||||||
|
$table->unsignedInteger('invoice_category_id')->nullable();
|
||||||
|
$table->unsignedInteger('payment_type_id')->nullable();
|
||||||
|
$table->unsignedInteger('recurring_expense_id')->nullable();
|
||||||
|
$table->boolean('is_deleted')->default(false);
|
||||||
|
$table->decimal('amount', 13, 2);
|
||||||
|
$table->decimal('foreign_amount', 13, 2);
|
||||||
|
$table->decimal('exchange_rate', 13, 4);
|
||||||
|
$table->string('tax_name1')->nullable();
|
||||||
|
$table->decimal('tax_rate1', 13, 3)->default(0);
|
||||||
|
$table->string('tax_name2')->nullable();
|
||||||
|
$table->decimal('tax_rate2', 13, 3)->default(0);
|
||||||
|
$table->string('tax_name3')->nullable();
|
||||||
|
$table->decimal('tax_rate3', 13, 3)->default(0);
|
||||||
|
$table->date('expense_date')->nullable();
|
||||||
|
$table->date('payment_date')->nullable();
|
||||||
|
$table->text('private_notes');
|
||||||
|
$table->text('public_notes');
|
||||||
|
$table->text('transaction_reference');
|
||||||
|
$table->boolean('should_be_invoiced')->default(false);
|
||||||
|
$table->boolean('invoice_documents')->default();
|
||||||
|
$table->string('transaction_id')->nullable();
|
||||||
|
|
||||||
|
$table->string('custom_value1')->nullable();
|
||||||
|
$table->string('custom_value2')->nullable();
|
||||||
|
$table->string('custom_value3')->nullable();
|
||||||
|
$table->string('custom_value4')->nullable();
|
||||||
|
|
||||||
|
// Relations
|
||||||
|
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,6 +62,14 @@ Route::group(['middleware' => ['api_db','api_secret_check','token_auth','locale'
|
|||||||
|
|
||||||
Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
|
Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
|
||||||
|
|
||||||
|
Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit
|
||||||
|
|
||||||
|
Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
|
||||||
|
|
||||||
|
Route::resource('vendors', 'VendorController'); // name = (vendors. index / create / show / update / destroy / edit
|
||||||
|
|
||||||
|
Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk');
|
||||||
|
|
||||||
Route::resource('client_statement', 'ClientStatementController@statement'); // name = (client_statement. index / create / show / update / destroy / edit
|
Route::resource('client_statement', 'ClientStatementController@statement'); // name = (client_statement. index / create / show / update / destroy / edit
|
||||||
|
|
||||||
Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit
|
Route::resource('payments', 'PaymentController'); // name = (payments. index / create / show / update / destroy / edit
|
||||||
@ -103,9 +111,7 @@ Route::group(['middleware' => ['api_db','api_secret_check','token_auth','locale'
|
|||||||
|
|
||||||
Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
|
Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
|
||||||
|
|
||||||
Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit
|
|
||||||
|
|
||||||
Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
|
|
||||||
|
|
||||||
|
|
||||||
Route::get('settings', 'SettingsController@index')->name('user.settings');
|
Route::get('settings', 'SettingsController@index')->name('user.settings');
|
||||||
|
@ -14,7 +14,6 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Parsedown;
|
|
||||||
use Tests\MockAccountData;
|
use Tests\MockAccountData;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user