main.py 18 KB

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