I am using Odoo 11 and I want to display a Warning popup in a #api.constraint method. The warning popup that I want to display has two buttons, the first is an OK button used to ignore the warning and the other one is a Cancel button used to attempt the saving operation, it' s similar to the warning popup that odoo uses like on the picture below :
I searched a lot on the web and I found different proposed solutions like using Wizard, exception.Warning() and osv.except_osv(), but unfortunately no one of this solution gives me exactly what I want.
Any help please?
You can raise warning message by different ways. I have created message related to stock quantity by this way:
if self.qty > new_qty:
message = _('You plan to sell %s quantity but you only have %s available in %s warehouse.') % \
(self.qty, self.product_id.virtual_available, self.order_id.warehouse_id.name)
mess= {
'title': _('Not enough inventory!'),
'message' : message
}
return {'warning': mess}
This return same wizard of warning as you want and as shown given image.
The basic odoo Warning that you can use is called from the odoo.exception class.
For example:
from odoo.exceptions import AccessError, UserError, RedirectWarning, ValidationError, Warning
#api.constrains('age')
def _check_something(self):
for record in self:
if record.age > 20:
raise Warning(_("Your record is too old: %s" % record.age))
This should work for your issue.
I write a (draft) module to open Dialog box see:
https://github.com/Micronaet/micronaet-sales/tree/master/confirm_dialog_wizard
In your button you can write this code to open, for ex. to hide a product:
#api.multi
def hide_product_pricelist(self):
""" Hide product
"""
return self.env['dialog.box.wizard'].open_dialog(
message='The product will be hided, <b>you cannot use again</b> '
'but remain in sale order where yet present, <br/>'
'confirm?',
action='self.env["product.product"].browse(%s).write('
'{"active": False})' % self.id,
title='Confirm request:',
mode='cancel_confirm',
)
The program will pop up a window to confirm (as in tree you cannot use "confirm" message parameter), I'm try to do better but ... its a begin ... :)
It is similar to the warning shown when we use the confirm attribute on a button.
<button confirm="Reset to draft!"/>
Raising a validation error or returning a warning as dictionary did not show the Cancel button.
Related
I am using Rasa core v10.2, with custom actions, but getting utter_template() missing 1 required positional argument: 'tracker' error on the run function.
Custom action file: (actions.py)
from rasa_core.actions import Action
from rasa_core.events import SlotSet
class searchJob(Action):
def name(self):
return 'action_search'
def run(self, dispatcher, tracker, domain):
return [SlotSet("jobsname", "as_aggregate")]
domain.yml:
slots:
jobsname:
type: text
templates:
utter_answer:
- text: "The required jobs are {jobsname}"
Stories:
* search
- action_search
- utter_answer
The output is [{'recipient_id': 'default', 'text': 'The required jobs are None'}] which means the Slot it not set. Could the error message be the cause of it?
Thank you.
Are you sure you are looking at the right custom action? I had the same error message because in one of my custom action I was using dispatcher.utter_template() like this:
dispatcher.utter_template('utter_something')
and apparently tracker is now a required argument, i.e. I add tracker like this:
dispatcher.utter_template('utter_something', tracker)
and the error is gone.
PS: I know this should be a comment, but I am not allowed since my reputation is not high enough.
So the issue seems to be the name of the custom action file, change it to anything else from 'actions' will do.
When i use below pywinauto code, i am getting error saying
from pywinauto.controls.win32_controls import ButtonWrapper
checkbox = ButtonWrapper(app.Dialog.child_window(title='Has Balance',auto_id='HasBalanceCheckEdit',control_type='CheckBox').TCheckBox.WrapperObject())
print(checkbox.GetCheckState())
Error:
raise MatchError(items = name_control_map.keys(), tofind = search_text)
pywinauto.findbestmatch.MatchError: Could not find 'TCheckBox' in 'dict_keys(['Has Balance', 'Has BalanceStatic', 'Static'])'
Based on the output you provided, next level spec TCheckBox is not needed. Just use this code:
checkbox = app.Dialog.child_window(title='Has Balance', auto_id='HasBalanceCheckEdit', control_type='CheckBox').wrapper_object()
Explicit ButtonWrapper instantiation is also not necessary because the control type is already auto detected by .wrapper_object(). That's why control_type='CheckBox' in your child_window can find the control.
used import pywinauto.controls.uia_controls to resolve the above code.
Currently I'm trying to fill all fields from a form using Python + uiautomator
My Code:
d = UIDevice(adb.deviceList[0].device)
last_item_exists = d(text='Memo').exists
while not last_item_exists:
print "Searching for fields on screen"
fields = d(className = 'android.widget.EditText', focusable = True)
for field in fields:
if not (field.text == '0' or field.text == '50'): #Skip fields with 0 or 50
print "Writing on the field"
field.click()
d.press(0x0000001d, 0x00001000)
d.press('del')
field.set_text('50')
else:
print "Skipping field"
print "Searching for Memo field"
last_item_exists = d(text='Memo').exists
print "Scrolling down"
d(scrollable=True).fling()
d(text='Confirm').click()
The Problem:
Depending on device resolution, this error may occur:
uiautomator.JsonRPCError: JsonRPC Error code: -32002, Message: com.android.uiautomator.core.UiObjectNotFoundException: UiSelector[CLASS=android.widget.EditText, INSTANCE=9, FOCUSABLE=true, RESOURCE_ID=com.salab.ABRT:id/task_info_item_count]
This is happening, because when I click on the last visible field field, the screen sometimes scrolls down a bit and the top field is not visible anymore.
Is there a workaround for this kind of problem, or I must change my logic(Can't think about anything right now...) ?
UiAutomator only sees what is visible on the screen at each moment. So if you scroll down (or the app does) then it can't interact with it.
You either change your logic or you swipe the screen up and down verifying if everything is filled and, if not, fill it.
I copied and pasted code into my IDE (TextWrangler). Now when I try to run my code, I get a ton of random errors regarding indentation and invalid syntax.
The code worked perfectly before I copied & pasted it from one Django view into another. I'm almost 100% sure the code is still correct in my new view, however, every time it runs I'll get a ton of errors relating to indentation and invalid syntax (even multiline comments like ''' trigger an "invalid syntax on line 234" error.
I've tried switching IDE's over to sublime, and even backspacing all indentations and then retabbing them to no avail. Each time I fix an "error" on one line, a new error on another line is created.
My code is below, please let me know any thoughts on how to fix.
#require_POST
def pay(request):
if request.method == 'POST':
form = CustomerForm(request.POST)
if form.is_valid():
# If the form has been submitted...
# All validation rules pass
#get the customer by session'd customer_id
c = get_object_or_404(Customer, pk = request.session['customer_id'])
#assign shipping info from POST to the customer object
c.first_name = request.POST['first_name']
c.last_name = request.POST['last_name']
c.street_address = request.POST['street_address']
c.city = request.POST['city']
c.state = request.POST['state']
c.zip = request.POST['zip']
#assign email info from POST to the customer object
c.email_address = request.POST['email_address']
stripe.api_key = REDACTED
# Get the credit card details submitted by the form
token = request.POST['stripeToken']
#tries to save the newly added form data.
try:
#save the new customer object's data
c.save()
########## THIS HANDLES CREATING A NEW STRIPE PAYMENT ################
# Create a Customer
try:
customer = stripe.Customer.create(
card=token,
plan="monthly",
email= c.email_address)
#need to save customer's id (ex: c.stripe_id = token.id)
#if there's a token error
except stripe.error.InvalidRequestError, e:
pass
#if the card is declined by Stripe
except stripe.error.CardError, e:
body = e.json_body
err = body['error']
print "Status is: %s" % e.http_status
print "Type is: %s" % err['type']
print "Code is: %s" % err['code']
# param is '' in this case
print "Param is: %s" % err['param']
print "Message is: %s" % err['message']
except stripe.error.AuthenticationError, e:
# Authentication with Stripe's API failed
# (maybe you changed API keys recently)
pass
except stripe.error.APIConnectionError, e:
# Network communication with Stripe failed
pass
except stripe.error.StripeError, e:
# Display a very generic error to the user, and maybe send
# yourself an email
pass
except Exception, e:
# Something else happened, completely unrelated to Stripe
pass
return render(request, 'shipment/confirm.html', {'date' : 'April 15, 2014'})
#passes the context to the template for confirming the customer's data
#context = { 'email_address' : c.email_address, 'first_name' : c.first_name,
# 'last_name' : c.last_name, 'street_address' : c.street_address,
# 'city' : c.city, 'state' : c.state, 'zip' : c.zip, }
#return render(request, 'shipment/pay.html', context)
#If there is a duplicate email it redirects the user back to the form with no error message.
#If anything else happens, it redirects the user back to the form.
else:
form = CustomerForm() # An unbound form
return render(request, 'shipment/createAccount.html', { 'form': form } )
Here's a couple of screenshots of your code in my editor with tabs (set to 4) and space characters shown in a reddish color. As you can see it contains quite a hodgepodge of the two on many lines. Python is very whitespace sensitive and it's important to be consistent. This is usually handled by configuring your editor to always convert tabs to n whitespace characters (or vice versa, but the former is often preferred).
To fix your problem, re-indent everything using a single method. My editor also has a convert-tabs-to-spaces command which could be used first to simplify the task somewhat.
This is why you should use soft tabs instead of hard tabs. You have at least one line that mixes them (check out the line with c.save()), looking at the edit version of your code. Change your IDE settings to always use spaces or tabs (if you haven't already), I recommend spaces.
See this question for how to view whitespace in sublime to find the offending tab character.
I'm using Plone with dexterity and I'm validating 2 related fields using the invariant decorator. Everything works but... I'd like to move the generic error message on one specific field.
How can I do this? I've found a three years old suggestion by Martin Aspeli about how it would be cool doing it:
http://plone.293351.n2.nabble.com/plone-app-form-does-not-display-invariant-errors-td348710.html
but they dont came out with a solution.
I've also found a way to do it but it's ugly: placing on the update method of the form this code:
for widget in widgets:
name = widget.context.getName()
if errors:
for error in errors:
if isinstance(error, Invalid) and name in error.args[1:]:
if widget._error is None:
widget._error = error
Isn't there a lower level implementation that allows to pass the names of the fields to the raised Invalid and does not need to loop trough all the fields and all the errors for each field?!?
You can do this by doing your extra validation in the form's action handler, and raise WidgetActionExecutionError specifying the widget for which the error should be shown.
This looks as follows (taken from http://plone.org/products/dexterity/documentation/manual/schema-driven-forms/customising-form-behaviour/validation):
from five import grok
from plone.directives import form
from zope.interface import invariant, Invalid
from zope import schema
from z3c.form import button
from z3c.form.interfaces import ActionExecutionError, WidgetActionExecutionError
from Products.CMFCore.interfaces import ISiteRoot
from Products.statusmessages.interfaces import IStatusMessage
from example.dexterityforms.interfaces import MessageFactory as _
...
class OrderForm(form.SchemaForm):
...
#button.buttonAndHandler(_(u'Order'))
def handleApply(self, action):
data, errors = self.extractData()
# Some additional validation
if 'address1' in data and 'address2' in data:
if len(data['address1']) < 2 and len(data['address2']) < 2:
raise ActionExecutionError(Invalid(_(u"Please provide a valid address")))
elif len(data['address1']) < 2 and len(data['address2']) > 10:
raise WidgetActionExecutionError('address2', Invalid(u"Please put the main part of the address in the first field"))
if errors:
self.status = self.formErrorsMessage
return
I think it may also be possible to raise WidgetActionExecutionError from your invariant, but then it might not do what you want if the invariant is getting checked at some other time than while processing a z3c.form form.