class HeaderImage(osv.osv): """Logo allows you to define multiple logo per company""" _name = "ir.header_img" _columns = { 'company_id' : fields.many2one('res.company', 'Company'), 'img' : fields.binary('Image', attachment=True), 'name' : fields.char('Name', required =True, help="Name of Image"), 'type' : fields.char('Type', required =True, help="Image type(png,gif,jpeg)") }
class test_converter(orm.Model): _name = 'web_editor.converter.test' # disable translation export for those brilliant field labels and values _translate = False _columns = { 'char': fields.char(), 'integer': fields.integer(), 'float': fields.float(), 'numeric': fields.float(digits=(16, 2)), 'many2one': fields.many2one('web_editor.converter.test.sub'), 'binary': fields.binary(), 'date': fields.date(), 'datetime': fields.datetime(), 'selection': fields.selection([ (1, "réponse A"), (2, "réponse B"), (3, "réponse C"), (4, "réponse D"), ]), 'selection_str': fields.selection( [ ('A', "Qu'il n'est pas arrivé à Toronto"), ('B', "Qu'il était supposé arriver à Toronto"), ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"), ('D', "La réponse D"), ], string= u"Lorsqu'un pancake prend l'avion à destination de Toronto et " u"qu'il fait une escale technique à St Claude, on dit:"), 'html': fields.html(), 'text': fields.text(), }
class restaurant_floor(osv.osv): _name = 'restaurant.floor' _columns = { 'name': fields.char('Floor Name', required=True, help='An internal identification of the restaurant floor'), 'pos_config_id': fields.many2one('pos.config', 'Point of Sale'), 'background_image': fields.binary( 'Background Image', attachment=True, help= 'A background image used to display a floor layout in the point of sale interface' ), 'background_color': fields.char( 'Background Color', help= 'The background color of the floor layout, (must be specified in a html-compatible format)' ), 'table_ids': fields.one2many('restaurant.table', 'floor_id', 'Tables', help='The list of tables in this floor'), 'sequence': fields.integer('Sequence', help='Used to sort Floors'), } _defaults = { 'sequence': 1, 'background_color': 'rgb(210, 210, 210)', } def set_background_color(self, cr, uid, id, background, context=None): self.write(cr, uid, [id], {'background_color': background}, context=context)
class xml_decl(osv.TransientModel): """ Intrastat XML Declaration """ _name = "l10n_be_intrastat_xml.xml_decl" _description = 'Intrastat XML Declaration' def _get_company_id(self, cr, uid, context=None): return self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id def _get_def_monthyear(self, cr, uid, context=None): td = datetime.strptime( fields.date.context_today(self, cr, uid, context=context), tools.DEFAULT_SERVER_DATE_FORMAT).date() return td.strftime('%Y'), td.strftime('%m') def _get_def_month(self, cr, uid, context=None): return self._get_def_monthyear(cr, uid, context=context)[1] def _get_def_year(self, cr, uid, context=None): return self._get_def_monthyear(cr, uid, context=context)[0] _columns = { 'name': fields.char('File Name'), 'month': fields.selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'), ('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'), ('10', 'October'), ('11', 'November'), ('12', 'December')], 'Month', required=True), 'year': fields.char('Year', size=4, required=True), 'company_id': fields.many2one('res.company', 'Company', required=True), 'arrivals': fields.selection([('be-exempt', 'Exempt'), ('be-standard', 'Standard'), ('be-extended', 'Extended')], 'Arrivals', required=True), 'dispatches': fields.selection([('be-exempt', 'Exempt'), ('be-standard', 'Standard'), ('be-extended', 'Extended')], 'Dispatches', required=True), 'file_save': fields.binary('Intrastat Report File', readonly=True), 'state': fields.selection([('draft', 'Draft'), ('download', 'Download')], string="State"), } _defaults = { 'arrivals': 'be-standard', 'dispatches': 'be-standard', 'name': 'intrastat.xml', 'company_id': _get_company_id, 'month': _get_def_month, 'year': _get_def_year, 'state': 'draft', } def _company_warning(self, cr, uid, translated_msg, context=None): """ Raise a error with custom message, asking user to configure company settings """ xmlid_mod = self.pool['ir.model.data'] action_id = xmlid_mod.xmlid_to_res_id(cr, uid, 'base.action_res_company_form') raise exceptions.RedirectWarning( translated_msg, action_id, _('Go to company configuration screen')) def create_xml(self, cr, uid, ids, context=None): """Creates xml that is to be exported and sent to estate for partner vat intra. :return: Value for next action. :rtype: dict """ decl_datas = self.browse(cr, uid, ids[0]) company = decl_datas.company_id if not (company.partner_id and company.partner_id.country_id and company.partner_id.country_id.id): self._company_warning(cr, uid, _('The country of your company is not set, ' 'please make sure to configure it first.'), context=context) kbo = company.company_registry if not kbo: self._company_warning( cr, uid, _('The registry number of your company is not set, ' 'please make sure to configure it first.'), context=context) if len(decl_datas.year) != 4: raise exceptions.Warning(_('Year must be 4 digits number (YYYY)')) #Create root declaration decl = ET.Element('DeclarationReport') decl.set('xmlns', INTRASTAT_XMLNS) #Add Administration elements admin = ET.SubElement(decl, 'Administration') fromtag = ET.SubElement(admin, 'From') fromtag.text = kbo fromtag.set('declarerType', 'KBO') ET.SubElement(admin, 'To').text = "NBB" ET.SubElement(admin, 'Domain').text = "SXX" if decl_datas.arrivals == 'be-standard': decl.append( self._get_lines(cr, SUPERUSER_ID, ids, decl_datas, company, dispatchmode=False, extendedmode=False, context=context)) elif decl_datas.arrivals == 'be-extended': decl.append( self._get_lines(cr, SUPERUSER_ID, ids, decl_datas, company, dispatchmode=False, extendedmode=True, context=context)) if decl_datas.dispatches == 'be-standard': decl.append( self._get_lines(cr, SUPERUSER_ID, ids, decl_datas, company, dispatchmode=True, extendedmode=False, context=context)) elif decl_datas.dispatches == 'be-extended': decl.append( self._get_lines(cr, SUPERUSER_ID, ids, decl_datas, company, dispatchmode=True, extendedmode=True, context=context)) #Get xml string with declaration data_file = ET.tostring(decl, encoding='UTF-8', method='xml') #change state of the wizard self.write( cr, uid, ids, { 'name': 'intrastat_%s%s.xml' % (decl_datas.year, decl_datas.month), 'file_save': base64.encodestring(data_file), 'state': 'download' }, context=context) return { 'name': _('Save'), 'context': context, 'view_type': 'form', 'view_mode': 'form', 'res_model': 'l10n_be_intrastat_xml.xml_decl', 'type': 'ir.actions.act_window', 'target': 'new', 'res_id': ids[0], } def _get_lines(self, cr, uid, ids, decl_datas, company, dispatchmode=False, extendedmode=False, context=None): intrastatcode_mod = self.pool['report.intrastat.code'] invoiceline_mod = self.pool['account.invoice.line'] product_mod = self.pool['product.product'] region_mod = self.pool['l10n_be_intrastat.region'] warehouse_mod = self.pool['stock.warehouse'] if dispatchmode: mode1 = 'out_invoice' mode2 = 'in_refund' declcode = "29" else: mode1 = 'in_invoice' mode2 = 'out_refund' declcode = "19" decl = ET.Element('Report') if not extendedmode: decl.set('code', 'EX%sS' % declcode) else: decl.set('code', 'EX%sE' % declcode) decl.set('date', '%s-%s' % (decl_datas.year, decl_datas.month)) datas = ET.SubElement(decl, 'Data') if not extendedmode: datas.set('form', 'EXF%sS' % declcode) else: datas.set('form', 'EXF%sE' % declcode) datas.set('close', 'true') intrastatkey = namedtuple( "intrastatkey", ['EXTRF', 'EXCNT', 'EXTTA', 'EXREG', 'EXGO', 'EXTPC', 'EXDELTRM']) entries = {} sqlreq = """ select inv_line.id from account_invoice_line inv_line join account_invoice inv on inv_line.invoice_id=inv.id left join res_country on res_country.id = inv.intrastat_country_id left join res_partner on res_partner.id = inv.partner_id left join res_country countrypartner on countrypartner.id = res_partner.country_id join product_product on inv_line.product_id=product_product.id join product_template on product_product.product_tmpl_id=product_template.id where inv.state in ('open','paid') and inv.company_id=%s and not product_template.type='service' and (res_country.intrastat=true or (inv.intrastat_country_id is null and countrypartner.intrastat=true)) and ((res_country.code is not null and not res_country.code=%s) or (res_country.code is null and countrypartner.code is not null and not countrypartner.code=%s)) and inv.type in (%s, %s) and to_char(inv.date_invoice, 'YYYY')=%s and to_char(inv.date_invoice, 'MM')=%s """ cr.execute(sqlreq, (company.id, company.partner_id.country_id.code, company.partner_id.country_id.code, mode1, mode2, decl_datas.year, decl_datas.month)) lines = cr.fetchall() invoicelines_ids = [rec[0] for rec in lines] invoicelines = invoiceline_mod.browse(cr, uid, invoicelines_ids, context=context) for inv_line in invoicelines: #Check type of transaction if inv_line.intrastat_transaction_id: extta = inv_line.intrastat_transaction_id.code else: extta = "1" #Check country if inv_line.invoice_id.intrastat_country_id: excnt = inv_line.invoice_id.intrastat_country_id.code else: excnt = inv_line.invoice_id.partner_id.country_id.code #Check region #If purchase, comes from purchase order, linked to a location, #which is linked to the warehouse #if sales, the sale order is linked to the warehouse #if sales, from a delivery order, linked to a location, #which is linked to the warehouse #If none found, get the company one. exreg = None if inv_line.invoice_id.type in ('in_invoice', 'in_refund'): #comes from purchase POL = self.pool['purchase.order.line'] poline_ids = POL.search(cr, uid, [('invoice_lines', 'in', inv_line.id)], context=context) if poline_ids: purchaseorder = POL.browse(cr, uid, poline_ids[0], context=context).order_id region_id = warehouse_mod.get_regionid_from_locationid( cr, uid, purchaseorder.location_id.id, context=context) if region_id: exreg = region_mod.browse(cr, uid, region_id).code elif inv_line.invoice_id.type in ('out_invoice', 'out_refund'): #comes from sales soline_ids = self.pool['sale.order.line'].search( cr, uid, [('invoice_lines', 'in', inv_line.id)], context=context) if soline_ids: saleorder = self.pool['sale.order.line'].browse( cr, uid, soline_ids[0], context=context).order_id if saleorder and saleorder.warehouse_id and saleorder.warehouse_id.region_id: exreg = region_mod.browse( cr, uid, saleorder.warehouse_id.region_id.id, context=context).code if not exreg: if company.region_id: exreg = company.region_id.code else: self._company_warning( cr, uid, _('The Intrastat Region of the selected company is not set, ' 'please make sure to configure it first.'), context=context) #Check commodity codes intrastat_id = product_mod.get_intrastat_recursively( cr, uid, inv_line.product_id.id, context=context) if intrastat_id: exgo = intrastatcode_mod.browse(cr, uid, intrastat_id, context=context).name else: raise exceptions.Warning( _('Product "%s" has no intrastat code, please configure it' ) % inv_line.product_id.display_name) #In extended mode, 2 more fields required if extendedmode: #Check means of transport if inv_line.invoice_id.transport_mode_id: extpc = inv_line.invoice_id.transport_mode_id.code elif company.transport_mode_id: extpc = company.transport_mode_id.code else: self._company_warning( cr, uid, _('The default Intrastat transport mode of your company ' 'is not set, please make sure to configure it first.' ), context=context) #Check incoterm if inv_line.invoice_id.incoterm_id: exdeltrm = inv_line.invoice_id.incoterm_id.code elif company.incoterm_id: exdeltrm = company.incoterm_id.code else: self._company_warning( cr, uid, _('The default Incoterm of your company is not set, ' 'please make sure to configure it first.'), context=context) else: extpc = "" exdeltrm = "" linekey = intrastatkey(EXTRF=declcode, EXCNT=excnt, EXTTA=extta, EXREG=exreg, EXGO=exgo, EXTPC=extpc, EXDELTRM=exdeltrm) #We have the key #calculate amounts if inv_line.price_unit and inv_line.quantity: amount = inv_line.price_unit * inv_line.quantity else: amount = 0 if (not inv_line.uom_id.category_id or not inv_line.product_id.uom_id.category_id or inv_line.uos_id.category_id.id != inv_line.product_id.uom_id.category_id.id): weight = inv_line.product_id.weight * inv_line.quantity else: weight = (inv_line.product_id.weight * inv_line.quantity * inv_line.uos_id.factor) if (not inv_line.uos_id.category_id or not inv_line.product_id.uom_id.category_id or inv_line.uos_id.category_id.id != inv_line.product_id.uom_id.category_id.id): supply_units = inv_line.quantity else: supply_units = inv_line.quantity * inv_line.uom_id.factor amounts = entries.setdefault(linekey, (0, 0, 0)) amounts = (amounts[0] + amount, amounts[1] + weight, amounts[2] + supply_units) entries[linekey] = amounts numlgn = 0 for linekey in entries: numlgn += 1 amounts = entries[linekey] item = ET.SubElement(datas, 'Item') self._set_Dim(item, 'EXSEQCODE', unicode(numlgn)) self._set_Dim(item, 'EXTRF', unicode(linekey.EXTRF)) self._set_Dim(item, 'EXCNT', unicode(linekey.EXCNT)) self._set_Dim(item, 'EXTTA', unicode(linekey.EXTTA)) self._set_Dim(item, 'EXREG', unicode(linekey.EXREG)) self._set_Dim(item, 'EXTGO', unicode(linekey.EXGO)) if extendedmode: self._set_Dim(item, 'EXTPC', unicode(linekey.EXTPC)) self._set_Dim(item, 'EXDELTRM', unicode(linekey.EXDELTRM)) self._set_Dim(item, 'EXTXVAL', unicode(round(amounts[0], 0)).replace(".", ",")) self._set_Dim(item, 'EXWEIGHT', unicode(round(amounts[1], 0)).replace(".", ",")) self._set_Dim(item, 'EXUNITS', unicode(round(amounts[2], 0)).replace(".", ",")) if numlgn == 0: #no datas datas.set('action', 'nihil') return decl def _set_Dim(self, item, prop, value): dim = ET.SubElement(item, 'Dim') dim.set('prop', prop) dim.text = value
class gamification_badge(osv.Model): """Badge object that users can send and receive""" CAN_GRANT = 1 NOBODY_CAN_GRANT = 2 USER_NOT_VIP = 3 BADGE_REQUIRED = 4 TOO_MANY = 5 _name = 'gamification.badge' _description = 'Gamification badge' _inherit = ['mail.thread'] def _get_owners_info(self, cr, uid, ids, name, args, context=None): """Return: the list of unique res.users ids having received this badge the total number of time this badge was granted the total number of users this badge was granted to """ result = dict((res_id, {'stat_count': 0, 'stat_count_distinct': 0, 'unique_owner_ids': []}) for res_id in ids) cr.execute(""" SELECT badge_id, count(user_id) as stat_count, count(distinct(user_id)) as stat_count_distinct, array_agg(distinct(user_id)) as unique_owner_ids FROM gamification_badge_user WHERE badge_id in %s GROUP BY badge_id """, (tuple(ids),)) for (badge_id, stat_count, stat_count_distinct, unique_owner_ids) in cr.fetchall(): result[badge_id] = { 'stat_count': stat_count, 'stat_count_distinct': stat_count_distinct, 'unique_owner_ids': unique_owner_ids, } return result def _get_badge_user_stats(self, cr, uid, ids, name, args, context=None): """Return stats related to badge users""" result = dict.fromkeys(ids, False) badge_user_obj = self.pool.get('gamification.badge.user') first_month_day = date.today().replace(day=1).strftime(DF) for bid in ids: result[bid] = { 'stat_my': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('user_id', '=', uid)], context=context, count=True), 'stat_this_month': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('create_date', '>=', first_month_day)], context=context, count=True), 'stat_my_this_month': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('user_id', '=', uid), ('create_date', '>=', first_month_day)], context=context, count=True), 'stat_my_monthly_sending': badge_user_obj.search(cr, uid, [('badge_id', '=', bid), ('create_uid', '=', uid), ('create_date', '>=', first_month_day)], context=context, count=True) } return result def _remaining_sending_calc(self, cr, uid, ids, name, args, context=None): """Computes the number of badges remaining the user can send 0 if not allowed or no remaining integer if limited sending -1 if infinite (should not be displayed) """ result = dict.fromkeys(ids, False) for badge in self.browse(cr, uid, ids, context=context): if self._can_grant_badge(cr, uid, badge.id, context) != 1: # if the user cannot grant this badge at all, result is 0 result[badge.id] = 0 elif not badge.rule_max: # if there is no limitation, -1 is returned which means 'infinite' result[badge.id] = -1 else: result[badge.id] = badge.rule_max_number - badge.stat_my_monthly_sending return result _columns = { 'name': fields.char('Badge', required=True, translate=True), 'description': fields.text('Description', translate=True), 'image': fields.binary("Image", attachment=True, help="This field holds the image used for the badge, limited to 256x256"), 'rule_auth': fields.selection([ ('everyone', 'Everyone'), ('users', 'A selected list of users'), ('having', 'People having some badges'), ('nobody', 'No one, assigned through challenges'), ], string="Allowance to Grant", help="Who can grant this badge", required=True), 'rule_auth_user_ids': fields.many2many('res.users', 'rel_badge_auth_users', string='Authorized Users', help="Only these people can give this badge"), 'rule_auth_badge_ids': fields.many2many('gamification.badge', 'gamification_badge_rule_badge_rel', 'badge1_id', 'badge2_id', string='Required Badges', help="Only the people having these badges can give this badge"), 'rule_max': fields.boolean('Monthly Limited Sending', help="Check to set a monthly limit per person of sending this badge"), 'rule_max_number': fields.integer('Limitation Number', help="The maximum number of time this badge can be sent per month per person."), 'stat_my_monthly_sending': fields.function(_get_badge_user_stats, type="integer", string='My Monthly Sending Total', multi='badge_users', help="The number of time the current user has sent this badge this month."), 'remaining_sending': fields.function(_remaining_sending_calc, type='integer', string='Remaining Sending Allowed', help="If a maxium is set"), 'challenge_ids': fields.one2many('gamification.challenge', 'reward_id', string="Reward of Challenges"), 'goal_definition_ids': fields.many2many('gamification.goal.definition', 'badge_unlocked_definition_rel', string='Rewarded by', help="The users that have succeeded theses goals will receive automatically the badge."), 'owner_ids': fields.one2many('gamification.badge.user', 'badge_id', string='Owners', help='The list of instances of this badge granted to users'), 'active': fields.boolean('Active'), 'unique_owner_ids': fields.function(_get_owners_info, string='Unique Owners', help="The list of unique users having received this badge.", multi='unique_users', type="many2many", relation="res.users"), 'stat_count': fields.function(_get_owners_info, string='Total', type="integer", multi='unique_users', help="The number of time this badge has been received."), 'stat_count_distinct': fields.function(_get_owners_info, type="integer", string='Number of users', multi='unique_users', help="The number of time this badge has been received by unique users."), 'stat_this_month': fields.function(_get_badge_user_stats, type="integer", string='Monthly total', multi='badge_users', help="The number of time this badge has been received this month."), 'stat_my': fields.function(_get_badge_user_stats, string='My Total', type="integer", multi='badge_users', help="The number of time the current user has received this badge."), 'stat_my_this_month': fields.function(_get_badge_user_stats, type="integer", string='My Monthly Total', multi='badge_users', help="The number of time the current user has received this badge this month."), } _defaults = { 'rule_auth': 'everyone', 'active': True, } def check_granting(self, cr, uid, badge_id, context=None): """Check the user 'uid' can grant the badge 'badge_id' and raise the appropriate exception if not Do not check for SUPERUSER_ID """ status_code = self._can_grant_badge(cr, uid, badge_id, context=context) if status_code == self.CAN_GRANT: return True elif status_code == self.NOBODY_CAN_GRANT: raise UserError(_('This badge can not be sent by users.')) elif status_code == self.USER_NOT_VIP: raise UserError(_('You are not in the user allowed list.')) elif status_code == self.BADGE_REQUIRED: raise UserError(_('You do not have the required badges.')) elif status_code == self.TOO_MANY: raise UserError(_('You have already sent this badge too many time this month.')) else: _logger.exception("Unknown badge status code: %d" % int(status_code)) return False def _can_grant_badge(self, cr, uid, badge_id, context=None): """Check if a user can grant a badge to another user :param uid: the id of the res.users trying to send the badge :param badge_id: the granted badge id :return: integer representing the permission. """ if uid == SUPERUSER_ID: return self.CAN_GRANT badge = self.browse(cr, uid, badge_id, context=context) if badge.rule_auth == 'nobody': return self.NOBODY_CAN_GRANT elif badge.rule_auth == 'users' and uid not in [user.id for user in badge.rule_auth_user_ids]: return self.USER_NOT_VIP elif badge.rule_auth == 'having': all_user_badges = self.pool.get('gamification.badge.user').search(cr, uid, [('user_id', '=', uid)], context=context) for required_badge in badge.rule_auth_badge_ids: if required_badge.id not in all_user_badges: return self.BADGE_REQUIRED if badge.rule_max and badge.stat_my_monthly_sending >= badge.rule_max_number: return self.TOO_MANY # badge.rule_auth == 'everyone' -> no check return self.CAN_GRANT def check_progress(self, cr, uid, context=None): try: model, res_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'gamification', 'badge_hidden') except ValueError: return True badge_user_obj = self.pool.get('gamification.badge.user') if not badge_user_obj.search(cr, uid, [('user_id', '=', uid), ('badge_id', '=', res_id)], context=context): values = { 'user_id': uid, 'badge_id': res_id, } badge_user_obj.create(cr, SUPERUSER_ID, values, context=context) return True
class test_model(orm.Model): _name = 'test_converter.test_model' _columns = { 'char': fields.char(), 'integer': fields.integer(), 'float': fields.float(), 'numeric': fields.float(digits=(16, 2)), 'many2one': fields.many2one('test_converter.test_model.sub'), 'binary': fields.binary(), 'date': fields.date(), 'datetime': fields.datetime(), 'selection': fields.selection([ (1, "réponse A"), (2, "réponse B"), (3, "réponse C"), (4, "réponse D"), ]), 'selection_str': fields.selection( [ ('A', "Qu'il n'est pas arrivé à Toronto"), ('B', "Qu'il était supposé arriver à Toronto"), ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"), ('D', "La réponse D"), ], string="Lorsqu'un pancake prend l'avion à destination de Toronto et " "qu'il fait une escale technique à St Claude, on dit:"), 'html': fields.html(), 'text': fields.text(), } # `base` module does not contains any model that implement the `_group_by_full` functionality # test this feature here... def _gbf_m2o(self, cr, uid, ids, domain, read_group_order, access_rights_uid, context): Sub = self.pool['test_converter.test_model.sub'] all_ids = Sub._search(cr, uid, [], access_rights_uid=access_rights_uid, context=context) result = Sub.name_get(cr, access_rights_uid or uid, all_ids, context=context) folds = {i: i not in ids for i, _ in result} return result, folds _group_by_full = { 'many2one': _gbf_m2o, }