Procházet zdrojové kódy

[IMP] product pricelists

robert před 6 roky
rodič
revize
3c7fbd8431

+ 2 - 0
controllers/main.py

@@ -37,6 +37,7 @@ class PosSales(http.Controller):
         from res_partner import get_customers
         from product_template import get_products
         from product_pricelist import get_pricelists
+        from product_category import get_categories
         from account_payment_term import get_payment_terms
         from res_bank import get_banks
         from res_bank_payment_type import get_bank_payment_types
@@ -74,6 +75,7 @@ class PosSales(http.Controller):
                 'customers': get_customers(image_type),
                 'products': get_products(image_type, map(lambda x: x.get('locationStock').get('id'), warehouses)),
                 'pricelists': get_pricelists('sale'),
+                'categories': get_categories(),
                 'paymentTerms': get_payment_terms(),
                 'banks': get_banks(),
                 'bankPaymentTypes': get_bank_payment_types(),

+ 23 - 0
controllers/product_category.py

@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+from openerp.http import request as r
+
+_MODEL = 'product.category'
+
+def get_categories():
+    domain = [
+        ('type', '!=', 'view'),
+        ('child_id', '=', False)
+    ]
+
+    return [
+        {
+            'id': c.id,
+            'name': c.display_name,
+            'completeName': c.complete_name,
+            'parent': {
+                'id': c.parent_id.id,
+                'name': c.parent_id.display_name,
+                'completeName': c.parent_id.complete_name
+            }
+        } for c in r.env[_MODEL].search(domain)
+    ]

+ 3 - 1
controllers/product_pricelist.py

@@ -31,7 +31,9 @@ def get_pricelists(type='sale'):
                             'priceMinMargin': i.price_min_margin,
                             'priceRound': i.price_round,
                             'priceSurcharge': i.price_surcharge,
-                            'productId': i.product_id.id or None
+                            'productId': i.product_id.id or None,
+                            'productTmplId': i.product_tmpl_id.id or None,
+                            'categoryId': i.categ_id or None
                         } for i in v.items_id
                     ],
                 } for v in p.version_id

+ 5 - 1
controllers/product_template.py

@@ -47,6 +47,7 @@ def get_products(image_type='small', location_ids=None):
             'minimumPrice': p.minimum_price,
             'maximumPrice': p.maximum_price,
             'discount': 0,
+            'categoryId': p.categ_id.id or None,
             'variants': [{
                 'id': v.id,
                 'name': v.display_name,
@@ -60,7 +61,10 @@ def get_products(image_type='small', location_ids=None):
                 'maximumPrice': p.maximum_price,
                 'discount': 0,
                 'pricelistId': v.pricelist_id.id or None,
-                'locations': in_locations.get(v.id, [])
+                'locations': in_locations.get(v.id, []),
+                'categoryId': v.categ_id.id or None,
+                'tmplId': p.id or None,
+                'tmplCategoryId': p.categ_id.id or None
             } for v in p.product_variant_ids]
         } for p in r.env[_MODEL].search(domain)
     ]

+ 107 - 0
src/components/modals/PricelistModal.vue

