Exemple #1
0
def get_payment_responsable_data(family_id):
    url, db, username, password, version = get_odoo_settings()

    if not version or not services._validate_version(version):
        return get_payment_responsable_data_legacy(family_id)

    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    result = models.execute_kw(
        db, uid, password, 'edoo.api.integration',
        'get_payment_responsable_data', [{
            'parent_id': family_id,
            'company_id': Odoo.CUSTOM_SETTINGS['company_pk']
        }]
    )

    role = result.get('errors') and 'Sin Cliente' or 'Cliente registrado'

    result.update({
        'display_as': 'user',
        'role': role,
        'profile_picture': Odoo.DEFAULT_AVATAR
    })

    return result
Exemple #2
0
def search_clients_legacy(query):
    url, db, username, password, version = get_odoo_settings()

    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    partners = models.execute_kw(db, uid, password,
        'res.partner', 'search_read',
        [[
            '|',
            ['ref', 'ilike', query],
            ['name', 'ilike', query],
            ['child_ids', '!=', False]
        ]]
    )

    partner_ids = list(map(lambda x: int(x['id']), partners))

    comercial_partners = models.execute_kw(db, uid, password,
        'res.partner', 'search_read',
        [[['parent_id', 'in', partner_ids], ['type', '=', 'invoice']]]
    )

    result = []

    for partner in partners:
        # Look for comercial partner

        # Logic 1
        cm = next((x for x in comercial_partners if x['parent_id'][0] == partner['id']), None)

        # Logic 2
        # cm = None
        # for comercial_partner in comercial_partners:
        #     if comercial_partner['parent_id'][0] == partner['id']:
        #         cm = comercial_partner
        #         break

        addresses = [cm['street'], cm['street2'], cm['city']] if cm else []

        client_object = {
            'display_as': 'user',
            'client_id': partner['id'],
            'client_name': partner['name'],
            'client_ref': partner['ref'],
            'comercial_id': cm['id'] if cm else None,
            'comercial_name': cm['name'] if cm else None,
            'comercial_number': cm['vat'] if (cm and cm['vat']) else None,
            'comercial_address': " ".join(address for address in addresses if address),
            'comercial_email': cm['email'] if (cm and cm['email']) else None,
            'profile_picture': Odoo.DEFAULT_AVATAR,
            'first_name': partner['name'],
            'role': "Cliente registrado"
        }

        result.append(client_object)

    return result
Exemple #3
0
def get_payment_responsable_data_legacy(client_id):
    url, db, username, password, version = get_odoo_settings()

    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    partner = models.execute_kw(db, uid, password,
        'res.partner', 'search_read',
        [[['id', '=', client_id]]],
        {'limit': 1}
    )

    if len(partner) != 1:
        raise Exception('No client found for id ' + str(client_id))

    partner = partner[0]

    comercial_partners = models.execute_kw(db, uid, password,
        'res.partner', 'search_read',
        [[['parent_id', '=', partner['id']], ['type', '=', 'invoice']]]
    )

    # A client must have one comercial partner
    if len(comercial_partners) == 0:
        raise Exception('No comercial partner found for client ' + str(client_id))
    elif len(comercial_partners) > 1:
        raise Exception('More than one comercial partner found for client ' + str(client_id))

    comercial_partner = comercial_partners[0]

    addresses = [
        comercial_partner['street'],
        comercial_partner['street2'],
        comercial_partner['city']
    ]

    payment_responsable_client_id = client_id
    payment_responsable_comercial_id = comercial_partner['id']
    payment_responsable_comercial_name = comercial_partner['name']
    payment_responsable_comercial_number = comercial_partner['vat'] or ''
    payment_responsable_comercial_address = " ".join(address for address in addresses if address)
    payment_responsable_comercial_email = comercial_partner['email'] or ''

    return {
        'display_as': 'user',
        'client_id': payment_responsable_client_id,
        'client_name': partner['name'],
        'client_ref': partner['ref'],
        'comercial_id': payment_responsable_comercial_id,
        'comercial_name': payment_responsable_comercial_name,
        'comercial_number': payment_responsable_comercial_number,
        'comercial_address': payment_responsable_comercial_address,
        'comercial_email': payment_responsable_comercial_email,
        'profile_picture': Odoo.DEFAULT_AVATAR,
        'first_name': partner['name'],
        'role': "Cliente registrado"
    }
