Feat: Create Customer Modal

This commit is contained in:
Rodia 2024-10-26 12:57:14 -05:00
parent 91f3d897e5
commit 18df5742d5
4 changed files with 251 additions and 135 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z"/></svg>

After

Width:  |  Height:  |  Size: 576 B

View File

@ -0,0 +1,86 @@
<template>
<v-dialog v-model="showModal" max-width="600px">
<v-card>
<v-card-title>
<span class="headline">Información del Cliente</span>
</v-card-title>
<v-card-text>
<v-form ref="form" v-model="valid">
<v-text-field
v-model="customer.name"
label="Nombre"
:rules="[rules.required]"
required
></v-text-field>
<v-text-field
v-model="customer.email"
label="Correo Electrónico"
:rules="[rules.required, rules.email]"
required
></v-text-field>
<v-text-field
v-model="customer.phone"
label="Teléfono"
:rules="[rules.required]"
required
></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="closeModal">Cancelar</v-btn>
<v-btn color="blue darken-1" text @click="submitForm">Guardar</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
data() {
return {
showModal: false,
valid: false,
customer: {
name: '',
email: '',
phone: ''
},
rules: {
required: value => !!value || 'Este campo es requerido.',
email: value => {
const pattern = /^[^ ]+@[^ ]+\.[a-z]{2,3}$/;
return pattern.test(value) || 'El correo no es válido.';
}
}
};
},
methods: {
openModal() {
this.showModal = true;
},
closeModal() {
this.showModal = false;
this.resetForm();
},
submitForm() {
if (this.$refs.form.validate()) {
// Aquí puedes manejar el envío del formulario
console.log('Cliente guardado:', this.customer);
this.closeModal();
}
},
resetForm() {
this.customer = {
name: '',
email: '',
phone: ''
};
this.$refs.form.reset();
}
}
};
</script>
<style scoped>
</style>

View File

@ -0,0 +1,19 @@
<template>
<div class="modal">
<div class="head">
<p>Nuevo Movimiento</p>
<img @click="close" src="@/assets/close-icon.svg" alt="cerrar"/>
</div>
<div class="body">
<slot></slot>
</div>
</div>
</template>
<script setup>
import { defineEmits } from "vue";
const emit = defineEmits(["close"]);
const close = () => emit("close");
</script>

View File

