Esempio n. 1
0
class ProductTemplate(orm.Model):

    _inherit = 'product.template'

    _columns = {
        'date_start':
        fields.date("Start date"),
        'date_end':
        fields.date("End Date"),
        'period':
        fields.selection([('week', 'Week'), ('month', 'Month'),
                          ('year', 'Year')], 'Time Period'),
        'analysis_type':
        fields.selection([('average', 'Average'),
                          ('end_of_period', 'End of period')],
                         'Type of analysis'),
        'stock_graphic':
        fields.binary("Graph")
    }

    _defaults = {
        'date_start':
        lambda *a:
        (datetime.now() - relativedelta(months=6)).strftime('%Y-%m-%d'),
        'date_end':
        lambda *a: datetime.now().strftime('%Y-%m-%d'),
        'period':
        'month',
        'analysis_type':
        'average'
    }
Esempio n. 2
0
class custom_calendar_event(osv.osv):
    _name = "calendar.event"
    _inherit = 'calendar.event'


    @api.depends('x_categ_id','x_partner_id')
    def _compute_categ_id_char(self):
        self.x_categ_id_char = self.x_categ_id.name
        if self.x_categ_id_char and self.x_partner_id.display_name and self.x_partner_id.phone:
            self.name = self.x_categ_id_char+' : '+self.x_partner_id.display_name+', '+self.x_partner_id.phone
        elif self.x_categ_id_char and self.x_partner_id.display_name:
            self.name = self.x_categ_id_char+' : '+self.x_partner_id.display_name
        elif self.x_partner_id.display_name:
            self.name = self.x_partner_id.display_name
        elif self.x_categ_id_char:
            self.name = self.x_categ_id_char
        else:
  
            
    _columns = {
        'x_domicile': fields.boolean('A domicile'),
        'x_partner_id': fields.many2one('res.partner', 'Attendee', default=''),
        'x_categ_id': fields.many2one('calendar.event.type', 'Tags'),
        'x_categ_id_char': fields.char(compute='_compute_categ_id_char', default=''),
        'x_event_is_billed': fields.boolean('is_billed'),
        'x_event_is_printed': fields.boolean('is_printed'),

        # related field res.partner 
        # -------------------------
        'x_event_display_name' : fields.related('x_partner_id', 'display_name', type="char"),
        'x_event_name' : fields.related('x_partner_id', 'name', type="char"),
        'x_event_phone' : fields.related('x_partner_id', 'phone', type="char", default=''),
        'x_event_patient_prenom': fields.related('x_partner_id', 'x_patient_prenom', type="char"),
        'x_event_patient_sexe': fields.related('x_partner_id', 'x_patient_sexe', type="selection", selection=SEXE_SELECTION),
        'x_event_patient_cafat': fields.related('x_partner_id', 'x_patient_cafat', type="char"),
        'x_event_dob': fields.date(related='x_partner_id.dob'),
        'x_event_age' : fields.integer(related='x_partner_id.age'),
        'x_event_src_avatar' : fields.binary(related='x_partner_id.x_src_avatar'),
        'x_event_medecin_traitant': fields.char(related='x_partner_id.x_medecin_traitant'),
        ########## MEDICAL INFO ???
        # 'x_event_groupe_sang': fields.related('x_partner_id', 'x_groupe_sang', type="selection", selection=GRP_SANG_SELECTION),
        # 'x_event_taille': fields.float(related='x_partner_id.x_taille'),
        # 'x_event_poids': fields.float(related='x_partner_id.x_poids'),
        # 'x_event_IMC': fields.float(related='x_partner_id.x_IMC'),
        ##########
        
        
        # related field calendar_event_type 
        # -------------------------
        'x_event_codeActe': fields.char(related='x_categ_id.x_code_acte', size=8),
        'x_event_priceActe': fields.float(related='x_categ_id.x_price_acte', digits=(4,0)),
        # -------------------------
    }
    _default = {
        'x_domicile': False,
    }
Esempio n. 3
0
class uis_papl_apl(models.Model):
	_name ='uis.papl.apl'
	name = fields.Char()
	full_name=fields.Char()
	inv_num = fields.Char()
	bld_year =fields.Char(string="Building year")
	startexp_date = fields.Date(string="Start operations date")
	line_len=fields.Float(digits=(3,2))
	line_len_calc=fields.Float(digits=(6,2), compute='_apl_get_len')
	prol_max_len=fields.Float(digits=(2,2), compute='_apl_get_len')
	prol_med_len=fields.Float(digits=(2,2), compute='_apl_get_len')
	prol_min_len=fields.Float(digits=(2,2), compute='_apl_get_len')
	pillar_id=fields.One2many('uis.papl.pillar','apl_id', string ="Pillars")
	tap_ids=fields.One2many('uis.papl.tap', 'apl_id', string="Taps")
	sup_substation_id=fields.Many2one('uis.papl.substation', string="Supply Substation")
	scheme_image=fields.binary(string="Scheme", compute='_get_scheme_image')
class demo_xls_report_file(osv.osv_memory):
    _name = 'demo.xls.report.file'
    _description = 'PDF Reports for showing all disconnection,reconnection'

    _columns = {
        'file': fields.binary('File'),
        'file_name': fields.char('File Name', size=64),
        'name': fields.many2one('xls.report', 'Name'),
        'partner_id': fields.many2one('res.partner', 'Customer')
    }

    def default_get(self, cr, uid, fields, context=None):
        if context is None:
            context = {}
        res = super(demo_xls_report_file, self).default_get(cr, uid, fields, context=context)
        res.update({'file_name': 'Report.xls'})
        if context.get('file'):
            res.update({'file': context['file']})
        return res
Esempio n. 5
0
class upload_images(osv.osv):
    _name = 'upload_images.tutorial'
    _description = 'Tutorial image uploading'

    def _get_image(self, cr, uid, ids, name, args, context=None):
        result = dict.fromkeys(ids, False)
        for obj in self.browse(cr, uid, ids, context=context):
            result[obj.id] = tools.image_get_resized_images(obj.image)
        return result

    def _set_image(self, cr, uid, id, name, value, args, context=None):
        return self.write(cr,
                          uid, [id],
                          {'image': tools.image_resize_image_big(value)},
                          context=context)

    _columns = {
    'name': fields.char('Name', required=True, translate=True),
    'image': fields.binary("Image",
            help="This field holds the image used as image for our customers, limited to 1024x1024px."),
    'image_medium': fields.function(_get_image, fnct_inv=_set_image,
            string="Image (auto-resized to 128x128):", type="binary", multi="_get_image",
            store={
                'upload_images.tutorial': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
            },help="Medium-sized image of the category. It is automatically "\
                 "resized as a 128x128px image, with aspect ratio preserved. "\
                 "Use this field in form views or some kanban views."),
    'image_small': fields.function(_get_image, fnct_inv=_set_image,
            string="Image (auto-resized to 64x64):", type="binary", multi="_get_image",
            store={
                'upload_images.tutorial': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
            },
            help="Small-sized image of the category. It is automatically "\
                 "resized as a 64x64px image, with aspect ratio preserved. "\
                 "Use this field anywhere a small image is required."),
    }
