mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-09-05 23:01:07 +00:00
chore(receivables): remove legacy-era receivables sources
This commit is contained in:
@@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Controllers\Company;
|
||||
|
||||
use App\Domains\Receivables\Http\Requests\PaymentMethodRequest;
|
||||
use App\Domains\Receivables\Http\Resources\PaymentMethodResource;
|
||||
use App\Domains\Receivables\Models\PaymentMethod;
|
||||
use App\Platform\Http\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class PaymentMethodsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('viewAny', PaymentMethod::class);
|
||||
|
||||
$limit = $request->has('limit') ? $request->limit : 5;
|
||||
|
||||
$paymentMethods = PaymentMethod::applyFilters($request->all())
|
||||
->where('type', PaymentMethod::TYPE_GENERAL)
|
||||
->whereCompany()
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
|
||||
return PaymentMethodResource::collection($paymentMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function store(PaymentMethodRequest $request)
|
||||
{
|
||||
$this->authorize('create', PaymentMethod::class);
|
||||
|
||||
$paymentMethod = PaymentMethod::create($request->getPaymentMethodPayload());
|
||||
|
||||
return new PaymentMethodResource($paymentMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function show(PaymentMethod $paymentMethod)
|
||||
{
|
||||
$this->authorize('view', $paymentMethod);
|
||||
|
||||
return new PaymentMethodResource($paymentMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function update(PaymentMethodRequest $request, PaymentMethod $paymentMethod)
|
||||
{
|
||||
$this->authorize('update', $paymentMethod);
|
||||
|
||||
$paymentMethod->update($request->getPaymentMethodPayload());
|
||||
|
||||
return new PaymentMethodResource($paymentMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function destroy(PaymentMethod $paymentMethod)
|
||||
{
|
||||
$this->authorize('delete', $paymentMethod);
|
||||
|
||||
if ($paymentMethod->payments()->exists()) {
|
||||
return respondJson('payments_attached', 'Payments Attached.');
|
||||
}
|
||||
|
||||
if ($paymentMethod->expenses()->exists()) {
|
||||
return respondJson('expenses_attached', 'Expenses Attached.');
|
||||
}
|
||||
|
||||
$paymentMethod->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => 'Payment method deleted successfully',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Controllers\Company;
|
||||
|
||||
use App\Domains\Receivables\Application\PaymentAllocationService;
|
||||
use App\Domains\Receivables\Application\PaymentService;
|
||||
use App\Domains\Receivables\Http\Requests\DeletePaymentsRequest;
|
||||
use App\Domains\Receivables\Http\Requests\PaymentRequest;
|
||||
use App\Domains\Receivables\Http\Requests\ReplacePaymentAllocationsRequest;
|
||||
use App\Domains\Receivables\Http\Requests\SendPaymentRequest;
|
||||
use App\Domains\Receivables\Http\Resources\PaymentResource;
|
||||
use App\Domains\Receivables\Models\Payment;
|
||||
use App\Platform\Http\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Mail\Markdown;
|
||||
|
||||
class PaymentsController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly PaymentAllocationService $paymentAllocationService,
|
||||
private readonly PaymentService $paymentService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('viewAny', Payment::class);
|
||||
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$payments = Payment::with(['allocations.invoice'])
|
||||
->whereCompany()
|
||||
->join('customers', 'customers.id', '=', 'payments.customer_id')
|
||||
->leftJoin('payment_methods', 'payment_methods.id', '=', 'payments.payment_method_id')
|
||||
->applyFilters($request->all())
|
||||
->select('payments.*', 'customers.name', 'payment_methods.name as payment_mode')
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
|
||||
return PaymentResource::collection($payments)
|
||||
->additional(['meta' => [
|
||||
'payment_total_count' => Payment::whereCompany()->count(),
|
||||
]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function store(PaymentRequest $request)
|
||||
{
|
||||
$this->authorize('create', Payment::class);
|
||||
|
||||
$payment = $this->paymentService->create(
|
||||
attributes: $request->getPaymentPayload(),
|
||||
allocations: $request->validated('allocations') ?? [],
|
||||
customFields: $this->customFields($request),
|
||||
);
|
||||
|
||||
return new PaymentResource($payment);
|
||||
}
|
||||
|
||||
public function show(Request $request, Payment $payment)
|
||||
{
|
||||
$this->authorize('view', $payment);
|
||||
|
||||
return new PaymentResource($payment->load(['allocations.invoice']));
|
||||
}
|
||||
|
||||
public function update(PaymentRequest $request, Payment $payment)
|
||||
{
|
||||
$this->authorize('update', $payment);
|
||||
|
||||
$payment = $this->paymentService->update(
|
||||
payment: $payment,
|
||||
attributes: $request->getPaymentPayload(),
|
||||
replaceAllocations: $request->exists('allocations'),
|
||||
allocations: $request->validated('allocations') ?? [],
|
||||
customFields: $this->customFields($request),
|
||||
);
|
||||
|
||||
return new PaymentResource($payment);
|
||||
}
|
||||
|
||||
public function replaceAllocations(ReplacePaymentAllocationsRequest $request, Payment $payment)
|
||||
{
|
||||
$this->authorize('update', $payment);
|
||||
|
||||
abort_unless((int) $payment->company_id === (int) $request->header('company'), 404);
|
||||
|
||||
$payment = $this->paymentAllocationService->replace($payment, $request->validated('allocations'));
|
||||
|
||||
return new PaymentResource($payment->load(['allocations.invoice']));
|
||||
}
|
||||
|
||||
public function delete(DeletePaymentsRequest $request)
|
||||
{
|
||||
$this->authorize('delete multiple payments');
|
||||
|
||||
$ids = Payment::whereCompany()
|
||||
->whereIn('id', $request->ids)
|
||||
->pluck('id');
|
||||
|
||||
$this->paymentService->delete($ids);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function send(SendPaymentRequest $request, Payment $payment)
|
||||
{
|
||||
$this->authorize('send payment', $payment);
|
||||
|
||||
$response = $this->paymentService->send($payment, $request->all());
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
|
||||
public function sendPreview(Request $request, Payment $payment)
|
||||
{
|
||||
$this->authorize('send payment', $payment);
|
||||
|
||||
$markdown = new Markdown(view(), config('mail.markdown'));
|
||||
|
||||
$data = $this->paymentService->sendPaymentData($payment, $request->all());
|
||||
$data['url'] = $payment->paymentPdfUrl;
|
||||
|
||||
return $markdown->render('emails.send.payment', ['data' => $data]);
|
||||
}
|
||||
|
||||
private function customFields(PaymentRequest $request): ?iterable
|
||||
{
|
||||
$customFields = $request->input('customFields');
|
||||
|
||||
return is_iterable($customFields) ? $customFields : null;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Controllers\CustomerPortal;
|
||||
|
||||
use App\Domains\Accounts\Models\Company;
|
||||
use App\Domains\Receivables\Http\Resources\CustomerPortal\PaymentMethodResource;
|
||||
use App\Domains\Receivables\Models\PaymentMethod;
|
||||
use App\Platform\Http\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class PaymentMethodController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle the incoming request.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function __invoke(Request $request, Company $company)
|
||||
{
|
||||
return PaymentMethodResource::collection(PaymentMethod::where('company_id', $company->id)->get());
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Controllers\CustomerPortal;
|
||||
|
||||
use App\Domains\Accounts\Models\Company;
|
||||
use App\Domains\Receivables\Http\Resources\CustomerPortal\PaymentResource;
|
||||
use App\Domains\Receivables\Models\Payment;
|
||||
use App\Platform\Http\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PaymentsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$limit = $request->has('limit') ? $request->limit : 10;
|
||||
|
||||
$payments = Payment::with(['customer', 'allocations.invoice', 'paymentMethod', 'creator'])
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->applyFilters($request->only([
|
||||
'payment_number',
|
||||
'payment_method_id',
|
||||
'orderByField',
|
||||
'orderBy',
|
||||
]))
|
||||
->select('payments.*')
|
||||
->latest()
|
||||
->paginateData($limit);
|
||||
|
||||
return PaymentResource::collection($payments)
|
||||
->additional(['meta' => [
|
||||
'paymentTotalCount' => Payment::whereCustomer(Auth::guard('customer')->id())->count(),
|
||||
]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param Payment $payment
|
||||
* @return Response
|
||||
*/
|
||||
public function show(Company $company, $id)
|
||||
{
|
||||
$payment = $company->payments()
|
||||
->whereCustomer(Auth::guard('customer')->id())
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $payment) {
|
||||
return response()->json(['error' => 'payment_not_found'], 404);
|
||||
}
|
||||
|
||||
return new PaymentResource($payment->load(['allocations.invoice']));
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Controllers;
|
||||
|
||||
use App\Domains\Receivables\Http\Resources\PaymentResource;
|
||||
use App\Domains\Receivables\Models\Payment;
|
||||
use App\Platform\Http\Controller;
|
||||
use App\Platform\Mail\Models\EmailLog;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PublicPaymentController extends Controller
|
||||
{
|
||||
public function getPdf(EmailLog $emailLog, Request $request)
|
||||
{
|
||||
$payment = $emailLog->mailable;
|
||||
abort_unless($payment instanceof Payment, 404);
|
||||
abort_if($emailLog->isExpired(), 403, 'Link Expired.');
|
||||
|
||||
return $payment->getGeneratedPDFOrStream('payment');
|
||||
}
|
||||
|
||||
public function getPayment(EmailLog $emailLog)
|
||||
{
|
||||
$payment = $emailLog->mailable;
|
||||
abort_unless($payment instanceof Payment, 404);
|
||||
abort_if($emailLog->isExpired(), 403, 'Link Expired.');
|
||||
|
||||
return new PaymentResource($payment);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class DeletePaymentsRequest 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('payments', 'id'),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Requests;
|
||||
|
||||
use App\Domains\Receivables\Models\PaymentMethod;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class PaymentMethodRequest 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('payment_methods')
|
||||
->where('company_id', $this->header('company')),
|
||||
],
|
||||
];
|
||||
|
||||
if ($this->getMethod() == 'PUT') {
|
||||
$data['name'] = [
|
||||
'required',
|
||||
Rule::unique('payment_methods')
|
||||
->ignore($this->route('payment_method'), 'id')
|
||||
->where('company_id', $this->header('company')),
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getPaymentMethodPayload()
|
||||
{
|
||||
return collect($this->validated())
|
||||
->merge([
|
||||
'company_id' => $this->header('company'),
|
||||
'type' => PaymentMethod::TYPE_GENERAL,
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Requests;
|
||||
|
||||
use App\Domains\Accounts\Models\CompanySetting;
|
||||
use App\Domains\Contacts\Models\Customer;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
class PaymentRequest 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 = [
|
||||
'payment_date' => [
|
||||
'required',
|
||||
],
|
||||
'customer_id' => [
|
||||
'required',
|
||||
Rule::exists('customers', 'id')->where('company_id', $this->header('company')),
|
||||
],
|
||||
'exchange_rate' => [
|
||||
'nullable',
|
||||
'numeric',
|
||||
'gt:0',
|
||||
],
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
'payment_number' => [
|
||||
'required',
|
||||
Rule::unique('payments')->where('company_id', $this->header('company')),
|
||||
],
|
||||
'allocations' => ['sometimes', 'array'],
|
||||
'allocations.*.invoice_id' => ['required', 'integer', 'distinct'],
|
||||
'allocations.*.amount' => ['required', 'integer', 'min:1'],
|
||||
'payment_method_id' => [
|
||||
'nullable',
|
||||
],
|
||||
'notes' => [
|
||||
'nullable',
|
||||
],
|
||||
];
|
||||
|
||||
if ($this->isMethod('PUT')) {
|
||||
$rules['payment_number'] = [
|
||||
'required',
|
||||
Rule::unique('payments')
|
||||
->ignore($this->route('payment')->id)
|
||||
->where('company_id', $this->header('company')),
|
||||
];
|
||||
}
|
||||
|
||||
$companyCurrency = CompanySetting::getSetting('currency', $this->header('company'));
|
||||
|
||||
$customer = Customer::find($this->customer_id);
|
||||
|
||||
if ($customer && $companyCurrency) {
|
||||
if ((string) $customer->currency_id !== $companyCurrency) {
|
||||
$rules['exchange_rate'] = [
|
||||
'required',
|
||||
'numeric',
|
||||
'gt:0',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject the retired field without advertising it in the generated API
|
||||
* schema. Payment-to-invoice links now exist only inside allocations.
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(function (Validator $validator): void {
|
||||
if ($this->exists('invoice_id')) {
|
||||
$validator->errors()->add(
|
||||
'invoice_id',
|
||||
__('validation.prohibited', ['attribute' => 'invoice id'])
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function getPaymentPayload()
|
||||
{
|
||||
$company_currency = CompanySetting::getSetting('currency', $this->header('company'));
|
||||
$currency = Customer::find($this->customer_id)->currency_id;
|
||||
$exchange_rate = (string) $company_currency !== (string) $currency
|
||||
? (float) $this->exchange_rate
|
||||
: 1;
|
||||
|
||||
return collect($this->validated())
|
||||
->except('allocations')
|
||||
->merge([
|
||||
'creator_id' => $this->user()->id,
|
||||
'company_id' => $this->header('company'),
|
||||
'exchange_rate' => $exchange_rate,
|
||||
'base_amount' => (int) round($this->amount * $exchange_rate),
|
||||
'currency_id' => $currency,
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SendPaymentRequest 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 [
|
||||
'subject' => [
|
||||
'required',
|
||||
],
|
||||
'body' => [
|
||||
'required',
|
||||
],
|
||||
'from' => [
|
||||
'required',
|
||||
],
|
||||
'to' => [
|
||||
'required',
|
||||
],
|
||||
'cc' => [
|
||||
'nullable',
|
||||
],
|
||||
'bcc' => [
|
||||
'nullable',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Resources\CustomerPortal;
|
||||
|
||||
use App\Domains\Accounts\Http\Resources\CustomerPortal\CompanyResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PaymentMethodResource 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);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Resources\CustomerPortal;
|
||||
|
||||
use App\Domains\Accounts\Http\Resources\CustomerPortal\CompanyResource;
|
||||
use App\Domains\Contacts\Http\Resources\CustomerPortal\CustomerResource;
|
||||
use App\Domains\Metadata\Http\Resources\CustomerPortal\CustomFieldValueResource;
|
||||
use App\Domains\Money\Http\Resources\CustomerPortal\CurrencyResource;
|
||||
use App\Domains\Sales\Http\Resources\CustomerPortal\InvoiceResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PaymentResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param Request $request
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
$allocations = $this->relationLoaded('allocations')
|
||||
? $this->allocations
|
||||
: $this->allocations()->with('invoice')->get();
|
||||
$allocatedAmount = (int) $allocations->sum('amount');
|
||||
$baseAllocatedAmount = (int) $allocations->sum('base_amount');
|
||||
$baseAmount = $this->base_amount === null
|
||||
? (int) round($this->amount * ($this->exchange_rate ?: 1))
|
||||
: (int) $this->base_amount;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'payment_number' => $this->payment_number,
|
||||
'payment_date' => $this->payment_date,
|
||||
'notes' => $this->notes,
|
||||
'amount' => $this->amount,
|
||||
'unique_hash' => $this->unique_hash,
|
||||
'company_id' => $this->company_id,
|
||||
'payment_method_id' => $this->payment_method_id,
|
||||
'customer_id' => $this->customer_id,
|
||||
'exchange_rate' => $this->exchange_rate,
|
||||
'base_amount' => $baseAmount,
|
||||
'allocations' => $allocations->map(fn ($allocation) => [
|
||||
'id' => $allocation->id,
|
||||
'invoice_id' => $allocation->invoice_id,
|
||||
'amount' => $allocation->amount,
|
||||
'base_amount' => $allocation->base_amount,
|
||||
'invoice' => $allocation->invoice ? new InvoiceResource($allocation->invoice) : null,
|
||||
]),
|
||||
'allocated_amount' => $allocatedAmount,
|
||||
'unallocated_amount' => (int) ((int) $this->amount - $allocatedAmount),
|
||||
'base_allocated_amount' => $baseAllocatedAmount,
|
||||
'base_unallocated_amount' => (int) ($baseAmount - $baseAllocatedAmount),
|
||||
'currency_id' => $this->currency_id,
|
||||
'transaction_id' => $this->transaction_id,
|
||||
'formatted_created_at' => $this->formattedCreatedAt,
|
||||
'formatted_payment_date' => $this->formattedPaymentDate,
|
||||
'payment_pdf_url' => $this->paymentPdfUrl,
|
||||
'customer' => $this->when($this->customer()->exists(), function () {
|
||||
return new CustomerResource($this->customer);
|
||||
}),
|
||||
'payment_method' => $this->when($this->paymentMethod()->exists(), function () {
|
||||
return new PaymentMethodResource($this->paymentMethod);
|
||||
}),
|
||||
'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);
|
||||
}),
|
||||
'transaction' => $this->when($this->transaction()->exists(), function () {
|
||||
return new TransactionResource($this->transaction);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Resources\CustomerPortal;
|
||||
|
||||
use App\Domains\Accounts\Http\Resources\CustomerPortal\CompanyResource;
|
||||
use App\Domains\Sales\Http\Resources\CustomerPortal\InvoiceResource;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class TransactionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array|Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'transaction_id' => $this->transaction_id,
|
||||
'type' => $this->type,
|
||||
'status' => $this->status,
|
||||
'transaction_date' => $this->transaction_date,
|
||||
'invoice_id' => $this->invoice_id,
|
||||
'invoice' => $this->when($this->invoice()->exists(), function () {
|
||||
return new InvoiceResource($this->invoice);
|
||||
}),
|
||||
'company' => $this->when($this->company()->exists(), function () {
|
||||
return new CompanyResource($this->company);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Resources;
|
||||
|
||||
use App\Domains\Accounts\Http\Resources\CompanyResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PaymentMethodResource 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,
|
||||
'type' => $this->type,
|
||||
'company' => $this->when($this->company()->exists(), function () {
|
||||
return new CompanyResource($this->company);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Resources;
|
||||
|
||||
use App\Domains\Accounts\Http\Resources\CompanyResource;
|
||||
use App\Domains\Contacts\Http\Resources\CustomerResource;
|
||||
use App\Domains\Metadata\Http\Resources\CustomFieldValueResource;
|
||||
use App\Domains\Money\Http\Resources\CurrencyResource;
|
||||
use App\Domains\Sales\Http\Resources\InvoiceResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PaymentResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param Request $request
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
$allocations = $this->relationLoaded('allocations')
|
||||
? $this->allocations
|
||||
: $this->allocations()->with('invoice')->get();
|
||||
$allocatedAmount = (int) $allocations->sum('amount');
|
||||
$baseAllocatedAmount = (int) $allocations->sum('base_amount');
|
||||
$baseAmount = $this->base_amount === null
|
||||
? (int) round($this->amount * ($this->exchange_rate ?: 1))
|
||||
: (int) $this->base_amount;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'payment_number' => $this->payment_number,
|
||||
'payment_date' => $this->payment_date,
|
||||
'notes' => $this->getNotes(),
|
||||
'amount' => $this->amount,
|
||||
'unique_hash' => $this->unique_hash,
|
||||
'company_id' => $this->company_id,
|
||||
'payment_method_id' => $this->payment_method_id,
|
||||
'creator_id' => $this->creator_id,
|
||||
'customer_id' => $this->customer_id,
|
||||
'exchange_rate' => $this->exchange_rate,
|
||||
'base_amount' => $baseAmount,
|
||||
'allocations' => $allocations->map(fn ($allocation) => [
|
||||
'id' => $allocation->id,
|
||||
'invoice_id' => $allocation->invoice_id,
|
||||
'amount' => $allocation->amount,
|
||||
'base_amount' => $allocation->base_amount,
|
||||
'invoice' => $allocation->invoice ? new InvoiceResource($allocation->invoice) : null,
|
||||
]),
|
||||
'allocated_amount' => $allocatedAmount,
|
||||
'unallocated_amount' => (int) ((int) $this->amount - $allocatedAmount),
|
||||
'base_allocated_amount' => $baseAllocatedAmount,
|
||||
'base_unallocated_amount' => (int) ($baseAmount - $baseAllocatedAmount),
|
||||
'currency_id' => $this->currency_id,
|
||||
'transaction_id' => $this->transaction_id,
|
||||
'sequence_number' => $this->sequence_number,
|
||||
'formatted_created_at' => $this->formattedCreatedAt,
|
||||
'formatted_payment_date' => $this->formattedPaymentDate,
|
||||
'payment_pdf_url' => $this->paymentPdfUrl,
|
||||
'customer' => $this->when($this->customer()->exists(), function () {
|
||||
return new CustomerResource($this->customer);
|
||||
}),
|
||||
'payment_method' => $this->when($this->paymentMethod()->exists(), function () {
|
||||
return new PaymentMethodResource($this->paymentMethod);
|
||||
}),
|
||||
'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);
|
||||
}),
|
||||
'transaction' => $this->when($this->transaction()->exists(), function () {
|
||||
return new TransactionResource($this->transaction);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Http\Resources;
|
||||
|
||||
use App\Domains\Accounts\Http\Resources\CompanyResource;
|
||||
use App\Domains\Sales\Http\Resources\InvoiceResource;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class TransactionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array|Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'transaction_id' => $this->transaction_id,
|
||||
'type' => $this->type,
|
||||
'status' => $this->status,
|
||||
'transaction_date' => $this->transaction_date,
|
||||
'invoice_id' => $this->invoice_id,
|
||||
'invoice' => $this->when($this->invoice()->exists(), function () {
|
||||
return new InvoiceResource($this->invoice);
|
||||
}),
|
||||
'company' => $this->when($this->company()->exists(), function () {
|
||||
return new CompanyResource($this->company);
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class GeneratePaymentPdfJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
public $payment;
|
||||
|
||||
public $deleteExistingFile;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($payment, $deleteExistingFile = false)
|
||||
{
|
||||
$this->payment = $payment;
|
||||
$this->deleteExistingFile = $deleteExistingFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->payment->generatePDF('payment', $this->payment->payment_number, $this->deleteExistingFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Mail;
|
||||
|
||||
use App\Domains\Receivables\Models\Payment;
|
||||
use App\Platform\Mail\Contracts\EmailLogWriter;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class SendPaymentMail extends Mailable
|
||||
{
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
public $data = [];
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$payment = Payment::findOrFail($this->data['payment']['id']);
|
||||
$token = app(EmailLogWriter::class)->record($payment, [
|
||||
'from' => $this->data['from'],
|
||||
'to' => $this->data['to'],
|
||||
'cc' => $this->data['cc'] ?? null,
|
||||
'bcc' => $this->data['bcc'] ?? null,
|
||||
'subject' => $this->data['subject'],
|
||||
'body' => $this->data['body'],
|
||||
]);
|
||||
|
||||
$this->data['url'] = route('payment', ['email_log' => $token]);
|
||||
|
||||
$mailContent = $this->from($this->data['from'], config('mail.from.name'))
|
||||
->subject($this->data['subject'])
|
||||
->markdown('emails.send.payment', ['data', $this->data]);
|
||||
|
||||
if ($this->data['attach']['data']) {
|
||||
$mailContent->attachData(
|
||||
$this->data['attach']['data']->output(),
|
||||
$this->data['payment']['payment_number'].'.pdf'
|
||||
);
|
||||
}
|
||||
|
||||
return $mailContent;
|
||||
}
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Models;
|
||||
|
||||
use App\Domains\Accounts\Models\Company;
|
||||
use App\Domains\Accounts\Models\CompanySetting;
|
||||
use App\Domains\Accounts\Models\User;
|
||||
use App\Domains\Contacts\Models\Customer;
|
||||
use App\Domains\Metadata\Concerns\HasCustomFields;
|
||||
use App\Domains\Money\Models\Currency;
|
||||
use App\Domains\Receivables\Contracts\PaymentPdfDataProvider;
|
||||
use App\Domains\Receivables\Jobs\GeneratePaymentPdfJob;
|
||||
use App\Domains\Sales\Models\Invoice;
|
||||
use App\Platform\Mail\Models\EmailLog;
|
||||
use App\Platform\Pdf\Concerns\GeneratesPdf;
|
||||
use App\Platform\Pdf\Rendering\PdfHtmlSanitizer;
|
||||
use App\Support\SafeOrderBy;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
||||
class Payment extends Model implements HasMedia
|
||||
{
|
||||
protected $table = 'payments';
|
||||
|
||||
use GeneratesPdf;
|
||||
use HasCustomFields;
|
||||
use HasFactory;
|
||||
use InteractsWithMedia;
|
||||
|
||||
protected $dates = ['created_at', 'updated_at', 'payment_date'];
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
protected $appends = [
|
||||
'formattedCreatedAt',
|
||||
'formattedPaymentDate',
|
||||
'paymentPdfUrl',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'notes' => 'string',
|
||||
'exchange_rate' => 'float',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::created(function ($payment) {
|
||||
DB::afterCommit(fn () => GeneratePaymentPdfJob::dispatch($payment)->afterCommit());
|
||||
});
|
||||
|
||||
static::updated(function ($payment) {
|
||||
DB::afterCommit(fn () => GeneratePaymentPdfJob::dispatch($payment, true)->afterCommit());
|
||||
});
|
||||
}
|
||||
|
||||
public function setSettingsAttribute($value)
|
||||
{
|
||||
if ($value) {
|
||||
$this->attributes['settings'] = json_encode($value);
|
||||
}
|
||||
}
|
||||
|
||||
public function getFormattedCreatedAtAttribute($value)
|
||||
{
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id);
|
||||
|
||||
return Carbon::parse($this->created_at)->translatedFormat($dateFormat);
|
||||
}
|
||||
|
||||
public function getFormattedPaymentDateAttribute($value)
|
||||
{
|
||||
$dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id);
|
||||
|
||||
return Carbon::parse($this->payment_date)->translatedFormat($dateFormat);
|
||||
}
|
||||
|
||||
public function getPaymentPdfUrlAttribute()
|
||||
{
|
||||
return url('/payments/pdf/'.$this->unique_hash);
|
||||
}
|
||||
|
||||
public function transaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Transaction::class);
|
||||
}
|
||||
|
||||
public function emailLogs(): MorphMany
|
||||
{
|
||||
return $this->morphMany(EmailLog::class, 'mailable');
|
||||
}
|
||||
|
||||
public function customer(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Customer::class, 'customer_id');
|
||||
}
|
||||
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function allocations(): HasMany
|
||||
{
|
||||
return $this->hasMany(PaymentAllocation::class);
|
||||
}
|
||||
|
||||
public function invoices(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Invoice::class, 'payment_allocations')
|
||||
->withPivot(['amount', 'base_amount'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'creator_id');
|
||||
}
|
||||
|
||||
public function currency(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Currency::class);
|
||||
}
|
||||
|
||||
public function paymentMethod(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(PaymentMethod::class);
|
||||
}
|
||||
|
||||
public function scopeWhereSearch($query, $search)
|
||||
{
|
||||
foreach (explode(' ', $search) as $term) {
|
||||
$query->whereHas('customer', function ($query) use ($term) {
|
||||
$query->where('name', 'LIKE', '%'.$term.'%')
|
||||
->orWhere('contact_name', 'LIKE', '%'.$term.'%')
|
||||
->orWhere('company_name', 'LIKE', '%'.$term.'%');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function scopePaymentNumber($query, $paymentNumber)
|
||||
{
|
||||
return $query->where('payments.payment_number', 'LIKE', '%'.$paymentNumber.'%');
|
||||
}
|
||||
|
||||
public function scopePaymentMethod($query, $paymentMethodId)
|
||||
{
|
||||
return $query->where('payments.payment_method_id', $paymentMethodId);
|
||||
}
|
||||
|
||||
public function scopePaginateData($query, $limit)
|
||||
{
|
||||
if ($limit == 'all') {
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
return $query->paginate($limit);
|
||||
}
|
||||
|
||||
public function scopeApplyFilters($query, array $filters)
|
||||
{
|
||||
$filters = collect($filters);
|
||||
|
||||
if ($filters->get('search')) {
|
||||
$query->whereSearch($filters->get('search'));
|
||||
}
|
||||
|
||||
if ($filters->get('payment_number')) {
|
||||
$query->paymentNumber($filters->get('payment_number'));
|
||||
}
|
||||
|
||||
if ($filters->get('payment_id')) {
|
||||
$query->wherePayment($filters->get('payment_id'));
|
||||
}
|
||||
|
||||
if ($filters->get('payment_method_id')) {
|
||||
$query->paymentMethod($filters->get('payment_method_id'));
|
||||
}
|
||||
|
||||
if ($filters->get('customer_id')) {
|
||||
$query->whereCustomer($filters->get('customer_id'));
|
||||
}
|
||||
|
||||
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->paymentsBetween($start, $end);
|
||||
}
|
||||
|
||||
if ($filters->get('orderByField') || $filters->get('orderBy')) {
|
||||
$field = $filters->get('orderByField') ? $filters->get('orderByField') : 'sequence_number';
|
||||
$orderBy = $filters->get('orderBy') ? $filters->get('orderBy') : 'desc';
|
||||
$query->whereOrder($field, $orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
public function scopePaymentsBetween($query, $start, $end)
|
||||
{
|
||||
return $query->whereBetween(
|
||||
'payments.payment_date',
|
||||
[$start->format('Y-m-d'), $end->format('Y-m-d')]
|
||||
);
|
||||
}
|
||||
|
||||
public function scopeWhereOrder($query, $orderByField, $orderBy)
|
||||
{
|
||||
SafeOrderBy::apply($query, $orderByField, $orderBy);
|
||||
}
|
||||
|
||||
public function scopeWherePayment($query, $payment_id)
|
||||
{
|
||||
$query->orWhere('id', $payment_id);
|
||||
}
|
||||
|
||||
public function scopeWhereCompany($query)
|
||||
{
|
||||
$query->where('payments.company_id', request()->header('company'));
|
||||
}
|
||||
|
||||
public function scopeWhereCustomer($query, $customer_id)
|
||||
{
|
||||
$query->where('payments.customer_id', $customer_id);
|
||||
}
|
||||
|
||||
public function getPDFData(): mixed
|
||||
{
|
||||
return app(PaymentPdfDataProvider::class)->getPdfData($this);
|
||||
}
|
||||
|
||||
public function getCompanyAddress(): string|false
|
||||
{
|
||||
if ($this->company && (! $this->company->address()->exists())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$format = CompanySetting::getSetting('payment_company_address_format', $this->company_id);
|
||||
|
||||
return $this->getFormattedString($format);
|
||||
}
|
||||
|
||||
public function getCustomerBillingAddress(): string|false
|
||||
{
|
||||
if ($this->customer && (! $this->customer->billingAddress()->exists())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$format = CompanySetting::getSetting('payment_from_customer_address_format', $this->company_id);
|
||||
|
||||
return $this->getFormattedString($format);
|
||||
}
|
||||
|
||||
public function getEmailAttachmentSetting(): bool
|
||||
{
|
||||
$paymentAsAttachment = CompanySetting::getSetting('payment_email_attachment', $this->company_id);
|
||||
|
||||
if ($paymentAsAttachment == 'NO') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getNotes(): string
|
||||
{
|
||||
return PdfHtmlSanitizer::sanitize($this->getFormattedString($this->notes));
|
||||
}
|
||||
|
||||
public function getEmailBody(string $body): string
|
||||
{
|
||||
$values = array_merge($this->getFieldsArray(), $this->getExtraFields());
|
||||
|
||||
$body = strtr($body, $values);
|
||||
|
||||
return preg_replace('/{(.*?)}/', '', $body);
|
||||
}
|
||||
|
||||
public function getExtraFields(): array
|
||||
{
|
||||
return [
|
||||
'{PAYMENT_DATE}' => $this->formattedPaymentDate,
|
||||
'{PAYMENT_MODE}' => $this->paymentMethod ? $this->paymentMethod->name : null,
|
||||
'{PAYMENT_NUMBER}' => $this->payment_number,
|
||||
'{PAYMENT_AMOUNT}' => format_money_pdf($this->amount, $this->customer->currency),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Models;
|
||||
|
||||
use App\Domains\Accounts\Models\Company;
|
||||
use App\Domains\Purchases\Models\Expense;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class PaymentMethod extends Model
|
||||
{
|
||||
protected $table = 'payment_methods';
|
||||
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [
|
||||
'id',
|
||||
];
|
||||
|
||||
public const TYPE_GENERAL = 'GENERAL';
|
||||
|
||||
public const TYPE_MODULE = 'MODULE';
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'settings' => 'array',
|
||||
'use_test_env' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function setSettingsAttribute($value)
|
||||
{
|
||||
$this->attributes['settings'] = json_encode($value);
|
||||
}
|
||||
|
||||
public function payments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
}
|
||||
|
||||
public function expenses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Expense::class);
|
||||
}
|
||||
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function scopeWhereCompanyId($query, $id)
|
||||
{
|
||||
$query->where('company_id', $id);
|
||||
}
|
||||
|
||||
public function scopeWhereCompany($query)
|
||||
{
|
||||
$query->where('company_id', request()->header('company'));
|
||||
}
|
||||
|
||||
public function scopeWherePaymentMethod($query, $payment_id)
|
||||
{
|
||||
$query->orWhere('id', $payment_id);
|
||||
}
|
||||
|
||||
public function scopeWhereSearch($query, $search)
|
||||
{
|
||||
$query->where('name', 'LIKE', '%'.$search.'%');
|
||||
}
|
||||
|
||||
public function scopeApplyFilters($query, array $filters)
|
||||
{
|
||||
$filters = collect($filters);
|
||||
|
||||
if ($filters->get('method_id')) {
|
||||
$query->wherePaymentMethod($filters->get('method_id'));
|
||||
}
|
||||
|
||||
if ($filters->get('company_id')) {
|
||||
$query->whereCompany($filters->get('company_id'));
|
||||
}
|
||||
|
||||
if ($filters->get('search')) {
|
||||
$query->whereSearch($filters->get('search'));
|
||||
}
|
||||
}
|
||||
|
||||
public function scopePaginateData($query, $limit)
|
||||
{
|
||||
if ($limit == 'all') {
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
return $query->paginate($limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the settings array for a payment method by its ID.
|
||||
*/
|
||||
public static function getSettings(int $id): mixed
|
||||
{
|
||||
$settings = PaymentMethod::find($id)
|
||||
->settings;
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Models;
|
||||
|
||||
use App\Domains\Accounts\Models\Company;
|
||||
use App\Domains\Accounts\Models\CompanySetting;
|
||||
use App\Domains\Sales\Models\Invoice;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Transaction extends Model
|
||||
{
|
||||
protected $table = 'transactions';
|
||||
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [
|
||||
'id',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'transaction_date',
|
||||
];
|
||||
|
||||
public const FAILED = 'FAILED';
|
||||
|
||||
public const SUCCESS = 'SUCCESS';
|
||||
|
||||
public function payments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
}
|
||||
|
||||
public function invoice(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Invoice::class);
|
||||
}
|
||||
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a completed transaction's public link has expired based on the
|
||||
* company's link expiry settings (link_expiry_days and automatically_expire_public_links).
|
||||
*/
|
||||
public function isExpired(): bool
|
||||
{
|
||||
$linkExpiryDays = (int) CompanySetting::getSetting('link_expiry_days', $this->company_id);
|
||||
$checkExpiryLinks = CompanySetting::getSetting('automatically_expire_public_links', $this->company_id);
|
||||
|
||||
$expiryDate = $this->updated_at->addDays($linkExpiryDays);
|
||||
|
||||
if ($checkExpiryLinks == 'YES' && $this->status == self::SUCCESS && Carbon::now()->format('Y-m-d') > $expiryDate->format('Y-m-d')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Policies;
|
||||
|
||||
use App\Domains\Accounts\Models\User;
|
||||
use App\Domains\Receivables\Models\Payment;
|
||||
use App\Domains\Receivables\Models\PaymentMethod;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Silber\Bouncer\BouncerFacade;
|
||||
|
||||
class PaymentMethodPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', Payment::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function view(User $user, PaymentMethod $paymentMethod): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', Payment::class) && $user->hasCompany($paymentMethod->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-payment', Payment::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(User $user, PaymentMethod $paymentMethod): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', Payment::class) && $user->hasCompany($paymentMethod->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete(User $user, PaymentMethod $paymentMethod): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', Payment::class) && $user->hasCompany($paymentMethod->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore(User $user, PaymentMethod $paymentMethod): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', Payment::class) && $user->hasCompany($paymentMethod->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceDelete(User $user, PaymentMethod $paymentMethod): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', Payment::class) && $user->hasCompany($paymentMethod->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Receivables\Policies;
|
||||
|
||||
use App\Domains\Accounts\Models\User;
|
||||
use App\Domains\Receivables\Models\Payment;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Silber\Bouncer\BouncerFacade;
|
||||
|
||||
class PaymentPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', Payment::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function view(User $user, Payment $payment): bool
|
||||
{
|
||||
if (BouncerFacade::can('view-payment', $payment) && $user->hasCompany($payment->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-payment', Payment::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(User $user, Payment $payment): bool
|
||||
{
|
||||
if (BouncerFacade::can('edit-payment', $payment) && $user->hasCompany($payment->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete(User $user, Payment $payment): bool
|
||||
{
|
||||
if (BouncerFacade::can('delete-payment', $payment) && $user->hasCompany($payment->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore(User $user, Payment $payment): bool
|
||||
{
|
||||
if (BouncerFacade::can('delete-payment', $payment) && $user->hasCompany($payment->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceDelete(User $user, Payment $payment): bool
|
||||
{
|
||||
if (BouncerFacade::can('delete-payment', $payment) && $user->hasCompany($payment->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can send email of the model.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function send(User $user, Payment $payment)
|
||||
{
|
||||
if (BouncerFacade::can('send-payment', $payment) && $user->hasCompany($payment->company_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete models.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function deleteMultiple(User $user)
|
||||
{
|
||||
if (BouncerFacade::can('delete-payment', Payment::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user