def account_creation(self, cr, uid, invoice, context=None): # Conti di ricavo/costo # La tabella costi/ricavi (lunghezza complessiva di 152 caratteri) è composta da 8 elementi account = {} account_data = '' for line in invoice.invoice_line: if line.account_id.code in account: account[line.account_id.code] += line.price_subtotal else: account[line.account_id.code] = line.price_subtotal if not account: raise orm.except_orm('Errore', 'Non ci sono conti ricavo/costo definite nella fattura {invoice}'.format(invoice=invoice.number)) elif len(account) > 8: raise orm.except_orm('Errore', 'Ci sono più di 8 conti ricavo/costo nella fattura {invoice}'.format(invoice=invoice.number)) for account_code in account.keys(): code = account_code.isdigit() and int(account_code) or 5810501 # 5810501 è un numero fisso merci/vendita account_data += account_template.format(**{ 'account_proceeds': code, 'total_proceeds': int(account.get(account_code) * 100) }) for k in range(0, 8 - len(account)): account_data += account_template.format(**{ 'account_proceeds': 0, 'total_proceeds': 0 }) return account_data
def button_upgrade(self, cr, uid, ids, context=None): depobj = self.pool.get('ir.module.module.dependency') todo = self.browse(cr, uid, ids, context=context) self.update_list(cr, uid) i = 0 while i < len(todo): mod = todo[i] i += 1 if mod.state not in ('installed', 'to upgrade'): raise orm.except_orm(_('Error'), _("Can not upgrade module '%s'. It is not installed.") % (mod.name,)) self.check_external_dependencies(mod.name, 'to upgrade') iids = depobj.search(cr, uid, [('name', '=', mod.name)], context=context) for dep in depobj.browse(cr, uid, iids, context=context): if dep.module_id.state == 'installed' and dep.module_id not in todo: todo.append(dep.module_id) ids = map(lambda x: x.id, todo) self.write(cr, uid, ids, {'state': 'to upgrade'}, context=context) to_install = [] for mod in todo: for dep in mod.dependencies_id: if dep.state == 'unknown': raise orm.except_orm(_('Error'), _('You try to upgrade a module that depends on the module: %s.\nBut this module is not available in your system.') % (dep.name,)) if dep.state == 'uninstalled': ids2 = self.search(cr, uid, [('name', '=', dep.name)]) to_install.extend(ids2) self.button_install(cr, uid, to_install, context=context) return dict(ACTION_DICT, name=_('Apply Schedule Upgrade'))
def state_update(self, newstate, states_to_update, level=100): if level < 1: raise orm.except_orm(_('Error'), _('Recursion error in modules dependencies !')) # whether some modules are installed with demo data demo = False for module in self: # determine dependency modules to update/others update_mods, ready_mods = self.browse(), self.browse() for dep in module.dependencies_id: if dep.state == 'unknown': raise orm.except_orm(_('Error'), _("You try to install module '%s' that depends on module '%s'.\nBut the latter module is not available in your system.") % (module.name, dep.name,)) if dep.depend_id.state == newstate: ready_mods += dep.depend_id else: update_mods += dep.depend_id # update dependency modules that require it, and determine demo for module update_demo = update_mods.state_update(newstate, states_to_update, level=level-1) module_demo = module.demo or update_demo or any(mod.demo for mod in ready_mods) demo = demo or module_demo # check dependencies and update module itself self.check_external_dependencies(module.name, newstate) if module.state in states_to_update: module.write({'state': newstate, 'demo': module_demo}) return demo
def action_export_primanota(self, cr, uid, ids, context): file_name = 'TRAF2000{number}.txt'.format(number=ids and ids[0]) file_data = StringIO() if context.get('active_ids'): invoice_ids = context['active_ids'] else: return {'type': 'ir.actions.act_window_close'} for invoice_id in invoice_ids: invoice = self.pool['account.invoice'].browse(cr, uid, invoice_id, context) book_values = self.map_invoice_data(cr, uid, invoice_id, context) row = cash_book.format(**book_values) if not len(row) == 7001: raise orm.except_orm(_('Error'), "La lunghezza della riga Prima Nota errata ({}). Fattura {}".format(len(row), invoice.number)) file_data.write(row) deadline_values = self.map_deadline_data(cr, uid, invoice_id, context) row = deadline_book.format(**deadline_values) if not len(row) == 7001: raise orm.except_orm(_('Error'), "La lunghezza della riga INTRASTAT errata ({}). Fattura {}".format(len(row), invoice.number)) file_data.write(row) industrial_values = self.map_industrial_data(cr, uid, invoice_id, context) row = industrial_accounting.format(**industrial_values) if not len(row) == 7001: raise orm.except_orm(_('Error'), "La lunghezza della riga INDUSTRIALE errata ({}). Fattura {}".format(len(row), invoice.number)) file_data.write(row) invoice.write({'teamsystem_export': True}) out = file_data.getvalue() out = out.encode("base64") return self.write(cr, uid, ids, {'state': 'end', 'data': out, 'name': file_name}, context=context)
def write(self, cr, user, ids, vals, context=None): """ Warn if user does not have rights to modify travel with current number of passengers or to add more than the limit. """ if type(ids) is not list: ids = [ids] users_pool = self.pool.get('res.users') limit = get_basic_passenger_limit(self.pool.get("ir.config_parameter"), cr, user, context=context) if (len(vals.get('passenger_ids', [])) > limit and not users_pool.has_group(cr, user, 'travel.group_travel_manager')): raise orm.except_orm( _('Warning!'), _('Only members of the Travel Managers group have the rights ' 'to add more than %d passengers to a travel.') % limit) for travel in self.browse(cr, user, ids, context=context): if (len(travel.passenger_ids) > limit and not users_pool.has_group(cr, user, 'travel.group_travel_manager')): raise orm.except_orm( _('Warning!'), _('Only members of the Travel Managers group have the ' 'rights to modify a Travel with more than %d passengers ' '(%s).') % (limit, travel.name)) return super(travel_travel, self).write(cr, user, ids, vals, context=context)
def _connect_to_asterisk(self, cr, uid, context=None): ''' Open the connection to the Asterisk Manager Returns an instance of the Asterisk Manager ''' user = self.pool['res.users'].browse(cr, uid, uid, context=context) # Note : if I write 'Error' without ' :', it won't get translated... # I don't understand why ! ast_server = self._get_asterisk_server_from_user(cr, uid, context=context) # We check if the current user has a chan type if not user.asterisk_chan_type: raise orm.except_orm(_('Error :'), _('No channel type configured for the current user.')) # We check if the current user has an internal number if not user.resource: raise orm.except_orm(_('Error :'), _('No resource name configured for the current user')) _logger.debug("User's phone : %s/%s" % (user.asterisk_chan_type, user.resource)) _logger.debug("Asterisk server = %s:%d" % (ast_server.ip_address, ast_server.port)) # Connect to the Asterisk Manager Interface try: ast_manager = Manager.Manager((ast_server.ip_address, ast_server.port), ast_server.login, ast_server.password) except Exception, e: _logger.error("Error in the Originate request to Asterisk server %s" % ast_server.ip_address) _logger.error("Here is the detail of the error : %s" % e.strerror) raise orm.except_orm(_('Error :'), _("Problem in the request from OpenERP to Asterisk. Here is the detail of the error: %s." % e.strerror)) return False
def m2o_to_x2m(cr, model, table, field, source_field): """ Transform many2one relations into one2many or many2many. Use rename_columns in your pre-migrate script to retain the column's old value, then call m2o_to_x2m in your post-migrate script. WARNING: If converting to one2many, there can be data loss, because only one inverse record can be mapped in a one2many, but you can have multiple many2one pointing to the same target. Use it when the use case allows this conversion. :param model: The target model registry object :param table: The source table :param field: The new field name on the target model :param source_field: the (renamed) many2one column on the source table. .. versionadded:: 8.0 """ if not model._columns.get(field): raise except_orm( "Error", "m2o_to_x2m: field %s doesn't exist in model %s" % ( field, model._name)) if isinstance(model._columns[field], (many2many, Many2many)): column = model._columns[field] if version_info[0] > 6 or version_info[0:2] == (6, 1): rel, id1, id2 = many2many._sql_names(column, model) else: rel, id1, id2 = column._rel, column._id1, column._id2 logged_query( cr, """ INSERT INTO %s (%s, %s) SELECT id, %s FROM %s WHERE %s is not null """ % (rel, id1, id2, source_field, table, source_field)) elif isinstance(model._columns[field], (One2many, one2many)): if isinstance(model._columns[field], One2many): target_table = ( model.pool[model._columns[field].comodel_name]._table) target_field = model._columns[field].inverse_name else: target_table = model.pool[model._columns[field]._obj]._table target_field = model._columns[field]._fields_id logged_query( cr, """ UPDATE %(target_table)s AS target SET %(target_field)s=source.id FROM %(source_table)s AS source WHERE source.%(source_field)s=target.id """ % {'target_table': target_table, 'target_field': target_field, 'source_field': source_field, 'source_table': table}) else: raise except_orm( "Error", "m2o_to_x2m: field %s of model %s is not a " "many2many/one2many one" % (field, model._name))
def action_move_create(self, cr, uid, ids, context=None): if context is None: context = {} t_invoice_data = self.browse(cr, uid, ids, context=context) for inv in t_invoice_data: if not inv.journal_id: raise orm.except_orm(_('Error!'), _('Journal not defined for this invoice!')) if not inv.journal_id.iva_registry_id: raise orm.except_orm(_('Error!'), _('You must link %s with a VAT registry!') % (inv.journal_id.name)) if 'company_id' not in context: context = {'company_id':inv.company_id.id} period_id = inv.period_id and inv.period_id.id or False if not period_id: period_obj = self.pool.get('account.period') period_ids = period_obj.find(cr, uid, inv.registration_date, context=context) period_id = period_ids and period_ids[0] or False if period_id: self.write(cr, uid, [inv.id], {'period_id': period_id}, context=context) res = super(account_invoice_makeover, self).action_move_create(cr, uid, ids, context=None) return res
def _build_codes_dict(self, tax_code, res={}, context=None): if context is None: context = {} tax_pool = self.pool.get('account.tax') if tax_code.sum_period: if res.get(tax_code.name, False): raise orm.except_orm(_('Error'), _('Too many occurences of tax code %s') % tax_code.name) # search for taxes linked to that code tax_ids = tax_pool.search(self.cr, self.uid, [('tax_code_id', '=', tax_code.id)], context=context) if tax_ids: tax = tax_pool.browse(self.cr, self.uid, tax_ids[0], context=context) # search for the related base code base_code = tax.base_code_id or tax.parent_id and tax.parent_id.base_code_id or False if not base_code: raise orm.except_orm(_('Error'), _('No base code found for tax code %s') % tax_code.name) # check if every tax is linked to the same tax code and base code for tax in tax_pool.browse(self.cr, self.uid, tax_ids, context=context): test_base_code = tax.base_code_id or tax.parent_id and tax.parent_id.base_code_id or False if test_base_code.id != base_code.id: raise orm.except_orm(_('Error'), _('Not every tax linked to tax code %s is linked the same base code') % tax_code.name) res[tax_code.name] = { 'vat': tax_code.sum_period, 'base': base_code.sum_period, } for child_code in tax_code.child_ids: res = self._build_codes_dict(child_code, res=res, context=context) return res
def _check_validity(self, cr, uid, ids): for server in self.browse(cr, uid, ids): out_prefix = ('Out prefix', server.out_prefix) dialplan_context = ('Dialplan context', server.context) alert_info = ('Alert-Info SIP header', server.alert_info) password = ('Event Socket password', server.password) if out_prefix[1] and not out_prefix[1].isdigit(): raise orm.except_orm( _('Error:'), _("Only use digits for the '%s' on the FreeSWITCH server " "'%s'" % (out_prefix[0], server.name))) if server.wait_time < 1 or server.wait_time > 120: raise orm.except_orm( _('Error:'), _("You should set a 'Wait time' value between 1 and 120 " "seconds for the FreeSWITCH server '%s'" % server.name)) if server.port > 65535 or server.port < 1: raise orm.except_orm( _('Error:'), _("You should set a TCP port between 1 and 65535 for the " "FreeSWITCH server '%s'" % server.name)) for check_str in [dialplan_context, alert_info, password]: if check_str[1]: try: check_str[1].encode('ascii') except UnicodeEncodeError: raise orm.except_orm( _('Error:'), _("The '%s' should only have ASCII caracters for " "the FreeSWITCH server '%s'" % (check_str[0], server.name))) return True
def perform_suspension(self, cr, uid, ids, context=None): project_id = context.get('active_id') if not project_id: raise orm.except_orm( _('No project selected'), _('Please select a project to suspend')) project_obj = self.pool.get('compassion.project') project = project_obj.browse(cr, uid, project_id, context) if project.suspension != 'fund-suspended': raise orm.except_orm( _('Suspension error'), _('The project is not fund-suspended. ' 'You cannot extend the suspension.')) wizard = self.browse(cr, uid, ids[0], context) date_start = datetime.strptime(wizard.date_start, DF) if \ wizard.date_start else None date_end = datetime.strptime(wizard.date_end, DF) if \ wizard.date_end else None project_obj.suspend_funds( cr, uid, project_id, context=context, date_start=date_start, date_end=date_end) return True
def fill_sale_order(self, cr, uid, ids, context=None): """Pass the order id to a wizard to retrieve a list of product categories for setting a default list of products.""" action_obj = self.pool.get('ir.actions.act_window') view_obj = self.pool.get('ir.ui.view') #Defensive programming. if len(ids) > 1: raise orm.except_orm("ERROR","You tried to pass more than one order.") action_id = action_obj.search(cr, uid, [('name','=','Fill Sale Products'), ('res_model','=','sale.order.fill')], limit=1, context=context) view_id = view_obj.search(cr, uid, [('name','=','sale.order.fill.view'), ('model','=','sale.order.fill')], limit=1, context=context) try: action_content = action_obj.read(cr, uid, action_id, context=context)[0] action_content.update({'views': [(view_id[0], 'form')]}) return action_content except IndexError: raise orm.except_orm('ERROR', """One or both of the following elements are missing: Action: Fill Sale Products View: sale.order.fill.view Please Update module.""")
def xls_export(self, cr, uid, ids, context=None): asset_obj = self.pool.get("account.asset.asset") wiz_form = self.browse(cr, uid, ids)[0] parent_asset_id = wiz_form.parent_asset_id.id if not parent_asset_id: parent_ids = asset_obj.search(cr, uid, [("type", "=", "view"), ("parent_id", "=", False)]) if not parent_ids: raise orm.except_orm(_("Configuration Error"), _("No top level asset of type 'view' defined!")) else: parent_asset_id = parent_ids[0] # sanity check error_ids = asset_obj.search(cr, uid, [("type", "=", "normal"), ("parent_id", "=", False)]) for error_id in error_ids: error = asset_obj.browse(cr, uid, error_id, context=context) error_name = error.name if error.code: error_name += " (" + error.code + ")" or "" raise orm.except_orm(_("Configuration Error"), _("No parent asset defined for asset '%s'!") % error_name) domain = [("type", "=", "normal"), ("id", "child_of", parent_asset_id)] asset_ids = asset_obj.search(cr, uid, domain) if not asset_ids: raise orm.except_orm(_("No Data Available"), _("No records found for your selection!")) datas = {"model": "account.asset.asset", "fiscalyear_id": wiz_form.fiscalyear_id.id, "ids": [parent_asset_id]} return {"type": "ir.actions.report.xml", "report_name": "account.asset.xls", "datas": datas}
def busca_dados(self, cr, uid, ids, field, args, context): ''' Descrição: Chamada pelas funções inline para buscar valores funcionais ''' uid = 1 dados = self.browse(cr, uid, ids, context)[0] if field == "matricula": if self.browse(cr, uid, ids, context)[0].solicitante_id.papel_ids[0].matricula != None: return {dados.id: self.browse(cr, uid, ids, context)[0].solicitante_id.papel_ids[0].matricula} else: raise except_orm(u"Matrícula não encontrada", u"Pessoa não possui nenhuma matrícula") elif field == "telefone": if self.browse(cr, uid, ids, context)[0].solicitante_id.mobile_phone != None or \ self.browse(cr, uid, ids, context)[0].solicitante_id.work_phone != None: return {dados.id: self.browse(cr, uid, ids, context)[0].solicitante_id.mobile_phone or self.browse(cr, uid, ids, context)[0].solicitante_id.work_phone} else: raise except_orm(u"Telefone não encontrado", u"É necessário ao menos um telefone cadastrado") elif field == "setor_id": if self.browse(cr, uid, ids, context)[0].solicitante_id.papel_ids[0].ud_setores.name != None: return {dados.id: self.browse(cr, uid, ids, context)[0].solicitante_id.papel_ids[0].ud_setores.name} elif self.browse(cr, uid, ids, context)[0].solicitante_id.papel_ids[0].ud_cursos.name != None: return {dados.id: self.browse(cr, uid, ids, context)[0].solicitante_id.papel_ids[0].ud_cursos.name} else: raise except_orm(u"Setor não encontrado", u"Pessoa está vinculada a nenhum setor") elif field == "email": if self.browse(cr, uid, ids, context)[0].solicitante_id.work_email != None: return {dados.id: self.browse(cr, uid, ids, context)[0].solicitante_id.work_email} else: raise except_orm(u"E-mail não encontrado", u"É necessário existir um e-mail cadastrado")
def test_sequence_order(self, cr, uid, ids): """ Tests whether production is done or not. @return: True or False """ print " in test sequence order ==============",ids,uid res = True for rec in self.browse(cr,uid,ids): employees_allowed_uid=[rec_c1.user_id.id for rec_c1 in rec.workcenter_id.employees_allowed if rec_c1.user_id] groups=self.pool.get('ir.model.data').get_object_reference(cr,uid,'mrp','group_mrp_user')[1] mrp_user_group=self.pool.get('res.groups').browse(cr,uid,groups) mrp_user_group_user_ids=map(int,mrp_user_group.users or []) groups=self.pool.get('ir.model.data').get_object_reference(cr,uid,'mrp','group_mrp_manager')[1] mrp_manager_group=self.pool.get('res.groups').browse(cr,uid,groups) mrp_manager_group_user_ids=map(int,mrp_user_group.users or []) print "11111144444,employees,employee_group_user_ids,uid",employees_allowed_uid,mrp_user_group_user_ids,uid if uid in mrp_user_group_user_ids and uid not in mrp_manager_group_user_ids and uid!=SUPERUSER_ID and (uid not in employees_allowed_uid or (uid in employees_allowed_uid and rec.hr_wc_ids and uid!=rec.hr_wc_ids.user_id.id)) : raise orm.except_orm(_('Warning'), _('You are not allowed to operate the workcenter. Please contact the administrator.')) work_orders_ids=self.search(cr,uid,[('production_id','=',rec.production_id.id),('state','not in',['cancel','done'])]) work_orders_obj=self.browse(cr,uid,work_orders_ids) for rec_orders in work_orders_obj: if rec_orders.sequence<rec.sequence: raise orm.except_orm(_('Warning'), _('Please cancel or finish work orders of lower sequence first.')) return res
def check_discount_with_restriction(self, cr, uid, discount, pricelist_id, company_id, context=None): if context is None: context = self.pool['res.users'].context_get(cr, uid, context=context) restriction_id = self.get_restriction_id(cr, uid, uid, pricelist_id, context=context) group_obj = self.pool['res.groups'] if not group_obj.user_in_group(cr, uid, uid, 'price_security.can_modify_prices', context=context): title = _('Discount out of range') msg1 = _('The applied discount is out of range with respect to the allowed. The discount can be between %s and %s for the current price list.') msg2 = _('The applied discount is out of range with respect to the allowed. You cannot give any discount with the current price list.') if restriction_id: restriction = self.browse(cr, uid, restriction_id, context=context) if isinstance(restriction, list): restriction = restriction[0] if discount < restriction.min_discount or discount > restriction.max_discount: raise orm.except_orm(title, msg1 % (restriction.min_discount, restriction.max_discount)) else: if not company_id: company_id = self.pool['res.users']._get_company(cr, uid) company_max_discount = self.pool['res.company'].browse(cr, uid, company_id, context).max_discount if discount > company_max_discount: if company_max_discount == 0.0: raise orm.except_orm(title, msg2) else: raise orm.except_orm(title, msg1 % (0, company_max_discount))
def get_tax_by_invoice_tax(self, cr, uid, invoice_tax, context=None): if ' - ' in invoice_tax: tax_descr = invoice_tax.split(' - ')[0] tax_ids = self.search(cr, uid, [ ('description', '=', tax_descr), ], context=context) if not tax_ids: raise orm.except_orm( _('Error'), _('No tax %s found') % tax_descr) if len(tax_ids) > 1: raise orm.except_orm( _('Error'), _('Too many tax %s found') % tax_descr) else: tax_name = invoice_tax tax_ids = self.search(cr, uid, [ ('name', '=', tax_name), ], context=context) if not tax_ids: raise orm.except_orm( _('Error'), _('No tax %s found') % tax_name) if len(tax_ids) > 1: raise orm.except_orm( _('Error'), _('Too many tax %s found') % tax_name) return tax_ids[0]
def action_proforma(self, cr, uid, ids, context=None): if context is None: context = self.pool['res.users'].context_get(cr, uid) if not ids: return True if isinstance(ids, (int, long)): ids = [ids] ait_obj = self.pool['account.invoice.tax'] for invoice in self.browse(cr, uid, ids, context=context): if invoice.number: raise orm.except_orm(_("Invoice"), _("Invoice just validate with number {number}, impossible to Create PROFORMA".format(number=invoice.number))) elif invoice.internal_number: raise orm.except_orm(_("Invoice"), _("Invoice just validate with internal number {number}, impossible to Create PROFORMA".format(number=invoice.internal_number))) vals = { 'state': 'proforma2', 'proforma_number': self.pool['ir.sequence'].get( cr, uid, 'account.invoice.proforma', ), 'date_proforma': invoice.date_proforma or time.strftime(DEFAULT_SERVER_DATE_FORMAT), # 'number': False, # 'date_invoice': False, # 'internal_number': False } compute_taxes = ait_obj.compute(cr, uid, invoice.id, context=context) self.check_tax_lines(cr, uid, invoice, compute_taxes, ait_obj) self.write(cr, uid, invoice.id, vals, context=context) return True
def change(self, cr, uid, ids, context={}): wzd = self.browse(cr, uid, ids[0], context) # test if user have autorization if wzd.price_type == 'sale': if not self.pool['res.groups'].user_in_group(cr, uid, uid, 'product_bom.group_sell_price', context): raise orm.except_orm(_("You don't have Permission!"), _("You must be on group 'Show Sell Price'")) if wzd.price_type == 'cost': if not self.pool['res.groups'].user_in_group(cr, uid, uid, 'product_bom.group_cost_price', context): raise orm.except_orm(_("You don't have Permission!"), _("You must be on group 'Show Cost Price'")) if wzd.price_type == 'sale': if wzd.name == 'fix': self.pool['product.product'].write(cr, uid, context['active_ids'], {'list_price': wzd.value}, context) else: product_obj = self.pool['product.product'] for ids in context['active_ids']: product = product_obj.browse(cr, uid, ids, context) new_price = product.list_price + ((product.list_price * wzd.value) / 100.00) product_obj.write(cr, uid, [ids, ], {'list_price': new_price}, context) else: if wzd.name == 'fix': self.pool['product.product'].write(cr, uid, context['active_ids'], {'standard_price': wzd.value}, context) else: product_obj = self.pool['product.product'] for ids in context['active_ids']: product = product_obj.browse(cr, uid, ids, context) new_price = product.standard_price + ((product.standard_price * wzd.value) / 100.00) product_obj.write(cr, uid, [ids, ], {'standard_price': new_price}, context) return {'type': 'ir.actions.act_window_close'}
def trg_last_action(self, uid, model, obj_id, cr): """ This function returns information about last workflow activity """ cr.execute("SELECT * FROM wkf_instance WHERE res_id=%s AND res_type=%s", (obj_id, model)) rows = cr.fetchall() if len(rows) > 1: raise orm.except_orm(_("Warning"), _("More than one result returned...")) inst_id, wkf_id, uid, res_id, res_type, state = rows[0] cr.execute("SELECT act_id, inst_id, state FROM wkf_workitem WHERE inst_id=%s", (inst_id,)) rows = cr.fetchall() if len(rows) > 1: raise orm.except_orm(_("Warning"), _("More than one result returned...")) act_id, inst_id, state = rows[0] cr.execute("SELECT id, wkf_id, name, action FROM wkf_activity WHERE id=%s ORDER BY id", (act_id,)) rows = cr.fetchall() if len(rows) > 1: raise orm.except_orm(_("Warning"), _("More than one result returned...")) return dict(zip(("wkf_activity_id", "wkf_instance_id", "name", "action"), rows[0]))
def _check_queue(self, cr, uid, context=None): if context is None: context = {} # //!!!!!!!+++++++++++++++++ [email protected] check_smpp_work() queue_obj = self.pool.get('sms.smsclient.queue') history_obj = self.pool.get('sms.smsclient.history') sids = queue_obj.search(cr, uid, [ ('state', '!=', 'send'), ('state', '!=', 'sending') ], limit=30, context=context) queue_obj.write(cr, uid, sids, {'state': 'sending'}, context=context) error_ids = [] sent_ids = [] for sms in queue_obj.browse(cr, uid, sids, context=context): if len(sms.msg) > 160: error_ids.append(sms.id) continue if sms.gateway_id.method == 'http': try: urllib.urlopen(sms.name) except Exception, e: raise orm.except_orm('Error', e) # //+++++++++++++++++ [email protected] if sms.gateway_id.method == 'http_atompark_xml': try: req = urllib2.Request(sms.name, sms.params) req.add_header("Content-type", "application/x-www-form-urlencoded") urllib2.urlopen(req) except Exception, e: raise orm.except_orm('http_atompark_xml - Error:', e)
def checkcodigo(self, cr, uid, ids, codigo, cantv_pre_config_clasificador_id): #Valida que el campo codigo solo permita números if codigo != False: if re.match("^[0-9]+$", codigo) == None: alerta = {'title':'Error !', 'message':' En este campo solo se permiten numeros . . .'} return {'warning': alerta} #Valida que la longitud del campo codigo no sea menor o mayor a la longitud definida en el nivel del clasificador if codigo: cr.execute('select sum(b.longitud) as longitud from cantv_pre_config_clasificador a ' +'inner join cantv_pre_nivel_clasificador b on a.id=b.cantv_pre_config_clasificador_id '+ 'where a.id=%s and b.cantv_catalogo_detalle_id=(select distinct b.cantv_catalogo_detalle_id from cantv_pre_config_clasificador a '+ 'inner join cantv_pre_nivel_clasificador b on a.id=b.cantv_pre_config_clasificador_id '+ 'where a.id=%s limit 1)',(cantv_pre_config_clasificador_id,cantv_pre_config_clasificador_id,)) longitud_mascara= cr.fetchone() if len(codigo)>longitud_mascara: raise orm.except_orm('Codigo Invalido',"El codigo no puede ser mayor a: %s"%(longitud_mascara[0],)) return False elif len(codigo)<longitud_mascara: raise orm.except_orm('Codigo Invalido',"El codigo no puede ser menor a: %s"%(longitud_mascara[0],)) return False cr.execute('select sum(longitud) as longitud_padre from cantv_pre_nivel_clasificador '+ 'where cantv_catalogo_detalle_id=(select cantv_catalogo_detalle_id from cantv_pre_config_clasificador a '+ 'inner join cantv_pre_nivel_clasificador b on a.id=b.cantv_pre_config_clasificador_id '+ 'where a.id=%s and b.id=%s) and nivel<(select b.nivel from cantv_pre_config_clasificador a '+ 'inner join cantv_pre_nivel_clasificador b on a.id=b.cantv_pre_config_clasificador_id'+ 'where a.id=%s and b.id=%s)',())
def get_name(self, cr, uid, fields, dte_dtr_id, selector, context=None): if dte_dtr_id == 'DTE': if selector == 'company': AltriDatiIdentificativi = (AltriDatiIdentificativiNoSedeType()) elif selector == 'customer' or selector == 'supplier': AltriDatiIdentificativi = (AltriDatiIdentificativiNoCAPType()) else: raise orm.except_orm( _('Error!'), _('Internal error: invalid partner selector')) else: if selector == 'company': AltriDatiIdentificativi = (AltriDatiIdentificativiNoSedeType()) elif selector == 'customer' or selector == 'supplier': AltriDatiIdentificativi = (AltriDatiIdentificativiNoCAPType()) else: raise orm.except_orm( _('Error!'), _('Internal error: invalid partner selector')) if 'xml_Denominazione' in fields: AltriDatiIdentificativi.Denominazione = self.str80Latin( fields['xml_Denominazione']) else: AltriDatiIdentificativi.Nome = self.str60Latin( fields['xml_Nome']) AltriDatiIdentificativi.Cognome = self.str60Latin( fields['xml_Cognome']) AltriDatiIdentificativi.Sede = self.get_sede( cr, uid, fields, dte_dtr_id, selector, context=context) return AltriDatiIdentificativi
def _check_deposit(self, cr, uid, ids): for deposit in self.browse(cr, uid, ids): deposit_currency = deposit.currency_id if deposit_currency == deposit.company_id.currency_id: for line in deposit.check_payment_ids: if line.currency_id: raise orm.except_orm( _("Error:"), _( "The check with amount %s and reference '%s' " "is in currency %s but the deposit is in " "currency %s." ) % (line.debit, line.ref or "", line.currency_id.name, deposit_currency.name), ) else: for line in deposit.check_payment_ids: if line.currency_id != deposit_currency: raise orm.except_orm( _("Error:"), _( "The check with amount %s and reference '%s' " "is in currency %s but the deposit is in " "currency %s." ) % (line.debit, line.ref or "", line.currency_id.name, deposit_currency.name), ) return True
def set_warranty_limit(self, cr, uid, ids, claim_line, context=None): date_invoice = claim_line.invoice_line_id.invoice_id.date_invoice if not date_invoice: raise orm.except_orm( _('Error'), _('Cannot find any date for invoice. ' 'Must be a validated invoice.')) warning = _(self.WARRANT_COMMENT['not_define']) date_inv_at_server = datetime.strptime(date_invoice, DEFAULT_SERVER_DATE_FORMAT) if claim_line.claim_id.claim_type == 'supplier': suppliers = claim_line.product_id.seller_ids if not suppliers: raise orm.except_orm( _('Error'), _('The product has no supplier configured.')) supplier = suppliers[0] warranty_duration = supplier.warranty_duration else: warranty_duration = claim_line.product_id.warranty limit = self.warranty_limit(date_inv_at_server, warranty_duration) # If waranty period was defined if warranty_duration > 0: claim_date = datetime.strptime(claim_line.claim_id.date, DEFAULT_SERVER_DATETIME_FORMAT) if limit < claim_date: warning = _(self.WARRANT_COMMENT['expired']) else: warning = _(self.WARRANT_COMMENT['valid']) self.write( cr, uid, ids, {'guarantee_limit': limit.strftime(DEFAULT_SERVER_DATE_FORMAT), 'warning': warning}, context=context) return True
def _construct_bvrplus_in_chf(self, bvr_string): if len(bvr_string) != 43: raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in first part')) elif self._check_number(bvr_string[0:2]) != int(bvr_string[2]): raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in second part')) elif self._check_number(bvr_string[4:30]) != int(bvr_string[30]): raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in third part')) elif self._check_number(bvr_string[33:41]) != int(bvr_string[41]): raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in fourth part')) else: bvr_struct = {'type': bvr_string[0:2], 'amount': 0.0, 'reference': bvr_string[4:31], 'bvrnumber': bvr_string[4:10], 'beneficiaire': self._create_bvr_account( bvr_string[33:42] ), 'domain': '', 'currency': '' } return bvr_struct
def _check_start_end_dates(self, cr, uid, ids): for invline in self.browse(cr, uid, ids): if invline.start_date and not invline.end_date: raise orm.except_orm( _('Error:'), _("Missing End Date for invoice line with " "Description '%s'.") % (invline.name)) if invline.end_date and not invline.start_date: raise orm.except_orm( _('Error:'), _("Missing Start Date for invoice line with " "Description '%s'.") % (invline.name)) if invline.end_date and invline.start_date and \ invline.start_date > invline.end_date: raise orm.except_orm( _('Error:'), _("Start Date should be before or be the same as " "End Date for invoice line with Description '%s'.") % (invline.name)) # Note : we can't check invline.product_id.must_have_dates # have start_date and end_date here, because it would # block automatic invoice generation. So we do the check # upon validation of the invoice (see below the function # action_move_create) return True
def check_partner_required(self, cr, uid, ids, vals, context=None): if 'account_id' in vals or 'partner_id' in vals or \ 'debit' in vals or 'credit' in vals: if isinstance(ids, (int, long)): ids = [ids] for move_line in self.browse(cr, uid, ids, context): if move_line.debit == 0 and move_line.credit == 0: continue policy = move_line.account_id.user_type.partner_policy if policy == 'always' and not move_line.partner_id: raise orm.except_orm(_('Error :'), _("Partner policy is set to 'Always' " "with account %s '%s' but the " "partner is missing in the account " "move line with label '%s'." % (move_line.account_id.code, move_line.account_id.name, move_line.name))) elif policy == 'never' and move_line.partner_id: raise orm.except_orm(_('Error :'), _("Partner policy is set to 'Never' " "with account %s '%s' but the " "account move line with label '%s' " "has a partner '%s'." % (move_line.account_id.code, move_line.account_id.name, move_line.name, move_line.partner_id.name)))
def _construct_bvr_in_chf(self, bvr_string): if len(bvr_string) != 53: raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in first part')) elif self._check_number(bvr_string[0:12]) != int(bvr_string[12]): raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in second part')) elif self._check_number(bvr_string[14:40]) != int(bvr_string[40]): raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in third part')) elif self._check_number(bvr_string[43:51]) != int(bvr_string[51]): raise orm.except_orm(_('Validation Error'), _('BVR CheckSum Error in fourth part')) else: bvr_struct = {'type': bvr_string[0:2], 'amount': float(bvr_string[2:12])/100, 'reference': bvr_string[14:41], 'bvrnumber': bvr_string[14:20], 'beneficiaire': self._create_bvr_account( bvr_string[43:52] ), 'domain': '', 'currency': '' } return bvr_struct
def generate_detailed_lines(self, cr, uid, ids, context=None): group_pool = self.pool.get('purchase.order.line.group') order_line_pool = self.pool.get('purchase.order.line') group_ids = group_pool.search(cr, uid, []) for master_line in self.browse(cr, uid, ids): if master_line.order_line_ids: raise orm.except_orm( _('Error'), _("Detailed lines generated yet (for master line '%s'). " "Remove them first") % master_line.name) if len(master_line.delivery_term_id.line_ids) > len(group_ids): raise orm.except_orm( _('Error'), _("Delivery term lines are %d. Order line groups are %d. " "Please create more groups") % (len(master_line.delivery_term_id.line_ids), len(group_ids))) if not master_line.delivery_term_id.is_total_percentage_correct(): raise orm.except_orm( _('Error'), _("Total percentage of delivery term %s is not equal to 1") % master_line.delivery_term_id.name) for group_index, term_line in enumerate( master_line.delivery_term_id.line_ids ): order_line_vals = self._prepare_order_line( cr, uid, term_line, master_line, group_index=group_index, context=context) order_line_pool.create(cr, uid, order_line_vals, context=context) return True
def generate_report(self, parser, data, objects): """ Build journal entries report in format xml based on company, period and target_move. """ context = parser.actual_context import tempfile account_move_model = self.pool.get('account.move') Etree = ET.ElementTree() # #Begin of Sql query Section period_id = data["form"]["period_id"] target_move = data["form"]["target_move"] period_obj = self.pool['account.period'] period = period_obj.browse( parser.cr, parser.uid, period_id, context=parser.actual_context ) sql_select = """ SELECT al.debit,al.credit,al.amount_currency,al.date,al.journal_id, al.ref,al.move_id,al.name,al.currency_id,al.account_id, al.reconcile_id, al.reconcile_partial_id FROM account_move_line al """ sql_where = """ WHERE al.period_id = %(period_id)s AND al.state = 'valid' AND al.account_id in %(account_id)s """ search_params = { 'period_id': period_id, 'account_id': self._get_lst_account( parser.cr, parser.uid, data['form']['account_id'], context=context ) } sql_joins = '' sql_orderby = 'ORDER BY al.move_id' if target_move == 'posted': sql_joins = 'LEFT JOIN account_move am ON move_id = am.id ' sql_where += """ AND am.state = %(target_move)s""" search_params.update({'target_move': target_move}) query_sql = ' '.join((sql_select, sql_joins, sql_where, sql_orderby)) parser.cr.execute(query_sql, search_params) lines = parser.cr.dictfetchall() # #End of Sql query Section if not lines: raise orm.except_orm( _('Error'), _('Not found Journal Entries for this Period.\n' 'Choose another Period!') ) # if Journal Entries have lines will create the xml report # Create main journal entries node type_request = data["form"]["type_request"] order_num = data["form"]["order_num"] pro_num = data["form"]["pro_num"] from datetime import datetime time_period = datetime.strptime(period.date_start, "%Y-%m-%d") polizas = ET.Element('PLZ:Polizas') # namespace polizas.set("xsi:schemaLocation", "www.sat.gob.mx/esquemas/ContabilidadE/1_1/PolizasPeriodo http://www.sat.gob.mx/esquemas/ContabilidadE/1_1/PolizasPeriodo/PolizasPeriodo_1_1.xsd") polizas.set("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance") polizas.set("xmlns:PLZ", "www.sat.gob.mx/esquemas/ContabilidadE/1_1/PolizasPeriodo") polizas.set('Version', '1.1') polizas.set('RFC', parser.company.partner_id.vat_split) polizas.set('Mes', str(time_period.month).rjust(2, '0')) polizas.set('Anio', str(time_period.year)) polizas.set('TipoSolicitud', type_request) if order_num: polizas.set('NumOrden', order_num) if pro_num: polizas.set('NumTramite', pro_num) Etree._setroot(polizas) # Groups of account move based on move id, # each group is one journal entries groups = defaultdict(list) for line in lines: groups[line.get('move_id')].append(line) for move_id in groups.keys(): # Load account.move object for current move lines move = account_move_model.browse( parser.cr, parser.uid, move_id, context=context ) cumul_debit = 0.0 cumul_credit = 0.0 poliza = ET.SubElement(polizas, 'PLZ:Poliza') # Check for SAT journal type using journal_entry_type_xml = self.get_journal_entrie_type_xml( parser, groups[move_id] ) for item_line in groups[move_id]: # required fields on journal entry node cumul_debit += item_line.get('debit') or 0.0 cumul_credit += item_line.get('credit') or 0.0 journal_id = item_line.get('journal_id') # #Begin on transaction node trans_concept = item_line.get('name') acccta = self.get_trans_cta( parser.cr, parser.uid, item_line.get('account_id'), context=context ) transaccion = ET.SubElement(poliza, 'PLZ:Transaccion') transaccion.set("NumCta", acccta.code) transaccion.set("DesCta", acccta.name) transaccion.set("Concepto", (trans_concept).encode( 'utf-8', 'ignore').decode('utf-8') ) transaccion.set("Debe", str(item_line.get('debit'))) transaccion.set("Haber", str(item_line.get('credit'))) # Begin on journal entry node if journal_entry_type_xml in [2]: # Get the check data related to the journal entry move self.get_check_data( parser.cr, parser.uid, parser.active_ids, context, move_id, journal_id, acccta.id, transaccion ) # #End of Check section # # Begin for Invoice CFDI Section self.get_invoice_data( parser.cr, parser.uid, parser.active_ids, context, item_line, journal_entry_type_xml, transaccion ) # # End for Invoice CFDI Section # Get the Transferencia or otrMetodoPago data related for the Journal Entry move if journal_entry_type_xml in [1, 2]: self.get_transferencia_data( parser.cr, parser.uid, item_line, journal_entry_type_xml, transaccion, context=context, ) self.get_otr_metodo_pago( parser.cr, parser.uid, item_line, journal_entry_type_xml, transaccion, context=context, ) # # End of Transferencia Section # #End on transaction node journal_entry_concept = self.get_journal_entry_concept( parser.cr, parser.uid, parser.active_ids, context, move_id ) concept_description = ("%s | $%s | $%s") % ( (journal_entry_concept).encode( 'utf-8', 'ignore').decode( 'utf-8'), cumul_debit, cumul_credit ) poliza.set("NumUnIdenPol", move.name) poliza.set("Concepto", concept_description) poliza.set("Fecha", move.date) # #End on journal entry node # Write data into temporal file with tempfile.NamedTemporaryFile(delete=False) as report: Etree.write(report.name, encoding='UTF-8') self.fname = report.name return
def run(self): # Recupera il record dal database self.filedata_obj = self.pool['bom.import'] self.bomImportRecord = self.filedata_obj.browse(self.cr, self.uid, self.bomImportID, context=self.context) self.file_name = self.bomImportRecord.file_name.split('\\')[-1] self.update_product_name = self.bomImportRecord.update_product_name # =================================================== Config = getattr(settings, self.bomImportRecord.format) self.HEADER = Config.HEADER_BOM self.REQUIRED = Config.REQUIRED_BOM self.BOM_PRODUCT_SEARCH = Config.BOM_PRODUCT_SEARCH self.BOM_SEARCH = Config.BOM_SEARCH # self.BOM_WARNINGS = Config.BOM_WARNINGS # self.BOM_ERRORS = Config.BOM_ERRORS # Default values self.BOM_DEFAULTS = Config.BOM_DEFAULTS self.FORMAT = self.bomImportRecord.format if not len(self.HEADER) == len(Config.COLUMNS_BOM.split(',')): pprint(zip(self.HEADER, Config.COLUMNS_BOM.split(','))) raise orm.except_orm( 'Error: wrong configuration!', 'The length of columns and headers must be the same') self.RecordBom = namedtuple('RecordBom', Config.COLUMNS_BOM) # =================================================== try: table, self.numberOfLines = import_sheet( self.file_name, self.bomImportRecord.content_text) except Exception as e: # Annulla le modifiche fatte self.cr.rollback() self.cr.commit() title = "Import failed" message = "Errore nell'importazione del file %s" % self.file_name + "\nDettaglio:\n\n" + str( e) if DEBUG: ### Debug _logger.debug(message) pdb.set_trace() self.notify_import_result(self.cr, self.uid, title, message, error=True, record=self.bomImportRecord) if DEBUG: # Importa il listino self.process(self.cr, self.uid, table) # Genera il report sull'importazione self.notify_import_result(self.cr, self.uid, self.message_title, 'Importazione completata', record=self.bomImportRecord) else: # Elaborazione del listino prezzi try: # Importa il listino self.process(self.cr, self.uid, table) # Genera il report sull'importazione self.notify_import_result(self.cr, self.uid, self.message_title, 'Importazione completata', record=self.bomImportRecord) except Exception as e: # Annulla le modifiche fatte self.cr.rollback() self.cr.commit() title = "Import failed" message = "Errore alla linea %s" % str( self.processed_lines) + "\nDettaglio:\n\n" + str(e) if DEBUG: ### Debug _logger.debug(message) pdb.set_trace() self.notify_import_result(self.cr, self.uid, title, message, error=True, record=self.bomImportRecord)
def makeOrder(self, cr, uid, ids, context=None): """ This function create Quotation on given case. @param self: The object pointer @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param ids: List of crm make sales' ids @param context: A standard dictionary for contextual values @return: Dictionary value of created sales order. """ if context is None: context = self.pool['res.users'].context_get(cr, uid) lead_obj = self.pool['crm.lead'] sale_obj = self.pool['sale.order'] partner_obj = self.pool['res.partner'] attachment_obj = self.pool['ir.attachment'] data = context and context.get('active_ids', []) or [] for make in self.browse(cr, uid, ids, context=context): partner = make.partner_id partner_addr = partner_obj.address_get( cr, uid, [partner.id], ['default', 'invoice', 'delivery', 'contact']) partner.write({'customer': True}) pricelist_id = partner.property_product_pricelist.id fpos_id = partner.property_account_position and partner.property_account_position.id or False payment_term = partner.property_payment_term and partner.property_payment_term.id or False new_ids = [] for lead in lead_obj.browse(cr, uid, data, context=context): if not partner and lead.partner_id: partner = lead.partner_id fpos_id = partner.property_account_position and partner.property_account_position.id or False payment_term = partner.property_payment_term and partner.property_payment_term.id or make.shop_id.payment_default_id and make.shop_id.payment_default_id.id or False partner_addr = partner_obj.address_get( cr, uid, [partner.id], ['default', 'invoice', 'delivery', 'contact']) pricelist_id = partner.property_product_pricelist and partner.property_product_pricelist.id or make.shop_id.pricelist_id and make.shop_id.pricelist_id.id if False in partner_addr.values(): raise orm.except_orm( _('Data Insufficient!'), _('Customer has no addresses defined!')) vals = { 'origin': _('Opportunity: %s') % str(lead.id), 'section_id': lead.section_id and lead.section_id.id or False, 'categ_id': lead.categ_id and lead.categ_id.id or False, 'shop_id': make.shop_id.id, 'partner_id': partner.id, 'pricelist_id': pricelist_id, 'partner_invoice_id': partner_addr['invoice'], 'partner_order_id': lead.partner_address_id and lead.partner_address_id.id or lead.partner_address_id, 'partner_shipping_id': lead.partner_address_id and lead.partner_address_id.id or partner_addr['delivery'], 'date_order': fields.date.context_today(self, cr, uid, context=context), 'fiscal_position': fpos_id, 'payment_term': payment_term, 'user_id': make.user_id.id, # 'user_id': partner and partner.user_id and partner.user_id.id or case.user_id and case.user_id.id, 'note': lead.description or '', 'contact_id': lead.contact_id and lead.contact_id.id or False } new_id = sale_obj.create(cr, uid, vals, context=context) sale_order = sale_obj.browse(cr, uid, new_id, context=context) lead_obj.write(cr, uid, [lead.id], { 'ref': 'sale.order,%s' % new_id, 'sale_order': new_id }, context) new_ids.append(new_id) message = _("Opportunity '%s' is converted to Quotation.") % ( lead.name) self.log(cr, uid, lead.id, message) lead_obj.message_append( cr, uid, [lead], _("Converted to Sales Quotation(%s).") % sale_order.name, context=context) if make.move_attachment: attachment_ids = attachment_obj.search( cr, uid, [('res_model', '=', 'crm.lead'), ('res_id', '=', lead.id)], context=context) for attachment_id in attachment_ids: attachment_obj.write(cr, uid, attachment_id, { 'res_model': 'sale.order', 'res_id': new_id }, context) if make.close: lead_obj.case_close(cr, uid, data) if not new_ids: return {'type': 'ir.actions.act_window_close'} if len(new_ids) <= 1: value = { 'domain': str([('id', 'in', new_ids)]), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'sale.order', 'view_id': False, 'type': 'ir.actions.act_window', 'res_id': new_ids and new_ids[0] } else: value = { 'domain': str([('id', 'in', new_ids)]), 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'sale.order', 'view_id': False, 'type': 'ir.actions.act_window', 'res_id': new_ids } return value
def invoice_validate_check(self, cr, uid, ids, context=None): context = context or self.pool['res.users'].context_get(cr, uid) res = super(account_invoice, self).invoice_validate_check(cr, uid, ids, context) if not res: return res for invoice in self.browse(cr, uid, ids, context): if invoice.type in ['out_invoice', 'out_refund']: if invoice.fiscal_position and invoice.fiscal_position.is_tax_exemption: # i'm on a Lettera intento, so check validity date_invoice = invoice.date_invoice or datetime.date.today( ).strftime(DEFAULT_SERVER_DATE_FORMAT) if date_invoice > invoice.fiscal_position.end_validity: raise orm.except_orm( _('Invoice'), _('Impossible to Validate, fiscal position {fiscal} is overdue' ).format(fiscal=invoice.fiscal_position.name)) if invoice.fiscal_position.amount: plafond_amount = invoice.fiscal_position.amount - invoice.fiscal_position.invoice_amount - invoice.amount_untaxed if plafond_amount < 0: raise orm.except_orm( _('Invoice'), _('Impossible to Validate, fiscal position {fiscal} is overdue' ).format( fiscal=invoice.fiscal_position.name)) if invoice.company_id.stop_invoice_internal_number: invoice_ids = self.search( cr, 1, [('internal_number', '!=', True), ('type', '=', 'out_invoice'), ('journal_id', '=', invoice.journal_id.id), ('state', '=', 'draft')], context=context) for invoice_old in self.browse( cr, 1, [x for x in invoice_ids if x not in ids], context): if not context.get('no_except', False): raise orm.except_orm( _('Invoice'), _('Impossible to Validate, there are just an invoice of {partner} that was just validate with number {invoice_number}' ).format(partner=invoice_old.partner_id.name, invoice_number=invoice_old. internal_number)) else: return False if not invoice.payment_term and invoice.company_id.check_invoice_payment_term: if not context.get('no_except', False): raise orm.except_orm( _('Invoice'), _('Impossible to Validate, need to set Payment Term on invoice of {partner}' ).format(partner=invoice.partner_id.name)) else: return False if invoice.payment_term and invoice.company_id.check_invoice_payment_term and invoice.payment_term.type == 'BB' and not invoice.partner_bank_id and invoice.type == 'out_invoice': if invoice.partner_id.company_bank_id: invoice.write({ 'partner_bank_id': invoice.partner_id.company_bank_id.id }) elif not context.get('no_except', False): raise orm.except_orm( _('Invoice'), _('Impossible to Validate, need to set Bank on invoice of {partner}' ).format(partner=invoice.partner_id.name)) else: return False if not invoice.fiscal_position and invoice.company_id.check_invoice_fiscal_position: if not context.get('no_except', False): raise orm.except_orm( _('Invoice'), _('Impossible to Validate, need to set Fiscal Position on invoice of {partner}' ).format(partner=invoice.partner_id.name)) else: return False elif invoice.fiscal_position.required_tax: if invoice.type in ['out_invoice', 'out_refund']: invoice.button_reset_taxes() if not invoice.tax_line: raise orm.except_orm( _('Invoice'), _('Impossible to Validate, need to set on Tax Line on invoice of {partner}' ).format(partner=invoice.partner_id.name)) else: return True if self.required_vat(cr, uid, invoice, context): if not context.get('no_except', False): raise orm.except_orm( _('Invoice'), _('Impossible to Validate, need to set on Partner {partner} VAT' ).format(partner=invoice.partner_id.name)) else: return False elif not invoice.supplier_invoice_number: if not context.get('no_except', False): raise orm.except_orm( _('Supplier Invoice'), _('Impossible to Validate, need to set Supplier invoice nr' )) else: return False # check if internal number is on recovery sequence if invoice.internal_number: recovery_ids = self.pool['ir.sequence_recovery'].search( cr, uid, [('name', '=', 'account.invoice'), ('sequence', '=', invoice.internal_number)], context=context) if recovery_ids: recovery_id = recovery_ids[0] self.pool['ir.sequence_recovery'].write( cr, uid, recovery_id, {'active': False}, context) return True
def action_number(self, cr, uid, ids, context=None): context = context or self.pool['res.users'].context_get(cr, uid) result = super(account_invoice, self).action_number(cr, uid, ids, context) for invoice in self.browse(cr, uid, ids, context): inv_type = invoice.type internal_number = invoice.internal_number number = invoice.number date_invoice = invoice.date_invoice reg_date = invoice.registration_date journal_id = invoice.journal_id.id # fy = obj_inv.period_id.fiscalyear_id fy_id = invoice.period_id.fiscalyear_id.id period = invoice.period_id vat_statement = self.pool[ 'account.vat.period.end.statement'].search( cr, uid, [('period_ids', 'in', period.id)], context=context) if internal_number: already_invoice = self.pool['account.invoice'].search( cr, uid, [('number', '=', internal_number)], context=context) if already_invoice and invoice.id not in already_invoice: raise orm.except_orm( _(u'Force Number Error!'), _(u'There are just another invoice with number {invoice_number}' .format(invoice_number=internal_number))) if vat_statement and self.pool[ 'account.vat.period.end.statement'].browse( cr, uid, vat_statement, context)[0].state != 'draft': raise orm.except_orm( _(u'Period Mismatch Error!'), _(u'Period %s have already a closed vat statement.') % period.name) # COMMENT WRONG CODE # #check correct typing of number - for module account_invoice_force_number (#TODO move code in that module?) # for as_fy in obj_inv.journal_id.sequence_id.fiscal_ids: # prefix = as_fy.sequence_id.prefix # # # check if it isn't an old db with %(fy) in sequence - #TODO show a message to correct the sequences # if prefix and prefix.find('fy') == -1: # continue check only if not found # if as_fy.fiscalyear_id == fy: # padding = as_fy.sequence_id.padding # if len(number) != padding + len(prefix): # raise orm.except_orm( # _('Number Mismatch Error!'), # _('Length not correct: prefix %s with number of %s length') # % (prefix, padding) # ) # # if number[:-padding] != prefix: # raise orm.except_orm( # _('Number Mismatch Error !'), # _('Prefix not correct: %s') # % (prefix) # ) # # if not number[-padding:].isdigit(): # raise orm.except_orm( # _('Number Mismatch Error!'), # _('After prefix only digits are permitted') # ) period_ids = self.pool['account.period'].search( cr, uid, [('fiscalyear_id', '=', fy_id), ('company_id', '=', invoice.company_id.id)], context=context) if inv_type in ['out_invoice', 'out_refund']: res = self.search(cr, uid, [('type', '=', inv_type), ('date_invoice', '>', date_invoice), ('number', '<', number), ('journal_id', '=', journal_id), ('period_id', 'in', period_ids), ('state', 'in', ['open', 'paid'])], context=context) if res and not internal_number: raise orm.except_orm( _(u'Date Inconsistency'), _(u'Cannot create invoice! Post the invoice with a greater date' )) if inv_type in ['in_invoice', 'in_refund']: res = self.search(cr, uid, [('type', '=', inv_type), ('registration_date', '>', reg_date), ('number', '<', number), ('journal_id', '=', journal_id), ('period_id', 'in', period_ids)], context=context) if res and not internal_number: raise orm.except_orm( _(u'Date Inconsistency'), _(u'Cannot create invoice! Post the invoice with a greater date' )) supplier_invoice_number = invoice.supplier_invoice_number partner_id = invoice.partner_id.id res = self.search( cr, uid, [('type', '=', inv_type), ('date_invoice', '=', date_invoice), ('journal_id', '=', journal_id), ('supplier_invoice_number', '=', supplier_invoice_number), ('partner_id', '=', partner_id), ('state', 'not in', ('draft', 'cancel'))], context=context) if res: raise orm.except_orm(_(u'Invoice Duplication'), _(u'Invoice already posted!')) return result
def create_auto_invoice(self, cr, uid, ids, context=None): context = context or {} new_invoice_ids = [] move_obj = self.pool.get('account.move') wf_service = netsvc.LocalService("workflow") for inv in self.browse(cr, uid, ids, context): # ----- Apply Auto Invoice only on supplier invoice/refund if not (inv.type == 'in_invoice' or inv.type == 'in_refund'): continue fiscal_position = inv.fiscal_position # ----- Check if fiscal positon is active for intra CEE invoice if not fiscal_position: continue if not (fiscal_position.active_intra_cee or fiscal_position.active_reverse_charge or fiscal_position.active_extra_ue_service): continue # ----- keep relation between tax and relative intra cee tax for line in inv.invoice_line: # ----- Check if taxes exist on each line if not line.invoice_line_tax_id: raise orm.except_orm( _('Error'), _('You must define a tax for each line \ in Intra CEE Invoice')) # ----- Check if tax has autoinvoice tax for tax in line.invoice_line_tax_id: if not tax.auto_invoice_tax_id: raise orm.except_orm( _('Error'), _('Set an Auto Invoice Tax for tax %s') % (tax.name)) # ----- Get actual invoice copy based on fiscal position flag if fiscal_position.active_intra_cee: new_inv = self.auto_invoice_vals(cr, uid, inv.id, fiscal_position.id, context) elif fiscal_position.active_reverse_charge: new_inv = self.rc_auto_invoice_vals(cr, uid, inv.id, fiscal_position.id, context) elif fiscal_position.active_extra_ue_service: new_inv = self.extra_ue_auto_invoice_vals( cr, uid, inv.id, fiscal_position.id, context) if not new_inv: continue # ----- Create Auto Invoice...Yeah!!!!! # ...Remove analytic account: for line_new in new_inv['invoice_line']: if 'account_analytic_id' in line_new[2]: line_new[2]['account_analytic_id'] = False # ...Remove picking refs: if 'picking_out_ids' in new_inv: new_inv['picking_out_ids'] = False auto_invoice_id = self.create(cr, uid, new_inv, context) new_invoice_ids.append(auto_invoice_id) # ----- Recompute taxes in new invoice self.button_reset_taxes(cr, uid, [auto_invoice_id], context) # ----- Validate invoice wf_service.trg_validate(uid, 'account.invoice', auto_invoice_id, 'invoice_open', cr) # ----- Get new values from auto invoice new_invoice = self.browse(cr, uid, auto_invoice_id, context) # ----- # Create tranfer entry movements # ----- account_move_line_vals = [] # ----- Tax for supplier debit_1 = credit_1 = 0.0 debit_2 = credit_2 = 0.0 debit_3 = credit_3 = 0.0 if inv.type == 'in_invoice': debit_1 = inv.auto_invoice_amount_tax debit_2 = inv.auto_invoice_amount_untaxed credit_3 = inv.auto_invoice_amount_total else: credit_1 = inv.auto_invoice_amount_tax credit_2 = inv.auto_invoice_amount_untaxed debit_3 = inv.auto_invoice_amount_total # To avoid vat lines for invoice without taxes if debit_1 or credit_1: account_move_line_vals.append(( 0, 0, { 'name': 'Tax for Supplier', 'debit': debit_1, 'credit': credit_1, #'partner_id': new_invoice.partner_id.id, 'partner_id': inv.partner_id.id, 'account_id': new_invoice.partner_id.property_account_payable.id, })) # ----- Products values account_move_line_vals.append((0, 0, { 'name': 'Products', 'debit': debit_2, 'credit': credit_2, 'partner_id': new_invoice.partner_id.id, 'account_id': fiscal_position.account_transient_id.id, })) # ----- Invoice Total account_move_line_vals.append((0, 0, { 'name': 'Invoice Total', 'debit': debit_3, 'credit': credit_3, 'partner_id': new_invoice.partner_id.id, 'account_id': new_invoice.partner_id.property_account_receivable.id, })) # ----- Account Move account_move_vals = { 'name': '/', 'state': 'draft', 'journal_id': fiscal_position.journal_transfer_entry_id.id, 'line_id': account_move_line_vals, 'date': inv.registration_date, 'period_id': inv.period_id.id } transfer_entry_id = move_obj.create(cr, uid, account_move_vals, context) move_obj.post(cr, uid, [transfer_entry_id], context) # ----- Link the tranfer entry move and auto invoice # to supplier invoice self.write( cr, uid, [inv.id], { 'auto_invoice_id': auto_invoice_id, 'transfer_entry_id': transfer_entry_id }) # ----- Pay Autoinvoice context.update({'no_compute_wt': True}) voucher_autoinvoice_id = self.voucher_from_invoice( cr, uid, new_invoice.id, new_invoice.amount_total, fiscal_position.journal_transfer_entry_id.id, 'receipt', context) # ---- Create a payment for vat of supplier invoice if inv.auto_invoice_amount_tax: voucher_vat_supplier_id = self.voucher_from_invoice( cr, uid, inv.id, inv.auto_invoice_amount_tax, fiscal_position.journal_transfer_entry_id.id, 'payment', context) # ---- Reconcile Credit of vat supplier payment with transfer move voucher_obj = self.pool['account.voucher'] move_line_obj = self.pool['account.move.line'] transfer_move = move_obj.browse(cr, uid, transfer_entry_id) line_voucher_to_be_reconcile = False line_supplier_to_be_reconcile = False # ...Voucher vat supplier if inv.auto_invoice_amount_tax: voucher_vat_supplier = voucher_obj.browse( cr, uid, voucher_vat_supplier_id) for move_line in voucher_vat_supplier.move_id.line_id: if not move_line.reconcile_id and move_line.credit: line_voucher_to_be_reconcile = move_line.id # ...Transfer line account_payable_id = new_invoice.partner_id.property_account_payable.id for move_line in transfer_move.line_id: if not move_line.reconcile_id and not move_line.reconcile_partial_id \ and move_line.debit \ and move_line.account_id.id == account_payable_id: line_supplier_to_be_reconcile = move_line.id # ...Reconcile if line_voucher_to_be_reconcile and line_supplier_to_be_reconcile: reconcile_ids = [ line_voucher_to_be_reconcile, line_supplier_to_be_reconcile ] move_line_obj.reconcile_partial(cr, uid, reconcile_ids, context=context) # ---- Reconcile Debit of Total Autoinvoice payment with transfer move line_voucher_to_be_reconcile = False line_autoinvoice_to_be_reconcile = False # ...Voucher debit autoinvoice payment voucher_autoinvoice = voucher_obj.browse(cr, uid, voucher_autoinvoice_id) for move_line in voucher_autoinvoice.move_id.line_id: if not move_line.reconcile_id and move_line.debit: line_voucher_to_be_reconcile = move_line.id # ...Transfer line account_receivable_id = new_invoice.partner_id.property_account_receivable.id for move_line in transfer_move.line_id: if not move_line.reconcile_id and not move_line.reconcile_partial_id \ and move_line.credit \ and move_line.account_id.id == account_receivable_id: line_autoinvoice_to_be_reconcile = move_line.id # ...Reconcile if line_voucher_to_be_reconcile and line_autoinvoice_to_be_reconcile: # Same account here x = move_line_obj.browse(cr, uid, line_voucher_to_be_reconcile) y = move_line_obj.browse(cr, uid, line_autoinvoice_to_be_reconcile) if x.account_id.id != y.account_id.id: raise orm.except_orm( _('Error!'), _('Supplier and Partner Autoinvoice haven\'t the same \ customer account\ first.')) reconcile_ids = [ line_voucher_to_be_reconcile, line_autoinvoice_to_be_reconcile ] move_line_obj.reconcile_partial(cr, uid, reconcile_ids, context=context) return new_invoice_ids
def merge_invoice(self, cr, uid, ids, merge_lines=False, journal_id=False, context=None): """ Merge draft invoices. Work only with same partner Moves all lines on the first invoice. @param merge_lines: sum quantities of invoice lines (or not) @type merge_line: boolean return account invoice id """ if not context: context = {} if len(ids) <= 1: return False sql = "SELECT DISTINCT type, state, partner_id FROM account_invoice WHERE id IN (%s)" % ','.join( map(str, ids)) cr.execute(sql) if len(cr.fetchall()) != 1: raise orm.except_orm( _('Invalid action !'), _('Can not merge invoice(s) on different partners or states !') ) merged_inv_id = 0 inv_line_obj = self.pool.get('account.invoice.line') default = {} if journal_id: default = {'journal_id': journal_id} for inv in self.browse(cr, uid, ids, context): if inv.state != 'draft': raise orm.except_orm( _('Invalid action !'), _('Can not merge invoice(s) that are already opened or paid !' )) if merged_inv_id == 0: merged_inv_id = self.copy(cr, uid, inv.id, default=default, context=context) wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'account.invoice', inv.id, 'invoice_cancel', cr) self.write(cr, uid, inv.id, {'merged_invoice_id': merged_inv_id}, context=context) self.write(cr, uid, merged_inv_id, {'origin': 'merged'}, context=context) else: line_ids = inv_line_obj.search(cr, uid, [('invoice_id', '=', inv.id)]) for inv_lin in inv_line_obj.browse(cr, uid, line_ids): mrg_pdt_ids = inv_line_obj.search( cr, uid, [('invoice_id', '=', merged_inv_id), ('product_id', '=', inv_lin.product_id.id)]) if merge_lines == True and mrg_pdt_ids: qty = inv_line_obj._can_merge_quantity( cr, uid, mrg_pdt_ids[0], inv_lin.id) if qty: inv_line_obj.write(cr, uid, mrg_pdt_ids, {'quantity': qty}) else: inv_line_obj.copy(cr, uid, inv_lin.id, { 'invoice_id': merged_inv_id, }) else: if merge_lines: inv_line_obj.copy(cr, uid, inv_lin.id, { 'invoice_id': merged_inv_id, }) else: inv_line_obj.copy( cr, uid, inv_lin.id, { 'invoice_id': merged_inv_id, 'origin': inv_lin.invoice_id.origin }) wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'account.invoice', inv.id, 'invoice_cancel', cr) self.write(cr, uid, [inv.id], {'merged_invoice_id': merged_inv_id}, context=context) if merged_inv_id: self.button_compute(cr, uid, [merged_inv_id]) return merged_inv_id
def get_invoice_data( self, cr, uid, ids, context, acc_move_line, journal_entry_type_xml, transaccion ): """ Get the info of the Invoice based on the move_id of journal entry """ invoice_obj = self.pool.get('account.invoice') filters = [] if ( journal_entry_type_xml in [1, 2] and (acc_move_line.get('reconcile_id') or acc_move_line.get('reconcile_partial_id')) ): # if journal entry in Ingreso|Egreso reconcile_field = acc_move_line.get( 'reconcile_id') and 'reconcile_id' or 'reconcile_partial_id' reconcile_value = acc_move_line.get( 'reconcile_id') or acc_move_line.get('reconcile_partial_id') filters = [(reconcile_field, '=', reconcile_value), ('journal_id', '!=', acc_move_line.get('journal_id'))] move_obj = self.pool.get('account.move.line') move_id = move_obj.search(cr, uid, filters) if move_id: move_data = move_obj.browse(cr, uid, move_id) for move in move_data: filters = [ ('move_id', '=', move.move_id.id), ('account_id', '=', acc_move_line.get('account_id')) ] else: return False elif journal_entry_type_xml in [3]: filters = [('move_id', '=', acc_move_line.get('move_id')), ('account_id', '=', acc_move_line.get('account_id'))] else: return False invoice_id = invoice_obj.search(cr, uid, filters) invoice_data = invoice_obj.browse(cr, uid, invoice_id) # Process each invoice if any for invoice in invoice_data: # Only add information about Comprobante # if there is an UUID at current invoice if invoice.cfdi_folio_fiscal: if not invoice.partner_id.vat_split: raise orm.except_orm( _('Error'), _('Partner %s do not have a VAT number assigned') % invoice.partner_id.name ) comprobante = ET.SubElement(transaccion, 'PLZ:CompNal') comprobante.set('MontoTotal', str(invoice.amount_total)) comprobante.set('RFC', invoice.partner_id.vat_split) comprobante.set('UUID_CFDI', invoice.cfdi_folio_fiscal) if invoice.currency_id.name != 'MXN': comprobante.set('Moneda', invoice.currency_id.name) comprobante.set('TipCamb', str(invoice.rate)) return True
def renumber(self, cr, uid, ids, context=None): """ Action that renumbers all the posted moves on the given journal and periods, and returns their ids. """ logger = logging.getLogger("account_renumber") form = self.browse(cr, uid, ids[0], context=context) period_ids = [x.id for x in form.period_ids] journal_ids = [x.id for x in form.journal_ids] number_next = form.number_next or 1 if not (period_ids and journal_ids): raise orm.except_orm(_('No Data Available'), _('No records found for your selection!')) logger.debug("Searching for account moves to renumber.") move_obj = self.pool['account.move'] sequence_obj = self.pool['ir.sequence'] sequences_seen = [] for period in period_ids: move_ids = move_obj.search(cr, uid, [('journal_id', 'in', journal_ids), ('period_id', '=', period), ('state', '=', 'posted')], limit=0, order='date,id', context=context) if not move_ids: continue logger.debug("Renumbering %d account moves." % len(move_ids)) for move in move_obj.browse(cr, uid, move_ids, context=context): sequence_id = self.get_sequence_id_for_fiscalyear_id( cr, uid, sequence_id=move.journal_id.sequence_id.id, fiscalyear_id=move.period_id.fiscalyear_id.id) if sequence_id not in sequences_seen: sequence_obj.write(cr, SUPERUSER_ID, [sequence_id], {'number_next': number_next}) sequences_seen.append(sequence_id) # Generate (using our own get_id) and write the new move number c = {'fiscalyear_id': move.period_id.fiscalyear_id.id} new_name = sequence_obj.next_by_id( cr, uid, move.journal_id.sequence_id.id, context=c) # Note: We can't just do a # "move_obj.write(cr, uid, [move.id], {'name': new_name})" # cause it might raise a # ``You can't do this modification on a confirmed entry`` # exception. cr.execute('UPDATE account_move SET name=%s WHERE id=%s', (new_name, move.id)) logger.debug("%d account moves renumbered." % len(move_ids)) sequences_seen = [] form.write({'state': 'renumber'}) data_obj = self.pool['ir.model.data'] view_ref = data_obj.get_object_reference(cr, uid, 'account', 'view_move_tree') view_id = view_ref and view_ref[1] or False, res = { 'type': 'ir.actions.act_window', 'name': _("Renumbered account moves"), 'res_model': 'account.move', 'domain': ("[('journal_id','in',%s), ('period_id','in',%s), " "('state','=','posted')]" % (journal_ids, period_ids)), 'view_type': 'form', 'view_mode': 'tree', 'view_id': view_id, 'context': context, 'target': 'current', } return res
def get_otr_metodo_pago( self, cr, uid, acc_move_line, journal_entry_type_xml, transaccion, context=None ): """ Get the info of the otrMetodoPago based on the move_id of journal entry """ context = context or {} payment_obj = self.pool.get('account.voucher') # Gets the default credit account ID for the journal journal = self.pool.get('account.journal').browse( cr, uid, acc_move_line.get('journal_id'), context=context ) credit_acc_id = journal.default_credit_account_id.id # If the used account is not the default credit account # don't continue if acc_move_line.get('account_id') != credit_acc_id: return if not journal.payment_type_id: raise orm.except_orm( _('Error'), _('Journal %s do not have set a Payment Type') % journal.name ) # If Payment Type is Check or Transfer, then exit if journal.payment_type_id.code in ['02', '03']: return payment_line_ids = payment_obj.search( cr, uid, [('move_id', '=', acc_move_line.get('move_id'))], context=context ) payment_line_data = payment_obj.browse( cr, uid, payment_line_ids, context=context ) # Process each payment line if any for payment_line in payment_line_data: otrmetodopago = ET.SubElement(transaccion, 'PLZ:OtrMetodoPago') # MetPagoPol # Fecha # Benef # RFC # Monto # Moneda # TipCamb partnerBank = payment_line.partner_bank_id partner = payment_line.partner_id # If dealing with income money rfc = partner.vat_split or 'N/A' benef = partner.name otrmetodopago.set('MetPagoPol', str(journal.payment_type_id.code)) otrmetodopago.set('Fecha', payment_line.date) otrmetodopago.set('Benef', benef) otrmetodopago.set('RFC', rfc) otrmetodopago.set('Monto', str(payment_line.amount)) if payment_line.is_multi_currency: otrmetodopago.set('Moneda', str(payment_line.currency_id.name)) otrmetodopago.set('TipCamb', str(payment_line.payment_rate)) return
def create_invoice(self, cr, uid, ids, context={}): invoice_obj = self.pool.get('account.invoice') appointment_obj = self.pool.get('medical.appointment') apps = context.get('active_ids') pats = [] for app_id in apps: pats.append( appointment_obj.browse(cr, uid, app_id).patient.name.id) if pats.count(pats[0]) == len(pats): invoice_data = {} for app_id in apps: appointment = appointment_obj.browse(cr, uid, app_id) # Check if the appointment is invoice exempt, and stop the invoicing process if appointment.no_invoice: raise orm.except_orm( _('UserError'), _('The appointment is invoice exempt')) if appointment.validity_status == 'invoiced': if len(apps) > 1: raise orm.except_orm( _('UserError'), _('At least one of the selected appointments is already invoiced' )) else: raise orm.except_orm(_('UserError'), _('Appointment already invoiced')) if appointment.validity_status == 'no': if len(apps) > 1: raise orm.except_orm( _('UserError'), _('At least one of the selected appointments can not be invoiced' )) else: raise orm.except_orm( _('UserError'), _('You can not invoice this appointment')) if appointment.patient.name.id: invoice_data['partner_id'] = appointment.patient.name.id res = self.pool.get('res.partner').address_get( cr, uid, [appointment.patient.name.id], ['contact', 'invoice']) invoice_data['address_contact_id'] = res['contact'] invoice_data['address_invoice_id'] = res['invoice'] invoice_data[ 'account_id'] = appointment.patient.name.property_account_receivable.id invoice_data[ 'fiscal_position'] = appointment.patient.name.property_account_position and appointment.patient.name.property_account_position.id or False invoice_data[ 'payment_term'] = appointment.patient.name.property_payment_term and appointment.patient.name.property_payment_term.id or False prods_data = {} for app_id in apps: appointment = appointment_obj.browse(cr, uid, app_id) logging.debug( 'appointment = %s; appointment.consultations = %s', appointment, appointment.consultations) if appointment.consultations: logging.debug( 'appointment.consultations = %s; appointment.consultations.id = %s', appointment.consultations, appointment.consultations.id) if prods_data.has_key(appointment.consultations.id): prods_data[ appointment.consultations.id]['quantity'] += 1 else: a = appointment.consultations.product_tmpl_id.property_account_income.id if not a: a = appointment.consultations.categ_id.property_account_income_categ.id prods_data[appointment.consultations.id] = { 'product_id': appointment.consultations.id, 'name': appointment.consultations.name, 'quantity': 1, 'account_id': a, 'price_unit': appointment.consultations.lst_price } else: raise orm.except_orm( _('UserError'), _('No consultation service is connected with the selected appointments' )) product_lines = [] for prod_id, prod_data in prods_data.items(): product_lines.append((0, 0, { 'product_id': prod_data['product_id'], 'name': prod_data['name'], 'quantity': prod_data['quantity'], 'account_id': prod_data['account_id'], 'price_unit': prod_data['price_unit'] })) invoice_data['invoice_line'] = product_lines invoice_id = invoice_obj.create(cr, uid, invoice_data) appointment_obj.write(cr, uid, apps, {'validity_status': 'invoiced'}) return { 'domain': "[('id','=', " + str(invoice_id) + ")]", 'name': 'Create invoice', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.invoice', 'type': 'ir.actions.act_window' } else: raise orm.except_orm( _('UserError'), _('When multiple appointments are selected, patient must be the same' ))
def write(self, cr, user, ids, vals, context=None): if context is None: context = {} if ('property_account_position' in vals and vals['property_account_position']): fiscal_obj = self.pool.get('account.fiscal.position') fiscal_data = fiscal_obj.browse(cr, user, vals['property_account_position']) if fiscal_data and fiscal_data.name == 'Regime Intra comunitario': t_partner_data = self.browse(cr, user, ids, context=context) for t_partner in t_partner_data: if 'delivery' not in vals and not t_partner.delivery: raise orm.except_orm( _('Error!'), _('Campo "Condizioni di Consegna" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'way_of_freight' not in vals and not t_partner.way_of_freight: raise orm.except_orm( _('Error!'), _('Campo "Metodo di Trasporto" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'payment_methods' not in vals and not t_partner.payment_methods: raise orm.except_orm( _('Error!'), _('Campo "Metodi di Pagamento" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'country_provenance' not in vals and not t_partner.country_provenance: raise orm.except_orm( _('Error!'), _('Campo "Paese di Provenienza" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'country_origin' not in vals and not t_partner.country_origin: raise orm.except_orm( _('Error!'), _('Campo "Paese di Origine" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'delivery' in vals and not vals['delivery']: raise orm.except_orm( _('Error!'), _('Campo "Condizioni di Consegna" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'way_of_freight' in vals and not vals['way_of_freight']: raise orm.except_orm( _('Error!'), _('Campo "Metodo di Trasporto" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'payment_methods' in vals and not vals['payment_methods']: raise orm.except_orm( _('Error!'), _('Campo "Metodi di Pagamento" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'country_provenance' in vals and not vals[ 'country_provenance']: raise orm.except_orm( _('Error!'), _('Campo "Paese di Provenienza" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) if 'country_origin' in vals and not vals['country_origin']: raise orm.except_orm( _('Error!'), _('Campo "Paese di Origine" obbligatorio se si imposta come posizione fiscale "Regime Intra comunitario"!' )) res = super(account_cee_res_partner, self).write(cr, user, ids, vals, context) return res
def _calculate_records(self, cr, uid, ids, context=None, recalculate=True): report_obj = self.pool['l10n.es.aeat.mod340.report'] mod340 = report_obj.browse(cr, uid, ids)[0] invoices340 = self.pool['l10n.es.aeat.mod340.issued'] invoices340_rec = self.pool['l10n.es.aeat.mod340.received'] period_obj = self.pool['account.period'] issued_obj = self.pool['l10n.es.aeat.mod340.tax_line_issued'] received_obj = self.pool['l10n.es.aeat.mod340.tax_line_received'] mod340.write({ 'state': 'calculated', 'calculation_date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) }) if not mod340.company_id.partner_id.vat: raise orm.except_orm(mod340.company_id.partner_id.name, _('This company dont have NIF')) code = '340' + mod340.fiscalyear_id.code + '' code += mod340.period_to.date_stop[5:7] + '0001' account_period_ids = period_obj.build_ctx_periods( cr, uid, mod340.period_from.id, mod340.period_to.id) if len(account_period_ids) is 0: raise orm.except_orm( _('Error'), _("The periods selected don't belong to the fiscal year %s") % (mod340.fiscalyear_id.name)) # Limpieza de las facturas calculadas anteriormente del_ids = invoices340.search(cr, uid, [('mod340_id', '=', mod340.id)]) if del_ids: invoices340.unlink(cr, uid, del_ids, context=context) del_ids = invoices340_rec.search(cr, uid, [('mod340_id', '=', mod340.id)]) if del_ids: invoices340_rec.unlink(cr, uid, del_ids, context=context) domain = [('period_id', 'in', account_period_ids), ('state', 'in', ('open', 'paid'))] invoice_obj = self.pool['account.invoice'] invoice_ids = invoice_obj.search(cr, uid, domain, context=context) for invoice in invoice_obj.browse(cr, uid, invoice_ids, context): include = False for tax_line in invoice.tax_line: if tax_line.base_code_id and tax_line.base: if tax_line.base_code_id.mod340: include = True break if include: if invoice.partner_id.vat_type == '1': if not invoice.partner_id.vat: raise orm.except_orm( _('La siguiente empresa no tiene asignado nif:'), invoice.partner_id.name) if invoice.partner_id.vat: country_code, nif = (re.match( r"([A-Z]{0,2})(.*)", invoice.partner_id.vat).groups()) else: country_code = False nif = False values = { 'mod340_id': mod340.id, 'partner_id': invoice.partner_id.id, 'partner_vat': nif, 'representative_vat': '', 'partner_country_code': country_code, 'invoice_id': invoice.id, 'base_tax': invoice.amount_untaxed, 'amount_tax': invoice.amount_tax, 'total': invoice.amount_total, 'date_invoice': invoice.date_invoice, } if invoice.type in ['out_refund', 'in_refund']: values['base_tax'] *= -1 values['amount_tax'] *= -1 values['total'] *= -1 if invoice.type in ['out_invoice', 'out_refund']: invoice_created = invoices340.create(cr, uid, values) if invoice.type in ['in_invoice', 'in_refund']: invoice_created = invoices340_rec.create(cr, uid, values) tot_tax_invoice = 0 check_tax = 0 check_base = 0 # Add the invoices detail to the partner record for tax_line in invoice.tax_line: if tax_line.base_code_id and tax_line.base: if tax_line.base_code_id.mod340: tax_percentage = tax_line.amount / tax_line.base values = { 'name': tax_line.name, 'tax_percentage': tax_percentage, 'tax_amount': tax_line.tax_amount, 'base_amount': tax_line.base_amount, 'invoice_record_id': invoice_created, } if invoice.type in ("out_invoice", "out_refund"): issued_obj.create(cr, uid, values) if invoice.type in ("in_invoice", "in_refund"): received_obj.create(cr, uid, values) tot_tax_invoice += tax_line.tax_amount check_tax += tax_line.tax_amount if tax_percentage >= 0: check_base += tax_line.base_amount if invoice.type in ['out_invoice', 'out_refund']: invoices340.write(cr, uid, invoice_created, {'amount_tax': tot_tax_invoice}) if invoice.type in ['in_invoice', 'in_refund']: invoices340_rec.write(cr, uid, invoice_created, {'amount_tax': tot_tax_invoice}) sign = 1 if invoice.type in ('out_refund', 'in_refund'): sign = -1 if str(invoice.amount_untaxed * sign) != str(check_base): raise orm.except_orm( "REVIEW INVOICE", _('Invoice %s, Amount untaxed Lines %.2f do not ' 'correspond to AmountUntaxed on Invoice %.2f') % (invoice.number, check_base, invoice.amount_untaxed * sign)) if recalculate: mod340.write({ 'state': 'calculated', 'calculation_date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) }) return True
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): context = context or {} if not context.get('active_model', False): raise orm.except_orm(_('Error'), _('Missing active_model in context!')) multi_model = context.get('multi_model', False) model_id_name = context.get('model_id_name', False) if multi_model and not model_id_name: raise orm.except_orm(_('Error'), _('Missing model id key name!')) target_obj = self.pool[context.get('active_model')] discriminant_field = target_obj._discriminant_field document_ids = context.get('active_ids') documents = target_obj.browse(cr, uid, document_ids, context=context) discriminants = [] for document in documents: if not document['is_duplicate_detected']: raise orm.except_orm( _('Error'), MSG.get(context['active_model'], _('You must only select duplicated entries!'))) discriminants.append(document[discriminant_field]) if len(set(discriminants)) != 1: raise orm.except_orm( _('Error'), _('You must select entries related to the same field "%s"!') % target_obj._columns[discriminant_field].string) if len(document_ids) == 1: discriminant = target_obj._is_discriminant_m2o( ) and discriminants[0].id or discriminants[0] domain_search = [(discriminant_field, '=', discriminant), ('is_duplicate_allowed', '=', True)] allowed_document_ids = target_obj.search(cr, SUPERUSER_ID, domain_search, context=context) if not allowed_document_ids: raise orm.except_orm(_('Error'), _('You must select more than one entry!')) res = super(allow_duplicate_wizard, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu) return res
def do_partial(self, cr, uid, ids, context=None): assert len( ids ) == 1, 'Partial picking processing may only be done one at a time' stock_picking = self.pool['stock.picking'] stock_move = self.pool['stock.move'] pallet_move_obj = self.pool['pallet.move'] uom_obj = self.pool['product.uom'] partial = self.browse(cr, uid, ids[0], context=context) partial_data = {'delivery_date': partial.date} picking_type = partial.picking_id.type pallet = {} for wizard_line in partial.move_ids: line_uom = wizard_line.product_uom move_id = wizard_line.move_id.id # Quantity must be Positive if wizard_line.quantity < 0: raise orm.except_orm(_('Warning!'), _('Please provide Proper Quantity !')) if wizard_line.quantity > 0 and wizard_line.tracking and not ( wizard_line.prodlot_id or wizard_line.new_prodlot_code): raise orm.except_orm( _('Error!'), _('Please provide lot on product "%s"' % wizard_line.product_id.name)) # Compute the quantity for respective wizard_line in the line uom (this jsut do the rounding if necessary) qty_in_line_uom = uom_obj._compute_qty(cr, uid, line_uom.id, wizard_line.quantity, line_uom.id) if line_uom.factor and line_uom.factor != 0: if float_compare(qty_in_line_uom, wizard_line.quantity, precision_rounding=line_uom.rounding) != 0: raise orm.except_orm( _('Warning'), _('The uom rounding does not allow you to ship "%s %s", only roundings of "%s %s" is accepted by the uom.' ) % (wizard_line.quantity, line_uom.name, line_uom.rounding, line_uom.name)) if move_id: # Check rounding Quantity.ex. # picking: 1kg, uom kg rounding = 0.01 (rounding to 10g), # partial delivery: 253g # => result= refused, as the qty left on picking would be 0.747kg and only 0.75 is accepted by the uom. initial_uom = wizard_line.move_id.product_uom # Compute the quantity for respective wizard_line in the initial uom qty_in_initial_uom = uom_obj._compute_qty( cr, uid, line_uom.id, wizard_line.quantity, initial_uom.id) without_rounding_qty = (wizard_line.quantity / line_uom.factor) * initial_uom.factor if float_compare(qty_in_initial_uom, without_rounding_qty, precision_rounding=initial_uom.rounding) != 0: raise orm.except_orm( _('Warning'), _('The rounding of the initial uom does not allow you to ship "%s %s", as it would let a quantity of "%s %s" to ship and only roundings of "%s %s" is accepted by the uom.' ) % (wizard_line.quantity, line_uom.name, wizard_line.move_id.product_qty - without_rounding_qty, initial_uom.name, initial_uom.rounding, initial_uom.name)) else: seq_obj_name = 'stock.picking.' + picking_type move_id = stock_move.create( cr, uid, { 'name': self.pool['ir.sequence'].get( cr, uid, seq_obj_name), 'product_id': wizard_line.product_id.id, 'product_qty': wizard_line.quantity, 'product_uom': wizard_line.product_uom.id, 'prodlot_id': wizard_line.prodlot_id.id, 'location_id': wizard_line.location_id.id, 'location_dest_id': wizard_line.location_dest_id.id, 'picking_id': partial.picking_id.id }, context=context) stock_move.action_confirm(cr, uid, [move_id], context) # Pack tracking existing_tracking = wizard_line.tracking_id.id if existing_tracking: # avoid creating a tracking twice # self.pool['stock.tracking').write(cr, uid, existing_tracking, {'name': partial.tracking_code}) tracking_id = existing_tracking else: if partial.tracking_code: tracking_id = self.pool['stock.tracking'].search( cr, uid, [('name', '=', partial.tracking_code)]) if not tracking_id: tracking_id = self.pool['stock.tracking'].create( cr, uid, { 'name': partial.tracking_code, }) else: tracking_id = tracking_id[0] self.pool['stock.move'].write(cr, uid, move_id, {'tracking_id': tracking_id}) tracking_id = int(tracking_id) else: tracking_id = None partial_data['move%s' % move_id] = { 'product_id': wizard_line.product_id.id, 'product_qty': wizard_line.quantity, 'product_uom': wizard_line.product_uom.id, 'prodlot_id': wizard_line.prodlot_id.id, 'balance': wizard_line.balance, 'tracking_id': tracking_id, 'pallet_qty': wizard_line.pallet_qty, 'pallet_id': wizard_line.pallet_id.id, } if (picking_type == 'in') and (wizard_line.product_id.cost_method == 'average'): partial_data['move%s' % wizard_line.move_id.id].update( product_price=wizard_line.cost, product_currency=wizard_line.currency.id) # compose the pallet list if wizard_line.pallet_id.id not in pallet: pallet[wizard_line.pallet_id.id] = 0 pallet[wizard_line.pallet_id.id] += wizard_line.pallet_qty # here i want to create 2 lines for pallet_id, pallet_qty in pallet.iteritems(): if pallet_qty: pallet_move_obj.create( cr, uid, { 'name': partial.picking_id.name, 'date': partial.picking_id.date, 'partner_id': partial.picking_id.partner_id.id, 'move': partial.picking_id.type, 'stock_picking_id': partial.picking_id.id, 'pallet_qty': pallet_qty, 'pallet_id': pallet_id, }, context=context) delivered_pack_id = stock_picking.do_partial(cr, uid, [partial.picking_id.id], partial_data, context=context) if picking_type == 'in': res = self.pool['ir.model.data'].get_object_reference( cr, uid, 'stock', 'view_picking_in_form') else: res = self.pool['ir.model.data'].get_object_reference( cr, uid, 'stock', 'view_picking_out_form') vals = { 'type': 'ir.actions.act_window', 'name': _('Delivered'), 'view_type': 'form', 'view_mode': 'form', 'view_id': res and res[1] or False, 'res_model': 'stock.picking', 'nodestroy': True, 'target': 'current', 'res_id': int(delivered_pack_id[partial.picking_id.id]), } if partial.picking_id.id == vals['res_id']: vals['type'] = 'ir.actions.act_window_close' return vals
def _price_rule_get_multi(self, cr, uid, pricelist, products_by_qty_by_partner, context=None): context = context or {} date = context.get('date') or time.strftime('%Y-%m-%d') date = date[0:10] products = map(lambda x: x[0], products_by_qty_by_partner) currency_obj = self.pool['res.currency'] product_obj = self.pool['product.template'] product_uom_obj = self.pool['product.uom'] supplierinfo_obj = self.pool['product.supplierinfo'] price_type_obj = self.pool['product.price.type'] if not products: return {} version = False for v in pricelist.version_id: if ((v.date_start is False) or (v.date_start <= date)) and ((v.date_end is False) or (v.date_end >= date)): version = v break if not version: raise orm.except_orm( _(u'Warning!'), _(u"At least one pricelist has no active version !\nPlease create or activate one." )) categ_ids = {} for p in products: categ = p.categ_id while categ: categ_ids[categ.id] = True categ = categ.parent_id categ_ids = categ_ids.keys() is_product_template = products[0]._name == "product.template" if is_product_template: prod_tmpl_ids = [tmpl.id for tmpl in products] # all variants of all products prod_ids = [ p.id for p in list( chain.from_iterable( [t.product_variant_ids for t in products])) ] else: prod_ids = [product.id for product in products] prod_tmpl_ids = [ product.product_tmpl_id.id for product in products ] # Load all rules cr.execute( 'SELECT i.id ' 'FROM product_pricelist_item AS i ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = any(%s)) ' 'AND (product_id IS NULL OR (product_id = any(%s))) ' 'AND ((categ_id IS NULL) OR (categ_id = any(%s))) ' 'AND (price_version_id = %s) ' 'ORDER BY sequence, min_quantity desc', (prod_tmpl_ids, prod_ids, categ_ids, version.id)) item_ids = [x[0] for x in cr.fetchall()] items = self.pool['product.pricelist.item'].browse(cr, uid, item_ids, context=context) price_types = {} results = {} for product, qty, partner in products_by_qty_by_partner: results[product.id] = 0.0 rule_id = False price = False # Final unit price is computed according to `qty` in the `qty_uom_id` UoM. # An intermediary unit price may be computed according to a different UoM, in # which case the price_uom_id contains that UoM. # The final price will be converted to match `qty_uom_id`. qty_uom_id = context.get('uom') or product.uom_id.id price_uom_id = product.uom_id.id qty_in_product_uom = qty if qty_uom_id != product.uom_id.id: try: qty_in_product_uom = product_uom_obj._compute_qty( cr, uid, context['uom'], qty, product.uom_id.id or product.uos_id.id) except orm.except_orm: # Ignored - incompatible UoM in context, use default product UoM pass for rule in items: if rule.min_quantity and qty_in_product_uom < rule.min_quantity: continue if is_product_template: if rule.product_tmpl_id and product.id != rule.product_tmpl_id.id: continue if rule.product_id and \ (product.product_variant_count > 1 or product.product_variant_ids[0].id != rule.product_id.id): # product rule acceptable on template if has only one variant continue else: if rule.product_tmpl_id and product.product_tmpl_id.id != rule.product_tmpl_id.id: continue if rule.product_id and product.id != rule.product_id.id: continue if rule.categ_id: cat = product.categ_id while cat: if cat.id == rule.categ_id.id: break cat = cat.parent_id if not cat: continue print "rule base", rule.base if rule.base == -1: if rule.base_pricelist_id: price_tmp = self._price_get_multi( cr, uid, rule.base_pricelist_id, [(product, qty, partner)], context=context)[product.id] ptype_src = rule.base_pricelist_id.currency_id.id price_uom_id = qty_uom_id price = currency_obj.compute(cr, uid, ptype_src, pricelist.currency_id.id, price_tmp, round=False, context=context) elif rule.base == -2: seller = False for seller_id in product.seller_ids: if (not partner) or (seller_id.name.id != partner): continue seller = seller_id if not seller and product.seller_ids: seller = product.seller_ids[0] if seller: qty_in_seller_uom = qty seller_uom = seller.product_uom.id if qty_uom_id != seller_uom: qty_in_seller_uom = product_uom_obj._compute_qty( cr, uid, qty_uom_id, qty, to_uom_id=seller_uom) price_uom_id = seller_uom for line in seller.pricelist_ids: if line.min_quantity <= qty_in_seller_uom: price = line.price elif rule.base == -3: if rule.price_version_id: price = rule.fixed_price elif rule.base == -4: price = product.cost_price else: if rule.base not in price_types: price_types[rule.base] = price_type_obj.browse( cr, uid, int(rule.base)) price_type = price_types[rule.base] # price_get returns the price in the context UoM, i.e. qty_uom_id price_uom_id = qty_uom_id price = currency_obj.compute( cr, uid, price_type.currency_id.id, pricelist.currency_id.id, product_obj._price_get(cr, uid, [product], price_type.field, context=context)[product.id], round=False, context=context) if price is not False and rule.base != -3: price_limit = price price *= (1.0 + (rule.price_discount or 0.0)) if rule.price_round: price = tools.float_round( price, precision_rounding=rule.price_round) convert_to_price_uom = ( lambda price: product_uom_obj._compute_price( cr, uid, product.uom_id.id, price, price_uom_id)) if rule.price_surcharge: price_surcharge = convert_to_price_uom( rule.price_surcharge) price += price_surcharge if rule.price_min_margin: price_min_margin = convert_to_price_uom( rule.price_min_margin) price = max(price, price_limit + price_min_margin) if rule.price_max_margin: price_max_margin = convert_to_price_uom( rule.price_max_margin) price = min(price, price_limit + price_max_margin) rule_id = rule.id break # Final price conversion to target UoM price = product_uom_obj._compute_price(cr, uid, price_uom_id, price, qty_uom_id) results[product.id] = (price, rule_id) return results
def danfe_join(self, cr, uid, ids, context=None): account_i_obj = self.pool.get('account.invoice').browse( cr, uid, context['active_ids'], context=context) output = PdfFileWriter() list_attachments = [] for rec_account_invoice in account_i_obj: attach_pool = self.pool.get('ir.attachment') attach_ids = attach_pool.search( cr, uid, [('res_id', '=', rec_account_invoice.id), ('res_model', '=', 'account.invoice')]) if attach_ids: for ir_attachment in attach_pool.browse(cr, uid, attach_ids, context=None): if ir_attachment.name[-3:] == 'pdf': list_attachments.append(ir_attachment) for ir_attachment_obj in list_attachments: fd, file_name = mkstemp() os.write( fd, base64.decodestring( attach_pool.browse(cr, uid, ir_attachment_obj.id).datas)) pdf = PdfFileReader(file(file_name, 'rb')) pg_pdf = pdf.getNumPages() for i in range(0, pg_pdf): output.addPage(pdf.getPage(i)) os.remove(os.path.join(file_name)) if not list_attachments: raise orm.except_orm( _('Error'), 'The PDF file is empty, no exists attachments for join the file.' ) fd_fl, file_name_fl = mkstemp() outputStream = file(file_name_fl, 'w+b') output.write(outputStream) outputStream.seek(0) ps = outputStream.read() outputStream.close() w_file = base64.b64encode(ps) w_timezone = self.pool.get('res.users').browse(cr, uid, uid).tz now = datetime.now(pytz.timezone(w_timezone)) filename = 'DANFE_UN_%04d-%02d-%02d.pdf' % (now.year, now.month, now.day) id_danfe_join = self.create(cr, uid, { 'data': w_file, 'filename': filename, 'invisible': True }, context=context) os.remove(os.path.join(file_name_fl)) return { 'type': 'ir.actions.act_window', 'res_model': 'danfe.join', 'view_mode': 'form', 'view_type': 'form', 'res_id': id_danfe_join, 'views': [(False, 'form')], 'target': 'new' }
def _get_formated_declaration_record(self, report, context=None): """ Returns a type 1, declaration/company, formated record. · All amounts must be positives · Numeric fields with no data must be filled with zeros · Alfanumeric/Alfabetic fields with no data must be filled with empty spaces · Numeric fields must be right aligned and filled with zeros on the left · Alfanumeric/Alfabetic fields must be uppercase left aligned, filled with empty spaces on right side. No special characters allowed unless specified in field description Format of the record: Tipo registro 1 – Registro de declarante: Posiciones Naturaleza Descripción 1 Numérico Tipo de Registro Constante = '1' 2-4 Numérico Modelo Declaración Constante = '349' 5-8 Numérico Ejercicio 9-17 Alfanumérico NIF del declarante 18-57 Alfanumérico Apellidos y nombre o razón social del declarante 58 Alfabético Tipo de soporte 59-67 Numérico (9) Teléfono contacto 68-107 Alfabético Apellidos y nombre contacto 108-120 Numérico Número identificativo de la declaración 121-122 Alfabético Declaración complementaria o substitutiva 123-135 Numérico Número identificativo de la declaración anterior 136-137 Alfanumérico Período 138-146 Numérico Número total de operadores intracomunitarios 147-161 Numérico Importe de las operaciones intracomunitarias - 147-159 Numérico Importe de las operaciones intracomunitarias (parte entera) - 160-161 Numérico Importe de las operaciones intracomunitarias (parte decimal) 162-170 Numérico Número total de operadores intracomunitarios con rectificaciones 171-185 Numérico Importe total de las rectificaciones - 171-183 Numérico Importe total de las rectificaciones (parte entera) - 184-185 Numérico Importe total de las rectificaciones (parte decimal) 186 Alfabético Indicador cambio periodicidad en la obligación a declarar (X o '') 187-390 Blancos ---------------------------------------- 391-399 Alfanumérico NIF del representante legal 400-487 Blancos ---------------------------------------- 488-500 Sello electrónico """ assert report, 'No Report defined' try: fiscal_year = int((report.fiscalyear_id.code or '')[:4]) except: raise orm.except_orm(_('Fiscal year code'), _('First four characters of fiscal year \ code must be numeric and contain the fiscal \ year number. Please, fix it and try again.')) company_name = self._get_company_name_with_title(report.company_id, context=context) period = report.period_selection == 'MO' and report.month_selection \ or report.period_selection text = '' # Empty text text += '1' # Tipo de Registro text += '349' # Modelo Declaración text += self._formatNumber(fiscal_year, 4) # Ejercicio text += self._formatString(report.company_vat, 9) # NIF del declarante text += self._formatString(company_name, 40) # Apellidos y nombre o razón social del declarante text += self._formatString(report.support_type, 1) # Tipo de soporte text += self._formatString(report.contact_phone.replace(' ', ''), 9) # Persona de contacto (Teléfono) text += self._formatString(report.contact_name, 40) # Persona de contacto (Apellidos y nombre) text += self._formatNumber(report.number, 13) # Número identificativo de la declaración text += self._formatString(report.type, 2).replace('N', ' ') # Declaración complementaria o substitutiva text += self._formatNumber(report.previous_number, 13) # Número identificativo de la declaración anterior text += self._formatString(period, 2) # Período text += self._formatNumber(report.total_partner_records, 9) # Número total de operadores intracomunitarios text += self._formatNumber(report.total_partner_records_amount, 13, 2) # Importe total de las operaciones intracomunitarias (parte entera) text += self._formatNumber(report.total_partner_refunds, 9) # Número total de operadores intracomunitarios con rectificaciones text += self._formatNumber(report.total_partner_refunds_amount, 13, 2) # Importe total de las rectificaciones text += self._formatBoolean(report.frequency_change) # Indicador cambio periodicidad en la obligación a declarar text += 204 * ' ' # Blancos text += self._formatString(report.representative_vat, 9) # NIF del representante legal #text += 9*' ' text += 88 * ' ' # Blancos text += 13 * ' ' # Sello electrónico text += '\r\n' # Retorno de carro + Salto de línea assert len(text) == 502, _("The type 1 record must be 502 characters long") return text
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 """ mod_obj = self.pool.get('ir.model.data') xml_data = self._get_datas(cr, uid, ids, context=context) data_file = '' # TODO: change code to use etree + add schema verification data_head = """<?xml version="1.0" encoding="ISO-8859-1"?> <ns2:IntraConsignment xmlns="http://www.minfin.fgov.be/InputCommon" xmlns:ns2="http://www.minfin.fgov.be/IntraConsignment" IntraListingsNbr="1"> """ data_comp_period = '\n\t\t<ns2:Declarant>' \ '\n\t\t\t<VATNumber>%(vatnum)s</VATNumber>' \ '\n\t\t\t<Name>%(company_name)s</Name>' \ '\n\t\t\t<Street>%(street)s</Street>' \ '\n\t\t\t<PostCode>%(post_code)s</PostCode>' \ '\n\t\t\t<City>%(city)s</City>' \ '\n\t\t\t<CountryCode>%(country)s</CountryCode>' \ '\n\t\t\t<EmailAddress>%(email)s</EmailAddress>' \ '\n\t\t\t<Phone>%(phone)s</Phone>' \ '\n\t\t</ns2:Declarant>' \ % (xml_data) if xml_data['period_code']: month_quarter = xml_data['period_code'][:2] year = xml_data['period_code'][2:] if month_quarter.startswith('3'): data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Quarter>' + month_quarter[1] + \ '</ns2:Quarter> \n\t\t\t<ns2:Year>' + year + \ '</ns2:Year>\n\t\t</ns2:Period>' elif month_quarter.startswith('0') and month_quarter.endswith('0'): data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Year>' + year + \ '</ns2:Year>\n\t\t</ns2:Period>' else: data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Month>' + month_quarter + \ '</ns2:Month> \n\t\t\t<ns2:Year>' + year + \ '</ns2:Year>\n\t\t</ns2:Period>' else: year = xml_data['year'] if xml_data['starting_month'] != xml_data['ending_month']: month_quarter = '3' + xml_data['quarter'] #starting month and ending month of selected period are not the same #it means that the accounting is not based on periods of 1 month but on quarters data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Quarter>%(quarter)s</ns2:Quarter> \n\t\t\t<ns2:Year>%(year)s</ns2:Year>\n\t\t</ns2:Period>' % ( xml_data) else: month_quarter = xml_data['ending_month'] data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Month>' + xml_data['ending_month'] + \ '</ns2:Month> \n\t\t\t<ns2:Year>%(year)s</ns2:Year>\n\t\t</ns2:Period>' \ % (xml_data) records = xml_data['clientlist'] client_datas = [] previous_record = {} for record in records: if record['vat'] == previous_record.get('vat') \ and record['intra_code'] == previous_record.get('intra_code'): client_datas.pop() record['amt'] += previous_record['amt'] record['amount'] = '%.2f' % record['amt'] record[ 'partner_name'] += ', ' + previous_record['partner_name'] client_datas.append(record) previous_record = record data_clientinfo = '' for client_data in client_datas: if not client_data['vatnum']: raise orm.except_orm( _('Insufficient Data!'), _('No vat number defined for %s.') % client_data['partner_name']) data_clientinfo += '\n\t\t<ns2:IntraClient SequenceNumber="%(seq)s">' \ '\n\t\t\t<ns2:CompanyVATNumber issuedBy="%(country)s">%(vatnum)s</ns2:CompanyVATNumber>' \ '\n\t\t\t<ns2:Code>%(intra_code)s</ns2:Code>' \ '\n\t\t\t<ns2:Amount>%(amount)s</ns2:Amount>' \ '\n\t\t</ns2:IntraClient>' \ % (client_data) data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum)s">' % ( xml_data) data_file += data_head + data_decl + data_comp_period + data_clientinfo if xml_data['comments']: data_file += '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>' % ( xml_data) data_file += '\n\t</ns2:IntraListing>\n</ns2:IntraConsignment>' self.write(cr, uid, ids, { 'file_save': base64.encodestring(data_file.encode('utf8')), 'name': 'vat_intra_%s_%s.xml' % (year, month_quarter[0] == '3' and ('Q' + month_quarter[1]) or month_quarter), }, context=context) model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'view_vat_intra_save')], context=context) resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id'] return { 'name': _('Save'), 'context': context, 'view_type': 'form', 'view_mode': 'form', 'res_id': ids[0], 'res_model': 'partner.vat.intra', 'views': [(resource_id, 'form')], 'view_id': 'view_vat_intra_save', 'type': 'ir.actions.act_window', 'target': 'new', }
def _render_tab(self, cr, uid, export_file, template_part, localdict): """Render the output of this template in a tabular format""" template = [] try: delimiter = eval(export_file.delimiter) except TypeError: delimiter = export_file.delimiter # Header & Footer if getattr(export_file, template_part): template.append( self._render(cr, uid, export_file, template_part, localdict)) # Header with fieldnames if template_part == 'header' and export_file.fieldnames_in_header: template.append( delimiter.join((tools.ustr(column.name) for column in export_file.column_ids))) # Body if template_part == 'body': sub_objects = localdict['object'] if export_file.refer_to_underlying_object: sub_objects = eval(export_file.records, localdict) if not isinstance(sub_objects, list): sub_objects = [sub_objects] for index, sub_object in enumerate(sub_objects): localdict['line_number'] += index localdict['object'] = sub_object line = [] for column in export_file.column_ids: try: column_value = _render_unicode(column.value or '', localdict) if column.default_value and not column_value: column_value = _render_unicode( column.default_value, localdict) if column.column_validator: validation = eval(column.column_validator, localdict) if not validation: try: exception_msg = _render_unicode( column.exception_msg, localdict) except Exception: exception_msg = column.exception_msg raise except_orm(_('Error'), exception_msg) column_value = tools.ustr(column_value) if column_value: if column.min_width: column_value = getattr( column_value, column.justify)( column.min_width, tools.ustr(column.fillchar)) if column.max_width: column_value = column_value[:column.max_width] if not column.not_string and export_file.extension != 'xls' and export_file.quotechar: try: quotechar = export_file.quotechar and eval( export_file.quotechar) or '' except TypeError: quotechar = export_file.quotechar column_value = '%(quotechar)s%(column_value)s%(quotechar)s' % { 'column_value': quotechar and column_value.replace( quotechar, "\\" + quotechar) or column_value, 'quotechar': quotechar, } line.append(column_value) except Exception, e: raise except_orm(_('Error'), 'column %s: %s' % (column.name, e)) template.append(delimiter.join(line))
def action_move_create(self): self.button_reset_taxes() #print 'dentro de action_move_create*************' if self.period(self.id) == 1: raise ValidationError( 'Fecha de comprobante no pertenece al periodo declarado') """ Creates invoice related analytics and financial move lines """ account_invoice_tax = self.env['account.invoice.tax'] account_move = self.env['account.move'] retencion_line = self.env['fiscal.retencion.ln'] for inv in self: # cambios de NELIO CIGUENCIA #RERV if modificado para que ingrese solo en nota de credito if (inv.type == 'out_refund' and inv.tipo == 'nota_credito_cliente' ) or (inv.type == 'in_refund' and inv.tipo == 'nota_credito_proveedor'): for line in inv.invoice_line: if line.quantity == 0.000: line.unlink() for line in inv.invoice_line: total_resta = 0.00 #RERV modificado para que haga la resta bien total_resta = float(line.cantidad_facturada - (line.cantidad_devuelta + line.quantity)) cantidad_restante = float(line.cantidad_facturada - line.cantidad_devuelta) if total_resta < 0: raise except_orm( _('Error!'), _("La cantidad de {0} es mayor a la cantidad restante. (Quedan {1})" .format(line.product_id.name, int(cantidad_restante)))) # fin cambios de NELIO CIGUENCIA if not inv.journal_id.sequence_id: raise except_orm( _('Error!'), _('Please define sequence on the journal related to this invoice.' )) if not inv.invoice_line: raise except_orm(_('No Invoice Lines!'), _('Please create some invoice lines.')) if inv.move_id: continue ctx = dict(self._context, lang=inv.partner_id.lang) if not inv.date_invoice: from openerp import fields inv.with_context(ctx).write( {'date_invoice': fields.Date.context_today(self)}) date_invoice = inv.date_invoice company_currency = inv.company_id.currency_id # create the analytical lines, one move line per invoice line iml = inv._get_analytic_lines() # check if taxes are all computed compute_taxes = account_invoice_tax.compute(inv) inv.check_tax_lines(compute_taxes) if inv.type == 'in_invoice': if not self.numeroret: res = self.calcularSecuencial(inv) ## anibal #print 'tranquilos ya regrese con secuencial = ', res inv.write(res) # self.actualiza_secuencial(inv) if inv.type == 'out_invoice': ## anibal #print 'voy a calcular secuencial de factura ', self.numerofac ## anibal #print 'res = self.calcularSecuencial(inv) ' if not self.numerofac: #RERV comentado me enceraba punto emision res = self.calcularSecuencial(inv) #print 'mira reeeeeeeeeeeeessss ', res inv.write(res) ## pongo esta linea a ver que pasa self.actualiza_secuencial_factura(inv) ## fin de pongo esta linea a ver que pasa if inv.type == 'out_refund': ## anibal print 'voy a calcular secuencial de factura ', self.numerofac ## anibal #print 'res = self.calcularSecuencial(inv) ' res = self.calcularSecuencial(inv) if not self.numerofac: #RERV comentado me enceraba punto emision # res = self.calcularSecuencial(inv) print 'mira reeeeeeeeeeeeessss ', res # inv.write(res) ## pongo esta linea a ver que pasa self.actualiza_secuencial_factura(inv) ## fin de pongo esta linea a ver que pasa if self.env['res.users'].has_group( 'account.group_supplier_inv_check_total'): if inv.type in ('in_invoice', 'in_refund') and abs( inv.check_total - inv.amount_total) >= (inv.currency_id.rounding / 2.0): raise except_orm( _('Bad Total!'), _('Please verify the price of the invoice!\nThe encoded total does not match the computed total.' )) if inv.payment_term: total_fixed = total_percent = 0 for line in inv.payment_term.line_ids: if line.value == 'fixed': total_fixed += line.value_amount if line.value == 'procent': total_percent += line.value_amount total_fixed = (total_fixed * 100) / (inv.amount_total or 1.0) if (total_fixed + total_percent) > 100: raise except_orm( _('Error!'), _("Cannot create the invoice.\nThe related payment term is probably misconfigured as it gives a computed amount greater than the total invoiced amount. In order to avoid rounding issues, the latest line of your payment term must be of type 'balance'." )) iml += account_invoice_tax.move_line_get(inv.id) if inv.type == 'in_invoice': iml += retencion_line.move_line_get(inv.id) if inv.type in ('in_invoice', 'in_refund'): ref = inv.reference else: ref = inv.number diff_currency = inv.currency_id != company_currency # create one move line for the total and possibly adjust the other lines amount total, total_currency, iml = inv.with_context( ctx).compute_invoice_totals(company_currency, ref, iml) name = inv.name or inv.supplier_invoice_number or '/' totlines = [] if inv.payment_term: totlines = inv.with_context(ctx).payment_term.compute( total, date_invoice)[0] if totlines: res_amount_currency = total_currency ctx['date'] = date_invoice for i, t in enumerate(totlines): if inv.currency_id != company_currency: amount_currency = company_currency.with_context( ctx).compute(t[1], inv.currency_id) else: amount_currency = False # last line: add the diff res_amount_currency -= amount_currency or 0 if i + 1 == len(totlines): amount_currency += res_amount_currency iml.append({ 'type': 'dest', 'name': name, 'price': t[1], 'account_id': inv.account_id.id, 'date_maturity': t[0], 'amount_currency': diff_currency and amount_currency, 'currency_id': diff_currency and inv.currency_id.id, 'ref': ref, }) else: iml.append({ 'type': 'dest', 'name': name, 'price': total, 'account_id': inv.account_id.id, 'date_maturity': inv.date_due, 'amount_currency': diff_currency and total_currency, 'currency_id': diff_currency and inv.currency_id.id, 'ref': ref }) date = date_invoice part = self.env['res.partner']._find_accounting_partner( inv.partner_id) line = [(0, 0, self.line_get_convert(l, part.id, date)) for l in iml] line = inv.group_lines(iml, line) journal = inv.journal_id.with_context(ctx) if journal.centralisation: raise except_orm( _('User Error!'), _('You cannot create an invoice on a centralized journal. Uncheck the centralized counterpart box in the related journal from the configuration menu.' )) line = inv.finalize_invoice_move_lines(line) move_vals = { 'ref': inv.reference or inv.name, 'line_id': line, 'journal_id': journal.id, 'date': inv.date_invoice, 'narration': inv.comment, 'company_id': inv.company_id.id, } ctx['company_id'] = inv.company_id.id period = inv.period_id if not period: period = period.with_context(ctx).find(date_invoice)[:1] if period: move_vals['period_id'] = period.id for i in line: i[2]['period_id'] = period.id ctx['invoice'] = inv move = account_move.with_context(ctx).create(move_vals) # make the invoice point to that move vals = { 'move_id': move.id, 'period_id': period.id, 'move_name': move.name, } inv.with_context(ctx).write(vals) # Pass invoice in context in method post: used if you want to get the same # account move reference when creating the same invoice after a cancelled one: move.post() #CAMBIOS NELIO PARA LA RECONCILACION DE NOTAS DE CREDITO #RERV if agregado para que solo entre en nota de credito if (inv.type == 'out_refund' and inv.tipo == 'nota_credito_cliente' ) or (inv.type == 'in_refund' and inv.tipo == 'nota_credito_proveedor'): self.reconciliar(self.env.cr, self.env.uid, self.ids, self.env.context) self._log_event() return True
def nfe_export(self, cr, uid, ids, context=None): data = self.read(cr, uid, ids, [], context=context)[0] inv_obj = self.pool.get('account.invoice') active_ids = self._get_invoice_ids(cr, uid, data, context) export_inv_ids = [] export_inv_numbers = [] company_ids = [] err_msg = '' if not active_ids: err_msg = u'Não existe nenhum documento fiscal para ser exportado!' for inv in inv_obj.browse(cr, uid, active_ids, context=context): if inv.state not in ('sefaz_export'): err_msg += u"O Documento Fiscal %s não esta definida para ser \ exportação para a SEFAZ.\n" % inv.internal_number elif not inv.issuer == '0': err_msg += u"O Documento Fiscal %s é do tipo externa e não \ pode ser exportada para a receita.\n" % inv.internal_number else: inv_obj.write( cr, uid, [inv.id], { 'nfe_export_date': False, 'nfe_access_key': False, 'nfe_status': False, 'nfe_date': False }) message = "O Documento Fiscal %s foi \ exportado." % inv.internal_number inv_obj.log(cr, uid, inv.id, message) export_inv_ids.append(inv.id) company_ids.append(inv.company_id.id) export_inv_numbers.append(inv.internal_number) if len(set(company_ids)) > 1: err_msg += u'Não é permitido exportar Documentos \ Fiscais de mais de uma empresa, por favor selecione Documentos \ Fiscais da mesma empresa.' if export_inv_ids: if len(export_inv_numbers) > 1: name = 'nfes%s-%s.%s' % (time.strftime('%d-%m-%Y'), self.pool.get('ir.sequence').get( cr, uid, 'nfe.export'), data['file_type']) else: name = 'nfe%s.%s' % (export_inv_numbers[0], data['file_type']) mod_serializer = __import__( 'l10n_br_account_product.sped.nfe.serializer.' + data['file_type'], globals(), locals(), data['file_type']) func = getattr(mod_serializer, 'nfe_export') nfes = func(cr, uid, export_inv_ids, data['nfe_environment'], '200', context) for nfe in nfes: #if nfe['message']: #status = 'error' #else: #status = 'success' #self.pool.get(self._name + '_result').create( #cr, uid, {'document': nfe['key'], #'message': nfe['message'], #'status': status, #'wizard_id': data['id']}) nfe_file = nfe['nfe'].encode('utf8') self.write(cr, uid, ids, { 'file': base64.b64encode(nfe_file), 'state': 'done', 'name': name }, context=context) if err_msg: raise orm.except_orm(_('Error!'), _("'%s'") % _(err_msg, )) mod_obj = self.pool.get('ir.model.data') model_data_ids = mod_obj.search( cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'l10n_br_account_product_nfe_export_invoice_form')], context=context) resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id'] return { 'type': 'ir.actions.act_window', 'res_model': self._name, 'view_mode': 'form', 'view_type': 'form', 'res_id': data['id'], 'views': [(resource_id, 'form')], 'target': 'new', }
def write(self, cr, uid, ids, vals, context=None): """ Implement a trigger to retrieve the corresponding move line when the invoice_id changes """ statement_line_obj = self.pool.get('account.bank.statement.line') transaction_obj = self.pool.get('banking.import.transaction') if not vals or not ids: return True wiz = self.browse(cr, uid, ids[0], context=context) # The following fields get never written # they are just triggers for manual matching # which populates regular fields on the transaction manual_invoice_ids = vals.pop('manual_invoice_ids', []) manual_move_line_ids = vals.pop('manual_move_line_ids', []) res = super(banking_transaction_wizard, self).write(cr, uid, ids, vals, context=context) wiz.refresh() # Process the logic of the written values # An invoice is selected from multiple candidates if vals and 'invoice_id' in vals: if (wiz.import_transaction_id.match_type == 'invoice' and wiz.import_transaction_id.invoice_id): found = False # the current value might apply if (wiz.move_line_id and wiz.move_line_id.invoice and wiz.move_line_id.invoice == wiz.invoice_id): found = True else: # Otherwise, retrieve the move line for this invoice # Given the arity of the relation, there is are always # multiple possibilities but the move lines here are # prefiltered for having account_id.type payable/receivable # and the regular invoice workflow should only come up with # one of those only. for move_line in wiz.import_transaction_id.move_line_ids: if (move_line.invoice == wiz.import_transaction_id.invoice_id): transaction_obj.write( cr, uid, wiz.import_transaction_id.id, { 'move_line_id': move_line.id, }, context=context) statement_line_obj.write( cr, uid, wiz.import_transaction_id.statement_line_id.id, { 'partner_id': move_line.partner_id.id or False, 'account_id': move_line.account_id.id, }, context=context) found = True break # Cannot match the invoice if not found: orm.except_orm( _("No entry found for the selected invoice"), _("No entry found for the selected invoice. " + "Try manual reconciliation.")) if manual_move_line_ids or manual_invoice_ids: move_line_obj = self.pool.get('account.move.line') invoice_obj = self.pool.get('account.invoice') statement_line_obj = self.pool.get('account.bank.statement.line') # Rewrite *2many directive notation if manual_invoice_ids: manual_invoice_ids = ( [i[1] for i in manual_invoice_ids if i[0] == 4] + [j for i in manual_invoice_ids if i[0] == 6 for j in i[2]]) if manual_move_line_ids: manual_move_line_ids = ( [i[1] for i in manual_move_line_ids if i[0] == 4] + [ j for i in manual_move_line_ids if i[0] == 6 for j in i[2] ]) for wiz in self.browse(cr, uid, ids, context=context): #write can be called multiple times for the same values #that doesn't hurt above, but it does here if wiz.match_type and (len(manual_move_line_ids) > 1 or len(manual_invoice_ids) > 1): continue todo = [] for invoice in invoice_obj.browse(cr, uid, manual_invoice_ids, context=context): found_move_line = False if invoice.move_id: for line in invoice.move_id.line_id: if line.account_id.type in ('receivable', 'payable'): todo.append((invoice.id, line.id)) found_move_line = True break if not found_move_line: raise orm.except_orm( _("Cannot select for reconcilion"), _("No entry found for the selected invoice. ")) for move_line_id in manual_move_line_ids: todo_entry = [False, move_line_id] move_line = move_line_obj.read(cr, uid, move_line_id, ['invoice'], context=context) if move_line['invoice']: todo_entry[0] = move_line['invoice'][0] todo.append(todo_entry) while todo: todo_entry = todo.pop() move_line = move_line_obj.browse(cr, uid, todo_entry[1], context) transaction_id = wiz.import_transaction_id.id statement_line_id = wiz.statement_line_id.id if len(todo) > 0: statement_line_id = wiz.statement_line_id.split_off( move_line.debit or -move_line.credit)[0] transaction_id = statement_line_obj.browse( cr, uid, statement_line_id, context=context).import_transaction_id.id vals = { 'move_line_id': todo_entry[1], 'move_line_ids': [(6, 0, [todo_entry[1]])], 'invoice_id': todo_entry[0], 'invoice_ids': [(6, 0, [todo_entry[0]] if todo_entry[0] else [])], 'match_type': 'manual', } transaction_obj.clear_and_write(cr, uid, transaction_id, vals, context=context) st_line_vals = { 'account_id': move_line_obj.read(cr, uid, todo_entry[1], ['account_id'], context=context)['account_id'][0], } if todo_entry[0]: st_line_vals['partner_id'] = invoice_obj.browse( cr, uid, todo_entry[0], context=context ).partner_id.commercial_partner_id.id statement_line_obj.write(cr, uid, statement_line_id, st_line_vals, context=context) return res
def _get_datas(self, cr, uid, ids, context=None): """Collects required data for vat intra xml :param ids: id of wizard. :return: dict of all data to be used to generate xml for Partner VAT Intra. :rtype: dict """ if context is None: context = {} obj_user = self.pool.get('res.users') obj_sequence = self.pool.get('ir.sequence') obj_partner = self.pool.get('res.partner') xmldict = {} post_code = street = city = country = data_clientinfo = '' seq = amount_sum = 0 wiz_data = self.browse(cr, uid, ids[0], context=context) comments = wiz_data.comments if wiz_data.tax_code_id: data_company = wiz_data.tax_code_id.company_id else: data_company = obj_user.browse(cr, uid, uid, context=context).company_id # Get Company vat company_vat = data_company.partner_id.vat if not company_vat: raise orm.except_orm( _('insufficient data!'), _('No VAT number associated with your company.')) company_vat = company_vat.replace(' ', '').upper() issued_by = company_vat[:2] if wiz_data.period_code and len(wiz_data.period_code) != 6: raise orm.except_orm(_('Error!'), _('Period code is not valid.')) if not wiz_data.period_ids: raise orm.except_orm(_('Insufficient Data!'), _('Please select at least one Period.')) p_id_list = obj_partner.search(cr, uid, [('vat', '!=', False)], context=context) if not p_id_list: raise orm.except_orm( _('Insufficient Data!'), _('No partner has a VAT number asociated with him.')) seq_declarantnum = obj_sequence.get(cr, uid, 'declarantseq') dnum = company_vat[2:] + seq_declarantnum[-4:] addr = obj_partner.address_get(cr, uid, [data_company.partner_id.id], ['invoice']) email = data_company.partner_id.email or '' phone = data_company.partner_id.phone or '' if addr.get('invoice', False): ads = obj_partner.browse(cr, uid, [addr['invoice']])[0] city = (ads.city or '') post_code = (ads.zip or '') if ads.street: street = ads.street if ads.street2: street += ' ' street += ads.street2 if ads.country_id: country = ads.country_id.code if not country: country = company_vat[:2] if not email: raise orm.except_orm( _('Insufficient Data!'), _('No email address associated with the company.')) if not phone: raise orm.except_orm(_('Insufficient Data!'), _('No phone associated with the company.')) account_periods = wiz_data.period_ids period_end_dates = sorted([x.date_stop for x in account_periods]) period_start_dates = sorted([x.date_start for x in account_periods]) starting_month = period_start_dates[0][5:7] ending_month = period_end_dates[-1][5:7] year = period_end_dates[-1][:4] quarter = str(((int(starting_month) - 1) / 3) + 1) xmldict.update({ 'company_name': data_company.name, 'company_vat': company_vat, 'vatnum': company_vat[2:], #'mand_id': wiz_data.mand_id, # dropped since also not supported in periodical VAT declaration 'sender_date': str(time.strftime('%Y-%m-%d')), 'street': street, 'city': city, 'post_code': post_code, 'country': country, 'email': email, 'phone': phone.replace('/', '').replace('.', '').replace('(', '').replace( ')', '').replace(' ', ''), 'period_code': wiz_data.period_code, 'quarter': quarter, 'starting_month': starting_month, 'ending_month': ending_month, 'year': year, 'clientlist': [], 'comments': comments, 'issued_by': issued_by, }) codes = ('44', '46L', '46T', '48s44', '48s46L', '48s46T') cr.execute( """ SELECT COALESCE(REPLACE(p.vat, ' ',''),'') AS vat, (CASE WHEN t.code IN ('44', '48s44') THEN 'S' WHEN t.code IN ('46L', '48s46L') THEN 'L' WHEN t.code IN ('46T', '48s46T') THEN 'T' ELSE t.code END) AS intra_code, p.name AS partner_name, l.partner_id AS partner_id, SUM(CASE WHEN t.code IN ('48s44','48s46L','48s46T') THEN -l.tax_amount ELSE l.tax_amount END) AS amount FROM account_move_line l INNER JOIN account_tax_code t ON (l.tax_code_id = t.id) LEFT JOIN res_partner p ON (l.partner_id = p.id) WHERE t.code IN %s AND l.period_id IN %s AND t.company_id = %s AND (l.debit + l.credit) != 0 GROUP BY vat, intra_code, partner_name, partner_id ORDER BY vat, intra_code, partner_name, partner_id """, (codes, tuple([p.id for p in wiz_data.period_ids]), data_company.id)) records = cr.dictfetchall() records = filter(lambda x: x['amount'] != 0, records) if not records: raise orm.except_orm( _('No Data Available'), _('No intracom transactions found for the selected period(s) !' )) p_count = 0 previous_vat = previous_code = False for record in records: if not record['vat']: p_count += 1 if record['vat'] != previous_vat or record[ 'intra_code'] != previous_code: seq += 1 previous_vat = record['vat'] previous_code = record['intra_code'] amt = record['amount'] or 0.0 amount_sum += amt xmldict['clientlist'].append({ 'partner_name': record['partner_name'], 'seq': seq, 'vatnum': record['vat'][2:], 'vat': record['vat'], 'country': record['vat'][:2], 'amount': '%.2f' % amt, # used in xml 'amt': amt, # used in pdf 'intra_code': record['intra_code'], }) xmldict.update({ 'dnum': dnum, 'clientnbr': str(seq), 'amountsum': '%.2f' % amount_sum, # used in xml 'amtsum': amount_sum, # used in pdf 'partner_wo_vat': p_count }) return xmldict
def _validate_outgoing_action(self, cr, uid, message, context=None): """ Validation of outgoing messages before sending them to GMC. """ action = message.action_id object_id = message.object_id if action.name == 'CreateCommitment': contract = self.pool.get(action.model).browse(cr, uid, object_id, context=context) # Check that the constituent is known by GMC. partner = contract.correspondant_id message_ids = self.search(cr, uid, [('name', '=', 'UpsertConstituent'), ('partner_id', '=', partner.id), ('state', '=', 'success')], context=context) if not message_ids: raise orm.except_orm( _("Constituent (%s) not sent to GMC") % partner.name, _("Please send the new constituents to GMC before sending" " the commitments.")) # Check that the contract is linked to a child child_id = contract.child_id if not child_id: raise orm.except_orm( _("Contract is not a sponsorship."), _("The new commitment of %s is not linked to a child and " "should not be sent to GMC.") % partner.name) else: # Check that there are no previous sponsorship cancellation # pending. message_ids = self.search(cr, uid, [('name', '=', 'CancelCommitment'), ('child_id', '=', child_id.id), ('state', 'in', ('new', 'pending'))], context=context) if message_ids: raise orm.except_orm( _("Commitment not sent (%s).") % child_id.code, _("Please send the previous commitment cancellation " "before the creation of a new commitment.")) elif action.name == 'CreateGift': # Check that the commitment is known by GMC. invoice_line = self.pool.get(action.model).browse(cr, uid, object_id, context=context) contract = invoice_line.contract_id if contract and contract.correspondant_id and contract.child_id: message_ids = self.search(cr, uid, [('name', '=', 'CreateCommitment'), ('object_id', '=', contract.id), ('state', '=', 'success')], context=context) if not message_ids: raise orm.except_orm( _("Commitment not sent to GMC (%s - %s)") % (contract.partner_id.ref, contract.child_id.code), _("The commitment the gift refers to was not " "sent to GMC.")) else: raise orm.except_orm( _("Unknown sponsorship."), _("The gift (%s - %s) is not related to a sponsorship so " "it should not be sent to GMC.") % (invoice_line.partner_id.name, invoice_line.name)) elif action.name == 'CancelCommitment': # Check that the commitment is known by GMC. message_ids = self.search(cr, uid, [('name', '=', 'CreateCommitment'), ('object_id', '=', object_id), ('state', '=', 'success')], context=context) if not message_ids: contract = self.pool.get(action.model).browse(cr, uid, object_id, context=context) raise orm.except_orm( _("Commitment not sent to GMC (%s - %s)") % (contract.partner_id.ref, contract.child_id.code), _("The commitment was not sent to GMC and therefore " "cannot be cancelled.")) return True
def _get_attendance_duration(self, cr, uid, ids, field_name, arg, context=None): res = {} attendance_pool = self.pool['resource.calendar.attendance'] precision = self.pool['res.users'].browse( cr, uid, uid, context=context).company_id.working_time_precision # 2012.10.16 LF FIX : Get timezone from context active_tz = pytz.timezone( context.get("tz", "UTC") if context else "UTC") str_now = datetime.strftime(datetime.now(), DEFAULT_SERVER_DATETIME_FORMAT) for attendance_id in ids: duration = 0.0 attendance = self.browse(cr, uid, attendance_id, context=context) res[attendance.id] = {} # 2012.10.16 LF FIX : Attendance in context timezone attendance_start = datetime.strptime( attendance.name, DEFAULT_SERVER_DATETIME_FORMAT).replace( tzinfo=pytz.utc).astimezone(active_tz) next_attendance_date = str_now next_attendance_ids = False # should we compute for sign out too? if attendance.action == 'sign_in': next_attendance_ids = self.search( cr, uid, [('employee_id', '=', attendance.employee_id.id), ('name', '>', attendance.name)], order='name', context=context) if next_attendance_ids: next_attendance = self.browse(cr, uid, next_attendance_ids[0], context=context) if next_attendance.action == 'sign_in': # 2012.10.16 LF FIX : Attendance in context timezone raise orm.except_orm( _('Error'), _('Incongruent data: sign-in %s is followed by ' 'another sign-in') % attendance_start) next_attendance_date = next_attendance.name # 2012.10.16 LF FIX : Attendance in context timezone attendance_stop = datetime.strptime( next_attendance_date, DEFAULT_SERVER_DATETIME_FORMAT).replace( tzinfo=pytz.utc).astimezone(active_tz) duration_delta = attendance_stop - attendance_start duration = self.total_seconds(duration_delta) / 3600.0 duration = round(duration / precision) * precision res[attendance.id]['duration'] = duration res[attendance.id]['end_datetime'] = next_attendance_date # If calendar is not specified: working days = 24/7 res[attendance.id]['inside_calendar_duration'] = duration res[attendance.id]['outside_calendar_duration'] = 0.0 reference_calendar = self.get_reference_calendar( cr, uid, attendance.employee_id.id, date=str_now[:10], context=context) if reference_calendar and next_attendance_ids: if reference_calendar: # TODO applicare prima arrotondamento o tolleranza? if reference_calendar.attendance_rounding: float_attendance_rounding = float( reference_calendar.attendance_rounding) rounded_start_hour = self._ceil_rounding( float_attendance_rounding, attendance_start) rounded_stop_hour = self._floor_rounding( float_attendance_rounding, attendance_stop) # if shift is approximately one hour if abs(1 - rounded_start_hour) < 0.01: attendance_start = datetime( attendance_start.year, attendance_start.month, attendance_start.day, attendance_start.hour + 1) else: attendance_start = datetime( attendance_start.year, attendance_start.month, attendance_start.day, attendance_start.hour, int(round(rounded_start_hour * 60.0))) attendance_stop = datetime( attendance_stop.year, attendance_stop.month, attendance_stop.day, attendance_stop.hour, int(round(rounded_stop_hour * 60.0))) # again duration_delta = attendance_stop - attendance_start duration = self.total_seconds(duration_delta) / 3600.0 duration = round(duration / precision) * precision res[attendance.id]['duration'] = duration res[attendance.id]['inside_calendar_duration'] = 0.0 res[attendance.id]['outside_calendar_duration'] = 0.0 calendar_id = reference_calendar.id intervals_within = 0 # split attendance in intervals = precision # 2012.10.16 LF FIX : no recursion in split attendance splitted_attendances = ( self.split_interval_time_by_precision( attendance_start, duration, precision)) counter = 0 for atomic_attendance in splitted_attendances: counter += 1 centered_attendance = (self.mid_time_interval( atomic_attendance[0], delta=atomic_attendance[1], )) # check if centered_attendance is within a working # schedule # 2012.10.16 LF FIX : weekday must be single character # not int weekday_char = unicode( unichr(centered_attendance.weekday() + 48)) matched_schedule_ids = self.matched_schedule( cr, uid, centered_attendance, weekday_char, calendar_id, context=context) if len(matched_schedule_ids) > 1: raise orm.except_orm( _('Error'), _('Wrongly configured working schedule with ' 'id %s') % unicode(calendar_id)) if matched_schedule_ids: intervals_within += 1 # sign in tolerance if intervals_within == 1: att = attendance_pool.browse( cr, uid, matched_schedule_ids[0], context=context) att_start = self.datetime_to_hour( attendance_start) if (att.hour_from and (att_start >= att_start - att.hour_from - att.tolerance_to) < 0.01): # handling float roundings (<=) additional_intervals = round( (att_start - att.hour_from) / precision) intervals_within += additional_intervals res[attendance.id]['duration'] = \ self.time_sum( res[attendance.id]['duration'], additional_intervals * precision) # sign out tolerance if len(splitted_attendances) == counter: att = attendance_pool.browse( cr, uid, matched_schedule_ids[0], context=context) att_stop = self.datetime_to_hour( attendance_stop) if (att_stop <= att.hour_to and (att_stop - att.hour_to + att.tolerance_from) > -0.01): # handling float roundings (>=) additional_intervals = round( (att.hour_to - att_stop) / precision) intervals_within += additional_intervals res[attendance.id]['duration'] = ( self.time_sum( res[attendance.id]['duration'], additional_intervals * precision)) res[attendance.id][ 'inside_calendar_duration'] = intervals_within * precision # make difference using time in order to avoid # rounding errors # inside_calendar_duration can't be > duration res[attendance.id][ 'outside_calendar_duration'] = self.time_difference( res[attendance.id]['inside_calendar_duration'], res[attendance.id]['duration'], help_message='Attendance ID %s' % attendance.id) if reference_calendar.overtime_rounding: if res[attendance.id]['outside_calendar_duration']: overtime = res[ attendance.id]['outside_calendar_duration'] cal = reference_calendar if cal.overtime_rounding_tolerance: overtime = self.time_sum( overtime, cal.overtime_rounding_tolerance) float_overtime_rounding = float( reference_calendar.overtime_rounding) res[attendance.id]['outside_calendar_duration'] = \ math.floor(overtime * float_overtime_rounding) / \ float_overtime_rounding return res
def load_invoices(self, cr, uid, commitment, commitment_line_model, dte_dtr_id, where, comm_lines, context=None): """Read all in/out invoices and return amount and fiscal parts""" invoice_model = self.pool['account.invoice'] account_tax_model = self.pool['account.tax'] sum_amounts = {} for f in ('total', 'taxable', 'tax', 'ignored'): sum_amounts[f] = 0.0 for invoice_id in invoice_model.search(cr, uid, where): inv_line = {} invoice = invoice_model.browse(cr, uid, invoice_id) country_code = self.get_country_code(cr, uid, invoice.partner_id) if country_code not in EU_COUNTRIES: sum_amounts['ignored'] += invoice.amount_total continue if invoice.type in ('out_invoice', 'out_refund') and country_code != 'IT': sum_amounts['ignored'] += invoice.amount_total continue if invoice.type == 'in_refund' and country_code != 'IT': _logger.error(u'Skipped invoice {0}'.format(invoice.number)) continue for invoice_tax in invoice.tax_line: tax_nature = False tax_payability = 'I' tax_rate = 0.0 tax_nodet_rate = 0.0 if invoice_tax.tax_code_id: if release.major_version == '6.1' and invoice_tax.tax_code_id.notprintable: continue if release.major_version == '6.1' and invoice_tax.tax_code_id.exclude_from_registries: continue taxcode_base_id = invoice_tax.tax_code_id.id taxcode_vat_id = False # for tax in invoice_tax.tax_code_id.tax_ids: for tax_id in account_tax_model.search( cr, uid, [('tax_code_id', '=', taxcode_base_id)]): tax = account_tax_model.browse(cr, uid, tax_id) if tax and not tax.parent_id: if tax.amount > tax_rate: tax_rate = tax.amount if tax.payability: tax_payability = tax.payability if tax_rate == 0.0: if tax.non_taxable_nature: tax_nature = tax.non_taxable_nature else: raise orm.except_orm( _(u'Error!'), _(u'Invalid tax %s nature') % (tax.name)) else: if release.major_version == '6.1': tax_rate = 0 for child in account_tax_model.browse( cr, uid, tax.parent_id.id).child_ids: if child.type == 'percent': tax_rate += child.amount tax_nodet_rate = 1 - (tax.amount / tax_rate) else: if tax.type == 'percent' and tax.amount > tax_nodet_rate: tax_nodet_rate = tax.amount tax = account_tax_model.browse( cr, uid, tax.parent_id.id) taxcode_base_id = invoice_tax.tax_code_id.id if tax.amount > tax_rate: tax_rate = tax.amount else: if invoice_tax.base_code_id.exclude_from_registries: continue taxcode_base_id = invoice_tax.base_code_id.id taxcode_vat_id = invoice_tax.tax_code_id.id for tax_id in account_tax_model.search( cr, uid, [('base_code_id', '=', taxcode_base_id)]): tax = account_tax_model.browse(cr, uid, tax_id) if tax and not tax.parent_id: if tax.non_taxable_nature: tax_nature = tax.non_taxable_nature if tax.payability: tax_payability = tax.payability if tax_nature == 'FC': sum_amounts['ignored'] += invoice.amount_total continue if not invoice_tax.tax_code_id and not tax_nature: raise orm.except_orm( _(u'Error!'), _(u'Invalid tax %s nature for invoice %s') % (invoice_tax.name, invoice.number)) if taxcode_base_id not in inv_line: inv_line[taxcode_base_id] = {} inv_line[taxcode_base_id]['amount_taxable'] = 0.0 inv_line[taxcode_base_id]['amount_tax'] = 0.0 inv_line[taxcode_base_id]['amount_total'] = 0.0 inv_line[taxcode_base_id]['tax_vat_id'] = taxcode_vat_id inv_line[taxcode_base_id]['tax_rate'] = tax_rate inv_line[taxcode_base_id][ 'tax_nodet_rate'] = tax_nodet_rate inv_line[taxcode_base_id]['tax_nature'] = tax_nature inv_line[taxcode_base_id][ 'tax_payability'] = tax_payability if tax_rate and not inv_line[taxcode_base_id]['tax_rate']: inv_line[taxcode_base_id]['tax_rate'] = tax_rate if tax_nodet_rate and not inv_line[taxcode_base_id][ 'tax_nodet_rate']: inv_line[taxcode_base_id][ 'tax_nodet_rate'] = tax_nodet_rate if tax_payability and not inv_line[taxcode_base_id][ 'tax_payability']: inv_line[taxcode_base_id][ 'tax_payability'] = tax_payability inv_line[taxcode_base_id]['amount_taxable'] += invoice_tax.base inv_line[taxcode_base_id]['amount_tax'] += invoice_tax.amount inv_line[taxcode_base_id]['amount_total'] += round( invoice_tax.base + invoice_tax.amount, 2) sum_amounts['taxable'] += invoice_tax.base sum_amounts['tax'] += invoice_tax.amount sum_amounts['total'] += round( invoice_tax.base + invoice_tax.amount, 2) if inv_line: comm_lines[invoice_id] = {} comm_lines[invoice_id]['partner_id'] = invoice.partner_id.id comm_lines[invoice_id]['taxes'] = inv_line return comm_lines, sum_amounts
def get_sede(self, cr, uid, fields, dte_dtr_id, selector, context=None): if dte_dtr_id == 'DTE': if selector == 'company': sede = (IndirizzoType()) elif selector == 'customer': if SPESOMETRO_VERSION == '2.0': sede = (IndirizzoNoCAPType()) else: sede = (IndirizzoType()) elif selector == 'supplier': sede = (IndirizzoType()) else: raise orm.except_orm( _('Error!'), _('Internal error: invalid partner selector')) else: if selector == 'company': sede = (IndirizzoType()) elif selector == 'customer': if SPESOMETRO_VERSION == '2.0': sede = (IndirizzoNoCAPType()) else: sede = (IndirizzoType()) elif selector == 'supplier': if SPESOMETRO_VERSION == '2.0': sede = (IndirizzoNoCAPType()) else: sede = (IndirizzoType()) else: raise orm.except_orm( _('Error!'), _('Internal error: invalid partner selector')) if fields.get('xml_Nazione'): sede.Nazione = fields['xml_Nazione'] else: raise orm.except_orm( _('Error!'), _('Unknow country of %s %s %S' % (fields.get('xml_Denominazione'), fields.get('xml_Nome'), fields.get('xml_Cognome')))) if fields.get('xml_Indirizzo'): sede.Indirizzo = self.str60Latin(fields['xml_Indirizzo']) else: raise orm.except_orm( _('Error!'), _('Missed address %s %s %S' % (fields.get('xml_Denominazione'), fields.get('xml_Nome'), fields.get('xml_Cognome')))) if fields.get('xml_Comune'): sede.Comune = self.str60Latin(fields['xml_Comune']) else: raise orm.except_orm( _('Error!'), _('Missed city %s %s %S' % (fields.get('xml_Denominazione'), fields.get('xml_Nome'), fields.get('xml_Cognome')))) if fields.get('xml_CAP') and fields['xml_Nazione'] == 'IT': sede.CAP = fields['xml_CAP'] elif selector == 'company': raise orm.except_orm(_('Error!'), _('Missed company zip code')) if fields.get('xml_Provincia') and fields['xml_Nazione'] == 'IT': sede.Provincia = fields['xml_Provincia'] return sede
def check_access_rule(self, cr, uid, ids, operation, context=None): """ Access rules of mail.message: - read: if - author_id == pid, uid is the author, OR - mail_notification (id, pid) exists, uid has been notified, OR - uid have read access to the related document if model, res_id - otherwise: raise - create: if - no model, no res_id, I create a private message OR - pid in message_follower_ids if model, res_id OR - mail_notification (parent_id.id, pid) exists, uid has been notified of the parent, OR - uid have write or create access on the related document if model, res_id, OR - otherwise: raise - write: if - author_id == pid, uid is the author, OR - uid has write or create access on the related document if model, res_id - otherwise: raise - unlink: if - uid has write or create access on the related document if model, res_id - otherwise: raise """ def _generate_model_record_ids(msg_val, msg_ids): """ :param model_record_ids: {'model': {'res_id': (msg_id, msg_id)}, ... } :param message_values: {'msg_id': {'model': .., 'res_id': .., 'author_id': ..}} """ model_record_ids = {} for id in msg_ids: vals = msg_val.get(id, {}) if vals.get('model') and vals.get('res_id'): model_record_ids.setdefault(vals['model'], set()).add(vals['res_id']) return model_record_ids if uid == SUPERUSER_ID: return if isinstance(ids, (int, long)): ids = [ids] not_obj = self.pool.get('mail.notification') fol_obj = self.pool.get('mail.followers') partner_id = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=None).partner_id.id # Read mail_message.ids to have their values message_values = dict((res_id, {}) for res_id in ids) cr.execute('SELECT DISTINCT id, model, res_id, author_id, parent_id FROM "%s" WHERE id = ANY (%%s)' % self._table, (ids,)) for id, rmod, rid, author_id, parent_id in cr.fetchall(): message_values[id] = {'model': rmod, 'res_id': rid, 'author_id': author_id, 'parent_id': parent_id} # Author condition (READ, WRITE, CREATE (private)) -> could become an ir.rule ? author_ids = [] if operation == 'read' or operation == 'write': author_ids = [mid for mid, message in message_values.iteritems() if message.get('author_id') and message.get('author_id') == partner_id] elif operation == 'create': author_ids = [mid for mid, message in message_values.iteritems() if not message.get('model') and not message.get('res_id')] # Parent condition, for create (check for received notifications for the created message parent) notified_ids = [] if operation == 'create': parent_ids = [message.get('parent_id') for mid, message in message_values.iteritems() if message.get('parent_id')] not_ids = not_obj.search(cr, SUPERUSER_ID, [('message_id.id', 'in', parent_ids), ('partner_id', '=', partner_id)], context=context) not_parent_ids = [notif.message_id.id for notif in not_obj.browse(cr, SUPERUSER_ID, not_ids, context=context)] notified_ids += [mid for mid, message in message_values.iteritems() if message.get('parent_id') in not_parent_ids] # Notification condition, for read (check for received notifications and create (in message_follower_ids)) -> could become an ir.rule, but not till we do not have a many2one variable field other_ids = set(ids).difference(set(author_ids), set(notified_ids)) model_record_ids = _generate_model_record_ids(message_values, other_ids) if operation == 'read': not_ids = not_obj.search(cr, SUPERUSER_ID, [ ('partner_id', '=', partner_id), ('message_id', 'in', ids), ], context=context) notified_ids = [notification.message_id.id for notification in not_obj.browse(cr, SUPERUSER_ID, not_ids, context=context)] elif operation == 'create': for doc_model, doc_ids in model_record_ids.items(): fol_ids = fol_obj.search(cr, SUPERUSER_ID, [ ('res_model', '=', doc_model), ('res_id', 'in', list(doc_ids)), ('partner_id', '=', partner_id), ], context=context) fol_mids = [follower.res_id for follower in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context)] notified_ids += [mid for mid, message in message_values.iteritems() if message.get('model') == doc_model and message.get('res_id') in fol_mids] # CRUD: Access rights related to the document other_ids = other_ids.difference(set(notified_ids)) model_record_ids = _generate_model_record_ids(message_values, other_ids) document_related_ids = [] for model, doc_ids in model_record_ids.items(): model_obj = self.pool[model] mids = model_obj.exists(cr, uid, list(doc_ids)) if hasattr(model_obj, 'check_mail_message_access'): model_obj.check_mail_message_access(cr, uid, mids, operation, context=context) else: self.pool['mail.thread'].check_mail_message_access(cr, uid, mids, operation, model_obj=model_obj, context=context) document_related_ids += [mid for mid, message in message_values.iteritems() if message.get('model') == model and message.get('res_id') in mids] # Calculate remaining ids: if not void, raise an error other_ids = other_ids.difference(set(document_related_ids)) if not other_ids: return raise orm.except_orm(_('Access Denied'), _('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') % (self._description, operation))
def _dati_partner(self, cr, uid, partner, args, context=None): if release.major_version == '6.1': address_id = self.pool['res.partner'].address_get( cr, uid, [partner.id])['default'] address = self.pool['res.partner.address'].browse( cr, uid, address_id, context) else: address = partner res = {} if partner.vat: vat = partner.vat res['xml_IdPaese'] = vat and vat[0:2] or '' res['xml_IdCodice'] = vat and vat[2:] or '' if partner.individual and partner.fiscalcode: res['xml_CodiceFiscale'] = partner.fiscalcode elif res.get('xml_IdPaese', '') == 'IT': res['xml_CodiceFiscale'] = res['xml_IdCodice'] if partner.individual: if release.major_version == '6.1': if partner.fiscalcode_firstname and partner.fiscalcode_surname: res['xml_Nome'] = partner.fiscalcode_firstname res['xml_Cognome'] = partner.fiscalcode_surname else: res['xml_Denominazione'] = partner.name[:80] else: res['xml_Nome'] = partner.firstname res['xml_Cognome'] = partner.lastname else: res['xml_Denominazione'] = partner.name[:80] res['xml_Nazione'] = address.country_id.code or res.get( 'xml_IdPaese', False) if not res['xml_Nazione']: raise orm.except_orm( 'Warning', _('Impossible determine country code for partner {}').format( partner.name)) if address.street: res['xml_Indirizzo'] = address.street.replace(u"'", '').replace( u"’", '') else: _logger.error(u'Partner {0} has no street on address'.format( partner.name)) res['xml_Indirizzo'] = ' ' if res.get('xml_IdPaese', '') == 'IT' and address.zip: res['xml_CAP'] = address.zip.replace('x', '0').replace('%', '0') res['xml_Comune'] = address.city or ' ' if not address.city: _logger.error(u'Partner {0} has no city on address'.format( partner.name)) if res['xml_Nazione'] == 'IT': if release.major_version == '6.1': res['xml_Provincia'] = address.province.code else: res['xml_Provincia'] = partner.state_id.code if not res['xml_Provincia']: del res['xml_Provincia'] return res