Exemple #4
0
def get_data_clients(client_ids, fields):
    url, db, username, password, version = get_odoo_settings()
    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    fields.append('parent_id')
    comercial_clients = models.execute_kw(db, uid, password,
            'res.partner', 'search_read',
            [[['parent_id', 'in', client_ids], ['type', '=', 'invoice']]],
            {'fields': fields}
        )

    return comercial_clients
Exemple #5
0
def post_client(data):
    url, db, username, password, version = get_odoo_settings()
    if not version or not services._validate_version(version):
        return post_client_legacy(data)

    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    partner = models.execute_kw(
        db, uid, password, 'edoo.api.integration',
        'post_client', [{ 'name': data.get('name') }]
    )

    return partner
Exemple #6
0
def get_client(client_id):
    url, db, username, password, version = get_odoo_settings()

    uid = services.authenticate_user(url, db, username, password)

    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    client = models.execute_kw(db, uid, password,
        'res.partner', 'search_read',
        [[['id', '=', client_id]]]
    )

    if not len(client):
        return None

    return client[0]
Exemple #7
0
def post_client_legacy(data):
    url, db, username, password, version = get_odoo_settings()
    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    odoo_client_id = models.execute_kw(db, uid, password,
        'res.partner', 'create',
        [{
            'name': data['name'],
        }]
    )

    odoo_client = models.execute_kw(db, uid, password,
        'res.partner', 'search_read',
        [[['id', '=', odoo_client_id]]]
    )

    return odoo_client[0]
Exemple #8
0
def get_account_statement(clients, filters):
    url, db, username, password, version = get_odoo_settings()

    uid = services.authenticate_user(url, db, username, password)

    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    transactions_by_client = models.execute_kw(db, uid, password,
            'edoo.api.integration', 'get_account_statement',
                [{
                    'clients': clients,
                    'allowed_invoice_journals': get_allowed_invoice_journals(),
                    'allowed_payment_journals': get_allowed_payment_journals(),
                    'filters': filters
                }]
        )

    return transactions_by_client
Exemple #9
0
def search_clients(query):
    url, db, username, password, version = get_odoo_settings()
    if not version or not services._validate_version(version):
        return search_clients_legacy(query)

    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    partners = models.execute_kw(
        db, uid, password, 'edoo.api.integration',
        'search_clients', [{ 'word': query }]
    )

    for partner in partners:
        partner.update({
            'display_as': 'user',
            'role': 'Cliente registrado',
            'profile_picture': Odoo.DEFAULT_AVATAR,
        })
    
    return partners
