programing

커밋하지 않고 상태가 Vuex에서 업데이트됨

prostudy 2022. 4. 13. 20:56
반응형

커밋하지 않고 상태가 Vuex에서 업데이트됨

좀 답답한 문제가 있는데, 어떤 항목을 선택한 다음 모달이 열리고 Add / update to table을 클릭하기만 하면 "itemstabla" 상태로 커밋되지만, 결과적으로 테이블의 항목을 편집하기 위해 그것을 주고 모델이 열리며, 수량을 다른 숫자로 변경하게 된다.커밋을 실행하지 않고 상태 "instabla"가 업데이트되며, 모달 버튼을 클릭할 때만 실행되어야 한다.

여기에 이미지 설명을 입력하십시오.

내 가게:

    let store = {
      state: {
        token: localStorage.getItem('access_token') || null,
        items: [],
        itemstabla: [],
        monedas: [],
        impuestos: [],
        venta: [],
        estadotienda: '',
      },
      getters: {
        loggedIn(state) {
          return state.token !== null
        },
      },
      mutations: {
        EliminarItemTabla(state, item) {
          var index = state.itemstabla.findIndex(c => c.id == item);
          state.itemstabla.splice(index, 1);
       },
        retrieveToken(state, token) {
          state.token = token
        },
        setmonedas(state, monedas) {
          state.monedas = monedas
        },
        setventa(state, venta) {
          state.venta = venta
        },
        setitemstabla(state, items) {
          let found = state.itemstabla.find(item => item.id == items.id);
          
          if(found) {
            if(items.accion=='agregar') {
              found.cantidad = parseInt(found.cantidad) + parseInt(items.cantidad)
            }  
            else {
              found.cantidad = parseInt(items.cantidad)
            }
          }
          else {
            state.itemstabla.push(items)
          }
          
        },
        actualizaritemstabla(state) {
          state.itemstabla.forEach(function (item) {
            if ((state.venta.moneda_id == 'S/' && item.moneda == 'S/') || (state.venta.moneda_id == '$' && item.moneda == '$')) {
              item.precio = parseFloat(item.precio).toFixed(2)
            }
            else if(state.venta.moneda_id == '$' && item.moneda == 'S/') {
              item.moneda = '$'
              item.precio = parseFloat(parseFloat(item.precio) / parseFloat(state.venta.tipocambio)).toFixed(2)
            }
            else if(state.venta.moneda_id == 'S/' && item.moneda == '$') {
              item.moneda = 'S/'
              item.precio = parseFloat(parseFloat(item.precio) * parseFloat(state.venta.tipocambio)).toFixed(2)
            }
          });
        },
        setimpuestos(state, impuestos) {
          state.impuestos = impuestos
        },
        setmonedaid(state, moneda_id) {
          state.venta.moneda_id = moneda_id
        },
        settipocambio(state, tipocambio) {
          state.venta.tipocambio = tipocambio
        },
        destroyToken(state) {
          state.token = null
        }
      },
      actions: {
        retrieveToken(context, credentials) {
    
          return new Promise((resolve, reject) => {
            axios.post('/api/login', {
              username: credentials.username,
              password: credentials.password,
            })
              .then(response => {
                const token = response.data.access_token
                localStorage.setItem('access_token', token)
                context.commit('retrieveToken', token)
    
                resolve(response)
              })
              .catch(error => {
                reject(error)
              })
          })
    
        },
        destroyToken(context) {
          
          if (context.getters.loggedIn){
            
            return new Promise((resolve, reject) => {
              axios.post('/api/logout', '', {
                  headers: { Authorization: "Bearer " + context.state.token }
                })
                .then(response => {
                  localStorage.removeItem('access_token')
                  context.commit('destroyToken')
      
                  resolve(response)
                })
                .catch(error => {
                  localStorage.removeItem('access_token')
                  context.commit('destroyToken')
    
                  reject(error)
                })
            })
    
          }
        }
      }
    }
    
    export default store

