I'm trying to redirect to view account.view_move_form after invoicing several POS orders and merging those invoices into one, but after the action is done it stays at POS order tree view. Here is my code:
def invoice_and_merge(self):
partner_id = self[0].partner_id
account_moves = []
account_moves_ids = []
wizard = {}
for pedido in self:
if pedido.partner_id != partner_id:
raise UserError('Todas las facturas debes ser del mismo cliente')
#Invoice each order at a time and add to array
account_moves.append(pedido.action_pos_order_invoice())
for move in account_moves:
account_moves_ids.append(move['res_id'])
factura = self.env['account.move'].search([('id', '=', move['res_id'])])
# Set state of created invoices to Draft so they can be merged
factura.button_draft()
wizard['merge_type'] = 'cancel'
wizard['partner_id'] = partner_id.id
merge_invoice = self.env['sh.minv.merge.invoice.wizard'].with_context({'active_ids': account_moves_ids}).create(wizard)
# This is a third party app that merges serveral invoices into a new one and returns a tree view with all new invoices
ret = merge_invoice.action_merge_invoice()
facturas = self.env['account.move'].search([('id','in', ret['domain'][0][2])])
id = 0
for factura in facturas:
if factura.name == '/':
self.account_move = factura
id = factura.id
# Set state of merged invoice to Posted
factura.action_post()
else:
factura.write({'agrupado': True})
# Return form view with the new invoice
return {
'name': _('Customer Invoice'),
'view_mode': 'form',
'view_id': self.env.ref('account.view_move_form').id,
'res_model': 'account.move',
'context': "{'move_type':'out_invoice'}",
'type': 'ir.actions.act_window',
'nodestroy': True,
'res_id': id,
'target': 'current'
}
Related
I have to construct a comment API to show whether the current member has liked it.
In Django I can send users infomation by context in serializer.
I have no idea in FastApi.
class Level2CommentListSerializer(serializers.ModelSerializer):
favor = serializers.SerializerMethodField()
class Meta:
model = CommentRecord
fields = "__all__"
read_only_fields = ['id', 'user', 'article', 'content', 'root', 'replyId', 'depth']
def get_favor(self, obj):
uuid = self.context['user']
if not uuid:
return False
data = CommentFavorRecord.objects.filter(comment=obj, user__uuid=uuid)
if data:
return True
else:
return False
I tried:
client.lists.members.create('1111111', {
'email_address' : 'frogger116#gmail.com',
'status' : 'subscribed',
"tags": [{'name': 'frogger', 'status' : 'active'}],
})
and get:
mailchimp3.mailchimpclient.MailChimpError: {
'type': 'http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/',
'title': 'Invalid Resource',
'status': 400,
'detail': 'Expected argument of type "string", "stdClass" given',
'instance': '5ae1b966-ed35-49f1-ad32-0a39c3d63593'
}
Without the "tags" line the satement works
This works for me (you need hash the email address)
hash = get_subscriber_hash(email_address)
data = {
'tags': [
{'name': 'foo', 'status': 'active'},
{'name': 'bar', 'status': 'inactive'}
]
}
client.lists.members.tags.update(list_id=list_id, subscriber_hash=hash, data=data)
I think in the latest version the tags are just strings. At least, this is what I use.
client.lists.members.create('1111111', {
'email_address' : 'frogger116#gmail.com',
'status' : 'subscribed',
'tags': ['frogger','invaders']
})
Also, to be certain, make sure tags exist in the system. Especially if doing an update rather than insert. Its not super consistant about dealing with unknown tags.
Also of course, make sure the '1111111' audience id exists.
SUPPLEMENTAL CODE
Of course, I've found a better way to ensure what you want is to use other methods to add to tags rather than on insert. You may have to tweak the below functions as they are part of a class, but they should give you other ideas on how to add and remove tags from users
def bulkUpdateTagNamesForEmails(self, emailsToUpdate, tagNames, remove=False):
audienceId = self.audienceId
if remove:
data = {'members_to_remove':emailsToUpdate}
else:
data = {'members_to_add':emailsToUpdate}
segments = None
for tagName in tagNames:
segId,segments = self.getSegmentIdFromTagName(tagName,segments)
if segId:
self.brResponse = self.mcClient.lists.segments.update_members(list_id=audienceId, segment_id=segId, data=data)
def createTagNameIfNeeded(self, tagName):
audienceId = self.audienceId
# Check for tag name
found = False
segments = self.mcClient.lists.segments.all(list_id=audienceId, get_all=False)
for segment in segments['segments']:
if segment['name'] == tagName:
found = True
print("Found tag")
# If not found, create it
if not found:
print(f"Creating new tag {tagName}")
data = {'name': tagName,'static_segment': []}
self.mcClient.lists.segments.create(list_id=audienceId, data=data)
def getSegmentIdFromTagName(self,reqTagName,segments=None):
audienceId = self.audienceId
reqId = None
if not segments:
segments = self.mcClient.lists.segments.all(list_id=audienceId, get_all=True)
for segment in segments['segments']:
segName = segment['name']
segId = segment['id']
if segName == reqTagName:
reqId = segId
break
return reqId,segments
I am using a template to send an email. I want to send the email to multiple recipients, but in the field email_to accept only object attributes:
<field name="email_to">${object.attribute}</field>
I want to send email using the same template to multiple recipients.
I am using below code:
def action_send_email_to_attendees(self, cr, uid, ids, context=None):
'''
This function opens a window to compose an email
'''
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
ir_model_data = self.pool.get('ir.model.data')
try:
template_id = ir_model_data.get_object_reference(cr, uid, 'mymodule', 'mymodule_invitation_email')[1]
except ValueError:
template_id = False
try:
compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1]
except ValueError:
compose_form_id = False
ctx = dict(context)
ctx.update({
'default_model': 'mymodule.module',
'default_res_id': ids[0],
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
'mark_so_as_sent': True
})
return {
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.compose.message',
'views': [(compose_form_id, 'form')],
'view_id': compose_form_id,
'target': 'new',
'context': ctx,
}
I'm fiddling with paypalrestsdk on my Flask app and here is the sequence for the payment. Could anyone experienced point out whether the cycle is rigid or not?
Create payment with appropriate redirect URLs.
payment = paypalrestsdk.Payment({
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": url_for('.payment_success', _external=True),
"cancel_url": url_for('.payment_cancel', _external=True)
},
...})
if payment.create():
...
If successful, save the following payment response details in the database.
class PayPalPayment(db.Model):
__tablename__ = 'ediket_paypal_payment'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('ediket_ediketuser.id'))
payment_id = db.Column(db.String(30))
amount = db.Column(db.String(10))
state = db.Column(db.String(10))
redirect_url = db.Column(db.VARCHAR)
created_at = db.Column(db.DateTime)
updated_at = db.Column(db.DateTime)
Then, redirect using HATEOAS links.
Transaction proceeds in PayPal. Redirects to return url.
Find Current User's last transaction with 'created' status from database.
pending_payment = PayPalPayment.query.filter_by(user_id=user_id).filter_by(state='created').first()
Execute Payment using payment_id and payer_id
payment = paypalrestsdk.Payment.find(pending_payment.payment_id)
if payment.execute({"payer_id": request.args.get('PayerID')}):
#We are done!
#Update Payment model for completion
It all works fine, but I'm not too convinced whether this flow is safe for real world application. Since the return url only contains PayerID and Token, the only way to locate the relevant payment to execute is through blind query on Payment table using current user id and status='created'.
Is there a room for improvement?
Any modification since then was that I stored extra field called token, which is passed with HATEOAS links. By storing this token, I was able to locate user's pending payment to proceed with execute.
Update:
Here is the implementation detail. It may not be perfect but it did the trick for now.
class PayPalPayment(db.Model):
__tablename__ = 'paypal_payment'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
payment_id = db.Column(db.String(30))
amount = db.Column(db.String(10))
state = db.Column(db.String(10))
token = db.Column(db.String(30))
redirect_url = db.Column(db.Text)
created_at = db.Column(db.DateTime)
updated_at = db.Column(db.DateTime)
def __init__(self, payment, product_id, user_id):
self.user_id = user_id
self.product_id = product_id
self.payment_id = payment.id
self.amount = payment.transactions[0].amount.total
self.state = payment.state
self.created_at = datetime.datetime.strptime(payment.create_time, "%Y-%m-%dT%H:%M:%SZ")
self.updated_at = datetime.datetime.strptime(payment.update_time, "%Y-%m-%dT%H:%M:%SZ")
for link in payment.links:
if link.method == "REDIRECT":
self.redirect_url = link.href
parsed = urlparse.urlparse(self.redirect_url)
self.token = urlparse.parse_qs(parsed.query)['token'][0]
#payment_view.route('/paypal', methods=['POST'])
#login_required
def paypal_payment():
user_id = current_user.get_id()
product = Product.query.filter_by(id=request.form.get('product')).first_or_404()
past = datetime.datetime.utcnow() - datetime.timedelta(minutes=3)
count = PayPalPayment.query.filter_by(user_id=user_id).filter_by(state='created').filter(PayPalPayment.created_at >= past).count()
# To prevent a spam where user creates Payment and never comes back to it
if count > 4:
return Response(render_template('payment/overflow.html'), mimetype='text/html')
payment = paypalrestsdk.Payment({
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": url_for('.payment_success', _external=True),
"cancel_url": url_for('.payment_cancel', _external=True)
},
"transactions": [{
"amount": {
"total": product.amount,
"currency": "USD"
},
"description": product.description
}]
})
if payment.create():
new_payment = PayPalPayment(payment, product.id, user_id)
db.session.add(new_payment)
db.session.commit()
return redirect(new_payment.redirect_url, code=302)
else:
return Response(render_template('payment/cancel.html'), mimetype='text/html')
#payment_view.route('/success')
#login_required
def payment_success():
user_id = current_user.get_id()
payerID = request.args.get('PayerID', None)
token = request.args.get('token', None)
pending_payment = PayPalPayment.query.filter_by(token=token).filter_by(state='created').first_or_404()
try:
payment = paypalrestsdk.Payment.find(pending_payment.payment_id)
except paypalrestsdk.exceptions.ResourceNotFound:
abort(404)
template = 'payment/error.html'
if payment.execute({"payer_id": request.args.get('PayerID')}):
pending_payment.state = payment.state
pending_payment.updated_at = datetime.datetime.strptime(payment.update_time, "%Y-%m-%dT%H:%M:%SZ")
template = 'payment/success.html'
db.session.commit()
return Response(render_template(template), mimetype='text/html')
Please feel free to criticize.
I'm new to tastypie and am trying to post to the following model:
class UserScore(models.Model):
"""
User Scores, used to categorise users
"""
user = models.OneToOneField(User)
category = models.ForeignKey(Category)
score = models.IntegerField()
and this is my api:
class UserScoreResource(ModelResource):
category = fields.ForeignKey(CategoryResource, 'category')
user = fields.OneToOneField(UserResource, 'user')
class Meta:
queryset = UserScore.objects.all()
resource_name = 'score'
authorization=Authorization()
allowed_methods = ['post', 'put', 'get']
In my unit tests I'm trying to run the following:
def test_no_post_to_userscore(self):
post_data = {
'user': {'resource_uri':'/api/v1/user/0/'},
'category': {'resource_uri':'/api/v1/category/0/'},
'score': 50,
}
print response.status_code
But am receiving a 500 error. Any help greatly appreciated!
Solved - bad syntax. Long day
Thanks