@@ -0,0 +1,107 @@
+<template lang="pug">
+    modal(
+        name='pricelist-modal'
+        transition='nice-modal-fade'
+        width='400px'
+        height='600px'
+        :classes="['v--modal', 'pricelist-modal']"
+        @before-close='beforeClose'
+    )
+        .pricelist-content
+            h1 Lista de precios
+            .pricelist-items-wrapper
+                ul.pricelist-items
+                    li.pricelist-item(
+                        v-for='item in items'
+                        :key='item.id'
+                        @click.prevent='onApply(item)'
+                    )
+                        h3 {{ computePrice(item) }}
+                        h1 {{ item.pricelistName }}
+            .pricelist-options
+                button.pricelist-option(
+                    @click.prevent='onCancel'
+                ) Cancelar
+</template>
+
+<script>
+    export default {
+        props: {
+            show: {
+                type: Boolean,
+                default: false
+            },
+            items: {
+                type: Array,
+                default: []
+            }
+        },
+        watch: {
+            show(canShow) {
+                if (canShow) {
+                    this.$modal.show('pricelist-modal')
+                    return
+                }
+
+                this.$modal.hide('pricelist-modal')
+            }
+        },
+        methods: {
+            beforeClose(e) {
+                if(this.show) {
+                    e.stop()
+                }
+            },
+            computePrice(item) {
+                return (item.productPrice * (1 + item.priceDiscount)) + item.priceSurcharge
+            },
+            onApply(item) {
+                const price = this.computePrice(item)
+                this.$emit('onApply', price)
+            },
+            onCancel(e) {
+                this.$emit('onCancel')
+            }
+        }
+    }
+</script>
+
+<style lang="sass">
+    @import '../../assets/variables'
+    .pricelist-modal
+        .pricelist-content
+            width: 100%
+            height: 100%
+            padding: 15px
+            h1
+                font-size: 12pt
+                color: #757575
+            .pricelist-items-wrapper
+                width: 100%
+                height: calc(100% - 95px)
+                overflow-y: auto
+                .pricelist-items
+                    width: 100%
+                    padding-left: 0
+                    a
+                    .pricelist-item
+                        list-style: none
+                        padding: 0
+                        border-bottom: 1px solid #d3d3d3
+                        h1
+                            font-size: 10pt
+                        &:hover
+                            cursor: pointer
+                            border-bottom: 2px solid $app-main-color
+            .pricelist-options
+                float: right
+                .pricelist-option
+                    width: 160px
+                    height: 40px
+                    border: none
+                    box-shadow: none
+                    border-radius: 0
+                    margin-right: 5px
+                    background: $app-main-color
+                    color: $app-bg-color
+</style>

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

@@ -28,11 +28,17 @@
                 @onCancel='hideProductForm'
             )
             variant-modal
