main.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. # -*- coding: utf-8 -*-
  2. from openerp import http
  3. from openerp.http import request
  4. from werkzeug.wrappers import Response
  5. from werkzeug.datastructures import Headers
  6. from datetime import datetime
  7. from dateutil.relativedelta import relativedelta as rd
  8. from dateutil.parser import parse
  9. from pytz import timezone
  10. from gzip import GzipFile
  11. from StringIO import StringIO as IO
  12. import simplejson as json
  13. import gzip
  14. import logging
  15. LOGGER = logging.getLogger(__name__)
  16. DATE_FORMAT = '%Y-%m-%d'
  17. DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
  18. GZIP_COMPRESSION_LEVEL = 9
  19. '''
  20. ___ ___ __ __ __ ___ __ __ ___ __ ___ __ __ __ __ __
  21. |__| | | |__) / ` / \ |\ | | |__) / \ | | |__ |__) |__ / \ |__) |__) / \ /__`
  22. | | | | | \__, \__/ | \| | | \ \__/ |___ |___ |___ | \ | \__/ | \ | \__/ .__/
  23. # Resource paths
  24. - /init: return json response gzip compressed contains values for sale operation
  25. - /create_product: create product on the fly POS and return it
  26. - /create_customer: create customer on the fly and return it
  27. - /process_sale: processing sale and return true if completed
  28. '''
  29. class PosSales(http.Controller):
  30. '''
  31. Get timezone
  32. '''
  33. def get_timezone(self):
  34. return timezone(request.context['tz'])
  35. '''
  36. Get server date
  37. '''
  38. def get_server_datetime(self):
  39. return datetime.now(self.get_timezone()).strftime(DATETIME_FORMAT)
  40. '''
  41. Get current user information
  42. '''
  43. def get_user(self):
  44. user = request.env.user
  45. return {
  46. 'id': user.id,
  47. 'name': user.name,
  48. 'displayName': user.display_name,
  49. 'currency': {
  50. 'id': user.company_id.currency_id.id,
  51. 'name': user.company_id.currency_id.name,
  52. 'displayName': user.company_id.currency_id.display_name,
  53. 'symbol': user.company_id.currency_id.symbol
  54. },
  55. 'company': {
  56. 'id': user.company_id.id,
  57. 'name': user.company_id.name,
  58. 'displayName': user.company_id.display_name,
  59. 'phone': user.company_id.phone or None,
  60. 'city': user.company_id.city or None,
  61. 'website': user.company_id.website,
  62. 'state': {
  63. 'id': user.company_id.state_id.id,
  64. 'name': user.company_id.state_id.name,
  65. 'displayName': user.company_id.state_id.display_name
  66. }
  67. }
  68. }
  69. '''
  70. Get currencies
  71. '''
  72. def get_currencies(self):
  73. return [{
  74. 'id': currency.id,
  75. 'name': currency.name,
  76. 'displayName': currency.display_name,
  77. 'base': currency.base,
  78. 'accuracy': currency.accuracy,
  79. 'rateSilent': currency.rate_silent,
  80. 'rounding': currency.rounding,
  81. 'symbol': currency.symbol,
  82. 'position': currency.position,
  83. 'decimalSeparator': currency.decimal_separator,
  84. 'decimalPlaces': currency.decimal_places,
  85. 'thousandsSeparator': currency.thousands_separator
  86. } for currency in request.env['res.currency'].search([('active', '=', True)])]
  87. '''
  88. Get all active journals
  89. '''
  90. def get_journals(self):
  91. return [{
  92. 'id': journal.id,
  93. 'name': journal.name,
  94. 'displayName': journal.display_name,
  95. 'code': journal.code,
  96. 'cashControl': journal.cash_control,
  97. 'type': journal.type,
  98. 'currency': {
  99. 'id': journal.currency.id,
  100. 'name': journal.currency.name,
  101. 'displayName': journal.currency.display_name
  102. },
  103. 'defaultCreditAccount': {
  104. 'id': journal.default_credit_account_id.id,
  105. 'name': journal.default_credit_account_id.name,
  106. 'displayName': journal.default_credit_account_id.display_name,
  107. 'code': journal.default_credit_account_id.code,
  108. 'exchangeRate': journal.default_credit_account_id.exchange_rate,
  109. 'foreignBalance': journal.default_credit_account_id.foreign_balance,
  110. 'reconcile': journal.default_credit_account_id.reconcile,
  111. 'debit': journal.default_credit_account_id.debit,
  112. 'credit': journal.default_credit_account_id.credit,
  113. 'currencyMode': journal.default_credit_account_id.currency_mode,
  114. 'companyCurrency': {
  115. 'id': journal.default_credit_account_id.company_currency_id.id,
  116. 'name': journal.default_credit_account_id.company_currency_id.name,
  117. 'displayName': journal.default_credit_account_id.company_currency_id.display_name,
  118. },
  119. 'currency': {
  120. 'id': journal.default_credit_account_id.currency_id.id,
  121. 'name': journal.default_credit_account_id.currency_id.name,
  122. 'displayName': journal.default_credit_account_id.currency_id.display_name
  123. },
  124. }
  125. } for journal in request.env['account.journal'].search([('type', 'in', ['bank', 'cash']), ('default_credit_account_id.currency_id', '=', False), ('active', '=', True)], order='id')]
  126. '''
  127. Get all active customers
  128. '''
  129. def get_customers(self):
  130. return [{
  131. 'id': customer.id,
  132. 'name': customer.name,
  133. 'displayName': customer.display_name,
  134. 'imageMedium': customer.image_medium,
  135. 'ruc': customer.ruc or None,
  136. 'phone': customer.phone or None,
  137. 'mobile': customer.mobile or None,
  138. 'email': customer.email or None
  139. } for customer in request.env['res.partner'].search([('customer', '=', True), ('active', '=', True)])]
  140. '''
  141. Get all saleable and active products
  142. '''
  143. def get_products(self):
  144. return [{
  145. 'id': product.id,
  146. 'name': product.name,
  147. 'displayName': product.display_name,
  148. 'ean13': product.ean13,
  149. 'defaultCode': product.default_code,
  150. 'imageMedium': product.image_medium,
  151. 'listPrice': product.list_price,
  152. 'variantCount': product.product_variant_count,
  153. 'quantity': 1,
  154. 'price': product.list_price,
  155. 'minimumPrice': product.minimum_price,
  156. 'maximumPrice': product.maximum_price,
  157. 'discount': 0,
  158. 'variants': [{
  159. 'id': variant.id,
  160. 'name': variant.name,
  161. 'displayName': variant.display_name,
  162. 'ean13': variant.ean13,
  163. 'defaultCode': product.default_code,
  164. 'imageMedium': variant.image_medium,
  165. 'listPrice': variant.list_price,
  166. 'quantity': 1,
  167. 'price': variant.list_price,
  168. 'minimumPrice': product.minimum_price,
  169. 'maximumPrice': product.maximum_price,
  170. 'discount': 0,
  171. } for variant in product.product_variant_ids if variant.active]
  172. } for product in request.env['product.template'].search([('sale_ok', '=', True), ('list_price', '>', 0), ('active', '=', True)])]
  173. '''
  174. Get all active payment terms
  175. '''
  176. def get_payment_terms(self):
  177. return [{
  178. 'id': payment_term.id,
  179. 'name': payment_term.name,
  180. 'displayName': payment_term.display_name,
  181. 'lines': [{
  182. 'id': line.id,
  183. 'days': line.days,
  184. 'days2': line.days2,
  185. 'value': line.value,
  186. 'valueAmount': line.value_amount
  187. } for line in payment_term.line_ids]
  188. } for payment_term in request.env['account.payment.term'].search([('active', '=', True)])]
  189. '''
  190. Make JSON response
  191. '''
  192. def make_json_response(self, data=None, status=200):
  193. return Response(json.dumps(data), status=status, content_type='application/json')
  194. '''
  195. Make GZIP to JSON response
  196. '''
  197. def make_gzip_response(self, data=None, status=200):
  198. gzip_buffer = IO()
  199. with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file:
  200. gzip_file.write(json.dumps(data))
  201. contents = gzip_buffer.getvalue()
  202. gzip_buffer.close()
  203. headers = Headers()
  204. headers.add('Content-Encoding', 'gzip')
  205. headers.add('Vary', 'Accept-Encoding')
  206. headers.add('Content-Length', len(contents))
  207. return Response(contents, status=status, headers=headers, content_type='application/json')
  208. '''
  209. '''
  210. def make_info_log(self, log):
  211. LOGGER.info(log)
  212. '''
  213. New purchase resource route
  214. '''
  215. @http.route('/eiru_sales/init', auth='user', methods=['GET'], cors='*')
  216. def init_sale(self, **kw):
  217. self.make_info_log('Sending JSON response')
  218. return self.make_gzip_response({
  219. 'date': self.get_server_datetime(),
  220. 'user': self.get_user(),
  221. 'currencies': self.get_currencies(),
  222. 'journals': self.get_journals(),
  223. 'customers': self.get_customers(),
  224. 'products': self.get_products(),
  225. 'paymentTerms': self.get_payment_terms()
  226. })
  227. '''
  228. Create customer and return data
  229. '''
  230. @http.route('/eiru_sales/create_customer', type='json', auth='user', methods=['POST'], cors='*')
  231. def create_customer(self, **kw):
  232. self.make_info_log('Creating customer')
  233. customer = request.env['res.partner'].create({
  234. 'name': kw.get('name'),
  235. 'ruc': kw.get('ruc'),
  236. 'mobile': kw.get('mobile'),
  237. 'customer': True
  238. })
  239. return {
  240. 'id': customer.id,
  241. 'name': customer.name,
  242. 'displayName': customer.display_name,
  243. 'imageMedium': customer.image_medium,
  244. 'ruc': customer.ruc or None,
  245. 'phone': customer.phone or None,
  246. 'mobile': customer.mobile or None,
  247. 'email': customer.email or None
  248. }
  249. '''
  250. Create product and return data
  251. '''
  252. @http.route('/eiru_sales/create_product', type='json', auth='user', methods=['POST'], cors='*')
  253. def create_product(self, **kw):
  254. self.make_info_log('Creating customer')
  255. product = request.env['product.template'].create({
  256. 'name': kw.get('name'),
  257. 'list_price': float(kw.get('price')),
  258. 'ean13': kw.get('ean13')
  259. })
  260. return {
  261. 'id': product.id,
  262. 'name': product.name,
  263. 'displayName': product.display_name,
  264. 'ean13': product.ean13,
  265. 'imageMedium': product.image_medium,
  266. 'listPrice': product.list_price,
  267. 'variantCount': product.product_variant_count,
  268. 'quantity': 1,
  269. 'price': product.list_price,
  270. 'discount': 0,
  271. 'variants': [{
  272. 'id': variant.id,
  273. 'name': variant.name,
  274. 'displayName': variant.display_name,
  275. 'ean13': variant.ean13,
  276. 'imageMedium': variant.image_medium,
  277. 'listPrice': variant.list_price,
  278. 'quantity': 1,
  279. 'price': variant.list_price,
  280. 'discount': 0,
  281. } for variant in product.product_variant_ids if variant.active]
  282. }
  283. '''
  284. Get currency from journal
  285. '''
  286. def get_currency(self, journal_id):
  287. journal = request.env['account.journal'].browse(journal_id)
  288. return journal.default_credit_account_id.currency_id.id or journal.default_credit_account_id.company_currency_id.id
  289. '''
  290. Check currency in pricelist and get it
  291. '''
  292. def get_pricelist(self, currency_id):
  293. pricelist = request.env['product.pricelist'].search([('active', '=', True), ('type', '=', 'sale')])
  294. if not True in pricelist.mapped(lambda p: p.currency_id.id == currency_id):
  295. pricelist = pricelist[0].copy()
  296. pricelist.write({
  297. 'currency_id': currency_id
  298. })
  299. else:
  300. pricelist = pricelist.filtered(lambda p: p.currency_id.id == currency_id)
  301. return pricelist
  302. '''
  303. Create sale order from cart items values
  304. '''
  305. def create_sale_from_cart(self, partner_id, cart_items, date_confirm, currency_id, pricelist_id, payment_term_id=None):
  306. return request.env['sale.order'].create({
  307. 'partner_id': partner_id,
  308. 'order_line': [[0, False, {
  309. 'product_id': int(line.get('id')),
  310. 'product_uom_qty': float(line.get('quantity')),
  311. 'price_unit': float(line.get('price'))
  312. }] for line in cart_items],
  313. 'picking_policy': 'direct',
  314. 'date_confirm': date_confirm,
  315. 'currency_id': currency_id,
  316. 'pricelist_id': pricelist_id,
  317. 'payment_term': payment_term_id,
  318. 'state': 'draft',
  319. })
  320. '''
  321. Confirm sale order
  322. '''
  323. def confirm_sale_order(self, sale_order_id):
  324. sale_order = request.env['sale.order'].browse(sale_order_id)
  325. sale_order.write({
  326. 'state': 'manual'
  327. })
  328. return sale_order.action_button_confirm()
  329. '''
  330. Create invoice from sale order
  331. '''
  332. def create_invoice(self, sale_order_id, currency_id, date_today):
  333. sale_order = request.env['sale.order'].browse(sale_order_id)
  334. invoice_id = sale_order.action_invoice_create()
  335. invoice = request.env['account.invoice'].browse(invoice_id)
  336. for picking in sale_order.picking_ids:
  337. picking.force_assign()
  338. picking.action_done()
  339. date_due = parse(date_today) + rd(days=max(invoice.payment_term.line_ids.mapped(lambda x: x.days + x.days2)))
  340. invoice.write({
  341. 'currency_id': currency_id,
  342. 'date_invoice': date_today,
  343. 'date_due': date_due.strftime(DATE_FORMAT),
  344. 'state': 'open'
  345. })
  346. return invoice
  347. '''
  348. Create move lines
  349. '''
  350. def create_invoice_move_lines(self, invoice_id, paid_amount, date_today):
  351. invoice = request.env['account.invoice'].browse(invoice_id)
  352. invoice_move_lines = invoice._get_analytic_lines()
  353. decimal_precision = request.env['decimal.precision'].precision_get('Account')
  354. compute_taxes = request.env['account.invoice.tax'].compute(invoice)
  355. invoice.check_tax_lines(compute_taxes)
  356. invoice._recompute_tax_amount()
  357. invoice_move_lines += request.env['account.invoice.tax'].move_line_get(invoice.id)
  358. total, total_currency, invoice_move_lines = invoice.compute_invoice_totals(invoice.company_id.currency_id, invoice.reference, invoice_move_lines)
  359. paid_percentage = paid_amount / round(total, decimal_precision)
  360. distributed_percentage = -(paid_percentage / len(invoice.payment_term.line_ids))
  361. payment_lines = []
  362. for line in invoice.payment_term.line_ids:
  363. date_due = (parse(date_today) + rd(days=line.days + line.days2)).strftime(DATE_FORMAT)
  364. if paid_percentage and paid_percentage < 1.0:
  365. payment_lines.append([date_today, paid_percentage])
  366. paid_percentage = paid_amount = 0
  367. if date_due == date_today and line.value_amount:
  368. distributed_percentage = -((payment_lines[0][1] - line.value_amount) / (len(invoice.payment_term.line_ids) - 1))
  369. continue
  370. if line.value != 'balance':
  371. payment_lines.append([date_due, line.value_amount + distributed_percentage])
  372. continue
  373. payment_lines.append([date_due, line.value_amount])
  374. for payment_line in payment_lines:
  375. current_price = round(total * payment_line[1], decimal_precision)
  376. if current_price < 0.0:
  377. continue
  378. paid_amount += current_price
  379. invoice_move_lines.append({
  380. 'type': 'dest',
  381. 'name': '/',
  382. 'price': current_price if payment_line[1] else round(total - paid_amount, decimal_precision) or total,
  383. 'account_id': invoice.account_id.id,
  384. 'date_maturity': payment_line[0],
  385. '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,
  386. 'currency_id': invoice.currency_id != invoice.company_id.currency_id and invoice.currency_id.id,
  387. 'ref': invoice.reference
  388. })
  389. payment_lines = []
  390. return invoice_move_lines
  391. '''
  392. Create account move
  393. '''
  394. def create_account_move(self, invoice_id, invoice_move_lines):
  395. invoice = request.env['account.invoice'].browse(invoice_id)
  396. accounting_partner = request.env['res.partner']._find_accounting_partner(invoice.partner_id)
  397. move_line_values = [(0, 0, invoice.line_get_convert(line, accounting_partner.id, invoice.date_invoice)) for line in invoice_move_lines]
  398. move_line_values = invoice.group_lines(invoice_move_lines, move_line_values)
  399. move_line_values = invoice.finalize_invoice_move_lines(move_line_values)
  400. ctx = dict(request.context, lang=invoice.partner_id.lang, company_id=invoice.company_id.id)
  401. period = invoice.period_id
  402. if not period:
  403. period = period.with_context(ctx).find(invoice.date_invoice)[:1]
  404. if period:
  405. for line in move_line_values:
  406. line[2]['period_id'] = period.id
  407. ctx['invoice'] = invoice
  408. ctx_nolang = ctx.copy()
  409. ctx_nolang.pop('lang', None)
  410. account_move = request.env['account.move'].with_context(ctx_nolang).create({
  411. 'ref': invoice.reference or invoice.name,
  412. 'line_id': move_line_values,
  413. 'journal_id': invoice.journal_id.id,
  414. 'date': invoice.date_invoice,
  415. 'narration': invoice.comment,
  416. 'company_id': invoice.company_id.id,
  417. 'period_id': period.id
  418. })
  419. invoice.with_context(ctx).write({
  420. 'move_id': account_move.id,
  421. 'period_id': account_move.period_id.id,
  422. 'move_name': account_move.name,
  423. })
  424. account_move.post()
  425. return account_move
  426. '''
  427. Number to invoice
  428. '''
  429. def number_invoice(self, invoice_id):
  430. request.env['account.invoice'].browse(invoice_id).action_number()
  431. '''
  432. Create voucher
  433. '''
  434. def create_account_voucher(self, account_move_id, journal_id, currency_id, paid_amount):
  435. account_move = request.env['account.move'].browse(account_move_id)
  436. account_journal = request.env['account.journal'].browse(journal_id)
  437. account_voucher = request.env['account.voucher'].create({
  438. 'reference': account_move.name,
  439. 'type': 'receipt',
  440. 'journal_id': account_journal.id,
  441. 'company_id': account_move.company_id.id,
  442. 'pre_line': True,
  443. 'amount': paid_amount,
  444. 'period_id': account_move.period_id.id,
  445. 'date': account_move.date,
  446. 'partner_id': account_move.partner_id.id,
  447. 'account_id': account_journal.default_credit_account_id.id,
  448. 'currency_id': currency_id,
  449. 'line_cr_ids': [[0, False, {
  450. 'date_due': l.date_maturity,
  451. 'account_id': l.account_id.id,
  452. 'date_original': l.invoice.date_invoice,
  453. 'move_line_id': l.id,
  454. 'amount_original': abs(l.credit or l.debit or 0.0),
  455. 'amount_unreconciled': abs(l.amount_residual),
  456. 'amount': abs(l.debit) if account_move.date == l.date_maturity else 0.0,
  457. 'reconcile': account_move.date == l.date_maturity,
  458. 'currency_id': currency_id
  459. }] for l in account_move.line_id]
  460. })
  461. account_voucher.action_move_line_create()
  462. return account_voucher
  463. '''
  464. Close a invoice
  465. '''
  466. def close_invoice(self, invoice_id):
  467. invoice = request.env['account.invoice'].browse(invoice_id)
  468. if invoice.residual == 0:
  469. invoice.write({
  470. 'state': 'paid'
  471. })
  472. '''
  473. Create account bank statement lines
  474. '''
  475. def create_bank_statement_lines(self, account_voucher_id, reference=None):
  476. account_voucher = request.env['account.voucher'].browse(account_voucher_id)
  477. return [[0, False, {
  478. 'name': account_voucher.reference,
  479. 'amount': account_voucher.amount,
  480. 'partner_id': account_voucher.partner_id.id,
  481. 'voucher_id': account_voucher.id,
  482. 'journal_id': account_voucher.journal_id.id,
  483. 'account_id': account_voucher.account_id.id,
  484. 'journal_entry_id': account_voucher.move_id.id,
  485. 'currency_id': account_voucher.currency_id.id,
  486. 'ref': 'POS/' + (reference or '')
  487. }]]
  488. '''
  489. Create account bank statement
  490. '''
  491. def create_bank_statement(self, account_voucher_id, account_bank_statement_lines, date_today):
  492. account_voucher = request.env['account.voucher'].browse(account_voucher_id)
  493. account_bank_statement = request.env['account.bank.statement'].search([('journal_id', '=', account_voucher.journal_id.id), ('date', '=', date_today)])
  494. account_bank_statement_values = {
  495. 'date': date_today,
  496. 'user_id': request.env.user.id,
  497. 'journal_id': account_voucher.journal_id.id,
  498. 'period_id': account_voucher.period_id.id,
  499. 'line_ids': account_bank_statement_lines,
  500. 'state': 'open' if account_voucher.journal_id.type == 'cash' else 'draft'
  501. }
  502. if account_bank_statement:
  503. size = len(account_bank_statement)
  504. if size == 1:
  505. account_bank_statement.write(account_bank_statement_values)
  506. else:
  507. account_bank_statement[size - 1].write(account_bank_statement_values)
  508. else:
  509. account_bank_statement.create(account_bank_statement_values)
  510. return account_bank_statement
  511. '''
  512. Process sale
  513. '''
  514. @http.route('/eiru_sales/process_sale', type='json', auth='user', methods=['POST'], cors='*')
  515. def process_sale(self, **kw):
  516. self.make_info_log('Processing sale...')
  517. # Get date
  518. date_now = datetime.now(self.get_timezone()).strftime(DATE_FORMAT)
  519. self.make_info_log('[OK] Getting date')
  520. # Get currency
  521. currency_id = self.get_currency(kw.get('journalId'))
  522. self.make_info_log('[OK] Getting journal')
  523. # Get Pricelist
  524. pricelist = self.get_pricelist(currency_id)
  525. self.make_info_log('[OK] Getting product pricelist')
  526. # Create sale order
  527. sale_order = self.create_sale_from_cart(kw.get('customerId'), kw.get('items'), date_now, currency_id, pricelist.id, kw.get('paymentTermId'))
  528. self.make_info_log('[OK] Creating sale order')
  529. # Check if budget
  530. if kw.get('mode', 'sale') != 'sale':
  531. return {
  532. 'process': True
  533. }
  534. # Confirm sale
  535. self.confirm_sale_order(sale_order.id)
  536. self.make_info_log('[OK] Confirm sale order')
  537. # Create invoice
  538. invoice = self.create_invoice(sale_order.id, currency_id, date_now)
  539. self.make_info_log('[OK] Creating invoice')
  540. # Create invoice move lines
  541. invoice_move_lines = self.create_invoice_move_lines(invoice.id, float(kw.get('payment')), date_now)
  542. self.make_info_log('[OK] Creating invoice move lines')
  543. # Create account move
  544. account_move = self.create_account_move(invoice.id, invoice_move_lines)
  545. self.make_info_log('[OK] Creating account move')
  546. # Number invoice
  547. self.number_invoice(invoice.id)
  548. self.make_info_log('[OK] Number invoice')
  549. # Create account voucher
  550. account_voucher = self.create_account_voucher(account_move.id, kw.get('journalId'), currency_id, float(kw.get('payment')))
  551. self.make_info_log('[OK] Creating account voucher')
  552. # Close invoice
  553. self.close_invoice(invoice.id)
  554. self.make_info_log('[OK] Closing invoice')
  555. # Create account bank statement lines
  556. account_bank_statement_lines = self.create_bank_statement_lines(account_voucher.id)
  557. self.make_info_log('[OK] Creating account bank statement lines')
  558. # Create bank statement
  559. self.create_bank_statement(account_voucher.id, account_bank_statement_lines, date_now)
  560. self.make_info_log('[OK] Creating account bank statement')
  561. return {
  562. 'process': True,
  563. 'name': sale_order.display_name,
  564. 'date': self.get_server_datetime()
  565. }