Exemple #10
0
def register_client_legacy(
        student_client_id='',
        student_profile=None,
        student_tutors=[],
        client_id='',
        client_name='',
        client_ref='',
        comercial_id='',
        comercial_address='',
        comercial_number='',
        comercial_name='',
        comercial_email=''):
    """
    client_id: family id, odoo contact top level
    student_client_id: student id, odoo contact child level
    comercial_id: family comercial id, odoo contact child level
    """
    url, db, username, password, version = get_odoo_settings()

    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    # Setup codes
    instance_prefix = Odoo.CUSTOM_SETTINGS['instance_prefix']
    family_code_prefix = Odoo.CUSTOM_SETTINGS['family_code_prefix']
    comercial_code_sufix = Odoo.CUSTOM_SETTINGS['comercial_code_sufix']

    family_code = instance_prefix + family_code_prefix + client_ref
    family_name = client_name
    comercial_code = instance_prefix + family_code_prefix + client_ref + comercial_code_sufix

    tutors_emails = map(lambda x: x.user.email, student_tutors) if student_tutors else []

    # Fallback for None type
    student_profile.user.first_name = student_profile.user.first_name or ''
    student_profile.user.last_name = student_profile.user.last_name or ''

    # -------- Family contact --------

    # Update family contact
    if client_id:
        family_id = client_id
        models.execute_kw(db, uid, password, 'res.partner', 'write', [
            [family_id],
            {
                'email': ",".join(tutors_emails)
            }
        ])
    # Create family contact
    else:
        family_id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{
            'ref': family_code.encode('utf-8'),
            'name': family_name.encode('utf-8'),
            'email': ",".join(tutors_emails),
            'company_id': Odoo.CUSTOM_SETTINGS['company_pk']
        }])

    # -------- Family comercial contact --------

    # Update family comercial contact
    if comercial_id:
        family_comercial_id = comercial_id
        models.execute_kw(db, uid, password, 'res.partner', 'write', [
            [family_comercial_id],
            {
                'street': comercial_address.encode('utf-8'),
                'vat': comercial_number,
                'name': comercial_name.encode('utf-8'),
                'email': comercial_email,
                'parent_id': family_id,
                'type': 'invoice'
            }
        ])
    # Create family comercial contact
    else:
        family_comercial_id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{
            'ref': comercial_code,
            'street': comercial_address.encode('utf-8'),
            'vat': comercial_number,
            'name': comercial_name.encode('utf-8'),
            'email': comercial_email,
            'parent_id': family_id,
            'type': 'invoice',
            'company_id': Odoo.CUSTOM_SETTINGS['company_pk']
        }])

    # Update 'vat' separately because it is not set during creation.
    # TODO: Fix this issue in Odoo.
    models.execute_kw(db, uid, password, 'res.partner', 'write', [
        [family_comercial_id],
        { 'vat': comercial_number }
    ])

    # -------- Student contact --------

    # Reasign family if student_client_id exists
    if student_client_id:
        student_id = student_client_id
        student = models.execute_kw(db, uid, password,
            'res.partner', 'search_read',
            [[['id', '=', student_id]]],
            {'limit': 1}
        )

        if len(student) != 1:
            raise Exception('No client found for id ' + str(student_id))

        student = student[0]

        # Check if family has changed for the student
        if student['parent_id'] and student['parent_id'][0] != family_id:
            # Get family partner because we need its current 'ref'.
            old_family = models.execute_kw(db, uid, password,
                'res.partner', 'search_read',
                [[['id', '=', student['parent_id'][0]]]],
                {'limit': 1, 'fields': ['ref']}
            )
            old_family = old_family[0]

            # Get family comercial partner because we need its current 'ref'.
            old_comercial_partner = models.execute_kw(db, uid, password,
                'res.partner', 'search_read',
                [[['parent_id', '=', old_family['id']], ['type', '=', 'invoice']]],
                {'limit': 1, 'fields': ['ref']}
            )

            if len(old_comercial_partner) != 1:
                raise Exception('No comercial partner found for client ' + str(old_family['id']))

            old_comercial_partner = old_comercial_partner[0]

            # If student_id was used, it will have associated invoices
            invoice_count = models.execute_kw(db, uid, password,
                'account.invoice', 'search_count',
                [[['partner_shipping_id', '=', student_id], ['state', 'in', ['open','paid']]]]
            )

            # Archive student
            if invoice_count:
                models.execute_kw(db, uid, password, 'res.partner', 'write', [
                    [student_id],
                    {
                        'ref': (student['ref'] or '') + 'INACTIVE',
                        'active': False
                    }
                ])
            # Unlink student
            else:
                models.execute_kw(db, uid, password, 'res.partner', 'unlink', [
                    [student_id]
                ])

            family_students_count = models.execute_kw(db, uid, password,
                'res.partner', 'search_count',
                [[['parent_id', '=', old_family['id']], ['type', '=', 'contact']]]
            )

            # Family doesn't have more students
            if not family_students_count:
                account_move_lines_count = models.execute_kw(db, uid, password,
                    'account.move.line', 'search_count',
                    [[['partner_id', '=', old_family['id']]]]
                )

                # Archive family and comercial partner
                if account_move_lines_count:
                    # Disable family partner
                    models.execute_kw(db, uid, password, 'res.partner', 'write', [
                        [old_family['id']],
                        {
                            'ref': (old_family['ref'] or '') + 'INACTIVE',
                            'active': False
                        }
                    ])

                    # Disable family comercial partner
                    models.execute_kw(db, uid, password, 'res.partner', 'write', [
                        [old_comercial_partner['id']],
                        {
                            'ref': (old_comercial_partner['ref'] or '') + 'INACTIVE',
                            'active': False
                        }
                    ])
                # Unlink family and comercial partner
                else:
                    models.execute_kw(db, uid, password, 'res.partner', 'unlink', [
                        [old_family['id'], old_comercial_partner['id']]
                    ])

            # Create new student with new family
            student_id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{
                'ref': instance_prefix + student_profile.code,
                'name': '{0}, {1}'.format(
                    student_profile.user.first_name.encode('utf-8'),
                    student_profile.user.last_name.encode('utf-8')
                ),
                'email': student_profile.user.email,
                'parent_id': family_id,
                'company_id': Odoo.CUSTOM_SETTINGS['company_pk']
            }])
        # Update student contact
        else:
            models.execute_kw(db, uid, password, 'res.partner', 'write', [
                [student_id],
                {
                    'ref': '{}{}'.format(instance_prefix, student_profile.code),
                    'name': '{0}, {1}'.format(
                        student_profile.user.first_name.encode('utf-8'),
                        student_profile.user.last_name.encode('utf-8')
                    ),
                    'email': student_profile.user.email
                }
            ])
    # Create student contact
    else:
        student_id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{
            'ref': instance_prefix + student_profile.code,
            'name': '{0}, {1}'.format(
                student_profile.user.first_name.encode('utf-8'),
                student_profile.user.last_name.encode('utf-8')
            ),
            'email': student_profile.user.email,
            'parent_id': family_id,
            'company_id': Odoo.CUSTOM_SETTINGS['company_pk']
        }])


    # Response
    client_id = student_id
    payment_responsable_client_id = family_id
    payment_responsable_comercial_id = family_comercial_id

    return (
        client_id,
        payment_responsable_client_id,
        payment_responsable_comercial_id,
        None,
        None
    )
