瀏覽代碼

[ADD] add producto feature from product step

Gogs 7 年之前
父節點
當前提交
016eae1c8d

+ 31 - 0
controllers/main.py

@@ -220,4 +220,35 @@ class Sales(http.Controller):
             'phone': customer.phone,
             'mobile': customer.mobile,
             'email': customer.email
+        }
+    
+    '''
+        Create product and return data
+    '''
+    @http.route('/eiru_sales/create_product', type='json', auth='user', methods=['POST'], cors='*')
+    def create_customer(self, **kw):
+        self.make_info_log('Creating customer')
+
+        product = request.env['product.template'].create({
+            'name': kw.get('name'),
+            'list_price': float(kw.get('price')),
+            'ean13': kw.get('ean13')
+        })
+
+        return {
+            'id': product.id,
+            'name': product.name,
+            'displayName': product.display_name,
+            'ean13': product.ean13,
+            'imageMedium': product.image_medium,
+            'listPrice': product.list_price,
+            'variantCount': product.product_variant_count,
+            'variants': [{
+                'id': variant.id,
+                'name': variant.name,
+                'displayName': variant.display_name,
+                'ean13': variant.ean13,
+                'imageMedium': variant.image_medium,
+                'listPrice': variant.list_price
+            } for variant in product.product_variant_ids if variant.active]
         }

+ 95 - 0
src/components/forms/ProductForm.vue

