forked from verdnatura/salix-front
Merge pull request 'Se crea formulario de creacion de cliente' (#34) from features/ms_63_client_create into dev
Reviewed-on: hyervoni/salix-front-mindshore#34
This commit is contained in:
commit
4c55896dfb
|
@ -0,0 +1,244 @@
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import CustomerCreateNewPostcode from './CustomerCreateNewPostcode.vue';
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import FormModel from 'components/FormModel.vue';
|
||||||
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const newClientForm = reactive({
|
||||||
|
active: true,
|
||||||
|
name: null,
|
||||||
|
salesPersonFk: null,
|
||||||
|
businessTypeFk: null,
|
||||||
|
fi: null,
|
||||||
|
socialName: null,
|
||||||
|
street: null,
|
||||||
|
postcode: null,
|
||||||
|
city: null,
|
||||||
|
provinceFk: null,
|
||||||
|
countryFk: null,
|
||||||
|
userName: null,
|
||||||
|
email: null,
|
||||||
|
isEqualizated: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const workersOptions = ref([]);
|
||||||
|
const businessTypesOptions = ref([]);
|
||||||
|
const citiesLocationOptions = ref([]);
|
||||||
|
const provincesLocationOptions = ref([]);
|
||||||
|
const countriesOptions = ref([]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (workersOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="Workers/search?departmentCodes"
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (businessTypesOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="BusinessTypes"
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (citiesLocationOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="Towns/location"
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (provincesLocationOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="Provinces/location"
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (countriesOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="Countries"
|
||||||
|
/>
|
||||||
|
<QPage>
|
||||||
|
<QToolbar class="bg-vn-dark">
|
||||||
|
<div id="st-data"></div>
|
||||||
|
<QSpace />
|
||||||
|
<div id="st-actions"></div>
|
||||||
|
</QToolbar>
|
||||||
|
<FormModel
|
||||||
|
:form-initial-data="newClientForm"
|
||||||
|
:observe-form-changes="false"
|
||||||
|
model="client"
|
||||||
|
url-create="Clients/createWithUser"
|
||||||
|
>
|
||||||
|
<template #form="{ data, validate }">
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QInput :label="t('Comercial name')" v-model="data.name" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('Salesperson')"
|
||||||
|
:options="workersOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
v-model="data.salesPersonFk"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('Business type')"
|
||||||
|
:options="businessTypesOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="description"
|
||||||
|
option-value="code"
|
||||||
|
v-model="data.businessTypeFk"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<QInput v-model="data.fi" :label="t('Tax number')" />
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QInput
|
||||||
|
:label="t('Business name')"
|
||||||
|
:rules="validate('Client.socialName')"
|
||||||
|
v-model="data.socialName"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QInput
|
||||||
|
:label="t('Street')"
|
||||||
|
:rules="validate('Client.street')"
|
||||||
|
v-model="data.street"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QInput v-model="data.postcode" :label="t('Postcode')">
|
||||||
|
<template #append>
|
||||||
|
<QBtn
|
||||||
|
class="cursor-pointer"
|
||||||
|
color="primary"
|
||||||
|
dense
|
||||||
|
icon="add"
|
||||||
|
round
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QPopupProxy
|
||||||
|
cover
|
||||||
|
transition-hide="scale"
|
||||||
|
transition-show="scale"
|
||||||
|
>
|
||||||
|
<CustomerCreateNewPostcode />
|
||||||
|
</QPopupProxy>
|
||||||
|
</QBtn>
|
||||||
|
</template>
|
||||||
|
</QInput>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<!-- ciudades -->
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('City')"
|
||||||
|
:options="citiesLocationOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="name"
|
||||||
|
option-value="name"
|
||||||
|
v-model="data.city"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{ scope.opt.name }}</QItemLabel>
|
||||||
|
<QItemLabel caption>
|
||||||
|
{{
|
||||||
|
`${scope.opt.name}, ${scope.opt.province.name} (${scope.opt.province.country.country})`
|
||||||
|
}}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelectFilter>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('Province')"
|
||||||
|
:options="provincesLocationOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
v-model="data.provinceFk"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>{{
|
||||||
|
`${scope.opt.name} (${scope.opt.country.country})`
|
||||||
|
}}</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelectFilter>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('Country')"
|
||||||
|
:options="countriesOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="country"
|
||||||
|
option-value="id"
|
||||||
|
v-model="data.countryFk"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QInput v-model="data.userName" :label="t('Web user')" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<QInput v-model="data.email" :label="t('Email')" />
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<QCheckbox
|
||||||
|
:label="t('Is equalizated')"
|
||||||
|
v-model="newClientForm.isEqualizated"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</FormModel>
|
||||||
|
</QPage>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
|
grid-gap: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
Comercial name: Nombre comercial
|
||||||
|
Salesperson: Comercial
|
||||||
|
Business type: Tipo de negocio
|
||||||
|
Tax number: NIF / CIF
|
||||||
|
Business name: Razón social
|
||||||
|
Street: Dirección fiscal
|
||||||
|
Postcode: Código postal
|
||||||
|
City: Población
|
||||||
|
Province: Provincia
|
||||||
|
Country: País
|
||||||
|
Web user: Usuario web
|
||||||
|
Email: Email
|
||||||
|
Is equalizated: Recargo de equivalencia
|
||||||
|
</i18n>
|
|
@ -0,0 +1,143 @@
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import FetchData from 'components/FetchData.vue';
|
||||||
|
import useNotify from 'src/composables/useNotify';
|
||||||
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||||
|
|
||||||
|
const { notify } = useNotify();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
city: null,
|
||||||
|
code: null,
|
||||||
|
countryFk: null,
|
||||||
|
provinceFk: null,
|
||||||
|
townFk: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const countriesOptions = ref([]);
|
||||||
|
const isLoading = ref(false);
|
||||||
|
const provincesOptions = ref([]);
|
||||||
|
const townsLocationOptions = ref([]);
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
isLoading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { city, code, countryFk, provinceFk } = data;
|
||||||
|
const payload = {
|
||||||
|
city: city.name,
|
||||||
|
code,
|
||||||
|
countryFk,
|
||||||
|
provinceFk,
|
||||||
|
townFk: city.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
await axios.patch('/postcodes', payload);
|
||||||
|
} catch (err) {
|
||||||
|
notify('errors.create', 'negative');
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (townsLocationOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="Towns/location"
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (provincesOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="Provinces"
|
||||||
|
/>
|
||||||
|
<FetchData
|
||||||
|
@on-fetch="(data) => (countriesOptions = data)"
|
||||||
|
auto-load
|
||||||
|
url="Countries"
|
||||||
|
/>
|
||||||
|
<div class="q-pa-lg">
|
||||||
|
<h6 class="q-my-xs">{{ t('New postcode') }}</h6>
|
||||||
|
<p>{{ t('Please, ensure you put the correct data!') }}</p>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-md">
|
||||||
|
<div class="col">
|
||||||
|
<QInput label="Postcode" v-model="data.code" />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('City')"
|
||||||
|
:options="townsLocationOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="name"
|
||||||
|
option-value="city"
|
||||||
|
v-model="data.city"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-gutter-md q-mb-xl">
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('Province')"
|
||||||
|
:options="provincesOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
v-model="data.provinceFk"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelectFilter
|
||||||
|
:label="t('Country')"
|
||||||
|
:options="countriesOptions"
|
||||||
|
hide-selected
|
||||||
|
option-label="country"
|
||||||
|
option-value="id"
|
||||||
|
v-model="data.countryFk"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<QBtn
|
||||||
|
:label="t('globals.cancel')"
|
||||||
|
class="q-mr-lg"
|
||||||
|
color="primary"
|
||||||
|
outline
|
||||||
|
v-close-popup
|
||||||
|
/>
|
||||||
|
<QBtn
|
||||||
|
:label="t('globals.save')"
|
||||||
|
@click="save"
|
||||||
|
color="primary"
|
||||||
|
v-close-popup
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<QInnerLoading
|
||||||
|
:showing="isLoading"
|
||||||
|
:label="t('globals.pleaseWait')"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
|
grid-gap: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
New postcode: Nuevo código postal
|
||||||
|
Please, ensure you put the correct data!: ¡Por favor, asegúrese de poner los datos correctos!
|
||||||
|
City: Ciudad
|
||||||
|
Province: Provincia
|
||||||
|
Country: País
|
||||||
|
</i18n>
|
|
@ -28,25 +28,29 @@ function viewSummary(id) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const redirectToCreateView = () => {
|
||||||
|
router.push({ name: 'CustomerCreate' });
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<template v-if="stateStore.isHeaderMounted()">
|
<template v-if="stateStore.isHeaderMounted()">
|
||||||
<Teleport to="#searchbar">
|
<Teleport to="#searchbar">
|
||||||
<VnSearchbar
|
<VnSearchbar
|
||||||
data-key="CustomerList"
|
|
||||||
:label="t('Search customer')"
|
|
||||||
:info="t('You can search by customer id or name')"
|
:info="t('You can search by customer id or name')"
|
||||||
|
:label="t('Search customer')"
|
||||||
|
data-key="CustomerList"
|
||||||
/>
|
/>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
<Teleport to="#actions-append">
|
<Teleport to="#actions-append">
|
||||||
<div class="row q-gutter-x-sm">
|
<div class="row q-gutter-x-sm">
|
||||||
<QBtn
|
<QBtn
|
||||||
flat
|
|
||||||
@click="stateStore.toggleRightDrawer()"
|
@click="stateStore.toggleRightDrawer()"
|
||||||
round
|
|
||||||
dense
|
dense
|
||||||
|
flat
|
||||||
icon="menu"
|
icon="menu"
|
||||||
|
round
|
||||||
>
|
>
|
||||||
<QTooltip bottom anchor="bottom right">
|
<QTooltip bottom anchor="bottom right">
|
||||||
{{ t('globals.collapseMenu') }}
|
{{ t('globals.collapseMenu') }}
|
||||||
|
@ -55,7 +59,7 @@ function viewSummary(id) {
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
</template>
|
</template>
|
||||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
|
<QDrawer :width="256" show-if-above side="right" v-model="stateStore.rightDrawer">
|
||||||
<QScrollArea class="fit text-grey-8">
|
<QScrollArea class="fit text-grey-8">
|
||||||
<CustomerFilter data-key="CustomerList" />
|
<CustomerFilter data-key="CustomerList" />
|
||||||
</QScrollArea>
|
</QScrollArea>
|
||||||
|
@ -63,18 +67,18 @@ function viewSummary(id) {
|
||||||
<QPage class="column items-center q-pa-md">
|
<QPage class="column items-center q-pa-md">
|
||||||
<div class="card-list">
|
<div class="card-list">
|
||||||
<VnPaginate
|
<VnPaginate
|
||||||
data-key="CustomerList"
|
|
||||||
url="/Clients/filter"
|
|
||||||
order="id DESC"
|
|
||||||
auto-load
|
auto-load
|
||||||
|
data-key="CustomerList"
|
||||||
|
order="id DESC"
|
||||||
|
url="/Clients/filter"
|
||||||
>
|
>
|
||||||
<template #body="{ rows }">
|
<template #body="{ rows }">
|
||||||
<CardList
|
<CardList
|
||||||
v-for="row of rows"
|
:id="row.id"
|
||||||
:key="row.id"
|
:key="row.id"
|
||||||
:title="row.name"
|
:title="row.name"
|
||||||
:id="row.id"
|
|
||||||
@click="navigate(row.id)"
|
@click="navigate(row.id)"
|
||||||
|
v-for="row of rows"
|
||||||
>
|
>
|
||||||
<template #list-items>
|
<template #list-items>
|
||||||
<VnLv :label="t('customer.list.email')" :value="row.email" />
|
<VnLv :label="t('customer.list.email')" :value="row.email" />
|
||||||
|
@ -103,6 +107,12 @@ function viewSummary(id) {
|
||||||
</template>
|
</template>
|
||||||
</VnPaginate>
|
</VnPaginate>
|
||||||
</div>
|
</div>
|
||||||
|
<QPageSticky :offset="[20, 20]">
|
||||||
|
<QBtn @click="redirectToCreateView()" color="primary" fab icon="add" />
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('New client') }}
|
||||||
|
</QTooltip>
|
||||||
|
</QPageSticky>
|
||||||
</QPage>
|
</QPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -117,4 +127,5 @@ function viewSummary(id) {
|
||||||
es:
|
es:
|
||||||
Search customer: Buscar cliente
|
Search customer: Buscar cliente
|
||||||
You can search by customer id or name: Puedes buscar por id o nombre del cliente
|
You can search by customer id or name: Puedes buscar por id o nombre del cliente
|
||||||
|
New client: Nuevo cliente
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -29,6 +29,14 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Customer/CustomerList.vue'),
|
component: () => import('src/pages/Customer/CustomerList.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
name: 'CustomerCreate',
|
||||||
|
meta: {
|
||||||
|
title: 'create',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Customer/CustomerCreate.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'payments',
|
path: 'payments',
|
||||||
name: 'CustomerPayments',
|
name: 'CustomerPayments',
|
||||||
|
|
Loading…
Reference in New Issue