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
Beispiel #2
0
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
Beispiel #4
0
    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
Beispiel #5
0
    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]
        }
Beispiel #6
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