Browse Source

[FIX] discount in products

Gogs 7 years ago
parent
commit
e943d0d4f5

+ 2 - 1
__init__.py

@@ -5,4 +5,5 @@ from models import account_voucher
 from models import product_template
 from models import res_company
 from models import res_currency
-from models import res_partner
+from models import res_partner
+from models import sale_order

+ 32 - 16
models/account_voucher.py

@@ -33,34 +33,40 @@ class AccountVoucher(models.Model):
 
         # Step 3: Create sale order and confirm
         sale_order = self.env['sale.order'].create({
-            'partner_id': int(values['customer_id']),
+            'partner_id': values.get('customer_id'),
             'order_line': [[0, False, { 
-                'product_id': int(v['id']), 
-                'product_uom_qty': float(v['qty']), 
-                'price_unit': float(v['price']),
-                'state': 'confirmed'
-            }] for v in values['cart_items']],
+                'product_id': int(v.get('id')), 
+                'product_uom_qty': float(v.get('qty')), 
+                'price_unit': float(v.get('price')),
+                'discount': float(v.get('discount')),
+            }] for v in values.get('cart_items', [])],
             'picking_policy': 'direct',
             'state': 'manual',
             'date_confirm': date_now,
             'currency_id': currency_id,
             'pricelist_id': pricelist.id,
-            'payment_term': int(values['payment_term_id'])
+            'payment_term': values.get('payment_term_id')
         })
 
+
+        sale_order.action_button_confirm()
+
         # Step 4: Create invoice and calculate due date
         invoice = self.env['account.invoice'].browse(sale_order.action_invoice_create())
 
+
         due_date = parse(date_now) + rd(days=max(invoice.payment_term.line_ids.mapped(lambda x: x.days + x.days2)))
 
         invoice.write({
             'currency_id': currency_id,
             'date_invoice': date_now,
-            'date_due': due_date.strftime(date_format)
+            'date_due': due_date.strftime(date_format),
+            'state': 'open'
         })
 
         # Step 5: Create invoice move lines
         amount_paid = float(values['amount_paid'])
+
         decimal_precision = self.env['decimal.precision'].precision_get('Account')
 
         invoice_move_lines = invoice._get_analytic_lines()
@@ -92,7 +98,7 @@ class AccountVoucher(models.Model):
             if line.value != 'balance':
                 total_lines.append([due_date, line.value_amount + distribute_percent])
                 continue
-            
+
             total_lines.append([due_date, line.value_amount])
 
             for total_line in total_lines:
@@ -122,17 +128,31 @@ class AccountVoucher(models.Model):
         move_line_values = invoice.group_lines(invoice_move_lines, move_line_values)
         move_line_values = invoice.finalize_invoice_move_lines(move_line_values)
 
