account_invoices.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. # -*- coding: utf-8 -*-
  2. from openerp import models, fields, tools, api
  3. from datetime import datetime
  4. from pytz import timezone
  5. import simplejson
  6. DATE_FORMAT = '%Y-%m-%d'
  7. class AccountInvoice(models.Model):
  8. _inherit = 'account.invoice'
  9. '''
  10. Get Move Line Customer
  11. '''
  12. def get_move_line_credit(self, invoice):
  13. decimal_precision = self.env['decimal.precision'].precision_get('Account')
  14. if (not invoice):
  15. return false
  16. return [{
  17. 'id': line.id,
  18. 'amountResidual': line.amount_residual,
  19. 'credit': line.credit,
  20. 'debit': line.debit,
  21. 'dateMaturity': line.date_maturity,
  22. 'invoice': invoice.id,
  23. 'amountCurrency': line.amount_currency if line.amount_currency > 0 else line.debit,
  24. 'amountResidualCurrency': line.amount_residual_currency,
  25. 'currencyAmount': [{
  26. 'id': currency.id,
  27. 'displayName': currency.display_name,
  28. 'symbol': currency.symbol,
  29. 'rateSilent': currency.rate_silent,
  30. 'rate': currency.rate,
  31. 'thousandsSeparator': currency.thousands_separator,
  32. 'decimalSeparator': currency.decimal_separator,
  33. 'decimalPlaces': currency.decimal_places,
  34. 'position': currency.position,
  35. 'base': currency.base,
  36. 'accuracy': currency.accuracy,
  37. 'rounding': currency.rounding,
  38. 'amountCurencyResidual': round((line.amount_residual_currency * (currency.rate_silent / invoice.currency_id.rate_silent)), decimal_precision)
  39. } for currency in self.env['res.currency'].search([('active', '=', True)])]
  40. } for line in invoice.move_id.line_id.sorted(key=lambda r: r.id) if (line.amount_residual > 0 and line.state != "draft" and line.credit <= 0)]
  41. '''
  42. Get Currency paymsntes
  43. '''
  44. @api.model
  45. def get_currency_payments_invoices(self):
  46. return [{
  47. 'id': currency.id,
  48. 'name': currency.name,
  49. 'symbol': currency.symbol,
  50. 'rate_silent': currency.rate_silent,
  51. 'base': currency.base,
  52. 'decimalSeparator': currency.decimal_separator,
  53. 'decimalPlaces': currency.decimal_places,
  54. 'thousandsSeparator': currency.thousands_separator,
  55. 'symbolPosition': currency.symbol_position,
  56. 'rate': currency.rate
  57. } for currency in self.env['res.currency'].search([('active','=', True)])]
  58. '''
  59. Get Move Line supplier
  60. '''
  61. def get_move_line_debit(self, invoice):
  62. decimal_precision = self.env['decimal.precision'].precision_get('Account')
  63. if (not invoice):
  64. return false
  65. return [{
  66. 'id': line.id,
  67. 'amountResidual': line.amount_residual,
  68. 'credit': line.credit,
  69. 'debit': line.debit,
  70. 'dateMaturity': line.date_maturity,
  71. 'invoice': invoice.id,
  72. 'amountCurrency': abs(line.amount_currency) if (abs(line.amount_currency) > 0) else line.credit,
  73. 'amountResidualCurrency': line.amount_residual_currency,
  74. 'currencyAmount': [{
  75. 'id': currency.id,
  76. 'displayName': currency.display_name,
  77. 'symbol': currency.symbol,
  78. 'rateSilent': currency.rate_silent,
  79. 'rate': currency.rate,
  80. 'thousandsSeparator': currency.thousands_separator,
  81. 'decimalSeparator': currency.decimal_separator,
  82. 'decimalPlaces': currency.decimal_places,
  83. 'position': currency.position,
  84. 'base': currency.base,
  85. 'accuracy': currency.accuracy,
  86. 'rounding': currency.rounding,
  87. 'amountCurencyResidual': round((line.amount_residual_currency * (currency.rate / invoice.currency_id.rate)), decimal_precision)
  88. } for currency in self.env['res.currency'].search([('active', '=', True)])]
  89. } for line in invoice.move_id.line_id.sorted(key=lambda r: r.id) if (line.amount_residual > 0 and line.state != "draft" and line.debit <= 0)]
  90. '''
  91. Get Move Line
  92. '''
  93. @api.model
  94. def get_moveline_invoice(self, id):
  95. accountInvoice = self.env['account.invoice'].browse(id)
  96. if (not accountInvoice):
  97. return False
  98. if (accountInvoice.type in ('out_invoice', 'in_refund')):
  99. return self.get_move_line_credit(accountInvoice)
  100. if (accountInvoice.type in ('out_refund', 'in_invoice')):
  101. return self.get_move_line_debit(accountInvoice)
  102. @api.model
  103. def get_bank_payments(self):
  104. resBankPayments = []
  105. for bankPayments in self.env['res.bank.payments'].search([('bank_payments_type_id.code', '!=', 'TJ')], order='id'):
  106. amountReceipt = 0
  107. amountPayment = 0
  108. amountBalance = 0
  109. amountCashed = 0
  110. amountRenegotiated = 0
  111. for line in bankPayments.payments_line:
  112. amountReceipt += line.type_operation in ('receipt') and line.amount or 0
  113. amountPayment += line.type_operation in ('payment') and line.amount or 0
  114. amountBalance += line.type_operation in ('balance') and line.amount or 0
  115. amountCashed += line.type_operation in ('cashed') and line.amount or 0
  116. amountRenegotiated += line.type_operation in ('renegotiated') and line.amount or 0
  117. resBankPayments.append({
  118. 'id': bankPayments.id,
  119. 'number': bankPayments.number,
  120. 'amountTotal': bankPayments.amount_total,
  121. 'dateMaturity': bankPayments.date_maturity,
  122. 'bankId': bankPayments.bank_id.id,
  123. 'bankPaymentsTypeId': bankPayments.bank_payments_type_id.id,
  124. 'numberCta': bankPayments.number_cta,
  125. 'nameHolder': bankPayments.name_holder,
  126. 'state': bankPayments.state,
  127. 'amountReceipt': amountReceipt,
  128. 'amountPayment': amountPayment,
  129. 'amountBalance': amountBalance,
  130. 'amountCashed': amountCashed,
  131. 'amountRenegotiated': amountRenegotiated,
  132. 'chequeTypeId': bankPayments.cheque_type_id.id
  133. });
  134. return resBankPayments
  135. '''
  136. Get User
  137. '''
  138. @api.model
  139. def get_user_login(self):
  140. return [{
  141. 'id': user.id,
  142. 'name': user.name
  143. } for user in self.env.user]
  144. '''
  145. get Statement
  146. '''
  147. @api.model
  148. def get_statement(self):
  149. BankStatement = []
  150. for statement in self.env['account.bank.statement'].search([('state','!=','confirm'),('user_id','=',self.env.user.id)]):
  151. if (statement.journal_id.type == 'cash' and statement.state =='draft'):
  152. continue
  153. BankStatement.append({
  154. 'id': statement.id,
  155. 'name': statement.name,
  156. 'journalID': statement.journal_id.id,
  157. 'userId': statement.user_id.id,
  158. 'date': statement.date,
  159. 'createDate': statement.create_date,
  160. 'periodId': statement.period_id.id,
  161. 'state': statement.state,
  162. 'journalType': statement.journal_id.type
  163. })
  164. return BankStatement
  165. '''
  166. Get All res_bank_payments_type.
  167. '''
  168. @api.model
  169. def get_bank_payment_type(self):
  170. self.env.cr.execute("SELECT id FROM res_bank_payments_type")
  171. return [{
  172. 'id': line.id,
  173. 'name': line.name,
  174. 'code': line.code,
  175. 'journal_ids': map(lambda x: x.id, line.journal_ids),
  176. 'allow_duplicate_operation': line.allow_duplicate_operation,
  177. 'fields_allowed': simplejson.loads(line.fields_allowed)
  178. }for line in self.env['res.bank.payments.type'].browse(map(lambda x: x['id'], self.env.cr.dictfetchall()))]
  179. '''
  180. GET account interest line
  181. '''
  182. @api.model
  183. def eiru_payments_account_interest_line(self,moveLine):
  184. return [{
  185. 'id': line.id,
  186. 'amountInterest': line.amount_interest,
  187. 'expiredDays': line.expired_days,
  188. 'state': line.state,
  189. 'moveLineId': line.move_line_id.id,
  190. 'invoice': [{
  191. 'id': accountInvoice.id,
  192. 'number': accountInvoice.number,
  193. 'state': accountInvoice.state,
  194. } for accountInvoice in self.env['account.invoice'].browse(line.invoice.id)],
  195. 'interest': [{
  196. 'id': line.interest_id.id,
  197. 'name': line.interest_id.name,
  198. 'state': line.interest_id.state,
  199. } for interest in self.env['account.interest'].browse(line.interest_id.id)],
  200. } for line in self.env['account.interest.line'].search([('move_line_id.id', 'in', moveLine)])]
  201. '''
  202. ____ ____ _
  203. / ___| __ ___ _____ | _ \ __ _ _ _ _ __ ___ ___ _ __ | |_ ___
  204. \___ \ / _` \ \ / / _ \ | |_) / _` | | | | '_ ` _ \ / _ \ '_ \| __/ __|
  205. ___) | (_| |\ V / __/ | __/ (_| | |_| | | | | | | __/ | | | |_\__ \
  206. |____/ \__,_| \_/ \___| |_| \__,_|\__, |_| |_| |_|\___|_| |_|\__|___/
  207. |___/
  208. '''
  209. '''
  210. check_module Installed
  211. '''
  212. def check_module(self, module_name):
  213. '''
  214. Método para verificar si los modulo están instalado
  215. :param module_name : Nombre del moduloself.
  216. :return: True 'Modulo instalado', False 'no instalado'
  217. '''
  218. module = self.env['ir.module.module'].search([('name', '=', module_name), ('state', '=', 'installed')])
  219. return len(module) != 0
  220. '''
  221. Get invoice
  222. '''
  223. def get_invoice(self, invoiceId):
  224. return self.env['account.invoice'].browse(invoiceId)
  225. '''
  226. Get Period
  227. '''
  228. def get_period(self, date_server):
  229. return self.env['account.period'].search([('date_start','<=', date_server), ('date_stop', '>=', date_server)])
  230. '''
  231. Get timezone
  232. '''
  233. def get_timezone(self):
  234. tz_name = self._context.get('tz') or self.env.user.tz
  235. return timezone(tz_name)
  236. '''
  237. Get server date
  238. '''
  239. def get_server_datetime(self):
  240. return datetime.now(self.get_timezone()).strftime(DATE_FORMAT)
  241. '''
  242. get Statement Config
  243. '''
  244. def getStatementConfig(self, id):
  245. return self.env['account.bank.statement.config'].browse(id)
  246. '''
  247. Create Voucher
  248. '''
  249. def create_voucher_invoice(self, period, invoice, company_id, amountPayments, date_server, journalId, move_line_Ids, customerId, voucherName, voucherObs, voucherSeq):
  250. ## Get Journal
  251. journal_id = self.env['account.journal'].browse(int(journalId))
  252. currency_id = journal_id.default_credit_account_id.currency_id.id or journal_id.default_credit_account_id.company_currency_id.id
  253. # Get Move Lines
  254. move_line = self.env['account.move.line'].browse(move_line_Ids).sorted(key=lambda r: r.id)
  255. ### res.partner
  256. customerId = self.env['res.partner']._find_accounting_partner(invoice.partner_id)
  257. ### decimal.precision
  258. decimal_precision = self.env['decimal.precision'].precision_get('Account')
  259. ### Currencies (company/ Journal)
  260. company_currency = self.env.user.company_id.currency_id
  261. currencyVocuher = self.env['res.currency'].browse(currency_id)
  262. ### Create Line Voucher 'seq_invoice': invoice.seq_invoice
  263. line_ids = []
  264. amount = round(float(amountPayments), decimal_precision)
  265. for line in move_line:
  266. amount_residual = line.amount_residual
  267. if (company_currency.id != currencyVocuher.id):
  268. amount_residual = round((amount_residual * (currencyVocuher.rate / company_currency.rate)), decimal_precision)
  269. line_ids.append([0, False, {
  270. 'date_due': line.date_maturity,
  271. 'account_id': line.account_id.id,
  272. 'date_original': line.move_id.date,
  273. 'move_line_id': line.id,
  274. 'amount_original': abs(line.credit or line.debit or 0.0),
  275. 'amount_unreconciled': abs(line.amount_residual),
  276. 'amount': min(abs(amount), abs(amount_residual)),
  277. 'reconcile': True if abs(amount_residual) == min(abs(amount), abs(amount_residual)) else False,
  278. 'currency_id': currency_id
  279. }])
  280. amount -= min(abs(amount), amount_residual)
  281. amountResidual = round(float(amountPayments), decimal_precision)
  282. values = {
  283. 'name': voucherName,
  284. 'reference': invoice.number,
  285. 'type': invoice.type in ('out_invoice','out_refund') and 'receipt' or 'payment',
  286. 'journal_id': journal_id.id,
  287. 'company_id': company_id,
  288. 'pre_line': True,
  289. 'amount': invoice.type in ('out_refund', 'in_refund') and -amountResidual or amountResidual,
  290. 'period_id': period.id,
  291. 'date': date_server,
  292. 'partner_id': customerId.id,
  293. 'account_id': journal_id.default_credit_account_id.id,
  294. 'currency_id': currency_id,
  295. 'line_cr_ids': invoice.type in ('out_invoice', 'in_refund') and line_ids or [],
  296. 'line_dr_ids': invoice.type in ('out_refund', 'in_invoice') and line_ids or [],
  297. 'payment_rate_currency_id': currency_id,
  298. 'comment_obs': voucherObs,
  299. 'seq_invoice': voucherSeq
  300. }
  301. account_voucher = self.env['account.voucher'].create(values)
  302. account_voucher.action_move_line_create()
  303. if (not account_voucher.name):
  304. account_voucher.write({'name': account_voucher.number})
  305. return account_voucher
  306. '''
  307. Change State invoice
  308. '''
  309. def close_status_invoice(self, invoiceid):
  310. invoice = self.env['account.invoice'].search([('id', '=', invoiceid)])
  311. if invoice.residual <= 0:
  312. invoice.confirm_paid()
  313. return invoice
  314. '''
  315. Create bank Statement
  316. '''
  317. def create_bank_statement(self, date_server, user_id, account_voucher, statementId):
  318. domain = [('journal_id', '=', account_voucher.journal_id.id),('user_id', '=', user_id)]
  319. if (statementId):
  320. domain.append(('id', '=', statementId))
  321. else:
  322. domain.append(('date', '=', date_server))
  323. bank_statement = self.env['account.bank.statement'].search(domain)
  324. bank = {
  325. 'journal_id': account_voucher.journal_id.id,
  326. 'period_id': account_voucher.period_id.id,
  327. 'date': date_server,
  328. 'user_id': user_id,
  329. 'state': 'open' if account_voucher.journal_id.type == 'cash' else 'draft',
  330. }
  331. bankStatement = bank_statement
  332. if bank_statement:
  333. if len(bank_statement) != 1:
  334. bankStatement = bank_statement[len(bank_statement) -1]
  335. bankStatement.button_open()
  336. else:
  337. bankStatement = bank_statement.create(bank)
  338. return bankStatement
  339. '''
  340. Create Statamente Line
  341. '''
  342. def create_bank_statement_line(self, account_voucher, statement):
  343. ### Create line bank
  344. bank_statement_line = {
  345. 'name': account_voucher.reference,
  346. 'partner_id': account_voucher.partner_id.id,
  347. 'amount': account_voucher.type in ('payment') and -account_voucher.amount or account_voucher.amount,
  348. 'voucher_id': account_voucher.id,
  349. 'journal_id': account_voucher.journal_id.id,
  350. 'account_id': account_voucher.account_id.id,
  351. 'journal_entry_id': account_voucher.move_id.id,
  352. 'currency_id': account_voucher.currency_id.id,
  353. 'ref': 'NP',
  354. 'statement_id': statement.id
  355. }
  356. line_id = self.env['account.bank.statement.line'].create(bank_statement_line)
  357. return line_id
  358. '''
  359. Bank Line
  360. '''
  361. def create_bank_paymnets(self, account_voucher, date_server, invoice, bankPayments):
  362. bankId = []
  363. bankPaymentsType = []
  364. bankChequeType = []
  365. amountTotal = 0
  366. for valor in bankPayments:
  367. if (valor == 'bank_id'):
  368. bankId = self.env['res.bank'].browse(bankPayments[valor])
  369. if (valor == 'bank_payments_type_id'):
  370. bankPaymentsType = self.env['res.bank.payments.type'].browse(bankPayments[valor])
  371. if (valor == 'cheque_type_id'):
  372. bankChequeType = self.env['res.bank.cheque.type'].browse(bankPayments[valor])
  373. if(valor == 'amount_total'):
  374. amountTotal = bankPayments[valor]
  375. bankPayments['date'] = date_server
  376. bankPayments['state'] = bankPaymentsType.default_state
  377. bankPayments['comment'] = 'Np'
  378. bankPayments['currency_id'] = account_voucher.currency_id.id
  379. bankPayments['customer_id'] = invoice.type in ('out_invoice','in_refund') and account_voucher.partner_id.id or ''
  380. bankPayments['supplier_id'] = invoice.type in ('in_invoice','out_refund') and account_voucher.partner_id.id or ''
  381. bankPayments['amount_total'] = amountTotal if (amountTotal > 0) else account_voucher.amount
  382. paymnets_bank = []
  383. if (not bankPaymentsType.allow_duplicate_operation):
  384. try:
  385. number = bankPayments['number']
  386. numberCta = bankPayments['number_cta']
  387. except Exception as e:
  388. number = None
  389. numberCta = None
  390. paymnets_bank = self.env['res.bank.payments'].search([ ('number', '=', number), ('bank_id', '=', bankId.id), ('number_cta', '=', numberCta)])
  391. if (paymnets_bank):
  392. bankPayments = []
  393. # ventas/rectific. compras/gastos
  394. if (invoice.type in ('out_invoice','in_refund')):
  395. bankPayments = {
  396. 'partner_id': invoice.type in ('out_invoice','in_refund') and account_voucher.partner_id.id or ''
  397. }
  398. ## Compras/gastos/rectific. ventas
  399. if (invoice.type in ('in_invoice','out_refund')):
  400. bankPayments = {
  401. 'supplier_id': invoice.type in ('in_invoice','out_refund') and account_voucher.partner_id.id or ''
  402. }
  403. if (bankPayments):
  404. paymnets_bank.write(bankPayments)
  405. else:
  406. paymnets_bank = self.env['res.bank.payments'].create(bankPayments)
  407. return paymnets_bank
  408. '''
  409. Create Bnak Paymnets Line
  410. '''
  411. def create_bank_paymnets_line(self, voucher, bank_payments, bank_statement_line, bank_statement, date_server, invoice):
  412. account_voucher = self.env['account.voucher'].browse(voucher.id)
  413. res_bank_payments = self.env['res.bank.payments'].browse(bank_payments.id)
  414. statement_line = self.env['account.bank.statement.line'].browse(bank_statement_line.id)
  415. statement = self.env['account.bank.statement'].browse(bank_statement.id)
  416. bank_line = {
  417. 'amount': abs(account_voucher.amount) ,
  418. 'date': date_server,
  419. 'bank_payments_id': res_bank_payments.id,
  420. 'statement_line_id': bank_statement_line.id,
  421. 'statement_id': bank_statement.id,
  422. 'type_operation': invoice.type in ('out_invoice','in_refund') and 'receipt' or 'payment',
  423. 'amount_currency' : 0.00,
  424. 'currency_id' : account_voucher.currency_id.id
  425. }
  426. paymnets_line = self.env['res.bank.payments.line'].create(bank_line)
  427. return paymnets_line
  428. '''
  429. Save payments
  430. '''
  431. @api.model
  432. def save_payments_invoice(self, values):
  433. ## Date Server
  434. date_server = self.get_server_datetime()
  435. ### Usuer
  436. resUser = self.env.user.id
  437. ### Compania
  438. resCompany = self.env.user.company_id.id
  439. ### Invoice
  440. accountInvoice = self.get_invoice(values['invoiceId'])
  441. if (not accountInvoice):
  442. return False
  443. ### Period
  444. accountPeriod = self.get_period(date_server)
  445. if (not accountPeriod):
  446. return False
  447. ### Create.
  448. ##### Vocuher.
  449. voucher = self.create_voucher_invoice(accountPeriod, accountInvoice, resCompany, values['amountPayments'], values['datePayments'], values['JournalId'], values['moveLines'], values['partnerId'], values['voucherName'], values['voucherObs'], values['voucherSeq'])
  450. ### Close invoice.
  451. closeInvoice = self.close_status_invoice(values['invoiceId'])
  452. ### Create bank Statement
  453. bank_statement = self.create_bank_statement(date_server, resUser, voucher, values['statementId'])
  454. ### Create bank statement Line
  455. bank_statement_line = self.create_bank_statement_line(voucher, bank_statement)
  456. ### Verify Type Operations 'journal_ids'
  457. if ((self.check_module('eiru_bank_payments_references')) and (values['JournalType'] == 'bank') and (values['bankPayments'])):
  458. typeOperation = self.env['res.bank.payments.type'].search(([('journal_ids', 'in', values['JournalId'])]))
  459. if (typeOperation):
  460. bank_payments = self.create_bank_paymnets(voucher, date_server, accountInvoice, values['bankPayments'])
  461. bank_payments_Line = self.create_bank_paymnets_line(voucher, bank_payments, bank_statement_line, bank_statement, date_server, accountInvoice)
  462. return {
  463. 'process': True
  464. }