def api_handle_errors(message=''): """ Handle error when calling the API It is meant to be used when a model does a direct call to a job using the API (not using job.delay()). Avoid to have unhandled errors raising on front of the user, instead, they are presented as :class:`openerp.exceptions.UserError`. """ if message: message = message + u'\n\n' try: yield except NetworkRetryableError as err: raise exceptions.UserError( _(u'{}Network Error:\n\n{}').format(message, err)) except (HTTPError, RequestException, ConnectionError) as err: raise exceptions.UserError( _(u'{}API / Network Error:\n\n{}').format(message, err)) except PrestaShopWebServiceError as err: raise exceptions.UserError( _(u'{}Authentication Error:\n\n{}').format(message, err)) except PrestaShopWebServiceError as err: raise exceptions.UserError( _(u'{}Error during synchronization with ' 'PrestaShop:\n\n{}').format(message, unicode(err)))
def do_oauth_leg_3(self): """ Perform OAuth step 3 to get access_token and secret """ oauth_hook = OAuth1( client_key=self.consumer_key, client_secret='', signature_method=SIGNATURE_RSA, rsa_key=self.backend_id.private_key, resource_owner_key=self.request_token, resource_owner_secret=self.request_secret, ) try: req = requests.post('%s/%s/access-token' % (self.backend_id.uri, self.OAUTH_BASE), verify=self.backend_id.verify_ssl, auth=oauth_hook) except requests.exceptions.SSLError as err: raise exceptions.UserError( _('SSL error during negociation: %s') % (err, )) resp = dict(parse_qsl(req.text)) token = resp.get('oauth_token') secret = resp.get('oauth_token_secret') if None in [token, secret]: raise exceptions.UserError( _('Did not get token (%s) or secret (%s) from Jira. Resp %s') % (token, secret, resp)) self.backend_id.write({ 'access_token': token, 'access_secret': secret, }) self.state = 'done' self.backend_id.state_setup() return self._next_action()
def lock_move(self, data): obj_move = self.env['account.move'] draft_move = obj_move.search([('state', '=', 'draft'), ('journal_id', 'in', self.journal_ids.ids), ('date', '>=', self.date_start), ('date', '<=', self.date_end)], order='date') if draft_move: raise exceptions.UserError(_('Unposted move in period/jounal \ selected, please post it before \ locking them')) move = obj_move.search([('state', '=', 'posted'), ('locked', '=', False), ('journal_id', 'in', self.journal_ids.ids), ('date', '>=', self.date_start), ('date', '<=', self.date_end)], order='date') if not move: raise exceptions.UserError(_('No move to locked found')) move.write({'locked': True}) return {'type': 'ir.actions.act_window_close'}
def _check_capital_fundraising(self): invoice = self if invoice.is_capital_fundraising: # Check mandatory field if not invoice.fundraising_category_id: raise exceptions.UserError( _("A Capital fundraising must have a capital category" " defined")) # Check products product_ids = invoice.invoice_line_ids.mapped('product_id.id') forbidden_product_ids =\ list(set(product_ids) - set( [invoice.fundraising_category_id.product_id.id])) if forbidden_product_ids: forbidden_products = self.env['product.product'].browse( forbidden_product_ids) raise exceptions.UserError( _("%s category do not allow %s products") % (invoice.fundraising_category_id.name, ', '.join( forbidden_products.mapped('name')))) ordered_qty = sum(invoice.invoice_line_ids.mapped('quantity')) to_order_qty = invoice.fundraising_category_id.check_minimum_qty( invoice.partner_id) if ordered_qty < to_order_qty: raise exceptions.UserError( _("This category and (previous orders) requires at least" " %d shares.") % (to_order_qty))
def make_batch_refund(self): if self.company_id != self.env.user.company_id: raise exceptions.UserError(_('Not in %s' % self.company_id.name)) ctx = self._context.copy() ctx.update(force_company=self.company_id.id, company_id=self.company_id.id) lines_to_invoice = self.claim_line_ids invoice_obj = self.env['account.invoice'].with_context(ctx) invoice_line_obj = self.env['account.invoice.line'].with_context(ctx) if self.claim_ids[0].claim_type.type == "supplier": type = ('in_refund') move_field = 'move_out_id' else: type = ('out_refund') move_field = 'move_in_id' #Creo una factura invoice_vals = self.get_invoice_vals_from_refund(type) invoice = invoice_obj.new(invoice_vals) invoice._onchange_partner_id() invoice_vals = invoice._convert_to_write(invoice._cache) new_invoice = invoice_obj.create(invoice_vals) stage = self.claim_ids[0]._stage_find(domain=[('default_done', '=', True)]) picking_ids = self.env['stock.picking'] for line in lines_to_invoice: invoice_line_vals = \ {'product_id': line.product_id.id, 'name': line.name, 'quantity': self.get_claim_line_qty_to_invoice(line) or line.product_returned_quantity, 'price_unit': line.unit_sale_price, 'invoice_id': new_invoice.id} invoice_line = invoice_line_obj.new(invoice_line_vals) invoice_line._onchange_product_id() invoice_line_vals = invoice_line._convert_to_write( invoice_line._cache) new_line = invoice_line_obj.create(invoice_line_vals) new_line.write({ 'price_unit': line.unit_sale_price, 'name': line.name }) line.write({ 'refund_line_id': new_line.id, }) picking_ids |= line[move_field].picking_id new_invoice.compute_taxes() new_invoice.compute_amount() new_invoice.picking_ids = picking_ids self.claim_ids.write({'invoice_id': new_invoice.id, 'stage_id': stage}) if not new_invoice or new_invoice and not new_line: raise exceptions.UserError(_('')) return new_invoice and new_invoice.open_this_invoice()
def create_webhooks(self): self.ensure_one() other_using_webhook = self.search([('use_webhooks', '=', True), ('id', '!=', self.id)]) if other_using_webhook: raise exceptions.UserError( _('Only one JIRA backend can use the webhook at a time. ' 'You must disable them on the backend "%s" before ' 'activating them here.') % (other_using_webhook.name, )) # open a new cursor because we'll commit after the creations # to be sure to keep the webhook ids with new_env(self.env) as env: backend = env[self._name].browse(self.id) base_url = backend.odoo_webhook_base_url if not base_url: raise exceptions.UserError( _('The Odoo Webhook base URL must be set.')) with backend.get_environment(self._name) as connector_env: backend.use_webhooks = True adapter = connector_env.get_connector_unit(JiraAdapter) # TODO: we could update the JQL of the webhook # each time a new project is sync'ed, so we would # filter out the useless events url = urlparse.urljoin(base_url, '/connector_jira/webhooks/issue') webhook = adapter.create_webhook( name='Odoo Issues', url=url, events=[ 'jira:issue_created', 'jira:issue_updated', 'jira:issue_deleted', ], ) # the only place where to find the hook id is in # the 'self' url, looks like # u'http://jira:8080/rest/webhooks/1.0/webhook/5' webhook_id = webhook['self'].split('/')[-1] backend.webhook_issue_jira_id = webhook_id env.cr.commit() url = urlparse.urljoin(base_url, '/connector_jira/webhooks/worklog') webhook = adapter.create_webhook( name='Odoo Worklogs', url=url, events=[ 'worklog_created', 'worklog_updated', 'worklog_deleted', ], ) webhook_id = webhook['self'].split('/')[-1] backend.webhook_worklog_jira_id = webhook_id env.cr.commit()
def get_route_info(self, error=False): for rec in self: departure = { 'latitude': rec.departure_id.latitude, 'longitude': rec.departure_id.longitude } arrival = { 'latitude': rec.arrival_id.latitude, 'longitude': rec.arrival_id.longitude } if not departure['latitude'] and not departure['longitude']: raise exceptions.UserError( _("The departure don't have coordinates.")) if not arrival['latitude'] and not arrival['longitude']: raise exceptions.UserError( _("The arrival don't have coordinates.")) url = 'http://maps.googleapis.com/maps/api/distancematrix/json' origins = (str(departure['latitude']) + ',' + str(departure['longitude'])) destinations = '' places = [ str(x.place_id.latitude) + ',' + str(x.place_id.longitude) for x in rec.route_place_ids if x.place_id.latitude and x.place_id.longitude ] for place in places: origins += "|" + place destinations += place + "|" destinations += (str(arrival['latitude']) + ',' + str(arrival['longitude'])) params = { 'origins': origins, 'destinations': destinations, 'mode': 'driving', 'language': self.env.lang, 'sensor': 'false', } try: result = json.loads(requests.get(url, params=params).content) distance = duration = 0.0 if result['status'] == 'OK': if rec.route_place_ids: for row in result['rows']: distance += ( row['elements'][1]['distance']['value'] / 1000.0) duration += ( row['elements'][1]['duration']['value'] / 3600.0) else: res = result['rows'][0]['elements'][0] distance = res['distance']['value'] / 1000.0 duration = res['duration']['value'] / 3600.0 self.distance = distance self.travel_time = duration except: raise exceptions.UserError(_("Google Maps is not available."))
def check_connection(self): self.ensure_one() try: self.get_api_client() except ValueError as err: raise exceptions.UserError(_('Failed to connect (%s)') % (err, )) except JIRAError as err: raise exceptions.UserError( _('Failed to connect (%s)') % (err.text, )) raise exceptions.UserError(_('Connection successful'))
def _prepare_account_move_line(self, qty, cost, credit_account_id, debit_account_id): res = super(StockMove, self)._prepare_account_move_line( qty, cost, credit_account_id, debit_account_id) if res: if len(res)>2: debit_line_vals = res[0][2] credit_line_vals = res[1][2] diff_line_vals = res[2][2] if ( self.operating_unit_id and self.operating_unit_dest_id and self.operating_unit_id != self.operating_unit_dest_id and debit_line_vals['account_id'] != credit_line_vals['account_id'] ): raise exceptions.UserError( _('You cannot create stock moves involving separate source' ' and destination accounts related to different ' 'operating units.') ) debit_line_vals['operating_unit_id'] = ( self.operating_unit_dest_id.id or self.operating_unit_id.id ) credit_line_vals['operating_unit_id'] = ( self.operating_unit_id.id or self.operating_unit_dest_id.id ) diff_line_vals['operating_unit_id'] = ( self.operating_unit_id.id or self.operating_unit_dest_id.id ) return [(0, 0, debit_line_vals), (0, 0, credit_line_vals), (0, 0, diff_line_vals)] else: debit_line_vals = res[0][2] credit_line_vals = res[1][2] if ( self.operating_unit_id and self.operating_unit_dest_id and self.operating_unit_id != self.operating_unit_dest_id and debit_line_vals['account_id'] != credit_line_vals['account_id'] ): raise exceptions.UserError( _('You cannot create stock moves involving separate source' ' and destination accounts related to different ' 'operating units.') ) debit_line_vals['operating_unit_id'] = ( self.operating_unit_dest_id.id or self.operating_unit_id.id ) credit_line_vals['operating_unit_id'] = ( self.operating_unit_id.id or self.operating_unit_dest_id.id ) return [(0, 0, debit_line_vals), (0, 0, credit_line_vals)] return res
def create_move_lines_from_template(self): template = self.template_id if self.request_type == 'template' and not template: raise exceptions.UserError(_('You need a template to ')) if self.request_type == 'file' and not self.file_upload: raise exceptions.UserError(_('You need a file to ')) lines = [] if self.request_type == 'template': for line in template.template_line_ids: lines.append({ 'product_id': line.product_id.id, 'product_uom': line.product_uom.id, 'product_uom_qty': line.product_uom_qty, 'stock_wizard_id': self.id, }) elif self.request_type == 'file': data = base64.b64decode(self.file_upload) file_input = cStringIO.StringIO(data) file_input.seek(0) reader_info = [] if self.delimeter: delimeter = str(self.delimeter) else: delimeter = ',' reader = csv.reader(file_input, delimiter=delimeter, lineterminator='\r\n') try: reader_info.extend(reader) except Exception: raise exceptions.Warning(_("Not a valid file!")) keys = reader_info[0] # check if keys exist if not isinstance(keys, list) or ('code' not in keys or 'quantity' not in keys): raise exceptions.Warning( _("Not 'code' or 'quantity' keys found")) del reader_info[0] for i in range(len(reader_info)): vals = {} field = reader_info[i] values = dict(zip(keys, field)) product_id = self.env['product.product'].search([ ('default_code', '=', values['code']) ]) vals['product_id'] = product_id.id vals['product_uom'] = product_id.uom_id.id vals['product_uom_qty'] = values['quantity'] vals['stock_wizard_id'] = self.id, lines.append(vals) self.create_pick_return_lines(lines=lines)
def set_warranty(self): """ Calculate warranty limit and address """ for line_id in self: if not line_id.product_id: raise exceptions.UserError(_('Please set product first')) if not line_id.invoice_line_id: raise exceptions.UserError(_('Please set invoice first')) line_id.set_warranty_limit() line_id.set_warranty_return_address()
def _dirty_check(self): if self.env.context.get('active_model', '') == 'account.invoice': ids = self.env.context['active_ids'] if len(ids) < 2: raise exceptions.UserError( _('Please select multiple invoice to merge in the list ' 'view.')) inv_obj = self.env['account.invoice'] invs = inv_obj.read(ids, ['account_id', 'state', 'type', 'company_id', 'partner_id', 'currency_id', 'journal_id']) for d in invs: if d['state'] != 'draft': raise exceptions.UserError( _('At least one of the selected invoices is %s!') % d['state']) if d['account_id'] != invs[0]['account_id']: raise exceptions.UserError( _('Not all invoices use the same account!')) if d['company_id'] != invs[0]['company_id']: raise exceptions.UserError( _('Not all invoices are at the same company!')) if d['partner_id'] != invs[0]['partner_id']: raise exceptions.UserError( _('Not all invoices are for the same partner!')) if d['type'] != invs[0]['type']: raise exceptions.UserError( _('Not all invoices are of the same type!')) if d['currency_id'] != invs[0]['currency_id']: raise exceptions.UserError( _('Not all invoices are at the same currency!')) if d['journal_id'] != invs[0]['journal_id']: raise exceptions.UserError( _('Not all invoices are at the same journal!')) return {}
def _process_record_33(self, st_group, line): """33 - Registro final de cuenta""" st_group['num_debe'] += int(line[20:25]) st_group['debe'] += float("%s.%s" % (line[25:37], line[37:39])) st_group['num_haber'] += int(line[39:44]) st_group['haber'] += float("%s.%s" % (line[44:56], line[56:58])) st_group['saldo_fin'] += float("%s.%s" % (line[59:71], line[71:73])) if line[58:59] == '1': st_group['saldo_fin'] *= -1 self.balance_end = st_group['saldo_fin'] # Group level checks debit_count = 0 debit = 0.0 credit_count = 0 credit = 0.0 for st_line in st_group['lines']: if st_line['importe'] < 0: debit_count += 1 debit -= st_line['importe'] else: credit_count += 1 credit += st_line['importe'] if st_group['num_debe'] != debit_count: # pragma: no cover raise exceptions.UserError( _("Number of debit records doesn't match with the defined in " "the last record of account.")) if st_group['num_haber'] != credit_count: # pragma: no cover raise exceptions.UserError( _("Number of credit records doesn't match with the defined " "in the last record of account.")) if abs(st_group['debe'] - debit) > 0.005: # pragma: no cover raise exceptions.UserError( _("Debit amount doesn't match with the defined in the last " "record of account.")) if abs(st_group['haber'] - credit) > 0.005: # pragma: no cover raise exceptions.UserError( _("Credit amount doesn't match with the defined in the last " "record of account.")) # Note: Only perform this check if the balance is defined on the file # record, as some banks may leave it empty (zero) on some circumstances # (like CaixaNova extracts for VISA credit cards). if st_group['saldo_fin'] and st_group['saldo_ini']: # pragma: no cover balance = st_group['saldo_ini'] + credit - debit if abs(st_group['saldo_fin'] - balance) > 0.005: raise exceptions.UserError( _("Final balance amount = (initial balance + credit " "- debit) doesn't match with the defined in the last " "record of account.")) return st_group
def unlink(self): if any(x.state not in ('draft', 'cancelled') for x in self): raise exceptions.UserError( _("You can't remove any closing that is not in draft or " "cancelled state.") ) return super(AccountFiscalyearClosing, self).unlink()
def _search_active(self, operator, operand): domain = [] if operator == 'in': if True in operand: domain += self._search_active('=', True) if False in operand: domain += self._search_active('=', False) if len(domain) > 1: domain = [(1, '=', 1)] elif operator == 'not in': if True in operand: domain += self._search_active('!=', True) if False in operand: domain += self._search_active('!=', False) if len(domain) > 1: domain = [(0, '=', 1)] elif operator in ('=', '!='): operators = { ('=', True): '>', ('=', False): '<=', ('!=', False): '>', ('!=', True): '<=', } domain = [('expires_at', operators[operator, operand], fields.Datetime.now())] else: raise exceptions.UserError( _('Invalid operator {operator} for field active!').format( operator=operator)) return domain
def send_voice(self, uuid, media_id): openid = self.get_openid_from_uuid(uuid) if openid: try: self.wxclient.send_voice_message(openid, media_id) except ClientException as e: raise exceptions.UserError(u'发送voice失败 %s' % e)
def create_index(self): self.ensure_one() if not self._install_trgm_extension(): raise exceptions.UserError( _('The pg_trgm extension does not exists or cannot be ' 'installed.')) table_name = self.env[self.field_id.model_id.model]._table column_name = self.field_id.name index_type = self.index_type index_name = '%s_%s_idx' % (column_name, index_type) index_exists, index_name = self.get_not_used_index( index_name, table_name) if not index_exists: self.env.cr.execute( """ CREATE INDEX %(index)s ON %(table)s USING %(indextype)s (%(column)s %(indextype)s_trgm_ops); """, { 'table': AsIs(table_name), 'index': AsIs(index_name), 'column': AsIs(column_name), 'indextype': AsIs(index_type) }) return index_name
def _compute_theoretical_multi(self): for template in self: classification = template.margin_classification_id if classification: multi = 1 + (classification.margin / 100) for tax in template.taxes_id: if tax.amount_type != 'percent' or not tax.price_include: raise exceptions.UserError( _("Unimplemented Feature\n" "The Tax %s is not correctly set for computing" " prices with coefficients for the product %s") % (tax.name, template.name)) multi *= 1 + (tax.amount / 100) template.theoretical_price = tools.float_round( template.standard_price * multi, precision_rounding=classification.price_round) +\ classification.price_surcharge else: template.theoretical_price = template.list_price difference = (template.list_price - template.theoretical_price) if max(difference, -difference) < 10**-9: difference = 0 template.theoretical_difference = difference if difference < 0: template.margin_state = 'cheap' elif difference > 0: template.margin_state = 'expensive' else: template.margin_state = 'ok'
def get_payable_bank(self, company=None, currency=None): if not company: self.ensure_one() company = self.company_id currency = self.currency_id for journal in company.bank_journal_ids: if not journal.display_on_footer: continue bank_acc = journal.bank_account_id if journal.currency_id == currency: _logger.info('Selected bank %s for invoice %s (company %s currency %s)', journal.name, self, company, currency) return journal else: _logger.info('Not using bank %s because of currency', journal) for journal in company.bank_journal_ids: if not journal.display_on_footer: continue if journal.currency_id: _logger.info('Not using bank %s because it has currency', journal) continue _logger.info('Selected bank %s [%s] for invoice %s', journal.name, journal.currency_id, self) return journal # No journal matching raise exceptions.UserError(_('Not able to determine payable bank account'))
def link_with_jira(self, backends=None): if backends is None: backends = self.env['jira.backend'].search([]) for backend in backends: with backend.get_environment('jira.res.users') as connector_env: binder = connector_env.get_connector_unit(Binder) adapter = connector_env.get_connector_unit(JiraAdapter) for user in self: if binder.to_backend(user, wrap=True): continue jira_user = adapter.search(fragment=user.email) if not jira_user: jira_user = adapter.search(fragment=user.login) if not jira_user: continue elif len(jira_user) > 1: raise exceptions.UserError( _('Several users found for %s. ' 'Set it manually..') % user.login) jira_user, = jira_user binding = self.env['jira.res.users'].create({ 'backend_id': backend.id, 'openerp_id': user.id, }) binder.bind(jira_user.key, binding)
def render_html(self, docids, data=None): data['context'].update({'active_ids': data['ids']}) if not docids: docids = data['ids'] model = self.env.context.get('active_model') docs = self.env[model].browse(data['ids']) ctx = self.env.context.copy() ctx.update({'active_ids': data['ids']}) if not data.get('form'): raise exceptions.UserError( _("Form content is missing, this report cannot be printed.")) obj_analytic = self.env['account.analytic.account'].browse(data['ids']) docargs = { 'doc_ids': docids, 'doc_model': self.env['account.analytic.account'], 'data': data, 'docs': self.env['account.analytic.account'].browse(data['ids']), 'time': time, 'doc_model': model, } return self.env['report'].render( 'biocare_reports_modifier.report_contract_wizard', docargs)
def prepare_move_lines_from_template(self, t, expected_date): # TODO: permitir inventariar pedidos con líneas ingresadas previamente. if self.move_lines: raise exceptions.UserError( _('El pedido debe estar vacío para poder ejecutar el inventario.' )) vals = super(StockPicking, self).prepare_move_lines_from_template( t=t, expected_date=expected_date) inventory_line = self.env['stock.inventory.line'].create({ 'inventory_id': self.inventory_id.id, 'product_id': vals['product_id'], 'location_id': vals['location_dest_id'], }) _logger.info('Inventory Line: %s', inventory_line) vals.update({ 'inventory_line_id': inventory_line.id, }) return vals
def send_voice(self, uuid, media_id): openid = self.UUID_OPENID.get(uuid, None) if openid: try: self.wxclient.send_voice_message(openid, media_id) except ClientException as e: raise exceptions.UserError(u'发送voice失败 %s' % e)
def action_confirm(self): for rec in self: mrp_exep = [] for line in rec.order_line: route_ids = [route.id for route in line.product_id.route_ids] if 6 in route_ids: product_bom = self.env["mrp.bom"].search([ ('product_id', '=', line.product_id.id) ]) if not product_bom: mrp_exep.append(line.product_id.name_get()[0][1]) if mrp_exep: res = "" for msg in mrp_exep: res += u"{},\n".format(msg) raise exceptions.ValidationError( u"Es necesaria la lista de materiales para el producto:\n {}" .format(res)) if not rec.client_order_ref: raise exceptions.UserError( u"Para confirmar una orden coloque el número de la orden de compra del cliente en el campo: Referencia cliente para el pedido {}." .format(rec.name)) client_order_ref = rec.search([ ('partner_id', '=', rec.partner_id.id), ('client_order_ref', '=', rec.client_order_ref), ('id', '!=', rec.id) ]) if client_order_ref: raise exceptions.ValidationError( "La orden de compra en la referencia del cliente ya fue utilizada en el pedido {}" .format(min(client_order_ref).name)) return super(Sale, self).action_confirm()
def _lock_timestamp(self, from_date_field): """ Update the timestamp for a synchro thus, we prevent 2 synchros to be launched at the same time. The lock is released at the commit of the transaction. Return the id of the timestamp if the lock could be acquired. """ assert from_date_field self.ensure_one() query = """ SELECT id FROM jira_backend_timestamp WHERE backend_id = %s AND from_date_field = %s FOR UPDATE NOWAIT """ try: self.env.cr.execute(query, (self.id, from_date_field)) except psycopg2.OperationalError: raise exceptions.UserError( _("The synchronization timestamp %s is currently locked, " "probably due to an ongoing synchronization." % from_date_field)) row = self.env.cr.fetchone() return row[0] if row else None
def _register_hook(self, cr): res = super(L10nEsAeatReport, self)._register_hook(cr) if self._name in ('l10n.es.aeat.report', 'l10n.es.aeat.report.tax.mapping'): return res with api.Environment.manage(): env = api.Environment(cr, SUPERUSER_ID, {}) aeat_num = getattr(self, '_aeat_number', False) if not aeat_num: raise exceptions.UserError( _("Modelo no válido: %s. Debe declarar una variable " "'_aeat_number'" % self._name)) seq_obj = env['ir.sequence'] sequence = "aeat%s-sequence" % aeat_num companies = env['res.company'].search([]) for company in companies: seq = seq_obj.search([ ('name', '=', sequence), ('company_id', '=', company.id), ]) if seq: continue seq_obj.create(env[self._name]._prepare_aeat_sequence_vals( sequence, aeat_num, company, )) return res
def button_cancel(self): # Cancel a move was done directly in SQL # so we need to test manualy if the move is locked for move in self: if move.locked: raise exceptions.UserError(_('Move Locked! %s') % (move.name)) return super(AccountMove, self).button_cancel()
def create_order(self): date_planned = self.date_planned if not date_planned: raise exceptions.UserError(_('Select a scheduled date first.')) order = self.env['purchase.order'].create({ 'date_order': self.date_planned, # 'date_planned': self.date_planned, 'partner_id': self.partner_id.id, 'fiscal_position_id': self.partner_id.property_account_position_id.id, 'picking_type_id': self.picking_type_id.id, }) lines = self.mapped('purchase_lines').filtered( lambda x: x.product_qty != 0) for line in lines: self.create_order_lines(order=order, line=line, date_planned=date_planned) return { 'type': 'ir.actions.act_window', 'res_model': 'purchase.order', 'view_type': 'form', 'view_mode': 'form', 'res_id': order.id, 'target': 'current', }
def _create_record(self, line): """Create a v11 record dict :param line: raw v11 line :type line: str :return: current line dict representation :rtype: dict """ amount = self._get_line_amount(line) cost = self._get_line_cost(line) record = { 'reference': line[12:39], 'amount': amount, 'date': time.strftime( '%Y-%m-%d', time.strptime(line[65:71], '%y%m%d') ), 'cost': cost, } if record['reference'] != mod10r(record['reference'][:-1]): raise exceptions.UserError( _('Recursive mod10 is invalid for reference: %s') % record['reference'] ) return record
def write(self, values): result = super(ProjectProject, self).write(values) for record in self: if record.jira_exportable and not record.jira_key: raise exceptions.UserError( _('The JIRA Key is mandatory on JIRA projects.')) return result