浏览代码

[ADD] process sale implemented

Gogs 7 年之前
父节点
当前提交
ea2b083302
共有 2 个文件被更改,包括 312 次插入14 次删除
  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.datastructures import Headers
 from datetime import datetime
+from dateutil.relativedelta import relativedelta as rd
+from dateutil.parser import parse
 from gzip import GzipFile
 from StringIO import StringIO as IO
 import simplejson as json
@@ -11,6 +13,8 @@ import gzip
 import logging
 
 LOGGER = logging.getLogger(__name__)
+DATE_FORMAT = '%Y-%m-%d'
+GZIP_COMPRESSION_LEVEL = 9
 
 class Sales(http.Controller):
 
@@ -18,7 +22,7 @@ class Sales(http.Controller):
         Get server date
     '''
     def get_server_date(self):
-        return datetime.now().strftime('%Y-%m-%d')
+        return datetime.now().strftime(DATE_FORMAT)
 
     '''
         Get current user information
@@ -167,7 +171,7 @@ class Sales(http.Controller):
     '''
     def make_gzip_response(self, data=None, status=200):
         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))
         
         contents = gzip_buffer.getvalue()
@@ -264,23 +268,317 @@ class Sales(http.Controller):
             } 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
                     }
                 }),
-                total: 0,
+                total: getters.cartTotal,
                 customerId: getters.selectedCustomer.id,
                 paymentTermId: getters.selectedPaymentTerm.id,
                 journalId: getters.selectedJournal.id,