Esempio n. 6
0
class ccg_travel_order_total_export(osv.osv_memory):  # orm.TransientModel
    _name = 'ccg.travel.order.total.export'

    _columns = {
        'data':
        fields.binary('File', readonly=True),
        'name':
        fields.char('Filename', size=255, readonly=True),
        'state':
        fields.selection((
            ('create', 'create'),
            ('get', 'get'),
        ),
                         default='create'),
        'delimiter':
        fields.selection((
            (',', ', (comma)'),
            (';', '; (semicolon)'),
            ('\t', '(tab)'),
        ),
                         default=';'),
        'quotation':
        fields.selection((
            ('"', '"'),
            ("'", "'"),
            ('none', '(none)'),
        ),
                         default='none'),
        'encoding':
        fields.selection((('utf-8', 'utf-8'), ('utf-8-sig', 'utf-8 with BOM'),
                          ("windows-1250", "windows-1250")),
                         default='utf-8'),
        'decimal':
        fields.selection((('.', '. (dot)'), (',', ', (comma)')), default=','),
    }

    _travel_order_name = ''

    def get_currency_code(self, cr, uid, currency_name, context=None):
        obj = self.pool.get('currency.mapping')
        ids = obj.search(cr,
                         uid, [('currency_name', '=', currency_name)],
                         context=context)
        currency_codes = obj.browse(cr, uid, ids, context=context)
        if currency_codes:
            return currency_codes[0].total_id
        else:
            return False

    def get_expense_id(self, cr, uid, ccg_product_id, context=None):
        obj = self.pool.get('expense.mapping')
        ids = obj.search(cr,
                         uid, [('product_id', '=', ccg_product_id)],
                         context=context)
        expenses = obj.browse(cr, uid, ids, context=context)
        if expenses:
            return expenses[0].total_id
        else:
            return False

    def get_transportation_type(self,
                                cr,
                                uid,
                                crm_transportation_id,
                                context=None):
        obj = self.pool.get('transportation.mapping')
        ids = obj.search(cr,
                         uid,
                         [('transportation_id', '=', crm_transportation_id)],
                         context=context)
        transportations = obj.browse(cr, uid, ids, context=context)
        if transportations:
            return transportations[0].total_id
        else:
            return False

    def get_employee_id(self,
                        cr,
                        uid,
                        company_id,
                        ccg_employee_id,
                        context=None):
        obj = self.pool.get('employee.mapping')
        ids = obj.search(cr,
                         uid, [('company_id', '=', company_id),
                               ('employee_id', '=', ccg_employee_id)],
                         context=context)
        employees = obj.browse(cr, uid, ids, context=context)
        if employees:
            return employees[0].total_id
        else:
            return False

    def get_responsible_person_id(self, cr, uid, company_id, context=None):
        obj = self.pool.get('responsible.person.mapping')
        ids = obj.search(cr,
                         uid, [('company_id', '=', company_id)],
                         context=context)
        responsible_persons = obj.browse(cr, uid, ids, context=context)
        if responsible_persons:
            return responsible_persons[0].total_id
        else:
            return False

    def _quotation(self):
        return self.form['quotation']

    def _delimiter(self):
        return self.form['delimiter']

    def _encoding(self):
        return self.form['encoding']

    def _decimal(self):
        return self.form['decimal']

    def _quoted(self, text):
        q = self._quotation()
        if q == 'none':
            return str(text)
        else:
            return '{1}{0}{1}'.format(text, q)

    def _trim(self, text):
        if text:
            s = text.replace('\n', ' ').replace(';', '.')
            return s
        else:
            return ""

    def _reformat_date(self, date):
        dd = date[8:10]
        mm = date[5:7]
        yyyy = date[0:4]
        return '{}.{}.{}'.format(dd, mm, yyyy)

    def _reformat_datetime(self, datetime_str, sec=False):
        fmt_in = '%Y-%m-%d %H:%M:%S'
        fmt_out = '%d.%m.%Y %H:%M:%S'
        t = datetime.strptime(datetime_str, fmt_in)
        localtime = timezone('UTC').localize(t).astimezone(
            timezone("Europe/Zagreb"))
        return localtime.strftime(fmt_out)

    def _document(self, cr, uid, travel_order, context=None):
        line = []
        # header - Vrijednost 1 obavezna u svakom retku
        line.append(self._quoted('1'))
        # datum_naloga (+)
        if travel_order.document_date:
            document_date = self._reformat_date(travel_order.document_date)
            document_datetime = '{} {}'.format(document_date,
                                               travel_order.create_date[-8:])
            line.append(document_datetime)
        else:
            raise Warning(
                _("Missing or invalid document date in travel order {} ({})!".
                  format(self._travel_order_name,
                         travel_order.employee_id.name)))
# datum_isplate (+)
        if travel_order.date_liquidation:
            date_liquidation = self._reformat_date(
                travel_order.date_liquidation)
            line.append(date_liquidation)
        else:
            raise Warning(
                _("Missing or invalid date liquidation in travel order {} ({})!"
                  .format(self._travel_order_name,
                          travel_order.employee_id.name)))
# sifra_zaposlenika_putnika
        employee_id = self.get_employee_id(cr, uid, travel_order.company_id.id,
                                           travel_order.employee_id.id)
        if employee_id:
            line.append(self._quoted(employee_id))
        else:
            raise Warning(
                _("Missing or invalid employee in travel order {}!".format(
                    self._travel_order_name)))
# sifra_zaposlenika_odobritelja
        responsible_person_id = self.get_responsible_person_id(
            cr, uid, travel_order.company_id.id)
        if responsible_person_id:
            line.append(self._quoted(responsible_person_id))
        else:
            raise Warning(
                _("Missing or invalid responsible person in travel order {} ({})!"
                  .format(self._travel_order_name,
                          travel_order.employee_id.name)))
# datum_i_vrijeme_odlaska
        date_from = self._reformat_datetime(travel_order.date_from)
        line.append(self._quoted(date_from))
        # datum_i_vrijeme_povratka
        date_to = self._reformat_datetime(travel_order.date_to)
        line.append(self._quoted(date_to))
        # pbr_mjesto_polaska
        departure_city_zip = travel_order.company_id.zip
        line.append(self._quoted(departure_city_zip))
        # pbr_mjesto_odrediste (*)
        #         city_destination = travel_order.dest_city.split(',')
        #         line.append(city_destination[0])
        if travel_order.partner_ids:
            destination_partner = travel_order.partner_ids[0]
            if destination_partner.zip:
                destination_city_zip = destination_partner.zip
            else:
                destination_city_zip = ''
        else:
            destination_city_zip = ''
        line.append(self._quoted(destination_city_zip))

        # opis_putovanja
        purpose = travel_order.purpose[:200] if travel_order.purpose else ""
        if not purpose:
            raise Warning(
                _("Missing purpose of travel order {} ({})!".format(
                    self._travel_order_name, travel_order.employee_id.name)))
        else:
            line.append(self._trim(purpose))