-        account_move = self.env['account.move'].create({
+        ctx = dict(self._context, lang=invoice.partner_id.lang, company_id=invoice.company_id.id)
+        period = invoice.period_id
+
+        if not period:
+            period = period.with_context(ctx).find(invoice.date_invoice)[:1]
+
+        if period:
+            for line in move_line_values:
+                line[2]['period_id'] = period.id
+
+        ctx['invoice'] = invoice
+        ctx_nolang = ctx.copy()
+        ctx_nolang.pop('lang', None)
+ 
+        account_move = self.env['account.move'].with_context(ctx_nolang).create({
             'ref': invoice.reference or invoice.name,
             'line_id': move_line_values,
             'journal_id': invoice.journal_id.id,
             'date': invoice.date_invoice,
             'narration': invoice.comment,
             'company_id': invoice.company_id.id,
-            'period_id': invoice.period_id.find(invoice.date_invoice).id
+            'period_id': period.id
         })
 
-        invoice.write({
+        invoice.with_context(ctx).write({
             'move_id': account_move.id,
             'period_id': account_move.period_id.id,
             'move_name': account_move.name,
@@ -140,11 +160,7 @@ class AccountVoucher(models.Model):
 
         account_move.post()
 
-        # Step 7: Validate invoice
         invoice.action_number()
-        invoice.write({
-            'state': 'open'
-        })
 
         # Step 8: Create voucher
         account_voucher = self.create({

+ 4 - 0
models/sale_order.py

@@ -0,0 +1,4 @@
+from openerp import api, fields, models
+
+class SaleOrder(models.Model):
+    _inherit = 'sale.order'

+ 2 - 2
src/App.vue

@@ -46,9 +46,9 @@
         methods: mapActions([
             'initSale',
             'checkCart',
-            'completeSale',
             'checkCustomer',
-            'checkAmountPaid'
+            'checkAmountPaid',
+            'completeSale'
         ]),
         mounted() {
             this.initSale(this.$root.pos_instance)

+ 3 - 2
src/components/cart/CartItem.vue

@@ -45,10 +45,10 @@
                 this.removeFromCart(item)
             },
             formatPrice() {
-                return accounting.formatMoney(this.item.list_price, this.currencySymbol, 0, '.', ',')
+                return accounting.formatMoney(this.item.price, this.currencySymbol, 0, '.', ',')
             },
             formatSubtotal() {
-                return accounting.formatMoney(this.item.list_price * this.item.qty, this.currencySymbol, 0, '.', ',')
+                return accounting.formatMoney(this.item.price * this.item.qty, this.currencySymbol, 0, '.', ',')
             },
             ...mapActions([
                 'addToCart',
@@ -59,6 +59,7 @@
         },
         mounted() {
             this.$set(this.item, 'qty', 1)
+            this.$set(this.item, 'price', this.item.list_price)
             this.$set(this.item, 'discount', 0)
         }
     }

+ 38 - 22
src/components/cart/ProductDiscount.vue

@@ -3,22 +3,20 @@
         form.discount-form
             .discount-item
                 label.discount-label Precio
-                input.discount-input(:value="formatAmount()")
-            
-            .discount-item
-                label.discount-label Descuento
-                input.discount-input(:value="discount")
-            
+                input.discount-input(:value="formatPrice()" readonly)
             .discount-item
                 label.discount-label Precio Mínimo
-                input.discount-input(:value="format('min')")
-            
+                input.discount-input(:value="formatMinPrice()" readonly)
             .discount-item
                 label.discount-label Precio Máximo
-                input.discount-input(:value="format('max')")
+                input.discount-input(:value="formatMaxPrice()" readonly)
+            //- hr
+            .discount-item
+                label.discount-label Descuento
+                input.discount-input(:value="discount" v-model="discount" autofocus)
         .discount-options
-            button.discount-button(value="accept" @click="discountHandler()") Aceptar
-            button.discount-button(value="cancel" @click="discountHandler()") Cancelar
+            button.discount-button(@click="applyDiscount({ apply: true })") Aceptar
+            button.discount-button(@click="applyDiscount({ apply: false })") Cancelar
 </template>
 
 <script>
@@ -26,12 +24,26 @@
 
     export default {
         computed: {
+            price() {
+                return this.productToDiscount ? this.productToDiscount.list_price : 0
+            },
+            minimumPrice() {
+                let amount = this.productToDiscount ? Math.min(...this.productToDiscount.prices.map(x => x.price)) : 0
+                return amount === Number.NEGATIVE_INFINITY || amount > this.price ? this.productToDiscount.list_price : amount
+            },
+            maximumPrice() {
+                let amount = this.productToDiscount ? Math.max(...this.productToDiscount.prices.map(x => x.price)) : 0
+                return amount === Number.POSITIVE_INFINITY || amount < this.price ? this.productToDiscount.list_price : amount
+            },
             discount: {
-                set(value) {
-                    console.log(value)
-                },
                 get() {
-                    return accounting.formatMoney(0, this.currencySymbol, 0, '.', ',')
+                    let value = (this.productToDiscount && this.productToDiscount.discount) || this.minimumPrice
+                    return accounting.formatMoney(value, this.currencySymbol, 0, '.', ',')
+                },
+                set(value) {
+                    value = accounting.unformat(value, ',')
+
+                    this.productToDiscount.discount = value
                 }
             },
             ...mapGetters([
@@ -49,14 +61,17 @@
             }
         },
         methods: {
-            discountHandler(e) {
-                this.discountFromCart(null)
+            formatPrice() {
+                return accounting.formatMoney(this.price, this.currencySymbol, 0, '.', ',')
+            },
+            formatMinPrice() {
+                return accounting.formatMoney(this.minimumPrice, this.currencySymbol, 0, '.', ',')
             },
-            formatAmount() {
-                return accounting.formatMoney(this.productToDiscount ? this.productToDiscount.list_price : 0, this.currencySymbol, 0, '.', ',')
+            formatMaxPrice() {
+                return accounting.formatMoney(this.maximumPrice, this.currencySymbol, 0, '.', ',')
             },
-            format(values) {
-                return accounting.formatMoney(0, this.currencySymbol, 0, '.', ',')
+            checkPrice() {
+                return this.minimumPrice >= this.productToDiscount.discount <= this.maximumPrice
             },
             beforeClose(e) {
                 if (this.productToDiscount) {
@@ -65,7 +80,8 @@
 
             },
             ...mapActions([
-                'discountFromCart'
+                'discountFromCart',
+                'applyDiscount'
             ])
         }
     }

+ 2 - 1
src/store/actions.js

@@ -44,7 +44,8 @@ const actions = {
                         return {
                             id: item.id,
                             qty: item.qty,
-                            price: item.list_price
+                            price: item.list_price,
+                            discount: item.price >= item.list_price ? 0 : item.price / item.list_price
                         }
                     }),
                     cart_total: getters.total,

+ 26 - 2
src/store/modules/cart.js

@@ -36,6 +36,10 @@ const mutations = {
     discountFromCart(state, payload) {
         state.productToDiscount = payload
     },
+    applyDiscount(state, payload) {
+        let finded = state.cart.find(item => item.id == state.productToDiscount.id)
+        finded.price = state.productToDiscount.discount
+    },
     removeFromCart(state, payload) {
         let findedIndex = state.cart.findIndex(item => item.id == payload.product.id)
         state.cart.splice(findedIndex, 1)
@@ -44,7 +48,7 @@ const mutations = {
         let sum = 0
 
         state.cart.forEach(item => {
-            sum = sum + (item.list_price * (item.qty || 1))
+            sum = sum + ((item.price || item.list_price) * (item.qty || 1))
         })
 
         state.total = sum
@@ -63,7 +67,7 @@ const actions = {
         //     product: null
         // })
     },
-    subtractFromCart({ commit, dispatch}, payload) {
+    subtractFromCart({ commit, dispatch }, payload) {
         if (payload.qty > 1) {
             commit('subtractFromCart', {
                 product: payload
@@ -79,6 +83,26 @@ const actions = {
     discountFromCart({ commit }, payload) {
         commit('discountFromCart', payload)
     },
+    applyDiscount({ getters, commit, dispatch  }, payload) {
+        if(payload.apply) {
+            let product = getters.productToDiscount
+            let min = Math.min(...product.prices.map(x => x.price))
+            let max = Math.max(...product.prices.map(x => x.price))
+
+            min = min === Number.NEGATIVE_INFINITY || min > product.list_price ? product.list_price : min
+            max = max === Number.POSITIVE_INFINITY || max < product.list_price ? product.list_price : max
+
+            if (product.discount < min || product.discount > max) {
+                dispatch('notify', 'No se puede aplicar este descuento')
+                return
+            }
+
+            commit('applyDiscount', product.id)
+            commit('calculateTotal')
+        }
+
+        dispatch('discountFromCart', null)
+    },
     removeFromCart({ commit, dispatch }, payload) {
         commit('removeFromCart', {
             product: payload