Browse Source

[ADD] process sale implemented

Gogs 7 years ago
parent
commit
ea2b083302
2 changed files with 312 additions and 14 deletions
  1. 311 13
      controllers/main.py
  2. 1 1
      src/store/actions.js

+ 311 - 13
controllers/main.py

@@ -4,6 +4,8 @@ from openerp.http import request
 from werkzeug.wrappers import Response
 from werkzeug.wrappers import Response
 from werkzeug.datastructures import Headers
 from werkzeug.datastructures import Headers
 from datetime import datetime
 from datetime import datetime
+from dateutil.relativedelta import relativedelta as rd
+from dateutil.parser import parse
 from gzip import GzipFile
 from gzip import GzipFile
 from StringIO import StringIO as IO
 from StringIO import StringIO as IO
 import simplejson as json
 import simplejson as json
@@ -11,6 +13,8 @@ import gzip
 import logging
 import logging
 
 
 LOGGER = logging.getLogger(__name__)
 LOGGER = logging.getLogger(__name__)
+DATE_FORMAT = '%Y-%m-%d'
+GZIP_COMPRESSION_LEVEL = 9
 
 
 class Sales(http.Controller):
 class Sales(http.Controller):
 
 
@@ -18,7 +22,7 @@ class Sales(http.Controller):
         Get server date
         Get server date
     '''
     '''
     def get_server_date(self):
     def get_server_date(self):
-        return datetime.now().strftime('%Y-%m-%d')
+        return datetime.now().strftime(DATE_FORMAT)
 
 
     '''
     '''
         Get current user information
         Get current user information
@@ -167,7 +171,7 @@ class Sales(http.Controller):
     '''
     '''
     def make_gzip_response(self, data=None, status=200):
     def make_gzip_response(self, data=None, status=200):
         gzip_buffer = IO()
         gzip_buffer = IO()
-        with GzipFile(mode='wb', compresslevel=9, fileobj=gzip_buffer) as gzip_file:
+        with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file:
             gzip_file.write(json.dumps(data))
             gzip_file.write(json.dumps(data))
         
         
         contents = gzip_buffer.getvalue()
         contents = gzip_buffer.getvalue()
@@ -264,23 +268,317 @@ class Sales(http.Controller):
             } for variant in product.product_variant_ids if variant.active]
             } for variant in product.product_variant_ids if variant.active]
         }
         }
 
 
-      
     '''
     '''
-        Create sale
+        Get currency from journal
     '''
     '''