@ -15,10 +15,12 @@
required
class="mr-4"
></v-autocomplete>
<v-btn color="primary" @click="openModal">Agregar Cliente</v-btn>
<CreateCustomerModal ref="customerModal" />
</v-col>
<v-col
lg="2"
>
>
<v-text-field
v-model="purchase.date"
label="Fecha"
@ -112,141 +114,149 @@
</template>
<script>
export default {
name: 'DonConfiao',
props: {
msg: String
},
data() {
return {
valid: false,
client_search: '',
product_search: '',
purchase: {
date: this.getCurrentDate(),
client: null,
notes: '',
saleline_set: [{product:'', unit_price: 0, quantity: 0}],
},
rules: {
required: value => !!value || 'Requerido.',
},
menuItems: [
{ title: 'Inicio', route: '/'},
{ title: 'Compras', route:'/compras'},
],
clients: [],
products: [],
};
},
created() {
this.fetchClients();
this.fetchProducts();
},
watch: {
group () {
this.drawer = false
},
},
computed: {
calculateTotal() {
return this.purchase.saleline_set.reduce((total, saleline) => {
return total + this.calculateSubtotal(saleline);
}, 0);
},
filteredClients() {
return this.clients.filter(client => {
if (this.client_search === '') {
return [];
} else {
return client.name.toLowerCase().includes(this.client_search.toLowerCase());
}
});
},
filteredProducts() {
return this.products.filter(product => {
if (this.product_search === '') {
return [];
} else {
return product.name.toLowerCase().includes(this.product_search.toLowerCase());
}
});
},
},
methods: {
getCurrentDate() {
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, '0');
const dd = String(today.getDate()).padStart(2, '0');
return `${yyyy}-${mm}-${dd}`;
},
import CustomerForm from './CreateCustomerModal.vue';
onProductChange(index) {
const selectedProductId = this.purchase.saleline_set[index].product;
const selectedProduct = this.products.find(p => p.id == selectedProductId);
this.purchase.saleline_set[index].unit_price = selectedProduct.price;
},
fetchClients() {
fetch('/don_confiao/api/customers/')
.then(response => response.json())
.then(data => {
this.clients = data;
})
.catch(error => {
console.error(error);
});
},
fetchProducts() {
fetch('/don_confiao/api/products/')
.then(response => response.json())
.then(data => {
console.log(data);
this.products = data;
})
.catch(error => {
console.error(error);
});
},
addLine() {
this.purchase.saleline_set.push({ product: '', unit_price: 0, quantity:0 });
},
removeLine(index) {
this.purchase.saleline_set.splice(index, 1);
},
calculateSubtotal(line) {
return line.unit_price * line.quantity;
},
async submit() {
if (this.$refs.form.validate()) {
try {
const response = await fetch('/don_confiao/api/sales/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(this.purchase),
});
if (response.ok) {
const data = await response.json();
console.log('Compra enviada:', data);
this.$router.push("SummaryPurchase");
} else {
console.error('Error al enviar la compra:', response.statusText);
}
} catch (error) {
console.error('Error de red:', error);
}
}
},
navigate(route) {
this.$router.push(route);
},
formatPrice(price) {
return new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'COP' }).format(price);
},
},
};
export default {
name: 'DonConfiao',
components: {
CustomerForm
},
props: {
msg: String
},
data() {
return {
valid: false,
client_search: '',
product_search: '',
purchase: {
date: this.getCurrentDate(),
client: null,
notes: '',
saleline_set: [{product:'', unit_price: 0, quantity: 0}],
},
rules: {
required: value => !!value || 'Requerido.',
},
menuItems: [
{ title: 'Inicio', route: '/'},
{ title: 'Compras', route:'/compras'},
],
clients: [],
products: [],
};
},
created() {
this.fetchClients();
this.fetchProducts();
},
watch: {
group () {
this.drawer = false
},
},
computed: {
calculateTotal() {
return this.purchase.saleline_set.reduce((total, saleline) => {
return total + this.calculateSubtotal(saleline);
}, 0);
},
filteredClients() {
return this.clients.filter(client => {
if (this.client_search === '') {
return [];
} else {
return client.name.toLowerCase().includes(this.client_search.toLowerCase());
}
});
},
filteredProducts() {
return this.products.filter(product => {
if (this.product_search === '') {
return [];
} else {
return product.name.toLowerCase().includes(this.product_search.toLowerCase());
}
});
},
},
methods: {
openModal() {
this.$refs.customerModal.openModal();
},
getCurrentDate() {
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, '0');
const dd = String(today.getDate()).padStart(2, '0');
return `${yyyy}-${mm}-${dd}`;
},
onProductChange(index) {
const selectedProductId = this.purchase.saleline_set[index].product;
const selectedProduct = this.products.find(p => p.id == selectedProductId);
this.purchase.saleline_set[index].unit_price = selectedProduct.price;
},
fetchClients() {
fetch('/don_confiao/api/customers/')
.then(response => response.json())
.then(data => {
this.clients = data;
})
.catch(error => {
console.error(error);
});
},
fetchProducts() {
fetch('/don_confiao/api/products/')
.then(response => response.json())
.then(data => {
console.log(data);
this.products = data;
})
.catch(error => {
console.error(error);
});
},
addLine() {
this.purchase.saleline_set.push({ product: '', unit_price: 0, quantity:0 });
},
removeLine(index) {
this.purchase.saleline_set.splice(index, 1);
},
calculateSubtotal(line) {
return line.unit_price * line.quantity;
},
async submit() {
if (this.$refs.form.validate()) {
try {
const response = await fetch('/don_confiao/api/sales/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(this.purchase),
});
if (response.ok) {
const data = await response.json();
console.log('Compra enviada:', data);
this.$router.push("SummaryPurchase");
} else {
console.error('Error al enviar la compra:', response.statusText);
}
} catch (error) {
console.error('Error de red:', error);
}
}
},
navigate(route) {
this.$router.push(route);
},
formatPrice(price) {
return new Intl.NumberFormat('es-ES', { style: 'currency', currency: 'COP' }).format(price);
},
},
};
</script>
<style>
</style>