# -*- coding: utf-8 -*- from openerp import http from openerp.http import request from werkzeug.wrappers import Response from werkzeug.datastructures import Headers from datetime import datetime from gzip import GzipFile from StringIO import StringIO as IO import simplejson as json import gzip import logging LOGGER = logging.getLogger(__name__) DATE_FORMAT = '%Y-%m-%d' GZIP_COMPRESSION_LEVEL = 9 class PaymentsSales(http.Controller): ''' Get server date ''' def get_server_date(self): return datetime.now().strftime(DATE_FORMAT) ''' Get partner customer ''' def get_user(self): user = request.env.user return { 'id': user.id, 'name': user.name, 'displayName': user.display_name, 'company': { 'id': user.company_id.id, 'name': user.company_id.name }, 'currency': { 'id': user.company_id.currency_id.id, 'name': user.company_id.currency_id.name, 'displayName': user.company_id.currency_id.display_name, 'symbol': user.company_id.currency_id.symbol, 'rateSilent': user.company_id.currency_id.rate_silent, 'thousandsSeparator': user.company_id.currency_id.thousands_separator, 'decimalSeparator': user.company_id.currency_id.decimal_separator, 'decimalPlaces': user.company_id.currency_id.decimal_places, 'position': user.company_id.currency_id.position } } ''' Get partner customer ''' def get_customers(self): domain = [('customer', '=', True), ('active', '=', True), ('credit', '>', 0)] partners = [] for customer in request.env['res.partner'].search(domain): invoices = [] partner_invoice = [] for invoice_ids in customer.invoice_ids: if invoice_ids.state == 'open': partner_invoice.append(invoice_ids.id) if customer.is_company == True: for child in customer.child_ids: for invoice_ids in child.invoice_ids: if invoice_ids.state == 'open': partner_invoice.append(invoice_ids.id) # for invoice in request.env['account.invoice'].browse(partner_invoice): for invoice in request.env['account.invoice'].search([('id', 'in', partner_invoice),('state', '=', 'open')]): movelines = [] moves = [] for move in invoice.move_id: for moveline in move.line_id: if moveline.amount_residual > 0 and moveline.state != "draft" and moveline.credit <= 0: currencyAmount = [] decimal_precision = request.env['decimal.precision'].precision_get('Account') domain = [('active', '=', True)] for currency in request.env['res.currency'].search(domain): amount_currency = moveline.amount_currency if moveline.amount_currency <= 0: amount_currency = moveline.debit currencyAmount.append({ 'id': currency.id, 'name': currency.name, 'displayName': currency.display_name, 'base': currency.base, 'accuracy': currency.accuracy, 'rateSilent': currency.rate_silent, 'rounding': currency.rounding, 'symbol': currency.symbol, 'position': currency.position, 'thousandsSeparator': currency.thousands_separator, 'decimalSeparator': currency.decimal_separator, 'decimalPlaces': currency.decimal_places, 'amountCurency': round(amount_currency * (currency.rate_silent/ invoice.currency_id.rate_silent), decimal_precision), 'amountCurencyResidual': round((moveline.amount_residual_currency * (currency.rate_silent / invoice.currency_id.rate_silent)), decimal_precision) }) movelines.append({ 'id': moveline.id, 'amountResidual': moveline.amount_residual, 'credit': moveline.credit, 'debit': moveline.debit, 'dateMaturity': moveline.date_maturity, 'invoice': invoice.id, 'amountCurrency': moveline.amount_currency if moveline.amount_currency > 0 else moveline.debit, 'amountResidualCurrency': moveline.amount_residual_currency, 'currencyAmount': currencyAmount }) invoices.append({ 'id': invoice.id, 'number': invoice.number, 'dateInvoice': invoice.date_invoice, 'amountTotal': invoice.amount_total, 'residual': invoice.residual, 'moveLines': movelines, 'currency' : { 'id': invoice.currency_id.id, 'name': invoice.currency_id.name, 'displayName': invoice.currency_id.display_name, 'symbol': invoice.currency_id.symbol, 'rateSilent': invoice.currency_id.rate_silent, 'thousandsSeparator': invoice.currency_id.thousands_separator, 'decimalSeparator': invoice.currency_id.decimal_separator, 'decimalPlaces': invoice.currency_id.decimal_places, 'position': invoice.currency_id.position } }) partners.append({ 'id': customer.id, 'name': customer.name, 'displayName': customer.display_name, 'ruc': customer.ruc, 'imageMedium': customer.image_medium, 'phone': customer.phone, 'mobile': customer.mobile, 'email': customer.email, 'credit': customer.credit, 'creditLimit': customer.credit_limit, 'invoices': invoices }) return partners ''' Get Journal ''' def get_journals(self): # domain =[('active', '=', True),('type', 'in',['bank', 'cash']), ('default_credit_account_id.currency_id', '=', False)] domain =[('active', '=', True),('type', 'in',['bank', 'cash'])] paymentsJournals = [] for journal in request.env['account.journal'].search(domain, order="id"): if not (journal.store_ids >= request.env.user.store_ids): continue paymentsJournals.append({ 'id': journal.id, 'name': journal.name, 'displayName': journal.display_name, 'code': journal.code, 'cashControl': journal.cash_control, 'type': journal.type, 'currency': { 'id': journal.currency.id, 'name': journal.currency.name, 'displayName': journal.currency.display_name, 'symbol': journal.currency.symbol, 'rateSilent': journal.currency.rate_silent, 'thousandsSeparator':journal.currency.thousands_separator, 'decimalSeparator': journal.currency.decimal_separator, 'decimalPlaces': journal.currency.decimal_places, 'position': journal.currency.position }, 'defaultCreditAccount':{ 'id': journal.default_credit_account_id.id, 'name': journal.default_credit_account_id.name, 'displayName': journal.default_credit_account_id.display_name, 'code': journal.default_credit_account_id.code, 'exchangeRate': journal.default_credit_account_id.exchange_rate, 'foreignBalance': journal.default_credit_account_id.foreign_balance, 'reconcile': journal.default_credit_account_id.reconcile, 'debit': journal.default_credit_account_id.debit, 'credit': journal.default_credit_account_id.credit, 'currencyMode': journal.default_credit_account_id.currency_mode, 'companyCurrency':{ 'id': journal.default_credit_account_id.company_currency_id.id, 'name': journal.default_credit_account_id.company_currency_id.name, 'displayName': journal.default_credit_account_id.company_currency_id.display_name, 'symbol': journal.default_credit_account_id.company_currency_id.symbol, 'rateSilent': journal.default_credit_account_id.company_currency_id.rate_silent }, 'currency':{ 'id': journal.default_credit_account_id.currency_id.id, 'name': journal.default_credit_account_id.currency_id.name, 'displayName': journal.default_credit_account_id.currency_id.display_name, 'symbol': journal.default_credit_account_id.currency_id.symbol, 'rateSilent': journal.default_credit_account_id.currency_id.rate_silent }, } }) return paymentsJournals ''' Get Currency ''' def get_currency(self): return [{ 'id': currency.id, 'name': currency.name, 'displayName': currency.display_name, 'base': currency.base, 'accuracy': currency.accuracy, 'rateSilent': currency.rate_silent, 'rounding': currency.rounding, 'symbol': currency.symbol, 'position': currency.position, 'thousandsSeparator': currency.thousands_separator, 'decimalSeparator': currency.decimal_separator, 'decimalPlaces': currency.decimal_places } for currency in request.env['res.currency'].search([('active', '=', True)])] ''' Make JSON response ''' def make_json_response(self, data=None, status=200): return Response(json.dumps(data), status=status, content_type='application/json') ''' Make GZIP to JSON response ''' def make_gzip_response(self, data=None, status=200): gzip_buffer = IO() with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file: gzip_file.write(json.dumps(data)) contents = gzip_buffer.getvalue() gzip_buffer.close() headers = Headers() headers.add('Content-Encoding', 'gzip') headers.add('Vary', 'Accept-Encoding') headers.add('Content-Length', len(contents)) return Response(contents, status=status, headers=headers, content_type='application/json') ''' Logger Info ''' def make_info_log(self, log): LOGGER.info(log) ''' New Payments resource router ''' @http.route('/eiru_payments/init', auth='user', methods=['GET'], cors='*') def init_payments(self, **kw): self.make_info_log('Sending JSON response') return self.make_gzip_response({ 'date': self.get_server_date(), 'user': self.get_user(), 'customers': self.get_customers(), 'journals': self.get_journals(), 'currencies': self.get_currency() }) ''' Get the current period ''' def get_period(self, date_server): return request.env['account.period'].search([('date_start','<=', date_server), ('date_stop', '>=', datetime.now().strftime(DATE_FORMAT))]) ''' Get Invoice ''' def get_invoice(self, invoice_id): return request.env['account.invoice'].search([('id', '=', invoice_id)]) ''' Create Voucher ''' def create_voucher(self, period, invoice, company_id, amountPayments, date_server, journalId, move_line_Ids, customerId): ## Get Journal journal_id = request.env['account.journal'].browse(int(journalId)) currency_id = journal_id.default_credit_account_id.currency_id.id or journal_id.default_credit_account_id.company_currency_id.id # currency_rateSilent = journal_id.default_credit_account_id.currency_id.rate_silent or journal_id.default_credit_account_id.company_currency_id.rate_silent # Get Move Lines move_line = request.env['account.move.line'].browse(move_line_Ids).sorted(key=lambda r: r.id) # get customer customerId = request.env['res.partner'].browse(customerId) decimal_precision = request.env['decimal.precision'].precision_get('Account') # Currencies company_currency = request.env.user.company_id.currency_id currencyVocuher = request.env['res.currency'].browse(currency_id) # Create Line Voucher line_cr_ids = [] amount = round(float(amountPayments), decimal_precision) for line in move_line: amount_residual = line.amount_residual if (company_currency.id != currencyVocuher.id): amount_residual = round((amount_residual * (currencyVocuher.rate / company_currency.rate)), decimal_precision) line_cr_ids.append([0, False, { 'date_due': line.date_maturity, 'account_id': line.account_id.id, 'date_original': line.move_id.date, 'move_line_id': line.id, 'amount_original': abs(line.credit or line.debit or 0.0), 'amount_unreconciled': abs(line.amount_residual), 'amount': min(abs(amount), abs(amount_residual)), 'reconcile': True if abs(amount_residual) == min(abs(amount), abs(amount_residual)) else False, 'currency_id': currency_id }]) amount -= min(abs(amount), amount_residual) values = { 'reference': invoice.number, 'type': 'receipt', 'journal_id': journal_id.id, 'company_id': company_id, 'pre_line': True, 'amount': round(float(amountPayments), decimal_precision), 'period_id': period.id, 'date': date_server, 'partner_id': customerId.id, 'account_id': journal_id.default_credit_account_id.id, 'currency_id': currency_id, 'line_cr_ids': line_cr_ids, 'payment_rate_currency_id': currency_id } account_voucher = request.env['account.voucher'].create(values) account_voucher.action_move_line_create() return account_voucher ''' close invoice ''' def close_invoice(self, invoiceid): invoice = request.env['account.invoice'].search([('id', '=', invoiceid)]) if invoice.residual <= 0: # invoice.write({ # 'state': 'paid' # }) invoice.confirm_paid() return invoice ''' Create bank Statement ''' def create_bank_statement(self, date_server, user_id, account_voucher): # Get bank Statamente bank_statement = request.env['account.bank.statement'].search([('journal_id', '=', account_voucher.journal_id.id), ('date', '=', date_server)]) # Create line bank bank_statement_line = [[0, False, { 'name': account_voucher.reference, 'partner_id': account_voucher.partner_id.id, 'amount': account_voucher.amount, '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': 'NP' }]] bank = { 'journal_id': account_voucher.journal_id.id, 'period_id': account_voucher.period_id.id, 'date': date_server, 'user_id': user_id, 'state': 'open' if account_voucher.journal_id.type == 'cash' else 'draft', 'line_ids': bank_statement_line } if bank_statement: if len(bank_statement) == 1: bank_statement.write(bank) else: bank_statement[len(bank_statement) -1].write(bank) else: bank_statement = bank_statement.create(bank) return bank_statement ''' Payment process ''' @http.route('/eiru_payments/payment_process', type='json', auth='user', methods=['POST'], cors='*') def payment_process(self, **kw): self.make_info_log('Processing payments...') # Get Date Server date_server = datetime.now().strftime(DATE_FORMAT) #Get Periodo period = self.get_period(date_server) self.make_info_log('[OK] Getting period') # Get invoice invoice = self.get_invoice(kw.get('invoiceId')) self.make_info_log('[OK] Getting invoice') # Get User - company user_id = request.env.user.id self.make_info_log('[OK] Getting user') # Get Company company_id = request.env.user.company_id.id self.make_info_log('[OK] Getting Company') # create voucher voucher = self.create_voucher(period, invoice, company_id, kw.get('amountPayments', 0), date_server, kw.get('journalId'), kw.get('moveLines'), kw.get('customerId')) self.make_info_log('[OK] creating voucher...') # close invoice close_invoice = self.close_invoice(kw.get('invoiceId')) self.make_info_log('[OK] closing invoice...') # Create bank statement bank_statement = self.create_bank_statement(date_server, user_id, voucher) self.make_info_log('[OK] creating bank statement') return { 'process': True }