# tip_prijevozno_sredstvo
        depart_transportation_type = self.get_transportation_type(
            cr, uid, travel_order.depart_transportation[0].id)
        if depart_transportation_type:
            line.append(self._quoted(depart_transportation_type))
        else:
            raise Warning(
                _("Missing or invalid transportation type in travel order {} ({})!"
                  .format(self._travel_order_name,
                          travel_order.employee_id.name)))
# marka_i_regbr_vozila
        if travel_order.depart_vehicle_ids:
            vehicle_registration = travel_order.depart_vehicle_ids[0].name
        else:
            vehicle_registration = ''
        line.append(vehicle_registration)
        # pocetno_stanje_brojila
        if travel_order.itinerary_ids:
            odometer_start = travel_order.itinerary_ids[0].odometer_start
        else:
            odometer_start = '0'
        line.append(self._quoted(odometer_start))
        # odobreni_predujam
        advance_payment = travel_order.advance_payment
        line.append(self._quoted(locale.str(advance_payment)))
        # valuta_za_predujam
        if travel_order.currency_id:
            advance_currency_code = self.get_currency_code(
                cr, uid, travel_order.currency_id.name)
        else:
            advance_currency_code = ''

        if advance_currency_code:
            line.append(self._quoted(advance_currency_code))
        else:
            raise Warning(
                _("Missing or invalid currency for advance payment in travel order {} ({})!"
                  .format(self._travel_order_name,
                          travel_order.employee_id.name)))
# putno_izvjesce
        report = travel_order.other_data
        if not report:
            raise Warning(
                _("Missing travel order report (Other Data) in travel order {} ({})!"
                  .format(self._travel_order_name,
                          travel_order.employee_id.name)))
        else:
            line.append(self._trim(report))

        csv_row = self._delimiter().join(line)
        return csv_row

    def _allowances(self, cr, uid, allowances, travel_order, context=None):
        lines = []
        for allowance in allowances:
            line = []
            # Header - Vrijednost 2 obavezna u svakom retku
            line.append(self._quoted('2'))
            # sifra_drzave
            country_code = get_country_code(allowance.country_id.code)
            if country_code:
                line.append(self._quoted(country_code))
            else:
                raise Warning(
                    _("Missing or invalid currency for advance payment in travel order {} ({})!"
                      .format(self._travel_order_name,
                              travel_order.employee_id.name)))

# datum_i_vrijeme_izlaska
# TODO convert datetime fron UTC to local time!!!
            date_to = allowance.date_to
            line.append(self._reformat_datetime(date_to))
            data = self._delimiter().join(line)
            lines.append(data)
        csv_rows = '\n'.join(lines)
        return (csv_rows)

    def _expenses(self, cr, uid, expenses, travel_order, context=None):
        lines = []
        for expense in expenses:
            line = []
            # header - Vrijednost 3 obavezna u svakom retku
            line.append(self._quoted('3'))
            # vrsta_putnog_troska
            expense_type = self.get_expense_id(cr, uid, expense.product_id.id)
            if expense_type:
                line.append(self._quoted(expense_type))
            else:
                raise Warning(
                    _("Missing or invalid expense type for '{}' in travel order {} ({})!"
                      .format(expense.name, self._travel_order_name,
                              travel_order.employee_id.name)))
# oznaka_placeno
            paid = 1 if expense.journal_id.type == 'bank' else 0
            line.append(self._quoted(paid))  # nije plaćeno
            # tip_isplate_joppd
            line.append(self._quoted('0'))  #ostalo
            # opis_troska
            line.append(self._quoted(expense.name))
            # kolicina
            qty = expense.unit_quantity
            line.append(self._quoted(locale.str(qty)))
            # cijena
            price = expense.unit_amount
            line.append(self._quoted(locale.str(price)))
            # valuta
            currency_name = expense.currency_id.name
            currency_code = self.get_currency_code(cr, uid,
                                                   expense.currency_id.name)
            if currency_code:
                line.append(self._quoted(currency_code))
            else:
                raise Warning(
                    _("Missing or invalid currency for expense '{}' in travel order {} ({})!"
                      .format(expense.name, self._travel_order_name,
                              travel_order.employee_id.name)))
# tecaj
            currency_rate = expense.lcy_rate
            line.append(self._quoted(locale.str(currency_rate)))
            # oznaka_pdv
            line.append(self._quoted(''))

            data = self._delimiter().join(line)
            lines.append(data)

        csv_rows = '\n'.join(lines)
        return (csv_rows)

    def _itinerary_expenses(self,
                            cr,
                            uid,
                            itinerary_lines,
                            travel_order,
                            context=None):
        lines = []
        for itinerary in itinerary_lines:
            line = []
            # header - Vrijednost 3 obavezna u svakom retku
            line.append(self._quoted('3'))
            # vrsta_putnog_troska = 1 (kilomterina)
            line.append(self._quoted('1'))
            # oznaka_placeno
            line.append(self._quoted(0))  # nije unaprijed plaćeno
            # tip_isplate_joppd - za privatni auto = 4 Isplata u gotovini, za službeni = 0 - nije plaćeno
            if itinerary.vehicle_id.type == 'private':
                line.append(
                    self._quoted('4'))  # kilometrina se isplaćuje u gotovini
            else:  # službeni
                line.append(self._quoted('0'))  # kilometrina se ne isplaćuje