-    @http.route('/eiru_sales/process_sale', type='json', auth='user', methods=['POST'], cors='*')
-    def process_sale(self, **kw):
-        print(kw)
+    def get_currency(self, journal_id):
+        journal = request.env['account.journal'].browse(journal_id)
+        return journal.default_credit_account_id.currency_id.id or journal.default_credit_account_id.company_currency_id.id
 
 
-        date_now = datetime.now().strftime('%Y-%m-%d')
+    '''
+        Create sale order from cart items values
+    '''
+    def create_sale_from_cart(self, partner_id, cart_items, date_confirm, currency_id, payment_term_id):
+        return request.env['sale.order'].create({
+            'partner_id': partner_id,
+            'order_line': [[0, False, {
+                'product_id': int(line.get('id')),
+                'product_uom_qty': float(line.get('quantity')),
+                'price_unit': float(line.get('price'))
+            }] for line in cart_items],
+            'picking_policy': 'direct',
+            'state': 'manual',
+            'date_confirm': date_confirm,
+            'currency_id': currency_id,
+            'payment_term': payment_term_id
+        })
 
 
+    '''
+        Confirm sale order
+    '''
+    def confirm_sale_order(self, sale_order_id):
+        return request.env['sale.order'].browse(sale_order_id).action_button_confirm()
 
 
-        return {
-            'message': 'ok'
+    '''
+        Create invoice from sale order
+    '''
+    def create_invoice(self, sale_order_id, currency_id, date_today):
+        sale_order = request.env['sale.order'].browse(sale_order_id)
+        invoice_id = sale_order.action_invoice_create()
+        invoice = request.env['account.invoice'].browse(invoice_id)
+
+        date_due = parse(date_today) + rd(days=max(invoice.payment_term.line_ids.mapped(lambda x: x.days + x.days2)))
+
+        invoice.write({
+            'currency_id': currency_id,
+            'date_invoice': date_today,
+            'date_due': date_due.strftime(DATE_FORMAT),
+            'state': 'open'
+        })
+
+        return invoice
+
+    '''
+        Create move lines
+    '''
+    def create_invoice_move_lines(self, invoice_id, paid_amount, date_today):
+        invoice = request.env['account.invoice'].browse(invoice_id)
+        invoice_move_lines = invoice._get_analytic_lines()
+        decimal_precision = request.env['decimal.precision'].precision_get('Account')
+
+        compute_taxes = request.env['account.invoice.tax'].compute(invoice)
+        invoice.check_tax_lines(compute_taxes)
+        invoice._recompute_tax_amount()
+
+        invoice_move_lines += request.env['account.invoice.tax'].move_line_get(invoice.id)
+
+        total, total_currency, invoice_move_lines = invoice.compute_invoice_totals(invoice.company_id.currency_id, invoice.reference, invoice_move_lines)
+
+        paid_percentage = paid_amount / round(total, decimal_precision)
+        distributed_percentage = -(paid_percentage / len(invoice.payment_term.line_ids))
+
+        payment_lines = []
+
+        for line in invoice.payment_term.line_ids:
+            date_due = (parse(date_today) + rd(days=line.days + line.days2)).strftime(DATE_FORMAT)
+
+            if paid_percentage and paid_percentage < 1.0:
+                payment_lines.append([date_today, paid_percentage])
+                paid_percentage = paid_amount = 0
+
+                if date_due == date_today and line.value_amount:
+                    distributed_percentage = -((payment_lines[0][1] - line.value_amount)  / (len(invoice.payment_term.line_ids) - 1))
+                    continue
+            
+            if line.value != 'balance':
+                payment_lines.append([date_due, line.value_amount + distributed_percentage])
+                continue
+
+            payment_lines.append([date_due, line.value_amount])
+
+            for payment_line in payment_lines:
+                current_price = round(total * payment_line[1], decimal_precision)
+
+                if current_price < 0.0:
+                    continue
+
+                paid_amount += current_price
+
+                invoice_move_lines.append({
+                    'type': 'dest',
+                    'name': '/',
+                    'price': current_price if payment_line[1] else round(total - paid_amount, decimal_precision) or total,
+                    'account_id': invoice.account_id.id,
+                    'date_maturity': payment_line[0],
+                    'amount_currency': invoice.company_id.currency_id.compute(payment_line[1], invoice.currency_id) if invoice.currency_id != invoice.company_id.currency_id else False,
+                    'currency_id': invoice.currency_id != invoice.company_id.currency_id and invoice.currency_id.id,
+                    'ref': invoice.reference
+                })
+                
+            payment_lines = []
+
+        return invoice_move_lines
+
+    '''
+        Create account move
+    '''
+    def create_account_move(self, invoice_id, invoice_move_lines):
+        invoice = request.env['account.invoice'].browse(invoice_id)
+        accounting_partner = request.env['res.partner']._find_accounting_partner(invoice.partner_id)
+
+        move_line_values = [(0, 0, invoice.line_get_convert(line, accounting_partner.id, invoice.date_invoice)) for line in invoice_move_lines]
+        move_line_values = invoice.group_lines(invoice_move_lines, move_line_values)
+        move_line_values = invoice.finalize_invoice_move_lines(move_line_values)
+
+        ctx = dict(request.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 = request.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': period.id
+        })
+
+        invoice.with_context(ctx).write({
+            'move_id': account_move.id,
+            'period_id': account_move.period_id.id,
+            'move_name': account_move.name,
+        })
+
+        account_move.post()
+
+        return account_move
+
+    '''
+        Number to invoice
+    '''
+    def number_invoice(self, invoice_id):
+        request.env['account.invoice'].browse(invoice_id).action_number()
+
+    '''
+        Create voucher
+    '''
+    def create_account_voucher(self, account_move_id, journal_id, currency_id, paid_amount):
+        account_move = request.env['account.move'].browse(account_move_id)
+        account_journal = request.env['account.journal'].browse(journal_id)
+
+        account_voucher = request.env['account.voucher'].create({
+            'reference': account_move.name,
+            'type': 'receipt',
+            'journal_id': account_journal.id,
+            'company_id': account_move.company_id.id,
+            'pre_line': True,
+            'amount': paid_amount,
+            'period_id': account_move.period_id.id,
+            'date': account_move.date,
+            'partner_id': account_move.partner_id.id,
+            'account_id': account_journal.default_credit_account_id.id,
+            'currency_id': currency_id,
+            'line_cr_ids': [[0, False, {
+                'date_due': l.date_maturity,
+                'account_id': l.account_id.id,
+                'date_original': l.invoice.date_invoice,
+                'move_line_id': l.id,
+                'amount_original': abs(l.credit or l.debit or 0.0),
+                'amount_unreconciled': abs(l.amount_residual),
+                'amount': abs(l.debit) if account_move.date == l.date_maturity else 0.0,
+                'reconcile': account_move.date == l.date_maturity,
+                'currency_id': currency_id
+            }] for l in account_move.line_id]
+        })
+
+        account_voucher.action_move_line_create()
+
+        return account_voucher
+
+    '''
+        Close a invoice
+    '''
+    def close_invoice(self, invoice_id):
+        invoice = request.env['account.invoice'].browse(invoice_id)
+
+        if invoice.residual == 0:
+            invoice.write({
+                'state': 'paid'
+            })
+
+    '''
+        Create account bank statement lines
+    '''
+    def create_bank_statement_lines(self, account_voucher_id, reference=None):
+        account_voucher = request.env['account.voucher'].browse(account_voucher_id)
+
+        return [[0, False, {
+            'name': account_voucher.reference,
+            'amount': account_voucher.amount,
+            'partner_id': account_voucher.partner_id.id,
+            'voucher_id': account_voucher.id,
+            'journal_id': account_voucher.journal_id.id,
+            'account_id': account_voucher.account_id.id,
+            'journal_entry_id': account_voucher.move_id.id,
+            'currency_id': account_voucher.currency_id.id,
+            'ref': 'POS/' + reference or ''
+        }]]
+
+
+    '''
+        Create account bank statement
+    '''
+    def create_bank_statement(self, account_voucher_id, account_bank_statement_lines, date_today):
+        account_voucher = request.env['account.voucher'].browse(account_voucher_id)
+        account_bank_statement = self.env['account.bank.statement'].search([('journal_id', '=', account_voucher.journal_id.id), ('date', '=', date_today)])
+
+        account_bank_statement_values = {
+            'date': date_today,
+            'user': request.env.user.id,
+            'journal_id': account_voucher.journal_id.id,
+            'period_id': account_voucher.period_id.id,
+            'line_ids': account_bank_statement_lines,
+            'state': 'open' if account_voucher.journal_id.type == 'cash' else 'draft'
         }
         }
 
 
