Explorar el Código

[ADD] all sale POS features

robert hace 6 años
padre
commit
51d6662101

+ 45 - 12
controllers/main.py

@@ -405,24 +405,46 @@ class Purchases(http.Controller):
     '''
         Create purchase order from cart and return id
     '''
-    def create_purchase_order(self, supplier_id, cart_items, date_order, currency_id, pricelist_id, payment_term_id=None):
-        return request.env['purchase.order'].create({
+    def create_purchase_order(
+        self, 
+        supplier_id, 
+        cart_items, 
+        date_order, 
+        currency_id, 
+        pricelist_id, 
+        payment_term_id=None
+    ):
+
+        def get_product_obj(product_id):
+            return request.env['product.product'].browse(product_id)
+
+        lines = []
+
+        for item in cart_items:
+            product = get_product_obj(item.get('id'))
+
+            lines += [[0, False, {
+                'name': item.get('name'),
+                'date_planned': date_order,
+                'product_id': product.id,
+                'product_qty': float(item.get('quantity')),
+                'price_unit': float(item.get('price')),
+                'product_uom': product.uom_id.id
+            }]]
+
+        values = {
             'name': '/',
             'partner_id': supplier_id,
-            'order_line': [[0, False, {
-                'name': line.get('name'),
-                'date_planned': date_order,
-                'product_id': int(line.get('id')),
-                'product_qty': float(line.get('quantity')),
-                'price_unit': float(line.get('price'))
-            }] for line in cart_items],
+            'order_line': lines,
             'date_order': datetime.utcnow().strftime(DATETIME_FORMAT),
             'currency_id': currency_id,
             'pricelist_id': pricelist_id,
             'payment_term_id': payment_term_id,
             'location_id': self.get_stock_location_id(),
             'invoice_method': 'order'
-        })
+        }
+
+        return request.env['purchase.order'].create(values)
 
     '''
         Confirm purchase order
@@ -442,7 +464,14 @@ class Purchases(http.Controller):
     '''
         Create invoice
     '''
-    def create_invoice(self, supplier_id, cart_items, currency_id, payment_term_id=None):
+    def create_invoice(
+        self, 
+        supplier_id, 
+        cart_items, 
+        currency_id, 
+        payment_term_id=None, 
+        supplier_invoice_number=None
+    ):
         partner = request.env['res.partner'].browse(supplier_id)
         journal = request.env['account.journal'].search([('type', 'in', ['purchase']), ('company_id', '=', partner.company_id.id)])
 
@@ -459,6 +488,7 @@ class Purchases(http.Controller):
             'journal_id': journal.id,
             'currency_id': currency_id,
             'payment_term': payment_term_id,
+            'supplier_invoice_number': supplier_invoice_number,
             'type': 'in_invoice'
         })
 
@@ -750,8 +780,11 @@ class Purchases(http.Controller):
             self.make_info_log('Purchase order confirmed')
             
             invoice = purchase_order.invoice_ids
+            invoice.write({
+                'supplier_invoice_number': kw.get('supplierInvoiceNumber', None)
+            })
         else:
-            invoice = self.create_invoice(kw.get('supplierId'), kw.get('items'), currency_id, kw.get('paymentTermId'))
+            invoice = self.create_invoice(kw.get('supplierId'), kw.get('items'), currency_id, kw.get('paymentTermId'), kw.get('supplierInvoiceNumber', None))
             self.make_info_log('Invoice created')
 
         invoice_ids = invoice.mapped(lambda x: x.id) 

+ 24 - 18
package.json

@@ -9,30 +9,36 @@
 		"build": "export NODE_ENV=production &&./node_modules/.bin/webpack --progress --config webpack.config.js"
 	},
 	"devDependencies": {
-		"babel-core": "^6.25.0",
-		"babel-loader": "^7.1.1",
-		"babel-preset-env": "^1.6.0",
+		"babel-core": "^6.26.0",
+		"babel-loader": "^7.1.2",
+		"babel-preset-env": "^1.6.1",
 		"babel-preset-stage-2": "^6.24.1",
-		"css-loader": "^0.28.4",
-		"extract-text-webpack-plugin": "^3.0.0",
-		"file-loader": "^0.11.2",
-		"node-sass": "^4.5.3",
-		"pug": "^2.0.0-rc.2",
+		"copy-webpack-plugin": "^4.5.2",
+		"css-loader": "^0.28.9",
+		"extract-text-webpack-plugin": "^3.0.2",
+		"file-loader": "^1.1.6",
+		"hard-source-webpack-plugin": "^0.5.16",
+		"node-sass": "^4.7.2",
+		"offline-plugin": "^5.0.5",
+		"pug": "^2.0.0-rc.4",
 		"sass-loader": "^6.0.6",
-		"style-loader": "^0.18.2",
-		"url-loader": "^0.5.9",
-		"vue-loader": "^12.2.2",
-		"vue-template-compiler": "^2.4.1",
-		"webpack": "^3.3.0",
+		"style-loader": "^0.20.1",
+		"url-loader": "^0.6.2",
+		"vue-loader": "^14.0.3",
+		"vue-template-compiler": "^2.5.13",
+		"webpack": "^3.10.0",
 		"webpack-livereload-plugin": "^1.0.0"
 	},
 	"dependencies": {
 		"axios": "^0.17.1",
 		"fuse.js": "^3.2.0",
-		"vue": "^2.4.1",
-		"vue-form-wizard": "^0.7.0",
-		"vue-js-modal": "^1.3.1",
-		"vue2-datepicker": "^2.6.1",
-		"vuex": "^2.3.1"
+		"install": "^0.12.1",
+		"velocity-animate": "^2.0.5",
+		"vue": "^2.5.13",
+		"vue-form-wizard": "^0.8.2",
+		"vue-js-modal": "^1.3.9",
+		"vue2-datepicker": "^2.0.3",
+		"vuex": "^3.0.1",
+		"vuex-persistedstate": "^2.5.4"
 	}
 }

+ 9 - 4
src/App.vue

@@ -33,6 +33,7 @@
         },
         computed: mapGetters([
             'isLoading',
+            'isCompleted',
             'isProcessing',
             'state',
             'mode'
@@ -43,14 +44,18 @@
                 'checkSupplier',
                 'checkCart',
                 'checkAmountReceived',
-                'createPurchase'
+                'createPurchase',
+                'resetPurchase'
             ])
         },
         watch: {
-            state(value) {
-                if (value === 'done') {
-                    this.$refs.wizard.changeTab(3, 0, false)
+            isCompleted(value) {
+                if (!value) {
+                    return
                 }
+
+                this.$refs.wizard.changeTab(2, 0, false)
+                this.resetPurchase()
             }
         },
         mounted() {

+ 2 - 13
src/components/modals/BankPaymentModal.vue

@@ -65,7 +65,7 @@
             )
                 div(class='wizard-footer-left')
                     wizard-button(
-                        v-if='!!props && props.activeTabIndex > 0'
+                        v-if='props.activeTabIndex > 0'
                         @click.native='props.prevTab()'
                         :style='props.fillButtonStyle'
                     ) Volver
@@ -185,11 +185,7 @@
                 this.$refs.wizard.nextTab()
             },
             journalStepIncomplete() {
-                if (!this.$refs.wizard) {
-                    return
-                }
-
-                return this.$refs.wizard.activeTabIndex == 0 && !this.selectedJournal || !this.selectedJournal.fieldsAllowed.length
+                return this.$refs.wizard.activeTabIndex == 0 && !this.selectedJournal || !this.selectedJournal.fieldsAllowed || !this.selectedJournal.fieldsAllowed.length
             },
             fieldsStepIncomplete() {
                 let completed = false;
@@ -200,10 +196,6 @@
                     }
                 }
 
-                if (!this.$refs.wizard) {
-                    return
-                }
-
                 return this.$refs.wizard.activeTabIndex == 1 && !completed
             },
             amountStepIncomplete() {
@@ -225,9 +217,6 @@
                 this.$emit('onCancel')
             }
         },
-        mounted() {
-            console.log(this.$refs)
-        },
         data() {
             return {
                 values: {}

+ 40 - 40
src/components/modals/PriceModal.vue

@@ -1,25 +1,25 @@
 <template lang="pug">
     modal(name='product-price' transition='nice-modal-fade' @before-close='beforeClose' :classes="['v--modal', 'product-price']")
         form
-            .form-item
-                label.form-label Precio unitario
-                input.form-input(:value='(!item || item.price) | currency(...options)' readonly)
-            .form-item
-                label.form-label Precio mínimo
-                input.form-input(:value='(!item || item.minimumPrice) | currency(...options)' readonly)
-            .form-item
-                label.form-label Precio máximo
-                input.form-input(:value='(!item || item.maximumPrice) | currency(...options)' readonly)
+            .price-item
+                label.price-label Precio unitario
+                input.price-input(:value='(!item || item.price) | currency(...options)' readonly)
+            .price-item
+                label.price-label Precio mínimo
+                input.price-input(:value='(!item || item.minimumPrice) | currency(...options)' readonly)
+            .price-item
+                label.price-label Precio máximo
+                input.price-input(:value='(!item || item.maximumPrice) | currency(...options)' readonly)
             hr
-            .form-item
-                label.form-label Precio aplicado
-                input.form-input(v-model='formattedAmmount' :class="{'price-input-invalid': !isValid()}" autofocus)
-            .form-item
-                label.form-label Diferencia
-                input.form-input(:value='residual | absolute | currency(...options)' readonly)
-            .form-actions
-                button.form-action(@click='onAccept' :disabled='isValid() === false') Aceptar
-                button.form-action(@click='onCancel') Cancelar
+            .price-item
+                label.price-label Precio aplicado
+                input.price-input(v-model='formattedAmmount' :class="{'price-input-invalid': !isValid()}" autofocus)
+            .price-item
+                label.price-label {{ residual < 0 ? 'Ganancia' : 'Descuento' }}
+                input.price-input(:value='residual | absolute | currency(...options)' readonly)
+            .price-actions
+                button.price-action(@click.prevent='onAccept' :disabled='isValid() === false') Aceptar
+                button.price-action(@click.prevent='onCancel') Cancelar
 </template> 
 
 <script>
@@ -51,15 +51,15 @@
         computed: {
             formattedAmmount: {
                 get() {
-                    let formatted = this.$options.filters.currency(this.ammount, {...this.options})
-                    return this.ammount !== 0 ? formatted : formatted.replace(/\d/, '')
+                    let formatted = this.$options.filters.currency(this.amount, {...this.options})
+                    return this.amount !== 0 ? formatted : formatted.replace(/\d/, '')
                 },
                 set(value) {
                     value = value.replace(/[\.|,](\d{0,2}$)/, '?$1').split(/\?/)
                     value[0] = value[0].replace(/[^0-9]/g, '')
                     value = Number.parseFloat(value.join('.')) || 0
 
-                    this.ammount = value
+                    this.amount = value
                     this.computeResisual()
                 }
             }
@@ -69,7 +69,7 @@
                 if (value) {
                     this.$modal.show('product-price')
                 } else {
-                    this.ammount = 0
+                    this.amount = 0
                     this.residual = 0
 
                     this.$modal.hide('product-price')
@@ -83,14 +83,14 @@
                 }
             },
             onAccept() {
-                this.$emit('onAccept', this.ammount)
+                this.$emit('onAccept', this.amount)
             },
             onCancel() {
                 this.$emit('onCancel')
             },
             computeResisual() {
-                if (this.ammount !== 0) {
-                    this.residual = this.item.price - this.ammount
+                if (this.amount !== 0) {
+                    this.residual = this.item.price - this.amount
                 } else {
                     this.residual = 0
                 }
@@ -100,7 +100,7 @@
                     return false
                 }
 
-                if (this.ammount === 0) {
+                if (this.amount === 0) {
                     return false
                 }
 
@@ -108,7 +108,7 @@
                     return true
                 }
 
-                if (this.ammount >= this.item.minimumPrice && this.ammount <= this.item.maximumPrice) {
+                if (this.amount >= this.item.minimumPrice && this.amount <= this.item.maximumPrice) {
                     return true
                 }
 
@@ -117,7 +117,7 @@
         },
         data() {
             return {
-                ammount: 0,
+                amount: 0,
                 residual: 0
             }
         }
@@ -130,48 +130,48 @@
         width: 600px
         height: 340px !important
         form
-            width: 100%
-            height: 290px
-            padding: 15px
-            .form-item
+            width: 100% !important
+            height: 290px !important
+            padding: 15px !important
+            .price-item
                 width: 100%
                 height: 45px
                 margin-bottom: 10px
                 &:nth-child(1)
-                    .form-input
+                    .price-input
                         border: none
                 &:nth-child(2), &:nth-child(3), &:nth-child(6) 
                     height: 35px
                     margin-bottom: 5px
-                    .form-label
+                    .price-label
                         width: 30%
                         height: 35px
                         font-size: 10pt
                         color: $app-dark-color
-                    .form-input
+                    .price-input
                         width: 70%
                         height: 35px
                         font-size: 18pt
                         text-align: right
                         border: none
-                .form-label
+                .price-label
                     width: 30%
                     height: 45px
                     font-size: 14pt
-                .form-input
+                .price-input
                     width: 70%
                     height: 45px
                     font-size: 28pt
                     text-align: right
                     border-radius: 0
-                    &.form-input-invalid
+                    &.price-input-invalid
                         border-color: $app-error-color
                         box-shadow: 1px 1px 2px $app-error-color, -1px -1px 2px $app-error-color
                         &:focus
                             outline: none
-            .form-actions
+            .price-actions
                 float: right
-                .form-action
+                .price-action
                     width: 160px
                     height: 40px
                     border: none

+ 26 - 13
src/components/steps/PaymentStep.vue

@@ -54,6 +54,9 @@
                     @onClickOption='changePaymentMethod'
                     @onChangeValue='changeAmountReceived($event)'
                 )
+            .form-item
+                label.form-label Nº de Factura
+                input.form-input(v-model='invoiceNumber' :value='invoiceNumber')
             //- input para el vuelto del pago en caso de pago en efectivo
             div(v-show="paymentType === 'cash'")
                 hr
@@ -75,18 +78,18 @@
                         tr(v-for='line in paymentLines')
                             td {{ line.total | currency(...selectedCurrency) }}
                             td {{ line.date }}
-        //- bank-payment-modal(
-        //-     :initialAmount='amountToPay'
-        //-     :journals='bankJournals'
-        //-     :selectedJournal='selectedJournal'
-        //-     :banks='banks'
-        //-     :chequeTypes='chequeTypes'
-        //-     :show='showBankPayment'
-        //-     @onSelectBankJounal='selectJournal'
-        //-     @onNotify='notify'
-        //-     @onDone='endBankPayment'
-        //-     @onCancel='cancelBankPayment'
-        //- )
+        bank-payment-modal(
+            :initialAmount='amountToPay'
+            :journals='bankJournals'
+            :selectedJournal='selectedJournal'
+            :banks='banks'
+            :chequeTypes='chequeTypes'
+            :show='showBankPayment'
+            @onSelectBankJounal='selectJournal'
+            @onNotify='notify'
+            @onDone='endBankPayment'
+            @onCancel='cancelBankPayment'
+        )
 </template>
 
 <script>
@@ -114,6 +117,14 @@
                     }
                 }
             },
+            invoiceNumber: {
+                get() {
+                    return this.supplierInvoiceNumber
+                },
+                set(value) {
+                    this.changeSupplierInvoiceNumber(value)
+                }
+            },
             ...mapGetters([
                 'companyName',
                 'amountToPay',
@@ -142,7 +153,8 @@
                 'paymentMethods',
                 'banks',
                 'bankPaymentTypes',
-                'chequeTypes'
+                'chequeTypes',
+                'supplierInvoiceNumber'
             ])
         },
         watch: {
@@ -189,6 +201,7 @@
                 'changeBankPaymentData',
                 'computePaymentLines',
                 'toggleBankPayment',
+                'changeSupplierInvoiceNumber',
                 'notify'
             ])
         }

+ 18 - 4
src/store/app.js

@@ -6,6 +6,7 @@ const state = {
     currentMode: Modes.PURCHASE,
     currentState: States.NONE,
     footerButtonsVisibility: false,
+    completed: false,
     loading: true
 }
 
@@ -25,6 +26,9 @@ const getters = {
     state() {
         return state.currentState
     },
+    isCompleted(state) {
+        return state.completed
+    },
     isLoading() {
         return state.loading
     }
@@ -40,6 +44,9 @@ const mutations = {
     toggleFooterButtonsVisibility(state) {
         state.footerButtonsVisibility = !state.footerButtonsVisibility
     },
+    setCompleted(state, completed) {
+        state.completed = completed
+    },
     setLoading(state, loading) {
         state.loading = loading
     }
@@ -50,6 +57,7 @@ const actions = {
         commit('setMode', payload || getters.mode)
 
         commit('setLoading', true)
+        commit('setCompleted', false)
         
         return axios.get(Urls.INIT_PURCHASE_URL, {
             params: {
@@ -57,6 +65,8 @@ const actions = {
             }
         }).then(response => {
             commit('setLoading', false)
+            commit('toggleFooterButtonsVisibility')
+            
             dispatch('explodeData', response.data)
         }).catch(error => console.log(error))
     },
@@ -65,7 +75,7 @@ const actions = {
             dispatch(`init${key[0].toUpperCase()}${key.slice(1)}`, payload[key])
         }
     },
-    createObject({ dispatch }, payload) {
+    createObject({ _ }, payload) {
         const data = {
             jsonrpc: '2.0',
             method: 'call',
@@ -117,12 +127,16 @@ const actions = {
                 supplierId: getters.selectedSupplier.id,
                 paymentTermId: getters.selectedPaymentTerm.id,
                 journalId: getters.selectedJournal.id,
-                payment: getters.initialPayment > getters.cartTotal ? getters.cartTotal : getters.initialPayment
+                payment: getters.initialPayment > getters.cartTotal ? getters.cartTotal : getters.initialPayment,
+                supplierInvoiceNumber: getters.supplierInvoiceNumber || null
             }
         }
 
-        return axios.post(Urls.PROCESS_PURCHASE_URL, data).then(response => {
+        return axios.post(Urls.PROCESS_PURCHASE_URL, data).then(_ => {
             dispatch('resetPurchase')
+
+            commit('setLoading', false)
+            commit('setCompleted', true)
         }).catch(error => {
             console.log(error)
         })
@@ -138,7 +152,7 @@ const actions = {
 
         dispatch('initPurchase')
     },
-    notify({ commit }, payload) {
+    notify({ _ }, payload) {
         openerp.web.notification.do_warn('Atención', payload)
         return false
     }

+ 4 - 0
src/store/modules/journal.js

@@ -54,6 +54,9 @@ const actions = {
         commit('autoSelectJournal')
         commit('setLoadingJournals', false)
     },
+    autoSelectJournal({ commit }) {
+        commit('autoSelectJournal')
+    },
     selectJournal({ commit }, payload) {
         commit('setSelectedJournal', payload)
     },
@@ -61,6 +64,7 @@ const actions = {
         commit('setLoadingJournals', false)
         commit('setJournals', [])
         commit('setSelectedJournal', null)
+        commit('autoSelectJournal')
     }
 }
 

+ 12 - 1
src/store/modules/payment.js

@@ -9,7 +9,8 @@ const state = {
     initialPayment: 0,
     amountResidual: 0,
     paymentLines: [],
-    bankPaymentData: null
+    bankPaymentData: null,
+    supplierInvoiceNumber: null
 }
 
 const getters = {
@@ -71,6 +72,9 @@ const getters = {
     paymentLines(state) {
         return state.paymentLines
     },
+    supplierInvoiceNumber(state) {
+        return state.supplierInvoiceNumber
+    },
     loadingPaymentTerms(state) {
         return state.loadingPaymentTerms
     }
@@ -192,6 +196,9 @@ const mutations = {
     },
     setBankPaymentData(state, bankPaymentData) {
         state.bankPaymentData = bankPaymentData
+    },
+    setSupplierInvoiceNumber(state, invoiceNumber) {
+        state.supplierInvoiceNumber = invoiceNumber
     }
 }
 
@@ -250,6 +257,9 @@ const actions = {
             total: getters.cartTotal
         })
     },
+    changeSupplierInvoiceNumber({ commit }, invoiceNumber) {
+        commit('setSupplierInvoiceNumber', invoiceNumber)
+    },
     resetPayment({ commit }) {
         commit('setLoadingPaymentTerms', true)
         commit('setPaymentTerms', [])
@@ -259,6 +269,7 @@ const actions = {
         commit('setAmountToPay', 0)
         commit('setInitialPayment', 0)
         commit('setAmountResidual')
+        commit('setSupplierInvoiceNumber', null)
 
         commit('autoSelectPaymentTerm')
     }

+ 1 - 1
src/store/modules/user.js

@@ -8,7 +8,7 @@ const getters = {
         return state.user
     },
     companyName(state) {
-        return state.user && state.user.companyName
+        return state.user && state.user.company.name
     },
     loadingUser(state) {
         return state.loadingUser

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 416 - 158
yarn.lock


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio