mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
Merge branch 'dillon/137-project-upgrade-update-1A' into vapor/test
This commit is contained in:
@@ -146,14 +146,19 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
$service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge();
|
||||
}
|
||||
|
||||
// refund service charges if booking is not E2E
|
||||
|
||||
$refundTotal = $refundAmount;
|
||||
|
||||
if ($booking->service_id !== 5) {
|
||||
$refundTotal = $refundTotal + $service_charges_to_refund + $transaction->tax;
|
||||
} else {
|
||||
$service_charges_to_refund = 0;
|
||||
}
|
||||
// refund service charges if booking is not E2E - starts
|
||||
// if ($booking->service_id !== 5) {
|
||||
// $refundTotal = $refundTotal + $service_charges_to_refund + $transaction->tax;
|
||||
// } else {
|
||||
// $service_charges_to_refund = 0;
|
||||
// }
|
||||
// refund service charges if booking is not E2E - ends
|
||||
|
||||
//Reinstate refund service charges to all services, no checking if it is E2E or otherwise
|
||||
$refundTotal = $refundTotal + $service_charges_to_refund + $transaction->tax;
|
||||
|
||||
$object = new TransactionObject($billNumber, TransactionType::REFUND, 1, $booking->company->id,
|
||||
1, PaymentMethodType::CASH,
|
||||
|
||||
@@ -133,10 +133,10 @@ class RegenerateInvoiceBookingV2Processor
|
||||
}
|
||||
//for E-INVOICE
|
||||
else {
|
||||
$transaction = $booking->transactions()->whereIn('type', [TransactionType::SUPPLIER_DELIVER])->get();
|
||||
foreach ($transaction as $key => $row) {
|
||||
$this->deletesTransaction->execute($row);
|
||||
}
|
||||
// $transaction = $booking->transactions()->whereIn('type', [TransactionType::SUPPLIER_DELIVER])->get();
|
||||
// foreach ($transaction as $key => $row) {
|
||||
// $this->deletesTransaction->execute($row);
|
||||
// }
|
||||
}
|
||||
|
||||
$document = $booking->documents()->whereIn('document_type', [DocumentType::PURCHASE_ORDER, DocumentType::INVOICE, DocumentType::EINVOICE, DocumentType::DELIVER_ORDER, DocumentType::SUPPLIER_DELIVER_ORDER])->get();
|
||||
|
||||
+26
-18
@@ -347,24 +347,32 @@ class CreateInvoiceTransactionV2Processor
|
||||
}
|
||||
|
||||
if($transactionTypeBill){
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::SUPPLIER_DELIVER,
|
||||
$transactionTypeBill->issuer,
|
||||
$transactionTypeBill->receiver,
|
||||
$transactionTypeBill->recipient_bank_account_id,
|
||||
$transactionTypeBill->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transactionTypeBill->currency_id,
|
||||
$transactionTypeBill->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object);
|
||||
$supplier_deliver_order_transaction = $booking->transactions()
|
||||
->whereIn('type', [TransactionType::SUPPLIER_DELIVER])
|
||||
->complete()
|
||||
->latest()
|
||||
->first();
|
||||
|
||||
if(!$supplier_deliver_order_transaction){
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::SUPPLIER_DELIVER,
|
||||
$transactionTypeBill->issuer,
|
||||
$transactionTypeBill->receiver,
|
||||
$transactionTypeBill->recipient_bank_account_id,
|
||||
$transactionTypeBill->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transactionTypeBill->currency_id,
|
||||
$transactionTypeBill->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$supplier_deliver_order_transaction = $this->createsTransaction->execute($purchaseOrder->booking, $transaction_object);
|
||||
}
|
||||
|
||||
// supply deliver order
|
||||
$this->invoiceDocumentProcessor->execute($supplier_deliver_order_transaction, $purchaseOrder, $supplier, DocumentType::SUPPLIER_DELIVER_ORDER, null);
|
||||
|
||||
@@ -201,7 +201,7 @@ const rules = computed(() => ({
|
||||
},
|
||||
password_confirmation: {
|
||||
required: requiredIf(step.value === 2),
|
||||
sameAs: sameAs(parameters.password)
|
||||
sameAs: sameAs(parameters.password, 'password')
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -126,6 +126,7 @@ const submitForm = () => {
|
||||
successHandler: (response: any) => {
|
||||
isLoading.value = false;
|
||||
if (response.payload.data.payment_method === 5) {
|
||||
closeModal();
|
||||
window.location.href = route('billplz.bill', response.payload.data.payment_reference) + '?auto_submit=true';
|
||||
} else {
|
||||
emit('cancelQuotation');
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="v$.fix_amount">
|
||||
<label class="muted">Booking Amount ({{data.fixed_currency.short_code}})</label>
|
||||
<input type="text" class="form-control" v-model="fix_amount" v-money3="money">
|
||||
<input type="text" class="form-control" v-model.lazy="fix_amount" v-money3="money">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="v$.amount_to_edit">
|
||||
<label class="muted">Booking Amount ({{data.fixed_currency.short_code}})</label>
|
||||
<input type="text" class="form-control" v-model="amount_to_edit" v-money3="money">
|
||||
<input type="text" class="form-control" v-model.lazy="amount_to_edit" v-money3="money">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
@@ -84,6 +84,7 @@ const submitForm = async () => {
|
||||
successHandler: () => {
|
||||
closeModal();
|
||||
formHandler();
|
||||
queueStore.reloadList({ name: "bookingDetailSection" });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -85,6 +85,7 @@ const submitForm = async () => {
|
||||
successHandler: () => {
|
||||
closeModal();
|
||||
formHandler();
|
||||
queueStore.reloadList({ name: "bookingDetailSection" });
|
||||
},
|
||||
errorHandler: (response: any) => {
|
||||
formHandler(response.message);
|
||||
|
||||
+12
-3
@@ -15,7 +15,7 @@
|
||||
<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.transaction.bill.status', item.id, 'pending'), 'put', section, true, true)">Confirm</div>
|
||||
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.transaction.bill.status', item.id, 'pending'), 'put', section, true, true, null, { successHandler })">Confirm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,10 +27,13 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useUiStore } from '@/stores/ui';
|
||||
import { useRequest } from '@/composables/useRequest';
|
||||
import { useFormHandler } from '@/composables/useFormHandler';
|
||||
import { useQueueStore } from '@/stores/queue';
|
||||
import { useComponentHandler } from '@/composables/useComponentHandler';
|
||||
import route from '@/general/functions/router';
|
||||
|
||||
|
||||
const queueStore = useQueueStore();
|
||||
const props = defineProps<{
|
||||
data: any;
|
||||
section: string;
|
||||
@@ -38,6 +41,12 @@ const props = defineProps<{
|
||||
|
||||
const uiStore = useUiStore();
|
||||
const isLoading = computed(() => uiStore.isLoading(props.section));
|
||||
const { submit } = useRequest();
|
||||
const { submit, closeModal } = useFormHandler(props);
|
||||
const { item } = useComponentHandler(props);
|
||||
|
||||
const successHandler = (response: any) => {
|
||||
closeModal();
|
||||
queueStore.reloadList({ name: "bookingDetailSection" });
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
+15
-10
@@ -9,7 +9,7 @@
|
||||
<div class="col">
|
||||
<div class="row m-b-5">
|
||||
<div class="col p-r-0">
|
||||
<div class="btn btn-xs btn-outline-primary btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" @click="selectedSupplier.status = !selectedSupplier.status">
|
||||
<div class="btn btn-xs btn-outline-primary btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" :class="{'disabled': sectionLoading}" @click="!sectionLoading && (dropdownOpen = !dropdownOpen)">
|
||||
<div class="row">
|
||||
<div class="col p-t-5 p-b-5 fs-9">
|
||||
{{selectedSupplier.name}} - {{selectedSupplier.reference}}
|
||||
@@ -17,14 +17,14 @@
|
||||
<div class="col-auto b-l b-success">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col">
|
||||
<i class="fa" :class="[{'fa-angle-down': !selectedSupplier.status}, {'fa-angle-up': selectedSupplier.status}]"></i>
|
||||
<i class="fa" :class="[{'fa-angle-down': !dropdownOpen}, {'fa-angle-up': dropdownOpen}]"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative w-100">
|
||||
<div class="absolute w-100 b-l b-b b-r b-primary" :class="[{'hide': !selectedSupplier.status}]" style="top: 100%; right: 0; z-index: 1;">
|
||||
<div class="absolute w-100 b-l b-b b-r b-primary" :class="[{'hide': !dropdownOpen}]" 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="supplier in suppliers" :key="supplier.id" :data="supplier">
|
||||
@@ -70,17 +70,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import route from '@/general/functions/router';
|
||||
import { useUiStore } from '@/stores/ui';
|
||||
import { useRequest } from '@/composables/useRequest';
|
||||
|
||||
const { submit } = useRequest();
|
||||
const uiStore = useUiStore();
|
||||
|
||||
const sectionLoading = computed(() => uiStore.isLoading('transactionGroupsListPaymentSection'));
|
||||
|
||||
const suppliers = ref<any[]>([]);
|
||||
const dropdownOpen = ref(false);
|
||||
const selectedSupplier = ref<any>({
|
||||
id: '',
|
||||
name: '',
|
||||
status: false
|
||||
name: ''
|
||||
});
|
||||
const payments = ref<any[]>([]);
|
||||
const currencyOrderKey = ref(1);
|
||||
@@ -88,21 +92,22 @@ const currencyOrderKey = ref(1);
|
||||
const successHandler = (response: any) => {
|
||||
suppliers.value = response.payload.data;
|
||||
if (suppliers.value.length > 0) {
|
||||
selectedSupplier.value = { ...suppliers.value[0], status: false };
|
||||
selectedSupplier.value = { ...suppliers.value[0] };
|
||||
}
|
||||
updateList();
|
||||
};
|
||||
|
||||
const updateSupplier = (supplier: any) => {
|
||||
if (supplier !== selectedSupplier.value) {
|
||||
selectedSupplier.value = { ...supplier, status: false };
|
||||
dropdownOpen.value = false;
|
||||
if (supplier.id !== selectedSupplier.value.id) {
|
||||
selectedSupplier.value = { ...supplier };
|
||||
updateList();
|
||||
}
|
||||
};
|
||||
|
||||
const updateList = () => {
|
||||
currencyOrderKey.value++;
|
||||
selectedSupplier.value.status = false;
|
||||
dropdownOpen.value = false;
|
||||
payments.value = [];
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import { required } from '@vuelidate/validators';
|
||||
import route from '@/general/functions/router';
|
||||
|
||||
interface Props {
|
||||
section: string;
|
||||
data: any;
|
||||
}
|
||||
|
||||
@@ -27,11 +28,7 @@ const emit = defineEmits<{
|
||||
(e: 'submit'): void;
|
||||
}>();
|
||||
|
||||
const { parameters, submit } = useFormHandler({
|
||||
data: {
|
||||
name: props.data?.name || ''
|
||||
}
|
||||
});
|
||||
const { parameters, submit } = useFormHandler(props);
|
||||
|
||||
const rules = {
|
||||
parameters: {
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="row d-none" :class="[{'d-flex': authStore.isAdmin}]" v-if="authStore.isAdmin && company" >
|
||||
<div class="col-8">
|
||||
<div class="row d-flex" :class="[{'d-flex': authStore.isAdmin}]" v-if="authStore.isAdmin && company" >
|
||||
<div class="col-md-8">
|
||||
<div class="row m-b-20">
|
||||
<div class="col bg-white p-t-10 p-b-15 p-r-20 shadow-sm">
|
||||
<customer-profile-component :data="company"></customer-profile-component>
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="col">
|
||||
<div class="row tabsContainer">
|
||||
<div class="col">
|
||||
<div class="row m-l-0 m-r-0 d-none d-md-flex">
|
||||
<div class="row m-l-0 m-r-0 d-flex flex-nowrap overflow-auto">
|
||||
<div class="col-7">
|
||||
<div class="row">
|
||||
<div class="col m-r-5">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div v-if="validator?.$error" class="text-danger fs-10">
|
||||
<template v-for="(rule, name) in validator" :key="name">
|
||||
<small class="bold" v-if="typeof rule === 'object' && rule.$invalid">
|
||||
<span class="btn-block">{{ getErrorMessage(name) }}</span>
|
||||
<span class="btn-block">{{ getErrorMessage({ ...rule, $validator: name as unknown as string }) }}</span>
|
||||
</small>
|
||||
</template>
|
||||
</div>
|
||||
@@ -15,6 +15,12 @@ interface Props {
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
interface ValidationErrorItem {
|
||||
$validator: string;
|
||||
$invalid: boolean;
|
||||
$params?: Record<string, any>;
|
||||
}
|
||||
|
||||
const errorMessages: Record<string, string> = {
|
||||
required: 'this field is required',
|
||||
email: 'enter a valid email address',
|
||||
@@ -28,7 +34,23 @@ const errorMessages: Record<string, string> = {
|
||||
numeric: 'this field must be numeric'
|
||||
};
|
||||
|
||||
const getErrorMessage = (name: string | number) => {
|
||||
return errorMessages[name as string] || 'invalid field';
|
||||
const getErrorMessage = (error: ValidationErrorItem): string => {
|
||||
if (!error) return 'invalid value';
|
||||
|
||||
const validatorName = error.$validator;
|
||||
const params = error.$params || {};
|
||||
|
||||
if (validatorName === 'minLength') return `${errorMessages.minLength} ${params.min} characters`;
|
||||
if (validatorName === 'maxLength') return `${errorMessages.maxLength} ${params.max} characters`;
|
||||
if (validatorName === 'sameAs' || validatorName === 'sameAsPassword') {
|
||||
let fieldName = params.otherName || params.eq || 'password';
|
||||
if (fieldName === 'password') fieldName = 'password';
|
||||
return `${errorMessages.sameAs} ${fieldName} field`;
|
||||
}
|
||||
if (validatorName === 'minValue') return `${errorMessages.minValue} ${params.min}`;
|
||||
if (validatorName === 'maxValue') return `${errorMessages.maxValue} ${params.max}`;
|
||||
|
||||
return errorMessages[validatorName] || 'invalid value';
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ const rules = computed(() => ({
|
||||
password: { required, minLength: minLength(6) },
|
||||
password_confirmation: {
|
||||
required,
|
||||
sameAsPassword: sameAs(() => parameters.value.password)
|
||||
sameAsPassword: sameAs(() => parameters.value.password, 'password')
|
||||
},
|
||||
is_internal: {}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ const rules = computed(() => ({
|
||||
password: { required, minLength: minLength(6) },
|
||||
password_confirmation: {
|
||||
required,
|
||||
sameAsPassword: sameAs(passwordRef)
|
||||
sameAsPassword: sameAs(passwordRef, 'password')
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -90,7 +90,7 @@ import { useComponentHandler } from '@/composables/useComponentHandler';
|
||||
import { useFormHandler } from '@/composables/useFormHandler';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { required, requiredIf, minValue } from '@vuelidate/validators';
|
||||
import { required, requiredIf } from '@vuelidate/validators';
|
||||
import route from '@/general/functions/router';
|
||||
|
||||
interface Props {
|
||||
@@ -132,7 +132,7 @@ const rules = computed(() => ({
|
||||
parameters: {
|
||||
amount: {
|
||||
required,
|
||||
minValue: minValue(minAllowedAmount.value)
|
||||
minValue: 0
|
||||
},
|
||||
reference: {
|
||||
required: requiredIf(() => parameters.value.transaction_type !== 0)
|
||||
|
||||
Reference in New Issue
Block a user