main.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  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 gzip import GzipFile
  8. from StringIO import StringIO as IO
  9. import simplejson as json
  10. import gzip
  11. import logging
  12. LOGGER = logging.getLogger(__name__)
  13. DATE_FORMAT = '%Y-%m-%d'
  14. GZIP_COMPRESSION_LEVEL = 9
  15. class PaymentsSales(http.Controller):
  16. '''
  17. Get server date
  18. '''
  19. def get_server_date(self):
  20. return datetime.now().strftime(DATE_FORMAT)
  21. '''
  22. Get partner customer
  23. '''
  24. def get_user(self):
  25. user = request.env.user
  26. return {
  27. 'id': user.id,
  28. 'name': user.name,
  29. 'displayName': user.display_name,
  30. 'company': {
  31. 'id': user.company_id.id,
  32. 'name': user.company_id.name
  33. },
  34. 'currency': {
  35. 'id': user.company_id.currency_id.id,
  36. 'name': user.company_id.currency_id.name,
  37. 'displayName': user.company_id.currency_id.display_name,
  38. 'symbol': user.company_id.currency_id.symbol,
  39. 'rateSilent': user.company_id.currency_id.rate_silent,
  40. 'thousandsSeparator': user.company_id.currency_id.thousands_separator,
  41. 'decimalSeparator': user.company_id.currency_id.decimal_separator,
  42. 'decimalPlaces': user.company_id.currency_id.decimal_places,
  43. 'position': user.company_id.currency_id.position
  44. }
  45. }
  46. '''
  47. Get Supplier
  48. '''
  49. def get_supplier(self):
  50. decimal_precision = request.env['decimal.precision'].precision_get('Account')
  51. return [{
  52. 'id': supplier.id,
  53. 'name': supplier.name,
  54. 'displayName': supplier.display_name,
  55. 'ruc': supplier.ruc,
  56. 'imageMedium': supplier.image_medium,
  57. 'phone': supplier.phone,
  58. 'mobile': supplier.mobile,
  59. 'email':supplier.email,
  60. 'debit': supplier.debit,
  61. 'invoices': [{
  62. 'id': invoice.id,
  63. 'number': invoice.number ,
  64. 'dateInvoice': invoice.date_invoice,
  65. 'amountTotal': invoice.amount_total,
  66. 'residual': invoice.residual,
  67. 'currencyInvoice': {
  68. 'id': invoice.currency_id.id,
  69. 'displayName': invoice.currency_id.display_name,
  70. 'symbol': invoice.currency_id.symbol,
  71. 'rateSilent': invoice.currency_id.rate_silent,
  72. 'rate': invoice.currency_id.rate,
  73. 'thousandsSeparator': invoice.currency_id.thousands_separator,
  74. 'decimalSeparator': invoice.currency_id.decimal_separator,
  75. 'decimalPlaces': invoice.currency_id.decimal_places,
  76. 'position': invoice.currency_id.position
  77. },
  78. 'moveLines' :[{
  79. 'id': line.id,
  80. 'invoiceNumber': invoice.number,
  81. 'amountResidual': line.amount_residual,
  82. 'credit': line.credit,
  83. 'debit': line.debit,
  84. 'dateMaturity': line.date_maturity,
  85. 'amountCurrency': (line.amount_currency * -1) if (line.amount_currency != 0) else line.credit,
  86. 'amountResidualCurrency': line.amount_residual_currency,
  87. 'currencyInvoice': {
  88. 'id': invoice.currency_id.id,
  89. 'displayName': invoice.currency_id.display_name,
  90. 'symbol': invoice.currency_id.symbol,
  91. 'rateSilent': invoice.currency_id.rate_silent,
  92. 'rate': invoice.currency_id.rate,
  93. 'thousandsSeparator': invoice.currency_id.thousands_separator,
  94. 'decimalSeparator': invoice.currency_id.decimal_separator,
  95. 'decimalPlaces': invoice.currency_id.decimal_places,
  96. 'position': invoice.currency_id.position
  97. },
  98. 'currencyAmount': [{
  99. 'id': currency.id,
  100. 'displayName': currency.display_name,
  101. 'symbol': currency.symbol,
  102. 'rateSilent': currency.rate_silent,
  103. 'rate': currency.rate,
  104. 'thousandsSeparator': currency.thousands_separator,
  105. 'decimalSeparator': currency.decimal_separator,
  106. 'decimalPlaces': currency.decimal_places,
  107. 'position': currency.position,
  108. 'base': currency.base,
  109. 'accuracy': currency.accuracy,
  110. 'rounding': currency.rounding,
  111. 'amountCurencyResidual': round((line.amount_residual_currency * (currency.rate / invoice.currency_id.rate)), decimal_precision)
  112. } for currency in request.env['res.currency'].search([('active', '=', True)])]
  113. } for line in invoice.move_id.line_id if (line.amount_residual > 0 and line.state != "draft" and line.debit <= 0)],
  114. } for invoice in supplier.invoice_ids if (invoice.state == 'open') ],
  115. } for supplier in request.env['res.partner'].search([('active', '=', True), ('supplier', '=', True), ('debit', '<', 0) ])]
  116. '''
  117. Get Journal
  118. '''
  119. def get_journals(self):
  120. domain =[('active', '=', True),('type', 'in',['bank', 'cash'])]
  121. paymentsJournals = []
  122. for journal in request.env['account.journal'].search(domain, order="id"):
  123. if not (journal.store_ids >= request.env.user.store_ids):
  124. continue
  125. paymentsJournals.append({
  126. 'id': journal.id,
  127. 'name': journal.name,
  128. 'displayName': journal.display_name,
  129. 'code': journal.code,
  130. 'cashControl': journal.cash_control,
  131. 'type': journal.type,
  132. 'currency': {
  133. 'id': journal.currency.id,
  134. 'name': journal.currency.name,
  135. 'displayName': journal.currency.display_name,
  136. 'symbol': journal.currency.symbol,
  137. 'rateSilent': journal.currency.rate_silent,
  138. 'thousandsSeparator':journal.currency.thousands_separator,
  139. 'decimalSeparator': journal.currency.decimal_separator,
  140. 'decimalPlaces': journal.currency.decimal_places,
  141. 'position': journal.currency.position
  142. },
  143. 'defaultCreditAccount':{
  144. 'id': journal.default_credit_account_id.id,
  145. 'name': journal.default_credit_account_id.name,
  146. 'displayName': journal.default_credit_account_id.display_name,
  147. 'code': journal.default_credit_account_id.code,
  148. 'exchangeRate': journal.default_credit_account_id.exchange_rate,
  149. 'foreignBalance': journal.default_credit_account_id.foreign_balance,
  150. 'reconcile': journal.default_credit_account_id.reconcile,
  151. 'debit': journal.default_credit_account_id.debit,
  152. 'credit': journal.default_credit_account_id.credit,
  153. 'currencyMode': journal.default_credit_account_id.currency_mode,
  154. 'companyCurrency':{
  155. 'id': journal.default_credit_account_id.company_currency_id.id,
  156. 'name': journal.default_credit_account_id.company_currency_id.name,
  157. 'displayName': journal.default_credit_account_id.company_currency_id.display_name,
  158. 'symbol': journal.default_credit_account_id.company_currency_id.symbol,
  159. 'rateSilent': journal.default_credit_account_id.company_currency_id.rate_silent
  160. },
  161. 'currency':{
  162. 'id': journal.default_credit_account_id.currency_id.id,
  163. 'name': journal.default_credit_account_id.currency_id.name,
  164. 'displayName': journal.default_credit_account_id.currency_id.display_name,
  165. 'symbol': journal.default_credit_account_id.currency_id.symbol,
  166. 'rateSilent': journal.default_credit_account_id.currency_id.rate_silent
  167. },
  168. }
  169. })
  170. return paymentsJournals
  171. '''
  172. Get Currency
  173. '''
  174. def get_currency(self):
  175. return [{
  176. 'id': currency.id,
  177. 'name': currency.name,
  178. 'displayName': currency.display_name,
  179. 'base': currency.base,
  180. 'accuracy': currency.accuracy,
  181. 'rateSilent': currency.rate_silent,
  182. 'rounding': currency.rounding,
  183. 'symbol': currency.symbol,
  184. 'position': currency.position,
  185. 'thousandsSeparator': currency.thousands_separator,
  186. 'decimalSeparator': currency.decimal_separator,
  187. 'decimalPlaces': currency.decimal_places
  188. } for currency in request.env['res.currency'].search([('active', '=', True)])]
  189. '''
  190. Get bank
  191. '''
  192. def get_bank(self):
  193. return [{
  194. 'id': bank.id,
  195. 'name': bank.name
  196. } for bank in request.env['res.bank'].search([('active', '=', True)])]
  197. '''
  198. Get Bank Payments Type
  199. '''
  200. def get_bank_payments_type(self):
  201. return [{
  202. 'id': bank_type.id,
  203. 'name': bank_type.name,
  204. 'code': bank_type.code,
  205. 'default_state': bank_type.default_state
  206. } for bank_type in request.env['res.bank.payments.type'].search([('is_payment', '=', True)])]
  207. '''
  208. Make JSON response
  209. '''
  210. def make_json_response(self, data=None, status=200):
  211. return Response(json.dumps(data), status=status, content_type='application/json')
  212. '''
  213. Make GZIP to JSON response
  214. '''
  215. def make_gzip_response(self, data=None, status=200):
  216. gzip_buffer = IO()
  217. with GzipFile(mode='wb', compresslevel=GZIP_COMPRESSION_LEVEL, fileobj=gzip_buffer) as gzip_file:
  218. gzip_file.write(json.dumps(data))
  219. contents = gzip_buffer.getvalue()
  220. gzip_buffer.close()
  221. headers = Headers()
  222. headers.add('Content-Encoding', 'gzip')
  223. headers.add('Vary', 'Accept-Encoding')
  224. headers.add('Content-Length', len(contents))
  225. return Response(contents, status=status, headers=headers, content_type='application/json')
  226. '''
  227. Logger Info
  228. '''
  229. def make_info_log(self, log):
  230. LOGGER.info(log)
  231. '''
  232. New Payments resource router
  233. '''
  234. @http.route('/eiru_payments_purchases/init', auth='user', methods=['GET'], cors='*')
  235. def init_payments(self, **kw):
  236. self.make_info_log('Sending JSON response')
  237. return self.make_gzip_response({
  238. 'date': self.get_server_date(),
  239. 'user': self.get_user(),
  240. 'supplier': self.get_supplier(),
  241. 'journals': self.get_journals(),
  242. 'currencies': self.get_currency(),
  243. 'bank':self.get_bank(),
  244. 'bankType': self.get_bank_payments_type()
  245. })
  246. '''
  247. ____ _ __ ____ __ _____ _ _ _____ ____ ____ ____ ___ ____ _____ ____ ____
  248. | _ \ / \\ \ / / \/ | ____| \ | |_ _/ ___| | _ \| _ \ / _ \ / ___| ____/ ___/ ___|
  249. | |_) / _ \\ V /| |\/| | _| | \| | | | \___ \ | |_) | |_) | | | | | | _| \___ \___ \
  250. | __/ ___ \| | | | | | |___| |\ | | | ___) | | __/| _ <| |_| | |___| |___ ___) |__) |
  251. |_| /_/ \_\_| |_| |_|_____|_| \_| |_| |____/ |_| |_| \_\\___/ \____|_____|____/____/
  252. '''
  253. '''
  254. Get the current period
  255. '''
  256. def get_period(self, date_server):
  257. return request.env['account.period'].search([('date_start','<=', date_server), ('date_stop', '>=', datetime.now().strftime(DATE_FORMAT))])
  258. '''
  259. Get Invoice
  260. '''
  261. def get_invoice(self, invoice_id):
  262. return request.env['account.invoice'].search([('id', '=', invoice_id)])
  263. '''
  264. Create Voucher
  265. '''
  266. def create_voucher(self, period, invoice, company_id, amountPayments, date_server, journalId, move_line_Ids, customerId):
  267. # Get Journal
  268. journal_id = request.env['account.journal'].browse(int(journalId))
  269. currency_id = journal_id.default_credit_account_id.currency_id.id or journal_id.default_credit_account_id.company_currency_id.id
  270. # Get Move Lines
  271. move_line = request.env['account.move.line'].browse(move_line_Ids).sorted(key=lambda r: r.id)
  272. # get customer
  273. customerId = request.env['res.partner'].browse(customerId)
  274. decimal_precision = request.env['decimal.precision'].precision_get('Account')
  275. # Create Line Voucher
  276. company_currency = request.env.user.company_id.currency_id
  277. currencyVocuher = request.env['res.currency'].browse(currency_id)
  278. line_dr_ids = []
  279. amount = round(float(amountPayments), decimal_precision)
  280. for line in move_line:
  281. amount_residual = line.amount_residual
  282. if (company_currency.id != currencyVocuher.id):
  283. amount_residual = round((amount_residual * ( currencyVocuher.rate / company_currency.rate)), decimal_precision)
  284. line_dr_ids.append([0, False, {
  285. 'date_due': line.date_maturity,
  286. 'account_id': line.account_id.id,
  287. 'date_original': line.move_id.date,
  288. 'move_line_id': line.id,
  289. 'amount_original': abs(line.credit or line.debit or 0.0),
  290. 'amount_unreconciled': abs(line.amount_residual),
  291. 'amount': min(abs(amount), abs(amount_residual)),
  292. 'reconcile': True if abs(amount_residual) == min(abs(amount), abs(amount_residual)) else False,
  293. 'currency_id': currency_id
  294. }])
  295. amount -= min(abs(amount), amount_residual)
  296. values = {
  297. 'reference': invoice.number,
  298. 'type': 'payment',
  299. 'journal_id': journal_id.id,
  300. 'company_id': company_id,
  301. 'pre_line': True,
  302. 'amount': round(float(amountPayments), decimal_precision),
  303. 'period_id': period.id,
  304. 'date': date_server,
  305. 'partner_id': customerId.id,
  306. 'account_id': journal_id.default_credit_account_id.id,
  307. 'currency_id': currency_id,
  308. 'line_dr_ids': line_dr_ids,
  309. 'payment_rate_currency_id': currency_id
  310. }
  311. account_voucher = request.env['account.voucher'].create(values)
  312. account_voucher.action_move_line_create()
  313. return account_voucher
  314. '''
  315. close invoice
  316. '''
  317. def close_invoice(self, invoiceid):
  318. invoice = request.env['account.invoice'].search([('id', '=', invoiceid)])
  319. if invoice.residual <= 0:
  320. invoice.confirm_paid()
  321. return invoice
  322. '''
  323. Create bank Statement
  324. '''
  325. def create_bank_statement(self, date_server, user_id, account_voucher):
  326. # Get bank Statamente
  327. bank_statement = request.env['account.bank.statement'].search([('journal_id', '=', account_voucher.journal_id.id), ('date', '=', date_server)])
  328. amount = account_voucher.amount
  329. if account_voucher.type == 'payment':
  330. amount = amount * -1
  331. # Create line bank
  332. bank_statement_line = [[0, False, {
  333. 'name': account_voucher.reference,
  334. 'partner_id': account_voucher.partner_id.id,
  335. 'amount': amount,
  336. 'voucher_id': account_voucher.id,
  337. 'journal_id': account_voucher.journal_id.id,
  338. 'account_id': account_voucher.account_id.id,
  339. 'journal_entry_id': account_voucher.move_id.id,
  340. 'currency_id': account_voucher.currency_id.id,
  341. 'ref': 'NP'
  342. }]]
  343. bank = {
  344. 'journal_id': account_voucher.journal_id.id,
  345. 'period_id': account_voucher.period_id.id,
  346. 'date': date_server,
  347. 'user_id': user_id,
  348. 'state': 'open' if account_voucher.journal_id.type == 'cash' else 'draft',
  349. 'line_ids': bank_statement_line
  350. }
  351. if bank_statement:
  352. if len(bank_statement) == 1:
  353. bank_statement.write(bank)
  354. else:
  355. bank_statement[len(bank_statement) -1].write(bank)
  356. else:
  357. bank_statement = bank_statement.create(bank)
  358. return bank_statement
  359. '''
  360. Payment process
  361. '''
  362. @http.route('/eiru_payments_purchases/purchases_process', type='json', auth='user', methods=['POST'], cors='*')
  363. def purchases_process(self, **kw):
  364. self.make_info_log('Processing payments purchases...')
  365. # Get Date Server
  366. date_server = datetime.now().strftime(DATE_FORMAT)
  367. #Get Periodo
  368. period = self.get_period(date_server)
  369. self.make_info_log('[OK] Getting period')
  370. # Get invoice
  371. invoice = self.get_invoice(kw.get('invoiceId'))
  372. self.make_info_log('[OK] Getting invoice')
  373. # Get User - company
  374. user_id = request.env.user.id
  375. self.make_info_log('[OK] Getting user')
  376. # Get Company
  377. company_id = request.env.user.company_id.id
  378. self.make_info_log('[OK] Getting Company')
  379. # create voucher
  380. voucher = self.create_voucher(period, invoice, company_id, kw.get('amountPayments', 0), date_server, kw.get('journalId'), kw.get('moveLinesId'), kw.get('supplierId'))
  381. self.make_info_log('[OK] creating voucher...')
  382. # close invoice
  383. close_invoice = self.close_invoice(kw.get('invoiceId'))
  384. self.make_info_log('[OK] closing invoice...')
  385. # Create bank statement
  386. bank_statement = self.create_bank_statement(date_server, user_id, voucher)
  387. self.make_info_log('[OK] creating bank statement')
  388. return {
  389. 'process': True
  390. }