Filter lines by categ_id and count qty - odoo

My goal is to loop through all lines with the same categ_id and calculate total quantity they have and if qty_categ_total < categ_id.qty_for_discount ( I added this field to 'product.category' than I need to post a message in text fields. the problem my code is not working as I want.
Example.
If I have 2 lines with the same categ_id with qty 2 and 5 and my categ_id.qty_for_discount is 10. The message should say that I need to add 3 more products with the same categ_id to get discount
Update
And if there are products with different categories I should get a message for each category
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
discount_warning_message = fields.Text(string='Discount Warning', compute='discount_warning')
#api.depends('order_line.product_id', 'order_line.product_qty')
def discount_warning(self):
qty_categ_total = 0.0
for line in self.order_line:
qty_categ_total += line.product_qty
if qty_categ_total < line.product_id.categ_id.qty_for_discount:
message = (_("You can get discount if you add %s more %s\n")) % (qty_categ_total, line.product_id.categ_id.name)
self.discount_warning_message = message

Your code seems to be correct, but i would change something. First either use #api.one to let odoo automatically loop through all orders or add one more for each loop and #api.multi. And secondly what about more than one category?
#api.multi
#api.depends('order_line.product_id', 'order_line.product_qty')
def discount_warning(self):
msg = _("You can get discount if you add %s more %s\n")
for order in self:
categ_qtys = {}
for line in order.order_line:
if line.product_id.categ_id not in categ_qtys:
categ_qtys[line.product_id.categ_id] = 0.0
categ_qtys[line.product_id.categ_id] += line.product_qty
msgs = []
for categ, qty in categ_qtys.iteritems():
if qty < categ.qty_for_discount:
msgs.append(msg % (qty, categ.name))
if msgs:
order.discount_warning_message = "".join(msgs)
General advice: Always try to debug into your methods. Are they even called? If not, the methods aren't the problem.

Related

Unable to iterate a list to a thread

I am trying to pass a json return between functions but I get errors. So I convert the json to a list. However, I cannot iterate the list from a while loop unless I specify an actual number.
Full code is
class BackendThread(QThread):
update_date = pyqtSignal(list)
def run(self):
device_mode = []
while True:
#do stuff and get json_return
for xx in json_return["result"]["devices"]:
for y in xx["nodes"]:
if y['type'] == "FRAME_BUFFER":
data = xx["device_id"] + "\n" + y['configuration']['display_mode']
device_mode.append(data)
self.update_date.emit(str(device_mode))
device_mode = []
time.sleep(1)
class Window(QDialog):
def __init__(self):
QDialog.__init__(self)
self.resize(400,400)
self.input=QTextEdit(self)
self.input.resize(400,400)
self.initUI()
def initUI(self):
self.backend=BackendThread()
self.backend.update_date.connect(self.handleDisplay)
self.backend.start()
def handleDisplay(self,data):
count = 0
while count < 11:
self.input.setText(data[count])
count += 1
if __name__ == '__main__':
app=QApplication(sys.argv)
win =Window()
win.show()
sys.exit(app.exec_())
So this part does not work. I only get the last item in the list
count = 0
while count < 11:
self.input.setText(data[count])
count += 1
When I do this, it works but I cannot hard code the item number becuase the list will never have the same amount of items
self.input.setText(data[0])
self.input.setText(data[1])
self.input.setText(data[2])
etc
Any ideas as to how to get that while loop working?

How can I convert the total price of an invoice to letters in odoo 11?

I have a created module called 'custom_report_module', where I make a personalized invoice ... The invoice works well but I want to add the total amount in letters .. for example .. if the purchase reached 500,000 that I printed in letters "are: five hundred thousand guaranies "or" are: five hundred thousand "
class account_invoice(models.Model):
_inherit = "account.invoice"
#api.multi
def amount_to_text(self, amount, currency='rupee'):
return amount_to_text(amount, currency)
my xml
<span t-esc="l.amount_to_text(l.price_unit, l.price_unit)"/>
Please have a look at the this code
#api.multi
def amount_to_text(self, amount):
self.ensure_one()
def _num2words(number, lang):
try:
return num2words(number, lang=lang).title()
except NotImplementedError:
return num2words(number, lang='en').title()
if num2words is None:
logging.getLogger(__name__).warning("The library 'num2words' is missing, cannot render textual amounts.")
return ""
formatted = "%.{0}f".format(self.decimal_places) % amount
parts = formatted.partition('.')
integer_value = int(parts[0])
fractional_value = int(parts[2] or 0)
lang_code = self.env.context.get('lang') or self.env.user.lang
lang = self.env['res.lang'].search([('code', '=', lang_code)])
amount_words = tools.ustr('{amt_value} {amt_word}').format(
amt_value=_num2words(integer_value, lang=lang.iso_code),
amt_word=self.currency_unit_label,
)
if not self.is_zero(amount - integer_value):
amount_words += ' ' + _('and') + tools.ustr(' {amt_value} {amt_word}').format(
amt_value=_num2words(fractional_value, lang=lang.iso_code),
amt_word=self.currency_subunit_label,
)
return amount_words

Scrapy: How would I add an item that numbers entries in my CSV output?

I need to include an item in my spider (item['number'] = ... ) that just assigns a number to each scraped row in my CSV output file in ascending order.
So the "number" column would assign a 1 to the first row, a 2 to the second row and so on. How would I code the item to return this in a way that returns incrementations of +1 each time?
*In case your wondering, I need to use the number column as a Dim Primary Key for a cube database.
Any help is appreciated. Thank you!
When you will read your csv file, you can use enumerate like:
import csv
with open('file.csv', 'w') as csvfile:
reader = csv.reader(csvfile)
for i, row in enumerate(reader, start=1):
print(i)
If you really want the number to be part of the item generation process and output, then you can use a Pipeline.
settings.py
ITEM_PIPELINES = {
"myspider.pipelines.NumberPipeline": 300,
}
pipelines.py
class NumberPipeline(object):
def open_spider(self, spider):
self.number = 1 # The starting number.
def process_item(self, item, spider):
item['number'] = self.number
self.number += 1
return item

Update fields with different number of values

In res.partner model I have a field
property_product_pricelist = fields.Many2many('product.pricelist')
and in sale.order
alternative_pricelist_ids = fields.Many2many(
'product.pricelist')
Partner can have more than one price list so my goal is to add the first pricelist to the pricelist_id field and other pricelists to alternative_pricelist_ids. The things are that how I wrote code is not really good, as you can see I will get an error if there are more than 4 pricelists. So how can I avoid it and write it another way?
#api.multi
#api.onchange('partner_id')
def onchange_partner_id(self):
super(SaleOrder,self).onchange_partner_id()
values = { 'pricelist_id': self.partner_id.property_product_pricelist[0] and self.partner_id.property_product_pricelist.id[0] or False,
'alternative_pricelist_ids': self.partner_id.property_product_pricelist[1] and self.partner_id.property_product_pricelist[2] and self.partner_id.property_product_pricelist[3] or False,
}
self.update(values)
Try this :
#api.multi
#api.onchange('partner_id')
def onchange_partner_id(self):
super(SaleOrder, self).onchange_partner_()
for record in self:
pricelist_id = False
alternative_ids = []
for pricelist in record.partner_id.property_product_pricelist:
if not pricelist_id:
pricelist_id = pricelist.id
else:
alternative_ids.append(pricelist.id)
record.pricelist_id = pricelist_id
record.alternative_pricelist_ids = [(6, 0, alternative_ids)]

Odoo - Is it possible to show both tax included and tax excluded total price in invoice lines ?

I try to show both columns in the account invoice form :
total of an invoice line, tax excluded
total of an invoice line, tax included.
I know that it is possible to set the tax object to be included or excluded in product price, but I don't see the way to show both in invoice form.
I already extended account.invoice.line as follow :
from openerp import api, models, fields
import openerp.addons.decimal_precision as dp
class cap_account_invoice_line(models.Model):
_inherit = 'account.invoice.line'
price_with_tax = fields.Float(string='Prix TTC', digits= dp.get_precision('Product Price'), store=True, readonly=True,)
"""
#api.multi
def button_reset_taxes(self):
#I guess I should override this method but i don't know how
#to calculate and load the total line with included tax
#into the field 'price_with_tax'
"""
Thank you in advance for your help
Victor
Solution found :
from openerp import api, models, fields
import openerp.addons.decimal_precision as dp
class AccountInvoiceLine(models.Model):
_inherit = 'account.invoice.line'
price_subtotal_tax = fields.Float(compute='_compute_price_tax', string=' Total including tax', digits= dp.get_precision('Product Price'), store=True)
#api.one
#api.depends('price_unit', 'discount', 'invoice_line_tax_id', 'quantity',
'product_id', 'invoice_id.partner_id', 'invoice_id.currency_id')
def _compute_price_tax(self):
price = self.price_unit * (1 - (self.discount or 0.0) / 100.0)
taxes = self.invoice_line_tax_id.compute_all(price, self.quantity, product=self.product_id,
partner=self.invoice_id.partner_id)
self.price_subtotal_tax = taxes['total_included']
if self.invoice_id:
self.price_subtotal_tax = self.invoice_id.currency_id.round(self.price_subtotal_tax)