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.
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.
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 !
Finally I got to some kind of solution for it.
Just add a new field on the prescription model related to a medicament, a function field to show up the stock, and a button to add a new line to the prescription lines.
It would be something like:
(....)
medicament_to_prescribe = fields.Many2One('gnuhealth.medicament','Medicament to prescribe',
states={'readonly': Eval('state') != 'draft'},depends=['state'])
medicament_to_prescribe_qty_in_pharmacy = fields.Function(
fields.Char('Quantity', help='Quantity of medicament on pharmacy'),
'on_change_with_medicament_to_prescribe_qty_in_pharmacy')
(....)
@fields.depends('pharmacy','medicament_to_prescribe')
def on_change_with_medicament_to_prescribe_qty_in_pharmacy(self, name=None):
pool = Pool()
Product = pool.get('product.product')
if self.pharmacy and self.medicament_to_prescribe:
location_id = self.pharmacy.warehouse.id
with Transaction().set_context(locations=[location_id]):
quantity = 0
for product in [x for x in self.medicament_to_prescribe.name.template.products]:
product = Product(product.id)
quantity += product.quantity
return str(quantity)
return '0.0'
@classmethod
@ModelView.button
def prescribe(cls, prescriptions):
pool = Pool()
PrescriptionLine = pool.get('gnuhealth.prescription.line')
prescription = prescriptions[0]
if prescription.medicament_to_prescribe_qty_in_pharmacy == '0.0':
cls.raise_user_warning(str(prescription.id),'medicament_qty_unknown',{},'There is no stock registered of this medicament')
PrescriptionLine.create([{
'name': prescription.id,
'medicament': prescription.medicament_to_prescribe.id,
'quantity': prescription.medicament_to_prescribe.name.qty_out,
'duration': prescription.delivery_duration,
}])
This way the health professional can check on the fly the quantity and create or not a new line.