Merge remote-tracking branch 'origin/master'

This commit is contained in:
Omair Saleh
2023-02-23 15:59:41 +08:00
27 changed files with 1025 additions and 20 deletions
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class CreatedAtBetween implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereBetween('created_at', $value);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class CurrencyRateIdIn implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->whereIn('currency_rate_id', $value);
}
}
@@ -0,0 +1,69 @@
<?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\DocumentType;
use App\Classes\Modules\Documents\Standards\Rules\CanDeleteDocument;
use App\Classes\Modules\Documents\Services\DeletesDocument;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeletePurchaseOrderPdfLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Purchase Order PDF Deleted',
'message' => 'You have successfully deleted the Purchase order PDF'
];
}
/** @var FetchesBooking */
private $fetchesBooking;
/** @var DeletesDocument */
private $deletesDocument;
/** @var CanDeleteDocument */
private $canDeleteDocument;
/**
* DeletePurchaseOrderPdfLogic constructor.
* @param FetchesBooking $fetchesBooking
* @param DeletesDocument $deletesDocument
* @param CanDeleteDocument $canDeleteDocument
*/
public function __construct(fetchesBooking $fetchesBooking, DeletesDocument $deletesDocument, CanDeleteDocument $canDeleteDocument)
{
$this->fetchesBooking = $fetchesBooking;
$this->deletesDocument = $deletesDocument;
$this->canDeleteDocument = $canDeleteDocument;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
$document = $booking->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first();
$this->canDeleteDocument->passes();
$this->deletesDocument->execute($document);
return $this->response([]);
}
}
@@ -0,0 +1,82 @@
<?php
namespace App\Classes\Modules\Companies\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Companies\DataTransferObjects\CompanyObject;
use App\Classes\Modules\Companies\Services\FetchesCompany;
use App\Classes\Modules\Companies\Services\UpdatesCompany;
use App\Classes\Modules\Companies\Services\UpdatesCompanyDebtor;
use App\Classes\Modules\Companies\Standards\Rules\CanUpdateCompany;
use App\Http\Resources\CompanyResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Component\ErrorHandler\Debug;
class UpdateCompanyNameAndDebtorLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Update Company Account Status',
'message' => 'You have successfully updated the Company Account Status'
];
}
/** @var CanUpdateCompany */
private $canUpdateCompany;
/** @var UpdatesCompany */
private $updatesCompany;
/** @var FetchesCompany */
private $fetchesCompany;
/** @var UpdatesCompanyDebtor */
private $updatesCompanyDebtor;
/**
* UpdateCompanyControllersLogic constructor.
* @param CanUpdateCompany $canUpdateCompany
* @param UpdatesCompany $updatesCompany
* @param FetchesCompany $fetchesCompany
* @param UpdatesCompanyDebtor $updatesCompanyDebtor
*/
public function __construct(
CanUpdateCompany $canUpdateCompany,
UpdatesCompany $updatesCompany,
FetchesCompany $fetchesCompany,
UpdatesCompanyDebtor $updatesCompanyDebtor
)
{
$this->canUpdateCompany = $canUpdateCompany;
$this->updatesCompany = $updatesCompany;
$this->fetchesCompany = $fetchesCompany;
$this->updatesCompanyDebtor = $updatesCompanyDebtor;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
$query = $this->fetchesCompany->execute(['id' => $request->route('id')]);
$object = new CompanyObject($request->input('name'), $request->input('reference'), $query->business_type, $request->input('type'));
$this->canUpdateCompany->passes($object);
$query = $this->updatesCompany->execute($query, $object);
if ($request->input('debtor') || $query->first()->debtor !== null) {
$this->updatesCompanyDebtor->execute($query, $request->input('debtor'));
}
return $this->resourceResponse(new CompanyResource($query));
}
}
@@ -83,4 +83,4 @@ class CompanyObject implements DataTransferObject
}
}
@@ -15,7 +15,7 @@ class UpdatesCompany extends AbstractUpdateRecord
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Company $model, CompanyObject $object)
public function execute(Company $model, CompanyObject $object)
{
$model->name = $object->getName();
$model->reference = $object->getReference();
@@ -23,4 +23,4 @@ class UpdatesCompany extends AbstractUpdateRecord
return $this->handler($model);
}
}
}
@@ -11,6 +11,7 @@ class UpdatesCompanyDebtor extends AbstractUpdateRecord
/**
* @param Company $model
* @param CompanyObject $object
* @param string $debtor
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
@@ -18,6 +19,7 @@ class UpdatesCompanyDebtor extends AbstractUpdateRecord
public function execute(Company $model, string $debtor)
{
$model->debtor = $debtor;
return $this->handler($model);
}
}
}
@@ -0,0 +1,84 @@
<?php
namespace App\Classes\Modules\Currencies\ControllersLogic\History;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Currencies\Services\Rates\ListsRateLogs;
use App\Classes\Modules\Currencies\Services\Rates\ListsRates;
use App\Classes\Modules\Currencies\Standards\Rules\Rates\CanListRates;
use App\Http\Resources\CurrencyRateLogResource;
use App\Models\CurrencyRateLog;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Carbon\Carbon;
class ListCurrencyRateHistoryLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Retrieved Currency Rate History',
'message' => 'You have successfully retrieved a list of Currency Rate History'
];
}
/** @var CanListRates */
private $canListRates;
/** @var ListsRateLogs */
private $listsRateLogs;
/** @var ListsRate */
private $listsRates;
/**
* ListRatesLogic constructor.
* @param CanListRates $canListRates
* @param ListsRates $listsRates
*/
public function __construct(CanListRates $canListRates, ListsRateLogs $listsRateLogs, listsRates $listsRates)
{
$this->canListRates = $canListRates;
$this->listsRateLogs = $listsRateLogs;
$this->listsRates = $listsRates;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request): JsonResponse
{
//$this->canListRates->passes();
$filterArray = json_decode($request->input('filters'));
$rate_filter['currency_id'] = $filterArray->currency_id;
$rate_filter['service_id'] = $filterArray->service_id;
$currency_rate_ids = $this->listsRates->execute(
[
'currency_id' => $filterArray->currency_id,
'service_id' => $filterArray->service_id,
]
)->pluck('id')->toArray();
$query = $this->listsRateLogs->execute(
[
'currency_rate_id_in' => $currency_rate_ids,
'date_start' => new Carbon($filterArray->date_from),
'date_end' => new Carbon($filterArray->date_to),
]
);
return $this->collectionResponse(CurrencyRateLogResource::collection($query));
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Classes\Modules\Currencies\Services\Rates;
use App\Classes\General\Eloquent\AbstractListRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\CurrencyRateLog;
class ListsRateLogs extends AbstractListRecord
{
/** @var CurrencyRateLog */
private $repository;
/**
* ListsRates constructor.
* @param CurrencyRate $repository
*/
public function __construct(CurrencyRateLog $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,16 @@
<?php
namespace App\Http\Controllers\Bookings;
use App\Classes\Modules\Bookings\ControllersLogic\DeletePurchaseOrderPdfLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeletePurchaseOrderPdfController
{
public function delete(Request $request, DeletePurchaseOrderPdfLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers\Companies;
use App\Classes\Modules\Companies\ControllersLogic\UpdateCompanyNameAndDebtorLogic;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateCompanyNameAndDebtorController extends Controller
{
/**
* @param Request $request
*/
public function update(Request $request, UpdateCompanyNameAndDebtorLogic $logic) : JsonResponse
{
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Currencies\History;
use App\Classes\Modules\Currencies\ControllersLogic\History\ListCurrencyRateHistoryLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ListCurrencyRateHistory
{
/**
* @param Request $request
* @param ListRatesLogic $logic
* @return JsonResponse
*/
public function list(Request $request, ListCurrencyRateHistoryLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
+1
View File
@@ -37,6 +37,7 @@ class CompanyResource extends JsonResource
'id' => $this->id,
'name' => $this->name,
'reference' => $this->reference,
'debtor' => $this->debtor,
'type' => (int) $this->type,
'business_type' => (int) $this->business_type,
'status' => (int) $this->status,
@@ -0,0 +1,26 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CurrencyRateLogResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$currencyRate = $this->currencyRate;
return [
'currency_rate_id' => $this->currency_rate_id,
'rate' => $this->selling,
'created_at' => $this->created_at->format('d-m-Y'),
'payment_method_type' => $currencyRate->payment_method_type,
];
}
}
+9
View File
@@ -1,10 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class CurrencyRateLog extends AbstractModel
{
protected $table = 'currency_rate_logs';
/**
* @return BelongsTo
*/
public function currencyRate(): BelongsTo
{
return $this->BelongsTo(CurrencyRate::class, 'currency_rate_id', 'id');
}
}
@@ -0,0 +1,118 @@
<template>
<div class="row">
<div class="col">
<div class="row" style="margin-left:1px; margin-right:1px;" v-if='selectedCurrency'>
<div class="col bg-primary text-white">
<div class="row h-100 align-items-center">
<div class="col-auto p-r-0">
<span class="p-t-20 p-b-20 flag-icon fs-14"
:class="'flag-icon-' + selectedCurrency.country.short_code.toLowerCase()"></span>
</div>
<div class="col p-l-5 p-r-20">
{{ selectedCurrency.short_code }}
</div>
<div class="col-auto h-100 pointer" @click="recipientMenu = !recipientMenu">
<div class="row align-items-center bg-primary-light h-100">
<div class="col ">
<i class="fa fa-angle-down fs-14 m-t-5"
:class="[{ 'fa-angle-down': !recipientMenu }, { 'fa-angle-up': recipientMenu }]"></i>
</div>
</div>
</div>
<div class="relative w-100 text-master">
<div class="absolute w-100 b-l b-b b-r b-success" :class="[{ 'hide': !recipientMenu }]"
style="top: 100%; right: 0; z-index: 1;">
<div class="row text-left no-margin bg-white">
<div class="col no-padding">
<div class="row no-margin" v-for="currency in currencyList"
v-bind:key="currency.id">
<div class="col b-b b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10 "
:class="[{ 'bg-primary-light': selectedCurrency.id === currency.id }, { 'text-white': selectedCurrency.id === currency.id }, { 'hover-primary': selectedCurrency.id !== currency.id }, { 'pointer': selectedCurrency.id !== currency.id }]"
@click="UpdateCurrency(currency)">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="row align-items-center justify-content-center">
<div class="col-auto p-r-5 p-l-0">
<span class="flag-icon fs-14"
:class="'flag-icon-' + currency.country.short_code.toLowerCase()"></span>
</div>
<div class="col-auto p-l-5">
<div class="font-heading fs-12">
{{ currency.short_code }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
section: 'chooseCurrencySection',
currencyList: [
// {
// "id": 1,
// "country": {
// "id": 1,
// "name": "Malaysia",
// "short_code": "MY",
// "phone_code": "60"
// },
// "name": "Malaysian Ringgit",
// "short_code": "MYR",
// "symbol": "RM"
// },
{
"id": 2,
"country": {
"id": 2,
"name": "China",
"short_code": "CN",
"phone_code": "86"
},
"name": "Yuan Renminbi",
"short_code": "RMB",
"symbol": "¥"
},
{
"id": 3,
"country": {
"id": 3,
"name": "United States",
"short_code": "US",
"phone_code": "1"
},
"name": "US Dollar",
"short_code": "USD",
"symbol": "$"
}
],
recipientMenu: false,
selectedCurrency: null,
};
},
mounted() {
this.UpdateCurrency(Object.values(this.currencyList)[0]);
},
methods: {
UpdateCurrency(currency) {
this.selectedCurrency = currency;
this.recipientMenu = false;
this.$emit('input', currency.id);
},
}
}
</script>
@@ -0,0 +1,97 @@
<template>
<div class="row h-100 mt-1 mb-1 m-md-0">
<div class="col">
<!-- <loading-component style="height: 100%; top: 0;" key="1" color="success" v-show="isLoading"></loading-component> -->
<div class="row h-100" style="margin-left:1px; margin-right:1px; min-height: 50px;" v-if='!isLoading'>
<div class="col bg-primary text-white">
<div class="row h-100 align-items-center">
<div class="col p-l-5 p-r-20">
<span class="m-l-10">{{ selectedCurrency.name }}</span>
</div>
<div class="col-auto h-100 pointer" @click="recipientMenu = !recipientMenu">
<div class="row align-items-center bg-primary-light h-100">
<div class="col ">
<i class="fa fa-angle-down fs-14 m-t-5"
:class="[{ 'fa-angle-down': !recipientMenu }, { 'fa-angle-up': recipientMenu }]"></i>
</div>
</div>
</div>
<div class="relative w-100 text-master">
<div class="absolute w-100 b-l b-b b-r b-success" :class="[{ 'hide': !recipientMenu }]"
style="top: 100%; right: 0; z-index: 1;">
<div class="row text-left no-margin bg-white">
<div class="col no-padding">
<div class="row no-margin" v-for="currency in currencyList"
v-bind:key="currency.id">
<div class="col b-b b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10 "
:class="[{ 'bg-primary-light': selectedCurrency.id === currency.id }, { 'text-white': selectedCurrency.id === currency.id }, { 'hover-primary': selectedCurrency.id !== currency.id }, { 'pointer': selectedCurrency.id !== currency.id }]"
@click="UpdateCurrency(currency)">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="row align-items-center justify-content-center">
<div class="col-auto p-l-5">
<div class="font-heading fs-12">
{{ currency.name }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
section: 'chooseCurrencySection',
currencyList: null,
recipientMenu: false,
selectedCurrency: null,
isLoading: true,
};
},
computed: {
pendingQueue() {
return this.$store.getters.isInCompleteQueue(this.section);
}
},
watch: {
pendingQueue(inComplete) {
if (inComplete) {
this.fetchCurrency();
}
}
},
created() {
this.$store.dispatch('updateListQueue', { 'name': this.section });
},
methods: {
fetchCurrency() {
this.submit(route('api.service_type.list'), 'get', this.section, false, false);
},
successHandler(response) {
this.isLoading = false;
this.currencyList = response.payload.data;
this.UpdateCurrency(this.currencyList[0]);
this.$emit('loaded', true);
},
UpdateCurrency(currency) {
this.selectedCurrency = currency;
this.recipientMenu = false;
this.$emit('input', currency.id);
},
}
}
</script>
@@ -0,0 +1,33 @@
<template>
<div class="row">
<div class="col">
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
<div class="row justify-content-center" v-show="!isLoading">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h3 class="all-caps">Are you Sure?</h3>
<div class="fs-11">Are you sure you want to delete the Purchase Order PDF?</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.booking.po.pdf.delete', data.id), 'delete', section, true, true)">Confirm</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
mixins: [componentHandler, ModalFormHandler]
}
</script>
@@ -0,0 +1,248 @@
<template>
<div class="row">
<div class="col">
<div class="row">
<div class="col-12 col-md">
<choose-currency-component v-on:input="updateCurrencyId($event)"></choose-currency-component>
</div>
<div class="col-12 col-md">
<choose-service-component v-on:input="updateServiceId($event)" v-on:loaded="isLoading=!isLoading"></choose-service-component>
</div>
<div class="col-12 col-md">
<validation-wrapper-component :validator="$v.filters.date_from">
<label class="all-caps">Date From</label>
<date-picker-component v-model.lazy="filters.date_from"></date-picker-component>
</validation-wrapper-component>
</div>
<div class="col-12 col-md">
<validation-wrapper-component :validator="$v.filters.date_to">
<label class="all-caps">Date To</label>
<date-picker-component v-model.lazy="filters.date_to"></date-picker-component>
</validation-wrapper-component>
</div>
</div>
<div class="row m-t-15">
<div class="col">
<button type="button" class="btn btn-lg btn-primary fs-11 " @click="fetchRateLogs" :class="[{'disabled': isLoading}]" :disabled="isLoading">Search</button>
<!-- <button type="button" class="btn btn-lg btn-secondary fs-11" @click="resetSarch">Reset</button> -->
</div>
</div>
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
<div class="row" v-if="!isLoading && !hasError">
<div class="col-12 mx-auto p-0 ">
<canvas style="width: 800px; height:350px" id="currency-history-chart"></canvas>
</div>
</div>
<div class="row" v-if="hasError">
<div class="col">
<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" style="letter-spacing: 2px;">Nothing To Show Here</p>
</div>
</div>
<div class="row m-t-5 align-items-center justify-content-center">
<div class="col">
<small class="fs-9 muted all-caps font-lato" style="letter-spacing: 2px">There is no results found, Try adjusting your filters to find what you are looking for.</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Chart from 'chart.js';
export default {
data() {
return {
rateHistory: null,
isLoading: true,
hasError: false,
section: 'rateHistorySection',
minWidth: {
minWidth: "100px",
},
minWidth150: {
minWidth: "150px",
},
filters: {
currency_id: null,
service_id: null,
date_to: null,
date_from: null,
},
chartLebels:[],
chartData: [],
paymentMethodsConst: [],
colors: [
'red',
'pink',
'blue',
'purple',
'black',
'yellow'
]
};
},
props:{
paymentMethods: {
type: Object
}
},
computed: {
pendingQueue() {
return this.$store.getters.isInCompleteQueue(this.section);
}
},
mounted(){
this.paymentMethodsConst = Object.entries(this.paymentMethods).reduce((acc, [key, value]) => {
acc[value] = key;
return acc;
}, {});
},
watch: {
pendingQueue(inComplete) {
if (inComplete) {
this.resetSarch();
}
},
rateHistory: function(newVal) {
const date_from_parts = this.filters.date_from.split("-");
const date_from_year = date_from_parts[2];
const date_from_month = date_from_parts[1] - 1; // Subtract 1 from month, since it's zero-based in Date objects
const date_from_day = date_from_parts[0];
const start = new Date(date_from_year, date_from_month, date_from_day);
const date_to_parts = this.filters.date_to.split("-");
const date_to_year = date_to_parts[2];
const date_to_month = date_to_parts[1] - 1; // Subtract 1 from month, since it's zero-based in Date objects
const date_to_day = date_to_parts[0];
const end = new Date(date_to_year, date_to_month, date_to_day);
// Group rates by payment method type
const ratesByType = {};
newVal.forEach(rate => {
if (!ratesByType[rate.payment_method_type]) {
ratesByType[rate.payment_method_type] = [];
}
ratesByType[rate.payment_method_type].push(rate);
});
const startYear = start.getFullYear();
const startMonth = start.getMonth() + 1;
const endYear = end.getFullYear();
const endMonth = end.getMonth() + 1;
// Get rates for date range
const ratesForRange = {};
Object.keys(ratesByType).forEach(type => {
ratesForRange[type] = [];
for (let i = start.getDate(); i <= end.getDate(); i++) {
const dateStr = `${i.toString().padStart(2, '0')}-${startMonth.toString().padStart(2, '0')}-${startYear}`;
if (i === end.getDate() && startMonth !== endMonth) {
// Handle end month
const endMonthDays = new Date(endYear, endMonth, 0).getDate();
for (let j = 1; j <= end.getDate(); j++) {
const dateStr = `${j.toString().padStart(2, '0')}-${endMonth.toString().padStart(2, '0')}-${endYear}`;
const rate = ratesByType[type].find(r => r.created_at === dateStr);
ratesForRange[type].push(rate ? rate.rate : '');
}
} else {
// Handle start month and other months in range
const rate = ratesByType[type].find(r => r.created_at === dateStr);
ratesForRange[type].push(rate ? rate.rate : '');
}
}
});
// Generate labels for chart
const labels = [];
for (let i = start.getDate(); i <= end.getDate(); i++) {
if (i === end.getDate() && startMonth !== endMonth) {
// Handle end month
const endMonthDays = new Date(endYear, endMonth, 0).getDate();
for (let j = 1; j <= end.getDate(); j++) {
labels.push(`${j.toString().padStart(2, '0')}-${endMonth.toString().padStart(2, '0')}-${endYear}`);
}
} else {
// Handle start month and other months in range
labels.push(`${i.toString().padStart(2, '0')}-${startMonth.toString().padStart(2, '0')}-${startYear}`);
}
}
// Generate datasets for chart
const datasets = [];
Object.keys(ratesForRange).forEach(type => {
datasets.push({
label: `${this.paymentMethodsConst[type]}`,
data: ratesForRange[type],
borderColor: this.colors[type],
fill: false
});
});
setTimeout(() => {
const ctx = document.getElementById("currency-history-chart");
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: datasets
},
});
}, 300);
}
},
created() {
this.$store.dispatch('updateListQueue', { 'name': this.section });
},
validations: {
filters: {
date_from: {},
date_to: {},
},
},
methods: {
fetchRateLogs() {
this.isLoading = true;
this.submit(route('api.currency.history.list') + '?filters=' + JSON.stringify(this.filters), 'get', this.section, false, false)
},
resetSarch() {
var currentDate = new Date();
this.filters.date_to =this.formatDate(new Date(currentDate.setDate(currentDate.getDate() + 3)));
this.filters.date_from =this.formatDate(new Date(currentDate.setDate(currentDate.getDate() - 6)));
},
updateCurrencyId(id){
this.filters.currency_id = id;
},
updateServiceId(id){
this.filters.service_id = id;
},
successHandler(response) {
this.isLoading = false;
this.rateHistory = response.payload.data;
},
formatDate($date) {
let d = new Date($date);
let ye = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(d);
let mo = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(d);
let da = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(d);
return(`${da}-${mo}-${ye}`);
},
errorHandler(error){
this.isLoading = false;
this.hasError = true;
// this.error = error.message;
}
},
}
</script>
@@ -261,6 +261,14 @@
</a>
</div>
</div>
<div class="row m-t-15" v-if="$store.getters.isAdmin && booking.service.id === 4 && booking.documents.ecommerce_purchase_order">
<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="deletePo">Delete PO</div>
</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deletePo">
<delete-po-form-component :data="booking" :section="section" class="text-center"></delete-po-form-component>
</modal-component>
</div>
<div class="row m-b-25" v-if="$store.getters.isAdmin && booking.service.id === 4 && booking.status !== 3">
<div class="col">
<div class="row" v-if="!booking.documents.ecommerce_purchase_order">
@@ -9,11 +9,19 @@
<div class="col">
<div class="row">
<div class="col">
<div class="row align-items-center">
<div class="row align-items-center parentContainer">
<div class="col-auto">
<div class="row">
<div class="col">
<div class="font-heading fs-14 bold">{{item.name}}</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="changeCustomerName">
<change-customer-name-form-component :section="'customerProfileSection'" :data="item"></change-customer-name-form-component>
</modal-component>
<div class="font-heading fs-14 bold">
{{item.name}}
<div class="btn btn-xs b-rad-none pointer requestModal d-inline rounded no-border hover-primary" data-type="changeCustomerName" >
<i class="fa fa-edit pointer fa-fw fs-15 m-l-5"></i>
</div>
</div>
</div>
</div>
<div class="row">
@@ -93,4 +101,4 @@
export default {
mixins: [componentHandler]
}
</script>
</script>
@@ -0,0 +1,73 @@
<template>
<div class="row" style="width: 450px; margin: auto;" @keyup.enter="submitForm">
<div class="col bg-white padding-40 b-rad-lg">
<div class="row m-b-10">
<div class="col text-center">
<h3>Edit Company Details</h3>
</div>
</div>
<div class="row">
<div class="col">
<validation-wrapper-component class="m-b-15" :validator="$v.parameters.name">
<label class="text-primary">Name</label>
<input class="form-control" v-model="parameters.name">
</validation-wrapper-component>
</div>
</div>
<div class="row">
<div class="col">
<validation-wrapper-component class="m-b-15" :validator="$v.parameters.debtor">
<label class="text-primary">Debtor Code</label>
<input class="form-control" v-model="parameters.debtor">
</validation-wrapper-component>
</div>
</div>
<div class="row m-t-15">
<div class="col-auto p-r-5">
<div class="btn btn-lg btn-default b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-primary w-100 btn-lg" @click="submitForm">Confirm</div>
</div>
</div>
</div>
</div>
</template>
<script>
import modalFormHandler from '../../../general/mixins/modalFormHandler';
import { required, minLength } from "vuelidate/lib/validators";
export default {
data() {
return {
parameters: {
id: this.data.id,
name: this.data.name,
debtor: this.data.debtor,
reference: this.data.reference,
type: this.data.type,
}
};
},
validations: {
parameters: {
name: {
required,
// minLength: minLength(8)
},
debtor: {
},
}
},
methods: {
successHandler(response) {
window.location.replace(this.route('customers', response.payload.data.reference));
},
submitForm() {
this.submit(this.route('api.company.update.nameAndDebtor', this.data.id), 'put', this.section, true, true)
}
},
mixins: [modalFormHandler]
}
</script>
@@ -0,0 +1,8 @@
@extends('layouts.base_portal')
@section('inner_content')
<div class="row">
<div class="col p-t-15 p-b-15">
<rate-histories-component :payment-methods="{{ json_encode($paymentMethods) }}"></rate-histories-component>
</div>
</div>
@endsection
+1
View File
@@ -28,6 +28,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking
Route::post('{id}/purchase_order/verification', 'ApprovePurchaseOrderController@approve')->name('po.approval');
Route::post('{id}/purchase_order/pdf', 'UploadPurchaseOrderController@upload')->name('po.pdf');
Route::delete('{id}/purchase_order/pdf', 'DeletePurchaseOrderPdfController@delete')->name('po.pdf.delete');
Route::put('{id}/updateAmount', 'UpdateBookingAmountController@update')->name('booking_amount.update');
+1
View File
@@ -9,6 +9,7 @@ Route::group(['prefix' => 'company', 'as' => 'company.', 'namespace' => 'Compani
Route::put('/update/{id}', 'UpdateCompanyController@update')->name('update');
Route::put('update/{id}/status', 'UpdateCompanyStatusController@update')->name('status.update');
Route::delete('/delete/{id}', 'DeleteCompanyController@destroy')->name('delete');
Route::put('/name-and-debtor/update/{id}', 'UpdateCompanyNameAndDebtorController@update')->name('update.nameAndDebtor');
Route::put('/update/debtor/{id}', 'UpdateCompanyDebtorController@update')->name('delete');
+5 -1
View File
@@ -7,4 +7,8 @@ Route::group(['namespace' => 'Currencies', 'as' => 'currency.', 'prefix' => 'cur
Route::get('/list', 'ListCurrencyController@list')->name('list');
Route::post('/create', 'CreateCurrencyController@create')->name('create');
Route::delete('/delete/{id}', 'DeleteCurrencyController@delete')->name('delete');
});
Route::group(['prefix' => 'history', 'namespace' => 'History', 'as' => 'history.'], function () {
Route::get('/list', 'ListCurrencyRateHistory@list')->name('list');
});
});
+17 -12
View File
@@ -1,26 +1,27 @@
<?php
use App\Classes\Modules\Bookings\Processors\CreatePurchaseOrderFor1688OrderProcessor;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use Carbon\Carbon;
use App\Models\User;
use App\Models\Wallet;
use App\Models\Booking;
use App\Models\Company;
use App\Models\Transaction;
use App\Models\User;
use App\Models\Wallet;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Excel;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Excel;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use Webklex\PDFMerger\Facades\PDFMergerFacade as PDFMerger;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Bookings\Processors\CreatePurchaseOrderFor1688OrderProcessor;
/*
|--------------------------------------------------------------------------
@@ -538,5 +539,9 @@ Route::get('/refund/fix', function(){
});
Route::get('/currency-rate-history', function () {
$paymentMethods = PaymentMethodType::PAYMENT_METHODS;
return view('pages.rate_histories')->with('paymentMethods', $paymentMethods);
})->name('currency_rate.history');