def create_reservation(self, channel_room_id, customer_name, email, city, phone, address, country_code, checkin, checkout, adults, children, notes=''): customer_name = _partner_split_name(customer_name) customer = { 'lname': customer_name[0], 'fname': customer_name[1], 'email': email, 'city': city, 'phone': phone, 'street': address, 'country': country_code, 'arrival_hour': fields.Datetime.from_string(checkin).strftime("%H:%M"), 'notes': notes } rcode, results = self._server.new_reservation( self._session_info[0], self._session_info[1], fields.Date.from_string(checkin).strftime(DEFAULT_WUBOOK_DATE_FORMAT), fields.Date.from_string(checkout).strftime(DEFAULT_WUBOOK_DATE_FORMAT), {channel_room_id: [adults+children, 'nb']}, customer, adults+children) if rcode != 0: raise ChannelConnectorError(_("Can't create reservations in wubook"), { 'message': results, 'date_from': checkin, 'date_to': checkout, }) return results
def get_customer_info(partner_id, country_id=False): if not country_id: country_id = partner_id.country_id return { "firstName": "" if partner_id.is_company else _partner_split_name(partner_id.name)[0], "lastName": partner_id.name if partner_id.is_company else _partner_split_name(partner_id.name)[1], "email": partner_id.email or "", "address1": partner_id.street[:40] if partner_id.street else "", "city": partner_id.city or "", "country": country_id.code or "", "ip": request.httprequest.remote_addr or "" }
def create_customer_profile(self, partner, cardnumber, expiration_date, card_code): """Create a payment and customer profile in the Authorize.net backend. Creates a customer profile for the partner/credit card combination and links a corresponding payment profile to it. Note that a single partner in the Odoo database can have multiple customer profiles in Authorize.net (i.e. a customer profile is created for every res.partner/payment.token couple). :param record partner: the res.partner record of the customer :param str cardnumber: cardnumber in string format (numbers only, no separator) :param str expiration_date: expiration date in 'YYYY-MM' string format :param str card_code: three- or four-digit verification number :return: a dict containing the profile_id and payment_profile_id of the newly created customer profile and payment profile :rtype: dict """ root = self._base_tree('createCustomerProfileRequest') profile = etree.SubElement(root, "profile") etree.SubElement( profile, "merchantCustomerId").text = 'ODOO-%s-%s' % (partner.id, uuid4().hex[:8]) etree.SubElement(profile, "email").text = partner.email or '' payment_profile = etree.SubElement(profile, "paymentProfiles") etree.SubElement( payment_profile, "customerType" ).text = 'business' if partner.is_company else 'individual' billTo = etree.SubElement(payment_profile, "billTo") if partner.is_company: etree.SubElement(billTo, "firstName").text = ' ' etree.SubElement(billTo, "lastName").text = partner.name else: etree.SubElement(billTo, "firstName").text = _partner_split_name( partner.name)[0] etree.SubElement(billTo, "lastName").text = _partner_split_name( partner.name)[1] etree.SubElement(billTo, "address").text = ( partner.street or '' + (partner.street2 if partner.street2 else '')) or None missing_fields = [ partner._fields[field].string for field in ['city', 'country_id'] if not partner[field] ] if missing_fields: raise ValidationError({'missing_fields': missing_fields}) etree.SubElement(billTo, "city").text = partner.city etree.SubElement(billTo, "state").text = partner.state_id.name or None etree.SubElement(billTo, "zip").text = partner.zip or '' etree.SubElement(billTo, "country").text = partner.country_id.name or None payment = etree.SubElement(payment_profile, "payment") creditCard = etree.SubElement(payment, "creditCard") etree.SubElement(creditCard, "cardNumber").text = cardnumber etree.SubElement(creditCard, "expirationDate").text = expiration_date etree.SubElement(creditCard, "cardCode").text = card_code etree.SubElement(root, "validationMode").text = 'liveMode' response = self._authorize_request(root) # If the user didn't set up authorize.net properly then the response # won't contain stuff like customerProfileId and accessing text # will raise a NoneType has no text attribute msg = response.find('messages') if msg is not None: rc = msg.find('resultCode') if rc is not None and rc.text == 'Error': err = msg.find('message') err_code = err.find('code').text err_msg = err.find('text').text raise UserError("Authorize.net Error:\nCode: %s\nMessage: %s" % (err_code, err_msg)) res = dict() res['profile_id'] = response.find('customerProfileId').text res['payment_profile_id'] = response.find( 'customerPaymentProfileIdList/numericString').text return res
def create_customer_profile(self, partner, cardnumber, expiration_date, card_code): """Create a payment and customer profile in the Authorize.net backend. Creates a customer profile for the partner/credit card combination and links a corresponding payment profile to it. Note that a single partner in the Odoo database can have multiple customer profiles in Authorize.net (i.e. a customer profile is created for every res.partner/payment.token couple). :param record partner: the res.partner record of the customer :param str cardnumber: cardnumber in string format (numbers only, no separator) :param str expiration_date: expiration date in 'YYYY-MM' string format :param str card_code: three- or four-digit verification number :return: a dict containing the profile_id and payment_profile_id of the newly created customer profile and payment profile :rtype: dict """ root = self._base_tree('createCustomerProfileRequest') profile = etree.SubElement(root, "profile") # merchantCustomerId is ODOO-{partner.id}-{random hex string} truncated to maximum 20 characters etree.SubElement(profile, "merchantCustomerId").text = ('ODOO-%s-%s' % (partner.id, uuid4().hex[:8]))[:20] etree.SubElement(profile, "email").text = partner.email or '' payment_profile = etree.SubElement(profile, "paymentProfiles") etree.SubElement(payment_profile, "customerType").text = 'business' if partner.is_company else 'individual' billTo = etree.SubElement(payment_profile, "billTo") if partner.is_company: etree.SubElement(billTo, "firstName").text = ' ' etree.SubElement(billTo, "lastName").text = partner.name else: etree.SubElement(billTo, "firstName").text = _partner_split_name(partner.name)[0] etree.SubElement(billTo, "lastName").text = _partner_split_name(partner.name)[1] etree.SubElement(billTo, "address").text = (partner.street or '' + (partner.street2 if partner.street2 else '')) or None missing_fields = [partner._fields[field].string for field in ['city', 'country_id'] if not partner[field]] if missing_fields: raise ValidationError({'missing_fields': missing_fields}) etree.SubElement(billTo, "city").text = partner.city etree.SubElement(billTo, "state").text = partner.state_id.name or None etree.SubElement(billTo, "zip").text = partner.zip or '' etree.SubElement(billTo, "country").text = partner.country_id.name or None payment = etree.SubElement(payment_profile, "payment") creditCard = etree.SubElement(payment, "creditCard") etree.SubElement(creditCard, "cardNumber").text = cardnumber etree.SubElement(creditCard, "expirationDate").text = expiration_date etree.SubElement(creditCard, "cardCode").text = card_code etree.SubElement(root, "validationMode").text = 'liveMode' response = self._authorize_request(root) # If the user didn't set up authorize.net properly then the response # won't contain stuff like customerProfileId and accessing text # will raise a NoneType has no text attribute msg = response.find('messages') if msg is not None: rc = msg.find('resultCode') if rc is not None and rc.text == 'Error': err = msg.find('message') err_code = err.find('code').text err_msg = err.find('text').text raise UserError( "Authorize.net Error:\nCode: %s\nMessage: %s" % (err_code, err_msg) ) res = dict() res['profile_id'] = response.find('customerProfileId').text res['payment_profile_id'] = response.find('customerPaymentProfileIdList/numericString').text return res
def create_customer_profile(self, partner, opaqueData): """Create a payment and customer profile in the Authorize.net backend. Creates a customer profile for the partner/credit card combination and links a corresponding payment profile to it. Note that a single partner in the Odoo database can have multiple customer profiles in Authorize.net (i.e. a customer profile is created for every res.partner/payment.token couple). :param record partner: the res.partner record of the customer :param str cardnumber: cardnumber in string format (numbers only, no separator) :param str expiration_date: expiration date in 'YYYY-MM' string format :param str card_code: three- or four-digit verification number :return: a dict containing the profile_id and payment_profile_id of the newly created customer profile and payment profile :rtype: dict """ values = { 'createCustomerProfileRequest': { 'merchantAuthentication': { 'name': self.name, 'transactionKey': self.transaction_key }, 'profile': { 'description': ('ODOO-%s-%s' % (partner.id, uuid4().hex[:8]))[:20], 'email': partner.email or '', 'paymentProfiles': { 'customerType': 'business' if partner.is_company else 'individual', 'billTo': { 'firstName': '' if partner.is_company else _partner_split_name(partner.name)[0], 'lastName': _partner_split_name(partner.name)[1], 'address': (partner.street or '' + (partner.street2 if partner.street2 else '')) or None, 'city': partner.city, 'state': partner.state_id.name or None, 'zip': partner.zip or '', 'country': partner.country_id.name or None, 'phoneNumber': partner.phone or '', }, 'payment': { 'opaqueData': { 'dataDescriptor': opaqueData.get('dataDescriptor'), 'dataValue': opaqueData.get('dataValue') } } } }, 'validationMode': 'liveMode' if self.state == 'enabled' else 'testMode' } } response = self._authorize_request(values) if response and response.get('err_code'): raise UserError(_( "Authorize.net Error:\nCode: %s\nMessage: %s" % (response.get('err_code'), response.get('err_msg')) )) return { 'profile_id': response.get('customerProfileId'), 'payment_profile_id': response.get('customerPaymentProfileIdList')[0] }
def api_values(self, reference, amount, currency_id, partner_id=False, values=None): """ Renders the form template of the given acquirer as a qWeb template. :param string reference: the transaction reference :param float amount: the amount the buyer has to pay :param currency_id: currency id :param dict partner_id: optional partner_id to fill values :param dict values: a dictionary of values for the transction that is given to the acquirer-specific method generating the form values All templates will receive: - acquirer: the payment.acquirer browse record - user: the current user browse record - currency_id: id of the transaction currency - amount: amount of the transaction - reference: reference of the transaction - partner_*: partner-related values - partner: optional partner browse record - 'feedback_url': feedback URL, controler that manage answer of the acquirer (without base url) -> FIXME - 'return_url': URL for coming back after payment validation (wihout base url) -> FIXME - 'cancel_url': URL if the client cancels the payment -> FIXME - 'error_url': URL if there is an issue with the payment -> FIXME - context: Odoo context """ if values is None: values = {} if not self.view_template_id: return None values.setdefault('return_url', '/payment/process') # reference and amount values.setdefault('reference', reference) amount = float_round(amount, 2) values.setdefault('amount', amount) # currency id currency_id = values.setdefault('currency_id', currency_id) if currency_id: currency = self.env['res.currency'].browse(currency_id) else: currency = self.env.company.currency_id values['currency'] = currency # Fill partner_* using values['partner_id'] or partner_id argument partner_id = values.get('partner_id', partner_id) billing_partner_id = values.get('billing_partner_id', partner_id) if partner_id: partner = self.env['res.partner'].browse(partner_id) if partner_id != billing_partner_id: billing_partner = self.env['res.partner'].browse( billing_partner_id) else: billing_partner = partner values.update({ 'partner': partner, 'partner_id': partner_id, 'partner_name': partner.name, 'partner_lang': partner.lang, 'partner_email': partner.email, 'partner_zip': partner.zip, 'partner_city': partner.city, 'partner_address': _partner_format_address(partner.street, partner.street2), 'partner_country_id': partner.country_id.id or self.env['res.company']._company_default_get().country_id.id, 'partner_country': partner.country_id, 'partner_phone': partner.phone, 'partner_state': partner.state_id, 'billing_partner': billing_partner, 'billing_partner_id': billing_partner_id, 'billing_partner_name': billing_partner.name, 'billing_partner_commercial_company_name': billing_partner.commercial_company_name, 'billing_partner_lang': billing_partner.lang, 'billing_partner_email': billing_partner.email, 'billing_partner_zip': billing_partner.zip, 'billing_partner_city': billing_partner.city, 'billing_partner_address': _partner_format_address(billing_partner.street, billing_partner.street2), 'billing_partner_country_id': billing_partner.country_id.id, 'billing_partner_country': billing_partner.country_id, 'billing_partner_phone': billing_partner.phone, 'billing_partner_state': billing_partner.state_id, }) if values.get('partner_name'): values.update({ 'partner_first_name': _partner_split_name(values.get('partner_name'))[0], 'partner_last_name': _partner_split_name(values.get('partner_name'))[1], }) if values.get('billing_partner_name'): values.update({ 'billing_partner_first_name': _partner_split_name(values.get('billing_partner_name'))[0], 'billing_partner_last_name': _partner_split_name(values.get('billing_partner_name'))[1], }) # Fix address, country fields if not values.get('partner_address'): values['address'] = _partner_format_address( values.get('partner_street', ''), values.get('partner_street2', '')) if not values.get('partner_country') and values.get( 'partner_country_id'): values['country'] = self.env['res.country'].browse( values.get('partner_country_id')) if not values.get('billing_partner_address'): values['billing_address'] = _partner_format_address( values.get('billing_partner_street', ''), values.get('billing_partner_street2', '')) if not values.get('billing_partner_country') and values.get( 'billing_partner_country_id'): values['billing_country'] = self.env['res.country'].browse( values.get('billing_partner_country_id')) # compute fees fees_method_name = '%s_compute_fees' % self.provider if hasattr(self, fees_method_name): fees = getattr(self, fees_method_name)(values['amount'], values['currency_id'], values.get('partner_country_id')) values['fees'] = float_round(fees, 2) # call <name>_form_generate_values to update the tx dict with acqurier specific values cust_method_name = '%s_form_generate_values' % (self.provider) if hasattr(self, cust_method_name): method = getattr(self, cust_method_name) values = method(values) values.update({ 'tx_url': self._context.get('tx_url', self.get_form_action_url()), }) _logger.info( 'payment.acquirer.render: <%s> values rendered for form payment:\n%s', self.provider, pprint.pformat(values)) return values