update company & crud budgets

This commit is contained in:
Alexandro Uc Santos
2023-12-30 14:41:07 -06:00
parent 7afd77b218
commit 25528cae8f
12 changed files with 380 additions and 48 deletions

View File

@@ -1,10 +1,55 @@
<script setup>
import { useCompanyStore } from '../stores/company';
defineProps({
budget: {
type: Object,
required: true
}
})
defineEmits(['set-budget'])
const companyStore = useCompanyStore();
const handleDeleteBudget = async() => {
Swal.fire({
title: 'Eliminar Presupuesto!',
text: '¿Estás seguro de eliminar este presupuesto?',
icon: 'warning',
showCancelButton: true,
cancelButtonColor: "#d33",
confirmButtonText: 'Eliminar',
cancelButtonText: 'Cancelar',
}).then(async(result) => {
if(result.isConfirmed) {
Swal.fire({
title: 'Por favor espere!',
html: 'Eliminando presupuesto...',// add html attribute if you want or remove
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading()
},
});
const resp = await companyStore.deleteBudgetCompany(props.budget._id);
if(resp != null) {
Swal.fire({
title: "Presupuesto eliminado!",
text: "Tu presupuesto ha sido eliminado exitosamente.",
icon: "success"
});
} else {
Swal.fire({
title: "No eliminado!",
text: "Tu presupuesto no se pudo eliminar, intente más tarde.",
icon: "error"
});
}
}
});
}
</script>
<template>
@@ -32,10 +77,17 @@
</div>
</div>
<div class="card-footer">
<button class="btn-primary-sm radius-sm">
<button
class="btn-primary-sm radius-sm"
@click="handleDeleteBudget"
>
<i class="fa-solid fa-trash" /> <span class="clear-xsm">Eliminar</span>
</button>
<button class="btn-primary-sm radius-sm">
<button
class="btn-primary-sm radius-sm"
@click="$emit('set-budget')"
data-toggle="modal" data-target="#budgetModal"
>
<i class="fa-solid fa-pen-to-square" /> <span class="clear-xsm">Editar</span>
</button>
<button type="button" class="btn btn-dark">

View File

