fix up group transactions bulk purchase orders

This commit is contained in:
omair saleh
2022-07-14 01:33:39 +08:00
parent 90461b172a
commit b9bb6b874b
19 changed files with 361 additions and 238 deletions
@@ -0,0 +1,22 @@
<?php
namespace App\Classes\Jobs;
use App\Classes\Modules\Transactions\Processors\GeneratesGroupTransactionsPurchaseOrder;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class GenerateGroupTransactionsPurchaseOrder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $timeout = 900;
public function handle()
{
(App()->make(GeneratesGroupTransactionsPurchaseOrder::class))->execute();
}
}
@@ -3,25 +3,15 @@
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\Jobs\GenerateGroupTransactionsPurchaseOrder;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Transactions\Services\ListsGroups;
use App\Classes\Modules\Transactions\Services\FetchesGroup;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Transactions\Processors\CreateInvoiceDocumentProcessor;
class CreateBulkPurchaseOrderDocumentLogic extends AbstractControllerLogic
{
/**
* @return array
*/
@@ -33,71 +23,25 @@ class CreateBulkPurchaseOrderDocumentLogic extends AbstractControllerLogic
];
}
/** @var ListsGroups */
private $listsGroups;
/** @var FetchesGroup */
private $fetchesGroup;
/** @var FetchesCompany */
private $fetchesCompany;
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFile;
/** @var GenerateGroupTransactionsPurchaseOrder */
private $generateGroupTransactionsPurchaseOrder;
/**
* CreateBulkPurchaseOrderTransactionLogic constructor.
* @param ListsGroups $listsGroups
* @param FetchesGroup $fetchesGroup
* @param FetchesCompany $fetchesCompany
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFile
* CreateBulkPurchaseOrderDocumentLogic constructor.
* @param GenerateGroupTransactionsPurchaseOrder $generateGroupTransactionsPurchaseOrder
*/
public function __construct(ListsGroups $listsGroups, FetchesGroup $fetchesGroup, FetchesCompany $fetchesCompany, CreatesDocument $createsDocument, CreatesFiles $createsFile)
public function __construct(GenerateGroupTransactionsPurchaseOrder $generateGroupTransactionsPurchaseOrder)
{
$this->listsGroups = $listsGroups;
$this->fetchesGroup = $fetchesGroup;
$this->fetchesCompany = $fetchesCompany;
$this->createsDocument = $createsDocument;
$this->createsFile = $createsFile;
$this->generateGroupTransactionsPurchaseOrder = $generateGroupTransactionsPurchaseOrder;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request): JsonResponse
{
$group = $this->fetchesGroup->execute(['id' => $request->route('id')]);
foreach ($group->transactions as $transaction) {
if ($transaction->owner()->owner()->transactions()->where('type', TransactionType::PURCHASE_ORDER)->where('status', '!=', ApprovalStatus::APPROVED)->exists()) {
throw new MalformedRequestException('You can\'t generate bulk purchased order if there in uncomplete transactions');
}
}
$supplier = $this->fetchesCompany->execute(['id' => $group->receiver]);
$document_type = DocumentType::BULK_PURCHASE_ORDER;
$lowercaseDocumentType = strtolower($document_type);
$order_pdf = LaravelMpdf::loadView('pages.pdfs.' . $lowercaseDocumentType, ['group' => $group, 'supplier' => $supplier]);
$document_object = new DocumentObject(
$document_type,
[chunk_split('data:application/pdf;base64,' . base64_encode($order_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
$lowercaseDocumentType . 's'
);
/** @var Document $document */
$document = $this->createsDocument->execute($group, $document_object);
$this->createsFile->execute($document, $document_object);
$this->generateGroupTransactionsPurchaseOrder::dispatch();
return $this->response([]);
}
@@ -122,7 +122,7 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
);
/** @var Document $document */
$document = $this->createsDocument->execute($supplier, $object);
$document = $this->createsDocument->execute($group, $object);
$this->createsFile->execute($document, $object);
@@ -0,0 +1,91 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
ini_set('memory_limit', '-1');
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Transactions\Services\ListsGroups;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Document;
use App\Models\Group;
use App\Models\Transaction;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
class GeneratesGroupTransactionsPurchaseOrder
{
/** @var ListsGroups */
private $listsGroups;
/** @var FetchesCompany */
private $fetchesCompany;
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFile;
/**
* GenerateGroupTransactionsPurchaseOrder constructor.
* @param ListsGroups $listsGroups
* @param FetchesCompany $fetchesCompany
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFile
*/
public function __construct(ListsGroups $listsGroups, FetchesCompany $fetchesCompany, CreatesDocument $createsDocument, CreatesFiles $createsFile)
{
$this->listsGroups = $listsGroups;
$this->fetchesCompany = $fetchesCompany;
$this->createsDocument = $createsDocument;
$this->createsFile = $createsFile;
}
public function execute(){
$groups = Group::where('status', '!=', ApprovalStatus::COMPLETED)->whereDoesntHave('transactions', function ($query){
$query->whereHasMorph('owner', [Transaction::class], function($query){
return $query->whereHas('booking', function($query){
return $query->whereDoesntHave('transactions', function($query){
return $query->where('type', TransactionType::PURCHASE_ORDER)->where('status', '=', ApprovalStatus::APPROVED);
});
});
});
})->get();
foreach ($groups as $group) {
// if ($transaction->owner()->owner()->transactions()->where('type', TransactionType::PURCHASE_ORDER)->where('status', '!=', ApprovalStatus::APPROVED)->exists()) {
// throw new MalformedRequestException('You can\'t generate bulk purchased order if there in uncomplete transactions');
// }
$supplier = $this->fetchesCompany->execute(['id' => $group->receiver]);
$document_type = DocumentType::BULK_PURCHASE_ORDER;
$lowercaseDocumentType = strtolower($document_type);
$order_pdf = LaravelMpdf::loadView('pages.pdfs.bulk_purchase_order', ['group' => $group, 'supplier' => $supplier]);
$document_object = new DocumentObject(
$document_type,
[chunk_split('data:application/pdf;base64,' . base64_encode($order_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
$lowercaseDocumentType . 's'
);
/** @var Document $document */
$document = $this->createsDocument->execute($group, $document_object);
$this->createsFile->execute($document, $document_object);
$group->status = ApprovalStatus::COMPLETED;
$group->save();
}
}
}
+34 -34
View File
@@ -31,43 +31,43 @@ class BookingResource extends JsonResource
'service' => new ServiceTypeResource($this->service),
'marking' => $this->marking,
'amount' => $this->fix_amount,
// 'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)),
// 'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
// 'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
// 'fixed_currency' => new CurrencyResource($this->fixedCurrency),
// 'convertible_currency' => new CurrencyResource($this->convertibleCurrency),
// 'conversion_currency' => new CurrencyResource($this->conversionCurrency),
// 'documents' => [
// 'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()),
// 'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()),
// 'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()),
// 'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()),
// 'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()),
// ],
'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)),
'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
'fixed_currency' => new CurrencyResource($this->fixedCurrency),
'convertible_currency' => new CurrencyResource($this->convertibleCurrency),
'conversion_currency' => new CurrencyResource($this->conversionCurrency),
'documents' => [
'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()),
'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()),
'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()),
'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()),
'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()),
],
'status' => $this->status,
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
// $this->mergeWhen($this->relationLoaded('transactions'), [
// 'purchase_order' => new TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()),
// 'payment_attempts' => TransactionResource::collection(
// $this->transactions()
// ->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)
// ->whereDate('expires_on', '>=', Carbon::now())
// ->get()
// ),
// 'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '<', Carbon::now())->get()),
// 'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){
// $query->where(function($query){
// $query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]);
// })->orWhere(function($query){
// $query->where(function($query){
// $query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]);
// })->orWhere(function($query){
// $query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
// });
// });
// })->latest()->get())
// ])
$this->mergeWhen($this->relationLoaded('transactions'), [
'purchase_order' => new TransactionResource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()),
'payment_attempts' => TransactionResource::collection(
$this->transactions()
->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)
->whereDate('expires_on', '>=', Carbon::now())
->get()
),
'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '<', Carbon::now())->get()),
'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){
$query->where(function($query){
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]);
})->orWhere(function($query){
$query->where(function($query){
$query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]);
})->orWhere(function($query){
$query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
});
});
})->latest()->get())
])
];
}
}
+27 -27
View File
@@ -40,33 +40,33 @@ class CompanyResource extends JsonResource
'type' => (int) $this->type,
'business_type' => (int) $this->business_type,
'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()->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(), []),
// 'confirmed_bookings' => $this->bookings()->whereHas('transactions', function ($query){
// $query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
// })->count(),
// 'total_payments' => (float) $totalPayments,
// 'average_spending_per_day' => (float) $totalPayments / ($this->created_at->diff(Carbon::now())->days === 0 ? 1 : $this->created_at->diff(Carbon::now())->days),
// 'average_spending_per_booking' => (float) $totalPayments > 0 ? $totalPayments / $this->bookings()->whereHas('transactions', function ($query){
// $query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
// })->count() : $totalPayments,
// '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)),
// 'default' => new BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first())
// ],
// 'segments' => SegmentResource::collection($this->segments),
// 'services' => (new FetchesCompanyServices())->getServices($this->servicesConfigurations()),
// 'wallet' => new WalletResource($this->wallets()->first()),
// 'created_at' => $this->created_at->format('d-m-Y'),
// $this->mergeWhen($this->business_type === BusinessType::CURRENCY_VENDOR, [
// 'currencies' => $segment ? CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : [],
// 'service_charge' => $serviceCharge
// ])
'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()->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(), []),
'confirmed_bookings' => $this->bookings()->whereHas('transactions', function ($query){
$query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})->count(),
'total_payments' => (float) $totalPayments,
'average_spending_per_day' => (float) $totalPayments / ($this->created_at->diff(Carbon::now())->days === 0 ? 1 : $this->created_at->diff(Carbon::now())->days),
'average_spending_per_booking' => (float) $totalPayments > 0 ? $totalPayments / $this->bookings()->whereHas('transactions', function ($query){
$query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
})->count() : $totalPayments,
'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)),
'default' => new BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first())
],
'segments' => SegmentResource::collection($this->segments),
'services' => (new FetchesCompanyServices())->getServices($this->servicesConfigurations()),
'wallet' => new WalletResource($this->wallets()->first()),
'created_at' => $this->created_at->format('d-m-Y'),
$this->mergeWhen($this->business_type === BusinessType::CURRENCY_VENDOR, [
'currencies' => $segment ? CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : [],
'service_charge' => $serviceCharge
])
];
}
+18 -10
View File
@@ -3,7 +3,10 @@
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Resources\Json\JsonResource;
@@ -18,25 +21,30 @@ class GroupResource extends JsonResource
*/
public function toArray($request)
{
$transactions = $this->transactions()->get();
$complete_transactions = new Collection([]);
foreach($transactions as $transaction){
$booking = $transaction->owner()->first()->owner()->first();
$purchaseOrders = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->where('status', '=', ApprovalStatus::APPROVED)->get();
$complete_transactions = $complete_transactions->merge($purchaseOrders);
}
return [
'id' => $this->id,
'original_amount' => (float) $this->original_amount,
'original_currency' => new CurrencyResource($this->original_currency),
'issuer_name' => $this->issuerCompany->name,
'issuer_id' => $this->issuerCompany->id,
'amount' => (float) $this->amount,
'service_charge' => (float) $this->amount,
'currency' => new CurrencyResource($this->currency),
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
'currency_rate' => (float) $this->currency_rate,
'transactions' => TransactionResource::collection($transactions),
'complete_transactions' => TransactionResource::collection($complete_transactions),
'transactions' => $this->transactions()->count(),
'complete_transactions' => $this->transactions()->whereHasMorph('owner', [Transaction::class], function($query){
return $query->whereHas('booking', function($query){
return $query->whereHas('transactions', function($query){
return $query->where('type', TransactionType::PURCHASE_ORDER)->where('status', '=', ApprovalStatus::APPROVED);
});
});
})->count(),
'documents' => [
'currency_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::CURRENCY_VENDOR_ORDER)->first()),
'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::BULK_PURCHASE_ORDER)->first())
]
];
}
}
+13 -13
View File
@@ -18,17 +18,17 @@ class TransactionResource extends JsonResource
public function toArray($request)
{
// $booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner;
// $days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1);
$booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner;
$days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1);
return [
'id' => $this->id,
// 'booking' => new BookingResource($booking),
'booking' => new BookingResource($booking),
'type' => (int) $this->type,
'bill_no' => $this->bill_no,
'payment_reference' => $this->payment_reference,
'payment_method' => (float) $this->payment_method,
// 'recipient_bank_account' => new BankResource($booking->bank),
'recipient_bank_account' => new BankResource($booking->bank),
'issuer_name' => $this->issuerCompany->name,
'issuer_id' => $this->issuerCompany->id,
'amount' => (double) $this->amount,
@@ -40,15 +40,15 @@ class TransactionResource extends JsonResource
'currency_rate' => (double) $this->currency_rate,
'status' => (int) $this->status,
'details' => TransactionDetailResource::collection($this->transactionDetails),
// 'documents' => new DocumentResource($this->documents()->first()),
// 'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())),
// 'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())),
// 'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'),
// 'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'),
// 'interval' => [
// 'value' => $days->gt(Carbon::now()) ? '+' : '-',
// 'duration' => $days->diff(Carbon::now())->format('%d'),
// ]
'documents' => new DocumentResource($this->documents()->first()),
'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())),
'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())),
'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'),
'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'),
'interval' => [
'value' => $days->gt(Carbon::now()) ? '+' : '-',
'duration' => $days->diff(Carbon::now())->format('%d'),
]
];
}
}
+21
View File
@@ -6,11 +6,15 @@ use Illuminate\Database\Eloquent\Model;
use App\Classes\General\Interfaces\Documentable;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Staudenmeir\EloquentHasManyDeep\HasManyDeep;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
class Group extends Model implements Documentable
{
use HasRelationships;
use \Staudenmeir\EloquentHasManyDeep\HasTableAlias;
public $timestamps = false;
public function transactions()
{
@@ -33,6 +37,23 @@ class Group extends Model implements Documentable
return $this->BelongsTo(Currency::class, 'currency_id', 'id');
}
/**
* @return HasManyDeep
*/
public function transferFees(): HasManyDeep
{
return $this->HasManyDeep(Transaction::class, [GroupTransaction::class, Transaction::class.' as alias'], ['group_id', ['owner_type', 'owner_id'], ['owner_type', 'owner_id']], ['id', null, null]);
}
/**
* @return BelongsTo
*/
public function issuerCompany(): BelongsTo
{
return $this->BelongsTo( Company::class, 'issuer', 'id');
}
/**
* @return BelongsTo
*/
@@ -1,5 +1,6 @@
<?php
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
@@ -24,6 +25,7 @@ class CreateGroupsTable extends Migration
$table->decimal('currency_rate', 14, 5)->default(0.00);
$table->decimal('tax', 14, 5)->default(0.00);
$table->decimal('service_charge', 14, 5)->default(0.00);
$table->integer('status')->default(ApprovalStatus::PENDING_VERIFICATION);
$table->timestamps();
});
}
@@ -1,14 +1,39 @@
<?php
ini_set('memory_limit', '-1');
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Document;
use App\Models\Transaction;
use App\Models\Group;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
class RecoverGroupTransactionTableSeeder extends Seeder
{
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFile;
/**
* RecoverGroupTransactionTableSeeder constructor.
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFile
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFile)
{
$this->createsDocument = $createsDocument;
$this->createsFile = $createsFile;
}
/**
* Run the database seeds.
*
@@ -17,24 +42,22 @@ class RecoverGroupTransactionTableSeeder extends Seeder
{
DB::beginTransaction();
$document = Document::where('document_type', 'CURRENCY_VENDOR_ORDER')->get();
$transaction_group = Transaction::
select('issuer', 'currency_rate', 'type', DB::raw('count(DISTINCT id) as total'), DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d') as new_date"))
select('issuer', 'currency_rate', 'type', DB::raw('count(DISTINCT id) as total'), DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d %H:%i') as new_date"))
->where('type', 3)
->groupBy(
'issuer',
'currency_rate',
'new_date'
)
->get();
// %H:%i
->orderBy('id')->get();
foreach ($transaction_group as $key => $row) {
$transaction = Transaction::
foreach ($transaction_group as $group) {
$transactions = Transaction::
where('type', 3)
->where('issuer', $row->issuer)
->where('currency_rate', $row->currency_rate)
->where(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')"), $row->new_date)
->where('issuer', $group->issuer)
->where('currency_rate', $group->currency_rate)
->where(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d %H:%i')"), $group->new_date)
->get();
$group = new Group();
@@ -51,18 +74,18 @@ class RecoverGroupTransactionTableSeeder extends Seeder
$tax = 0;
$service_charge = 0;
foreach ($transaction as $key_2 => $row_2) {
$group->transactions()->sync($row_2->id, false);
$issuer = $row_2->issuer;
$date = $row_2->created_at;
$receiver = $row_2->receiver;
$amount += $row_2->amount;
$original_amount += $row_2->original_amount;
$currency_id = $row_2->currency_id;
$original_currency_id = $row_2->original_currency_id;
$currency_rate = $row_2->currency_rate;
$tax += $row_2->tax;
$service_charge += $row_2->service_charge;
foreach ($transactions as $transaction) {
$group->transactions()->sync($transaction->id, false);
$issuer = $transaction->issuer;
$date = $transaction->created_at;
$receiver = $transaction->receiver;
$amount += $transaction->amount;
$original_amount += $transaction->original_amount;
$currency_id = $transaction->currency_id;
$original_currency_id = $transaction->original_currency_id;
$currency_rate = $transaction->currency_rate;
$tax += $transaction->tax;
$service_charge += $transaction->service_charge;
}
$group->issuer = $issuer;
@@ -75,8 +98,23 @@ class RecoverGroupTransactionTableSeeder extends Seeder
$group->tax = $tax;
$group->service_charge = $service_charge;
$group->created_at = $date;
$group->updated_at = $date;
$group->update();
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $group->transactions, 'transferFeeTransactions' => $group->transferFees, 'supplier' => $group->issuerCompany]);
$object = new DocumentObject(
DocumentType::CURRENCY_VENDOR_ORDER,
[chunk_split('data:application/pdf;base64,'.base64_encode($pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'currency_vendor_order'
);
/** @var Document $document */
$document = $this->createsDocument->execute($group, $object);
$this->createsFile->execute($document, $object);
}
DB::commit();
@@ -17,28 +17,58 @@
{{item.currency_rate}}
</div>
</div>
<div class="col-auto">
<div class="font-heading fs-10 muted all-caps">Currency Amount</div>
<div class="font-heading fs-10">
{{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
</div>
</div>
<div class="col text-right">
<div class="font-heading fs-10 muted all-caps">Amount</div>
<div class="font-heading fs-14 text-success bold">
{{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
{{item.currency.short_code}} {{((Math.round(( item.amount + Number.EPSILON) * 100) / 100)).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="col-auto">
<div class="font-heading fs-10 muted all-caps">reference</div>
<span class="font-heading fs-10" v-for="transaction in item.transactions">
<a :href="route('booking.details', transaction.booking.marking)">{{transaction.booking.marking}}&nbsp;</a>
</span>
<document-file-viewer-component v-if="item.documents.currency_order" :file="item.documents.currency_order.files[0]">
<template slot="button">
<button class="btn btn-xs btn-default bg-master-lightest b-rad-none no-border">
<i class="fa fa-eye"></i>
</button>
</template>
</document-file-viewer-component>
<!--<span class="font-heading fs-10" v-for="transaction in item.transactions">-->
<!--<a :href="route('booking.details', transaction.booking.marking)">{{transaction.booking.marking}}&nbsp;</a>-->
<!--</span>-->
</div>
<div class="col">
<div class="font-heading fs-10 muted all-caps">PO Completion</div>
<document-file-viewer-component v-if="item.documents.purchase_order" :file="item.documents.purchase_order.files[0]">
<template slot="button">
<button class="btn btn-xs btn-default bg-master-lightest b-rad-none no-border">
<i class="fa fa-file-pdf-o"></i>
</button>
</template>
</document-file-viewer-component>
<p class="font-heading fs-12 bold text-success"><span :class="[{'text-danger': item.complete_transactions !== item.transactions}]">{{item.complete_transactions}}</span>/{{item.transactions}}</p>
<!--<span class="font-heading fs-10" v-for="transaction in item.transactions">-->
<!--<a :href="route('booking.details', transaction.booking.marking)">{{transaction.booking.marking}}&nbsp;</a>-->
<!--</span>-->
</div>
<div class="col-auto">
<div class="row parentContainer">
<div class="col p-l-0">
<button class="btn btn-xs btn-complete b-rad-none">
<i class="fa fa-refresh text-white" @click="updateDo()"></i>
</button>
<button class="btn btn-xs btn-default bg-warning b-rad-none no-border requestModal" data-type="editTransactionGroup">
<i class="fa fa-pencil text-white"></i>
</button>
<modal-component small type="editTransactionGroup">
<edit-transaction-group-form-component :section="section" :currency_rate="item.currency_rate" :supplier_id ="data.transactions[0].issuer_id" :id="item.id"></edit-transaction-group-form-component>
<edit-transaction-group-form-component :section="section" :currency_rate="item.currency_rate" :supplier_id ="data.issuer_id" :id="item.id"></edit-transaction-group-form-component>
</modal-component>
<button class="btn btn-xs btn-default bg-danger b-rad-none no-border requestModal" data-type="deleteTransactionGroup">
<i class="fa fa-times text-white"></i>
@@ -91,7 +121,12 @@
deleteGroupTransaction() {
this.isLoading = true;
this.submit(this.route('api.transaction.group.delete', this.item.id), 'delete', this.section, true, true);
},
updateDo() {
this.isLoading = true;
this.submit(this.route('api.transaction.group.bulk.po'), 'post', this.section, true, true);
}
},
mixins: [componentHandler, staticFormHandler]
}
@@ -1,7 +1,6 @@
<template>
<div class="row parentContainer">
<div class="col">
<new-service-announcement-component :data="data"></new-service-announcement-component>
<div class="row">
<div class="col">
<div class="row m-l-0 m-r-0 m-b-20" v-if="!data.services.length">
@@ -13,7 +13,7 @@
</div>
</div>
</div>
<div class="row parentContainer" v-if="item.status !== 2">
<div class="row parentContainer" v-if="item.status !== 2 && item.status !== 0">
<div class="col">
<div class="row no-margin">
<div class="col" :class="[{'bg-danger-lighter': item.status !== 1}, {'bg-master-lighter': item.status === 1}]">
@@ -203,6 +203,7 @@
<div class="col-12 col-lg-3">
<wallet-component :data="company"></wallet-component>
<verification-warning-component v-if="!isLoading" :data="company"></verification-warning-component>
<new-service-announcement-component :data="company"></new-service-announcement-component>
</div>
</div>
</div>
@@ -1,5 +1,5 @@
<template>
<div class="row parentContainer">
<div class="row parentContainer" v-if="item.status === 2">
<div class="col">
<div class="row m-b-20 parentContainer" v-if="data.id === 9">
<div class="col-auto">
+9 -4
View File
@@ -32,23 +32,28 @@
</div>
<div class="row">
<div class="col">
<list-component key="2" section="currencyOrdersListSection" :options="{'per_page': 20, 'document_type_in': ['CURRENCY_VENDOR_ORDER'], 'status': 2, 'with_company': true}" :endpoint="route('api.document.list')">
<list-component key="2" section="completeTransactionGroupsListSection" :options="{'per_page': 20, 'status': 3}" :endpoint="route('api.transaction.group.list')">
<template slot="list" slot-scope="{data}">
<currency-order-component section="currencyOrdersListSection" :data="data"></currency-order-component>
<transaction-group-component section="transactionGroupsListSection" :data="data"></transaction-group-component>
</template>
</list-component>
{{--<list-component key="2" section="currencyOrdersListSection" :options="{'per_page': 20, 'document_type_in': ['CURRENCY_VENDOR_ORDER'], 'status': 2, 'with_company': true}" :endpoint="route('api.document.list')">--}}
{{--<template slot="list" slot-scope="{data}">--}}
{{--<currency-order-component section="currencyOrdersListSection" :data="data"></currency-order-component>--}}
{{--</template>--}}
{{--</list-component>--}}
</div>
</div>
</div>
<div class="col-12 col-md-4">
<div class="row m-b-15 p-b-10 b-b b-grey">
<div class="col">
<small class="all-caps muted fs-10">Transaction Groups</small>
<small class="all-caps muted fs-10">Open Currency Orders</small>
</div>
</div>
<div class="row">
<div class="col">
<list-component key="2" section="transactionGroupsListSection" :options="{'per_page': 5}" :endpoint="route('api.transaction.group.list')">
<list-component key="2" section="transactionGroupsListSection" :options="{'per_page': 20, 'status_in': [0, 1, 2]}" :endpoint="route('api.transaction.group.list')">
<template slot="list" slot-scope="{data}">
<transaction-group-component section="transactionGroupsListSection" :data="data"></transaction-group-component>
</template>
@@ -25,38 +25,16 @@
<tr>
<td width="50%" class="top">
<span class="buyer-seller-title">
Buyer
Seller
</span>
<br>
<div class="buyer-company">
Marking#: {{ $group->transactions[0]->owner()->first()->owner()->first()->marking }}
</div>
<span class="buyer-company">
{{ $supplier->name }}
</span>
<span class="reg">
{{-- {{ $supplier }} --}}
</span>
<br>
<span class="address">
@php
$addresses = $supplier->addresses()->where('billing', '=', true)->first();
@endphp
{{ $addresses->street_one }}
{{ $addresses->street_two }}
{{ $addresses->state()->first()->name }}
{{ $addresses->district()->first()->name }}
</span>
<br>
<span class="contact-no">
Phone: {{ $supplier->contacts()->first()->phone }}
</span>
</td>
<td width="50%" class="top">
<span class="buyer-seller-title">
Seller
Buyer
</span>
<br>
<span class="buyer-company">
@@ -91,34 +69,21 @@
@endphp
@foreach($group->transactions as $po_order_transaction)
@foreach ($po_order_transaction->owner()->first()->transactionDetails as $key => $transaction_detail)
@foreach ($po_order_transaction->owner->owner->transactions()->where('type', \App\Classes\ValueObjects\Constants\TransactionType::PURCHASE_ORDER)->where('status', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->first()->transactionDetails as $key => $transaction_detail)
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
<td class="stock-code top" width="10%">{{ $transaction_detail->product_code }}</td>
<td class="description">{{ $transaction_detail->product_name }}</td>
<td width="10%" class="center top">{{ $transaction_detail->quantity }}</td>
<td width="15%" class="center top">
@if($po_order_transaction->owner()->first()->booking()->first()->fix_currency_id !== 1)
{{ number_format( (1/$group->currency_rate) * $transaction_detail->price, 2) }}
@else
{{ number_format($transaction_detail->price, 2) }}
@endif
{{ number_format( (1/$group->currency_rate) * $transaction_detail->price, 2) }}
</td>
<td width="20%" class="right top">
@if($po_order_transaction->owner()->first()->booking()->first()->fix_currency_id !== 1)
{{ number_format((float)number_format( (1/$group->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }}
@php
$subtotal += number_format((float)number_format( (1/$group->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.','');
@endphp
@else
{{ number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }}
{{ number_format((float)number_format( (1/$group->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }}
@php
$subtotal += number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.','');
@endphp
@endif
@php
$subtotal += number_format((float)number_format( (1/$group->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.','');
@endphp
</td>
</tr>
@endforeach
@@ -143,11 +108,7 @@
<td colspan="4"></td>
<td class="right">Adjustment</td>
<td class="right">
@if($group->transactions[0]->owner()->first()->owner()->first()->fix_currency_id !== 1)
{{ number_format((float)number_format( (1/$group->currency_rate) * $group->amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }}
@else
{{ number_format((float)number_format($group->amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }}
@endif
{{ number_format((float)number_format( (1/$group->currency_rate) * $group->original_amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }}
</td>
</tr>
@if($group->tax > 0)
@@ -161,11 +122,7 @@
<td colspan="4"></td>
<td class="right middle">Total</td>
<td class="total right middle">
@if($group->transactions[0]->owner()->first()->owner()->first()->fix_currency_id !== 1)
{{ number_format( ((1/$group->currency_rate) * $group->amount) + $group->service_charge + $group->tax, 2) }}
@else
{{ number_format($group->amount + $group->service_charge + $group->tax, 2) }}
@endif
{{ number_format( ((1/$group->currency_rate) * $group->original_amount) + $group->service_charge + $group->tax, 2) }}
</td>
</tr>
</tfoot>
+1 -1
View File
@@ -29,6 +29,6 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
Route::get('/list', 'ListGroupsController@list')->name('list');
Route::delete('/{id}/delete', 'DeleteGroupController@delete')->name('delete');
Route::put('/{id}/update', 'UpdateGroupController@update')->name('update');
Route::get('/{id}/bulk/po', 'CreateBulkPurchaseOrderDocumentController@create')->name('bulk.po');
Route::post('bulk/po', 'CreateBulkPurchaseOrderDocumentController@create')->name('bulk.po');
});
});