Files
suite/pos_elavon/models/pos_elavon_transaction.py
2020-10-30 16:01:10 +00:00

129 lines
4.1 KiB
Python

from datetime import date, timedelta
import requests
import werkzeug
from odoo import models, api, service
from odoo.tools.translate import _
from odoo.exceptions import UserError
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, misc
class ElavonTransaction(models.Model):
_name = 'pos_elavon.elavon_transaction'
def _get_pos_session(self):
pos_session = self.env['pos.session'].search([('state', '=', 'opened'), ('user_id', '=', self.env.uid)], limit=1)
if not pos_session:
raise UserError(_("No opened point of sale session for user %s found") % self.env.user.name)
pos_session.login()
return pos_session
def _get_pos_elavon_config_id(self, config, journal_id):
journal = config.journal_ids.filtered(lambda r: r.id == journal_id)
if journal and journal.pos_elavon_config_id:
return journal.pos_elavon_config_id
else:
raise UserError(_("No Elavon configuration associated with the journal."))
def _setup_request(self, data):
# todo: in master make the client include the pos.session id and use that
pos_session = self._get_pos_session()
config = pos_session.config_id
pos_elavon_config = self._get_pos_elavon_config_id(config, data['journal_id'])
data['ssl_merchant_id'] = pos_elavon_config.sudo().merchant_id
data['ssl_user_id'] = pos_elavon_config.sudo().merchant_user_id
# Load from team
data['ssl_pin'] = config.sudo().crm_team_id.pos_elavon_merchant_pin
data['ssl_show_form'] = 'false'
data['ssl_result_format'] = 'ascii'
def _do_request(self, data):
if not data['ssl_merchant_id'] or not data['ssl_user_id'] or not data['ssl_pin']:
return "not setup"
response = ''
url = 'https://api.convergepay.com/VirtualMerchant/process.do'
if self.env['ir.config_parameter'].sudo().get_param('pos_elavon.enable_test_env'):
url = 'https://api.demo.convergepay.com/VirtualMerchantDemo/process.do'
try:
r = requests.post(url, data=data, timeout=500)
r.raise_for_status()
response = werkzeug.utils.unescape(r.content.decode())
except Exception:
response = "timeout"
return response
def _do_reversal_or_voidsale(self, data, is_voidsale):
try:
self._setup_request(data)
except UserError:
return "internal error"
# Can we voidsale?
#data['is_voidsale'] = is_voidsale
data['ssl_transaction_type'] = 'CCVOID'
response = self._do_request(data)
return response
@api.model
def do_payment(self, data):
try:
self._setup_request(data)
except UserError:
return "internal error"
data['ssl_transaction_type'] = 'CCSALE'
response = self._do_request(data)
return response
@api.model
def do_reversal(self, data):
return self._do_reversal_or_voidsale(data, False)
@api.model
def do_voidsale(self, data):
return self._do_reversal_or_voidsale(data, True)
@api.model
def do_return(self, data):
try:
self._setup_request(data)
except UserError:
return "internal error"
data['ssl_transaction_type'] = 'CCRETURN'
response = self._do_request(data)
return response
@api.model
def do_credit(self, data):
try:
self._setup_request(data)
except UserError:
return "internal error"
data['ssl_transaction_type'] = 'CCCREDIT'
response = self._do_request(data)
return response
# One time (the ones we use) Elavon tokens are required to be
# deleted after 6 months
# This is a from Mercury, probably not needed anymore.
@api.model
def cleanup_old_tokens(self):
expired_creation_date = (date.today() - timedelta(days=6 * 30)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
for order in self.env['pos.order'].search([('create_date', '<', expired_creation_date)]):
order.ref_no = ""
order.record_no = ""