@@ -1,18 +1,72 @@
<script setup>
import { computed, reactive } from 'vue';
import { computed, onMounted, reactive } from 'vue';
import CustomInput from './ui/CustomInput.vue';
import Products from './ui/Products.vue';
import TruckTypes from './ui/TruckTypes.vue';
import { useAuthStore } from '../stores/auth';
import { useCompanyStore } from '../stores/company';
defineProps({
const props = defineProps({
budget: {
type: Object,
required: false
}
})
const budgetForm = reactive({
const authStore = useAuthStore();
const companyStore = useCompanyStore();
onMounted(() => {
console.log('entra onmounted')
console.log(props.budget);
if(props.budget) {
budgetForm.budget_id = props.budget._id;
budgetForm.client = props.budget.client;
budgetForm.material = props.budget.material._id;
budgetForm.origin = props.budget.origin;
budgetForm.destination = props.budget.destination;
// let product = props.budget.material.name;
// budgetForm.budgetproduct = {
// name: product
// }
budgetForm.budgetproduct = props.budget.material
budgetForm.budgetTrucktypes = props.budget.truck_type
// let truck_type = props.budget.truck_type;
// budgetForm.budgetTrucktypes = {
// meta_value: truck_type
// }
budgetForm.num_tons = props.budget.num_tons;
budgetForm.price_per_ton = props.budget.price_per_ton;
budgetForm.tonnage = props.budget.tonnage;
budgetForm.pickup_distance = props.budget.pickup_distance;
budgetForm.delivery_distance = props.budget.delivery_distance;
budgetForm.warehouse_distance = props.budget.warehouse_distance;
budgetForm.cost_per_liter = props.budget.cost_per_liter;
budgetForm.fuel_price_per_liter = props.budget.fuel_price_per_liter;
budgetForm.other_fuel_expenses = props.budget.other_fuel_expenses;
budgetForm.driver_salary = props.budget.driver_salary;
budgetForm.accomadation_allowance = props.budget.accomadation_allowance;
budgetForm.other_administrative_expenses = props.budget.other_administrative_expenses;
budgetForm.total_administrative_expenses = props.budget.total_administrative_expenses;
budgetForm.total_before_tax = props.budget.total_before_tax;
budgetForm.total_utility_per_km = props.budget.total_utility_per_km;
budgetForm.total_profit = props.budget.total_profit;
budgetForm.profit_percentage = props.budget.profit_percentage;
} else {
Object.assign(budgetForm, initalState);
}
})
defineEmits(['reset-budget']);
const initalState = {
client: '',
material: '',
origin: '',
@@ -39,47 +93,46 @@
total_fuel_cost: 0.0,
budgetproduct:[],
budgetTrucktypes:[],
})
const clearMoal = () => {
// loadsStore.openProposalsModal = false;
// loadsStore.currentLoad = false;
}
const budgetForm = reactive({
...initalState
})
// const total = computed(() => {
// });
const totalTravel = computed(() => {
budgetForm.total_travel = budgetForm.warehouse_distance * 1 + budgetForm.delivery_distance * 1 + budgetForm.pickup_distance * 1;
budgetForm.total_travel = isNaN(budgetForm.total_travel) ? 0.0 : budgetForm.total_travel;
return budgetForm.total_travel;
});
const totalFuel = computed(() => {
budgetForm.total_fuel = budgetForm.total_travel / budgetForm.cost_per_liter;
console.log(budgetForm.total_travel)
console.log(budgetForm.cost_per_liter)
console.log('TOTAL: ', budgetForm.total_fuel);
budgetForm.total_fuel = isNaN(budgetForm.total_travel / budgetForm.cost_per_liter) ? 0.0 : (budgetForm.total_travel / budgetForm.cost_per_liter);
return isNaN(budgetForm.total_fuel) ? '0.0' : parseFloat(budgetForm.total_fuel).toFixed(2);
});
const totalFuelCost = computed(() => {
budgetForm.total_fuel_cost = budgetForm.total_fuel * budgetForm.fuel_price_per_liter;
budgetForm.total_fuel_cost = isNaN(budgetForm.total_fuel * budgetForm.fuel_price_per_liter) ? 0.0 : budgetForm.total_fuel * budgetForm.fuel_price_per_liter;
return "$" + (isNaN(budgetForm.total_fuel_cost) ? '0.0' : parseFloat(budgetForm.total_fuel_cost).toFixed(2));
});
const totalAdminExpenses = computed(() => {
budgetForm.total_administrative_expenses = budgetForm.driver_salary*1 + budgetForm.accomadation_allowance*1 + budgetForm.other_administrative_expenses*1;
budgetForm.total_administrative_expenses = budgetForm.driver_salary*1 + budgetForm.accomadation_allowance*1 + budgetForm.other_administrative_expenses*1;
budgetForm.total_administrative_expenses = isNaN(budgetForm.total_administrative_expenses) ? 0.0 : budgetForm.total_administrative_expenses;
return "$" + (isNaN(budgetForm.total_administrative_expenses) ? '0.0' : parseFloat(budgetForm.total_administrative_expenses).toFixed(2));
});
const totalBeforeTax = computed(() => {
budgetForm.total_before_tax = budgetForm.tonnage * budgetForm.price_per_ton;
budgetForm.total_before_tax = isNaN(budgetForm.total_before_tax) ? 0.0 : budgetForm.total_before_tax;
return "$" + (isNaN(budgetForm.total_before_tax) ? '0.0' : parseFloat(budgetForm.total_before_tax).toFixed(2));
});
const totalUtilityPerKm = computed(() => {
budgetForm.total_utility_per_km = budgetForm.total_before_tax / budgetForm.total_travel;
budgetForm.total_utility_per_km = isNaN(budgetForm.total_before_tax / budgetForm.total_travel) ? 0.0 : (budgetForm.total_before_tax / budgetForm.total_travel);
return "$" + (isNaN(budgetForm.total_utility_per_km) ? '0.0' : parseFloat(budgetForm.total_utility_per_km).toFixed(2));
});
@@ -90,9 +143,53 @@
const totalPercentage = computed(() => {
budgetForm.profit_percentage = budgetForm.total_profit / budgetForm.total_before_tax * 100;
budgetForm.profit_percentage = isNaN(budgetForm.profit_percentage) ? 0.0 : budgetForm.profit_percentage;
return (isNaN(budgetForm.profit_percentage) ? '0.0' : parseFloat(budgetForm.profit_percentage).toFixed(2)) + "%";
});
const saveBudget = async() => {
let budgetData ={
client: budgetForm.client,
material: budgetForm.budgetproduct.length <= 0 ? null : budgetForm.budgetproduct,
origin: budgetForm.origin,
destination: budgetForm.destination,
truck_type: budgetForm.budgetTrucktypes.length <= 0 ? null : budgetForm.budgetTrucktypes,
num_tons: budgetForm.num_tons,
price_per_ton: budgetForm.price_per_ton,
tonnage: budgetForm.tonnage,
pickup_distance: budgetForm.pickup_distance,
delivery_distance: budgetForm.delivery_distance,
warehouse_distance: budgetForm.warehouse_distance,
total_km_travel: budgetForm.total_travel,
cost_per_liter: budgetForm.cost_per_liter,
fuel_price_per_liter: budgetForm.fuel_price_per_liter,
other_fuel_expenses: budgetForm.other_fuel_expenses,
total_fuel_consumed: budgetForm.total_fuel,
total_cost_fuel: budgetForm.total_fuel_cost,
driver_salary: budgetForm.driver_salary,
accomadation_allowance: budgetForm.accomadation_allowance,
other_administrative_expenses: budgetForm.other_administrative_expenses,
total_administrative_expenses: budgetForm.total_administrative_expenses,
total_before_tax: budgetForm.total_before_tax,
total_utility_per_km: budgetForm.total_utility_per_km,
total_profit: budgetForm.total_profit,
profit_percentage: (isNaN(budgetForm.profit_percentage) || isFinite(budgetForm.profit_percentage)) ? 0.0 : budgetForm.profit_percentage,
company: authStore.user.company,
}
if(props.budget !== null) { // update
const result = companyStore.updateBudgetCompany(props.budget._id, budgetData);
console.log(result)
} else { // create
const result = companyStore.createBudgetCompany(budgetData);
console.log(result)
}
}
</script>
<template>
@@ -104,7 +201,7 @@
<button
id="btnClosebudgetModal"
type="button"
@click="clearMoal"
@click="$emit('reset-budget')"
class="close bg-white" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
@@ -352,7 +449,7 @@
<button
type="button"
class="btn btn-dark"
@click="clearMoal"
@click="$emit('reset-budget')"
data-dismiss="modal">Cerrar</button>
</div>
</div>

View File

@@ -199,7 +199,9 @@
<button
type="button"
class="btn btn-dark"
data-dismiss="modal">Cerrar</button>
data-dismiss="modal"
@click="$emit('reset-load')"
>Cerrar</button>
</div>
</div>
</div>

View File

@@ -51,6 +51,8 @@
:type="type"
:id="name"
:name="name"
:min="0"
:step="0.1"
:value="field"
:disabled="readonly"
:readonly="readonly"

View File

@@ -25,10 +25,12 @@
onMounted(() => {
console.log('EditCompanyModal');
console.log(companyStore.company)
if(companyStore.company){
companyCategories.value = companyStore.company.categories.map(m =>{
return { name: m.name };
});
// companyCategories.value = companyStore.company.categories.map(m =>{
// return { name: m.name };
// });
companyCategories.value = companyStore.company.categories;
}
if(companyStore.company){
companyStates.value = companyStore.company.company_state.map(m =>{
@@ -54,17 +56,34 @@
description: companyStore.company?.company_description ?? '',
});
const handleSave = () => {
const handleSave = async() => {
// const resp = editCompany()
const resp = validations();
if(resp !== '') {
msgError.value = resp;
clearMessages();
} else {
// $('#editcompanymodal').modal('toggle');
document.getElementById('btnCloseEditCompany').click();
notifications.show = true;
notifications.text = 'Empresa actualizada';
loading.value = true;
let companyData = {
is_company: companyStore.company._id,
company_type: companyStore.company.company_type,
meta_data: companyStore.company.meta_data,
categories: company.segments,
company_city: company.cities.map((e) => e.city_name),
company_state: company.states.map((e) => e.state_name),
truck_type: company.truckTypes.map((e) => e.meta_value),
company_description: company.description
};
const result = await companyStore.editCompany(companyData);
loading.value = false;
if(result === 'success') {
document.getElementById('btnCloseEditCompany').click();
notifications.show = true;
notifications.text = 'Empresa actualizada';
} else {
msgError.value === result;
clearMessages();
}
}
}
@@ -89,6 +108,7 @@
}
</script>
<template>
@@ -139,8 +159,11 @@
:filled="false"
v-model:field="company.description"
/>
<input type="submit" value="Cuardar cambios" class="btn-primary-lg btn-lg-block my-4">
<Spiner v-if="loading"/>
<input
v-else
type="submit"
value="Cuardar cambios" class="btn-primary-lg btn-lg-block my-4">
</form>
</div>
<div class="modal-footer">

View File

@@ -123,7 +123,6 @@ const router = createRouter({
router.beforeEach( async(to, from, next) => {
const requiresAuth = to.matched.some(url => url.meta.requiresAuth)
const session = localStorage.getItem('session');
console.log('Se ejecuta router');
if(requiresAuth) {
//Comprobamos si el usuario esta authenticado
if(session) {

View File

@@ -12,10 +12,12 @@ export const getCompany = async(companyId) => {
}
}
export const editCompany = async(companyId, formData) => {
export const updateCompany = async(companyId, formData) => {
try {
const endpoint = `/companies/${companyId}`;
console.log(endpoint);
const {data} = await api.patch(endpoint, formData);
console.log(data);
return data;
} catch (error) {
console.log(error);
@@ -26,7 +28,6 @@ export const editCompany = async(companyId, formData) => {
export const getBudgets = async(filter) => {
try {
const endpoint = `/budgets/${filter}`;
console.log(endpoint);
const {data} = await api.get(endpoint);
console.log(data);
return data;
@@ -37,6 +38,40 @@ export const getBudgets = async(filter) => {
}
export const updateBudget = async(id, formData) => {
try {
const endpoint = `/budgets/${id}`;
const {data} = await api.patch(endpoint, formData);
return data;
} catch (error) {
console.log(error);
return null;
}
}
export const createBudget = async(formData) => {
try {
const endpoint = `/budgets`;
const {data} = await api.post(endpoint, formData);
return data;
} catch (error) {
console.log(error);
return null;
}
}
export const deleteBudget = async(id) => {
try {
const endpoint = `/budgets/${id}`;
const {data} = await api.delete(endpoint);
return data;
} catch (error) {
console.log(error);
return null;
}
}
// export const editCompany = async(companyId, formData) => {
// try {
// const endpoint = `/companies/${companyId}`;

View File

@@ -17,7 +17,6 @@ export const useAuthStore = defineStore('auth', () => {
const user = ref(null)
onMounted( async() => {
console.log('Se ejecuta onMounted auth');
checkSession();
});

View File

@@ -1,6 +1,6 @@
import { defineStore } from "pinia";
import { ref } from "vue";
import { getBudgets, getCompany } from "../services/company";
import { getBudgets, getCompany, updateBudget, updateCompany, deleteBudget, createBudget } from "../services/company";
import api from "../lib/axios";
export const useCompanyStore = defineStore('company', () => {
@@ -22,9 +22,24 @@ export const useCompanyStore = defineStore('company', () => {
loading.value = false;
}
const editCompany = async(formData) => {
const data = await updateCompany(company.value._id, formData);
if(data === null) {
return 'Algo salio mal, intente más tarde';
} else {
company.value = {
...company.value,
...formData,
};
console.log(company.value);
return 'success';
}
}
const clear = () => {
company.value = null;
companyid.value = null;
companyid = null;
loading.value = false;
}
@@ -34,7 +49,6 @@ export const useCompanyStore = defineStore('company', () => {
const getProposalsCompany = async() => {
try {
const endpoint = `/proposals?carrier=${companyid}`;
console.log(endpoint);
const {data} = await api.get(endpoint);
proposals.value = data.data;
console.log(data);
@@ -54,8 +68,6 @@ export const useCompanyStore = defineStore('company', () => {
filterStr ="?"+cleanfilterArr.join("&");
}
console.log(filterStr);
if(budgets.value.length <= 0 || reload === true) {
try {
const data = await getBudgets(filterStr);
@@ -70,11 +82,65 @@ export const useCompanyStore = defineStore('company', () => {
}
}
const updateBudgetCompany = async(id, formData) => {
try {
const data = await updateBudget(id, formData);
console.log(data);
if(data) {
const index = budgets.value.findIndex((budget) => budget._id === id);
budgets.value[index] = {
...budgets.value[index],
...data,
material: udgets.value[index].material
};
return data;
} else {
return null;
}
} catch (error) {
return null;
}
}
const createBudgetCompany = async(formData) => {
try {
const data = await createBudget(formData);
console.log(data);
if(data) {
budgets.value.push(data);
return data;
} else {
return null;
}
} catch (error) {
return null;
}
}
const deleteBudgetCompany = async(id) => {
try {
const data = await deleteBudget(id);
console.log(data);
if(data) {
budgets.value = budgets.value.filter(budget => budget._id !== id);
return data;
} else {
return null;
}
} catch (error) {
return null;
}
}
return {
getCompanyData,
getProposalsCompany,
getBudgetsCompany,
editCompany,
updateBudgetCompany,
createBudgetCompany,
deleteBudgetCompany,
budgets,
clear,
loading,

View File

@@ -13,6 +13,8 @@
const loading = ref(false);
const filterQuery = ref([]);
const query = ref('');
const currentBudget = ref(null);
const openModal = ref(false);
onMounted(() => {
getInitData();
@@ -57,10 +59,25 @@
query.value = '';
}
}
const handleSetCurrentBudget = (budget) => {
openModal.value = true;
currentBudget.value = budget;
}
const handleResetCurrentBudget = () => {
openModal.value = false;
currentBudget.value = null;
}
</script>
<template>
<CreateBudgetModal/>
<CreateBudgetModal
v-if="openModal === true"
:budget="currentBudget"
@reset-budget="handleResetCurrentBudget"
/>
<div>
<h2 class="title my-2">Calculadora</h2>
</div>
@@ -76,7 +93,7 @@
<button
class="btn-primary-sm radius-sm"
data-toggle="modal" data-target="#budgetModal"
@click=""
@click="handleSetCurrentBudget(null)"
><i class="fa-solid fa-plus"></i> <span class="clear-sm"> Crear</span><span class="clear-md"> presupuesto</span></button>
</div>
<Spiner v-if="loading"/>
@@ -85,6 +102,7 @@
v-if="companyStore.budgets.length > 0"
v-for="budget in companyStore.budgets"
:budget="budget"
@set-budget="handleSetCurrentBudget(budget)"
/>
<CardEmpty
v-else

View File

@@ -72,7 +72,17 @@
<template>
<div>
<h2 class="title">Calendario</h2>
<h2 class="title mb-4">Calendario</h2>
<div class="box-indicators">
<h2>Indicadores de estado de la carga</h2>
<div class="indicators">
<i class="fa-solid fa-circle" style="color: yellow"></i> Publicado
<i class="fa-solid fa-circle" style="color: green"></i> Cargando
<i class="fa-solid fa-circle" style="color: red"></i> En transito
<i class="fa-solid fa-circle" style="color: blue"></i> Descargando
<i class="fa-solid fa-circle" style="color: blue"></i> Entregado
</div>
</div>
<div class="calendar">
<!-- <div class="calendar is-light-mode"> -->
<Qalendar
@@ -111,7 +121,7 @@
<style lang="scss" scoped>
.calendar {
height: calc(100vh - 150px);
height: calc(100vh - 220px);
}
.tracking-icon {
@@ -152,4 +162,33 @@
font-weight: 700;
}
.box-indicators {
display: flex;
justify-content: end;
flex-direction: column;
padding: 12px 10px;
}
.box-indicators h2 {
display: flex;
justify-content: end;
font-weight: 600;
font-size: 1.2rem;
}
.indicators {
display: flex;
justify-content: end;
flex-direction: row;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
@media (max-width: 768px) {
.calendar {
height: calc(100vh - 280px);
}
}
</style>

View File

@@ -63,19 +63,19 @@
<div class="col-sm-12 col-md-6 col-lg-6">
<div class="item-company">
<span class="font-weight-bold">Segmento de empresa: </span>
{{company.company?._categories}}
{{company.company?.categories.map((e) => e.name).join(', ')}}
</div>
<div class="item-company">
<span class="font-weight-bold">Ubicación de carga por estado: </span>
{{company.company?._company_state}}
{{company.company?.company_state.map((e) => e).join(', ')}}
</div>
<div class="item-company">
<span class="font-weight-bold">Ubicación de carga por municipio: </span>
{{company.company?._company_city}}
{{company.company?.company_city.map((e) => e).join(', ')}}
</div>
<div class="item-company">
<span class="font-weight-bold">ETransportes utilizados: </span>
{{company.company?._truck_types}}
<span class="font-weight-bold">Transportes utilizados: </span>
{{company.company?.truck_type.map((e) => e).join(', ')}}
</div>
<div class="item-company">
<span class="font-weight-bold">Información general de la empresa: </span>