Get the stock on each line at the fly

Hi everyone,
I am working on gnuhealth and I need to make some customizations on the prescriptions order form.
The idea is to have the remaining stock on the same line that the medicament prescription at the time the new line is created.

So I have something like this:

class PatientPrescriptionOrder(metaclass=PoolMeta):
       (......)
    prescription_line = fields.One2Many(
        'gnuhealth.prescription.line', 'name', 'Prescription line',
        states = STATES)
    pharmacy = fields.Many2One(
        'party.party', 'Pharmacy', domain=[('is_pharmacy', '=', True)],
        states={
            'readonly': (Eval('state') != 'draft') & Bool(Eval('pharmacy')),
            },
        depends=['state'])
     (....)

class PrescriptionLine(metaclass=PoolMeta):
    (....)
    stock = fields.Function(fields.Char('Stock on pharmacy'),
        'on_change_with_stock')
    (....)

   @fields.depends('quantity', 'name', 'medicament')
    def on_change_with_stock(self, name=None):
        pool = Pool()
        Product = pool.get('product.product')
               
        if self.name.pharmacy and self.name.pharmacy.warehouse:
            warehouse_id = self.name.pharmacy.warehouse.id
            products = Product.search([('template.id','=',self.medicament.name.template.id)])
            products_by_location = Product.products_by_location(
                location_ids = [warehouse_id],
                with_childs=True)
            stock = sum([products_by_location[(warehouse_id,x.id)] for x in products])
            if stock > 0:
                return str(stock)
        return '-------'

This way only works when the PatientPrescriptionOrder is saved.

Any help will be really appreciated. Thanks

I think this behaviour is done on health_service module, using the service line and description. Please take a look.

If you have a product and a warehouse you can just browse it using the proper context:

Product = pool.get('product.product')
with Trsansaction().set_context(locations=[location_id]):
    product = Product(product_id)
    return product.quantity

Where product_id is the id of the product to get the stock and location_id is the id of location where to compute the stock. It can be a warehouse or any storage location.

Hope this helps!

1 Like

It is a fancy solution, but it doesn’t work on my case. It only shows the quantity once the form is saved. I need to show quantities when the medicament is set.
Thanks anyway :+1:!

You should use an function field which is computed when the medicament is changed (using on_change_with).

This will show the values when the form is saved but also update them when the medicament is changed.

1 Like

Indeed I am using an on_change function_with.

Thanks anyway!