Exemple #11
0
def register_client(
        student_client_id=False,
        student_profile=None,
        student_tutors=[],
        client_id=False,
        client_name='',
        client_ref=False,
        comercial_id=False,
        comercial_address='',
        comercial_number='',
        comercial_name='',
        comercial_email=''):
    """
    client_id: family id, odoo contact top level
    student_client_id: student id, odoo contact child level
    comercial_id: family comercial id, odoo contact child level
    """
    url, db, username, password, version = get_odoo_settings()
    print version, type(version)

    if not version or not services._validate_version(version):
        return register_client_legacy(
            student_client_id,
            student_profile,
            student_tutors,
            client_id,
            client_name,
            client_ref,
            comercial_id,
            comercial_address,
            comercial_number,
            comercial_name,
            comercial_email
        )

    student_client_id = student_client_id or False
    client_id = client_id or False
    comercial_id = comercial_id or False

    uid = services.authenticate_user(url, db, username, password)
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    company_id = Odoo.CUSTOM_SETTINGS['company_pk']

    family_code = client_ref or False

    data = {
        'company_id': company_id,
        'family': {
            'id': client_id,
            'emails': [tutor.user.email for tutor in student_tutors],
            'company_id': company_id,
            'name': client_name.encode('utf-8'),
            'ref': family_code
        },

        'commercial_contact': {
            'id': comercial_id,
            'address': comercial_address.encode('utf-8'),
            'vat': comercial_number,
            'name': comercial_name.encode('utf-8'),
            'email': comercial_email,
            'parent_id': client_id,
            'type': 'invoice',
            'company_id': company_id
        },

        'student': {
            'id': student_client_id,
            'ref': student_profile.code,
            'name': student_profile.user.formal_name.encode('utf-8'),
            'email': student_profile.user.email,
            'parent_id': client_id,
            'company_id': company_id,
            'level_id': student_profile.level.pk if student_profile.level else False
        }
    }

    res = models.execute_kw(
        db, uid, password, 'edoo.api.integration',
        'register_client', [data]
    )

    if 'errors' in res:
        return (
            None,
            None,
            None,
            None,
            res.get('errors')
        )

    return (
        res.get('client_id'),
        res.get('payment_responsable_client_id'),
        res.get('payment_responsable_comercial_id'),
        res.get('student_ref'),
        None
    )
