feat: refs #7984 add currency in ticket basic-data
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
parent
f3f0c0e88c
commit
3c6a4c1e16
|
@ -6,7 +6,7 @@ import { ref } from 'vue';
|
||||||
import { watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
|
|
||||||
const model = defineModel({
|
const model = defineModel({
|
||||||
type: [String, Number, Object],
|
type: Number,
|
||||||
default: null,
|
default: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,8 +16,12 @@ const clientId = defineModel('clientId', {
|
||||||
});
|
});
|
||||||
|
|
||||||
const currencyList = ref([]);
|
const currencyList = ref([]);
|
||||||
|
|
||||||
|
const emit = defineEmits(['newValue']);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
currencyList.value = (await axios.get('Currencies')).data;
|
currencyList.value = (await axios.get('Currencies')).data;
|
||||||
|
emitCurrency(model.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -30,6 +34,14 @@ watch(
|
||||||
model.value = data.defaultCurrencyFk;
|
model.value = data.defaultCurrencyFk;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function emitCurrency(id) {
|
||||||
|
if (!id) return;
|
||||||
|
emit(
|
||||||
|
'newValue',
|
||||||
|
currencyList.value?.find((c) => c.id == id)
|
||||||
|
);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -40,5 +52,6 @@ watch(
|
||||||
:options="currencyList"
|
:options="currencyList"
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-caption="code"
|
option-caption="code"
|
||||||
|
@update:model-value="(id) => emitCurrency(id)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -27,26 +27,28 @@ const $props = defineProps({
|
||||||
description: 'find currency code in array data model',
|
description: 'find currency code in array data model',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const arrayData = $props.arrayDataModel && useArrayData($props.arrayDataModel);
|
||||||
const foreignValue = computed(() => $props.model?.[$props.foreignField]);
|
const foreignValue = computed(() => $props.model?.[$props.foreignField]);
|
||||||
const localValue = computed(() => $props.model?.[$props.localField]);
|
const localValue = computed(() => $props.model?.[$props.localField]);
|
||||||
const currency = computed(() => $props.currencyCode ?? currencyCodeModel.value);
|
const currency = computed(
|
||||||
|
() => $props.currencyCode ?? arrayData.store.data?.currency?.code
|
||||||
|
);
|
||||||
const toCurrencyLabel = computed(() =>
|
const toCurrencyLabel = computed(() =>
|
||||||
toCurrency(foreignValue.value ?? localValue.value, currency.value)
|
toCurrency(foreignValue.value ?? localValue.value, currency.value)
|
||||||
);
|
);
|
||||||
const currencyCodeModel = ref();
|
const currencyCodeModel = ref();
|
||||||
|
|
||||||
onMounted(() => {
|
// onMounted(() => {
|
||||||
if ($props.arrayDataModel) {
|
// if ($props.arrayDataModel) {
|
||||||
const arrayData = useArrayData($props.arrayDataModel);
|
// currencyCodeModel.value = arrayData.store.data?.currency?.code;
|
||||||
currencyCodeModel.value = arrayData.store.data?.currency?.code;
|
// }
|
||||||
}
|
// });
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<span :title="toCurrencyLabel">
|
<span :title="toCurrencyLabel" v-if="currency && localValue">
|
||||||
<span v-if="foreignValue">{{ toCurrency(localValue) }} /</span>
|
<span v-if="foreignValue">{{ toCurrencyLabel }} /</span>
|
||||||
{{ toCurrencyLabel }}
|
{{ toCurrency(localValue) }}
|
||||||
</span>
|
</span>
|
||||||
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -22,7 +22,7 @@ export function useVnConfirm() {
|
||||||
{ customHTML: () => h(component, props) }
|
{ customHTML: () => h(component, props) }
|
||||||
),
|
),
|
||||||
}).onOk(async () => {
|
}).onOk(async () => {
|
||||||
if (successFn) successFn();
|
if (successFn) await successFn();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const ORDER_MODEL = 'order';
|
const ORDER_MODEL = 'Order';
|
||||||
|
|
||||||
const isNew = Boolean(!route.params.id);
|
const isNew = Boolean(!route.params.id);
|
||||||
const clientList = ref([]);
|
const clientList = ref([]);
|
||||||
|
@ -56,33 +56,6 @@ const fetchOrderDetails = (order) => {
|
||||||
fetchAgencyList(order?.landed, order?.addressFk);
|
fetchAgencyList(order?.landed, order?.addressFk);
|
||||||
};
|
};
|
||||||
|
|
||||||
const orderFilter = {
|
|
||||||
include: [
|
|
||||||
{ relation: 'agencyMode', scope: { fields: ['name'] } },
|
|
||||||
{
|
|
||||||
relation: 'address',
|
|
||||||
scope: { fields: ['nickname'] },
|
|
||||||
},
|
|
||||||
{ relation: 'rows', scope: { fields: ['id'] } },
|
|
||||||
{
|
|
||||||
relation: 'client',
|
|
||||||
scope: {
|
|
||||||
fields: [
|
|
||||||
'salesPersonFk',
|
|
||||||
'name',
|
|
||||||
'isActive',
|
|
||||||
'isFreezed',
|
|
||||||
'isTaxDataChecked',
|
|
||||||
],
|
|
||||||
include: {
|
|
||||||
relation: 'salesPersonUser',
|
|
||||||
scope: { fields: ['id', 'name'] },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const onClientChange = async (clientId) => {
|
const onClientChange = async (clientId) => {
|
||||||
const { data } = await axios.get(`Clients/${clientId}`);
|
const { data } = await axios.get(`Clients/${clientId}`);
|
||||||
await fetchAddressList(data.defaultAddressFk);
|
await fetchAddressList(data.defaultAddressFk);
|
||||||
|
@ -93,12 +66,9 @@ const onClientChange = async (clientId) => {
|
||||||
<VnSubToolbar v-if="isNew" />
|
<VnSubToolbar v-if="isNew" />
|
||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<FormModel
|
<FormModel
|
||||||
:url="`Orders/${route.params.id}`"
|
|
||||||
:url-update="`Orders/${route.params.id}/updateBasicData`"
|
:url-update="`Orders/${route.params.id}/updateBasicData`"
|
||||||
:model="ORDER_MODEL"
|
:model="ORDER_MODEL"
|
||||||
:filter="orderFilter"
|
|
||||||
@on-fetch="fetchOrderDetails"
|
@on-fetch="fetchOrderDetails"
|
||||||
auto-load
|
|
||||||
>
|
>
|
||||||
<template #form="{ data }">
|
<template #form="{ data }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
|
|
@ -9,9 +9,33 @@ import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
|
||||||
base-url="Orders"
|
base-url="Orders"
|
||||||
:descriptor="OrderDescriptor"
|
:descriptor="OrderDescriptor"
|
||||||
:user-filter="{
|
:user-filter="{
|
||||||
include: {
|
include: [
|
||||||
relation: 'currency',
|
{ relation: 'agencyMode', scope: { fields: ['name'] } },
|
||||||
},
|
{
|
||||||
|
relation: 'address',
|
||||||
|
scope: { fields: ['nickname'] },
|
||||||
|
},
|
||||||
|
{ relation: 'rows', scope: { fields: ['id'] } },
|
||||||
|
{
|
||||||
|
relation: 'client',
|
||||||
|
scope: {
|
||||||
|
fields: [
|
||||||
|
'salesPersonFk',
|
||||||
|
'name',
|
||||||
|
'isActive',
|
||||||
|
'isFreezed',
|
||||||
|
'isTaxDataChecked',
|
||||||
|
],
|
||||||
|
include: {
|
||||||
|
relation: 'salesPersonUser',
|
||||||
|
scope: { fields: ['id', 'name'] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'currency',
|
||||||
|
},
|
||||||
|
],
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import FetchData from 'components/FetchData.vue';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { toCurrency } from 'filters/index';
|
import { toCurrency } from 'filters/index';
|
||||||
import { useRole } from 'src/composables/useRole';
|
import { useRole } from 'src/composables/useRole';
|
||||||
|
import VnCurrency from 'src/components/ui/VnCurrency.vue';
|
||||||
|
|
||||||
const haveNegatives = defineModel('haveNegatives', { type: Boolean, required: true });
|
const haveNegatives = defineModel('haveNegatives', { type: Boolean, required: true });
|
||||||
const formData = defineModel({ type: Object, required: true });
|
const formData = defineModel({ type: Object, required: true });
|
||||||
|
@ -18,7 +19,7 @@ const { t } = useI18n();
|
||||||
const { hasAny } = useRole();
|
const { hasAny } = useRole();
|
||||||
|
|
||||||
const ticketUpdateActions = ref(null);
|
const ticketUpdateActions = ref(null);
|
||||||
const rows = computed(() => formData.value?.sale?.items || []);
|
const rows = computed(() => formData.value?.ticket?.sales || []);
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
|
@ -83,20 +84,6 @@ const loadDefaultTicketAction = () => {
|
||||||
formData.value.option = isSalesAssistant ? 'mana' : 'renewPrices';
|
formData.value.option = isSalesAssistant ? 'mana' : 'renewPrices';
|
||||||
};
|
};
|
||||||
|
|
||||||
const totalPrice = computed(() => {
|
|
||||||
return rows.value.reduce((acc, item) => acc + item.price * item.quantity, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
const totalNewPrice = computed(() => {
|
|
||||||
return rows.value.reduce(
|
|
||||||
(acc, item) => acc + item.component.newPrice * item.quantity,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const totalDifference = computed(() => {
|
|
||||||
return rows.value.reduce((acc, item) => acc + item.component?.difference || 0, 0);
|
|
||||||
});
|
|
||||||
const showMovableColumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : []));
|
const showMovableColumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : []));
|
||||||
const haveDifferences = computed(() => formData.value.sale?.haveDifferences);
|
const haveDifferences = computed(() => formData.value.sale?.haveDifferences);
|
||||||
async function ticketHaveNegatives() {
|
async function ticketHaveNegatives() {
|
||||||
|
@ -141,17 +128,34 @@ onMounted(async () => {
|
||||||
<QCardSection class="column items-left" horizontal>
|
<QCardSection class="column items-left" horizontal>
|
||||||
<span>
|
<span>
|
||||||
{{ t('basicData.price') }}:
|
{{ t('basicData.price') }}:
|
||||||
{{ toCurrency(totalPrice) }}
|
<VnCurrency
|
||||||
|
:model="formData?.ticket"
|
||||||
|
local-field="totalUnitPrice"
|
||||||
|
foreign-field="totalForeignUnitPrice"
|
||||||
|
:currency-code="formData.currency.code"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<QCardSection class="column items-left" horizontal>
|
<QCardSection class="column items-left" horizontal>
|
||||||
<span>
|
<span>
|
||||||
{{ t('basicData.newPrice') }}: {{ toCurrency(totalNewPrice) }}
|
{{ t('basicData.newPrice') }}:
|
||||||
|
<VnCurrency
|
||||||
|
:model="formData?.ticket"
|
||||||
|
local-field="totalNewPrice"
|
||||||
|
foreign-field="totalForeignNewPrice"
|
||||||
|
:currency-code="formData.currency.code"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<QCardSection class="column items-left" horizontal>
|
<QCardSection class="column items-left" horizontal>
|
||||||
<span>
|
<span>
|
||||||
{{ t('basicData.difference') }}: {{ toCurrency(totalDifference) }}
|
{{ t('basicData.difference') }}:
|
||||||
|
<VnCurrency
|
||||||
|
:model="formData?.ticket"
|
||||||
|
local-field="totalDifference"
|
||||||
|
foreign-field="totalForeignDifference"
|
||||||
|
:currency-code="formData.currency.code"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
</QCard>
|
</QCard>
|
||||||
|
@ -244,5 +248,33 @@ onMounted(async () => {
|
||||||
/>
|
/>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
<template #body-cell-price="{ row }">
|
||||||
|
<QTd class="number">
|
||||||
|
<VnCurrency
|
||||||
|
:model="row.component"
|
||||||
|
:currency-code="formData.currency.code"
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-newPrice="{ row }">
|
||||||
|
<QTd class="number">
|
||||||
|
<VnCurrency
|
||||||
|
:model="row.component"
|
||||||
|
:currency-code="formData.currency.code"
|
||||||
|
local-field="newPrice"
|
||||||
|
foreign-field="newForeignPrice"
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
|
<template #body-cell-difference="{ row }">
|
||||||
|
<QTd class="number">
|
||||||
|
<VnCurrency
|
||||||
|
:model="row.component"
|
||||||
|
:currency-code="formData.currency.code"
|
||||||
|
local-field="difference"
|
||||||
|
foreign-field="foreignDifference"
|
||||||
|
/>
|
||||||
|
</QTd>
|
||||||
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -15,6 +15,7 @@ import useNotify from 'src/composables/useNotify.js';
|
||||||
import { useAcl } from 'src/composables/useAcl';
|
import { useAcl } from 'src/composables/useAcl';
|
||||||
import { useValidator } from 'src/composables/useValidator';
|
import { useValidator } from 'src/composables/useValidator';
|
||||||
import { toTimeFormat } from 'filters/date.js';
|
import { toTimeFormat } from 'filters/date.js';
|
||||||
|
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||||
|
|
||||||
const formData = defineModel({
|
const formData = defineModel({
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -357,7 +358,7 @@ async function getZone(options) {
|
||||||
:rules="validate('basicData.alias')"
|
:rules="validate('basicData.alias')"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('ticketList.company')"
|
:label="t('ticketList.company')"
|
||||||
v-model="formData.companyFk"
|
v-model="formData.companyFk"
|
||||||
|
@ -369,6 +370,12 @@ async function getZone(options) {
|
||||||
:required="true"
|
:required="true"
|
||||||
:rules="validate('ticketList.company')"
|
:rules="validate('ticketList.company')"
|
||||||
/>
|
/>
|
||||||
|
<VnSelectCurrency
|
||||||
|
v-model="formData.currencyFk"
|
||||||
|
@new-value="(value) => (formData.currency = value)"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('basicData.agency')"
|
:label="t('basicData.agency')"
|
||||||
v-model="agencyModeId"
|
v-model="agencyModeId"
|
||||||
|
|
|
@ -77,12 +77,13 @@ const getPriceDifference = async () => {
|
||||||
zoneId: formData.value.zoneFk,
|
zoneId: formData.value.zoneFk,
|
||||||
warehouseId: formData.value.warehouseFk,
|
warehouseId: formData.value.warehouseFk,
|
||||||
shipped: formData.value.shipped,
|
shipped: formData.value.shipped,
|
||||||
|
currencyId: formData.value.currencyFk,
|
||||||
};
|
};
|
||||||
const { data } = await axios.post(
|
const { data } = await axios.post(
|
||||||
`tickets/${formData.value.id}/priceDifference`,
|
`tickets/${formData.value.id}/priceDifference`,
|
||||||
params
|
params
|
||||||
);
|
);
|
||||||
formData.value.sale = data;
|
formData.value.ticket = data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
|
@ -102,6 +103,7 @@ const submit = async () => {
|
||||||
option: formData.value.option,
|
option: formData.value.option,
|
||||||
isWithoutNegatives: formData.value.withoutNegatives,
|
isWithoutNegatives: formData.value.withoutNegatives,
|
||||||
withWarningAccept: formData.value.withWarningAccept,
|
withWarningAccept: formData.value.withWarningAccept,
|
||||||
|
currencyFk: formData.value.currencyFk,
|
||||||
keepPrice: false,
|
keepPrice: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,7 +121,7 @@ const submit = async () => {
|
||||||
|
|
||||||
const submitWithNegatives = async () => {
|
const submitWithNegatives = async () => {
|
||||||
formData.value.withWarningAccept = true;
|
formData.value.withWarningAccept = true;
|
||||||
submit();
|
await submit();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onNextStep = async () => {
|
const onNextStep = async () => {
|
||||||
|
@ -136,7 +138,7 @@ const onNextStep = async () => {
|
||||||
t('basicData.negativesConfirmMessage'),
|
t('basicData.negativesConfirmMessage'),
|
||||||
submitWithNegatives
|
submitWithNegatives
|
||||||
);
|
);
|
||||||
else submit();
|
else await submit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ import { toTimeFormat } from 'src/filters/date';
|
||||||
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||||
import TicketProblems from 'src/components/TicketProblems.vue';
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
import VnSection from 'src/components/common/VnSection.vue';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
import VnSelectCompany from 'src/components/common/VnSelectCompany.vue';
|
||||||
|
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -636,43 +638,45 @@ function setReference(data) {
|
||||||
</VnSelect>
|
</VnSelect>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<div class="col">
|
<VnInputDate
|
||||||
<VnInputDate
|
placeholder="dd-mm-aaa"
|
||||||
placeholder="dd-mm-aaa"
|
:label="t('globals.landed')"
|
||||||
:label="t('globals.landed')"
|
v-model="data.landed"
|
||||||
v-model="data.landed"
|
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<div class="col">
|
<VnSelect
|
||||||
<VnSelect
|
url="Warehouses"
|
||||||
url="Warehouses"
|
:sort-by="['name']"
|
||||||
:sort-by="['name']"
|
:label="t('globals.warehouse')"
|
||||||
:label="t('globals.warehouse')"
|
v-model="data.warehouseId"
|
||||||
v-model="data.warehouseId"
|
:options="warehousesOptions"
|
||||||
:options="warehousesOptions"
|
option-value="id"
|
||||||
option-value="id"
|
option-label="name"
|
||||||
option-label="name"
|
hide-selected
|
||||||
hide-selected
|
required
|
||||||
required
|
@update:model-value="() => fetchAvailableAgencies(data)"
|
||||||
@update:model-value="() => fetchAvailableAgencies(data)"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<div class="col">
|
<VnSelect
|
||||||
<VnSelect
|
:label="t('globals.agency')"
|
||||||
:label="t('globals.agency')"
|
v-model="data.agencyModeId"
|
||||||
v-model="data.agencyModeId"
|
:options="agenciesOptions"
|
||||||
:options="agenciesOptions"
|
option-value="agencyModeFk"
|
||||||
option-value="agencyModeFk"
|
option-label="agencyMode"
|
||||||
option-label="agencyMode"
|
hide-selected
|
||||||
hide-selected
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
<VnSelectCompany
|
||||||
|
v-model="data.companyId"
|
||||||
|
v-model:client-id="data.clientId"
|
||||||
|
/>
|
||||||
|
<VnSelectCurrency
|
||||||
|
v-model="data.currencyId"
|
||||||
|
v-model:client-id="data.clientId"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue