mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-25 23:43:58 +00:00
Merge branch 'master' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into refund-booking
This commit is contained in:
@@ -16,6 +16,8 @@ class CreatedAfterOrEqual implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('created_at', '>=', Carbon::parse($value));
|
||||
$table = $builder->getModel()->getTable();
|
||||
$startDate = Carbon::createFromFormat('d-m-Y', $value)->startOfDay();
|
||||
return $builder->where("{$table}.created_at", '>=', $startDate);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ class CreatedBeforeOrEqual implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('created_at', '<=', Carbon::parse($value));
|
||||
$table = $builder->getModel()->getTable();
|
||||
$endDate = Carbon::createFromFormat('d-m-Y', $value)->endOfDay();
|
||||
return $builder->where("{$table}.created_at", '<=', $endDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class GroupByImportedDate implements Filter
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->groupby('imported_date');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ImportedDateFrom implements Filter
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereDate('imported_date', '>=', date('Y-m-d',strtotime($value)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ImportedDateTo implements Filter
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereDate('imported_date', '<=', date('Y-m-d',strtotime($value)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class IsMappedFalseOrMappedButStatusIn implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where(function($q) use ($value) {
|
||||
$q->whereDoesntHave('owners');
|
||||
$q->orwhereDoesntHave('owner_status');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,8 @@ class OwnerId implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('owner_id', $value);
|
||||
$table = $builder->getModel()->getTable();
|
||||
return $builder->where("{$table}.owner_id", $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,8 @@ class OwnerType implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('owner_type', $value);
|
||||
$table = $builder->getModel()->getTable();
|
||||
return $builder->where("{$table}.owner_type", $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatementTransactionInvoiceReference implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereHas('owners', function ($query) use ($value) {
|
||||
return $query->where('Invoice_reference', $value);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatementTransactionOwnerInvoiceOrReceiptRefNotNull implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereHas('owners', function ($query) {
|
||||
return $query->where(function ($q) {
|
||||
$q->orWhereNotNull('invoice_reference')->orWhereNotNull('receipt_reference');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatementTransactionOwnerReference implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereHas('owners', function ($query) use ($value) {
|
||||
return $query->where('owner_reference', $value);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatementTransactionPostingEnd implements Filter
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereDate('posting_date', '<=', date('Y-m-d',strtotime($value)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatementTransactionPostingStart implements Filter
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereDate('posting_date', '>=', date('Y-m-d',strtotime($value)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatementTransactionReceiptReference implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereHas('owners', function ($query) use ($value) {
|
||||
return $query->where('receipt_reference', $value);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,8 @@ class StatusIn implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereIn('status', $value);
|
||||
$table = $builder->getModel()->getTable();
|
||||
return $builder->whereIn("{$table}.status", $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class WhereHasOwnersAndNotNull implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereHas('owners', function ($query) use ($value) {
|
||||
return $query->whereNotNull($value);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class WhereHasOwnersAndNull implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereHas('owners', function ($query) use ($value) {
|
||||
return $query->whereNull($value);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class WithBookingMarkingLike implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->join('transactions as t2', 't2.payment_reference', '=', 'transactions.bill_no')
|
||||
->join('bookings', function ($join) use ($value) {
|
||||
$join->on('bookings.id', '=', 't2.owner_id')
|
||||
->where('bookings.marking', 'LIKE', '%'.$value.'%');
|
||||
})
|
||||
->addSelect(['transactions.*','t2.owner_id as bookingId', 'bookings.marking as bookingMarking']);
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,15 @@ class CreateBankStatementTransactionOwners implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
private $transactions;
|
||||
|
||||
public function __construct($transactions) {
|
||||
$this->transactions = $transactions;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
(App()->make(CreateBankStatementTransactionOwnersProcessor::class))->execute();
|
||||
(App()->make(CreateBankStatementTransactionOwnersProcessor::class))->execute($this->transactions);
|
||||
}
|
||||
|
||||
public function delay($delay)
|
||||
|
||||
+52
-60
@@ -135,7 +135,7 @@ class ApproveDuplicateBankStatementDetailsStatusLogic extends AbstractController
|
||||
public function logic(Request $request): JsonResponse
|
||||
{
|
||||
// Determine the approval status
|
||||
$status = $this->getApprovalStatus($request);
|
||||
$status = $this->getConstantStatus($request->route('status'));
|
||||
|
||||
// Find the statement transaction owner
|
||||
$owner = $this->getOwner($request);
|
||||
@@ -143,21 +143,33 @@ class ApproveDuplicateBankStatementDetailsStatusLogic extends AbstractController
|
||||
// Update owner status
|
||||
$this->updateOwnerStatus($owner, $status);
|
||||
|
||||
// If the status is 'approved', handle the approval process
|
||||
if ($status === ApprovalStatus::APPROVED) {
|
||||
$this->handleApprovedStatus($owner);
|
||||
}
|
||||
// handle the siblings process
|
||||
$this->handleSiblingsStatus($owner, $this->getSiblingsStatus($status));
|
||||
|
||||
// Check and approve remaining matches if any
|
||||
$this->checkAndApproveRemainingMatches($owner);
|
||||
$this->checkAndApproveRemainingMatches($owner, $status);
|
||||
|
||||
// Return an empty response
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
private function getApprovalStatus(Request $request): int
|
||||
private function getConstantStatus(String $statusName=null): int
|
||||
{
|
||||
return $request->route('status') == 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED;
|
||||
switch ($statusName) {
|
||||
case 'approve':
|
||||
return ApprovalStatus::APPROVED;
|
||||
|
||||
case 'pending_verification':
|
||||
return ApprovalStatus::PENDING_VERIFICATION;
|
||||
|
||||
default:
|
||||
return ApprovalStatus::REJECTED;
|
||||
}
|
||||
}
|
||||
|
||||
private function getSiblingsStatus(int $status): int
|
||||
{
|
||||
return $status == ApprovalStatus::APPROVED ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION;
|
||||
}
|
||||
|
||||
private function getOwner(Request $request): StatementTransactionOwner
|
||||
@@ -170,23 +182,24 @@ class ApproveDuplicateBankStatementDetailsStatusLogic extends AbstractController
|
||||
$this->updatesBankStatementTransactionOwnerStatus->execute($owner, $status);
|
||||
}
|
||||
|
||||
private function handleApprovedStatus(StatementTransactionOwner $owner): void
|
||||
private function handleSiblingsStatus(StatementTransactionOwner $owner, int $siblingStatus): void
|
||||
{
|
||||
// Reject all other owners with the same system, owner type, and owner ID
|
||||
$this->rejectOtherOwners($owner);
|
||||
// update all other owners with the same system, owner type, and owner ID
|
||||
$this->updateOtherOwners($owner, $siblingStatus);
|
||||
|
||||
// Find all siblings and process them
|
||||
$siblings = $this->getSiblings($owner);
|
||||
$this->processSiblings($siblings);
|
||||
|
||||
foreach ($siblings as $sibling) {
|
||||
$this->processSibling($sibling, $siblingStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private function rejectOtherOwners(StatementTransactionOwner $owner): void
|
||||
private function updateOtherOwners(StatementTransactionOwner $owner, int $status): void
|
||||
{
|
||||
StatementTransactionOwner::where('system', $owner->system)
|
||||
->where('owner_type', $owner->owner_type)
|
||||
->where('owner_id', $owner->owner_id)
|
||||
StatementTransactionOwner::getSiblingsOwner()
|
||||
->where('id', '!=', $owner->id)
|
||||
->update(['status' => ApprovalStatus::REJECTED]);
|
||||
->update(['status' => $status]);
|
||||
}
|
||||
|
||||
private function getSiblings(StatementTransactionOwner $owner): Collection
|
||||
@@ -196,86 +209,65 @@ class ApproveDuplicateBankStatementDetailsStatusLogic extends AbstractController
|
||||
->get();
|
||||
}
|
||||
|
||||
private function processSiblings(Collection $siblings): void
|
||||
{
|
||||
foreach ($siblings as $sibling) {
|
||||
$this->processSibling($sibling);
|
||||
}
|
||||
}
|
||||
|
||||
private function processSibling(StatementTransactionOwner $sibling): void
|
||||
private function processSibling(StatementTransactionOwner $sibling, int $siblingStatus): void
|
||||
{
|
||||
// Reject the sibling and save the changes
|
||||
$sibling->status = ApprovalStatus::REJECTED;
|
||||
$sibling->status = $siblingStatus;
|
||||
$sibling->save();
|
||||
|
||||
|
||||
// Find all twins and process them
|
||||
$twins = $this->getTwins($sibling);
|
||||
$this->processTwins($twins);
|
||||
}
|
||||
|
||||
private function getTwins(StatementTransactionOwner $sibling): Collection
|
||||
{
|
||||
return StatementTransactionOwner::where('system', $sibling->system)
|
||||
->where('owner_type', $sibling->owner_type)
|
||||
->where('owner_id', $sibling->owner_id)
|
||||
->where('id', '!=', $sibling->id)
|
||||
->get();
|
||||
}
|
||||
|
||||
private function processTwins(Collection $twins): void
|
||||
{
|
||||
foreach ($twins as $twin) {
|
||||
$this->processTwin($twin);
|
||||
}
|
||||
}
|
||||
|
||||
private function getTwins(StatementTransactionOwner $sibling): Collection
|
||||
{
|
||||
return StatementTransactionOwner::getSiblingsOwner()
|
||||
->where('id', '!=', $sibling->id)
|
||||
->get();
|
||||
}
|
||||
|
||||
private function processTwin(StatementTransactionOwner $twin): void
|
||||
{
|
||||
// Find all owners with the same statement transaction ID as the twin
|
||||
$owners = $this->getOwners($twin);
|
||||
$owners = $this->getSiblings($twin);
|
||||
|
||||
// If there is only one owner (the twin itself), approve it
|
||||
if ($owners->count() === 1) {
|
||||
$this->updateOwnerStatus($twin, ApprovalStatus::APPROVED);
|
||||
$this->updateOwnerStatus($twin, $this->getConstantStatus(request()->route('status')));
|
||||
}
|
||||
}
|
||||
|
||||
private function getOwners(StatementTransactionOwner $transactionOwner): Collection
|
||||
{
|
||||
return StatementTransactionOwner::where('statement_transaction_id', $transactionOwner->statement_transaction_id)
|
||||
->where('id', '!=', $transactionOwner->id)
|
||||
->get();
|
||||
}
|
||||
|
||||
private function checkAndApproveRemainingMatches(StatementTransactionOwner $owner): void
|
||||
private function checkAndApproveRemainingMatches(StatementTransactionOwner $owner, int $status): void
|
||||
{
|
||||
// Find all remaining matching owners for the related transaction
|
||||
$remainingMatches = $this->getRemainingMatches($owner);
|
||||
$checkStatus = ($status == ApprovalStatus::APPROVED ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::APPROVED);
|
||||
$remainingMatches = $this->getRemainingMatches($owner, $checkStatus);
|
||||
|
||||
// Process each remaining match
|
||||
foreach ($remainingMatches as $match) {
|
||||
$this->processRemainingMatch($match);
|
||||
$this->processRemainingMatch($match, $status);
|
||||
}
|
||||
}
|
||||
|
||||
private function getRemainingMatches(StatementTransactionOwner $owner): Collection
|
||||
private function getRemainingMatches(StatementTransactionOwner $owner, int $checkStatus): Collection
|
||||
{
|
||||
return StatementTransactionOwner::where('system', $owner->system)
|
||||
->where('owner_type', $owner->owner_type)
|
||||
->where('owner_id', $owner->owner_id)
|
||||
->where('status', ApprovalStatus::PENDING_VERIFICATION)
|
||||
return StatementTransactionOwner::getSiblingsOwner()
|
||||
->where('status', $checkStatus)
|
||||
->get();
|
||||
}
|
||||
|
||||
private function processRemainingMatch(StatementTransactionOwner $match): void
|
||||
private function processRemainingMatch(StatementTransactionOwner $match, int $status): void
|
||||
{
|
||||
// Find all owners with the same statement transaction ID as the match
|
||||
$owners = $this->getOwners($match);
|
||||
$owners = $this->getSiblings($match);
|
||||
|
||||
// If there is only one owner (the match itself), approve it
|
||||
if ($owners->count() === 1) {
|
||||
$this->updateOwnerStatus($match, ApprovalStatus::APPROVED);
|
||||
$this->updateOwnerStatus($match, $status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-8
@@ -57,17 +57,12 @@ class GroupApproveStatementTransactionLogic extends AbstractControllerLogic
|
||||
public function logic(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
$filters = [
|
||||
"min_amount" => 0,
|
||||
"is_mapped" => true,
|
||||
"is_mapped_with_multiple" => false,
|
||||
"statement_transaction_owner_type_in" => [1, 2],
|
||||
"statement_transaction_owner_status_in" => [1]
|
||||
];
|
||||
$filters = $request->except(['per_page','order_by']);
|
||||
|
||||
$statementTransactions = $this->listsBankStatementTransactions->execute($filters);
|
||||
|
||||
foreach ($statementTransactions as $statementTransaction) {
|
||||
$owners = $statementTransaction->owners;
|
||||
$owners = $statementTransaction->owners()->where('status', ApprovalStatus::PENDING_VERIFICATION)->get();
|
||||
|
||||
if (count($owners)) {
|
||||
$this->updatesBankStatementTransactionOwnerStatus->execute($owners->first(), ApprovalStatus::APPROVED);
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounting\ControllersLogic;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Http\Resources\TransactionMappingLogResource;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounting\Services\ListTransactionMappingLogs;
|
||||
|
||||
|
||||
class HistoryImportedTransactionMappedControllerLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Retrieved History Imported Invoices',
|
||||
'message' => 'You have successfully retrieved history imported invoices'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var ListTransactionMappingLogs */
|
||||
private $listTransactionMappingLogs;
|
||||
|
||||
/**
|
||||
* UpdateAnnouncementLogic constructor.
|
||||
* @param ListTransactionMappingLogs $listTransactionMappingLogs
|
||||
*/
|
||||
public function __construct(
|
||||
ListTransactionMappingLogs $listTransactionMappingLogs
|
||||
) {
|
||||
$this->listTransactionMappingLogs = $listTransactionMappingLogs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function logic(Request $request): JsonResponse
|
||||
{
|
||||
$query = $this->listTransactionMappingLogs->execute($this->listTransactionMappingLogs->deserializeFilters($request->input('filters')));
|
||||
|
||||
return $this->collectionResponse(TransactionMappingLogResource::collection($query));
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,9 @@ use App\Models\Wallet;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Accounting\Services\UpdatesBankStatementTransactionOwnerStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\StatementTransactionOwner;
|
||||
|
||||
class UpdateBankStatementDetailLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -40,14 +43,21 @@ class UpdateBankStatementDetailLogic extends AbstractControllerLogic
|
||||
/** @var ChecksBillNumber */
|
||||
private $checksBillNumber;
|
||||
|
||||
/** @var UpdatesBankStatementTransactionOwnerStatus */
|
||||
private $updatesBankStatementTransactionOwnerStatus;
|
||||
|
||||
/**
|
||||
* @param FetchesBankStatementTransaction $fetchesBankStatementTransaction
|
||||
* @param ChecksBillNumber $checksBillNumber
|
||||
*/
|
||||
public function __construct(FetchesBankStatementTransaction $fetchesBankStatementTransaction, ChecksBillNumber $checksBillNumber)
|
||||
public function __construct(
|
||||
FetchesBankStatementTransaction $fetchesBankStatementTransaction,
|
||||
ChecksBillNumber $checksBillNumber,
|
||||
UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus)
|
||||
{
|
||||
$this->fetchesBankStatementTransaction = $fetchesBankStatementTransaction;
|
||||
$this->checksBillNumber = $checksBillNumber;
|
||||
$this->updatesBankStatementTransactionOwnerStatus = $updatesBankStatementTransactionOwnerStatus;
|
||||
}
|
||||
|
||||
public function logic(Request $request): JsonResponse
|
||||
@@ -129,7 +139,10 @@ class UpdateBankStatementDetailLogic extends AbstractControllerLogic
|
||||
|
||||
$system = $systemReference != null ? SystemType::SYSTEM_NAMES[$systemReference] : '';
|
||||
|
||||
$this->createBankStatementTransactionOwner($bankStatementTransaction, $statementTransactionOwnerType, $system, $owner_type, $owner_id, $owner_reference);
|
||||
$statementTransactionOwner = $this->createBankStatementTransactionOwner($bankStatementTransaction, $statementTransactionOwnerType, $system, $owner_type, $owner_id, $owner_reference);
|
||||
|
||||
// this for edit a transaction already mapped
|
||||
if ($request->has('editMapped')) $this->editAccountMapped($statementTransactionOwner);
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
@@ -144,9 +157,26 @@ class UpdateBankStatementDetailLogic extends AbstractControllerLogic
|
||||
'owner_reference' => $owner_reference,
|
||||
];
|
||||
|
||||
$bankStatementTransaction->owners()->firstOrCreate($ownerData);
|
||||
|
||||
return $bankStatementTransaction->owners()->where('status','<>',ApprovalStatus::REJECTED)->firstOrCreate($ownerData);
|
||||
}
|
||||
|
||||
private function editAccountMapped(StatementTransactionOwner $owner){
|
||||
$this->updateOwnerStatus($owner, ApprovalStatus::APPROVED);
|
||||
|
||||
// update all other owners with the same system, owner type, and owner ID
|
||||
$this->updateOtherOwners($owner, ApprovalStatus::REJECTED);
|
||||
}
|
||||
|
||||
private function updateOwnerStatus(StatementTransactionOwner $owner, int $status)
|
||||
{
|
||||
$this->updatesBankStatementTransactionOwnerStatus->execute($owner, $status);
|
||||
}
|
||||
|
||||
private function updateOtherOwners(StatementTransactionOwner $owner, int $status): void
|
||||
{
|
||||
StatementTransactionOwner::where('statement_transaction_id', $owner->statement_transaction_id)
|
||||
->where('id', '!=', $owner->id)
|
||||
->update(['status' => $status]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
-34
@@ -2,16 +2,14 @@
|
||||
|
||||
namespace App\Classes\Modules\Accounting\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounting\Services\FetchesBankStatementTransaction;
|
||||
use App\Http\Resources\BankStatementTransactionResource;
|
||||
use App\Classes\Modules\Accounting\Services\UpdatesBankStatementTransactionOwnerStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Http\Resources\BankStatementTransactionOwnerResource;
|
||||
use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType;
|
||||
use App\Classes\Modules\Accounting\Services\FetchesBankStatementTransactionOwner;
|
||||
use App\Classes\Modules\Accounting\Services\UpdatesBankStatementTransactionOwnerStatus;
|
||||
|
||||
class UpdateStatementTransactionStatusLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -27,29 +25,23 @@ class UpdateStatementTransactionStatusLogic extends AbstractControllerLogic
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesBankStatementTransaction */
|
||||
private $fetchesBankStatementTransaction;
|
||||
/** @var FetchesBankStatementTransactionOwner */
|
||||
private $fetchesBankStatementTransactionOwner;
|
||||
|
||||
/** @var UpdatesBankStatementTransactionOwnerStatus */
|
||||
private $updatesBankStatementTransactionOwnerStatus;
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/**
|
||||
* UpdateAnnouncementLogic constructor.
|
||||
* @param FetchesBankStatementTransaction $fetchesBankStatementTransaction
|
||||
* @param FetchesBankStatementTransactionOwner $fetchesBankStatementTransactionOwner
|
||||
* @param UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
*/
|
||||
public function __construct(
|
||||
FetchesBankStatementTransaction $fetchesBankStatementTransaction,
|
||||
UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus,
|
||||
UpdatesTransactionStatus $updatesTransactionStatus
|
||||
FetchesBankStatementTransactionOwner $fetchesBankStatementTransactionOwner,
|
||||
UpdatesBankStatementTransactionOwnerStatus $updatesBankStatementTransactionOwnerStatus
|
||||
) {
|
||||
$this->fetchesBankStatementTransaction = $fetchesBankStatementTransaction;
|
||||
$this->fetchesBankStatementTransactionOwner = $fetchesBankStatementTransactionOwner;
|
||||
$this->updatesBankStatementTransactionOwnerStatus = $updatesBankStatementTransactionOwnerStatus;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,21 +53,10 @@ class UpdateStatementTransactionStatusLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request): JsonResponse
|
||||
{
|
||||
$statementTrasaction = $this->fetchesBankStatementTransaction->execute(['id' => $request->route('id')]);
|
||||
|
||||
$statementTrasactionOwner = $statementTrasaction->owners->first();
|
||||
$statementTrasactionOwner = $this->fetchesBankStatementTransactionOwner->execute(['id' => $request->route('id')]);
|
||||
|
||||
$this->updatesBankStatementTransactionOwnerStatus->execute($statementTrasactionOwner, $request->route('status') == 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED);
|
||||
|
||||
// todo-new: approve payments status, need to check the owner(if system is shipping, need to api with shipping portal)
|
||||
// if ($request->route('status') == 'approve') {
|
||||
// if ($statementTrasactionOwner->transaction->type === StatementTransactionOwnerType::SALES) {
|
||||
// if ($statementTrasactionOwner->owner->status === ApprovalStatus::PENDING_VERIFICATION) {
|
||||
// $this->updatesTransactionStatus->execute($statementTrasactionOwner->owner, ApprovalStatus::APPROVED);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return $this->resourceResponse(new BankStatementTransactionResource($statementTrasaction));
|
||||
return $this->resourceResponse(new BankStatementTransactionOwnerResource($statementTrasactionOwner));
|
||||
}
|
||||
}
|
||||
|
||||
+30
-25
@@ -23,15 +23,12 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function execute() {
|
||||
|
||||
$transactions = StatementTransaction::whereDoesntHave('owners', function($query){
|
||||
return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})->orderBy('posting_date')->get();
|
||||
public function execute($transactions) {
|
||||
|
||||
// $transactions = StatementTransaction::whereDoesntHave('owners')->where('amount', '<', 0)->get();
|
||||
|
||||
foreach ($transactions as $transaction) {
|
||||
$mapped = false;
|
||||
$keywords = array_filter(explode(" ", $transaction->transaction_description . " " . $transaction->transaction_description_2));
|
||||
|
||||
if($transaction->amount > 0){
|
||||
@@ -40,7 +37,7 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::PAYMENT, Booking::class, PaymentMethodType::WALLET, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
|
||||
foreach ($creditTransactions as $creditTransaction) {
|
||||
$isArray = is_array($creditTransaction);
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::SALES,
|
||||
'system' => 'EXCHANGE',
|
||||
'owner_type' => Transaction::class,
|
||||
@@ -49,12 +46,11 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
// Shipping Portal Sales
|
||||
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 2, PaymentMethodType::WALLET);
|
||||
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), [2], PaymentMethodType::WALLET);
|
||||
foreach ($creditTransactions as $creditTransaction) {
|
||||
if($creditTransaction['owner_type'] === Wallet::class) continue;
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::SALES,
|
||||
'system' => 'SHIPPING_PORTAL',
|
||||
'owner_type' => $creditTransaction['owner_type'],
|
||||
@@ -67,7 +63,7 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
$creditTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::TOP_UP, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
|
||||
foreach ($creditTransactions as $creditTransaction) {
|
||||
$isArray = is_array($creditTransaction);
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
|
||||
'system' => 'EXCHANGE',
|
||||
'owner_type' => Transaction::class,
|
||||
@@ -76,9 +72,9 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
]);
|
||||
}
|
||||
|
||||
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), 5, null);
|
||||
$creditTransactions = $this->getTransactionsFromShippingPortal($transaction->amount, $this->getDateRange($transaction->posting_date, 1), [5,15], null);
|
||||
foreach ($creditTransactions as $creditTransaction) {
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::WALLET_TOP_UP,
|
||||
'system' => 'SHIPPING_PORTAL',
|
||||
'owner_type' => $creditTransaction['owner_type'],
|
||||
@@ -89,7 +85,7 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
|
||||
// fpx charge refund
|
||||
if($transaction->transaction_description === 'DUITNOW S/CHRG REFUND'){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::FPX_CHARGE_REFUND
|
||||
]);
|
||||
}
|
||||
@@ -98,7 +94,7 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
|
||||
// INTERNAL_BANK_TRANSFER_IN
|
||||
if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE')){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_IN
|
||||
]);
|
||||
}
|
||||
@@ -123,7 +119,7 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
->where('amount', '<=', (($transaction->amount * -1) + 0.01))->whereDate('created_at', '>=', $paymentDateStart)->whereDate('created_at', '<=', $paymentDateEnd)->get();
|
||||
|
||||
foreach ($debitTransactions as $debitTransaction) {
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::SUPPLIER_PAYMENT,
|
||||
'system' => 'EXCHANGE',
|
||||
'owner_type' => Group::class,
|
||||
@@ -139,7 +135,7 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
$debitTransactions = $this->getTransactions($transaction->posting_date, $transaction->amount, TransactionType::DEBIT_NOTE, Wallet::class, null, [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED], $keywords);
|
||||
foreach ($debitTransactions as $debitTransaction) {
|
||||
$isArray = is_array($creditTransaction);
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::WALLET_WITHDRAWAL,
|
||||
'system' => 'EXCHANGE',
|
||||
'owner_type' => Transaction::class,
|
||||
@@ -152,50 +148,52 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
|
||||
// STATUTORY
|
||||
if(str_contains($transaction->transaction_description_2, 'PEMBANGUNAN SUMBER') || str_contains($transaction->transaction_description_2, 'HASIL') || str_contains($transaction->transaction_description_2, 'PERTUBUHAN KESELAMAT') || str_contains($transaction->transaction_description_2, 'KUMPULAN WANG SIMPAN')){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::STATUTORY
|
||||
]);
|
||||
}
|
||||
|
||||
// FPX_CHARGE
|
||||
if($transaction->transaction_description === 'DR DUITNOW S/CHRG' || str_contains($transaction->transaction_description, 'Manual FPX') || str_contains($transaction->transaction_description, 'CMS - DR FPX CHG')){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::FPX_CHARGE
|
||||
]);
|
||||
}
|
||||
|
||||
// BANK_CHARGE
|
||||
if($transaction->transaction_description === 'CMS - DR CORP CHG' || $transaction->transaction_description === 'MONTHLY PROFIT DEBIT'){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::BANK_CHARGE
|
||||
]);
|
||||
}
|
||||
|
||||
// CREDIT_CARD_PAYMENT
|
||||
if(str_contains($transaction->transaction_description_2, 'VISA CARD')){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::CREDIT_CARD_PAYMENT
|
||||
]);
|
||||
}
|
||||
|
||||
// INTERNAL_BANK_TRANSFER_OUT
|
||||
if(str_contains($transaction->transaction_description_2, 'CIEF WORLDWIDE') || str_contains($transaction->transaction_description_2, 'CIEF WORLWIDE') || str_contains($transaction->transaction_description_2, 'IZYIM GLOBAL')){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::INTERNAL_BANK_TRANSFER_OUT
|
||||
]);
|
||||
}
|
||||
|
||||
// non-operational charges
|
||||
if(str_contains($transaction->transaction_description_2, 'HIRE PURCHASE') || str_contains($transaction->transaction_description_2, 'TENAGA NASIONAL') || str_contains($transaction->transaction_description, 'CABLE CHARGE') || str_contains($transaction->transaction_description_2, 'CTOS DATA SYSTEMS') || str_contains($transaction->transaction_description_2, 'MAXIS')){
|
||||
$transaction->owners()->firstOrCreate([
|
||||
$data = $transaction->owners()->firstOrCreate([
|
||||
'type' => StatementTransactionOwnerType::NON_OPERATIONAL
|
||||
]);
|
||||
}
|
||||
}
|
||||
if (isset($data) && $data->wasRecentlyCreated) $mapped = true;
|
||||
$this->updateMappedRate($transaction, $mapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) {
|
||||
private function getTransactions($date, $amount, $type, $ownerType, $paymentMethod, $statuses, $keywords, $model = Transaction::class) {
|
||||
$dateRange = $this->getDateRange($date, 4);
|
||||
if (App::environment(['production'])) {
|
||||
$query = $model::whereIn('status', $statuses)
|
||||
@@ -322,7 +320,7 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
try{
|
||||
|
||||
$client = new \GuzzleHttp\Client(['verify' => false]);
|
||||
$response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2]'.$paymentMethodFilter.',"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in":['.$type.']}');
|
||||
$response = $client->request('GET', $url.'?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters={"order_by":{"column":"id","DESC":true},"status_in":[2]'.$paymentMethodFilter.',"created_after":"'.$dateRange['start_date'].'","created_before":"'.$dateRange['end_date'].'","amount_exceed":'.($amount - 0.01).',"amount_short":'.($amount + 0.01).',"type_in":'.json_encode($type).'}');
|
||||
$body = $response->getBody();
|
||||
$data = json_decode($body, true);
|
||||
$payload = $data['payload'];
|
||||
@@ -349,4 +347,11 @@ class CreateBankStatementTransactionOwnersProcessor
|
||||
'end_date' => $nextDay,
|
||||
];
|
||||
}
|
||||
|
||||
private function updateMappedRate($transaction, $mapped) {
|
||||
$statement = $transaction->statement;
|
||||
$statement->total_rows = StatementTransaction::where('account_statement_id',$transaction->account_statement_id)->count();
|
||||
$statement->mapped_rows = $mapped ? $statement->mapped_rows+1 : $statement->mapped_rows;
|
||||
$statement->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ class ListShippingPortalTransactions
|
||||
{
|
||||
try {
|
||||
$url = 'https://izyim.cief-malaysia.com/public/api/v1/transactions/mappable/query/with-details';
|
||||
// $url = 'http://127.0.0.1:8001/public/api/v1/transactions/mappable/query/with-details';
|
||||
$client = new \GuzzleHttp\Client(['verify' => false]);
|
||||
$response = $client->request('GET', $url . '?api-key=510acd13d8d24375cf038ad626c282565451461a9c2399357e0b65365300787e&filters=' . json_encode($filters));
|
||||
$body = $response->getBody();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounting\Services;
|
||||
|
||||
use App\Models\StatementTransactionOwner;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Classes\General\Eloquent\AbstractFetchRecord;
|
||||
|
||||
class FetchesBankStatementTransactionOwner extends AbstractFetchRecord
|
||||
{
|
||||
|
||||
/** @var StatementTransactionOwner */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* FetchesBankStatementDetails constructor.
|
||||
* @param StatementTransactionOwner $repository
|
||||
*/
|
||||
public function __construct(StatementTransactionOwner $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Accounting\Services;
|
||||
|
||||
use App\Models\TransactionMappingLog;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Classes\General\Eloquent\AbstractListRecord;
|
||||
|
||||
class ListTransactionMappingLogs extends AbstractListRecord
|
||||
{
|
||||
|
||||
/** @var TransactionMappingLog */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ListsBankStatementDetails constructor.
|
||||
* @param TransactionMappingLog $repository
|
||||
*/
|
||||
public function __construct(TransactionMappingLog $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ExpireBookingPaymentControllerLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Expire Payment',
|
||||
'message' => 'You have successfully expire the Payment'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/**
|
||||
* DeletePurchaseOrderPdfLogic constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
*/
|
||||
public function __construct(fetchesBooking $fetchesBooking)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
|
||||
|
||||
$payment = $booking->transactions()
|
||||
->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->first();
|
||||
|
||||
$payment->status = ApprovalStatus::EXPIRED;
|
||||
$payment->save();
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,13 +9,16 @@ use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus;
|
||||
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
|
||||
use App\Classes\Modules\Documents\Services\DeletesDocument;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
|
||||
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionWithInvoiceNoProcessor;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -23,7 +26,8 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
protected function notification(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Regenerate Booking Invoice',
|
||||
'message' => 'You have successfully regenerate booking invoice'
|
||||
@@ -48,6 +52,9 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
/** @var CreateInvoiceTransactionProcessor */
|
||||
private $createInvoiceTransactionProcessor;
|
||||
|
||||
/** @var CreateInvoiceTransactionWithInvoiceNoProcessor */
|
||||
private $createInvoiceTransactionWithInvoiceNoProcessor;
|
||||
|
||||
/**
|
||||
* FetchBookingLogic constructor.
|
||||
* @param CanFetchBooking $canFetchBooking
|
||||
@@ -56,6 +63,7 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
* @param UpdatesBookingStatus $updatesBookingStatus
|
||||
* @param DeletesDocument $deletesDocument
|
||||
* @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
|
||||
* @param CreateInvoiceTransactionWithInvoiceNoProcessor $createInvoiceTransactionWithInvoiceNoProcessor
|
||||
*/
|
||||
public function __construct(
|
||||
CanFetchBooking $canFetchBooking,
|
||||
@@ -63,15 +71,16 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
DeletesTransaction $deletesTransaction,
|
||||
UpdatesBookingStatus $updatesBookingStatus,
|
||||
DeletesDocument $deletesDocument,
|
||||
CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
|
||||
)
|
||||
{
|
||||
CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor,
|
||||
CreateInvoiceTransactionWithInvoiceNoProcessor $createInvoiceTransactionWithInvoiceNoProcessor
|
||||
) {
|
||||
$this->canFetchBooking = $canFetchBooking;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->deletesTransaction = $deletesTransaction;
|
||||
$this->updatesBookingStatus = $updatesBookingStatus;
|
||||
$this->deletesDocument = $deletesDocument;
|
||||
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
|
||||
$this->createInvoiceTransactionWithInvoiceNoProcessor = $createInvoiceTransactionWithInvoiceNoProcessor;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,18 +91,45 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
public function logic(Request $request): JsonResponse
|
||||
{
|
||||
$this->canFetchBooking->passes();
|
||||
|
||||
$booking = $this->fetchesBooking->execute([
|
||||
'id' => $request->route('id'),
|
||||
'status' => ApprovalStatus::COMPLETED,
|
||||
'with_transactions' => true]
|
||||
$booking = $this->fetchesBooking->execute(
|
||||
[
|
||||
'id' => $request->route('id'),
|
||||
'status' => ApprovalStatus::COMPLETED,
|
||||
'with_transactions' => true
|
||||
]
|
||||
);
|
||||
|
||||
$this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED);
|
||||
|
||||
$firstInvoice = $booking->transactions()
|
||||
->whereIn('type', [TransactionType::INVOICE])
|
||||
->withTrashed()
|
||||
->orderBy('created_at', 'asc')
|
||||
->first();
|
||||
|
||||
// get the first bill_no
|
||||
$firstBillNo = $firstInvoice->bill_no;
|
||||
if (strpos($firstBillNo, '-deleted') !== false) {
|
||||
$firstBillNo = substr($firstBillNo, 0, strpos($firstBillNo, '-deleted'));
|
||||
}
|
||||
|
||||
// update currentInvoice bill_no to '-deleted-'
|
||||
$currentInvoice = $booking->transactions()->where('type', TransactionType::INVOICE)->first();
|
||||
$currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp);
|
||||
$currentInvoice->save();
|
||||
|
||||
$transactionWithSameBillNo = Transaction::where('bill_no', $firstBillNo)->withTrashed()->get();
|
||||
if ($transactionWithSameBillNo) {
|
||||
foreach ($transactionWithSameBillNo as $transaction) {
|
||||
$transaction->bill_no = $transaction->bill_no . "-deleted-" . Str::random(10);
|
||||
$transaction->save();
|
||||
}
|
||||
}
|
||||
|
||||
$transaction = $booking->transactions()->whereIn('type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->get();
|
||||
foreach ($transaction as $key => $row) {
|
||||
$this->deletesTransaction->execute($row);
|
||||
@@ -104,9 +140,8 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
$this->deletesDocument->execute($row);
|
||||
}
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
$this->createInvoiceTransactionWithInvoiceNoProcessor->execute($booking, $firstBillNo);
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use ZipArchive;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Company;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class BulkDownloadCustomerInvoicesLogic
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function execute(Request $request)
|
||||
{
|
||||
try {
|
||||
$company = Company::where('reference', $request->input('marking'))->first();
|
||||
|
||||
if (!$company) {
|
||||
return response()->json([
|
||||
'status' => 'Failed',
|
||||
'message' => 'Customer not found.',
|
||||
]);
|
||||
}
|
||||
|
||||
$startDate = Carbon::createFromFormat('d-m-Y', $request->input('startDate'))->startOfDay();
|
||||
$endDate = Carbon::createFromFormat('d-m-Y', $request->input('endDate'))->endOfDay();
|
||||
|
||||
$invoicebookings = $company->bookings()
|
||||
->whereDate('created_at', '>=', $startDate)
|
||||
->whereDate('created_at', '<=', $endDate)
|
||||
->whereHas('transactions', function ($query) {
|
||||
$query->where('transactions.type', TransactionType::INVOICE)
|
||||
->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})
|
||||
->orderBy('created_at')
|
||||
->get();
|
||||
|
||||
if ($invoicebookings->isEmpty()) {
|
||||
return response()->json([
|
||||
'status' => 'Failed',
|
||||
'message' => 'No invoices found for this customer in the given date range.',
|
||||
]);
|
||||
}
|
||||
|
||||
$zipDirectory = storage_path('app/bulk_invoice'); // Update this with the actual directory path
|
||||
|
||||
if (!file_exists($zipDirectory)) {
|
||||
mkdir($zipDirectory, 0755, true);
|
||||
}
|
||||
|
||||
$zip_file = "{$zipDirectory}/invoices_{$request->input('startDate')}_to_{$request->input('endDate')}_{$company->reference}.zip";
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zip_file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
|
||||
foreach ($invoicebookings as $booking) {
|
||||
$invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->whereNull('deleted_at')->first()->files()->first();
|
||||
$zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
return response()->download($zip_file);
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'Error',
|
||||
'message' => 'Failed to create the Zip archive.',
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Log the exception for debugging
|
||||
Log::error('Error in BulkDownloadCustomerInvoicesLogic: ' . $e->getMessage());
|
||||
|
||||
return response()->json([
|
||||
'status' => 'Error',
|
||||
'message' => 'An error occurred while processing the request.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\ControllersLogic;
|
||||
|
||||
use ZipArchive;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Company;
|
||||
use App\Models\Group;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class BulkDownloadSupplierWhiteFormsLogic
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return void
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(Request $request)
|
||||
{
|
||||
try {
|
||||
|
||||
$startDate = Carbon::createFromFormat('d-m-Y', $request->input('startDate'))->startOfDay();
|
||||
$endDate = Carbon::createFromFormat('d-m-Y', $request->input('endDate'))->endOfDay();
|
||||
|
||||
$companyReference = Company::find($request->input('supplier'))->reference;
|
||||
$groups = Group::where('issuer', $request->input('supplier'))
|
||||
->whereDate('created_at', '>=', $startDate)
|
||||
->whereDate('created_at', '<=', $endDate)
|
||||
->orderBy('created_at', 'DESC')
|
||||
->get();
|
||||
|
||||
if (count($groups) > 0) {
|
||||
|
||||
$zipDirectory = storage_path('app/bulk_whiteform'); // Update this with the actual directory path
|
||||
|
||||
if (!file_exists($zipDirectory)) {
|
||||
mkdir($zipDirectory, 0755, true);
|
||||
}
|
||||
|
||||
$zip_file = "{$zipDirectory}/currency_vendor_orders_{$request->input('startDate')}_to_{$request->input('endDate')}_{$companyReference}.zip";
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
|
||||
foreach($groups as $group) {
|
||||
$document = $group->documents()->where('document_type', DocumentType::CURRENCY_VENDOR_ORDER)->whereNull('deleted_at')->first()->files()->first();
|
||||
$created_at = $group->created_at->format('Y-m-d');
|
||||
$zip->addFile(Storage::disk('documents')->path($document->file->file_info->original->file), $created_at . "_" . $group->amount . "_" . $group->reference . '.pdf');
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
return response()->download($zip_file);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'status' => 'Failed',
|
||||
'message' => 'No white form found for this supplier in the given date range.',
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// Log the exception for debugging
|
||||
Log::error('Error in BulkDownloadSupplierWhiteFormsLogic: ' . $e->getMessage());
|
||||
|
||||
return response()->json([
|
||||
'status' => 'Error',
|
||||
'message' => 'An error occurred while processing the request.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
|
||||
class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
|
||||
{
|
||||
use Exportable;
|
||||
|
||||
private $dateTime;
|
||||
private $count;
|
||||
private $counter = 1;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->dateTime = $request->input('date').' '.$request->input('time');
|
||||
$this->count = 0;
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'No',
|
||||
'Doc No',
|
||||
'Date',
|
||||
'Debtor Code',
|
||||
'Debtor Name',
|
||||
'Shipping Info',
|
||||
'Net Total',
|
||||
'Cancelled',
|
||||
'Mapped Status',
|
||||
'Mapped Reference No',
|
||||
'MapPayment Received Date'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection|mixed
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return TransactionMappingLog::where('imported_date', $this->dateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction $transaction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function map($transaction): array
|
||||
{
|
||||
$this->count += 1;
|
||||
$data = $transaction->data;
|
||||
return [
|
||||
$this->count,
|
||||
Arr::get($data,'doc_no'),
|
||||
Arr::get($data,'date'),
|
||||
Arr::get($data,'debtor_code'),
|
||||
Arr::get($data,'debtor_name'),
|
||||
Arr::get($data,'shipping_info'),
|
||||
Arr::get($data,'net_total'),
|
||||
Arr::get($data,'cancelled'),
|
||||
Arr::get($data,'mapped_status'),
|
||||
Arr::get($data,'mapped_result_reference'),
|
||||
Arr::get($data,'payment_received_date'),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
|
||||
class ExportsImportedReceiptMappeds implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
|
||||
{
|
||||
use Exportable;
|
||||
|
||||
private $dateTime;
|
||||
private $count;
|
||||
private $counter = 1;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->dateTime = $request->input('date').' '.$request->input('time');
|
||||
$this->count = 0;
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'Check',
|
||||
'Doc No',
|
||||
'Doc Date',
|
||||
'Debtor Code',
|
||||
'Company Name',
|
||||
'Description',
|
||||
'Payment Amount',
|
||||
'Created User',
|
||||
'Curr.',
|
||||
'To Home Rate',
|
||||
'Local Payment Amount',
|
||||
'Cancelled',
|
||||
'Mapped Status',
|
||||
'Mapped Reference No',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection|mixed
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return TransactionMappingLog::where('imported_date', $this->dateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction $transaction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function map($transaction): array
|
||||
{
|
||||
$this->count += 1;
|
||||
$data = $transaction->data;
|
||||
return [
|
||||
$this->count,
|
||||
Arr::get($data,'doc_no'),
|
||||
Arr::get($data,'doc_date'),
|
||||
Arr::get($data,'debtor_code'),
|
||||
Arr::get($data,'company_name'),
|
||||
Arr::get($data,'description'),
|
||||
Arr::get($data,'payment_amount'),
|
||||
Arr::get($data,'created_user'),
|
||||
Arr::get($data,'curr'),
|
||||
Arr::get($data,'to_home_rate'),
|
||||
Arr::get($data,'local_payment_amount'),
|
||||
Arr::get($data,'cancelled'),
|
||||
Arr::get($data,'2nd_doc_no'),
|
||||
Arr::get($data,'mapped_status'),
|
||||
Arr::get($data,'mapped_result_reference'),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\StatementTransactionOwnerType;
|
||||
use App\Models\StatementTransactionOwner;
|
||||
use App\Models\Transaction;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
@@ -18,6 +17,8 @@ use App\Classes\Modules\Accounting\Processors\ListShippingPortalTransactions;
|
||||
use App\Classes\ValueObjects\Constants\ShippingTransactionType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Classes\General\Eloquent\ApplyFiltersToQuery;
|
||||
use App\Models\StatementTransaction;
|
||||
|
||||
class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
|
||||
{
|
||||
@@ -33,7 +34,7 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
$header = [
|
||||
'DocNo',
|
||||
'DocDate',
|
||||
'DebtorCode',
|
||||
@@ -49,6 +50,7 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
'AccNo',
|
||||
'DeptNo'
|
||||
];
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,9 +58,10 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return StatementTransactionOwner::whereNull('invoice_reference')
|
||||
->whereIn('type', [StatementTransactionOwnerType::SALES, StatementTransactionOwnerType::WALLET_TOP_UP])
|
||||
->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED]);
|
||||
$data = (new ApplyFiltersToQuery())->execute(StatementTransaction::query(), json_decode($this->request->input('filter'), true));
|
||||
if ($this->request->has('bankStatementTransactionId')) $data = $data->whereIn('id',json_decode($this->request->input('bankStatementTransactionId'), true));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,11 +71,12 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
*/
|
||||
public function map($transaction): array
|
||||
{
|
||||
$statementTransactionOwner = $transaction->owners()->whereIn('status', [ApprovalStatus::APPROVED])->first();
|
||||
$logArray = [
|
||||
'counter' => $this->counter,
|
||||
'system' => $transaction->system,
|
||||
'StatementTransactionOwner_id' => $transaction->id,
|
||||
'transaction_table_id' => $transaction->owner_id,
|
||||
'system' => $statementTransactionOwner->system,
|
||||
'StatementTransactionOwner_id' => $statementTransactionOwner->id,
|
||||
'transaction_table_id' => $statementTransactionOwner->owner_id,
|
||||
];
|
||||
$this->counter += 1;
|
||||
$logArray = json_encode($logArray);
|
||||
@@ -82,8 +86,8 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
$textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $logArray . PHP_EOL;
|
||||
file_put_contents($filePath, $textToAppend, FILE_APPEND);
|
||||
|
||||
if ($transaction->system == 'EXCHANGE') {
|
||||
$row = (App()->make($transaction->owner_type))->where('id', $transaction->owner_id)->first();
|
||||
if ($statementTransactionOwner->system == 'EXCHANGE') {
|
||||
$row = (App()->make($statementTransactionOwner->owner_type))->where('id', $statementTransactionOwner->owner_id)->first();
|
||||
$company = $row->type === TransactionType::PAYMENT ? $row->owner->company : $row->owner->owner;
|
||||
|
||||
$booking = $row->owner;
|
||||
@@ -104,46 +108,61 @@ class ExportsInvoiceTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
'500-0000',
|
||||
'CIEF'
|
||||
];
|
||||
} else {
|
||||
} elseif ($statementTransactionOwner->owner_id) {
|
||||
$row = (App()->make(ListShippingPortalTransactions::class))->execute([
|
||||
'id' => $transaction->owner_id,
|
||||
'id' => $statementTransactionOwner->owner_id,
|
||||
'with_company' => true,
|
||||
]);
|
||||
|
||||
if (empty($row) || $row[0]['status'] != 'success') {
|
||||
if (!empty($row) && $row[0]['status'] != 'success') {
|
||||
$textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' Fetch Shipping Transaction Fail ' . json_encode([
|
||||
'id' => $transaction->owner_id,
|
||||
'id' => $statementTransactionOwner->owner_id,
|
||||
'with_company' => true,
|
||||
'StatementTransactionOwner_id' => $transaction->id,
|
||||
'StatementTransactionOwner_id' => $statementTransactionOwner->id,
|
||||
]) . PHP_EOL;
|
||||
file_put_contents($errorFilePath, $textToAppend, FILE_APPEND);
|
||||
|
||||
$textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' Shipping Portal Respnose ' . json_encode($row) . PHP_EOL;
|
||||
file_put_contents($errorFilePath, $textToAppend, FILE_APPEND);
|
||||
|
||||
Log::info('Error in Exports Invoice Transactions ' . $this->counter);
|
||||
return [
|
||||
'<<New>>',
|
||||
Carbon::parse($row['created_at'])->format('m/d/Y H:m'),
|
||||
$row['debtor_code'],
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? $row['order_reference'] : $row['marking'],
|
||||
'',
|
||||
'MYR',
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? $row['order_reference'] : $row['bill_no'],
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? '' : 'W1',
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? 'PLEASE REFER TO THE ATTACHED APPENDIX REF `' . $row['order_reference'] : 'CREDIT SALES',
|
||||
'',
|
||||
1,
|
||||
round($row['amount'], 2),
|
||||
'500-0000',
|
||||
'CIEF'
|
||||
];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
$row = $row[0];
|
||||
|
||||
return [
|
||||
'<<New>>',
|
||||
Carbon::parse($row['updated_at'])->format('m/d/Y H:m'),
|
||||
$row['debtor_code'],
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? $row['order_reference'] : $row['marking'],
|
||||
'',
|
||||
'MYR',
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? $row['order_reference'] : $row['bill_no'],
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? '' : 'W1',
|
||||
$row['type'] === ShippingTransactionType::PAYMENT ? 'PLEASE REFER TO THE ATTACHED APPENDIX REF `' . $row['order_reference'] : 'CREDIT SALES',
|
||||
'',
|
||||
1,
|
||||
round($row['amount'], 2),
|
||||
'500-0000',
|
||||
'CIEF'
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'Transaction Not Found',
|
||||
$transaction->posting_date->format('m/d/Y H:m'),
|
||||
$transaction->transaction_description.' - '.$transaction->transaction_description_2,
|
||||
$statementTransactionOwner->system,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
$transaction->amount,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
''
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Classes\General\Eloquent\ApplyFiltersToQuery;
|
||||
use App\Models\StatementTransaction;
|
||||
use App\Models\Company;
|
||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
|
||||
class ExportsReceiptTransactions implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize, WithEvents, WithCustomStartCell
|
||||
{
|
||||
use Exportable;
|
||||
|
||||
private $request;
|
||||
private $counter = 1;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function startCell(): string
|
||||
{
|
||||
return 'A2';
|
||||
}
|
||||
|
||||
public function registerEvents(): array {
|
||||
|
||||
return [
|
||||
AfterSheet::class => function(AfterSheet $event) {
|
||||
$sheet = $event->sheet;
|
||||
|
||||
$sheet->mergeCells('A1:A1');
|
||||
$sheet->setCellValue('A1', '"');
|
||||
|
||||
$sheet->mergeCells('M1:Y1');
|
||||
$sheet->setCellValue('M1', "Payment Detail Column");
|
||||
|
||||
$sheet->mergeCells('Z1:AB1');
|
||||
$sheet->setCellValue('Z1', "Knock Off Detail");
|
||||
|
||||
$styleArray = [
|
||||
'alignment' => [
|
||||
'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
|
||||
],
|
||||
];
|
||||
|
||||
$cellRange = 'A1:AB1';
|
||||
$event->sheet->getDelegate()->getStyle($cellRange)->applyFromArray($styleArray);
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
$header = [
|
||||
[
|
||||
' ',
|
||||
'(20 chars)',
|
||||
'(Date: dd/MM/yyyy)',
|
||||
'(12 chars)',
|
||||
'(40 chars)',
|
||||
'(25 chars)',
|
||||
'(10 chars)',
|
||||
'(10 chars)',
|
||||
'(5 chars)',
|
||||
'(Number, use System Currency Rate Decimal)',
|
||||
'(Number, use System Currency Rate Decimal)',
|
||||
'(Rich Text)',
|
||||
'(20 chars)',
|
||||
'(20 chars)',
|
||||
'(Number, use System Currency Decimal)',
|
||||
'(Number, use System Currency Decimal)',
|
||||
'(Number, use System Currency Rate Decimal)',
|
||||
'(14 chars)',
|
||||
'(30 chars)',
|
||||
'(10 chars)',
|
||||
'(10 chars)',
|
||||
'(20 chars)',
|
||||
'(Integer)',
|
||||
'(Boolean. Indicate T for stock control or F for non stock control)',
|
||||
'(Returned Cheque Date: dd/MM/yyyy)',
|
||||
'(2 chars, RI for Invoice, RD for D/N)',
|
||||
'',
|
||||
'(Number, use System Currency Decimal)',
|
||||
],
|
||||
[
|
||||
'DocNo',
|
||||
'DocDate',
|
||||
'DebtorCode',
|
||||
'Description',
|
||||
'DocNo2',
|
||||
'ProjNo',
|
||||
'DeptNo',
|
||||
'CurrencyCode',
|
||||
'ToHomeRate',
|
||||
'ToDebtorRate',
|
||||
'Note',
|
||||
'PaymentMethod',
|
||||
'ChequeNo',
|
||||
'PaymentAmt',
|
||||
'BankCharge',
|
||||
'ToBankRate',
|
||||
'BankChargeTaxType',
|
||||
'BankChargeTaxRefNo',
|
||||
'BankChargeProjNo',
|
||||
'BankChargeDeptNo',
|
||||
'PaymentBy',
|
||||
'FloatDay',
|
||||
'IsRCHQ',
|
||||
'RCHQDate',
|
||||
'KnockOffDocType',
|
||||
'KnockOffDocNo',
|
||||
'KnockOffAmt',
|
||||
'',
|
||||
]
|
||||
];
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection|mixed
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$data = (new ApplyFiltersToQuery())->execute(StatementTransaction::query(), json_decode($this->request->input('filter'), true));
|
||||
if ($this->request->has('bankStatementTransactionId')) $data = $data->whereIn('id',json_decode($this->request->input('bankStatementTransactionId'), true));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StatementTransaction $transaction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function map($transaction): array
|
||||
{
|
||||
$statementTransactionOwner = $transaction->owners()->whereIn('status', [ApprovalStatus::APPROVED])->first();
|
||||
$logArray = [
|
||||
'counter' => $this->counter,
|
||||
'system' => $statementTransactionOwner->system,
|
||||
'StatementTransactionOwner_id' => $statementTransactionOwner->id,
|
||||
'transaction_table_id' => $statementTransactionOwner->owner_id,
|
||||
];
|
||||
$this->counter += 1;
|
||||
$logArray = json_encode($logArray);
|
||||
|
||||
$filePath = storage_path('logs/exports_receipt_transactions.log');
|
||||
$errorFilePath = storage_path('logs/exports_receipt_transactions_error.log');
|
||||
$textToAppend = Carbon::now()->format('[Y-m-d H:i:s]') . ' ' . $logArray . PHP_EOL;
|
||||
file_put_contents($filePath, $textToAppend, FILE_APPEND);
|
||||
|
||||
$company = Company::where('name',$transaction->transaction_description_2)->first();
|
||||
|
||||
return [
|
||||
'<<New>>',
|
||||
Carbon::parse($transaction->posting_date)->format('d/m/Y'),
|
||||
($company ? $company->debtor : null),
|
||||
'Payment for '.$transaction->transaction_description,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'MYR',
|
||||
1,
|
||||
1,
|
||||
'',
|
||||
'MBB',
|
||||
'',
|
||||
$transaction->amount,
|
||||
'',
|
||||
1,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'0',
|
||||
'',
|
||||
'',
|
||||
'RI',
|
||||
$transaction->transaction_ref,
|
||||
$transaction->amount,
|
||||
'',
|
||||
];
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\TransactionResource;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class ImportPurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Update Purchase Order',
|
||||
'message' => 'You have successfully updated you booking\'s purchase order'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var CreatePurchaseOrderTransactionProcessor */
|
||||
private $createPurchaseOrderTransactionProcessor;
|
||||
|
||||
/**
|
||||
* CreatePurchaseOrderTransactionLogic constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $id
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request, $id = '') : JsonResponse
|
||||
{
|
||||
$files = $request->file('files');
|
||||
|
||||
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
|
||||
foreach ($object->getFiles() as $file){
|
||||
$collection = Excel::toCollection(null, json_decode($file)->file_info->original->file, null, null, true);
|
||||
|
||||
$sheet = $collection->first()->skip(1);
|
||||
|
||||
$products = $sheet->map(function ($row) {
|
||||
Log::info($row);
|
||||
$stockCode = $row[0];
|
||||
$description = $row[1];
|
||||
$quantity = $row[2];
|
||||
$unit_price = $row[3];
|
||||
|
||||
return [
|
||||
'stockCode' => $stockCode,
|
||||
'description' => $description,
|
||||
'quantity' => $quantity,
|
||||
'unit_price' => $unit_price
|
||||
];
|
||||
})->all();
|
||||
}
|
||||
|
||||
// dd($products);
|
||||
|
||||
/** @var Booking $booking */
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('PO-');
|
||||
|
||||
$total = collect($products)->sum(function($product){
|
||||
return $product['quantity'] * floatval(str_replace(',', '', $product['unit_price']));
|
||||
});
|
||||
|
||||
$object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1,
|
||||
1, PaymentMethodType::CASH,
|
||||
$total, $total, $booking->fix_currency_id, $booking->fix_currency_id,
|
||||
1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products);
|
||||
|
||||
|
||||
$transaction = $this->createPurchaseOrderTransactionProcessor->execute($booking, $object);
|
||||
|
||||
return $this->resourceResponse(new TransactionResource($transaction));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,19 @@ class ListWalletTransactionsLogic extends AbstractControllerLogic
|
||||
$query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters')));
|
||||
|
||||
if (str_contains($request->input('filters'), "owner_id") && $query->count() > 0) {
|
||||
$currentWalletBalance = Wallet::find($query->first()->owner_id)->amount;
|
||||
$wallet_total_incoming = Transaction::where('owner_type', $query->first()->owner_type)
|
||||
->where('owner_id', $query->first()->owner_id)
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->whereIn('type', [TransactionType::TOP_UP, TransactionType::CREDIT_NOTE])
|
||||
->sum('amount');
|
||||
|
||||
$wallet_total_outgoing = Transaction::where('owner_type', $query->first()->owner_type)
|
||||
->where('owner_id', $query->first()->owner_id)
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->whereIn('type', [TransactionType::PAYMENT, TransactionType::DEBIT_NOTE])
|
||||
->sum('amount');
|
||||
|
||||
$currentWalletBalance = $wallet_total_incoming - $wallet_total_outgoing;
|
||||
$incoming = Transaction::where('owner_type', $query->first()->owner_type)
|
||||
->where('owner_id', $query->first()->owner_id)
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\SegmentConstant;
|
||||
|
||||
class CreateInvoiceTransactionProcessorWithInvoiceNo
|
||||
class CreateInvoiceTransactionWithInvoiceNoProcessor
|
||||
{
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
@@ -35,7 +35,7 @@ class GeneratesTransactionBillNumber
|
||||
$attempt = 0;
|
||||
while ($attempt < 10) { // Retry up to 10 times
|
||||
// $billNumber = $prefix . $date->format('Y') . $date->format('m') . '-' . intval(microtime(true));
|
||||
$billNumber = $prefix . $date->format('Y') . $date->format('m') . '-' . mt_rand(1000000000, 9999999999);
|
||||
$billNumber = $prefix . $date->format('Y') . $date->format('m') . '-' . mt_rand(1000000, 9999999);
|
||||
if (!$this->checksIfTransactionBillNumberExists->execute($billNumber)) {
|
||||
return $billNumber;
|
||||
}
|
||||
|
||||
@@ -8,9 +8,21 @@ final class SystemType {
|
||||
|
||||
public const SHIPPING_PORTAL = 'SHIPPING_PORTAL';
|
||||
|
||||
public const CNTR = 'CNTR';
|
||||
|
||||
public const LITE = 'LITE';
|
||||
|
||||
public const PROBASHI = 'PROBASHI';
|
||||
|
||||
public const PETS = 'PETS';
|
||||
|
||||
public const SYSTEM_NAMES = [
|
||||
'exchange' => self::EXCHANGE,
|
||||
'shipping_portal' => self::SHIPPING_PORTAL,
|
||||
'izyim' => self::SHIPPING_PORTAL,
|
||||
'lite' => self::LITE,
|
||||
'cntr' => self::CNTR,
|
||||
'probashi' => self::PROBASHI,
|
||||
'pets' => self::PETS
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class DeleteBulkInvoiceFiles extends Command
|
||||
{
|
||||
protected $signature = 'delete:bulk-download-files';
|
||||
|
||||
protected $description = 'Delete all the bulk download files';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$directories = [
|
||||
storage_path('app/bulk_invoice'),
|
||||
storage_path('app/bulk_whiteform'),
|
||||
];
|
||||
|
||||
foreach ($directories as $directory) {
|
||||
$start = new Carbon();
|
||||
$this->info(Carbon::now() . ' Start cleaning - ' . $directory);
|
||||
|
||||
if (File::isDirectory($directory)) {
|
||||
File::cleanDirectory($directory);
|
||||
$this->info('All files have been deleted.');
|
||||
} else {
|
||||
$this->info('Directory does not exist.');
|
||||
}
|
||||
|
||||
$end = new Carbon();
|
||||
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
|
||||
|
||||
$this->info(Carbon::now() . ' Process ended. ElapsedTime: ' . $elapsedTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,10 +38,10 @@ class Kernel extends ConsoleKernel
|
||||
->dailyAt('01:00')
|
||||
->appendOutputTo(storage_path().'/logs/soft-delete-seasonal-segmant-company.log')
|
||||
->withoutOverlapping();
|
||||
|
||||
$schedule->command('regenerateInvoice')
|
||||
->everyMinute()
|
||||
->appendOutputTo(storage_path().'/logs/regenerateInvoice.log')
|
||||
|
||||
$schedule->command('delete:bulk-download-files')
|
||||
->hourly()
|
||||
->appendOutputTo(storage_path().'/logs/delete-bulk-download-files.log')
|
||||
->withoutOverlapping();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use DateTime;
|
||||
use App\Models\StatementTransaction;
|
||||
|
||||
class BankStatementController extends Controller
|
||||
{
|
||||
@@ -88,7 +89,9 @@ class BankStatementController extends Controller
|
||||
|
||||
public function rerun()
|
||||
{
|
||||
CreateBankStatementTransactionOwners::dispatch();
|
||||
foreach (StatementTransaction::doesntMapStatement()->get()->chunk(30) as $key => $transaction) {
|
||||
CreateBankStatementTransactionOwners::dispatch($transaction);
|
||||
}
|
||||
return redirect()->back()->with('success', 'Rerun triggered successfully');
|
||||
}
|
||||
|
||||
@@ -129,7 +132,7 @@ class BankStatementController extends Controller
|
||||
->download($statement->date_from->format('Y-m-d') . '_' . $statement->date_to->format('Y-m-d') . '_statement.csv');
|
||||
}
|
||||
|
||||
public function fetch(Request $request, ListBankStatementDetailsLogic $logic): JsonResponse
|
||||
public function fetch(Request $request, ListBankStatementTransactionsLogic $logic): JsonResponse
|
||||
{
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Accounting;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Classes\Modules\Accounting\ControllersLogic\HistoryImportedTransactionMappedControllerLogic;
|
||||
|
||||
class HistoryImportedTransactionMappedController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ApprovePaymentLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function getImported(Request $request, HistoryImportedTransactionMappedControllerLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bookings;
|
||||
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\ExpireBookingPaymentControllerLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ExpireBookingPaymentController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param DeleteBookingPaymentControllerLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function expire(Request $request, ExpireBookingPaymentControllerLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Companies;
|
||||
|
||||
use App\Classes\Modules\Companies\ControllersLogic\BulkDownloadCustomerInvoicesLogic;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BulkDownloadCustomerInvoicesController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param BulkDownloadCustomerInvoicesLogic $logic
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function download(Request $request, BulkDownloadCustomerInvoicesLogic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Companies;
|
||||
|
||||
use App\Classes\Modules\Companies\ControllersLogic\BulkDownloadSupplierWhiteFormsLogic;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BulkDownloadSupplierWhiteFormsController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param BulkDownloadSupplierWhiteFormsLogic $logic
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function download(Request $request, BulkDownloadSupplierWhiteFormsLogic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,10 @@ use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Maatwebsite\Excel\Excel;
|
||||
use App\Classes\Modules\Exports\Services\ExportsImportedInvoiceMappeds;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use App\Classes\Modules\Exports\Services\ExportsReceiptTransactions;
|
||||
use App\Classes\Modules\Exports\Services\ExportsImportedReceiptMappeds;
|
||||
|
||||
class ExportCustomersToExcelController
|
||||
{
|
||||
@@ -64,6 +68,13 @@ class ExportCustomersToExcelController
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function receiptTransactions(Request $request){
|
||||
$exportsTransactions = new ExportsReceiptTransactions($request);
|
||||
$response = $exportsTransactions->download('receipt-transactions.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function bookingTransactions(ExportsBookingTransactions $exportsBookingTransactions, Request $request){
|
||||
$response = $exportsBookingTransactions->download('bookingTransactions.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
@@ -75,4 +86,16 @@ class ExportCustomersToExcelController
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function importedInvoiceMapped(ExportsImportedInvoiceMappeds $exportsImportedInvoiceMappeds, Request $request) {
|
||||
$response = $exportsImportedInvoiceMappeds->download($request->input('fileName').'.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function importedReceiptMapped(ExportsImportedReceiptMappeds $exportsImportedReceiptMappeds, Request $request) {
|
||||
$response = $exportsImportedReceiptMappeds->download($request->input('fileName').'.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -2,94 +2,194 @@
|
||||
|
||||
namespace App\Http\Controllers\Imports;
|
||||
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Imports\Services\GenericImport;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Segment;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Models\Company;
|
||||
use App\Models\Segment;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\SeasonalSegment;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\Modules\Imports\Services\GenericImport;
|
||||
use App\Classes\ValueObjects\Response\ApiResponseObject;
|
||||
use App\Classes\Modules\Accounting\Processors\ChecksBillNumber;
|
||||
use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment;
|
||||
use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor;
|
||||
use App\Models\Company;
|
||||
use App\Models\SeasonalSegment;
|
||||
use App\Models\Transaction;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject;
|
||||
|
||||
class ImportStatementInvoiceController
|
||||
{
|
||||
private $responseTitle;
|
||||
private $responseMessage;
|
||||
|
||||
public function __construct() {
|
||||
$this->responseTitle = 'Import Invoice Mapping';
|
||||
$this->responseMessage = 'You have successfully imported invoice mapping';
|
||||
}
|
||||
|
||||
public function mapping($row) {
|
||||
// Shipping Info
|
||||
// TOPUP -> map with transaction.bill_no
|
||||
if (str_starts_with($row['shipping_info'], 'TOPUP')) {
|
||||
// find in exchange first, if cannont then find in izyim
|
||||
foreach (['exchange','izyim'] as $system) {
|
||||
[$returnReference, $transactionDate] = $this->mappingTopUp($row, $system);
|
||||
if ($returnReference) {
|
||||
// $row['mapped_result_reference'] = $data['owner_reference'];
|
||||
// $row['payment_received_date'] = date('Y-m-d', strtotime($data['created_at']));
|
||||
$row['mapped_result_reference'] = $returnReference;
|
||||
$row['payment_received_date'] = $transactionDate ? date('d-m-Y', strtotime($transactionDate)) : null;
|
||||
$row['mapped_status'] = 'success';
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[$returnReference, $transactionDate] = $this->mappingExchange($row);
|
||||
if ($returnReference) {
|
||||
$row['mapped_result_reference'] = $returnReference;
|
||||
$row['payment_received_date'] = date('d-m-Y', strtotime($transactionDate));
|
||||
$row['mapped_status'] = 'success';
|
||||
return $row;
|
||||
}
|
||||
|
||||
// if still unable to map, will try to check the shipping_info without TOPUP
|
||||
// foreach (['exchange','izyim'] as $system) {
|
||||
// $returnReference = $this->mappingTopUp($row, $system);
|
||||
// if ($returnReference) {
|
||||
// $row['mapped_result_reference'] = $returnReference;
|
||||
// $row['mapped_status'] = 'success';
|
||||
// }
|
||||
// }
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function import(Request $request)
|
||||
public function import(Request $request) : JsonResponse
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
try {
|
||||
ini_set('memory_limit', '-1');
|
||||
$importDate = date('Y-m-d H:i:s');
|
||||
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
|
||||
$file = json_decode($object->getFiles()[0])->file_info->original->file;
|
||||
|
||||
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
|
||||
$file = json_decode($object->getFiles()[0])->file_info->original->file;
|
||||
$import = new GenericImport();
|
||||
Excel::import($import, $file);
|
||||
$excelRows = $import->rows;
|
||||
$excelRows = $excelRows->toArray();
|
||||
|
||||
$import = new GenericImport();
|
||||
Excel::import($import, $file);
|
||||
$excelRows = $import->rows;
|
||||
$excelRows = $excelRows->toArray();
|
||||
$data = [];
|
||||
foreach ($excelRows as $row) {
|
||||
$row['mapped_result_reference'] = null;
|
||||
$row['payment_received_date'] = null;
|
||||
$row['mapped_status'] = 'failed';
|
||||
$row['date'] = in_array(gettype($row['date']), ['integer', 'double']) ? $this->changeExcelDate($row['date']) : date('Y-m-d', strtotime($row['date']));
|
||||
|
||||
$row = $this->mapping($row);
|
||||
|
||||
TransactionMappingLog::create([
|
||||
'imported_date'=>$importDate,
|
||||
'type' => 'invoices',
|
||||
'data'=>$row,
|
||||
]);
|
||||
array_push($data, $row);
|
||||
|
||||
|
||||
// if 5 digits -> exchange booking reference
|
||||
// find transation
|
||||
// find statement_transaction_owners, and fill up the details
|
||||
|
||||
// if <5 digits, find the transaction id (order number in izyim), find the payment in izyim
|
||||
// find transation
|
||||
// find statement_transaction_owners, and fill up the details
|
||||
|
||||
// dd([
|
||||
// 'type' => $statementTransactionOwnerType,
|
||||
// 'system' => $system,
|
||||
// // 'owner_type' => Transaction::class,
|
||||
// // todo-new: make sure owner_type is a class
|
||||
// 'owner_type' => $owner_type,
|
||||
// 'owner_id' => $owner_id,
|
||||
// 'owner_reference' => $owner_reference
|
||||
// ]);
|
||||
|
||||
// $bankStatementTransaction->owners()->firstOrCreate([
|
||||
// 'type' => $statementTransactionOwnerType,
|
||||
// 'system' => $system,
|
||||
// // 'owner_type' => Transaction::class,
|
||||
// // todo-new: make sure owner_type is a class
|
||||
// 'owner_type' => $owner_type,
|
||||
// 'owner_id' => $owner_id,
|
||||
// 'owner_reference' => $owner_reference
|
||||
// ]);
|
||||
|
||||
foreach ($excelRows as $row) {
|
||||
dd($row);
|
||||
// $row['debtor_code']
|
||||
|
||||
// attempt 1 - try map by amount and date
|
||||
// $transactionDate = $this->changeExcelDate($row['date']);
|
||||
// $transaction = Transaction::where('original_amount', $row['total'])->whereDate('created_at', $transactionDate)->get();
|
||||
// if ($transaction) {
|
||||
// // check company
|
||||
// // $company = Company::where('debtor', $row['debtor_code'])->first();
|
||||
// // dd($company);
|
||||
// // try to verify is it the correct transaction
|
||||
// }
|
||||
|
||||
// Shipping Info
|
||||
// TOPUP -> map with transaction.bill_no
|
||||
if (str_starts_with($row['shipping_info'], 'TOPUP')) {
|
||||
// find in exchange first, if cannont then find in izyim
|
||||
// (App()->make(ChecksBillNumber::class))->execute($bill_no, 'exchange');
|
||||
}
|
||||
|
||||
// if 5 digits -> exchange booking reference
|
||||
// find transation
|
||||
// find statement_transaction_owners, and fill up the details
|
||||
|
||||
// if <5 digits, find the transaction id (order number in izyim), find the payment in izyim
|
||||
// find transation
|
||||
// find statement_transaction_owners, and fill up the details
|
||||
|
||||
// dd([
|
||||
// 'type' => $statementTransactionOwnerType,
|
||||
// 'system' => $system,
|
||||
// // 'owner_type' => Transaction::class,
|
||||
// // todo-new: make sure owner_type is a class
|
||||
// 'owner_type' => $owner_type,
|
||||
// 'owner_id' => $owner_id,
|
||||
// 'owner_reference' => $owner_reference
|
||||
// ]);
|
||||
|
||||
// $bankStatementTransaction->owners()->firstOrCreate([
|
||||
// 'type' => $statementTransactionOwnerType,
|
||||
// 'system' => $system,
|
||||
// // 'owner_type' => Transaction::class,
|
||||
// // todo-new: make sure owner_type is a class
|
||||
// 'owner_type' => $owner_type,
|
||||
// 'owner_id' => $owner_id,
|
||||
// 'owner_reference' => $owner_reference
|
||||
// ]);
|
||||
|
||||
|
||||
return $this->response($this->responseTitle, $this->responseMessage, HttpStatus::OK_WITH_MESSAGE, ['data'=>$data,'importedDate'=>$importDate]);
|
||||
} catch (\Exception $exception){
|
||||
return $this->response('import invoice failed',$exception->getMessage(), ($exception->getCode()? $exception->getCode() : HttpStatus::SERVER_ERROR));
|
||||
}
|
||||
}
|
||||
|
||||
public function response(String $responseTitle, String $responseMessage, int $httpStatus, ?array $data = []) : JsonResponse {
|
||||
return (new ApiResponseObject($responseTitle, $responseMessage, $httpStatus, $data))->handler();
|
||||
}
|
||||
|
||||
private function mappingTopUp(Array $row, String $system) {
|
||||
try {
|
||||
if ($data = (App()->make(ChecksBillNumber::class))->execute($row['shipping_info'], $system)) {
|
||||
// if ($system == 'izyim' && isset($data['owner_reference'])) return $data;
|
||||
if ($system == 'izyim' && isset($data['owner_reference'])) return [$data['owner_reference'], null];
|
||||
|
||||
if ($system == 'exchange') return $this->updateTransactionOwnerReference($data, $row['doc_no']);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function mappingExchange(Array $row) {
|
||||
$date = $row['date'];
|
||||
$transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('owner_reference', $row['shipping_info'])->first();
|
||||
|
||||
if ($transaction && $transaction->count() == 0) {
|
||||
$transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where('statement_transactions.amount', $row['net_total'])->whereRaw("DATE(posting_date) = '$date'")->first();
|
||||
}
|
||||
|
||||
if ($transaction && $transaction->count() == 0) {
|
||||
$transaction = Transaction::getReceiverWithJoinStatementTransactionAndOwner($row)->select('transactions.*')->where(DB::raw('FLOOR(statement_transactions.amount)'), floor($row['net_total']))->whereRaw("DATE(posting_date) = '$date'")->first();
|
||||
}
|
||||
|
||||
if ($transaction && $transaction->count() > 0) {
|
||||
return $this->updateTransactionOwnerReference($transaction, $row['doc_no']);
|
||||
}
|
||||
return [false, false];
|
||||
}
|
||||
|
||||
public function updateTransactionOwnerReference($transaction, String $docNo) {
|
||||
$transactionOwner = $transaction->transaction_owner;
|
||||
if ($transactionOwner) {
|
||||
$transactionOwner->update([
|
||||
'invoice_reference'=>$docNo,
|
||||
'status'=>ApprovalStatus::COMPLETED
|
||||
]);
|
||||
return [$transactionOwner->owner_reference, $transaction->created_at];
|
||||
}
|
||||
return [false, false];
|
||||
}
|
||||
|
||||
public function changeExcelDate($date)
|
||||
{
|
||||
$unixTime = (($date - 25569) * 86400);
|
||||
|
||||
@@ -2,24 +2,40 @@
|
||||
|
||||
namespace App\Http\Controllers\Imports;
|
||||
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Imports\Services\GenericImport;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Segment;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Models\Company;
|
||||
use App\Models\Segment;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\SeasonalSegment;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use App\Models\StatementTransactionOwner;
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\Modules\Imports\Services\GenericImport;
|
||||
use App\Classes\ValueObjects\Response\ApiResponseObject;
|
||||
use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment;
|
||||
use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor;
|
||||
use App\Models\Company;
|
||||
use App\Models\SeasonalSegment;
|
||||
use App\Models\Transaction;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject;
|
||||
|
||||
class ImportStatementReceiptsController
|
||||
{
|
||||
private $responseTitle;
|
||||
private $responseMessage;
|
||||
|
||||
private $removeStr = 'Payment for ';
|
||||
|
||||
public function __construct() {
|
||||
$this->responseTitle = 'Import Receipt Mapping';
|
||||
$this->responseMessage = 'You have successfully imported receipt mapping';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return array
|
||||
@@ -27,20 +43,74 @@ class ImportStatementReceiptsController
|
||||
*/
|
||||
public function import(Request $request)
|
||||
{
|
||||
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
|
||||
$file = json_decode($object->getFiles()[0])->file_info->original->file;
|
||||
try {
|
||||
$importDate = date('Y-m-d H:i:s');
|
||||
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
|
||||
$file = json_decode($object->getFiles()[0])->file_info->original->file;
|
||||
|
||||
$import = new GenericImport();
|
||||
Excel::import($import, $file);
|
||||
$excelRows = $import->rows;
|
||||
$excelRows = $excelRows->toArray();
|
||||
$import = new GenericImport();
|
||||
Excel::import($import, $file);
|
||||
$excelRows = $import->rows;
|
||||
$excelRows = $excelRows->toArray();
|
||||
|
||||
foreach ($excelRows as $row) {
|
||||
// if has date column
|
||||
// $transactionDate = $this->changeExcelDate($row['date']);
|
||||
$data = [];
|
||||
foreach ($excelRows as $row) {
|
||||
$row['mapped_result_reference'] = null;
|
||||
$row['mapped_status'] = 'failed';
|
||||
$row['date'] = in_array(gettype($row['doc_date']), ['integer', 'double']) ? $this->changeExcelDate($row['doc_date']) : date('Y-m-d', strtotime($row['doc_date']));
|
||||
|
||||
if ($invRefer = $this->getInvoiceReference($row['description'])) {
|
||||
$returnReference = $this->mappingExchange($invRefer, $row['doc_no']);
|
||||
if ($returnReference) {
|
||||
$row['mapped_result_reference'] = $returnReference;
|
||||
$row['mapped_status'] = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
TransactionMappingLog::create([
|
||||
'imported_date'=>$importDate,
|
||||
'type' => 'receipts',
|
||||
'data'=>$row,
|
||||
]);
|
||||
array_push($data, $row);
|
||||
}
|
||||
|
||||
return $this->response($this->responseTitle, $this->responseMessage, HttpStatus::OK_WITH_MESSAGE, ['data'=>$data,'importedDate'=>$importDate]);
|
||||
} catch (\Exception $exception){
|
||||
return $this->response('import invoice failed',$exception->getMessage(), ($exception->getCode()? $exception->getCode() : HttpStatus::SERVER_ERROR));
|
||||
}
|
||||
}
|
||||
|
||||
private function getInvoiceReference($invRefer) {
|
||||
$arrStr = explode($this->removeStr, $invRefer);
|
||||
if (isset($arrStr[1])) return $arrStr[1];
|
||||
return null;
|
||||
}
|
||||
|
||||
public function response(String $responseTitle, String $responseMessage, int $httpStatus, ?array $data = []) : JsonResponse {
|
||||
return (new ApiResponseObject($responseTitle, $responseMessage, $httpStatus, $data))->handler();
|
||||
}
|
||||
|
||||
private function mappingExchange($invRefer, $docNo) {
|
||||
$transactionOwner = StatementTransactionOwner::where('invoice_reference',$invRefer)->whereNull('receipt_reference')->where('status', ApprovalStatus::COMPLETED)->first();
|
||||
|
||||
if ($transactionOwner) {
|
||||
return $this->updateTransactionOwnerReference($transactionOwner, $docNo);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateTransactionOwnerReference($transactionOwner, String $docNo) {
|
||||
if ($transactionOwner) {
|
||||
$transactionOwner->update([
|
||||
'receipt_reference'=>$docNo,
|
||||
'status'=>ApprovalStatus::COMPLETED
|
||||
]);
|
||||
return $transactionOwner->owner_reference;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function changeExcelDate($date)
|
||||
{
|
||||
$unixTime = (($date - 25569) * 86400);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\Transactions;
|
||||
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\ImportPurchaseOrderTransactionLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
||||
class ImportPurchaseOrderTransactionController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ImportPurchaseOrderTransactionLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function import(Request $request, ImportPurchaseOrderTransactionLogic $logic) : JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,10 @@ class BankStatementDetailResource extends JsonResource
|
||||
'id' => $this->id,
|
||||
'date' => Carbon::parse($transaction->posting_date)->format('Y-m-d'),
|
||||
'transaction_description_1' => $transaction->transaction_description,
|
||||
'transaction_description_2' => $transaction->transaction_description_2,
|
||||
'transaction_description_3' => $transaction->transaction_description_3,
|
||||
'transaction_description_4' => $transaction->transaction_description_4,
|
||||
'transaction_description_5' => $transaction->transaction_description_5,
|
||||
'pay_for' => $transaction->transaction_description_2,
|
||||
'system_references' => $this->system,
|
||||
'amount' => $transaction->amount,
|
||||
|
||||
@@ -28,7 +28,7 @@ class BankStatementTransactionOwnerResource extends JsonResource
|
||||
}
|
||||
|
||||
if($this->type === StatementTransactionOwnerType::WALLET_TOP_UP){
|
||||
$referenceLink = route('booking.details', $this->owner_reference);
|
||||
$referenceLink = route('wallet.details', $this->owner_reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ class BankStatementTransactionResource extends JsonResource
|
||||
'owners' => [
|
||||
'approved' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::APPROVED])->get()),
|
||||
'pending_verification' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION])->get()),
|
||||
'rejected' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::REJECTED])->get())
|
||||
'rejected' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::REJECTED])->get()),
|
||||
'completed' => BankStatementTransactionOwnerResource::collection($this->owners()->whereIn('status', [ApprovalStatus::COMPLETED])->get()),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ class TransactionDetailResource extends JsonResource
|
||||
{
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'stockCode' => $this->product_code,
|
||||
'description' => $this->product_name,
|
||||
'quantity' => $this->quantity,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class TransactionMappingLogResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'imported_date' => $this->imported_date,
|
||||
'type' => $this->type
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ class AccountStatement extends Model
|
||||
'total_amount',
|
||||
'begin_balance',
|
||||
'end_balance',
|
||||
'total_rows',
|
||||
'mapped_rows',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
|
||||
+19
-7
@@ -109,7 +109,7 @@ class Company extends AbstractModel implements Documentable
|
||||
{
|
||||
return $this->hasManyDeep(Transaction::class, [Booking::class], ['company_id', 'owner_id'], ['id', 'id']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return HasMany
|
||||
*/
|
||||
@@ -130,13 +130,25 @@ class Company extends AbstractModel implements Documentable
|
||||
* @return Builder
|
||||
*/
|
||||
public function services(): Builder {
|
||||
return ServiceType::where('status', ApprovalStatus::APPROVED)->whereHas('constants', function($query) {
|
||||
$query->Where(function($query){
|
||||
$query->where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->is_active', true);
|
||||
})->orWhere(function($query) {
|
||||
$query->where('reference', SegmentConstants::CUSTOM_SERVICE_TYPE)->where('detail->is_active', true)->whereIn('segment_id', $this->segments->pluck('id'));
|
||||
|
||||
if ($this->business_type === 3) {
|
||||
return ServiceType::where('status', ApprovalStatus::APPROVED)->whereHas('constants', function($query) {
|
||||
$query->where(function($query) {
|
||||
$query->where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->is_active', true);
|
||||
})->orWhere(function($query) {
|
||||
$query->where('reference', SegmentConstants::CUSTOM_SERVICE_TYPE)->where('detail->is_active', true);
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Existing logic for other company types
|
||||
return ServiceType::where('status', ApprovalStatus::APPROVED)->whereHas('constants', function($query) {
|
||||
$query->Where(function($query){
|
||||
$query->where('reference', SegmentConstants::SERVICE_TYPE)->where('detail->is_active', true);
|
||||
})->orWhere(function($query) {
|
||||
$query->where('reference', SegmentConstants::CUSTOM_SERVICE_TYPE)->where('detail->is_active', true)->whereIn('segment_id', $this->segments->pluck('id'));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function servicesConfigurations(): Collection {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
|
||||
class StatementTransaction extends Model
|
||||
{
|
||||
@@ -47,4 +48,16 @@ class StatementTransaction extends Model
|
||||
{
|
||||
return $this->hasMany(StatementTransactionOwner::class);
|
||||
}
|
||||
|
||||
public function owner_status()
|
||||
{
|
||||
return $this->owners()->whereIn('status',[ApprovalStatus::APPROVED,ApprovalStatus::COMPLETED,ApprovalStatus::PENDING_VERIFICATION]);
|
||||
}
|
||||
|
||||
public function scopeDoesntMapStatement($query)
|
||||
{
|
||||
$query->whereDoesntHave('owners', function($query){
|
||||
return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})->orderBy('posting_date');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class StatementTransactionOwner extends Model
|
||||
{
|
||||
@@ -21,9 +22,20 @@ class StatementTransactionOwner extends Model
|
||||
'receipt_reference',
|
||||
'status',
|
||||
];
|
||||
|
||||
public function owner(): morphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function transaction(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(StatementTransaction::class, 'statement_transaction_id', 'id');
|
||||
}
|
||||
|
||||
public function scopeGetSiblingsOwner($query) {
|
||||
$query->where('system', $this->system)
|
||||
->where('owner_type', $this->owner_type)
|
||||
->where('owner_id', $this->owner_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Staudenmeir\EloquentHasManyDeep\HasTableAlias;
|
||||
use App\Models\StatementTransactionOwner;
|
||||
|
||||
|
||||
class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable
|
||||
@@ -53,6 +54,14 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
|
||||
return $this->MorphOne(Transaction::class, 'owner')->where('type', TransactionType::CREDIT_NOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
|
||||
*/
|
||||
public function transaction_owner()
|
||||
{
|
||||
return $this->MorphOne(StatementTransactionOwner::class, 'owner','owner_type','owner_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
@@ -69,6 +78,16 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
|
||||
return $this->BelongsTo( Company::class, 'issuer', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user that owns the Transaction
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function receiverCompany(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Company::class, 'receiver', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
@@ -202,6 +221,22 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
|
||||
return $query->whereIn('status', [ApprovalStatus::APPROVED]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopeGetReceiverWithJoinStatementTransactionAndOwner(Builder $query, Array $row) {
|
||||
$query->join('companies',function($q) use ($row) {
|
||||
$q->on('companies.id','=','transactions.receiver');
|
||||
$q->where('debtor',$row['debtor_code']);
|
||||
})
|
||||
->join('statement_transaction_owners', function ($q) {
|
||||
$q->on('statement_transaction_owners.owner_id','=','transactions.id');
|
||||
$q->where('statement_transaction_owners.owner_type','=',Transaction::class);
|
||||
})
|
||||
->join('statement_transactions','statement_transactions.id','=','statement_transaction_owners.statement_transaction_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MorphMany
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TransactionMappingLog extends Model
|
||||
{
|
||||
protected $fillable = ['imported_by','data','imported_date','type'];
|
||||
|
||||
protected $casts = [
|
||||
'data' => 'array',
|
||||
];
|
||||
|
||||
public static function boot() {
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($model) {
|
||||
$model->imported_by = auth()->user()->id;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,6 +104,10 @@ return [
|
||||
'path' => storage_path('logs/regenerateInvoice.log'),
|
||||
'level' => 'info',
|
||||
],
|
||||
'guzzleShippingPortal' => [
|
||||
'driver' => 'errorlog',
|
||||
'level' => 'debug',
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateTransactionMappingLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('transaction_mapping_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->bigInteger('imported_by')->unsigned();
|
||||
$table->foreign('imported_by')->references('id')->on('users');
|
||||
$table->dateTime('imported_date')->nullable();
|
||||
$table->text('data')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('transaction_mapping_logs');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddMappedRateToAccountStatementsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('account_statements', function (Blueprint $table) {
|
||||
$table->integer('total_rows')->unsigned()->default(0)->after('end_balance');
|
||||
$table->integer('mapped_rows')->unsigned()->default(0)->after('end_balance');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('account_statements', function (Blueprint $table) {
|
||||
$table->dropColumn('total_rows');
|
||||
$table->dropColumn('mapped_rows');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddTypeToTransactionMappingLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('transaction_mapping_logs', function (Blueprint $table) {
|
||||
$table->string('type',50)->default('invoices')->after('imported_date');
|
||||
});
|
||||
|
||||
foreach (DB::table('transaction_mapping_logs')->get() as $key => $value) {
|
||||
$data = json_decode($value->data);
|
||||
DB::table('transaction_mapping_logs')->where('id',$value->id)->update([
|
||||
'type' => (isset($data->description) ? 'receipts' : 'invoices')
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('transaction_mapping_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('type');
|
||||
});
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -77,6 +77,13 @@
|
||||
import { required } from "vuelidate/lib/validators";
|
||||
|
||||
export default {
|
||||
props:{
|
||||
editMapped: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
error: '',
|
||||
@@ -116,6 +123,8 @@
|
||||
system_references : this.system_references ? this.system_references.toLowerCase() : '',
|
||||
transaction_reference : this.transaction_reference
|
||||
};
|
||||
|
||||
if (this.editMapped) this.parameters['editMapped'] = true;
|
||||
|
||||
this.submit(this.route('api.accounting.statement.details.update', this.data.id), 'put', this.section, true, true);
|
||||
},
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="row m-b-10 parentContainer">
|
||||
<div class="col">
|
||||
<div class="row p-b-10 b-b b-grey">
|
||||
<div class="col-2">{{ item.imported_date }}</div>
|
||||
<div class="col-2">
|
||||
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped(item.imported_date)">
|
||||
Download Invoices Mapped
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
export default {
|
||||
props: {
|
||||
stage: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
downloadInvoiceMapped(importedDate) {
|
||||
var arrDateTime = importedDate.split(" ");
|
||||
const fileName = 'InvoiceMapped';
|
||||
|
||||
window.open(this.route('importedInvoiceMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="row m-b-10 parentContainer">
|
||||
<div class="col">
|
||||
<div class="row p-b-10 b-b b-grey">
|
||||
<div class="col-2">{{ item.imported_date }}</div>
|
||||
<div class="col-2">
|
||||
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped(item.imported_date)">
|
||||
Download Receipts Mapped
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
export default {
|
||||
props: {
|
||||
stage: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
downloadInvoiceMapped(importedDate) {
|
||||
var arrDateTime = importedDate.split(" ");
|
||||
const fileName = 'ReceiptMapped';
|
||||
|
||||
window.open(this.route('importedReceiptMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
+76
-4
@@ -4,6 +4,8 @@
|
||||
<div class="row p-b-10 b-b b-grey">
|
||||
<div class="col-2">{{ item.posting_date }}</div>
|
||||
<div class="col-2">{{ item.transaction_description_1 + ' - ' + item.transaction_description_2 }}</div>
|
||||
|
||||
<!-- Mapping Approval tab -->
|
||||
<div class="col-5" v-if="item.owners.pending_verification.length === 1">
|
||||
<div class="row">
|
||||
<div class="col">{{item.owners.pending_verification[0].system}}</div>
|
||||
@@ -11,6 +13,47 @@
|
||||
<div class="col"><a :href="item.owners.pending_verification[0].reference_link" target="_blank">{{item.owners.pending_verification[0].reference}}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pending Export tab -->
|
||||
<div class="col-5" v-if="item.owners.approved.length === 1">
|
||||
<div class="row">
|
||||
<div class="col">{{item.owners.approved[0].system}}</div>
|
||||
<div class="col">{{ typeString(item.owners.approved[0].type) }}</div>
|
||||
<div class="col">
|
||||
<div class="col d-flex justify-content-between">
|
||||
<a :href="item.owners.approved[0].reference_link" target="_blank">{{item.owners.approved[0].reference}}</a>
|
||||
<div v-if="stage === 4">
|
||||
<!-- revert button -->
|
||||
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="approveCorrectMappingTransaction">
|
||||
<i class="fa fa-times fa-fw"></i>
|
||||
</button>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" type="approveCorrectMappingTransaction">
|
||||
<general-confirmation-form-component
|
||||
:contentText="returnTextRevert(item.owners.approved[0].reference)"
|
||||
modalType="confirm"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.accounting.bankStatement.details.status.update', item.owners.approved[0].id, 'pending_verification')"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
<!-- edit button -->
|
||||
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5 requestModal" data-type="updateOwner">
|
||||
<i class="fa fa-edit"></i>
|
||||
</button>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="updateOwner">
|
||||
<edit-single-item-in-list-component :data="item" :section="section" editMapped="true"></edit-single-item-in-list-component>
|
||||
</modal-component>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mapping Review tab -->
|
||||
<div class="col-5" v-if="item.owners.pending_verification.length > 1">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@@ -31,7 +74,7 @@
|
||||
<div class="row parentContainer" v-for="owner in item.owners.pending_verification">
|
||||
<div class="col d-flex justify-content-between">
|
||||
<a :href="owner.reference_link" target="_blank">{{ owner.reference }}</a>
|
||||
<div v-if="stage === 2">
|
||||
<div v-if="stage === 2" style="display: flex;">
|
||||
<button class="btn btn-xs btn-outline-primary b-rad-none m-r-5 requestModal" data-type="approveCorrectMappingTransaction">
|
||||
<i class="fa fa-check fa-fw"></i>
|
||||
</button>
|
||||
@@ -46,13 +89,30 @@
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
|
||||
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="revertPendingMappingTransaction">
|
||||
<i class="fa fa-times fa-fw"></i>
|
||||
</button>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" type="revertPendingMappingTransaction">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to reject this mapping?"
|
||||
modalType="delete"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.accounting.statement_transaction.owner.status.update', owner.id, 'reject')"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5" v-if="!item.owners.pending_verification.length">
|
||||
|
||||
<!-- unknow tab -->
|
||||
<div class="col-5" v-if="!item.owners.pending_verification.length && !item.owners.approved.length">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5 requestModal" data-type="updateOwner">
|
||||
@@ -81,7 +141,13 @@
|
||||
|
||||
</div>
|
||||
<div class="col-1">{{ item.amount }}</div>
|
||||
<div class="col-1 text-success" v-if="item.owners.approved.length">{{ [6, 7, 8, 9, 10, 11, 12, 13, 14].include(item.owners.approved[0].type) ? 'Miscellaneous' : 'Approved' }}</div>
|
||||
<div class="col-1 text-success" v-if="item.owners.approved.length">{{ [6, 7, 8, 9, 10, 11, 12, 13, 14].includes(item.owners.approved[0].type) ? 'Miscellaneous' : 'Approved' }}</div>
|
||||
|
||||
<!-- Pending Export tab for checkbox here -->
|
||||
<div class="col-1" v-if="item.owners.approved.length === 1">
|
||||
<input type="checkbox" class="request_export_item" v-model="selectAll" :value="item.id">
|
||||
</div>
|
||||
|
||||
<div class="col-1 text-danger" v-if="!item.owners.approved.length">Pending...</div>
|
||||
<div class="col-1" v-if="stage === 1">
|
||||
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="deleteMappingTransaction">
|
||||
@@ -92,7 +158,7 @@
|
||||
contentText="Are you sure you want to reject this mapping?"
|
||||
modalType="delete"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.accounting.statement_transaction.owner.status.update', item.id, 'reject')"
|
||||
:apiRoute="route('api.accounting.statement_transaction.owner.status.update', item.owners.pending_verification[0].id, 'reject')"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
@@ -117,6 +183,9 @@
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
selectAll: {
|
||||
type:Boolean
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -154,6 +223,9 @@
|
||||
},
|
||||
returnTextWithVariable(variable) {
|
||||
return "Are you sure you want to choose this mapping " + variable + "?";
|
||||
},
|
||||
returnTextRevert(variable) {
|
||||
return "Are you sure you want to revert this mapping " + variable + "?";
|
||||
}
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div class="row m-b-10 parentContainer">
|
||||
<div class="col">
|
||||
<div class="row p-b-10 b-b b-grey">
|
||||
<div class="col-2">{{ item.posting_date }}</div>
|
||||
<div class="col-2">{{ item.transaction_description_1 + ' - ' + item.transaction_description_2 }}</div>
|
||||
<div class="col-7">
|
||||
<div class="row">
|
||||
<div class="col">{{item.owners.completed[0].system}}</div>
|
||||
<div class="col">{{ typeString(item.owners.completed[0].type) }}</div>
|
||||
<div class="col"><a :href="item.owners.completed[0].reference_link" target="_blank">{{item.owners.completed[0].reference}}</a></div>
|
||||
<div class="col">{{item.owners.completed[0].invoice_reference}}</div>
|
||||
<div class="col">{{item.owners.completed[0].receipt_reference}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-1">{{ item.amount }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
export default {
|
||||
props: {
|
||||
stage: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
typeString(type){
|
||||
switch(type) {
|
||||
case 1:
|
||||
return 'Sales';
|
||||
case 2:
|
||||
return 'Wallet Top Up';
|
||||
case 3:
|
||||
return 'Wallet Withdrawal';
|
||||
case 4:
|
||||
return 'Payment Refund';
|
||||
case 5:
|
||||
return 'Supplier Payment';
|
||||
case 6:
|
||||
return 'Internal Bank Transfer Out';
|
||||
case 7:
|
||||
return 'Internal Bank Transfer In';
|
||||
case 8:
|
||||
return 'Salary Payment';
|
||||
case 9:
|
||||
return 'Statutory Payment';
|
||||
case 10:
|
||||
return 'FPX Charges';
|
||||
case 11:
|
||||
return 'FPX Charges Refund';
|
||||
case 12:
|
||||
return 'Bank Charges';
|
||||
case 13:
|
||||
return 'Credit Card Payment';
|
||||
case 14:
|
||||
return 'Non-Operational Payment';
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<div class="row h-100 parentContainer">
|
||||
<div class="col-12" style="min-height: 20px;">
|
||||
<loading-component style="height: 20px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>{{ componentTitle }}</h3>
|
||||
<div class="row m-b-10 animate__animated animate__fadeInUpBig animate__fast" v-if="error">
|
||||
<div class="col">
|
||||
<small class="bold fs-10 text-danger">{{error}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped">
|
||||
Download Invoices Mapped
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<div class="card-body table-responsive p-0">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="item in tableHeaders">{{ item }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-show="!isLoading">
|
||||
<tr v-for="(item, index) in $store.getters.getListData(section)">
|
||||
<td>{{index+1}}</td>
|
||||
<td>{{item.doc_no }}</td>
|
||||
<td>{{item.date}}</td>
|
||||
<td>{{item.debtor_code }}}</td>
|
||||
<td>{{item.debtor_name}}</td>
|
||||
<td>{{item.shipping_info}}</td>
|
||||
<td>{{item.net_total}}</td>
|
||||
<td>{{item.cancelled}}</td>
|
||||
<td>{{item.mapped_status}}</td>
|
||||
<td>{{item.mapped_result_reference}}</td>
|
||||
<td>{{item.payment_received_date}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
<div class="card-footer">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<pagination-component :section="section" class="mb-5" ref="pagination"></pagination-component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
files: {
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
error: '',
|
||||
importedDate: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pendingQueue() {
|
||||
return this.$store.getters.isInCompleteQueue(this.section);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pendingQueue(inComplete, oldValue){
|
||||
if(inComplete){
|
||||
this.importInvoice();
|
||||
}
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.appendComponentTitle();
|
||||
this.appendComponentTableHeader();
|
||||
this.$store.dispatch('updateListQueue', {'name': this.section});
|
||||
},
|
||||
methods: {
|
||||
appendComponentTitle() {
|
||||
this.componentTitle = 'Imported Invoices Mapped';
|
||||
},
|
||||
appendComponentTableHeader() {
|
||||
this.tableHeaders = ['No','Doc No','Date','Debtor Code','Debtor Name','Shipping Info','Net Total','Cancelled','Mapped Status','Mapped Reference No','Payment Received Date'];
|
||||
},
|
||||
importInvoice(){
|
||||
this.isLoading = true;
|
||||
this.parameters = {
|
||||
files: this.files
|
||||
};
|
||||
this.submit(this.route('api.import_invoices.upload'), 'post', this.section, true, false);
|
||||
},
|
||||
|
||||
successHandler(response){
|
||||
this.$store.dispatch('completeList', {'name': this.section, 'data': response.payload.data});
|
||||
this.importedDate = response.payload.importedDate;
|
||||
this.isLoading = false;
|
||||
},
|
||||
|
||||
errorHandler(error){
|
||||
this.isLoading = false;
|
||||
this.error = error.message;
|
||||
},
|
||||
|
||||
downloadInvoiceMapped() {
|
||||
var arrDateTime = this.importedDate.split(" ");
|
||||
const fileName = 'importInvoiceMapping';
|
||||
|
||||
window.open(this.route('importedInvoiceMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div class="row h-100 parentContainer">
|
||||
<div class="col-12" style="min-height: 20px;">
|
||||
<loading-component style="height: 20px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>{{ componentTitle }}</h3>
|
||||
<div class="row m-b-10 animate__animated animate__fadeInUpBig animate__fast" v-if="error">
|
||||
<div class="col">
|
||||
<small class="bold fs-10 text-danger">{{error}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped">
|
||||
Download Receipts Mapped
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<div class="card-body table-responsive p-0">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="item in tableHeaders">{{ item }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-show="!isLoading">
|
||||
<tr v-for="(item, index) in $store.getters.getListData(section)">
|
||||
<td>{{index+1}}</td>
|
||||
<td>{{item.check }}</td>
|
||||
<td>{{item.doc_no}}</td>
|
||||
<td>{{item.doc_date }}}</td>
|
||||
<td>{{item.debtor_code}}</td>
|
||||
<td>{{item.company_name}}</td>
|
||||
<td>{{item.description}}</td>
|
||||
<td>{{item.payment_amount}}</td>
|
||||
<td>{{item.created_user}}</td>
|
||||
<td>{{item.curr}}</td>
|
||||
<td>{{item.to_home_rate}}</td>
|
||||
<td>{{item.local_payment_amount}}</td>
|
||||
<td>{{item.cancelled}}</td>
|
||||
<td>{{item.mapped_status}}</td>
|
||||
<td>{{item.mapped_result_reference}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
<div class="card-footer">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<pagination-component :section="section" class="mb-5" ref="pagination"></pagination-component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
files: {
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
error: '',
|
||||
importedDate: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pendingQueue() {
|
||||
return this.$store.getters.isInCompleteQueue(this.section);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pendingQueue(inComplete, oldValue){
|
||||
if(inComplete){
|
||||
this.importInvoice();
|
||||
}
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.appendComponentTitle();
|
||||
this.appendComponentTableHeader();
|
||||
this.$store.dispatch('updateListQueue', {'name': this.section});
|
||||
},
|
||||
methods: {
|
||||
appendComponentTitle() {
|
||||
this.componentTitle = 'Imported Receipts Mapped';
|
||||
},
|
||||
appendComponentTableHeader() {
|
||||
this.tableHeaders = ['Check','Doc No','Doc Date','Debtor Code','Company Name','Description','Payment Amount','Created User','Curr.','To Home Rate','Local Payment Amount','Cancelled','Mapped Status','Mapped Reference No'];
|
||||
},
|
||||
importInvoice(){
|
||||
this.isLoading = true;
|
||||
this.parameters = {
|
||||
files: this.files
|
||||
};
|
||||
this.submit(this.route('api.import_receipts.upload'), 'post', this.section, true, false);
|
||||
},
|
||||
|
||||
successHandler(response){
|
||||
this.$store.dispatch('completeList', {'name': this.section, 'data': response.payload.data});
|
||||
this.importedDate = response.payload.importedDate;
|
||||
this.isLoading = false;
|
||||
},
|
||||
|
||||
errorHandler(error){
|
||||
this.isLoading = false;
|
||||
this.error = error.message;
|
||||
},
|
||||
|
||||
downloadInvoiceMapped() {
|
||||
var arrDateTime = this.importedDate.split(" ");
|
||||
const fileName = 'ReceiptMapped';
|
||||
|
||||
window.open(this.route('importedReceiptMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1]+'&fileName='+fileName, '_blank');
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="justify-content-center align-items-center m-t-50 m-b-50" v-show="step === 0">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<div class="row text-center">
|
||||
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getReportFilter()">Mapped Report</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row text-center">
|
||||
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedInvReport()">History Imported Invoices Report</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row text-center">
|
||||
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedRecReport()">History Imported Receipts Report</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="step > 0 && report == 'mappedRecords'">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="justify-content-center align-items-center m-t-50 m-b-50">
|
||||
<div class="row mb-3">
|
||||
<div class="col-4">
|
||||
<validation-wrapper-component :validator="$v.parameters.owner_reference">
|
||||
<label class="text-primary">Reference</label>
|
||||
<input type="text" class="form-control" v-model="parameters.owner_reference">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<validation-wrapper-component :validator="$v.parameters.invoice_reference">
|
||||
<label class="text-primary">Invoice Reference</label>
|
||||
<input type="text" class="form-control" v-model="parameters.invoice_reference">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<validation-wrapper-component :validator="$v.parameters.receipt_reference">
|
||||
<label class="text-primary">Receipt Reference</label>
|
||||
<input type="text" class="form-control" v-model="parameters.receipt_reference">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row text-center">
|
||||
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getReportFilter()">Mapped Report</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="row p-t-10 p-b-10 b-b b-grey text-master-light">
|
||||
<div class="col-2">Date</div>
|
||||
<div class="col-2">Description</div>
|
||||
<div class="col-7">
|
||||
<div class="row">
|
||||
<div class="col">System</div>
|
||||
<div class="col">Type</div>
|
||||
<div class="col">Reference</div>
|
||||
<div class="col">Invoice Reference</div>
|
||||
<div class="col">Receipt Reference</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">Amount</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<list-component :key="step" ref="TransactionsMappedList" section="TransactionsMappedSection" :endpoint="route('api.accounting.bank.transaction')" :options="filter">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<statement-transaction-mapped-component :data="data" :section="section"></statement-transaction-mapped-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- report for imported Invoices -->
|
||||
<div class="row" v-if="step > 0 && report == 'importedInv'">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="justify-content-center align-items-center m-t-50 m-b-50">
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row text-center">
|
||||
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedInvReport()">History Imported Invoices Report</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="row p-t-10 p-b-10 b-b b-grey text-master-light">
|
||||
<div class="col-2">Date</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<list-component :key="step" ref="HistoryImportedInvList" section="HistoryImportedInvSection" :endpoint="route('api.accounting.history.imported')" :options="filter">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<history-imported-invoices :data="data" :section="section"></history-imported-invoices>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- report for imported Receipts -->
|
||||
<div class="row" v-if="step > 0 && report == 'importedRec'">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="justify-content-center align-items-center m-t-50 m-b-50">
|
||||
<div class="row">
|
||||
<div class="col-3">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="row text-center">
|
||||
<div class="col b-a b-grey padding-20 m-r-15 pointer bg-complete text-white" @click="getHistoryImportedRecReport()">History Imported Receipts Report</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="row p-t-10 p-b-10 b-b b-grey text-master-light">
|
||||
<div class="col-2">Date</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<list-component :key="step" ref="HistoryImportedRecList" section="HistoryImportedRecSection" :endpoint="route('api.accounting.history.imported')" :options="filter">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<history-imported-receipts :data="data" :section="section"></history-imported-receipts>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { required } from "vuelidate/lib/validators";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
parameters: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
owner_reference: '',
|
||||
invoice_reference: '',
|
||||
receipt_reference: ''
|
||||
},
|
||||
step: 0,
|
||||
filter: {},
|
||||
report: ''
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
startDate: {
|
||||
required
|
||||
},
|
||||
endDate: {
|
||||
required
|
||||
},
|
||||
owner_reference: {},
|
||||
invoice_reference: {},
|
||||
receipt_reference: {}
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.parameters.startDate = this.startDate();
|
||||
this.parameters.endDate = this.endDate();
|
||||
},
|
||||
methods: {
|
||||
startDate() {
|
||||
var date = new Date();
|
||||
return '01-'+(date.getMonth() + 1)+'-'+date.getFullYear();
|
||||
},
|
||||
endDate() {
|
||||
var date = new Date();
|
||||
var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
||||
return lastDay.getDate()+'-'+(lastDay.getMonth() + 1)+'-'+lastDay.getFullYear();
|
||||
},
|
||||
getReportFilter() {
|
||||
this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [3], per_page: 100, order_by: {column: 'posting_date', DESC: true}};
|
||||
|
||||
this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}};
|
||||
this.filter = {...this.filter, ...{statement_transaction_posting_end:this.parameters.endDate}}
|
||||
|
||||
if (typeof this.parameters.owner_reference != 'undefined' && this.parameters.owner_reference != '') this.filter = {...this.filter, ...{statement_transaction_owner_reference: this.parameters.owner_reference}};
|
||||
|
||||
if (typeof this.parameters.invoice_reference != 'undefined' && this.parameters.invoice_reference != '') this.filter = {...this.filter, ...{statement_transaction_invoice_reference: this.parameters.invoice_reference}};
|
||||
|
||||
if (typeof this.parameters.receipt_reference != 'undefined' && this.parameters.receipt_reference != '') this.filter = {...this.filter, ...{statement_transaction_receipt_reference: this.parameters.receipt_reference}};
|
||||
|
||||
this.step = this.step + 1;
|
||||
this.report = 'mappedRecords';
|
||||
},
|
||||
getHistoryImportedRecReport() {
|
||||
this.filter = {
|
||||
imported_date_from: this.parameters.startDate,
|
||||
imported_date_to:this.parameters.endDate,
|
||||
group_by_imported_date:true,
|
||||
type:'receipts'
|
||||
};
|
||||
this.step = this.step + 1;
|
||||
this.report = 'importedRec';
|
||||
},
|
||||
getHistoryImportedInvReport() {
|
||||
this.filter = {
|
||||
imported_date_from: this.parameters.startDate,
|
||||
imported_date_to:this.parameters.endDate,
|
||||
group_by_imported_date:true,
|
||||
type:'invoices'
|
||||
};
|
||||
this.step = this.step + 1;
|
||||
this.report = 'importedInv';
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
+12
-13
@@ -65,10 +65,12 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Date</th>
|
||||
<th>Posting Date</th>
|
||||
<th>Description 1</th>
|
||||
<th>Pay For</th>
|
||||
<th>System References</th>
|
||||
<th>Description 2</th>
|
||||
<th>Description 3</th>
|
||||
<th>Description 4</th>
|
||||
<th>Description 5</th>
|
||||
<th>Amount</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
@@ -76,11 +78,12 @@
|
||||
<tbody v-show="!isLoading">
|
||||
<tr v-for="item in $store.getters.getListData(section)" :key="item.id">
|
||||
<td>{{item.id}}</td>
|
||||
<td>{{item.date}}</td>
|
||||
<td v-if="item.transaction_description_1 != null">{{item.transaction_description_1 | truncate(30, '...')}}</td>
|
||||
<td v-if="item.transaction_description_1 == null"></td>
|
||||
<td>{{item.pay_for}}</td>
|
||||
<td>{{item.system_references}}</td>
|
||||
<td>{{item.posting_date}}</td>
|
||||
<td>{{item.transaction_description_1}}</td>
|
||||
<td>{{item.transaction_description_2}}</td>
|
||||
<td>{{item.transaction_description_3}}</td>
|
||||
<td>{{item.transaction_description_4}}</td>
|
||||
<td>{{item.transaction_description_5}}</td>
|
||||
<td>{{item.amount}}</td>
|
||||
<td>
|
||||
<a href="#">
|
||||
@@ -184,11 +187,7 @@ export default {
|
||||
},
|
||||
created(){
|
||||
this.setDecoratorDefault();
|
||||
if (this.statement === 0) {
|
||||
this.filters = { 'per_page': 10, order_by: {column: 'id', DESC: true} };
|
||||
} else {
|
||||
this.filters = { 'per_page': 10, order_by: {column: 'id', DESC: true}, 'has_account_statement_id': this.statement };
|
||||
}
|
||||
this.filters = { 'per_page': 10, order_by: {column: 'id', DESC: true} };
|
||||
this.$store.dispatch('updateListQueue', {'name': this.section, 'page': 1, 'filters': this.filters});
|
||||
},
|
||||
methods: {
|
||||
|
||||
+107
-17
@@ -55,7 +55,7 @@
|
||||
<div class="col"></div>
|
||||
<div class="col-auto pointer bold text-danger" @click="step=0">X</div>
|
||||
</div>
|
||||
<div class="row parentContainer" v-if="step > 0 && stage !== 4">
|
||||
<div class="row parentContainer" v-if="step > 0">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@@ -68,11 +68,38 @@
|
||||
class="text-center"
|
||||
:apiRoute="route('api.accounting.statement_transaction.owner.groupApprove')"
|
||||
apiMethod="post"
|
||||
:params="filter"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
|
||||
<!-- filter for Pending Export tab -->
|
||||
<div v-if="stage === 4">
|
||||
<div class="row pt-3 pb-3">
|
||||
<div class="col-5 col-md-3 ">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-5 col-md-3 ">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-2 col-md-auto">
|
||||
<div class="btn btn-lg btn-primary fs-11 w-100 h-100 d-flex justify-content-center align-items-center" @click="startMapping(4)">
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="row p-t-10 p-b-10 b-b b-grey text-master-light">
|
||||
@@ -86,19 +113,23 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">Amount</div>
|
||||
<div class="col-1" v-if="stage === 4"></div>
|
||||
<div class="col-1" v-if="stage === 4">Select <input type="checkbox" v-model="selectAll">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<list-component ref="bankTransactionsList" section="bankTransactionSection" :endpoint="route('api.accounting.bank.transaction')" :options="this.filter">
|
||||
|
||||
<list-component :key="stage" ref="bankTransactionsList" section="bankTransactionSection" :endpoint="route('api.accounting.bank.transaction')" :options="this.filter">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<statement-transaction-component :data="data" :section="section" :stage="stage"></statement-transaction-component>
|
||||
<statement-transaction-component :data="data" :section="section" :stage="stage" :selectAll="selectAll"></statement-transaction-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="stage === 4">
|
||||
<div class="row parentContainer" v-if="stage === 4">
|
||||
<div class="col">
|
||||
<div class="row text-center m-t-50 m-b-50 p-t-50 p-b-50" v-show="exportStage === 0">
|
||||
<div class="col">
|
||||
@@ -122,7 +153,7 @@
|
||||
</file-input-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn btn-lg btn-primary m-t-20" @click="importInvoice">Import Invoices</div>
|
||||
<div class="btn btn-lg btn-primary m-t-20 requestModal" data-type="ModalImportInvoice" @click="importInvoice">Import Invoices</div>
|
||||
<!-- todo-new: delete later --><br><div class="btn btn-lg btn-primary m-t-20" @click="exportStage++">Nest Step</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
@@ -130,11 +161,19 @@
|
||||
<a href="https://docs.google.com/presentation/d/1XwKcdBCpHQSCQmsgnUHsypcqk5kdc8uZMqkjW9JXiw4/edit?usp=sharing" target="_blank">Learn How to do this step?</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="ModalImportInvoice">
|
||||
<imported-invoice-mapped-component section="importInvoiceMapping" v-if="invMappedTrue" :files="files"></imported-invoice-mapped-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row text-center m-t-50 m-b-50 p-t-50 p-b-50" v-show="exportStage === 2">
|
||||
<div class="col">
|
||||
<div class="btn btn-lg btn-primary" @click="exportStage++">Export Receipts To AutoCount</div>
|
||||
<div class="btn btn-lg btn-primary" @click="exportReceiptToAutoCount">Export Receipts To AutoCount</div>
|
||||
<!-- todo-new: delete later --><br><div class="btn btn-lg btn-primary m-t-20" @click="exportStage++">Nest Step</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@@ -153,7 +192,7 @@
|
||||
</file-input-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn btn-lg btn-primary m-t-20" @click="importReceipts">Import Receipts</div>
|
||||
<div class="btn btn-lg btn-primary m-t-20 requestModal" data-type="ModalImportReceipt" @click="importReceipts">Import Receipts</div>
|
||||
<!-- todo-new: delete later --><br><div class="btn btn-lg btn-primary m-t-20" @click="exportStage++">Nest Step</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
@@ -161,6 +200,13 @@
|
||||
<a href="https://docs.google.com/presentation/d/1xMiWjU1hqPaihMhbgflFSDsu1sC_0Lk7OFmwDaXVt-w/edit?usp=sharing" target="_blank">Learn How to do this step?</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="ModalImportReceipt">
|
||||
<imported-receipt-mapped-component section="importReceiptMapping" v-if="recMappedTrue" :files="files"></imported-receipt-mapped-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row text-center m-t-50 m-b-50 p-t-50 p-b-50" v-show="exportStage === 4">
|
||||
@@ -182,6 +228,10 @@ export default {
|
||||
|
||||
data(){
|
||||
return {
|
||||
parameters: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
},
|
||||
type: null,
|
||||
stage: null,
|
||||
exportStage: 0,
|
||||
@@ -190,28 +240,59 @@ export default {
|
||||
files: [],
|
||||
parameters: {},
|
||||
section: 'bankTransactionSection',
|
||||
invMappedTrue: false,
|
||||
recMappedTrue: false,
|
||||
selectAll: false,
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
startDate: {
|
||||
required
|
||||
},
|
||||
endDate: {
|
||||
required
|
||||
},
|
||||
},
|
||||
files: {
|
||||
// required // todo-new: set required if is pdf section
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
importInvoice(){
|
||||
this.parameters = {
|
||||
files: this.files
|
||||
};
|
||||
this.submit(this.route('api.import_invoices.upload'), 'post', this.section, true, false);
|
||||
this.invMappedTrue = true;
|
||||
},
|
||||
importReceipts(){
|
||||
this.parameters = {
|
||||
files: this.files
|
||||
};
|
||||
this.submit(this.route('api.import_receipts.upload'), 'post', this.section, true, false);
|
||||
this.recMappedTrue = true;
|
||||
},
|
||||
exportInvoiceToAutoCount(){
|
||||
window.open(this.route('invoiceTransactions.export'), '_blank');
|
||||
const checkedStatementTransactions = this.getCheckedStatementOwners();
|
||||
|
||||
let route = this.route('invoiceTransactions.export')+'?filter='+JSON.stringify(this.filter);
|
||||
if (checkedStatementTransactions) {
|
||||
route += '&bankStatementTransactionId='+checkedStatementTransactions;
|
||||
}
|
||||
|
||||
window.open(route, '_blank');
|
||||
},
|
||||
exportReceiptToAutoCount(){
|
||||
const checkedStatementTransactions = this.getCheckedStatementOwners();
|
||||
|
||||
this.filter['where_has_owners_and_null'] = 'statement_transaction_owners.receipt_reference';
|
||||
this.filter['where_has_owners_and_not_null'] = 'statement_transaction_owners.invoice_reference';
|
||||
let route = this.route('receiptTransactions.export')+'?filter='+JSON.stringify(this.filter);
|
||||
if (checkedStatementTransactions) {
|
||||
route += '&bankStatementTransactionId='+checkedStatementTransactions;
|
||||
}
|
||||
|
||||
window.open(route, '_blank');
|
||||
},
|
||||
getCheckedStatementOwners() {
|
||||
let bankStatementTransactionId = [];
|
||||
$('.request_export_item:checked').each(function() {
|
||||
bankStatementTransactionId.push($(this).val());
|
||||
});
|
||||
return (bankStatementTransactionId.length > 0 ? JSON.stringify(bankStatementTransactionId) : null);
|
||||
},
|
||||
successHandler(){
|
||||
this.step += 1;
|
||||
@@ -233,10 +314,14 @@ export default {
|
||||
this.filter = {min_amount: 0, is_mapped: true, is_mapped_with_multiple: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [1], per_page: 100, order_by: {column: 'posting_date', DESC: true}}
|
||||
break;
|
||||
case 3:
|
||||
this.filter = {min_amount: 0, is_mapped: false, per_page: 100, order_by: {column: 'posting_date', DESC: true}}
|
||||
this.filter = {min_amount: 0, is_mapped_false_or_mapped_but_status_in: [4], per_page: 100, order_by: {column: 'posting_date', DESC: true}}
|
||||
break;
|
||||
case 4:
|
||||
this.filter = {min_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [1, 2], statement_transaction_owner_status_in: [2], per_page: 100, order_by: {column: 'posting_date', DESC: true}}
|
||||
|
||||
if (typeof this.parameters.startDate != 'undefined' && this.parameters.startDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}};
|
||||
|
||||
if (typeof this.parameters.endDate != 'undefined' && this.parameters.endDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_end:this.parameters.endDate}};
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -254,6 +339,11 @@ export default {
|
||||
break;
|
||||
case 4:
|
||||
this.filter = {max_amount: 0, is_mapped: true, statement_transaction_owner_type_in: [3, 5], statement_transaction_owner_status_in: [2], per_page: 100, order_by: {column: 'posting_date', DESC: true}}
|
||||
|
||||
if (typeof this.parameters.startDate != 'undefined' && this.parameters.startDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_start: this.parameters.startDate}};
|
||||
|
||||
if (typeof this.parameters.endDate != 'undefined' && this.parameters.endDate != '') this.filter = {...this.filter, ...{statement_transaction_posting_end:this.parameters.endDate}};
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col d-none d-lg-block" v-if="$store.getters.isAdmin">
|
||||
<div class="col-auto d-none d-lg-block" v-if="$store.getters.isAdmin">
|
||||
<div class="font-heading fs-10 muted all-caps">Marking</div>
|
||||
<div class="font-heading">
|
||||
<a :href="route('customer.profile', item.company.reference)">{{this.item.company.reference}}</a>
|
||||
@@ -34,7 +34,7 @@
|
||||
<span class="flag-icon" :class="'flag-icon-'+item.convertible_currency.country.short_code.toLowerCase()"></span> {{this.item.convertible_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto d-none d-lg-block">
|
||||
<div class="col-3 d-none d-lg-block">
|
||||
<div class="font-heading fs-10 muted all-caps">Transfer Type</div>
|
||||
<div class="font-heading fs-12">{{this.item.service.name}}</div>
|
||||
</div>
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div class="row m-b-15">
|
||||
<div class="col-12">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="row m-l-0 m-r-0">
|
||||
<div class="col mb-2 mb-md-0 p-l-3 p-r-3 p-md-0">
|
||||
<validation-wrapper-component selectable :validator="$v.parameters.supplier">
|
||||
<label>Supplier</label>
|
||||
<selectable-component :disableOnFetch="true" :endpoint="route('api.company.list') + '?filters=' + JSON.stringify({'business_type': 3, 'status_in': [1, 2, 0]})" section="exportSupplierFilterSection" valueColumn="id" :labelColumn="['name']" v-model="parameters.supplier"></selectable-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col mb-2 mb-md-0 p-l-3 p-r-3 p-md-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col mb-2 mb-md-0 p-l-3 p-r-3 p-md-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-auto p-l-3 p-r-3 p-md-0">
|
||||
<div class="btn btn-lg btn-primary fs-11 w-100 h-100 d-flex justify-content-center align-items-center" @click="bulkDownloadWhiteForm()">
|
||||
<span>
|
||||
Export
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-center justify-content-center bg-white p-t-50 p-b-50 p-l-15 p-r-15 margin-15" v-if="returnData">
|
||||
<div class="col-10">
|
||||
<div class="row align-items-center justify-content-center hint-text">
|
||||
<div class="col-4 hint-text"><img src="/images/not-found-illustration.png" class="w-100 hint-text" /></div>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<div class="col">
|
||||
<div class="row m-t-20">
|
||||
<div class="col">
|
||||
<p class="all-caps no-margin fs-11" :class="[{'text-danger': returnData.status == 'Error'}]" style="letter-spacing: 2px;">{{ returnData.message }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentHandler from "../../../general/mixins/componentHandler";
|
||||
import { required } from "vuelidate/lib/validators";
|
||||
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
returnData: null,
|
||||
parameters: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
supplier: ''
|
||||
},
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
supplier: {
|
||||
required
|
||||
},
|
||||
startDate: {
|
||||
required
|
||||
},
|
||||
endDate: {
|
||||
required
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
bulkDownloadWhiteForm(){
|
||||
this.submit(this.route('api.suppliers.white_forms'), 'post', this.section, false, false);
|
||||
},
|
||||
successHandler(response) {
|
||||
this.isLoading = false;
|
||||
if (response.message) {
|
||||
this.returnData = response;
|
||||
} else {
|
||||
this.returnData = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-8 p-l-0">
|
||||
<small class="all-caps muted fs-10">Export Payment Transactions CSV</small>
|
||||
<download-billing-with-dates-component section="paymentsReportSection" ></download-billing-with-dates-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-8 p-l-0">
|
||||
<small class="all-caps muted fs-10">Download Zip White Form</small>
|
||||
<download-supplier-white-form-component section="paymentsReportSection" ></download-supplier-white-form-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col p-l-0">
|
||||
<small class="all-caps muted fs-10">Filter Supplier</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col padding-0">
|
||||
<validation-wrapper-component selectable :validator="$v.filterSupplier">
|
||||
<label>Supplier</label>
|
||||
<selectable-component :disableOnFetch="true" :endpoint="route('api.company.list') + '?filters=' + JSON.stringify({'business_type': 3, 'status_in': [1, 2, 0]})" section="supplierFilterSection" valueColumn="id" :labelColumn="['name']" v-model="filterSupplier"></selectable-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-2 p-l-0">
|
||||
<button type="button" class="btn btn-lg btn-complete fs-11 h-100 d-flex justify-content-center align-items-center" @click="reset()">Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col bg-white p-t-15 p-b-15">
|
||||
<div class="row no-margin">
|
||||
<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">Complete Payments</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<list-component key="2" section="paymentVerificationSection" :endpoint="route('api.transaction.list')" :options="{'type': 1, 'status': 3, 'payment_method_not_in': [4]}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<payment-verification-component section="paymentVerificationSection" :data="data" :no_action="true"></payment-verification-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">Complete Currency Orders</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<list-component :key="currencyOrderKey" section="completeTransactionGroupsListSection" :options="{'per_page': 20, 'status': 3, ...this.filterSupplier && {'issuer_in': [this.filterSupplier]}}" :endpoint="route('api.transaction.group.list')">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<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">Open Currency Orders</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<list-component :key="currencyOrderKey" section="transactionGroupsListSection" :options="{'per_page': 20, 'status_in': [0, 1, 2], ...this.filterSupplier && {'issuer_in': [this.filterSupplier]}}" :endpoint="route('api.transaction.group.list')">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<transaction-group-component section="transactionGroupsListSection" :data="data"></transaction-group-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
filterSupplier: "",
|
||||
currencyOrderKey: 1,
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
filterSupplier: {}
|
||||
},
|
||||
watch: {
|
||||
filterSupplier() {
|
||||
this.currencyOrderKey += 1;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reset() {
|
||||
this.filterSupplier = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
File diff suppressed because one or more lines are too long
@@ -289,6 +289,22 @@
|
||||
<regenerate-booking-invoices-component :data="booking" :section="section" class="text-center"></regenerate-booking-invoices-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="row m-t-10" v-if="$store.getters.isSuperAdmin">
|
||||
<div class="col-sm col-md-auto">
|
||||
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal" data-type="deleteTransfer">Delete Transfer</div>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" type="deleteTransfer">
|
||||
<general-confirmation-form-component
|
||||
contentText="Are you sure you want to delete this Order?"
|
||||
modalType="delete"
|
||||
class="text-center"
|
||||
:apiRoute="route('api.booking.payment.expire', booking.id)"
|
||||
apiMethod="post"
|
||||
:section="section"
|
||||
>
|
||||
</general-confirmation-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-5 mt-3 mt-sm-0">
|
||||
<booking-payment-quotation-component :data="booking" :section="section"></booking-payment-quotation-component>
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-b-5" @keyup.enter="submitSearch">
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.marking">
|
||||
<label class="all-caps">Marking</label>
|
||||
<!-- <input type="text" class="form-control" v-model="parameters.marking" :class="[{ 'not-allowed': hasMarkingParameter }]" :disabled="hasMarkingParameter"> -->
|
||||
<input type="text" class="form-control" v-model="parameters.marking" :class="[{ 'not-allowed': hasMarking }]" :disabled="hasMarking">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col col-md-auto d-flex justify-content-center align-items-center">
|
||||
<button type="button" class="btn btn-lg btn-primary fs-11 w-100"
|
||||
@click="submitSearch()">Download</button>
|
||||
</div>
|
||||
</div>
|
||||
<loading-component style="height: 100px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div class="row align-items-center justify-content-center bg-white p-t-50 p-b-50 p-l-15 p-r-15 margin-15" v-if="!isLoading && returnData">
|
||||
<div class="col-10">
|
||||
<div class="row align-items-center justify-content-center hint-text">
|
||||
<div class="col-4 hint-text"><img src="/images/not-found-illustration.png" class="w-100 hint-text" /></div>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<div class="col">
|
||||
<div class="row m-t-20">
|
||||
<div class="col">
|
||||
<p class="all-caps no-margin fs-11" :class="[{'text-danger': returnData.status == 'Error'}]" style="letter-spacing: 2px;">{{ returnData.message }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { required } from "vuelidate/lib/validators";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
key: 1,
|
||||
returnData: null,
|
||||
isLoading: false,
|
||||
hasMarking: false,
|
||||
parameters: {
|
||||
marking: null,
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
marking: { required },
|
||||
startDate: { required },
|
||||
endDate: { required },
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||
if (urlSearchParams.has('marking')) {
|
||||
this.parameters.marking = urlSearchParams.get('marking');
|
||||
}
|
||||
this.hasMarkingParameter();
|
||||
},
|
||||
methods: {
|
||||
submitSearch() {
|
||||
this.isLoading = true;
|
||||
this.submit(this.route('api.customers.invoices'), 'post', this.section, false, false);
|
||||
},
|
||||
errorHandler(error) {
|
||||
this.isLoading = false;
|
||||
console.log(error);
|
||||
},
|
||||
successHandler(response) {
|
||||
this.isLoading = false;
|
||||
if (response.message) {
|
||||
this.returnData = response;
|
||||
} else {
|
||||
this.returnData = null;
|
||||
}
|
||||
},
|
||||
hasMarkingParameter() {
|
||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||
this.hasMarking = urlSearchParams.has('marking');
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -99,6 +99,7 @@
|
||||
updateFilters(filters){
|
||||
this.filters = filters;
|
||||
this.setDecoratorDefault();
|
||||
this.$store.dispatch('updateListQueue', {'name': this.section, 'page': 1, 'filters': this.filters});
|
||||
this.submit(this.endpoint + '?page=1&filters=' + JSON.stringify(this.filters), 'get', this.section, false, false)
|
||||
},
|
||||
successHandler(response){
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="btn btn-sm btn-default btn-block bg-master-lighter" data-dismiss="modal">Cancel</div>
|
||||
</div>
|
||||
<div class="col p-l-5">
|
||||
<div class="btn btn-sm btn-block b-rad-none" :class="[{'btn-danger': modalType !== 'confirm'}, {'btn-success': modalType === 'confirm'}]" @click="submit(apiRoute, apiMethod, section, true, true)">{{ buttonText }}</div>
|
||||
<div class="btn btn-sm btn-block b-rad-none" :class="[{'btn-danger': modalType !== 'confirm'}, {'btn-success': modalType === 'confirm'}]" @click="submitForm()">{{ buttonText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -32,6 +32,10 @@
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
params: {
|
||||
type: Array,
|
||||
required: false
|
||||
},
|
||||
modalType: {
|
||||
type: String,
|
||||
default: 'confirm'
|
||||
@@ -50,6 +54,10 @@
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
submitForm() {
|
||||
if (this.params) this.parameters = this.params;
|
||||
return this.submit(this.apiRoute, this.apiMethod, this.section, true, true);
|
||||
}
|
||||
},
|
||||
mixins: [componentHandler, ModalFormHandler]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<select class="form-control">
|
||||
<select class="form-control" :disabled="this.options.length === 0 && this.disableOnFetch">
|
||||
<option disabled></option>
|
||||
</select>
|
||||
</template>
|
||||
@@ -13,6 +13,10 @@
|
||||
},
|
||||
value: {
|
||||
required: false
|
||||
},
|
||||
disableOnFetch: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<select-component :options="$store.getters.getSelectableList(section)" :value="value" @input="(val) => {$emit('input', val)}"></select-component>
|
||||
<select-component :disableOnFetch="disableOnFetch" :options="$store.getters.getSelectableList(section)" :value="value" @input="(val) => {$emit('input', val)}"></select-component>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
valueColumn: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
disableOnFetch: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
created(){
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-b-5" @keyup.enter="submitSearch">
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.reference_no">
|
||||
<label class="all-caps">Booking Reference</label>
|
||||
<input type="text" class="form-control" v-model="parameters.reference_no">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col col-md-auto d-flex justify-content-center align-items-center">
|
||||
<button type="button" class="btn btn-lg btn-primary fs-11 w-100" @click="submitSearch()">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row padding-10">
|
||||
@@ -11,7 +34,7 @@
|
||||
<div class="col-2 fs-10 text-right">Balance</div>
|
||||
</div>
|
||||
|
||||
<list-component :key="key" section="topUp" :endpoint="route('api.transaction.wallet.list')" :options="{status_in: [2, 3], owner_type: 'App\\Models\\Wallet', owner_id: wallet_id, per_page: showingTransactionCount}">
|
||||
<list-component :key="key" section="topUp" :endpoint="route('api.transaction.wallet.list')" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<customer-wallet-transaction-component :data="data" :deciamls="deciamls"></customer-wallet-transaction-component>
|
||||
</template>
|
||||
@@ -39,12 +62,50 @@ export default {
|
||||
data(){
|
||||
return {
|
||||
key: 1,
|
||||
parameters: {
|
||||
reference_no: null,
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
options: {
|
||||
status_in: [2, 3],
|
||||
owner_type: 'App\\Models\\Wallet',
|
||||
owner_id: this.wallet_id,
|
||||
per_page: this.showingTransactionCount
|
||||
}
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
reference_no: { },
|
||||
startDate: { },
|
||||
endDate: { },
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
showingTransactionCount() {
|
||||
this.options.per_page = this.showingTransactionCount;
|
||||
this.key ++;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitSearch() {
|
||||
delete this.options.with_booking_marking_like;
|
||||
delete this.options.created_after_or_equal;
|
||||
delete this.options.created_before_or_equal;
|
||||
|
||||
if (this.parameters.reference_no) {
|
||||
this.options.with_booking_marking_like = this.parameters.reference_no
|
||||
}
|
||||
if (this.parameters.startDate) {
|
||||
this.options.created_after_or_equal = this.parameters.startDate
|
||||
}
|
||||
if (this.parameters.endDate) {
|
||||
this.options.created_before_or_equal = this.parameters.endDate
|
||||
}
|
||||
|
||||
this.key ++;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
+27
-27
@@ -1,36 +1,37 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
|
||||
<div class="col no-padding">
|
||||
<h6>Wallet Transaction History</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center h-100">
|
||||
<span class="btn btn-md fs-11 bg-primary text-white fs-12 bold m-r-5" :class="[{'bg-primary-darker': showingPreciseAmount}]" @click="showingPreciseAmount=!showingPreciseAmount">{{ showingPreciseAmount ? 'Showing Precise Wallet Transaction' : 'Show Precise Wallet Transaction'}}</span>
|
||||
<a v-if="company" :href="route('wallet.details-export', company.reference, showingPreciseAmount)" target="_blank" class="btn btn-md btn-primary fs-11"><i class="fa fa-download m-r-5"></i>{{ showingPreciseAmount ? 'Download Precise Transaction' : 'Download Transaction'}}</a>
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div v-if="!isLoading">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
|
||||
<div class="col no-padding">
|
||||
<h6>Wallet Transaction History</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<validation-wrapper-component selectable :validator="$v.showingTransactionCount">
|
||||
<label>Showing Rows</label>
|
||||
<select-component :options="[5, 10, 20, 30, 50]" v-model="showingTransactionCount"></select-component>
|
||||
</validation-wrapper-component>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center h-100">
|
||||
<span class="btn btn-md fs-11 bg-primary text-white fs-12 m-r-5" :class="[{'bg-primary-darker': showingPreciseAmount}]" @click="showingPreciseAmount=!showingPreciseAmount">{{ showingPreciseAmount ? 'Showing Precise Wallet Transaction' : 'Show Precise Wallet Transaction'}}</span>
|
||||
<a v-if="company" :href="route('wallet.details-export', company.reference, showingPreciseAmount)" target="_blank" class="btn btn-md btn-primary fs-11"><i class="fa fa-download m-r-5"></i>{{ showingPreciseAmount ? 'Download Precise Transaction' : 'Download Transaction'}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<validation-wrapper-component selectable :validator="$v.showingTransactionCount">
|
||||
<label>Showing Rows</label>
|
||||
<select-component :options="[5, 10, 20, 30, 50]" v-model="showingTransactionCount"></select-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="!showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="2" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
<div v-show="showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="5" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="!showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="2" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
<div v-show="showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="5" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 m-l-15">
|
||||
<div v-if="!isLoading">
|
||||
<div class="col-3 m-l-15">
|
||||
<wallet-component :data="company" :creditable=true></wallet-component>
|
||||
<div class="row m-t-20">
|
||||
<div class="col">
|
||||
@@ -68,7 +69,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<div class="col-auto">
|
||||
<div class="btn btn-xs p-l-15 p-r-20 b-rad-none font-heading btn-rounded bg-white" @click="reload = true"><i class="fa fa-plus fs-8 m-r-5"></i> Reload</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0" v-if="!mini">
|
||||
<div class="col-auto p-l-0" v-if="!mini && data.wallet">
|
||||
<a class="text-white fs-10" :href="route('wallet.details', data.reference)" target="_blank">Transaction History<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,9 +52,18 @@
|
||||
<wallet-top-up-form-component :data="data" :amount="(!data.wallet ? amount : (Math.round((((amount - data.wallet.amount) < '0.00' ? '0.00' : (amount - data.wallet.amount)) + Number.EPSILON) * 100) / 100).toFixed(2))" :creditable="creditable"></wallet-top-up-form-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-20" v-if="$store.getters.isAdmin">
|
||||
<div class="row m-t-10" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<a :href="route('account.statment', data.reference)">View Account Statement<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
<div class="row m-t-10" v-if="$store.getters.isSuperAdmin">
|
||||
<div class="col">
|
||||
<a :href="route('account.statment', data.reference)">View Account Statement<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10">
|
||||
<div class="col">
|
||||
<a :href="downloadInvoiceUrl()">Download All Invoices<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -79,6 +88,11 @@
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
downloadInvoiceUrl(){
|
||||
return this.route('customers.invoices') + '?marking=' + this.data.reference;
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
reload: false,
|
||||
|
||||
+29
-9
@@ -13,19 +13,39 @@ export default {
|
||||
let statusCode = response.status,
|
||||
success = response.ok;
|
||||
|
||||
response.json().then(response => {
|
||||
if (response.headers.get("content-type") === "application/zip") {
|
||||
const fileName = response.headers.get('Content-Disposition').split('filename=')[1].replaceAll('"', '');
|
||||
|
||||
if(!success){
|
||||
this.openModal();
|
||||
errorNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'error'}): null;
|
||||
this.errorHandler(response, statusCode); return;
|
||||
}
|
||||
response.blob().then(response => {
|
||||
if (!success) {
|
||||
this.openModal();
|
||||
errorNotification ? this.$store.dispatch('createNotification', { title: response.title, message: response.message, type: 'error' }) : null;
|
||||
this.errorHandler(response, statusCode); return;
|
||||
}
|
||||
|
||||
successNotification ? this.$store.dispatch('createNotification', {title: response.title, message: response.message, type: 'success'}): null;
|
||||
this.successHandler(response)
|
||||
successNotification ? this.$store.dispatch('createNotification', { title: response.title, message: response.message, type: 'success' }) : null;
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.href = window.URL.createObjectURL(response);
|
||||
link.download = fileName.trim();
|
||||
link.click();
|
||||
this.successHandler(response)
|
||||
});
|
||||
} else {
|
||||
response.json().then(response => {
|
||||
|
||||
if (!success) {
|
||||
this.openModal();
|
||||
errorNotification ? this.$store.dispatch('createNotification', { title: response.title, message: response.message, type: 'error' }) : null;
|
||||
this.errorHandler(response, statusCode); return;
|
||||
}
|
||||
|
||||
successNotification ? this.$store.dispatch('createNotification', { title: response.title, message: response.message, type: 'success' }) : null;
|
||||
this.successHandler(response)
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
this.$store.dispatch('createNotification', {title: 'Unexpected Error', message: 'An unexpected error has occurred. Try again!', type: 'error'});
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
<div class="row justify-content-end">
|
||||
<div class="col">
|
||||
<div class="row fs-12 text-center">
|
||||
<div class="col p-t-20 p-b-20 bg-master-lighter tabButton" tab-name="complete">
|
||||
<div class="col p-t-20 p-b-20 bg-master-lighter tabButton" tab-name="ReportMapped">
|
||||
<div class="row justify-content-center m-b-5">
|
||||
<div class="col-auto">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
@@ -312,6 +312,14 @@
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- tab for report & Analysis --}}
|
||||
<div class="row tabsContainer tabContent" tab-name="ReportMapped">
|
||||
<div class="col">
|
||||
<report-transactions-mapped-component></report-transactions-mapped-component>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
@extends('layouts.base_portal')
|
||||
@section('inner_content')
|
||||
<div class="row" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<bulk-download-invoice-component section="BulkDownloadInvoiceComponent"></bulk-download-invoice-component>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -1,67 +1,4 @@
|
||||
@extends('layouts.base_portal')
|
||||
@section('inner_content')
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 no-padding">
|
||||
<download-billing-with-dates-component section="paymentsReportSection" ></download-billing-with-dates-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col bg-white p-t-15 p-b-15">
|
||||
<div class="row no-margin">
|
||||
<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">Complete Payments</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<list-component key="2" section="paymentVerificationSection" :endpoint="route('api.transaction.list')" :options="{'type': 1, 'status': 3, 'payment_method_not_in': [4]}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<payment-verification-component section="paymentVerificationSection" :data="data" :no_action="true"></payment-verification-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">Complete Currency Orders</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<list-component key="2" section="completeTransactionGroupsListSection" :options="{'per_page': 20, 'status': 3}" :endpoint="route('api.transaction.group.list')">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<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">Open Currency Orders</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<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>
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<payment-component></payment-component>
|
||||
@endsection
|
||||
@@ -69,109 +69,8 @@
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<table class="line-table" style="overflow: wrap" autosize="1">
|
||||
<!-- Table Header -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%">No</th>
|
||||
<th class="stock-code" width="10%">Stock Code</th>
|
||||
<th class="description">Description</th>
|
||||
<th width="10%">Quantity</th>
|
||||
<th width="15%">Unit Price (RM)</th>
|
||||
<th width="10%">Total Amount<br>(RM)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@php
|
||||
$subtotal = "0";
|
||||
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 5) : "0";
|
||||
$displayedSubtotal = "0";
|
||||
$exactTotal = "0";
|
||||
@endphp
|
||||
@include('pages.pdfs.purchase_order_table')
|
||||
|
||||
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
|
||||
@php
|
||||
$exactUnitPrice = bcdiv($transaction_detail->price, $transaction->currency_rate, 5);
|
||||
$itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5);
|
||||
|
||||
// Round half to even for displayed item total
|
||||
$displayedItemTotal = round(bcmul($exactUnitPrice, $transaction_detail->quantity, 2), 2, PHP_ROUND_HALF_EVEN);
|
||||
|
||||
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
|
||||
$subtotal = bcadd($subtotal, $itemTotal, 5);
|
||||
$exactTotal = bcadd($exactTotal, $displayedItemTotal, 5);
|
||||
@endphp
|
||||
<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">
|
||||
{{ number_format($exactUnitPrice, 2) }}
|
||||
</td>
|
||||
<td width="20%" class="right top">
|
||||
{{ number_format($itemTotal, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
@php
|
||||
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5);
|
||||
@endphp
|
||||
<tr class="subtotal">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Subtotal</td>
|
||||
<td class="right middle">{{ number_format($subtotal, 2) }}</td>
|
||||
</tr>
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Service Charges</td>
|
||||
<td class="right">{{ number_format($transaction->service_charge, 2) }}</td>
|
||||
</tr>
|
||||
|
||||
@if($voucher_redemption)
|
||||
<tr class="voucher">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Voucher ({{ $voucher_redemption->voucher->code }})</td>
|
||||
<td class="right middle">-{{ number_format($voucherDiscount, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if($transaction->tax > 0)
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Tax</td>
|
||||
<td class="right">{{ number_format($transaction->tax, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@php
|
||||
// Calculate the totals with 5 decimal places
|
||||
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
|
||||
// Calculate the displayed totals with 2 decimal places
|
||||
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 2), $transaction->tax, 2), $voucherDiscount, 2);
|
||||
|
||||
// Calculate the discrepancy
|
||||
$discrepancy = bcsub($expectedTotal, $displayedTotal, 5);
|
||||
|
||||
// Calculate the final total
|
||||
$total = bcadd($expectedTotal, $discrepancy, 5);
|
||||
@endphp
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Adjustment</td>
|
||||
<td class="right middle">{{number_format($discrepancy, 5)}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Total</td>
|
||||
<td class="total right middle">
|
||||
{{ number_format($total, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<htmlpagefooter name="page-footer">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
|
||||
@@ -58,97 +58,8 @@
|
||||
<br>
|
||||
|
||||
<!-- Invoice Table -->
|
||||
<table class="line-table" style="overflow: wrap" autosize="1">
|
||||
<!-- Table Header -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%">No</th>
|
||||
<th class="stock-code" width="10%">Stock Code</th>
|
||||
<th class="description">Description</th>
|
||||
<th width="10%">Quantity</th>
|
||||
<th width="15%">Unit Price (RM)</th>
|
||||
<th width="10%">Total Amount<br>(RM)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@php
|
||||
$subtotal = "0";
|
||||
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 2) : "0";
|
||||
$displayedSubtotal = 0;
|
||||
@endphp
|
||||
@include('pages.pdfs.purchase_order_table')
|
||||
|
||||
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
|
||||
@php
|
||||
$exactUnitPrice = bcdiv($transaction_detail->price, $transaction->currency_rate, 7);
|
||||
$itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5);
|
||||
$displayedItemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 2);
|
||||
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
|
||||
$subtotal = bcadd($subtotal, $itemTotal, 5);
|
||||
@endphp
|
||||
<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">
|
||||
{{ number_format($exactUnitPrice, 2) }}
|
||||
</td>
|
||||
<td width="20%" class="right top">
|
||||
{{ number_format($itemTotal, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
@php
|
||||
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5);
|
||||
@endphp
|
||||
<tr class="subtotal">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Subtotal</td>
|
||||
<td class="right middle">{{ number_format($subtotal, 2) }}</td>
|
||||
</tr>
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Service Charges</td>
|
||||
<td class="right">{{ number_format($transaction->service_charge, 2) }}</td>
|
||||
</tr>
|
||||
|
||||
@if($voucher_redemption)
|
||||
<tr class="voucher">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Voucher ({{ $voucher_redemption->voucher->code }})</td>
|
||||
<td class="right middle">-{{ number_format($voucherDiscount, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if($transaction->tax > 0)
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Tax</td>
|
||||
<td class="right">{{ number_format($transaction->tax, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@php
|
||||
$displayedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
$discrepancy = bcsub($displayedTotal, $expectedTotal, 5);
|
||||
$total = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
@endphp
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Adjustment</td>
|
||||
<td class="right middle">{{number_format($discrepancy, 5)}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Total</td>
|
||||
<td class="total right middle">
|
||||
{{ number_format($total, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<br>
|
||||
<div class="note">
|
||||
<strong>Note:</strong> All items purchased are subject to our Terms & Conditions. Please refer to our official website for more information.
|
||||
@@ -158,6 +69,6 @@
|
||||
Please transfer the payment to:<br>
|
||||
Bank: Maybank Berhad<br>
|
||||
Account Name: CIEF Worldwide Sdn Bhd<br>
|
||||
Account No: 564892103405<br>
|
||||
Account No: 568603010762<br>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -76,109 +76,8 @@
|
||||
|
||||
<br>
|
||||
|
||||
<table class="line-table" style="overflow: wrap" autosize="1">
|
||||
<!-- Table Header -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%">No</th>
|
||||
<th class="stock-code" width="10%">Stock Code</th>
|
||||
<th class="description">Description</th>
|
||||
<th width="10%">Quantity</th>
|
||||
<th width="15%">Unit Price (RM)</th>
|
||||
<th width="10%">Total Amount<br>(RM)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@php
|
||||
$subtotal = "0";
|
||||
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 5) : "0";
|
||||
$displayedSubtotal = "0";
|
||||
$exactTotal = "0";
|
||||
@endphp
|
||||
@include('pages.pdfs.purchase_order_table')
|
||||
|
||||
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
|
||||
@php
|
||||
$exactUnitPrice = bcdiv($transaction_detail->price, $transaction->currency_rate, 5);
|
||||
$itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5);
|
||||
|
||||
// Round half to even for displayed item total
|
||||
$displayedItemTotal = round(bcmul($exactUnitPrice, $transaction_detail->quantity, 2), 2, PHP_ROUND_HALF_EVEN);
|
||||
|
||||
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
|
||||
$subtotal = bcadd($subtotal, $itemTotal, 5);
|
||||
$exactTotal = bcadd($exactTotal, $displayedItemTotal, 5);
|
||||
@endphp
|
||||
<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">
|
||||
{{ number_format($exactUnitPrice, 2) }}
|
||||
</td>
|
||||
<td width="20%" class="right top">
|
||||
{{ number_format($itemTotal, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
@php
|
||||
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5);
|
||||
@endphp
|
||||
<tr class="subtotal">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Subtotal</td>
|
||||
<td class="right middle">{{ number_format($subtotal, 2) }}</td>
|
||||
</tr>
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Service Charges</td>
|
||||
<td class="right">{{ number_format($transaction->service_charge, 2) }}</td>
|
||||
</tr>
|
||||
|
||||
@if($voucher_redemption)
|
||||
<tr class="voucher">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Voucher ({{ $voucher_redemption->voucher->code }})</td>
|
||||
<td class="right middle">-{{ number_format($voucherDiscount, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if($transaction->tax > 0)
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Tax</td>
|
||||
<td class="right">{{ number_format($transaction->tax, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@php
|
||||
// Calculate the totals with 5 decimal places
|
||||
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
|
||||
// Calculate the displayed totals with 2 decimal places
|
||||
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 2), $transaction->tax, 2), $voucherDiscount, 2);
|
||||
|
||||
// Calculate the discrepancy
|
||||
$discrepancy = bcsub($expectedTotal, $displayedTotal, 5);
|
||||
|
||||
// Calculate the final total
|
||||
$total = bcadd($expectedTotal, $discrepancy, 5);
|
||||
@endphp
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Adjustment</td>
|
||||
<td class="right middle">{{number_format($discrepancy, 5)}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Total</td>
|
||||
<td class="total right middle">
|
||||
{{ number_format($total, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<htmlpagefooter name="page-footer">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<table class="line-table" style="overflow: wrap" autosize="1">
|
||||
<!-- Table Header -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="5%">No</th>
|
||||
<th class="stock-code" width="10%">Stock Code</th>
|
||||
<th class="description">Description</th>
|
||||
<th width="10%">Quantity</th>
|
||||
<th width="15%">Unit Price (RM)</th>
|
||||
<th width="10%">Total Amount<br>(RM)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@php
|
||||
$subtotal = "0";
|
||||
$voucherDiscount = $voucher_redemption ? bcmul((string)$voucher_redemption->value, "-1", 2) : "0";
|
||||
$displayedSubtotal = 0;
|
||||
$currency_id = $transaction->owner->fix_currency_id;
|
||||
@endphp
|
||||
|
||||
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
|
||||
@php
|
||||
$exactUnitPrice = ($currency_id) === 1 ? $transaction_detail->price : bcdiv($transaction_detail->price, $transaction->currency_rate, 7);
|
||||
$displayUnitPrice = round($exactUnitPrice, 2);
|
||||
$itemTotal = bcmul($exactUnitPrice, $transaction_detail->quantity, 5);
|
||||
$displayedItemTotal = round(bcmul($displayUnitPrice, $transaction_detail->quantity, 7), 2);
|
||||
$displayedSubtotal = bcadd($displayedSubtotal, $displayedItemTotal, 2);
|
||||
$subtotal = bcadd($subtotal, $itemTotal, 5);
|
||||
@endphp
|
||||
<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">
|
||||
{{ number_format($displayUnitPrice, 2) }}
|
||||
</td>
|
||||
<td width="20%" class="right top">
|
||||
{{ number_format($displayedItemTotal, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
@php
|
||||
$subtotalWithDiscount = bcsub($subtotal, $voucherDiscount, 5);
|
||||
@endphp
|
||||
<tr class="subtotal">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Subtotal</td>
|
||||
<td class="right middle">{{ number_format($displayedSubtotal, 2) }}</td>
|
||||
</tr>
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Service Charges</td>
|
||||
<td class="right">{{ number_format($transaction->service_charge, 2) }}</td>
|
||||
</tr>
|
||||
|
||||
@if($voucher_redemption)
|
||||
<tr class="voucher">
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Voucher ({{ $voucher_redemption->voucher->code }})</td>
|
||||
<td class="right middle">-{{ number_format($voucherDiscount, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if($transaction->tax > 0)
|
||||
<tr class="billingcharges">
|
||||
<td colspan="4"></td>
|
||||
<td class="right">Tax</td>
|
||||
<td class="right">{{ number_format($transaction->tax, 2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@php
|
||||
$displayedTotal = bcadd(bcadd(bcadd($displayedSubtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
$expectedTotal = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
$discrepancy = bcsub($expectedTotal, $displayedTotal, 5);
|
||||
$total = bcadd(bcadd(bcadd($subtotal, $transaction->service_charge, 5), $transaction->tax, 5), $voucherDiscount, 5);
|
||||
@endphp
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Adjustment</td>
|
||||
<td class="right middle">{{number_format($discrepancy, 5)}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="right middle">Total</td>
|
||||
<td class="total right middle">
|
||||
{{ number_format($total, 2) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
@@ -10,10 +10,13 @@ Route::group(['prefix' => 'accounting', 'as' => 'accounting.', 'namespace' => 'A
|
||||
Route::put('/details/update', 'BankStatementController@update')->name('details.update');
|
||||
});
|
||||
|
||||
Route::post('bankStatement/{id}/details/{status}', 'ApproveDuplicateBankStatementDetailsStatusController@update')->where('status', 'approve|reject')->name('bankStatement.details.status.update');
|
||||
Route::post('bankStatement/{id}/details/{status}', 'ApproveDuplicateBankStatementDetailsStatusController@update')->where('status', 'approve|reject|pending_verification')->name('bankStatement.details.status.update');
|
||||
|
||||
Route::group(['prefix' => 'statement_transaction', 'as' => 'statement_transaction.'], function () {
|
||||
Route::post('/owner/group-approve', 'GroupApproveStatementTransactionController@approve')->name('owner.groupApprove');
|
||||
Route::post('/{id}/owner/{status}', 'UpdateStatementTransactionStatusController@update')->where('status', 'approve|reject')->name('owner.status.update');
|
||||
});
|
||||
|
||||
Route::get('history/imported', 'HistoryImportedTransactionMappedController@getImported')->name('history.imported');
|
||||
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user