Exemple #12
0
def get_account_statement_legacy(client_id, comercial_id, filters):
    url, db, username, password, version = get_odoo_settings()
    comercial_id = int(comercial_id)
    client_id = int(client_id)

    allowed_invoice_journals = get_allowed_invoice_journals()
    allowed_payment_journals = get_allowed_payment_journals()

    uid = services.authenticate_user(url, db, username, password)

    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))

    query_filters = [
        '|',
        ['partner_id', '=', comercial_id],
        ['commercial_partner_id', '=', comercial_id],
        ['journal_id', 'in', allowed_invoice_journals],
        ['state', 'in', ['open','paid']]
    ]

    if ('date_start' in filters):
        # Throw error if date_start does not match format '%Y-%m-%d'
        time.strptime(filters['date_start'], '%Y-%m-%d')

        query_filters.append(['date', '>=', filters['date_start']])

    if ('date_end' in filters):
        # Throw error if date_end does not match format '%Y-%m-%d'
        time.strptime(filters['date_end'], '%Y-%m-%d')

        query_filters.append(['date', '<=', filters['date_end']])

    """
    --------------------------------------------
    Invoices
    --------------------------------------------
    """

    # Get client invoices.
    account_invoices = models.execute_kw(db, uid, password,
        'account.invoice', 'search_read',
        [query_filters],
        {'order': 'company_id, date_invoice'}
    )

    account_invoice_line_ids = []

    transactions_by_company = []
    company_invoices = []
    prev_company_id = None
    prev_company_name = None

    # Get the information that interests us, grouping by company.
    for account_invoice in account_invoices:
        company_id = account_invoice['company_id'][0]
        company_name = account_invoice['company_id'][1]

        if (prev_company_id and prev_company_id != company_id):
            transactions_by_company.append({
                'company_id': prev_company_id,
                'company_name': prev_company_name,
                'invoices': company_invoices,
                'payments': [],
                'balance': 0
            })

            company_invoices = []

        invoice  = {
            'id': account_invoice['id'],
            'number': account_invoice['number'],
            'date_invoice': account_invoice['date_invoice'],
            'date_due': account_invoice['date_due'],
            'amount_total_signed': account_invoice['amount_total_signed'],
            'invoice_line_ids': account_invoice['invoice_line_ids'],
            'reconciled': account_invoice['reconciled'],
            'journal_id': account_invoice['journal_id'],
            'type': account_invoice['type']
        }

        account_invoice_line_ids.extend(account_invoice['invoice_line_ids'])

        company_invoices.append(invoice)
        prev_company_id = company_id
        prev_company_name = company_name

    # The algorithm of the previous loop does not add the last company_invoices.
    # Add it if the loop was entered.
    if prev_company_id:
        transactions_by_company.append({
            'company_id': prev_company_id,
            'company_name': prev_company_name,
            'invoices': company_invoices,
            'payments': [],
            'balance': 0
        })

    # Get the details of the invoices to get the descriptions.
    account_invoice_lines = models.execute_kw(db, uid, password,
        'account.invoice.line', 'search_read',
        [[['id', 'in', account_invoice_line_ids]]]
    )

    invoice_line_indexed = {}
    for account_invoice_line in account_invoice_lines:
        invoice_line_indexed[account_invoice_line['id']] = {
            'display_name': account_invoice_line['display_name'],
            'x_price_included': account_invoice_line['x_price_included']
        }

    # Include descriptions.
    for company_data in transactions_by_company:
        for invoice in company_data['invoices']:
            invoice['invoice_lines'] = map(
                lambda x: {
                    'id': x,
                    'display_name': invoice_line_indexed[x]['display_name'],
                    'x_price_included': invoice_line_indexed[x]['x_price_included']
                },
                invoice['invoice_line_ids']
            )

            # This key will no longer serve us.
            invoice.pop('invoice_line_ids')

    query_filters = [
        ['partner_id', '=', client_id],
        ['journal_id', 'in', allowed_payment_journals]
    ]

    if ('date_start' in filters):
        # Throw error if date_start does not match format '%Y-%m-%d'
        time.strptime(filters['date_start'], '%Y-%m-%d')

        query_filters.append(['payment_date', '>=', filters['date_start']])

    if ('date_end' in filters):
        # Throw error if date_end does not match format '%Y-%m-%d'
        time.strptime(filters['date_end'], '%Y-%m-%d')

        query_filters.append(['payment_date', '<=', filters['date_end']])


    """
    --------------------------------------------
    Payments
    --------------------------------------------
    """
    # Get client payments.
    account_payments = models.execute_kw(db, uid, password,
        'account.payment', 'search_read',
        [query_filters],
        {'order': 'company_id, payment_date'}
    )

    company_payments = [];
    prev_company_id = None
    prev_company_name = None

    # Get the information that interests us, grouping by company.
    for account_payment in account_payments:
        company_id = account_payment['company_id'][0]
        company_name = account_payment['company_id'][1]

        if (prev_company_id and prev_company_id != company_id):
            # Add payment info to the respective company.
            for company_data in transactions_by_company:
                if (company_data['company_id'] == company_id):
                    company_data['payments'] = company_payments
                    break

            company_payments = []

        payment = {
            'id': account_payment['id'],
            'display_name': account_payment['display_name'],
            'payment_date': account_payment['payment_date'],
            'amount': account_payment['amount'],
            'state': account_payment['state'],
            'journal_id': account_payment['journal_id'],
            'payment_type': account_payment['payment_type']
        }

        company_payments.append(payment)
        prev_company_id = company_id
        prev_company_name = company_name

    # The algorithm of the previous loop does not add the last company_payments.
    # Add it if the loop was entered.

    if prev_company_id:
        # Add payment info to the respective company.
        for company_data in transactions_by_company:
            if (company_data['company_id'] == prev_company_id):
                company_data['payments'] = company_payments
                break

    """
    --------------------------------------------
    Balance calc for each company
    --------------------------------------------
    """

    account_acount_ids = models.execute_kw(db, uid, password,
        'account.account', 'search',
        [[['internal_type', '=', 'receivable']]]
    )

    # Get invoice lines.
    account_move_lines = models.execute_kw(db, uid, password,
        'account.move.line', 'search_read',
        [[
            ['partner_id', '=', client_id],
            ['date', '<', filters['date_start']],
            ['account_id', 'in', account_acount_ids]
        ]],
        {'order': 'company_id'}
    )

    prev_company_id = None
    current_balance = 0

    for account_move_line in account_move_lines:
        company_id = account_move_line['company_id'][0]

        if (prev_company_id and prev_company_id != company_id):
            # Add balance to the respective company.
            for company_data in transactions_by_company:
                if (company_data['company_id'] == company_id):
                    company_data['balance'] = current_balance
                    break

            current_balance = 0

        current_balance += account_move_line['balance']
        prev_company_id = company_id


    if prev_company_id:
        # Add balance to the respective company.
        for company_data in transactions_by_company:
            if (company_data['company_id'] == prev_company_id):
                company_data['balance'] = current_balance
                break


    return transactions_by_company