Using Odoo 15 and python xmlrpc for API
here is my problem: I have a created payment for which I store the id. Then, when i create the invoice that corresponds, I want to be able to add this specific outstanding credit of the customer through API just like this "Ajouter" (Add) button does. ("crédits en circulation" is outstanding credits):
invoice screenshot
How would I do with python and xml-rpc tu simulate the use of this button for a specific payment (with its id)?
Note: For our sales workflow we have to create payments straight away and invoices later so I can't create the payment when creating the invoice
When you click on Add button, Odoo will call the js_assign_outstanding_line function.
def js_assign_outstanding_line(self, line_id):
''' Called by the 'payment' widget to reconcile a suggested journal item to the present
invoice.
:param line_id: The id of the line to reconcile with the current invoice.
'''
self.ensure_one()
lines = self.env['account.move.line'].browse(line_id)
lines += self.line_ids.filtered(lambda line: line.account_id == lines[0].account_id and not line.reconciled)
return lines.reconcile()
The Add button depends on the value of the computed invoice_outstanding_credits_debits_widget field. To reproduce the same logic using XML-RPC, you need to get the payment credit line id and call the js_assign_outstanding_line function like following:
models.execute_kw(db, uid, password, 'account.move', 'js_assign_outstanding_line', [move_id, line_id])
It will add the payment and return the result of reconcile function which will raise the following error (XML-RPC code):
TypeError: cannot marshal <class \'odoo.api.account.partial.reconcile\'> objects\n'>
Related
I am trying to make a single action on a sales order in Odoo v15 CE that creates an invoice for the sales order and immediately posts it and registers a payment for it. The way I'm doing so is through a wizard method that looks like this:
def create_invoices(self):
sale_orders = self.env['sale.order'].browse(self._context.get('active_ids', []))
for order in sale_orders:
order._create_invoices()
for inv in order.invoice_ids:
# make invoice:
inv.action_post()
# register payment
# ????
Currently, it creates the invoice and posts it. I would like to add something like inv.register_payment() to the final line in order to register the payment.
I've fount the action_register_payment method of the account.move model and also looked into using the account.payment.register wizard but neither worked. I've also found this question, which is trying to do something similar, but through an XML-RPC call (from what I can tell).
Can anyone please explain how to do this? Thanks!
You have to post the invoices using action_post then register payment by creating a payment like in
https://github.com/odoo/odoo/blob/15.0/addons/account/wizard/account_payment_register.py#L496
account.payment.register is a wizard, that's why you need to create values for it, otherwise you can action_register_payment which is a window action that will trigger the wizard and then it's for the user to register the payment (which is the standard behavior of Odoo)
You can create an account.payment.register record and pass the model and invoice ids in context then call action_create_payments to create the payment with the default values.
Example:
payment_register.with_context(
{'active_model': 'account.move',
'active_ids': inv.ids}
).create({}).action_create_payments()
In Odoo 10, when user "A" creates a new sales order and assigns it to a different salesperson (user "B"), no matter what configuration you have applied to email templates/subtypes/send notifications, an email is automatically sent to the customer and the salesperson (I am still amazed on which business logic was follow to send internal notification emails to customers by default).
The email is the well known one with this format:
"You have been assigned to SOxxxx."
To make things worse the email is set to "Auto-delete", so you do not even know what your system is sending to customers (no comments).
Which module or function or setting in Odoo 10 CE shall be overwritten to avoid such default behaviour?
Overwrite _message_auto_subscribe_notify method for sale.order class and add to context mail_auto_subscribe_no_notify.
from odoo import models, api
class SaleOrder(models.Model):
_inherit = 'sale.order'
#api.multi
def _message_auto_subscribe_notify(self, partner_ids):
""" Notify newly subscribed followers of the last posted message.
:param partner_ids : the list of partner to add as needaction partner of the last message
(This excludes the current partner)
"""
return super(SaleOrder, self.with_context(mail_auto_subscribe_no_notify=True))\
._message_auto_subscribe_notify(partner_ids)
The original method will not send the message if that key is passed in the context
#api.multi
def _message_auto_subscribe_notify(self, partner_ids):
""" Notify newly subscribed followers of the last posted message.
:param partner_ids : the list of partner to add as needaction partner of the last message
(This excludes the current partner)
"""
if not partner_ids:
return
if self.env.context.get('mail_auto_subscribe_no_notify'): # Here
return
# send the email only to the current record and not all the ids matching active_domain !
# by default, send_mail for mass_mail use the active_domain instead of active_ids.
if 'active_domain' in self.env.context:
ctx = dict(self.env.context)
ctx.pop('active_domain')
self = self.with_context(ctx)
for record in self:
record.message_post_with_view(
'mail.message_user_assigned',
composition_mode='mass_mail',
partner_ids=[(4, pid) for pid in partner_ids],
auto_delete=True,
auto_delete_message=True,
parent_id=False, # override accidental context defaults
subtype_id=self.env.ref('mail.mt_note').id)
If this should only be disabled for SaleOrder which are generated through custom code (e.g. an developed API endpoint), you could use the with_context() method on each model:
sale_order = {
'partner_id': partner['id'],
'state': 'sent',
'user_id': 6,
'source_id': 3,
'currency_id': currency['id'],
'payment_term_id': payment_term['id'],
}
created_sale_order = request.env['sale.order'].with_context(mail_auto_subscribe_no_notify=True).create(sale_order)
In my example, the user with the ID 6 does not get the notification about the assignment of this sale order.
I'm creating a bill (supplier invoice) in Xero API (C# .Net). Everything populates perfectly except for the Reference number which remains blank.
Excerpt:
var invoiceObject = new Invoice
{
Reference = "TEST123",
Contact = contact,
Date = DateTime.Now,
DueDate = DateTime.Now,
ExpectedPaymentDate = DateTime.Now,
Status = Xero.Api.Core.Model.Status.InvoiceStatus.Draft,
LineItems = lineItems,
Type = Xero.Api.Core.Model.Types.InvoiceType.AccountsPayable
};
var invoice = api.Invoices.Create(invoiceObject);
The following screenshot demonstrates the issue:
Every other field, lineitem, tax code, etc. populates perfectly.
I've tried different combinations of upper and lowercase characters, numbers, etc. but it doesn't work.
If I log in to Xero, open the Invoice and manually enter TEST123 an save the invoice, it works perfectly.
I've also tried saving the invoice, then editing it and re-saving in the API and the reference still does not populate.
How can I set the reference in the API?
Quick answer
Xero Invoice API docs indicate that you can't set the reference value for an ACCPAY invoice, but that whatever you put for the Invoice Number (which is a non-unique field on ACCPAY Invoices) will also appear in the reference field.
Explanation
I ran into this same issue. I found this comment on Xero's support forum:
https://community.xero.com/developer/discussion/40489223
... which says this:
Reference is presently slightly differently based on whether the
invoice is a sales invoice (ACCREC) or a purchase invoice/bill
(ACCPAY). For a bill the reference is presented in the InvoiceNumber
element, check our documentation on invoices here where we explain
this in more detail.
From the linked to docs
All that said, the screenshot you include in your post does have a "reference" input on it, but that's not an input for the invoice's reference value - that's an input for a possible reference value for a payment you enter against the invoice. The reference value for an invoice appears at the top next to the due date:
I have the exact same issue. I'm using Python Xero but hopefully, it is the same for Javascript.
In my case, I have to use InvoiceNumber instead of Reference for bills.
I'm adding a new product to the open erp. However, I'm unable to add a unique number to each product. But there should be a unique product number for every product.
You can use #api.constrains decorator.
#api.one
#api.constrains('code')
def _unique_code(self):
if len(self.search([('code', '=', self.code)])) > 1:
raise ValidationError("Product code must be unique!")
Id is the always unique for all model in openerp.
And another way,
you can also add your custome field for unique number usind "_sql_constraints"
eg: _sql_constraints = [
('seq_uniq', 'unique (item_code)', _("The Item Code must be \
unique per Stage!"))]
I have a problem, I made two custom fields in
Sale.order
Stock.picking
How to do when the sale order is confirmed, the field in stock.picking also filled? and the data was picked up from the field at sale.order I've made before.
I'm using odoo 10
Thanks
Yeah, first, depend in your module of sale_stock, then, inherit the sales confirm button and search for the pickings associated:
#api.multi
def action_confirm(self):
result = super(SaleOrder, self).action_confirm()
for order in self:
order.picking_ids.write({'your_field_in_picking': order.your_field_in_sale})
return result
Put it in a class that inherits from sale.order