diff --git a/app/Classes/General/Eloquent/Filters/DoesNotHaveSegments.php b/app/Classes/General/Eloquent/Filters/DoesNotHaveSegments.php new file mode 100644 index 00000000..88a1ab3d --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/DoesNotHaveSegments.php @@ -0,0 +1,21 @@ +whereDoesntHave('segments', function ($segment) use ($value) { + $segment->whereIn('id', $value); + }); + } +} diff --git a/app/Classes/General/Eloquent/Filters/SegmentsIn.php b/app/Classes/General/Eloquent/Filters/SegmentsIn.php new file mode 100644 index 00000000..3f756810 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/SegmentsIn.php @@ -0,0 +1,21 @@ +whereHas('segments', function ($segment) use ($value) { + $segment->whereIn('id', $value); + }); + } +} diff --git a/app/Classes/General/Eloquent/Filters/WithOutTransactions.php b/app/Classes/General/Eloquent/Filters/WithOutTransactions.php new file mode 100644 index 00000000..3b551f65 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WithOutTransactions.php @@ -0,0 +1,20 @@ +whereDoesntHave('transactions'); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/WithTotalPayments.php b/app/Classes/General/Eloquent/Filters/WithTotalPayments.php new file mode 100644 index 00000000..d93e55e2 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WithTotalPayments.php @@ -0,0 +1,25 @@ +leftJoin('bookings', 'companies.id', '=', 'bookings.company_id')->rightJoin('transactions', function ($join) { + $join->on('bookings.id', '=', 'transactions.booking_id')->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + })->addSelect(['companies.*', DB::raw('SUM(transactions.amount) as total_payments')])->groupBy(['companies.id']); + } +} \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/WithoutConfirmedPayments.php b/app/Classes/General/Eloquent/Filters/WithoutConfirmedPayments.php new file mode 100644 index 00000000..e17ed5da --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WithoutConfirmedPayments.php @@ -0,0 +1,24 @@ +whereDoesntHave('transactions', function($transaction){ + return $transaction->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]); + }); + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php index b2a0732a..df2a7960 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php @@ -80,7 +80,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic $outstanding = $this->calculatesBookingOutstanding->execute($booking); - if($conversionObject->getAmount() > $outstanding) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.'); + if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.'); $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject); diff --git a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php index c20450d8..5885d560 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/FetchBookingPaymentQuotationLogic.php @@ -68,7 +68,7 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]); $outstanding = $this->calculatesBookingOutstanding->execute($booking); - if($conversionObject->getAmount() > $outstanding) throw new MalformedRequestException('Your payment must not be greater than '.$booking->fixedCurrency->short_code.' '. number_format((float)$outstanding, 2, '.', ',')); + if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '.$booking->fixedCurrency->short_code.' '. number_format((float)$outstanding, 2, '.', ',')); return $this->response(['data' => $this->generatesBookingQuotation->execute( $this->fetchBookingQuotation->execute($booking->company, $conversionObject), diff --git a/app/Http/Resources/CompanyResource.php b/app/Http/Resources/CompanyResource.php index 655cfc98..a35c7082 100644 --- a/app/Http/Resources/CompanyResource.php +++ b/app/Http/Resources/CompanyResource.php @@ -9,6 +9,7 @@ use App\Classes\ValueObjects\Constants\BusinessType; use App\Classes\ValueObjects\Constants\DocumentType; use App\Classes\ValueObjects\Constants\RoleTypes; use App\Classes\ValueObjects\Constants\SegmentConstants; +use App\Classes\ValueObjects\Constants\TransactionType; use App\Models\Currency; use App\Models\SegmentConstant; use Illuminate\Http\Resources\Json\JsonResource; @@ -24,6 +25,7 @@ class CompanyResource extends JsonResource */ public function toArray($request) { + $lastPayment = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->orderBy('id', 'DESC')->first(); return [ 'id' => $this->id, 'name' => $this->name, @@ -33,9 +35,11 @@ class CompanyResource extends JsonResource 'status' => (int) $this->status, 'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())), 'address' => new AddressResource($this->when($this->has('addresses'), $this->addresses->where('billing', true)->first())), - 'employee' => new UserResource(Auth::user()->type === RoleTypes::USER ? $this->employees()->where('email', '=', Auth::user()->email)->first() : $this->employees()->where('users.status', '=', ApprovalStatus::APPROVED)->orderBy('id', 'DESC')->first()), + 'employee' => new UserResource(Auth::user()->type === RoleTypes::USER ? $this->employees()->where('email', '=', Auth::user()->email)->first() : $this->employees()->orderBy('id', 'DESC')->first()), 'identification' => new DocumentResource($this->documents->whereIn('document_type', DocumentType::IDENTIFICATION_DOCUMENTS)->first()), 'bookings' => $this->whenLoaded('bookings', $this->bookings()->orderBy('id', 'DESC')->get(), []), + 'total_payments' => (float) $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'), + 'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments', 'personal_banks' => BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)), 'recipient_banks' => [ 'accounts' => BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)), @@ -46,7 +50,8 @@ class CompanyResource extends JsonResource 'currencies' => $this->when($this->business_type === BusinessType::CURRENCY_VENDOR, function(){ $segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first(); return $segment ? CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : []; - }) + }), + 'created_at' => $this->created_at->format('d-m-Y') ]; diff --git a/app/Models/Company.php b/app/Models/Company.php index c1a6a191..e2c9dda4 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -12,6 +12,9 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Collection; +use Staudenmeir\EloquentHasManyDeep\HasManyDeep; +use Staudenmeir\EloquentHasManyDeep\HasRelationships; + /** * Class Company @@ -27,11 +30,12 @@ use Illuminate\Support\Collection; */ class Company extends AbstractModel implements Documentable { + use HasRelationships; use SoftDeletes; protected $table = 'companies'; - protected $dates = ['deleted_at']; + protected $dates = ['deleted_at', 'created_at']; /** @@ -90,6 +94,14 @@ class Company extends AbstractModel implements Documentable return $this->HasMany(Booking::class, 'company_id'); } + /** + * @return hasManyDeep + */ + public function transactions(): hasManyDeep + { + return $this->hasManyDeep(Transaction::class, [Booking::class], ['company_id', 'booking_id'], ['id', 'id']); + } + /** * @return Builder */ diff --git a/composer.json b/composer.json index 7c7d11ba..377c8932 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "php": "^7.2.5", "ext-fileinfo": "*", "ext-json": "^1.6", + "ext-zip": "*", "barryvdh/laravel-dompdf": "^0.9.0", "carlos-meneses/laravel-mpdf": "^2.1", "fideloper/proxy": "^4.2", @@ -23,8 +24,8 @@ "rinvex/countries": "^6.1", "spatie/laravel-activitylog": "^3.14", "spatie/laravel-permission": "^3.17", - "tymon/jwt-auth": "^1.0", - "ext-zip": "*" + "staudenmeir/eloquent-has-many-deep": "^1.7", + "tymon/jwt-auth": "^1.0" }, "require-dev": { "facade/ignition": "^2.0", diff --git a/config/database.php b/config/database.php index b42d9b30..aeabec6f 100644 --- a/config/database.php +++ b/config/database.php @@ -56,7 +56,7 @@ return [ 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, - 'strict' => true, + 'strict' => false, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), diff --git a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue index de55e62c..ba3a39b1 100644 --- a/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue +++ b/resources/assets/vue/components/bookings/forms/PurchaseOrderFormComponent.vue @@ -101,9 +101,9 @@