Create Sale Order Line in route_id on-change method - python-3.x

I have to create sale order line in on change of route_id, but i am trying to using self.copy() method, but there is issue of order_id.
I didn't get order_id, because I need current record id of Sale Order instead of NewId.
#api.multi
#api.onchange('route_id')
def _onchange_route_id(self):
# Ht stock route dosen't have enough quantity, add new sale order line
remain_qty = 0
route_ht_stock = self.env.ref('custom_stock.route_warehouse0_ht_stock', raise_if_not_found=False)
if self.route_id.id == route_ht_stock.id:
if not self.product_id.qty_available >= self.product_uom_qty:
remain_qty = self.product_uom_qty - self.product_id.qty_available
new_line = self.copy(default = {'order_id': self.order_id}))

Related

how to insert multiple rows into sqllite3 database

I am trying to select rows and fetch them from the DB table and then insert them into a list so I can insert all of the rows at once into the database, but I got an error.
def paid_or_returned_buyingchecks(self):
date = datetime.now()
now = date.strftime('%Y-%m-%d')
self.tenlistchecks=[]
self.con = sqlite3.connect('car dealership.db')
self.cursorObj = self.con.cursor()
self.dashboard_buying_checks_dates = self.cursorObj.execute("select id, paymentdate , paymentvalue, car ,sellername from cars_buying_checks where nexttendays=?",(now,))
self.dashboard_buying_checks_dates_output = self.cursorObj.fetchall()
self.tenlistchecks.append(self.dashboard_buying_checks_dates_output)
print(self.tenlistchecks)
self.dashboard_buying_checks_dates = self.cursorObj.executemany("insert into paid_buying_checks VALUES(?,?,?,?,?)",[self.tenlistchecks])
self.con.commit()
but I got an error :
[[(120, '21-08-2022', '1112', 'Alfa Romeo', 'james'), (122, '21-08-2022', '465', 'Buick', 'daniel '), (123, '21-08-2022', '789', 'Buick', 'daniel ')]]
self.dashboard_buying_checks_dates = self.cursorObj.executemany(
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 5, and there are 1 supplied.
self.cursorObj.fetchall() returns a list of tuples, which is what you need to feed to executemany, so
self.cursorObj.executemany("insert into paid_buying_checks VALUES(?,?,?,?,?)",self.tenlistchecks)
not
self.cursorObj.executemany("insert into paid_buying_checks VALUES(?,?,?,?,?)",[self.tenlistchecks])

Odoo 13: Creating invoice from purchase order in odoo via api

I am brand new to odoo! On odoo 13 EE I am trying to create and confirm a vendor bill after importing a purchase order and the item receipts. I can create an invoice directly, but haven't been able to link that to the PO/receipt?
Sadly under purchase.order the method action_create_invoice seems hidden from the API
order_id = PurchaseOrder.create(po)
purchaseorder = PurchaseOrder.browse([order_id])
print("Before validating:", purchaseorder.name, purchaseorder.state) # draft
odoo.env.context['check_move_validity'] = True
purchaseorder.button_confirm()
purchaseorder = PurchaseOrder.browse([order_id])
picking_count = purchaseorder.picking_count
print("After Post:", purchaseorder.name, purchaseorder.state, "picking_count = ", purchaseorder.picking_count)
if picking_count == 0:
print("Nothing to receive. Straight to to Billing.") # ok so far
tryme = purchaseorder.action_view_invoice()
## Error => odoorpc.error.RPCError: type object 'purchase.order' has no attribute 'action_create_invoice'
SO I tried overriding/extending this way
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
#api.model
def create_invoice(self, context=None):
# try 1 => odoorpc.error.RPCError: 'super' object has no attribute # 'action_create_invoice'
rtn = super().action_create_invoice(self)
# try2 => odoorpc.error.RPCError: name 'action_create_invoice' is # not defined
# rtn = action_create_invoice(self)
# try3 => Error %s 'super' object has no attribute ' # action_create_invoice'
# rtn = super(models.Model, self).action_create_invoice(self)
return rtn
I hope somebody can suggest a solution! Thank you.
Please dont customize it without having a functional knowledge in odoo. In odoo, if you go to purchase settings, you can find billing options under invoicing where you can find 2 options, ordered quantity and received quantity. if it is ordered quantity, then you can create invoice after confirming the Purchase order. if it is received quantity, then after confirming the purchase order, a incoming shipment will be created and after the incoming shipment is processed, you can find the create invoice button in purchase order
If you can do it from the browser client, than you should just look what API commands the browser sends to the odoo server (in Chrome by enabling the debug view by pressing F12, and looking in the network tab), so that you just need to copy that communication.

How can i change a boolean value in model A, when a new instance of model B (have many2one field to model A) is created in ODOO 12?

I have two odoo 12 models,(biblio.location and biblio.book),
-the model "biblio.book" contains a boolean "disponibile" set to true by defaul.
-the model "biblio.location" have a many2one field references to model "biblio.book".
i want the value of the boolean "disponible" in biblio.book to be changed automatically (change also in database) when a new instance of biblio.location is created, in other way when we rent(location) a book we must change disponibility in model book to FALSE.
i tried "computed field, #api.onchange and #api.depends" and nothing works for me, please help me in this issue and i want to know de difference between those three mehods.thank you
class book(models.Model):
_name = 'biblio.book'
_description = 'All books'
name=fields.Char()
annee_edition = fields.Date(string="année d'édition")
ISBN = fields.Integer(required=True)
editor = fields.Char(required=True)
auteur = fields.Many2many('biblio.author',string='auteur_livre',required=True)
disponible=fields.Boolean(default=True,required=True,related='biblio.location.disponible',store=True )
class location(models.Model):
_name = 'biblio.location'
_description = 'All librarians'
name=fields.Char()
livre = fields.Many2one('biblio.book',string='livre',required=True,domain =[('disponible','=',True)])
client = fields.Many2one('biblio.customer',string="client",required=True)
date_location =fields.Datetime(required=True)
date_retour_prevu=fields.Datetime(required=True,string="Date retour prévu")
date_retour_reelle=fields.Datetime(required=True,string="Date retour réelle")
disponible = fields.Boolean(default=False)
File "C:\Users\PycharmProjects\Odoo12\odoo\odoo\fields.py", line 484, in setup_full
self._setup_related_full(model)
File "C:\User\PycharmProjects\Odoo12\odoo\odoo\fields.py", line 527, in _setup_related_full field = target._fields[name]
KeyError: 'biblio' - - -
OK, for this to work the way you want it you need to set up a foreign key in your biblio.book model.
book_location = fields.Many2one('biblio.location', string='Book Location')
Then you can do your computed field
disponible = field.Boolean(compute='_disponible', string='Available for Loan', default=False)
#api.model
def _disponible(self):
for book in self:
book.disponible = True if book.book_location else False
You don't want to set this as storable as you want it to check every time that the field is called. If you set it to storable it will only compute when the record is created.

How to call a function every interval time Odoo 11

i know we can create automatic action using cron in odoo
but I want something a different
in the mass mailing of odoo i want to add a repetion option of mail mass mailings
Example in the Form view_mail_mass_mailing_form > Options page
I added a repetition selection field,
I added this because I want each mass mail alone
class MailMassMailing(models.Model):
_inherit = 'mail.mass_mailing'
recurrence_mail = fields.Selection([
('daily', 'Day'),
('weekly', 'Weeks'),
('monthly', 'Months'),
], string='Recurring')
I want this mass mailng to send each (days or weeks or months)
how to call a function with interval date,
how to call a function every (days or weeks or months)
The sending of this mass mailing is revived from the date of creation
Just extend Mass Mailing model with a new date field and implement a model method to use for a daily running ir.cron.
from odoo import api, fields, models
class MailMassMailing(models.Model):
_inherit = 'mail.mass_mailing'
recurrence_mail = fields.Selection([
('daily', 'Day'),
('weekly', 'Weeks'),
('monthly', 'Months'),
], string='Recurring')
last_sent_on = fields.Date()
#api.model
def run_send_recurring(self):
""" Resend mass mailing with recurring interval"""
domain = [('recurrence_mail', '!=', False)]
# TODO monthly should be solved in another way, but that
# is not needed for this example
deltas = {'daily': 1, 'weekly': 7, 'monthly': 30}
today = fields.Date.today()
for mass_mail in self.search(domain):
# never sent? go send it
if not mass_mail.last_sent_on:
# send the way you want
# or get delta between today and last_sent_on
last_dt = fields.Date.from_string(mass_mail.last_sent_on)
if (today - last_dt).days >= deltas[mass_mail.recurrence_mail]:
# send the way you want
Thank you #CZoellner for your help
I found the solution with your idea
# Solution ############### .py
#api.model
def run_send_recurring(self):
""" Resend mass mailing with recurring interval"""
date_format = '%Y-%m-%d'
domain = [('recurrence_mail', '!=', False),('state','=','done')]
deltas = {'daily': 1, 'weekly': 7, 'monthly': 30}
logger.info("______deltas________: %s ",deltas)
today = fields.Date.today()
logger.info("______today________: %s ",today)
for mass_mail in self.search(domain):
logger.info("______mass_mail________: %s ",mass_mail)
# never sent? go send it
if not mass_mail.last_sent_on:
self.put_in_queue()
joining_date = mass_mail.last_sent_on
current_date = (datetime.today()).strftime(date_format)
print('joining_date',joining_date)
d1 = datetime.strptime(joining_date, date_format).date()
logger.info("______1 day________: %s ",d1)
d2 = datetime.strptime(current_date, date_format).date()
logger.info("______2 day________: %s ",d2)
logger.info("______deltas[mass_mail.recurrence_mail]________: %s ",deltas[mass_mail.recurrence_mail])
r = relativedelta(d1,d2)
logger.info("______r day________: %s ",r.days)
if (r ,'>=' , deltas[mass_mail.recurrence_mail]):
mass_mail.put_in_queue()

select on sub query peewee

I am wondering if I can do select() on sub_query.
I am able to do join sub_query with any peewee.Model. But when I wrote a sub_query and I wanted to just group by with one of the column
e.g. sub_query.select(sub_query.c.column_1, fn.COUNT(sub_query.c.column2)alias('col2_count')).group_by(sub_query.c.column_1)
query was not nested and was giving SQL syntax error.
(Can't reveal the code)
(I have done alias() on sub_query)
Edit
Example:
class Product(Model):
id = PrimaryKeyField()
name = CharField()
created_date = DateField()
class Part(Model):
id = PrimaryKeyField()
product = ForeignKeyField(Product)
name = CharField()
class ProductError(Model):
id = PrimaryKeyField()
product = ForeignKeyField(Product)
note = CharField()
class PartError(Model):
id = PrimaryKeyField()
part = ForeignKeyField(Part)
error = ForeignKeyField(ErrorMaster)
Here Product can have general error and
parts can have specific error which are predefined in ErrorMaster
I just want to know count of product which have errors against total products date wise. (error is product error or error in any part)
So sub_query is something like
sub_q = Product.select(
Product.created_date,
Product.id.alias('product_id'),
fn.IF(# checks if product has error
ProductError.is_null(True), if no product error check part error
fn.IF(fn.COUNT(PartError.id) == 0, 0, 1), # checks if error count > 0 then there is error in part
1
).alias('is_error')
).join(Part, on=Product.id == Part.product)
.join(ProductError, JOIN_LEFT_OUTER, on=Product.id == ProductError.product)
.join(PartError, JOIN_LEFT_OUTER, on=PartError.part == Part.id)
.where(Product.created_date.between(from_date, to_date))
.group_by(Product.id).alias('some_alias')
# below does not work but I can do this in sql
query = sub_q.select(sub_q.c.created_date,
fn.COUNT(sub_q.c.product_id).alias('total_products'),
fn.SUM(sub_q.c.is_error).alias('product_with_errors'))
.group_by(sub_q.c.created_date)

Resources