-            discount-modal(
-                :item='itemToDiscount' 
-                :options='baseCurrency'
+            //- discount-modal(
+            //-     :item='itemToDiscount' 
+            //-     :options='baseCurrency'
+            //-     :show='!!itemToDiscount'
+            //-     @onAccept='applyPrice'
+            //-     @onCancel='applyPrice'
+            //- )
+            pricelist-modal(
                 :show='!!itemToDiscount'
-                @onAccept='applyPrice'
+                :items='pricelistsForProduct'
+                @onApply='applyPrice'
                 @onCancel='applyPrice'
             )
         cart(
@@ -53,6 +59,7 @@
     import ProductModal from '../modals/ProductModal'
     import VariantModal from '../modals/VariantModal'
     import DiscountModal from '../modals/DiscountModal'
+    import PricelistModal from '../modals/PricelistModal'
 
     export default {
         components: {
@@ -62,11 +69,13 @@
             StoreSelector,
             ProductModal,
             VariantModal,
-            DiscountModal
+            DiscountModal,
+            PricelistModal
         },
         computed: {
             ...mapGetters([
                 'products',
+                'pricelistsForProduct',
                 'visibleProducts',
                 'variants',
                 'stores',

+ 1 - 1
src/store/getters.js

@@ -6,7 +6,7 @@ const getters = {
         return state.data
     },
     hasDataToSync(state) {
-        return state.data.length !== 0
+        return state.data && state.data.length !== 0
     },
     isSale(state) {
         return state.mode === 'sale'

+ 9 - 5
src/store/index.js

@@ -1,7 +1,7 @@
 import Vue from 'vue'
 import Vuex from 'vuex'
 import createLogger from 'vuex/dist/logger'
-import createDB from './plugins'
+// import createDB from './plugins'
 
 import state from '@/store/state'
 import getters from '@/store/getters'
@@ -24,6 +24,8 @@ import storeModule from './modules/store'
 import saleOrderModule from './modules/saleOrder'
 import stockPickingModule from './modules/stockPicking'
 import warehouseModule from './modules/warehouse'
+import pricelistModule from './modules/pricelist'
+import categoryModule from './modules/category'
 
 Vue.use(Vuex)
 
@@ -48,11 +50,13 @@ const store = new Vuex.Store({
         storeModule,
         saleOrderModule,
         stockPickingModule,
-        warehouseModule
+        warehouseModule,
+        pricelistModule,
+        categoryModule
     },
-    plugins: [
-        createDB,
-    ],
+    // plugins: [
+    //     createDB,
+    // ],
     strict: true
 })
 

+ 2 - 2
src/store/modules/bank.js

@@ -24,7 +24,7 @@ const mutations = {
     setLoadingBanks(state, loading) {    
         state.loadingBanks = !!loading
     },
-    setBanks (state, payload) {
+    setBanks(state, payload) {
         state.banks = payload
     },
     setSelectedBank(state, bankId) {
@@ -40,7 +40,7 @@ const mutations = {
 }
 
 const actions = {
-    initBanks ({ commit}, payload) {
+    initBanks ({ commit }, payload) {
         commit('setBanks', payload)
         commit('setLoadingBanks')
     },

+ 40 - 0
src/store/modules/category.js

@@ -0,0 +1,40 @@
+const state = {
+    loadingCategories: false,
+    categories: []
+}
+
+const getters = {
+    loadingCategories(state) {
+        return state.loadingCategories
+    },
+    categories(state) {
+        return state.categories
+    }
+}
+
+const mutations = {
+    setLoadingCategories(state, loading) {
+        state.loadingCategories = !!loading
+    },
+    setCategories(state, categories) {
+        state.categories = categories
+    }
+}
+
+const actions = {
+    initCategories({ commit }, categories) {
+        commit('setCategories', categories)
+        commit('setLoadingCategories')
+    },
+    resetCategory({ commit }) {
+        commit('setLoadingCategories', true)
+        commit('setCategories', [])
+    }
+}
+
+export default {
+    state,
+    getters,
+    actions,
+    mutations
+}

+ 86 - 0
src/store/modules/pricelist.js

@@ -0,0 +1,86 @@
+const state = {
+    loadingPricelists: false,
+    pricelists: [],
+    showPricelists: false
+}
+
+const getters = {
+    loadingPricelists(state) {
+        return state.loadingPricelists
+    },
+    pricelists(state) {
+        return state.pricelists
+    },
+    pricelistsForProduct(state, getters) {
+        let item = getters.itemToDiscount
+
+        if (!item) {
+            return []
+        }
+
+        let pricelists = []
+
+        for (let p of state.pricelists) {
+            if (p.type !== 'sale') {
+                continue
+            }
+
+            for (let v of p.versions) {
+                for (let i of v.items) {
+                    if (i.productId !== item.id && i.productTmplId !== item.tmplId && i.categoryId !== item.categoryId) {
+                        continue
+                    }
+
+                    pricelists.push({
+                        pricelistName: p.name,
+                        versionName: v.name,
+                        productPrice: getters.itemToDiscount.listPrice,
+                        ...i
+                    })
+                }
+            }
+        }
+
+        return pricelists
+    },
+    showPricelists(state) {
+        return state.showPricelists
+    }
+}
+
+const mutations = {
+    setLoadingPricelists(state, loading) {
+        state.loadingPricelists = !!loading
+    },
+    setPricelists(state, pricelists) {
+        state.pricelists = pricelists
+    },
+    togglePricelists(state, pricelistId) {
+        if (!pricelistId) {
+            return
+        }
+
+        state.showPricelists = !state.showPricelists
+    }
+}
+
+const actions = {
+    initPricelists({ commit }, pricelists) {
+        commit('setPricelists', pricelists)
+        commit('setLoadingPricelists')
+    },
+    togglePricelists({ commit }) {
+        commit('togglePricelists')
+    },
+    resetPricelist({ commit }) {
+        commit('setLoadingPricelists', true)
+        commit('setPricelists', [])
+    }
+}
+
+export default {
+    state,
+    getters,
+    actions,
+    mutations
+}