+        if account_bank_statement:
+            size = len(account_bank_statement)
+
+            if size == 1:
+                account_bank_statement.write(account_bank_statement_values)
+            else:
+                account_bank_statement[size - 1].write(account_bank_statement_values)
+        else:
+            account_bank_statement.create(account_bank_statement_values)
+
+        return account_bank_statement
+
     '''
     '''
+        Process sale
     '''
     '''
-    def get_currency(self, journal_id):
-        journal = request.env['account.journal'].browse(journal_id)
-        return journal.default_credit_account_id.currency_id.id or journal.default_credit_account_id.company_currency_id.id
+    @http.route('/eiru_sales/process_sale', type='json', auth='user', methods=['POST'], cors='*')
+    def process_sale(self, **kw):
+        self.make_info_log('Processing sale...')
+
+        # Get date
+        self.make_info_log('Getting date')
+        date_now = datetime.now().strftime(DATE_FORMAT)
+
+        # Get currency
+        currency_id = self.get_currency(kw.get('journalId'))
+        self.make_info_log('[OK] Getting journal')
+
+        # Create sale orde
+        sale_order = self.create_sale_from_cart(kw.get('customerId'), kw.get('items'), date_now, currency_id, kw.get('paymentTermId'))
+        self.make_info_log('[OK] Creating sale order')
+
+        # Confirm sale
+        self.confirm_sale_order(sale_order.id)
+        self.make_info_log('[OK] Confirm sale order')
+
+        # Create invoice
+        invoice = self.create_invoice(sale_order.id, currency_id, date_now)
+        self.make_info_log('[OK] Creating invoice')
+
+        # Create invoice move lines
+        invoice_move_lines = self.create_invoice_move_lines(invoice.id, kw.get('total', 0), date_now)
+        self.make_info_log('[OK] Creating invoice move lines')
+
+        # Create account move
+        account_move = self.Creatingnt_move(invoice.id, invoice_move_lines)
+        self.make_info_log('[OK] Creating account move')
+
+        # Number invoice
+        self.number_invoice(invoice.id)
+        self.make_info_log('[OK] Number invoice')
+
+        # Create account voucher
+        account_voucher = self.create_account_voucher(account_move.id, kw.get('journalId'), currency_id, float(kw.get('payment')))
+        self.make_info_log('[OK] Creating account voucher')
+
+        # Close invoice
+        self.close_invoice(invoice.id)
+        self.make_info_log('[OK] Closing invoice')
+
+        # Create account bank statement lines
+        account_bank_statement_lines = self.create_bank_statement_lines(account_voucher.id)
+        self.make_info_log('[OK] Creating account bank statement lines')
+
+        # Create bank statement
+        self.create_bank_statement(account_voucher.id, account_bank_statement_lines, date_today)
+        self.make_info_log('[OK] Creating account bank statement')
+
+        return {
+            'process': True
+        }

+ 1 - 1
src/store/actions.js

@@ -89,7 +89,7 @@ const actions = {
                         price: item.price
                         price: item.price
                     }
                     }
                 }),
                 }),
-                total: 0,
+                total: getters.cartTotal,
                 customerId: getters.selectedCustomer.id,
                 customerId: getters.selectedCustomer.id,
                 paymentTermId: getters.selectedPaymentTerm.id,
                 paymentTermId: getters.selectedPaymentTerm.id,
                 journalId: getters.selectedJournal.id,
                 journalId: getters.selectedJournal.id,