# opis_troska
            description = 'Kilometrina'
            line.append(self._quoted(description))
            # kolicina
            qty = itinerary.distance
            line.append(self._quoted(locale.str(qty)))
            # cijena
            #            print itinerary.vehicle_type.lower(), itinerary.vehicle_id.name, itinerary.vehicle_id.type
            if itinerary.vehicle_id.type == 'private':
                price = 2.0  #HRK/km
            else:
                price = 0.0
            line.append(self._quoted(locale.str(price)))
            # valuta
            currency_name = 'HRK'
            currency_code = self.get_currency_code(cr, uid, currency_name)
            line.append(self._quoted(currency_code))
            # tecaj
            currency_rate = 1.0
            line.append(self._quoted(locale.str(currency_rate)))
            # oznaka_pdv
            line.append(self._quoted(''))

            data = self._delimiter().join(line)
            lines.append(data)

        csv_rows = '\n'.join(lines)
        return (csv_rows)

    def _daily_allowance_expenses(self,
                                  cr,
                                  uid,
                                  daily_allowance_lines,
                                  travel_order,
                                  context=None):
        lines = []
        for allowance in daily_allowance_lines:
            if allowance.num_of_allowances:
                line = []
                # header - Vrijednost 3 obavezna u svakom retku
                line.append(self._quoted('3'))
                # vrsta_putnog_troska
                if allowance.currency_id.name == 'HRK':
                    expense_type = self._quoted('2')
                    description = 'Domaća dnevnica'
                else:
                    expense_type = self._quoted('3')
                    description = 'Inozemna dnevnica'
                line.append(expense_type)
                # oznaka_placeno
                line.append(self._quoted(0))  # nije plaćeno
                # tip_isplate_joppd
                line.append(self._quoted('4'))  # dnevnice
                # opis_troska
                line.append(self._quoted(description))
                # kolicina
                qty = allowance.num_of_allowances
                line.append(self._quoted(locale.str(qty)))
                # cijena
                #                 price = allowance.allowance_amount_total
                price = allowance.allowance_unit_amount
                line.append(self._quoted(locale.str(price)))
                # valuta
                currency_name = allowance.currency_id.name
                currency_code = self.get_currency_code(cr, uid, currency_name)
                line.append(self._quoted(currency_code))
                # tecaj
                currency_rate = allowance.lcy_rate
                line.append(self._quoted(locale.str(currency_rate)))
                # oznaka_pdv
                line.append(self._quoted(''))

                data = self._delimiter().join(line)
                lines.append(data)

        csv_rows = '\n'.join(lines)
        return (csv_rows)

    def _csv_lines(self, cr, uid, travel_orders, context=None):
        csv = []
        self._set_decimal_point(self._decimal())
        for to in travel_orders:
            self._travel_order_name = to.name
            # hr.travel.order
            document_csv = self._document(cr, uid, to, context)
            csv.append(document_csv)
            # daily.allowance.lines
            if to.daily_allowance_ids:
                allowances_csv = self._allowances(cr, uid,
                                                  to.daily_allowance_ids, to,
                                                  context)
                csv.append(allowances_csv)
            # hr.expense.line
            if to.expense_line_ids:
                expenses_csv = self._expenses(cr, uid, to.expense_line_ids, to,
                                              context)
                csv.append(expenses_csv)
            # append itinerrary to expenses hr.travel.opder.itinerary.lines
            if to.itinerary_ids:
                itinerary_csv = self._itinerary_expenses(
                    cr, uid, to.itinerary_ids, to, context)
                csv.append(itinerary_csv)
            # append daily allowances to expenses daily.allowance.lines
            if to.daily_allowance_ids:
                allowance_csv = self._daily_allowance_expenses(
                    cr, uid, to.daily_allowance_ids, to, context)
                csv.append(allowance_csv)

        self._set_decimal_point()  # reset decimal point to default
        return csv

    def _set_decimal_point(self, frm=''):
        if frm == '.':
            locale.setlocale(locale.LC_NUMERIC, 'en_US.utf8')
        elif frm == ',':
            locale.setlocale(locale.LC_NUMERIC, 'hr_HR.utf8')
        else:
            locale.setlocale(locale.LC_ALL, '')  # reset to system default

    def generate_csv(self, cr, uid, ids, context=None):

        if context is None:
            context = {}
        self.form = self.read(cr, uid, ids)[0]
        active_model = context.get('active_model', None)
        active_ids = context.get('active_ids', [])
        sorted_ids = self.pool.get(active_model).search(
            cr, uid, [('id', 'in', active_ids)], order='name', context=context)
        travel_orders = self.pool.get(active_model).browse(cr,
                                                           uid,
                                                           sorted_ids,
                                                           context=context)
        csv_lines = self._csv_lines(cr, uid, travel_orders, context)

        data = '\n'.join(csv_lines)
        if len(active_ids) == 1:
            # ima datoteke se sastoji od broja putnog naloga
            filename = 'travel_order_{}.csv'.format(
                travel_orders.name.replace('/', '_'))
        else:
            # ako ima više putnih naloga, ime datoteke ima ukupni broj putnih naloga
            filename = 'travel_order_{}.csv'.format(len(active_ids))

        self.write(
            cr,
            uid,
            ids, {
                'data': base64.encodestring(data.encode(self._encoding())),
                'name': filename,
                'state': 'get'
            },
            context=context)
        # ovaj dictionary sadrži podatke kao i record 'action_export_opportunity_for_ds_wizard' u xml-u
        # tako da po povratku iz ove metode opet otvori takav prozor
        return {
            'context': context,
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'ccg.travel.order.total.export',
            'res_id': ids[0],
            'view_id': False,
            'type': 'ir.actions.act_window',
            'target': 'new',
            'name': 'Export for TOTAL',
        }