@@ -0,0 +1,95 @@
+<template lang="pug">
+    .product-form
+        .form-header
+            h2 {{ title }}
+            hr
+        form.form-display
+            .form-item
+                label.form-label Nombre
+                input.form-input(v-model='product.name' autofocus)
+            .form-item
+                label.form-label Precio
+                input.form-input(v-model='product.price')
+            .form-item
+                label.form-label Código de barras
+                input.form-input(v-model='product.ean13')
+            .form-actions
+                button.form-action(@click='onAccept') Aceptar
+                button.form-action(@click='onCancel') Cancelar
+</template>
+
+<script>
+    export default {
+        props: {
+            title: String,
+            default: ''
+        },
+        data() {
+            return {
+                product: {
+                    name: '',
+                    price: 0,
+                    ean13: ''
+                }
+            }
+        },
+        methods: {
+            onAccept() {
+                this.$emit('onAccept', this.product)
+            },
+            onCancel() {
+                this.$emit('onCancel')
+            }
+        },
+        mounted() {
+            Object.assign(this.product, {
+                name: '',
+                price: 0,
+                ean13: ''
+            })
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables' 
+    .product-form
+        width: 600px
+        height: 100%
+        .form-header
+            margin-top: 30px
+            h2
+                font-size: 10pt
+                color: $app-border-color
+                margin-left: 15px
+            hr
+                margin: 0 15px
+        .form-display
+            width: 100%
+            height: 100%
+            padding: 15px
+            .form-item
+                width: 100%
+                height: 45px
+                margin-bottom: 10px
+                .form-label
+                    width: 30%
+                    height: 45px
+                    font-size: 14pt
+                .form-input
+                    width: 70%
+                    height: 45px
+                    font-size: 18pt
+                    border-radius: 0
+            .form-actions
+                float: right
+                .form-action
+                    width: 150px
+                    height: 40px
+                    border: none
+                    box-shadow: none
+                    border-radius: 0
+                    margin-right: 5px
+                    background: $app-main-color
+                    color: $app-bg-color
+</style>

+ 50 - 0
src/components/modals/ProductModal.vue

@@ -0,0 +1,50 @@
+<template lang="pug">
+    modal(name='product-modal' transition='nice-modal-fade' @before-close='beforeClose' :classes="['v--modal', 'product-modal']")
+        product-form(title='Nuevo Producto' @onAccept='onAccept' @onCancel='onCancel')
+</template>
+
+<script>
+    import ProductForm from '@@/forms/ProductForm'
+
+    export default {
+        components: {
+            ProductForm
+        },
+        props: {
+            title: {
+                type: String,
+                default: ''
+            },
+            show: {
+                type: Boolean,
+                default: false
+            }
+        },
+        watch: {
+            show(value) {
+                if (!value) {
+                    this.$modal.hide('product-modal')
+                    return
+                }
+
+                this.$modal.show('product-modal')
+            }
+        },
+        methods: {
+            beforeClose(e) {
+                if (this.show) {
+                    e.stop()
+                }
+            },
+            onAccept(value) {
+                this.$emit('onAccept', value)
+            },
+            onCancel() {
+                this.$emit('onCancel')
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+</style>

+ 12 - 5
src/components/steps/Product.vue

@@ -2,30 +2,37 @@
     .pos-step
         .products-selector
             searcher(:items='products' :keys="['name', 'displayName']")
-            card-grid(:items='products' :loading='loadingProducts' @onSelect='selectProduct')
+            card-grid(:items='products' :loading='loadingProducts' canAdd @onAdd='showProductForm' @onSelect='selectProduct')
+            product-modal(:show='showingProductForm' @onAccept='submitProduct' @onCancel='hideProductForm')
         cart(:items='cartItems' @onTotalComputed='changeCartTotal')
 </template>
 
 <script>
     import { mapGetters, mapActions } from 'vuex'
-    import { Searcher, CardGrid, Cart } from '@/components/common'
+    import { Searcher, CardGrid, Cart } from '@@/common'
+    import ProductModal from '@@/modals/ProductModal'
 
-    import { SELECT_PRODUCT, CHANGE_CART_TOTAL } from '@/constants/actionTypes'
+    import { SELECT_PRODUCT, CHANGE_CART_TOTAL, SHOW_PRODUCT_FORM, HIDE_PRODUCT_FORM, SUBMIT_PRODUCT } from '@/constants/actionTypes'
 
     export default {
         components: {
             Searcher,
             CardGrid,
-            Cart
+            Cart,
+            ProductModal
         },
         computed: mapGetters([
             'products',
             'loadingProducts',
+            'showingProductForm',
             'cartItems'
         ]),
         methods: mapActions([
             SELECT_PRODUCT,
-            CHANGE_CART_TOTAL
+            CHANGE_CART_TOTAL,
+            SHOW_PRODUCT_FORM,
+            HIDE_PRODUCT_FORM,
+            SUBMIT_PRODUCT
         ])
     }
 </script>

+ 15 - 0
src/constants/actionTypes.js

@@ -10,6 +10,16 @@ const INIT_USER = 'initUser'
 
 const INIT_PRODUCTS = 'initProducts'
 
+const SHOW_PRODUCT_FORM = 'showProductForm'
+
+const HIDE_PRODUCT_FORM = 'hideProductForm'
+
+const SUBMIT_PRODUCT = 'submitProduct'
+
+const CREATE_PRODUCT = 'createProduct'
+
+const RECEIVE_PRODUCT = 'receiveProduct'
+
 const SELECT_PRODUCT = 'selectProduct'
 
 const INIT_PAYMENT_TERMS = 'initPaymentTerms'
@@ -45,6 +55,11 @@ export {
     CREATE_SALE,
     INIT_USER,
     INIT_PRODUCTS,
+    SHOW_PRODUCT_FORM,
+    HIDE_PRODUCT_FORM,
+    SUBMIT_PRODUCT,
+    CREATE_PRODUCT,
+    RECEIVE_PRODUCT,
     SELECT_PRODUCT,
     INIT_PAYMENT_TERMS,
     INIT_JOURNALS,

+ 5 - 1
src/constants/mutationTypes.js

@@ -6,6 +6,10 @@ const SET_PRODUCTS = 'setProducts'
 
 const SET_LOADING_PRODUCTS = 'setLoadingProducts'
 
+const ADD_PRODUCT = 'addProduct'
+
+const SET_SHOW_PRODUCT_FORM = 'setShowProductForm'
+
 const SELECT_PRODUCT = 'selectProduct'
 
 const SET_PRODUCT_WITH_VARIANT = 'setProductWithVariant'
@@ -42,7 +46,7 @@ const SET_CART_TOTAL = 'setCartTotal'
 
 export {
     SET_USER, SET_LOADING_USER, // User
-    SET_PRODUCTS, SET_LOADING_PRODUCTS, SELECT_PRODUCT, SET_PRODUCT_WITH_VARIANT, // Product
+    SET_PRODUCTS, SET_LOADING_PRODUCTS, ADD_PRODUCT, SET_SHOW_PRODUCT_FORM, SELECT_PRODUCT, SET_PRODUCT_WITH_VARIANT, // Product
     SET_PAYMENT_TERMS, SET_LOADING_PAYMENT_TERMS, // Payment Term
     SET_JOURNALS, SET_LOADING_JOURNALS, // Journal
     SET_DATE, SET_LOADING_DATE, // Date

+ 3 - 0
src/constants/resourcePaths.js

@@ -2,12 +2,15 @@ const BASE_URL = '/eiru_sales'
 
 const INIT_SALE_URL = `${BASE_URL}/init`
 
+const CREATE_PRODUCT_URL = `${BASE_URL}/create_product`
+
 const CREATE_CUSTOMER_URL = `${BASE_URL}/create_customer`
 
 const PROCESS_SALE_URL = `${BASE_URL}/process`
 
 export {
     INIT_SALE_URL,
+    CREATE_PRODUCT_URL,
     CREATE_CUSTOMER_URL,
     PROCESS_SALE_URL
 }

+ 27 - 2
src/store/actions.js

@@ -1,6 +1,6 @@
 import axios from 'axios'
-import { INIT_SALE_URL, CREATE_CUSTOMER_URL, PROCESS_SALE_URL } from '@/constants/resourcePaths'
-import { INIT_SALE, NOTIFY, EXPLODE_DATA, CREATE_CUSTOMER, RECEIVE_CUSTOMER, CREATE_SALE } from '@/constants/actionTypes'
+import { INIT_SALE_URL, CREATE_PRODUCT_URL, CREATE_CUSTOMER_URL, PROCESS_SALE_URL } from '@/constants/resourcePaths'
+import { INIT_SALE, NOTIFY, EXPLODE_DATA, CREATE_PRODUCT, CREATE_CUSTOMER, RECEIVE_PRODUCT, RECEIVE_CUSTOMER, CREATE_SALE } from '@/constants/actionTypes'
 
 const actions = {
     /**
@@ -33,6 +33,31 @@ const actions = {
             dispatch(`init${value[0].toUpperCase()}${value.slice(1)}`, payload[value])
         }
     },
+    /**
+     * 
+     * @param {*} param0 
+     * @param {*} payload 
+     */
+    [CREATE_PRODUCT] ({ dispatch }, payload) {
+        const data = {
+            jsonrpc: '2.0',
+            method: 'call',
+            params: {
+                ...payload
+            }
+        }
+
+        return axios.post(CREATE_PRODUCT_URL, data).then(response => {
+            dispatch(RECEIVE_PRODUCT, response.data.result)
+        }).catch(error => {
+            console.log(error)
+        })
+    },
+    /**
+     * 
+     * @param {*} param0 
+     * @param {*} payload 
+     */
     [CREATE_CUSTOMER] ({ dispatch }, payload) {
         const data = {
             jsonrpc: '2.0',

+ 61 - 2
src/store/modules/product.js

@@ -1,9 +1,10 @@
-import { SET_PRODUCTS, SET_LOADING_PRODUCTS, SET_PRODUCT_WITH_VARIANT } from '@/constants/mutationTypes'
-import { INIT_PRODUCTS, SELECT_PRODUCT, ADD_TO_CART } from '@/constants/actionTypes'
+import { SET_PRODUCTS, SET_LOADING_PRODUCTS, SET_SHOW_PRODUCT_FORM, SET_PRODUCT_WITH_VARIANT, ADD_PRODUCT } from '@/constants/mutationTypes'
+import { INIT_PRODUCTS, SHOW_PRODUCT_FORM, HIDE_PRODUCT_FORM, SUBMIT_PRODUCT, CREATE_PRODUCT, RECEIVE_PRODUCT, SELECT_PRODUCT, ADD_TO_CART } from '@/constants/actionTypes'
 
 const initialState = {
     products: [],
     loadingProducts: false,
+    showingProductForm: false,
     showVariants: false,
     productWithVariant: null
 }
@@ -11,6 +12,7 @@ const initialState = {
 const state = {
     products: initialState.products,
     loadingProducts: !initialState.loadingProducts,
+    showingProductForm: initialState.showingProductForm,
     showVariants: initialState.showVariants,
     productWithVariant: initialState.productWithVariant
 }
@@ -30,6 +32,13 @@ const getters = {
     loadingProducts(state) {
         return state.loadingProducts
     },
+    /**
+     * 
+     * @param {*} state 
+     */
+    showingProductForm(state) {
+        return state.showingProductForm
+    },
     /**
      * 
      * @param {*} state 
@@ -63,6 +72,22 @@ const mutations = {
     [SET_LOADING_PRODUCTS] (state, payload) {
         state.loadingProducts = !!payload
     },
+    /**
+     * 
+     * @param {*} state 
+     * @param {*} payload 
+     */
+    [SET_SHOW_PRODUCT_FORM] (state, payload) {
+        state.showingProductForm = !!payload
+    },
+    /**
+     * 
+     * @param {*} state 
+     * @param {*} payload 
+     */
+    [ADD_PRODUCT] (state, payload) {
+        state.products = [payload, ...state.products]
+    },
     /**
      * 
      * @param {*} state 
@@ -83,6 +108,40 @@ const actions = {
         commit(SET_PRODUCTS, payload)
         commit(SET_LOADING_PRODUCTS)
     },
+    /**
+     * 
+     * @param {*} param0 
+     * @param {*} payload 
+     */
+    [SHOW_PRODUCT_FORM] ({ commit }) {
+        commit(SET_SHOW_PRODUCT_FORM, true)
+    },
+    /**
+     * 
+     * @param {*} param0 
+     */
+    [HIDE_PRODUCT_FORM] ({ commit }) {
+        commit(SET_SHOW_PRODUCT_FORM, false)
+    },
+    /**
+     * 
+     * @param {*} param0 
+     * @param {*} payload 
+     */
+    [SUBMIT_PRODUCT] ({ commit, dispatch }, payload) {
+        commit(SET_LOADING_PRODUCTS, true)
+        dispatch(CREATE_PRODUCT, payload)
+        dispatch(HIDE_PRODUCT_FORM)
+    },
+    /**
+     * 
+     * @param {*} param0 
+     * @param {*} payload 
+     */
+    [RECEIVE_PRODUCT] ({ commit }, payload) {
+        commit(ADD_PRODUCT, payload)
+        commit(SET_LOADING_PRODUCTS, false)
+    },
     /**
      * 
      * @param {*} param0