chore(catalog,contacts): remove legacy-era catalog and contacts sources

This commit is contained in:
Darko Gjorgjijoski
2026-08-20 21:50:34 +02:00
parent 2b4de6bd09
commit b5b4e2c978
34 changed files with 0 additions and 2513 deletions
@@ -1,119 +0,0 @@
<?php
namespace App\Domains\Catalog\Http\Controllers;
use App\Domains\Catalog\Application\ItemService;
use App\Domains\Catalog\Http\Requests\DeleteItemsRequest;
use App\Domains\Catalog\Http\Requests\ItemsRequest;
use App\Domains\Catalog\Http\Resources\ItemResource;
use App\Domains\Catalog\Models\Item;
use App\Domains\Taxation\Models\TaxType;
use App\Platform\Http\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ItemsController extends Controller
{
public function __construct(
private readonly ItemService $itemService,
) {}
/**
* Retrieve a list of existing Items.
*
* @return JsonResponse
*/
public function index(Request $request)
{
$this->authorize('viewAny', Item::class);
$limit = $request->has('limit') ? $request->limit : 10;
$items = Item::whereCompany()
->leftJoin('units', 'units.id', '=', 'items.unit_id')
->applyFilters($request->all())
->select('items.*', 'units.name as unit_name')
->latest()
->paginateData($limit);
return ItemResource::collection($items)
->additional(['meta' => [
'tax_types' => TaxType::whereCompany()
->whereTransactionType(TaxType::TRANSACTION_TYPE_SALES)
->latest()
->get(),
'item_total_count' => Item::whereCompany()->count(),
]]);
}
/**
* Create Item.
*
* @return JsonResponse
*/
public function store(ItemsRequest $request)
{
$this->authorize('create', Item::class);
$item = $this->itemService->create(
$request->validated(),
$request->input('taxes', []),
(int) $request->header('company'),
(int) $request->user()->getAuthIdentifier(),
);
return new ItemResource($item);
}
/**
* get an existing Item.
*
* @return JsonResponse
*/
public function show(Item $item)
{
$this->authorize('view', $item);
return new ItemResource($item);
}
/**
* Update an existing Item.
*
* @return JsonResponse
*/
public function update(ItemsRequest $request, Item $item)
{
$this->authorize('update', $item);
$item = $this->itemService->update(
$item,
$request->validated(),
$request->input('taxes', []),
(int) $request->header('company'),
);
return new ItemResource($item);
}
/**
* Delete a list of existing Items.
*
* @param Request $request
* @return JsonResponse
*/
public function delete(DeleteItemsRequest $request)
{
$this->authorize('delete multiple items');
$ids = Item::whereCompany()
->whereIn('id', $request->ids)
->pluck('id');
Item::destroy($ids);
return response()->json([
'success' => true,
]);
}
}
@@ -1,94 +0,0 @@
<?php
namespace App\Domains\Catalog\Http\Controllers;
use App\Domains\Catalog\Http\Requests\UnitRequest;
use App\Domains\Catalog\Http\Resources\UnitResource;
use App\Domains\Catalog\Models\Unit;
use App\Platform\Http\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class UnitsController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index(Request $request)
{
$this->authorize('viewAny', Unit::class);
$limit = $request->has('limit') ? $request->limit : 5;
$units = Unit::applyFilters($request->all())
->whereCompany()
->latest()
->paginateData($limit);
return UnitResource::collection($units);
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return Response
*/
public function store(UnitRequest $request)
{
$this->authorize('create', Unit::class);
$unit = Unit::create($request->getUnitPayload());
return new UnitResource($unit);
}
/**
* Display the specified resource.
*
* @return Response
*/
public function show(Unit $unit)
{
$this->authorize('view', $unit);
return new UnitResource($unit);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @return Response
*/
public function update(UnitRequest $request, Unit $unit)
{
$this->authorize('update', $unit);
$unit->update($request->getUnitPayload());
return new UnitResource($unit);
}
/**
* Remove the specified resource from storage.
*
* @return Response
*/
public function destroy(Unit $unit)
{
$this->authorize('delete', $unit);
if ($unit->items()->exists()) {
return respondJson('items_attached', 'Items Attached');
}
$unit->delete();
return response()->json([
'success' => 'Unit deleted successfully',
]);
}
}
@@ -1,38 +0,0 @@
<?php
namespace App\Domains\Catalog\Http\Requests;
use App\Domains\Catalog\Models\Item;
use App\Rules\RelationNotExist;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class DeleteItemsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'ids' => [
'required',
],
'ids.*' => [
'required',
Rule::exists('items', 'id'),
new RelationNotExist(Item::class, 'invoiceItems'),
new RelationNotExist(Item::class, 'estimateItems'),
new RelationNotExist(Item::class, 'taxes'),
],
];
}
}
@@ -1,37 +0,0 @@
<?php
namespace App\Domains\Catalog\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ItemsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'name' => [
'required',
],
'price' => [
'required',
],
'unit_id' => [
'nullable',
],
'description' => [
'nullable',
],
];
}
}
@@ -1,51 +0,0 @@
<?php
namespace App\Domains\Catalog\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UnitRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
$data = [
'name' => [
'required',
Rule::unique('units')
->where('company_id', $this->header('company')),
],
];
if ($this->getMethod() == 'PUT') {
$data['name'] = [
'required',
Rule::unique('units')
->ignore($this->route('unit'), 'id')
->where('company_id', $this->header('company')),
];
}
return $data;
}
public function getUnitPayload()
{
return collect($this->validated())
->merge([
'company_id' => $this->header('company'),
])
->toArray();
}
}
@@ -1,47 +0,0 @@
<?php
namespace App\Domains\Catalog\Http\Resources;
use App\Domains\Accounts\Http\Resources\CompanyResource;
use App\Domains\Money\Http\Resources\CurrencyResource;
use App\Domains\Taxation\Http\Resources\TaxResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ItemResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'price' => $this->price,
'unit_id' => $this->unit_id,
'company_id' => $this->company_id,
'creator_id' => $this->creator_id,
'currency_id' => $this->currency_id,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'tax_per_item' => $this->tax_per_item,
'formatted_created_at' => $this->formattedCreatedAt,
'unit' => $this->when($this->unit()->exists(), function () {
return new UnitResource($this->unit);
}),
'company' => $this->when($this->company()->exists(), function () {
return new CompanyResource($this->company);
}),
'taxes' => $this->when($this->taxes()->exists(), function () {
return TaxResource::collection($this->taxes);
}),
'currency' => $this->when($this->currency()->exists(), function () {
return new CurrencyResource($this->currency);
}),
];
}
}
@@ -1,27 +0,0 @@
<?php
namespace App\Domains\Catalog\Http\Resources;
use App\Domains\Accounts\Http\Resources\CompanyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class UnitResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'company_id' => $this->company_id,
'company' => $this->when($this->company()->exists(), function () {
return new CompanyResource($this->company);
}),
];
}
}
-156
View File
@@ -1,156 +0,0 @@
<?php
namespace App\Domains\Catalog\Models;
use App\Domains\Accounts\Models\Company;
use App\Domains\Accounts\Models\CompanySetting;
use App\Domains\Accounts\Models\User;
use App\Domains\Money\Models\Currency;
use App\Domains\Sales\Models\EstimateItem;
use App\Domains\Sales\Models\InvoiceItem;
use App\Domains\Taxation\Models\Tax;
use App\Support\SafeOrderBy;
use Carbon\Carbon;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Item extends Model
{
protected $table = 'items';
use HasFactory;
protected $guarded = ['id'];
protected $appends = [
'formattedCreatedAt',
];
protected function casts(): array
{
return [
'price' => 'integer',
];
}
public function unit(): BelongsTo
{
return $this->belongsTo(Unit::class, 'unit_id');
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'creator_id');
}
public function currency(): BelongsTo
{
return $this->belongsTo(Currency::class);
}
public function scopeWhereSearch(Builder $query, string $search): Builder
{
return $query->where('items.name', 'LIKE', '%'.$search.'%');
}
public function scopeWherePrice(Builder $query, int $price): Builder
{
return $query->where('items.price', $price);
}
public function scopeWhereUnit(Builder $query, int $unit_id): Builder
{
return $query->where('items.unit_id', $unit_id);
}
public function scopeWhereOrder(Builder $query, string $orderByField, string $orderBy): void
{
SafeOrderBy::apply($query, $orderByField, $orderBy);
}
public function scopeWhereItem(Builder $query, int $item_id): void
{
$query->orWhere('id', $item_id);
}
/**
* Apply multiple filter conditions including search, price, unit, item, and ordering.
*/
public function scopeApplyFilters(Builder $query, array $filters): void
{
$filters = collect($filters);
if ($filters->get('search')) {
$query->whereSearch($filters->get('search'));
}
if ($filters->get('price')) {
$query->wherePrice($filters->get('price'));
}
if ($filters->get('unit_id')) {
$query->whereUnit($filters->get('unit_id'));
}
if ($filters->get('item_id')) {
$query->whereItem($filters->get('item_id'));
}
if ($filters->get('orderByField') || $filters->get('orderBy')) {
$field = $filters->get('orderByField') ? $filters->get('orderByField') : 'name';
$orderBy = $filters->get('orderBy') ? $filters->get('orderBy') : 'asc';
$query->whereOrder($field, $orderBy);
}
}
/**
* @return LengthAwarePaginator|Collection
*/
public function scopePaginateData(Builder $query, string $limit)
{
if ($limit == 'all') {
return $query->get();
}
return $query->paginate($limit);
}
public function getFormattedCreatedAtAttribute(mixed $value): string
{
$dateFormat = CompanySetting::getSetting('carbon_date_format', request()->header('company'));
return Carbon::parse($this->created_at)->translatedFormat($dateFormat);
}
public function taxes(): HasMany
{
return $this->hasMany(Tax::class)
->where('invoice_item_id', null)
->where('estimate_item_id', null);
}
public function scopeWhereCompany(Builder $query): void
{
$query->where('items.company_id', request()->header('company'));
}
public function invoiceItems(): HasMany
{
return $this->hasMany(InvoiceItem::class);
}
public function estimateItems(): HasMany
{
return $this->hasMany(EstimateItem::class);
}
}
-77
View File
@@ -1,77 +0,0 @@
<?php
namespace App\Domains\Catalog\Models;
use App\Domains\Accounts\Models\Company;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Unit extends Model
{
protected $table = 'units';
use HasFactory;
protected $fillable = ['name', 'company_id'];
public function items(): HasMany
{
return $this->hasMany(Item::class);
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public function scopeWhereCompany(Builder $query): void
{
$query->where('company_id', request()->header('company'));
}
public function scopeWhereUnit(Builder $query, int $unit_id): void
{
$query->orWhere('id', $unit_id);
}
public function scopeWhereSearch(Builder $query, string $search): Builder
{
return $query->where('name', 'LIKE', '%'.$search.'%');
}
public function scopeApplyFilters(Builder $query, array $filters): Builder
{
$filters = collect($filters);
if ($filters->get('search')) {
$query->whereSearch($filters->get('search'));
}
if ($filters->get('unit_id')) {
$query->whereUnit($filters->get('unit_id'));
}
if ($filters->get('company_id')) {
$query->whereCompany($filters->get('company_id'));
}
return $query;
}
/**
* @return Collection|LengthAwarePaginator
*/
public function scopePaginateData(Builder $query, string $limit)
{
if ($limit == 'all') {
return $query->get();
}
return $query->paginate($limit);
}
}
-125
View File
@@ -1,125 +0,0 @@
<?php
namespace App\Domains\Catalog\Policies;
use App\Domains\Accounts\Models\User;
use App\Domains\Catalog\Models\Item;
use Illuminate\Auth\Access\HandlesAuthorization;
use Silber\Bouncer\BouncerFacade;
class ItemPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* @return mixed
*/
public function viewAny(User $user): bool
{
if (BouncerFacade::can('view-item', Item::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can view the model.
*
* @return mixed
*/
public function view(User $user, Item $item): bool
{
if (BouncerFacade::can('view-item', $item) && $user->hasCompany($item->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can create models.
*
* @return mixed
*/
public function create(User $user): bool
{
if (BouncerFacade::can('create-item', Item::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can update the model.
*
* @return mixed
*/
public function update(User $user, Item $item): bool
{
if (BouncerFacade::can('edit-item', $item) && $user->hasCompany($item->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can delete the model.
*
* @return mixed
*/
public function delete(User $user, Item $item): bool
{
if (BouncerFacade::can('delete-item', $item) && $user->hasCompany($item->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can restore the model.
*
* @return mixed
*/
public function restore(User $user, Item $item): bool
{
if (BouncerFacade::can('delete-item', $item) && $user->hasCompany($item->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can permanently delete the model.
*
* @return mixed
*/
public function forceDelete(User $user, Item $item): bool
{
if (BouncerFacade::can('delete-item', $item) && $user->hasCompany($item->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can delete models.
*
* @return mixed
*/
public function deleteMultiple(User $user)
{
if (BouncerFacade::can('delete-item', Item::class)) {
return true;
}
return false;
}
}
-112
View File
@@ -1,112 +0,0 @@
<?php
namespace App\Domains\Catalog\Policies;
use App\Domains\Accounts\Models\User;
use App\Domains\Catalog\Models\Item;
use App\Domains\Catalog\Models\Unit;
use Illuminate\Auth\Access\HandlesAuthorization;
use Silber\Bouncer\BouncerFacade;
class UnitPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* @return mixed
*/
public function viewAny(User $user): bool
{
if (BouncerFacade::can('view-item', Item::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can view the model.
*
* @return mixed
*/
public function view(User $user, Unit $unit): bool
{
if (BouncerFacade::can('view-item', Item::class) && $user->hasCompany($unit->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can create models.
*
* @return mixed
*/
public function create(User $user): bool
{
if (BouncerFacade::can('view-item', Item::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can update the model.
*
* @return mixed
*/
public function update(User $user, Unit $unit): bool
{
if (BouncerFacade::can('view-item', Item::class) && $user->hasCompany($unit->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can delete the model.
*
* @return mixed
*/
public function delete(User $user, Unit $unit): bool
{
if (BouncerFacade::can('view-item', Item::class) && $user->hasCompany($unit->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can restore the model.
*
* @return mixed
*/
public function restore(User $user, Unit $unit): bool
{
if (BouncerFacade::can('view-item', Item::class) && $user->hasCompany($unit->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can permanently delete the model.
*
* @return mixed
*/
public function forceDelete(User $user, Unit $unit): bool
{
if (BouncerFacade::can('view-item', Item::class) && $user->hasCompany($unit->company_id)) {
return true;
}
return false;
}
}
@@ -1,37 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Controllers\Company;
use App\Domains\Contacts\Contracts\CustomerStatsProvider;
use App\Domains\Contacts\Http\Resources\CustomerResource;
use App\Domains\Contacts\Models\Customer;
use App\Domains\Reporting\Queries\CustomerStatementQuery;
use App\Platform\Http\Controller;
use Illuminate\Http\Request;
class CustomerStatsController extends Controller
{
public function __construct(
private readonly CustomerStatsProvider $customerStatsProvider,
private readonly CustomerStatementQuery $customerStatementQuery,
) {}
public function __invoke(Request $request, Customer $customer)
{
$this->authorize('view', $customer);
$chartData = $this->customerStatsProvider->get(
$customer,
$request->header('company'),
$request->has('previous_year')
);
$customer = Customer::find($customer->id);
$this->customerStatementQuery->hydrateAccountSummaries([$customer]);
return (new CustomerResource($customer))
->additional(['meta' => [
'chartData' => $chartData,
]]);
}
}
@@ -1,126 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Controllers\Company;
use App\Domains\Contacts\Application\CustomerService;
use App\Domains\Contacts\Http\Requests\CustomerRequest;
use App\Domains\Contacts\Http\Requests\DeleteCustomersRequest;
use App\Domains\Contacts\Http\Resources\CustomerResource;
use App\Domains\Contacts\Models\Customer;
use App\Domains\Reporting\Queries\CustomerStatementQuery;
use App\Platform\Http\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
class CustomersController extends Controller
{
public function __construct(
private readonly CustomerService $customerService,
private readonly CustomerStatementQuery $customerStatementQuery,
) {}
/**
* Display a listing of the resource.
*
* @return JsonResponse
*/
public function index(Request $request)
{
$this->authorize('viewAny', Customer::class);
$limit = $request->has('limit') ? $request->limit : 10;
$customers = Customer::with('creator')
->whereCompany()
->applyFilters($request->all())
->paginateData($limit);
$this->customerStatementQuery->hydrateAccountSummaries(
$customers instanceof LengthAwarePaginator ? $customers->getCollection() : $customers
);
return CustomerResource::collection($customers)
->additional(['meta' => [
'customer_total_count' => Customer::whereCompany()->count(),
]]);
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return JsonResponse
*/
public function store(CustomerRequest $request)
{
$this->authorize('create', Customer::class);
$customer = $this->customerService->create(
attributes: $request->customerAttributes(),
shippingAddress: $request->shippingAddress(),
billingAddress: $request->billingAddress(),
customFields: $request->customFields(),
);
$this->customerStatementQuery->hydrateAccountSummaries([$customer]);
return new CustomerResource($customer);
}
/**
* Display the specified resource.
*
* @return JsonResponse
*/
public function show(Customer $customer)
{
$this->authorize('view', $customer);
$this->customerStatementQuery->hydrateAccountSummaries([$customer]);
return new CustomerResource($customer);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @return JsonResponse
*/
public function update(CustomerRequest $request, Customer $customer)
{
$this->authorize('update', $customer);
$customer = $this->customerService->update(
customer: $customer,
attributes: $request->customerAttributes(),
shippingAddress: $request->shippingAddress(),
billingAddress: $request->billingAddress(),
customFields: $request->customFields(),
);
$this->customerStatementQuery->hydrateAccountSummaries([$customer]);
return new CustomerResource($customer);
}
/**
* Remove a list of Customers along side all their resources (ie. Estimates, Invoices, Payments and Addresses)
*
* @param Request $request
* @return JsonResponse
*/
public function delete(DeleteCustomersRequest $request)
{
$this->authorize('delete multiple customers');
$ids = Customer::whereCompany()
->whereIn('id', $request->ids)
->pluck('id');
$this->customerService->delete($ids);
return response()->json([
'success' => true,
]);
}
}
@@ -1,24 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Controllers;
use App\Domains\Contacts\Http\Resources\CountryResource;
use App\Domains\Contacts\Models\Country;
use App\Platform\Http\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class CountriesController extends Controller
{
/**
* Handle the incoming request.
*
* @return JsonResponse
*/
public function __invoke(Request $request)
{
$countries = Country::all();
return CountryResource::collection($countries);
}
}
@@ -1,56 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Controllers\CustomerPortal\Auth;
use App\Platform\Http\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Password;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
public function broker()
{
return Password::broker('customers');
}
/**
* Get the response for a successful password reset link.
*
* @param string $response
* @return RedirectResponse|JsonResponse
*/
protected function sendResetLinkResponse(Request $request, $response)
{
return response()->json([
'message' => 'Password reset email sent.',
'data' => $response,
]);
}
/**
* Get the response for a failed password reset link.
*
* @param string $response
* @return RedirectResponse|JsonResponse
*/
protected function sendResetLinkFailedResponse(Request $request, $response)
{
return response('Email could not be sent to this email address.', 403);
}
}
@@ -1,45 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Controllers\CustomerPortal\Auth;
use App\Domains\Accounts\Models\Company;
use App\Domains\Contacts\Http\Requests\CustomerPortal\CustomerLoginRequest;
use App\Domains\Contacts\Models\Customer;
use App\Platform\Http\Controller;
use Hash;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
class LoginController extends Controller
{
/**
* Handle the incoming request.
*
* @return Response
*/
public function __invoke(CustomerLoginRequest $request, Company $company)
{
$user = Customer::whereRaw('LOWER(email) = ?', [strtolower($request->email)])
->where('company_id', $company->id)
->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
if (! $user->enable_portal) {
throw ValidationException::withMessages([
'email' => ['Customer portal not available for this user.'],
]);
}
Auth::guard('customer')->login($user);
return response()->json([
'success' => true,
]);
}
}
@@ -1,84 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Controllers\CustomerPortal\Auth;
use App\Platform\Http\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Contracts\Auth\CanResetPassword;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Password;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::CUSTOMER_HOME;
public function broker()
{
return Password::broker('customers');
}
/**
* Get the response for a successful password reset.
*
* @param string $response
* @return RedirectResponse|JsonResponse
*/
protected function sendResetResponse(Request $request, $response)
{
return response()->json([
'message' => 'Password reset successfully.',
]);
}
/**
* Reset the given user's password.
*
* @param CanResetPassword $user
* @param string $password
* @return void
*/
protected function resetPassword($user, $password)
{
$user->password = $password;
$user->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
}
/**
* Get the response for a failed password reset.
*
* @param string $response
* @return RedirectResponse|JsonResponse
*/
protected function sendResetFailedResponse(Request $request, $response)
{
return response('Failed, Invalid Token.', 403);
}
}
@@ -1,45 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Controllers\CustomerPortal;
use App\Domains\Accounts\Models\CompanySetting;
use App\Domains\Contacts\Http\Resources\CustomerPortal\CustomerResource;
use App\Domains\Money\Models\Currency;
use App\Platform\Http\Controller;
use App\Platform\Modules\Models\Module;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
class BootstrapController extends Controller
{
/**
* Handle the incoming request.
*
* @return Response
*/
public function __invoke(Request $request)
{
$customer = Auth::guard('customer')->user();
foreach (\Menu::get('customer_portal_menu')->items->toArray() as $data) {
if ($customer) {
$menu[] = [
'title' => $data->title,
'link' => $data->link->path['url'],
];
}
}
$companyCurrencyId = CompanySetting::getSetting('currency', $customer->company_id);
return (new CustomerResource($customer))
->additional(['meta' => [
'menu' => $menu,
'current_customer_currency' => Currency::find($customer->currency_id),
'current_company_currency' => $companyCurrencyId ? Currency::find($companyCurrencyId) : null,
'modules' => Module::where('enabled', true)->pluck('name'),
'current_company_language' => CompanySetting::getSetting('language', $customer->company_id),
]]);
}
}
@@ -1,31 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Middleware;
use Closure;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class CustomerPortalMiddleware
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (\Illuminate\Http\Response|RedirectResponse) $next
* @return \Illuminate\Http\Response|RedirectResponse
*/
public function handle(Request $request, Closure $next): Response
{
$user = Auth::guard('customer')->user();
if (! $user->enable_portal) {
Auth::guard('customer')->logout();
return response('Unauthorized.', 401);
}
return $next($request);
}
}
@@ -1,33 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Requests\CustomerPortal;
use Illuminate\Foundation\Http\FormRequest;
class CustomerLoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'email' => [
'required',
'string',
],
'password' => [
'required',
'string',
],
];
}
}
@@ -1,143 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Requests\CustomerPortal;
use App\Domains\Contacts\Models\Address;
use App\Rules\IdnEmail;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
class CustomerProfileRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'name' => [
'nullable',
],
'password' => [
'nullable',
'min:8',
],
'email' => [
'nullable',
new IdnEmail,
Rule::unique('customers')->where('company_id', $this->header('company'))->ignore(Auth::id(), 'id'),
],
'billing.name' => [
'nullable',
],
'billing.address_street_1' => [
'nullable',
],
'billing.address_street_2' => [
'nullable',
],
'billing.city' => [
'nullable',
],
'billing.state' => [
'nullable',
],
'billing.country_id' => [
'nullable',
],
'billing.zip' => [
'nullable',
],
'billing.phone' => [
'nullable',
],
'billing.fax' => [
'nullable',
],
'shipping.name' => [
'nullable',
],
'shipping.address_street_1' => [
'nullable',
],
'shipping.address_street_2' => [
'nullable',
],
'shipping.city' => [
'nullable',
],
'shipping.state' => [
'nullable',
],
'shipping.country_id' => [
'nullable',
],
'shipping.zip' => [
'nullable',
],
'shipping.phone' => [
'nullable',
],
'shipping.fax' => [
'nullable',
],
'customer_avatar' => [
'nullable',
'file',
'mimes:gif,jpg,png',
'max:20000',
],
'is_customer_avatar_removed' => [
'nullable',
'boolean',
],
];
}
/** @return array<string, mixed> */
public function customerAttributes(): array
{
return $this->safe()->only(['name', 'email', 'password']);
}
/** @return array<string, mixed>|null */
public function shippingAddress(): ?array
{
$address = $this->input('shipping');
if (! is_array($address)) {
return null;
}
return collect($address)
->merge([
'type' => Address::SHIPPING_TYPE,
])
->toArray();
}
/** @return array<string, mixed>|null */
public function billingAddress(): ?array
{
$address = $this->input('billing');
if (! is_array($address)) {
return null;
}
return collect($address)
->merge([
'type' => Address::BILLING_TYPE,
])
->toArray();
}
}
@@ -1,200 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Requests;
use App\Domains\Contacts\Models\Address;
use App\Rules\IdnEmail;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Validation\Rule;
class CustomerRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
$rules = [
'name' => [
'required',
],
'email' => [
new IdnEmail,
'nullable',
Rule::unique('customers')->where('company_id', $this->header('company')),
],
'password' => [
'nullable',
],
'phone' => [
'nullable',
],
'company_name' => [
'nullable',
],
'contact_name' => [
'nullable',
],
'website' => [
'nullable',
],
'prefix' => [
'nullable',
],
'tax_id' => [
'nullable',
],
'enable_portal' => [
'boolean',
],
'currency_id' => [
'nullable',
],
'billing.name' => [
'nullable',
],
'billing.address_street_1' => [
'nullable',
],
'billing.address_street_2' => [
'nullable',
],
'billing.city' => [
'nullable',
],
'billing.state' => [
'nullable',
],
'billing.country_id' => [
'nullable',
],
'billing.zip' => [
'nullable',
],
'billing.phone' => [
'nullable',
],
'billing.fax' => [
'nullable',
],
'shipping.name' => [
'nullable',
],
'shipping.address_street_1' => [
'nullable',
],
'shipping.address_street_2' => [
'nullable',
],
'shipping.city' => [
'nullable',
],
'shipping.state' => [
'nullable',
],
'shipping.country_id' => [
'nullable',
],
'shipping.zip' => [
'nullable',
],
'shipping.phone' => [
'nullable',
],
'shipping.fax' => [
'nullable',
],
];
if ($this->isMethod('PUT') && $this->email != null) {
$rules['email'] = [
new IdnEmail,
'nullable',
Rule::unique('customers')->where('company_id', $this->header('company'))->ignore($this->route('customer')->id),
];
}
return $rules;
}
/** @return array<string, mixed> */
public function customerAttributes(): array
{
return collect($this->validated())
->only([
'name',
'email',
'currency_id',
'password',
'phone',
'prefix',
'tax_id',
'company_name',
'contact_name',
'website',
'enable_portal',
'estimate_prefix',
'payment_prefix',
'invoice_prefix',
])
->merge([
'creator_id' => $this->user()->id,
'company_id' => $this->header('company'),
])
->toArray();
}
/** @return array<string, mixed>|null */
public function shippingAddress(): ?array
{
$address = $this->input('shipping');
if (! is_array($address) || ! $this->hasAddress($address)) {
return null;
}
return collect($address)
->merge([
'type' => Address::SHIPPING_TYPE,
])
->toArray();
}
/** @return array<string, mixed>|null */
public function billingAddress(): ?array
{
$address = $this->input('billing');
if (! is_array($address) || ! $this->hasAddress($address)) {
return null;
}
return collect($address)
->merge([
'type' => Address::BILLING_TYPE,
])
->toArray();
}
/** @return array<int, mixed>|null */
public function customFields(): ?array
{
$customFields = $this->input('customFields');
return is_array($customFields) && $customFields !== [] ? $customFields : null;
}
private function hasAddress(array $address): bool
{
return Arr::where($address, fn ($value): bool => isset($value)) !== [];
}
}
@@ -1,33 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class DeleteCustomersRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'ids' => [
'required',
],
'ids.*' => [
'required',
Rule::exists('customers', 'id'),
],
];
}
}
@@ -1,41 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Resources;
use App\Domains\Accounts\Http\Resources\UserResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class AddressResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'address_street_1' => $this->address_street_1,
'address_street_2' => $this->address_street_2,
'city' => $this->city,
'state' => $this->state,
'country_id' => $this->country_id,
'zip' => $this->zip,
'phone' => $this->phone,
'fax' => $this->fax,
'type' => $this->type,
'user_id' => $this->user_id,
'company_id' => $this->company_id,
'customer_id' => $this->customer_id,
'country' => $this->when($this->country()->exists(), function () {
return new CountryResource($this->country);
}),
'user' => $this->when($this->user()->exists(), function () {
return new UserResource($this->user);
}),
];
}
}
@@ -1,24 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CountryResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'code' => $this->code,
'name' => $this->name,
'phone_code' => $this->phone_code,
];
}
}
@@ -1,41 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Resources\CustomerPortal;
use App\Domains\Accounts\Http\Resources\CustomerPortal\UserResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class AddressResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'address_street_1' => $this->address_street_1,
'address_street_2' => $this->address_street_2,
'city' => $this->city,
'state' => $this->state,
'country_id' => $this->country_id,
'zip' => $this->zip,
'phone' => $this->phone,
'fax' => $this->fax,
'type' => $this->type,
'user_id' => $this->user_id,
'company_id' => $this->company_id,
'customer_id' => $this->customer_id,
'country' => $this->when($this->country()->exists(), function () {
return new CountryResource($this->country);
}),
'user' => $this->when($this->user()->exists(), function () {
return new UserResource($this->user);
}),
];
}
}
@@ -1,24 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Resources\CustomerPortal;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CountryResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'code' => $this->code,
'name' => $this->name,
'phonecode' => $this->phonecode,
];
}
}
@@ -1,55 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Resources\CustomerPortal;
use App\Domains\Accounts\Http\Resources\CustomerPortal\CompanyResource;
use App\Domains\Metadata\Http\Resources\CustomerPortal\CustomFieldValueResource;
use App\Domains\Money\Http\Resources\CustomerPortal\CurrencyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CustomerResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'phone' => $this->phone,
'contact_name' => $this->contact_name,
'company_name' => $this->company_name,
'website' => $this->website,
'enable_portal' => $this->enable_portal,
'currency_id' => $this->currency_id,
'company_id' => $this->company_id,
'facebook_id' => $this->facebook_id,
'google_id' => $this->google_id,
'github_id' => $this->github_id,
'formatted_created_at' => $this->formattedCreatedAt,
'avatar' => $this->avatar,
'prefix' => $this->prefix,
'tax_id' => $this->tax_id,
'billing' => $this->when($this->billingAddress()->exists(), function () {
return new AddressResource($this->billingAddress);
}),
'shipping' => $this->when($this->shippingAddress()->exists(), function () {
return new AddressResource($this->shippingAddress);
}),
'fields' => $this->when($this->fields()->exists(), function () {
return CustomFieldValueResource::collection($this->fields);
}),
'company' => $this->when($this->company()->exists(), function () {
return new CompanyResource($this->company);
}),
'currency' => $this->when($this->currency()->exists(), function () {
return new CurrencyResource($this->currency);
}),
];
}
}
@@ -1,66 +0,0 @@
<?php
namespace App\Domains\Contacts\Http\Resources;
use App\Domains\Accounts\Http\Resources\CompanyResource;
use App\Domains\Metadata\Http\Resources\CustomFieldValueResource;
use App\Domains\Money\Http\Resources\CurrencyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CustomerResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'phone' => $this->phone,
'contact_name' => $this->contact_name,
'company_name' => $this->company_name,
'website' => $this->website,
'enable_portal' => $this->enable_portal,
'password_added' => $this->password ? true : false,
'currency_id' => $this->currency_id,
'company_id' => $this->company_id,
'facebook_id' => $this->facebook_id,
'google_id' => $this->google_id,
'github_id' => $this->github_id,
'created_at' => $this->created_at,
'formatted_created_at' => $this->formattedCreatedAt,
'updated_at' => $this->updated_at,
'avatar' => $this->avatar,
'due_amount' => $this->due_amount,
'base_due_amount' => $this->base_due_amount,
'invoice_due_amount' => $this->invoice_due_amount,
'base_invoice_due_amount' => $this->base_invoice_due_amount,
'available_credit' => $this->available_credit,
'base_available_credit' => $this->base_available_credit,
'account_balance' => $this->account_balance,
'base_account_balance' => $this->base_account_balance,
'prefix' => $this->prefix,
'tax_id' => $this->tax_id,
'billing' => $this->when($this->billingAddress()->exists(), function () {
return new AddressResource($this->billingAddress);
}),
'shipping' => $this->when($this->shippingAddress()->exists(), function () {
return new AddressResource($this->shippingAddress);
}),
'fields' => $this->when($this->fields()->exists(), function () {
return CustomFieldValueResource::collection($this->fields);
}),
'company' => $this->when($this->company()->exists(), function () {
return new CompanyResource($this->company);
}),
'currency' => $this->when($this->currency()->exists(), function () {
return new CurrencyResource($this->currency);
}),
];
}
}
-59
View File
@@ -1,59 +0,0 @@
<?php
namespace App\Domains\Contacts\Models;
use App\Domains\Accounts\Models\Company;
use App\Domains\Accounts\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Symfony\Component\Intl\Countries;
class Address extends Model
{
protected $table = 'addresses';
use HasFactory;
public const BILLING_TYPE = 'billing';
public const SHIPPING_TYPE = 'shipping';
protected $guarded = ['id'];
public function getCountryNameAttribute(): ?string
{
if (! $this->country) {
return null;
}
try {
return Countries::getName(
$this->country->code,
app()->getLocale()
);
} catch (\Exception $e) {
return $this->country->name;
}
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public function country(): BelongsTo
{
return $this->belongsTo(Country::class);
}
}
-19
View File
@@ -1,19 +0,0 @@
<?php
namespace App\Domains\Contacts\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Country extends Model
{
protected $table = 'countries';
use HasFactory;
public function address(): HasMany
{
return $this->hasMany(Address::class);
}
}
-257
View File
@@ -1,257 +0,0 @@
<?php
namespace App\Domains\Contacts\Models;
use App\Domains\Accounts\Models\Company;
use App\Domains\Accounts\Models\CompanySetting;
use App\Domains\Contacts\Notifications\CustomerMailResetPasswordNotification;
use App\Domains\Metadata\Concerns\HasCustomFields;
use App\Domains\Money\Models\Currency;
use App\Domains\Purchases\Models\Expense;
use App\Domains\Receivables\Models\Payment;
use App\Domains\Sales\Models\Estimate;
use App\Domains\Sales\Models\Invoice;
use App\Domains\Sales\Models\RecurringInvoice;
use App\Platform\Mail\Models\EmailLog;
use App\Support\SafeOrderBy;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Silber\Bouncer\Database\HasRolesAndAbilities;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Customer extends Authenticatable implements HasMedia
{
protected $table = 'customers';
use HasApiTokens;
use HasCustomFields;
use HasFactory;
use HasRolesAndAbilities;
use InteractsWithMedia;
use Notifiable;
protected $guarded = [
'id',
];
protected $hidden = [
'password',
'remember_token',
];
protected $with = [
'currency',
];
protected $appends = [
'formattedCreatedAt',
'avatar',
];
protected function casts(): array
{
return [
'enable_portal' => 'boolean',
];
}
public function getFormattedCreatedAtAttribute($value)
{
$dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id);
return Carbon::parse($this->created_at)->translatedFormat($dateFormat);
}
public function setPasswordAttribute($value)
{
if ($value != null) {
$this->attributes['password'] = bcrypt($value);
}
}
public function estimates(): HasMany
{
return $this->hasMany(Estimate::class);
}
public function expenses(): HasMany
{
return $this->hasMany(Expense::class);
}
public function invoices(): HasMany
{
return $this->hasMany(Invoice::class);
}
public function payments(): HasMany
{
return $this->hasMany(Payment::class);
}
public function emailLogs(): MorphMany
{
return $this->morphMany(EmailLog::class, 'mailable');
}
public function addresses(): HasMany
{
return $this->hasMany(Address::class);
}
public function recurringInvoices(): HasMany
{
return $this->hasMany(RecurringInvoice::class);
}
public function currency(): BelongsTo
{
return $this->belongsTo(Currency::class);
}
public function creator(): BelongsTo
{
return $this->belongsTo(Customer::class, 'creator_id');
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public function billingAddress(): HasOne
{
return $this->hasOne(Address::class)->where('type', Address::BILLING_TYPE);
}
public function shippingAddress(): HasOne
{
return $this->hasOne(Address::class)->where('type', Address::SHIPPING_TYPE);
}
public function sendPasswordResetNotification(mixed $token): void
{
$this->notify(new CustomerMailResetPasswordNotification($token));
}
public function getAvatarAttribute()
{
$avatar = $this->getMedia('customer_avatar')->first();
if ($avatar) {
return asset($avatar->getUrl());
}
return 0;
}
public function scopePaginateData($query, $limit)
{
if ($limit == 'all') {
return $query->get();
}
return $query->paginate($limit);
}
public function scopeWhereCompany($query)
{
return $query->where('customers.company_id', request()->header('company'));
}
public function scopeWhereContactName($query, $contactName)
{
return $query->where('contact_name', 'LIKE', '%'.$contactName.'%');
}
public function scopeWhereDisplayName($query, $displayName)
{
return $query->where('name', 'LIKE', '%'.$displayName.'%');
}
public function scopeWhereOrder($query, $orderByField, $orderBy)
{
SafeOrderBy::apply($query, $orderByField, $orderBy);
}
public function scopeWhereSearch($query, $search)
{
foreach (explode(' ', $search) as $term) {
$query->where(function ($query) use ($term) {
$query->where('name', 'LIKE', '%'.$term.'%')
->orWhere('email', 'LIKE', '%'.$term.'%')
->orWhere('phone', 'LIKE', '%'.$term.'%');
});
}
}
public function scopeWherePhone($query, $phone)
{
return $query->where('phone', 'LIKE', '%'.$phone.'%');
}
public function scopeWhereCustomer($query, $customer_id)
{
$query->orWhere('customers.id', $customer_id);
}
public function scopeApplyInvoiceFilters($query, array $filters)
{
$filters = collect($filters);
if ($filters->get('from_date') && $filters->get('to_date')) {
$start = Carbon::createFromFormat('Y-m-d', $filters->get('from_date'));
$end = Carbon::createFromFormat('Y-m-d', $filters->get('to_date'));
$query->invoicesBetween($start, $end);
}
}
public function scopeInvoicesBetween($query, $start, $end)
{
$query->whereHas('invoices', function ($query) use ($start, $end) {
$query->whereBetween(
'invoice_date',
[$start->format('Y-m-d'), $end->format('Y-m-d')]
);
});
}
public function scopeApplyFilters($query, array $filters)
{
$filters = collect($filters);
if ($filters->get('search')) {
$query->whereSearch($filters->get('search'));
}
if ($filters->get('contact_name')) {
$query->whereContactName($filters->get('contact_name'));
}
if ($filters->get('display_name')) {
$query->whereDisplayName($filters->get('display_name'));
}
if ($filters->get('customer_id')) {
$query->whereCustomer($filters->get('customer_id'));
}
if ($filters->get('phone')) {
$query->wherePhone($filters->get('phone'));
}
if ($filters->get('orderByField') || $filters->get('orderBy')) {
$field = $filters->get('orderByField') ? $filters->get('orderByField') : 'name';
$orderBy = $filters->get('orderBy') ? $filters->get('orderBy') : 'asc';
$query->whereOrder($field, $orderBy);
}
}
}
@@ -1,62 +0,0 @@
<?php
namespace App\Domains\Contacts\Notifications;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class CustomerMailResetPasswordNotification extends ResetPassword
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($token)
{
parent::__construct($token);
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
*/
public function via($notifiable): array
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
*/
public function toMail($notifiable): MailMessage
{
$link = url("/{$notifiable->company->slug}/customer/reset/password/".$this->token);
return (new MailMessage)
->subject('Reset Password Notification')
->line('Hello! You are receiving this email because we received a password reset request for your account.')
->action('Reset Password', $link)
->line('This password reset link will expire in '.config('auth.passwords.users.expire').' minutes')
->line('If you did not request a password reset, no further action is required.');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
*/
public function toArray($notifiable): array
{
return [
//
];
}
}
@@ -1,125 +0,0 @@
<?php
namespace App\Domains\Contacts\Policies;
use App\Domains\Accounts\Models\User;
use App\Domains\Contacts\Models\Customer;
use Illuminate\Auth\Access\HandlesAuthorization;
use Silber\Bouncer\BouncerFacade;
class CustomerPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* @return mixed
*/
public function viewAny(User $user): bool
{
if (BouncerFacade::can('view-customer', Customer::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can view the model.
*
* @return mixed
*/
public function view(User $user, Customer $customer): bool
{
if (BouncerFacade::can('view-customer', $customer) && $user->hasCompany($customer->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can create models.
*
* @return mixed
*/
public function create(User $user): bool
{
if (BouncerFacade::can('create-customer', Customer::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can update the model.
*
* @return mixed
*/
public function update(User $user, Customer $customer): bool
{
if (BouncerFacade::can('edit-customer', $customer) && $user->hasCompany($customer->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can delete the model.
*
* @return mixed
*/
public function delete(User $user, Customer $customer): bool
{
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can restore the model.
*
* @return mixed
*/
public function restore(User $user, Customer $customer): bool
{
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can permanently delete the model.
*
* @return mixed
*/
public function forceDelete(User $user, Customer $customer): bool
{
if (BouncerFacade::can('delete-customer', $customer) && $user->hasCompany($customer->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can delete models.
*
* @return mixed
*/
public function deleteMultiple(User $user)
{
if (BouncerFacade::can('delete-customer', Customer::class)) {
return true;
}
return false;
}
}