class crm_lead_export_for_ds(osv.osv_memory): # orm.TransientModel
    _name = 'crm.lead.export.for.ds'
    
    _columns = {
        'data'      : fields.binary('File', readonly=True),
        'name'      : fields.char('Filename', size=32, readonly=True),
        'state'     : fields.selection((('choose', 'choose'), ('get', 'get'),)),
        'delimiter' : fields.selection(((',', ', (comma)'), (';', '; (semicolon)'), ('\t', '(tab)'),), default=','),
        'quotation' : fields.selection((('"', '"'), ("'", "'"), ('none', '(none)'),), default='"'),
        'encoding'  : fields.selection((('utf-8', 'utf-8'), ('utf-8-sig', 'utf-8 with BOM'), ("windows-1250", "windows-1250")), default='utf-8'),
        'decimal'   : fields.selection((('.', '(dot)'), (',', ', (comma)')), default='.'),
    }

    _ds_fields = ['CustomerName',       #A
                  'DSSiteID',           #B
                  'PartnerCustomerID',  #C
                  'CustomerDUNSNumber', #D
                  'CustomerVATNumber', #E
                  'CustomerRegistrationID', #F
                  'CustomerAddress1', #G
                  'CustomerAddress2', #H
                  'CustomerCity', #I
                  'CustomerCountry',#J
                  'CustomerStatePrefecture', #K
                  'CustomerZipPostcode', #L
                  'CustomerWebsiteHomepageURL', #M
                  'CustomerContactSalutation', #N
                  'CustomerContactFirstName', #O
                  'CustomerContactLastName', #P
                  'CustomerContactJobTitle', #Q
                  'CustomerContactTel', #R
                  'CustomerContactEmail', #S
                  'PartnerSalesRepFirstName', #T
                  'PartnerSalesRepLastName', # U
                  'PartnerSalesRepEmail', #V
                  'OpportunityLeadName', #W
                  'OpportunityLeadDescription', #X
                  'PartnerOpportunityID', #Y
                  'DSLeadID', #Z
#                  'CoMarketingYN', #  not in specification
                  'COMETCampaignCode', #AA
                  'CampaignName', #AB
                  'SalesStage', #AC
                  'ForecastCategory', #AD
                  'DomainofInterest', #AE
                  'LeadSource', #AF
                  'NextMilestone', #AG
                  'NextMilestoneDate', #AH
                  'CloseDate', #AI
                  'ReasonLost', #AJ
                  'ReasonWon', #AK
                  'ReasonWonLostComment', #AL
                  'IfLostWhoWon', #AM
                  'OfferName', # AN
                  'RevenueAmount', #AO
                  'RevenueCurrency', #AP
                  'RevenueType', #AQ
                  ]

    
    _field_mappings = { # 0-table, 1-field, 2-alias, 3-string, 4-active, 5-required
        'CustomerName'      : ('res_partner', 'name', 'partner_name', 'Customer', True, True ),
        'DSSiteID'          : ('res_partner', 'site_id', 'site_id', 'DSSiteID', True, False ),
        'HeadOfficeID'      : ('res_partner', 'head_office_id', 'head_office_id', 'HeadOfficeID', False, False ),
        'CustomerAddress1'  : ('res_partner', 'street', 'street', 'Address Street', True, True ),
        'CustomerAddress2'  : ('res_partner', 'street2', 'street2', 'Address Street2', True, False ),
        'CustomerCity'      : ('res_partner', 'city', 'city', 'City', True, True ),
        'CustomerCountry'   : ('res_country', 'name', 'country', 'Country', True, True ),
        'CustomerZipPostcode' : ('res_partner', 'zip', 'zip', 'ZIP', True, True ),
        'CustomerVATNumber' : ('res_partner', 'vat', 'vat', 'VAT', True, True ),
        'OfferName'         : ('ccg_offer_name', 'name', 'offer_name', 'Offer name', True, True ),
        'RevenueAmount'     : ('crm_lead', 'ds_expected_revenue', 'planned_revenue', 'Expected revenue for DS', True, True ),
        'RevenueCurrency'   : ('', "'EUR'", 'currency', 'Currency', True, True ),
        'PartnerOpportunityID' : ('crm_lead', 'lead_ref_no', 'opportunity_id', 'Opportunity ID', True, True ),
        'CCGSalesStage'        : ('crm_case_stage', 'name', 'ccg_sales_stage', 'CCG Sales stage', True, True ),
        'SalesStage'        : ('', "''", 'sales_stage', 'Sales stage', True, True ),
        'ForecastCategory'  : ('', "''", 'forecast_category', 'Forecast category', True, True ),
        'CloseDate'         : ('crm_lead', 'date_deadline', 'close_date', 'Expected closing date', True, True ),
        'RevenueType'       : ('crm_lead', 'revenue_type', 'revenue_type', 'Revenue type', True, True ),
        'CustomerContactName'       : ('partner_contact', 'name', 'contact_name', "Customer's Contact Person Name", False, False),
        'CustomerContactFirstName'  : ('', "''", 'contact_first_name', "Customer's Contact Person First Name", True, True ),
        'CustomerContactLastName'   : ('', "''", 'contact_last_name', "Customer's Contact Person Last Name", True, True ),
        'CustomerContactEmail'  : ('partner_contact', 'email', 'contact_email', "Customer's Contact Email", True, True ),
        'DSLeadID'              : ('crm_lead', 'ds_lead_id', 'ds_lead_id', 'DS Lead ID', True, False ),
        'COMETCampaignCode'     : ('crm_lead', 'comet_campaign_code', 'comet_campaign_code', 'COMET Campaign Code', True, False ),
        'CampaignName'          : ('crm_lead', 'campaign_name', 'campaign_name', 'Campaign Name', True, False ),
        'NextMilestone'         : ('crm_lead', 'next_milestone', 'next_milestone', 'Next Milestone', True, False ),
        'PartnerSalesRepName'       : ('sales', 'name', 'partner_sales_name', "Partner's Salesman", False, False),
        'PartnerSalesRepFirstName'  : ('', "''", 'partner_sales_first_name', "Partner's Salesman First Name", True, True ),
        'PartnerSalesRepLastName'   : ('', "''", 'partner_sales_last_name', "Partner's Salesman Last Name", True, True ),
        'PartnerSalesRepEmail'      : ('sales', 'email', 'partner_sales_email', "Partner's Salesman Email", True, True ),
        'OpportunityLeadName'       : ('',"crm_lead.name || ' [' || crm_lead.lead_ref_no || ']'",'opportunity_name', "Opportunity name", True, True ),
        'Management Assessment'     : ('crm_lead','management_assessment','management_assessment','management assessment',  False, False ),
        'ReasonLost'                : ('crm_lost_reason','name','lost_reason','Lost Reason', True, False ),
     }

    """ DS Sales stages
    Closed/Lost
    Closed/Won
    1-Sales Lead
    2-Validate Opportunity
    3-Establish Value
    4-Reach Agreement
    """
        
    """ DS Forecast categories:
    Upside
    Commit
    Safe
    Won
    Lost
    """
    
    _stage_mapping = {
        'New':              ('1-Sales Lead',            'Upside'),
        'Validation' :      ('2-Validate Opportunity',  'Upside'), 
        'Establish value' : ('3-Establish Value',       'Upside'),
        'Negotiation' :     ('3-Establish Value',       'Commit'),
        'Reach Agreement':  ('4-Reach Agreement',       'Safe'),
        'Won' :             ('Closed/Won',              'Won'),
        'Lost' :            ('Closed/Lost',             'Lost'),
        'Sleeping' :        ('2-Validate Opportunity',  'Upside'),
        }

    def default_get(self, cr, uid, fields, context=None):
        res = super(crm_lead_export_for_ds, self).default_get(cr, uid, fields, context=context)
        res['state'] = 'choose'
        return res

    def map_stage(self, cr, uid, row, context=None):
        sales_stage = row['ccg_sales_stage']
        new_stage = self._stage_mapping[sales_stage][0]
        if not new_stage:
            raise Warning(_("Cannot export opportunity which is in state '{}'!".format(sales_stage)))
         
        forecast_category = row['ccg_sales_stage']
        new_forecast_category = self._stage_mapping[forecast_category][1]
        row.update({'sales_stage':new_stage, 'forecast_category':new_forecast_category})
        return row
    
    def split_contact_name(self, cr, uid, row, context=None):
        contact_name = row['contact_name']
        if contact_name:
            names = contact_name.split()
            first_name = names[0]
            last_name = " ".join([ln for ln in names[1:] if ln])
        else:
            opportunity_id = row['opportunity_id']
            field_label = self._field_mappings['CustomerContactName'][3]
            raise osv.except_osv(_('Export Error!'), _('Missing field "{}" in opportunity "{}"!'.format(field_label, opportunity_id)))
        row.update({'contact_first_name':first_name, 'contact_last_name':last_name})
        return row

    def split_salesman_name(self, cr, uid, row, context=None):
        partner_sales_name = row['partner_sales_name']
        if partner_sales_name:
            names = partner_sales_name.split()
            first_name = names[0]
            last_name = " ".join([ln for ln in names[1:] if ln])
        else:
            opportunity_id = row['opportunity_id']
            field_label = self._field_mappings['PartnerSalesRepName'][3]
            raise osv.except_osv(_('Export Error!'), _('Missing field "{}" in opportunity "{}"!'.format(field_label, opportunity_id)))
        row.update({'partner_sales_first_name':first_name, 'partner_sales_last_name':last_name})
        return row

    def management_assessment_into_next_milestone(self, cr, uid, row, context=None):
        print row
        next_milestone = row['next_milestone'] or ''
        management_assessment = row['management_assessment'] if row['ccg_sales_stage']=='Negotiation' else ''
        value = ' - '.join([l for l in [ management_assessment, next_milestone] if l])
        row.update({'next_milestone': value})
        print row
        return row
    
    def _quotation(self):
        return self.form['quotation']
 
    def _delimiter(self):
        return self.form['delimiter']
     
    def _encoding(self):
        return self.form['encoding']
    
    def _decimal(self):
        return self.form['decimal']

    def _quoted(self, text):
        q = self._quotation()
        not_null_text = text if text else ''
        if q=='none':
            return str(not_null_text)
        else:
            return '{1}{0}{1}'.format(not_null_text, q)

    def _get_opportunity_fields(self, cr, uid, context=None):
        ids = context.get('active_ids', [])
        fields = []
        for key in self._field_mappings.keys():
            value = self._field_mappings[key]
            table = value[0]
            field = value[1]
            alias = value[2] or field
            if table:
                fields.append('{}.{} as {}'.format(table, field, alias))
            else:
                fields.append('{} as {}'.format(field, alias))
        
        sql = '''
        SELECT {}
        FROM crm_lead 
        LEFT JOIN res_partner ON (crm_lead.partner_id=res_partner.id)
        LEFT JOIN crm_case_stage ON (crm_lead.stage_id = crm_case_stage.id) 
        LEFT JOIN res_country ON (res_partner.country_id = res_country.id)
        LEFT JOIN ccg_offer_name ON (crm_lead.offer_name_id = ccg_offer_name.id)
        LEFT JOIN res_partner partner_contact ON (crm_lead.contact_name_id=partner_contact.id)
        LEFT JOIN res_users users ON (res_partner.user_id=users.id)
        LEFT JOIN res_partner sales ON (users.partner_id=sales.id)
        LEFT JOIN crm_lost_reason ON (crm_lead.lost_reason_id = crm_lost_reason.id)
        WHERE crm_lead.id in ({})
        '''.format(','.join([f for f in fields ]), ','.join([str(i) for i in ids]))
        print sql
        cr.execute(sql)
        return  cr.dictfetchall()

    def _csv_lines(self, cr, uid, context=None):
        data = self._get_opportunity_fields(cr, uid, context)
        lines = []
        for row_original in data:
            line = []
            opportunity_id = row_original['opportunity_id']
            row = self.map_stage(cr, uid, row_original, context)
            row = self.split_contact_name(cr, uid, row, context)
            row = self.split_salesman_name(cr, uid, row, context)
            row = self.management_assessment_into_next_milestone(cr, uid, row, context)
            print row
            for ds_field_name in self._ds_fields:
                value = self._field_mappings.get(ds_field_name, False)
                field_value_strnig = ''
                if value:
                    if value[4]: # is active
                        crm_field_name = value[2] or value[1]
                        field_value = row[crm_field_name]
                        print crm_field_name, ':', field_value
                        required = value[5]
                        field_label = value[3]
                        if not field_value:
                            if required:
                                raise osv.except_osv(_('Export Error!'), _('Missing field "{}" in opportunity "{}"!'.format(field_label, opportunity_id)))