내 파일 Vue:

    <template>
    <div>
        <!-- MODAL PARA EDITAR ITEM -->
        <div class="modal fade" id="editarItem" tabindex="-1" role="dialog" aria-labelledby="editarItem" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        
                        <h5 class="modal-title" id="exampleModalLabel">Editar ítem</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <div class="form-group row">
                            <label for="cantidadEdit" class="col-sm-4 col-form-label col-form-label-sm font-weight-bold">Cantidad</label>
                            <div class="col-sm-8">
                                <div class="input-group">
                                    <input v-model="item.cantidad" type="number" class="form-control text-center font-weight-bold h2" min="1" tabindex="1" onfocus="this.select();">
                                </div>
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="itemEdit" class="col-sm-4 col-form-label col-form-label-sm">Stock</label>
                            <div class="col-sm-8">
                                <input type="text" class="form-control text-center font-weight-bold h2" v-model="item.stock" disabled>
    
                            </div>
                        </div>
    
                        <div class="form-group row">
                            <label for="precioEdit" class="col-sm-4 col-form-label col-form-label-sm">Precio unitario<small class="text-muted" id="porcentajefinalprecio">+ {{item.primer_margen}}%</small></label>
                            <div class="col-sm-8">
                                <input v-model="item.precio" type="text" class="form-control font-weight-bold" tabindex="2" onfocus="this.select();">
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="" class="col-sm-4 col-form-label col-form-label-sm">Tipo de impuesto</label>
                            <div class="col-sm-8">
                                
                                <select v-model="item.impuesto" class="imp custom-select" id="imp">
                                    <option v-for="imp in impuestos" v-bind:key="imp.id" v-bind:value="imp.id">{{ imp.nombre }}</option>
                                </select>
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="precioTotalEdit" class="col-sm-4 col-form-label col-form-label-sm">Subtotal <small id="simboloparatodos" class="text-muted">{{item.moneda_id}}</small></label>
                            <div class="col-sm-8">
                                <input type="text" v-model="subtotal" class="form-control form-control-sm" id="precioTotalEdit" onfocus="this.select();" readonly>
                            </div>
                        </div>
    
                        <div class="form-group row">
                            <label for="precioigvEdit" class="col-sm-4 col-form-label col-form-label-sm">I.G.V. </label>
                            <div class="col-sm-8">
                                <input type="text"  v-model="igv" class="form-control form-control-sm" id="precioigvEdit" readonly>
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="descuentoEdit" class="col-sm-4 col-form-label col-form-label-sm">Descuento</label>
                            <div class="col-sm-8">
                                <input v-model="item.descuento" type="text" class="form-control form-control-sm" id="descuentoEdit" data-toggle="popover" data-placement="top" data-html="true" data-content="Para montos. Ej: 10<br>Para porcentajes agrega %. Ej: 10%" data-trigger="hover" tabindex="4" onfocus="this.select();">
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="precioSubtotalEdit" class="col-sm-4 col-form-label col-form-label-sm">Total <small id="simboloparatodos" class="text-muted">{{ moneda_id }}</small></label>
                            <div class="col-sm-8">
                                <input v-model="total" type="text" class="form-control font-weight-bold" id="precioSubtotalEdit" value="0" tabindex="5" onfocus="this.select();">
                            </div>
                        </div>
    
                        <div class="form-group row">
                            <label for="precio20Edit" class="col-sm-4 col-form-label col-form-label-sm">Precio <small class="text-muted" id="porcentajeinicial">+ {{item.primer_margen}}%</small></label>
                            <div class="col-sm-8">
                                <div id="margeninicialx">{{ item.masprimermargen }}</div>
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="precio35Edit" class="col-sm-4 col-form-label col-form-label-sm">Precio <small class="text-muted" id="porcentajefinal">+ {{item.segundo_margen}}%</small></label>
                            <div class="col-sm-8">
                                <div id="margenfinalx"> {{ item.massegundomargen }}</div>
                            </div>
                        </div>
                        <div class="form-group row">
                            <label for="itemEdit" class="col-sm-4 col-form-label col-form-label-sm">Item</label>
                            <div class="col-sm-8">
                                <small id="marcaEdit">{{ item.marca }}</small> <a href="#" title="" target="_blank" id="itemEdit" style="text-transform: capitalize;">{{ item.nombre }}</a><br><span class="text-muted small" title="códigos" id="codigoedit" v-for="cod in codigos" v-bind:key="cod.id">{{ cod.nombre_codigo }}-{{ cod.pivot.nombre }}<br></span>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Cancelar</button>
                        <button type="button" class="btn btn-sm btn-primary" tabindex="5" @click="anadiritem">Añadir</button>
                    </div>
                </div>
            </div>
        </div>
         <!-- FIN DE MODAL PARA EDITAR ITEM -->
        
         <!-- SECCION SELECCIONAR ITEM Y AGREGAR A LA TABLA -->
          
        <div class="">
            <div class="input-group input-group-sm mb-3">
                <div class="input-group-prepend">
                    <span class="input-group-text"><i class="fas fa-search"></i></span>
                </div>
                <div class="prefetch">
                    <input type="text" id="item" class="form-control typeahead" placeholder="Buscar item (Ctrl+.)" v-model.trim="q" @keyup.enter="buscaritem">
    
                </div>
                <div class="input-group-append">
                    <button class="btn btn-outline-secondary" id="button-addon2" disabled></button>
                </div>
            </div>
        </div>
        <table class="table table-striped table-hover table-sm table-responsive-md text-nowrap mt-3" id="detailFactura">
            <thead>
                <tr>
                    <th>Ítem</th>
                    <th class="text-right">Cnt.</th>
                    <th class="text-right">Costo U.</th>
                    <th></th>
                    <th class="text-right text-nowrap">
                        SubTotal
                    </th>
                    <th class="text-right text-nowrap">
                        I.G.V
                    </th>
                    <th class="text-right text-nowrap"><span class="text-muted">
                            Total
                            <div id="monedaText"></div>
                        </span></th>
                </tr>
            </thead>
            <tbody>
               
                <tr v-for="itemtabla in itemstabla" v-bind:key="itemtabla.id">
                    <td class="overflow-hidden" style="max-width: 299px; text-overflow: ellipsis"><a href="#" title="" target="_blank">{{ item.nombre }}</a> <small class="text-muted">({{ itemtabla.marca }})</small> </td>
                    <td class="text-right"><small class="text-muted mr-1" title="Unidades">{{ itemtabla.unidad }}</small>{{ itemtabla.cantidad }}</td>
                    <td class="text-right">{{ itemtabla.precio }}</td>
                    <td class="text-right">
                        <a href="javascript:void(0);" class="edt" v-on:click="editaritem(itemtabla)"><i class="fas fa-pencil-alt mr-2"></i></a>
                        <a href="javascript:void(0);" class="borrar" v-on:click="deleteitem(itemtabla.id)"><i class="far fa-trash-alt"></i></a>
                    </td>
                    <td class="text-right">{{ preciosegunmoneda(itemtabla.precio, itemtabla.moneda, itemtabla.cantidad, itemtabla.impuesto, itemtabla.descuento).subtotal }}</td>
                    <td class="text-right">{{ preciosegunmoneda(itemtabla.precio, itemtabla.moneda, itemtabla.cantidad, itemtabla.impuesto, itemtabla.descuento).igv }}</td>
                    <td class="text-right">{{ preciosegunmoneda(itemtabla.precio, itemtabla.moneda, itemtabla.cantidad, itemtabla.impuesto, itemtabla.descuento).total }}</td>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="2" class="text-right" id="cantidadItems">{{ itemstabla.length }} </td>
                    <td class="small font-weight-bolder">ítem(s)</td>
                </tr>
            </tfoot>
        </table>
          <!-- FIN DE SECCION SELECCIONAR ITEM Y AGREGAR A LA TABLA -->
    </div>
    </template>
    
    <script>
    import {
        required,
        minLength,
        maxLength,
        between
    } from 'vuelidate/lib/validators'
    import Bloodhound from 'corejs-typeahead/dist/bloodhound';
    import typeahead from 'corejs-typeahead/dist/typeahead.jquery';
    export default {
        name: 'tabla-item',
        props: {
            tienda: Number,
        },
        data() {
            return {
                resource: 'venta',
                error: false,
                submitStatus: null,
                isLoading: false,
                fullPage: true,
                q: '',
                suggestions: null,
                item: {},
    
            }
        },
        created() {
    
        },
        mounted() {
            let contextoVue = this
            // Cargar los datos del typeahead en items
            this.suggestions = new Bloodhound({
                datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'),
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                identify: function (item) {
                    return item.id;
                },
                remote: {
                    url: '/item/records/' + this.tienda + '/' + '%QUERY',
                    wildcard: '%QUERY'
                }
            });
    
            let inputEl = $('.prefetch input');
            inputEl.typeahead({
                minLength: 1,
                highlight: true,
            }, {
                name: 'suggestions',
                source: this.suggestions,
                limit: 20,
                display: 'label',
                templates: {
                    suggestion: (data) => {
                        let codigos = data.codigos
                        let nuevoscodigos = ""
                        codigos.forEach(function (valor, indice, array) {
                            nuevoscodigos = nuevoscodigos + valor.pivot.nombre + ','
                        });
                        let nuevoprecio = ((parseFloat(contextoVue.preciosegunmoneda(data.precio, data.moneda,'1',data.impuesto_id).precio) * parseFloat(data.primer_margen) / 100) + parseFloat(contextoVue.preciosegunmoneda(data.precio, data.moneda,'1',data.impuesto_id).precio)).toFixed(2)
                        return `<div class="ss-suggestion">
                        <div class="codigos">
                        ${data.nombre_marca} <span title="Código global"> - ${nuevoscodigos}</span>
                        <span title="Código de barras"></span>
                        </div>
                        <div class="searchproducto" style="text-transform: capitalize;">
                        <strong>${data.nombre}</strong>
                        </div>
                        <div class="d-flex mt-1"><div class="searchprice text-primary">${contextoVue.moneda_id} 
                        <span id="pricechange">${nuevoprecio}</span></div>
                        <div class="searchstock flex-grow-1 text-danger"><b>Stock</b>: 
                        <b style="color: red;">${data.stock}</b><b></b></div></div></div>`;
    
                    }
                }
            });
            // Cuando se hace click en un item 
            $('.prefetch input').bind('typeahead:selected', function (evt, suggestion) {
                $('#editarItem').modal('show')
                let preciosegunmoneda = ((parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio) * parseFloat(suggestion.primer_margen) / 100) + parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio)).toFixed(2)
                let massegundomargen = ((parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio) * parseFloat(suggestion.segundo_margen) / 100) + parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio)).toFixed(2)
                contextoVue.item = {
                    id: suggestion.id,
                    stock: suggestion.stock,
                    nombre: suggestion.nombre,
                    precio: preciosegunmoneda,
                    marca: suggestion.nombre_marca,
                    impuesto: suggestion.impuesto_id,
                    primer_margen: suggestion.primer_margen,
                    segundo_margen: suggestion.segundo_margen,
                    masprimermargen: preciosegunmoneda,
                    massegundomargen: massegundomargen,
                    codigos: suggestion.codigos,
                    cantidad: '1',
                    descuento: '0',
                    moneda: contextoVue.moneda_id,
                    unidad: suggestion.nombre_unidad,
                }
    
            });
            // Fin typeahead items
    
        },
        updated() {
    
        },
    
        computed: {
            total()  {
                return this.item.precio *  this.item.cantidad -  this.item.descuento
            },
            igv()  {
            if(this.item.impuesto=="1") {
                        return (parseFloat(this.total) * 18/100).toFixed(2)
                    }
                    else {
                        return 0
                    }
            },
            subtotal()  {
                return (parseFloat(this.total) - this.igv).toFixed(2)
            },
            tipocambio: {
                get() {
                    return this.$store.state.venta.tipocambio
                },
                set(value) {
                    this.$store.commit('settipocambio', value)
                }
            },
            moneda_id: {
                get() {
                    return this.$store.state.venta.moneda_id
                },
                set(value) {
                    this.$store.commit('setmonedaid', value)
                }
            },
            itemstabla: {
                get() {
                    return this.$store.state.itemstabla
                },
                
            },
            impuestos: {
                get() {
                    return this.$store.state.impuestos
                },
            },
    
        },
        watch: {
        moneda_id: function (val) {
            //this.$store.commit('actualizaritemstabla')
        },
        },
        methods: {
            submit() {},
            preciosegunmoneda(precio, moneda, cantidad, impuesto, descuento) {
                let total,nuevoprecio,subtotal,igv = 0
                if ((this.moneda_id == 'S/' && moneda == 'S/') || (this.moneda_id == '$' && moneda == '$')) {
                    nuevoprecio = parseFloat(precio).toFixed(2)
                    total = parseFloat((parseFloat(precio) * cantidad) - descuento).toFixed(2)
                    igv = parseFloat((parseFloat(total) * (impuesto=='1' ? 18/100 : 0))).toFixed(2)
                    subtotal = parseFloat(total - igv).toFixed(2)
                    return {precio: nuevoprecio, total: total, igv: igv, subtotal: subtotal  }
                } 
                else if (this.moneda_id == 'S/' && moneda == '$') {
                    nuevoprecio = parseFloat(precio * this.tipocambio).toFixed(2)
                    total = parseFloat((parseFloat(precio * this.tipocambio) * cantidad) - descuento).toFixed(2)
                    igv = parseFloat((parseFloat(total) * (impuesto=='1' ? 18/100 : 0))).toFixed(2)
                    subtotal = parseFloat(total - igv).toFixed(2)
                    return {precio: nuevoprecio, total: total, igv: igv, subtotal: subtotal }
                }
                else if (this.moneda_id == '$' && moneda == 'S/') {
                    nuevoprecio = parseFloat(precio / this.tipocambio).toFixed(2)
                    total = parseFloat((parseFloat(precio / this.tipocambio) * cantidad) - descuento).toFixed(2)
                    igv = parseFloat((parseFloat(total) * (impuesto=='1' ? 18/100 : 0))).toFixed(2)
                    subtotal = parseFloat(total - igv).toFixed(2)
                    return {precio: nuevoprecio, total: total, igv: igv, subtotal: subtotal }
                }
            },
            deleteitem(i) {
                this.$store.commit('EliminarItemTabla', i);
            },
            editaritem(item) {
                $('#editarItem').modal('show')
                this.item = item
            },
            anadiritem(event) {
                 $('#editarItem').modal('hide')
                 this.$store.commit('setitemstabla', this.item )
            },
    
        },
        validations: {
            form: {
                nombre_codigo: {
                    required,
                },
            }
        }
    }
    </script>

의 사용으로editaritem너처럼, 내 생각엔 네가 실제로 그 물건을 전달하고 있는 것 같아. 그래서 참고사항인 만큼 수정되는 거야.

    editaritem(item) {
        $('#editarItem').modal('show')
        this.item = { ...item } // or some way to copy the object 
    }

그리고 편집을 마친 후 편집된 객체의 실제 업데이트를 수행하십시오.

참조URL: https://stackoverflow.com/questions/63400864/i-do-not-commit-and-the-state-is-updated-in-vuex

반응형