#                            else:
#                                raise Warning (_('Warning!'), _('Field "{}" in opportunity "{}" is missing but needed in some situations!'.format(field_label, opportunity_id)))
                        if crm_field_name == 'close_date':
                            field_value = '{}.{}.{}'.format(field_value[8:10],field_value[5:7],field_value[0:4])
                        field_value_strnig = self._quoted(field_value)
                line.append(field_value_strnig)
            csv_line = self._delimiter().join(line)   
            lines.append(csv_line)
        if len(lines) > 1:
            csv_file_name ='opportunities.csv'
        else:
            csv_file_name = 'opportunity_{}.csv'.format(opportunity_id)
        return '\n'.join(lines), csv_file_name
    
    def generate_csv(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        self.form = self.read(cr, uid, ids)[0]
#        header = self._delimiter().join([k for k in self._ds_fields if self._field_mappings[k][4]])
        header = self._delimiter().join(self._ds_fields)
        lines, filename = self._csv_lines(cr, uid, context)
        if header and lines:
            data = header + '\n' + lines
        self.write(cr, uid, ids, {'data': base64.encodestring(data.encode(self._encoding())), 
                                  'name':filename, 
                                  'state':'get'}, context=context)
        # ovaj dictionary sadrži podatke kao i record 'action_export_opportunity_for_ds_wizard' u xml-u 
        # tako da po povratku iz ove metode opet otvori takav prozor
        return {
        'context': context,
        'view_type': 'form',
        'view_mode': 'form',
        'res_model': 'crm.lead.export.for.ds',
        'res_id': ids[0],
        'view_id': False,
        'type': 'ir.actions.act_window',
        'target': 'new',
        'name' : 'Export for DS portal',
         }
class crm_logika_export(osv.osv_memory):  # orm.TransientModel
    _name = 'crm.logika.export'

    _columns = {
        'data':
        fields.binary('File', readonly=True),
        'name':
        fields.char('Filename', size=255, readonly=True),
        'state':
        fields.selection((
            ('create', 'create'),
            ('get', 'get'),
        ),
                         default='create'),
        'delimiter':
        fields.selection((
            (',', ', (comma)'),
            (';', '; (semicolon)'),
            ('\t', '(tab)'),
        ),
                         default=';'),
        'quotation':
        fields.selection((
            ('"', '"'),
            ("'", "'"),
            ('none', '(none)'),
        ),
                         default='none'),
        'encoding':
        fields.selection((('utf-8', 'utf-8'), ('utf-8-sig', 'utf-8 with BOM'),
                          ("windows-1250", "windows-1250")),
                         default='utf-8'),
        'decimal':
        fields.selection((('.', '. (dot)'), (',', ', (comma)')), default=','),
    }

    def _quotation(self):
        return self.form['quotation']

    def _delimiter(self):
        return self.form['delimiter']

    def _encoding(self):
        return self.form['encoding']

    def _decimal(self):
        return self.form['decimal']

    def _quoted(self, text):
        q = self._quotation()
        if q == 'none':
            return str(text)
        else:
            return '{1}{0}{1}'.format(text, q)

    def _reformat_date(self, date):
        dd = date[8:10]
        mm = date[5:7]
        yyyy = date[0:4]
        return '{}.{}.{}'.format(dd, mm, yyyy)

    def _document(self, cr, uid, id, context=None):
        active_model = context.get('active_model', None)
        active_id = id
        invoice_obj = self.pool.get(active_model).browse(cr,
                                                         uid,
                                                         id,
                                                         context=context)
        invoice = invoice_obj.browse(active_id)

        # A: Header - Vrijednost 1 obavezna u svakom retku
        invoice_data = [self._quoted('1')]
        # B: Alt. broj - Alternativni broj računa (broj za Total se generira automatski)
        invoice_number = invoice.internal_invoice_number
        invoice_data.append(self._quoted(invoice_number))
        # C: Datum - Datum računa
        invoice_data.append(
            self._quoted(self._reformat_date(invoice.date_invoice)))
        # D: Datum isporuke - Datum isporuke tj- datum otpreme
        #        invoice_data.append(self._quoted(self._reformat_date(invoice.date_delivery))) # neće se više koristiti
        invoice_data.append(self._quoted(''))  # šalje se prazno polje
        # E: Rok plaćanja - Rok plaćanja u danima
        date_format = '%Y-%m-%d'
        dd = datetime.strptime(invoice.date_due, date_format)
        di = datetime.strptime(invoice.date_invoice, date_format)
        date_delta = dd - di
        if date_delta.days < 0:
            raise Warning(
                _("Wrong date in invoice {0}. Due date ({1:%d.%m.%Y}) is prior to the invoice date ({2:%d.%m.%Y})"
                  .format(invoice_number, dd, di)))
        invoice_data.append(self._quoted(date_delta.days))
        # F: Valuta - Šifra valute za račun (191 = HRK itd.)
        currency_code = {
            'EUR': '978',
            'HRK': '191',
            'USD': '840'
        }.get(invoice.currency_id.name)
        invoice_data.append(self._quoted(currency_code))
        # G: Tečaj - Tečaj računa (za HRK upisati iznos 1)
        invoice_data.append(self._quoted(locale.str(invoice.lcy_rate)))
        # H: Uvodni tekst - Uvodni tekst računa (1000 znakova)
        invoice_data.append(self._quoted('Invoice description'))
        # I: Šifra_prodavača - Ne koristimo
        invoice_data.append(self._quoted(''))
        # J: Tip računa - 1 = redovni, 2 = avansni
        invoice_type = 2 if invoice.advance_payment else 1
        invoice_data.append(self._quoted(invoice_type))

        data = self._delimiter().join(invoice_data)
        partner_id = invoice.partner_id
        lines = invoice.invoice_line
        return (data, invoice_number, invoice.partner_id, lines)

    def _partner(self, cr, uid, partner, context=None):
        fields = []
        # A: Header - Vrijednost 2 obavezna u svakom retku
        partner_data = [self._quoted('2')]
        # B: OIB - OIB partnera prema koje će se pronaći šifra partnera
        partner_data.append(self._quoted(partner.vat.replace('HR', '')))
        # C: Naziv partnera - Naziv partnera (opcionalno)
        partner_data.append(self._quoted(partner.name))
        # D: Poštanski broj - Poštanski broj mjesta partnera (opcionalno)
        partner_data.append(self._quoted(partner.zip))
        # E: Naziv mjesta - Naziv mjesta partnera (opcionalno)
        partner_data.append(self._quoted(partner.city))
        # F: Šifra države - Šifra države partnera (opcionalno)
        partner_data.append(self._quoted(''))
        # G: Adresa - Adresa i kućni broj partnera (opcionalno)
        partner_data.append(self._quoted(partner.street))

        data = self._delimiter().join(partner_data)
        return (data, partner.name)

    def _items(self, cr, uid, lines, context=None):
        data = []
        for line in lines:
            # A: Header - Vrijednost 3 obavezna u svakom retku
            line_data = [self._quoted('3')]
            # B: Kataloški broj - Kataloški broj artikla - KONTO PRODUKTA će biti šifra!!!
            line_data.append(self._quoted(line.account_id.code[4:]))
            # C: Količina - Prodana količina artikla
            line_data.append(self._quoted(locale.str(line.quantity)))
            # D: Oznaka stope PDV - 0 = 0%, 2 = 10%, 4 = 25%, 5 = 5%
            tax_percent = line.invoice_line_tax_id[0].amount * 100
            tax_code = {
                0: '0',
                10: '2',
                25: '4',
                5: '5'
            }.get(tax_percent, '-1')
            line_data.append(self._quoted(tax_code))
            # E: Oznaka oslobođ. PDV - Ako nema oslobođenja PDV ostaviti prazno
            line_data.append(self._quoted(''))
            # F: Cijena - Veleprodajna cijena prodanog artikla
            line_data.append(self._quoted(locale.str(line.price_unit)))
            # G: Rabat - Odobreni rabat
            line_data.append(self._quoted(locale.str(line.discount)))
            # H: Opis artikla - Dodatni opis za ovu stavku ako postoji (ako je prefix # opis pregazi naziv iz baze artikala)
            line_data.append(self._quoted('#' + line.product_id.name))
            line_csv = self._delimiter().join(line_data)
            data.append(line_csv)

        return '\n'.join(data)

    def _csv_lines(self, cr, uid, ids, context=None):
        csv = []
        for id in ids:
            (invoice_data, invoice_number, partner_id,
             lines) = self._document(cr, uid, id, context)
            csv.append(invoice_data)
            (partner_data,
             partner_name) = self._partner(cr, uid, partner_id, context)
            csv.append(partner_data)
            csv.append(self._items(cr, uid, lines, context))

        return (csv, invoice_number, partner_name)

    def _set_decimal_point(self, frm=''):
        if frm == '.':
            locale.setlocale(locale.LC_NUMERIC, 'en_US.utf8')
        elif frm == ',':
            locale.setlocale(locale.LC_NUMERIC, 'hr_HR.utf8')
        else:
            locale.setlocale(locale.LC_ALL, '')  # reset to system default

    def _sort_ids_by_invoice_number(self, cr, uid, ids, context=None):
        active_model = context.get('active_model', None)
        sorted_ids = self.pool.get(active_model).search(
            cr,
            uid, [('id', 'in', ids)],
            order='internal_invoice_number',
            context=context)
        return sorted_ids

    def generate_csv(self, cr, uid, ids, context=None):
        if context is None:
            context = {}

        self.form = self.read(cr, uid, ids)[0]
        active_ids = context.get('active_ids', [])
        sorted_ids = self._sort_ids_by_invoice_number(cr,
                                                      uid,
                                                      active_ids,
                                                      context=context)
        self._set_decimal_point(self._decimal())
        (csv, invoice, partner) = self._csv_lines(cr, uid, sorted_ids, context)
        self._set_decimal_point()  # reset decimal point to default

        data = '\n'.join(csv)
        if len(active_ids) == 1:
            # ima datoteke se sastoji od broja računa i prvih 10 slova partnera
            filename = 'invoice_{}_{}.csv'.format(
                invoice,
                partner.replace('.', '_').replace(' ', '_')[:10])
        else:
            # ako ima više računa, ime datoteke ima ukupni broj računa
            filename = 'invoices_{}.csv'.format(len(active_ids))

        self.write(
            cr,
            uid,
            ids, {
                'data': base64.encodestring(data.encode(self._encoding())),
                'name': filename,
                'state': 'get'
            },
            context=context)
        # ovaj dictionary sadrži podatke kao i record 'action_export_opportunity_for_ds_wizard' u xml-u
        # tako da po povratku iz ove metode opet otvori takav prozor
        return {
            'context': context,
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'crm.logika.export',
            'res_id': ids[0],
            'view_id': False,
            'type': 'ir.actions.act_window',
            'target': 'new',
            'name': 'Export for TOTAL',
        }
Esempio n. 9
0
class custom_res_partner(osv.osv):
    _name = "res.partner"
    _inherit = 'res.partner'

    def _x_opportunity_meeting_count(self,
                                     cr,
                                     uid,
                                     ids,
                                     field_name,
                                     arg,
                                     context=None):
        res = dict(
            map(
                lambda x: (x, {
                    'x_opportunity_count': 0,
                    'x_meeting_count': 0
                }), ids))
        # the user may not have access rights for opportunities or meetings
        try:
            for partner in self.browse(cr, uid, ids, context):
                if partner.is_company:
                    operator = 'child_of'
                else:
                    operator = '='
                opp_ids = self.pool['crm.lead'].search(
                    cr,
                    uid, [('partner_id', operator, partner.id),
                          ('type', '=', 'opportunity'),
                          ('probability', '<', '100')],
                    context=context)
                res[partner.id] = {
                    'x_opportunity_count': len(opp_ids),
                    'x_meeting_count': len(partner.x_meeting_ids),
                }
        except:
            pass
        return res

    ##########           MEDICAL INFO ???
    # @api.one
    # @api.depends('x_poids','x_taille')
    # def _compute_IMC(self):
    #     if self.x_taille == 0:
    #         self.x_IMC = '0'
    #     else:
    #         self.x_IMC = self.x_poids / ((self.x_taille / 100) * (self.x_taille / 100))
    ##########

    @api.one
    @api.depends('name', 'x_patient_prenom')
    def _compute_display_name(self):
        if self.x_patient_prenom == '':
            names = [self.name]
        else:
            names = [self.name, self.x_patient_prenom]
        self.display_name = ' '.join(filter(None, names))


    _columns = {
        'partner_id' : fields.many2one('res.partner','Customer', default=lambda self: self.env.user.partner_id),
        'display_name' : fields.char(string='Name', compute='_compute_display_name'),
        'x_patient_prenom': fields.char('Prénom', size=16),
        'x_patient_sexe': fields.selection(SEXE_SELECTION, string='Sexe'),
        'x_convention_type': fields.selection(CONVENTION_SELECTION, string='Protection'),
        'x_patient_cafat': fields.char(string='Numéro assuré', size=8, help='Numéro CAFAT du patient'),
        'x_is_pro': fields.boolean('is_pro_bool', help="Check if the contact is a professional, otherwise it is a patient"),
        'x_compte_type': fields.selection(selection=[('patient', 'Patient'), ('pro', 'Pro')], string='Type compte'),
        'dob': fields.date('Date de naissance'),
        'age' : fields.integer('Age'),
        'x_src_avatar' : fields.binary("x_src_avatar", attachment=True,
            help="This field holds the image used as avatar for this contact, limited to 1024x1024px"),
        'x_medecin_traitant': fields.char('Médecin traitant', size=32),
        ##########           MEDICAL INFO ???
        # 'x_groupe_sang': fields.selection(GRP_SANG_SELECTION, string='Groupe sang.'),
        # 'x_taille': fields.float('Taille (cm)',digits=(4,6)),
        # 'x_poids': fields.float('Poids (kg)',digits=(4,6)),
        # 'x_IMC': fields.float(string='IMC', compute='_compute_IMC',digits=(4,6)),
        ##########

        # Reprise de CRM
        'x_opportunity_ids': fields.one2many('crm.lead', 'partner_id',\
            'Opportunities', domain=[('type', '=', 'opportunity')]),
        'x_meeting_ids': fields.one2many('calendar.event', 'x_partner_id',
            'Meetings'),
        'x_opportunity_count': fields.function(_x_opportunity_meeting_count, string="Opportunity", type='integer', multi='opp_meet'),
        'x_meeting_count': fields.function(_x_opportunity_meeting_count, string="# Meetings", type='integer', multi='opp_meet'),
    }

    def redirect_partner_form(self, cr, uid, partner_id, context=None):
        search_view = self.pool.get('ir.model.data').get_object_reference(
            cr, uid, 'base', 'view_res_partner_filter')

    _order = 'name, x_patient_prenom'

    _default = {
        'x_patient_sexe': 'masculin',
        'x_patient_cafat': '',
        'x_is_pro': False,
        'x_compte_type': 'pro',
        'x_medecin_traitant': ' ',
        'x_groupe_sang': '',
        ##########           MEDICAL INFO ???
        # 'x_taille': '0,1',
        # 'x_poids': '0,1',
        ##########
    }

    _sql_constraints = []

    #############            Changement Praticien <-> Patient            #############
    @api.multi
    def _on_change_compte_type(self, x_compte_type):
        return {'value': {'x_is_pro': x_compte_type == 'pro'}}

    #############            Changement de date de naissance            #############
    @api.onchange('dob')
    def _onchange_getage_id(self, cr, uid, ids, dob, context=None):
        current_date = datetime.now()
        current_year = current_date.year
        birth_date = parser.parse(dob)
        current_age = current_year - birth_date.year

        val = {'age': current_age}
        return {'value': val}

    #############            Donne l'image a utiliser comme avatar            #############
    #############    MODIFY ??? !!!
    @api.model
    def _get_default_avatar(self, vals):
        if getattr(threading.currentThread(), 'testing',
                   False) or self.env.context.get('install_mode'):
            return False
        # ------------------ CABINET
        if self.is_company == True:
            img_path = openerp.modules.get_module_resource(
                'AlloDoc', 'static/src/img', 'company_image.png')
        elif self.x_compte_type == 'pro':
            if self.x_patient_sexe == 'feminin':
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_medecin_femme.png')
            else:
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_medecin_homme.png')
        # ------------------ PATIENTS
        #----------------------- Adultes
        elif self.age > 18:
            if self.x_patient_sexe == 'feminin':
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_femme.png')
            else:
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_homme.png')
        #----------------------- Enfants
        elif self.age > 2:
            if self.x_patient_sexe == 'feminin':
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_fille.png')
            else:
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_garcon.png')
        #----------------------- Bebes
        elif self.age <= 2:
            if self.x_patient_sexe == 'feminin':
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_bebe_f.png')
            else:
                img_path = openerp.modules.get_module_resource(
                    'AlloDoc', 'static/src/img', 'avatar_bebe_g.png')
        #----------------------- Default
        else:
            img_path = openerp.modules.get_module_resource(
                'AlloDoc', 'static/src/img', 'avatar_default.png')

        with open(img_path, 'rb') as f:
            x_src_avatar = f.read()

        # return img_avatar
        return tools.image_resize_image_big(x_src_avatar.encode('base64'))

    def name_get(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        if isinstance(ids, (int, long)):
            ids = [ids]
        res = []
        for record in self.browse(cr, uid, ids, context=context):
            name = record.display_name or ''
            if record.parent_id and not record.is_company:
                if not name and record.type in [
                        'invoice', 'delivery', 'other'
                ]:
                    name = dict(
                        self.fields_get(
                            cr, uid, ['type'],
                            context=context)['type']['selection'])[record.type]
                name = "%s, %s" % (record.parent_name, name)
            if context.get('show_address_only'):
                name = self._display_address(cr,
                                             uid,
                                             record,
                                             without_company=True,
                                             context=context)
            if context.get('show_address'):
                name = name + "\n" + self._display_address(
                    cr, uid, record, without_company=True, context=context)
            name = name.replace('\n\n', '\n')
            name = name.replace('\n\n', '\n')
            if context.get('show_email') and record.email:
                name = "%s <%s>" % (name, record.email)
            if context.get('html_format'):
                name = name.replace('\n', '<br/>')
            res.append((record.id, name))
        return res

    # Need to write these lines twice to get result I excepted...
    # if not, at save, avatar is not updated with value filled in form (_get_default_avatar),
    # but with values previously stored in DB
    @api.multi
    def write(self, vals):

        vals['x_src_avatar'] = self._get_default_avatar(vals)
        result = super(custom_res_partner, self).write(vals)
        vals['x_src_avatar'] = self._get_default_avatar(vals)
        result = super(custom_res_partner, self).write(vals)

        return result