Mercurial > hgweb > health
changeset 4878:0af7f7ed8f6f
task #16043: Migration to GNU Health 4.0: Migrate and cleanup health_stock
| author | Luis Falcon <falcon@gnuhealth.org> |
|---|---|
| date | Sat, 15 Jan 2022 11:11:19 +0000 |
| parents | f878697cc363 |
| children | 6acbbe8bcac4 |
| files | tryton/health_stock/__init__.py tryton/health_stock/data/messages/messages.xml tryton/health_stock/exceptions.py tryton/health_stock/health_stock.py tryton/health_stock/tryton.cfg tryton/health_stock/wizard/wizard_create_prescription_stock_move.py tryton/health_stock/wizard/wizard_create_vaccination_stock_move.py |
| diffstat | 7 files changed, 164 insertions(+), 132 deletions(-) [+] |
line wrap: on
line diff
--- a/tryton/health_stock/__init__.py +++ b/tryton/health_stock/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ############################################################################## # # GNU Health: The Free Health and Hospital Information System @@ -23,26 +22,31 @@ ############################################################################## from trytond.pool import Pool -from .health_stock import * -from .wizard import * +from . import health_stock +from . import wizard + def register(): Pool.register( - Party, - Lot, - Move, - PatientAmbulatoryCare, - PatientAmbulatoryCareMedicament, - PatientAmbulatoryCareMedicalSupply, - PatientRounding, - PatientRoundingMedicament, - PatientRoundingMedicalSupply, - PatientPrescriptionOrder, - PatientVaccination, + health_stock.Party, + health_stock.Lot, + health_stock.Move, + health_stock.PatientAmbulatoryCare, + health_stock.PatientAmbulatoryCareMedicament, + health_stock.PatientAmbulatoryCareMedicalSupply, + health_stock.PatientRounding, + health_stock.PatientRoundingMedicament, + health_stock.PatientRoundingMedicalSupply, + health_stock.PatientPrescriptionOrder, + health_stock.PatientVaccination, + wizard.wizard_create_prescription_stock_move. CreatePrescriptionStockMoveInit, + wizard.wizard_create_vaccination_stock_move. CreateVaccinationStockMoveInit, module='health_stock', type_='model') Pool.register( + wizard.wizard_create_prescription_stock_move. CreatePrescriptionStockMove, + wizard.wizard_create_vaccination_stock_move. CreateVaccinationStockMove, module='health_stock', type_='wizard')
new file mode 100644 --- /dev/null +++ b/tryton/health_stock/data/messages/messages.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- This file is part of GNU Health. The COPYRIGHT file at the top level of +this repository contains the full copyright notices and license terms. --> +<tryton> + <data grouped="1"> + <record model="ir.message" id="msg_expired_vaccine"> + <field name="text">EXPIRED VACCINE. PLEASE INFORM THE LOCAL HEALTH AUTHORITIES AND DO NOT USE IT !!!</field> + </record> + <record model="ir.message" id="msg_stock_move_exists"> + <field name="text">Stock move already exists</field> + </record> + <record model="ir.message" id="msg_no_pharmacy"> + <field name="text">You need to select a pharmacy</field> + </record> + </data> +</tryton>
new file mode 100644 --- /dev/null +++ b/tryton/health_stock/exceptions.py @@ -0,0 +1,14 @@ +# This file is part of GNU Health. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. +from trytond.model.exceptions import ValidationError + + +class ExpiredVaccine(ValidationError): + pass + + +class StockMoveExists(ValidationError): + pass + +class NoPharmacy(ValidationError): + pass
--- a/tryton/health_stock/health_stock.py +++ b/tryton/health_stock/health_stock.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- ############################################################################## # # GNU Health: The Free Health and Hospital Information System @@ -23,39 +22,31 @@ ############################################################################## from datetime import datetime from trytond.model import Workflow, ModelView, ModelSQL, fields -from trytond.wizard import Wizard, StateView, Button, StateTransition from trytond.pyson import If, Or, Eval, Not, Bool from trytond.exceptions import UserError -from trytond.transaction import Transaction from trytond.pool import Pool, PoolMeta -from functools import reduce +from trytond.modules.health.core import get_health_professional +from trytond.i18n import gettext + +from .exceptions import (ExpiredVaccine) __all__ = ['Party', 'Lot', 'Move', - 'PatientAmbulatoryCare', 'PatientAmbulatoryCareMedicament', - 'PatientAmbulatoryCareMedicalSupply', - 'PatientRounding', 'PatientRoundingMedicament', - 'PatientRoundingMedicalSupply', - 'PatientPrescriptionOrder', 'PatientVaccination'] - + 'PatientAmbulatoryCare', 'PatientAmbulatoryCareMedicament', + 'PatientAmbulatoryCareMedicalSupply', + 'PatientRounding', 'PatientRoundingMedicament', + 'PatientRoundingMedicalSupply', + 'PatientPrescriptionOrder', 'PatientVaccination'] + _STATES = { 'readonly': Eval('state') == 'done', } _DEPENDS = ['state'] -""" -Deprecated : Using now the quantity related to the product -class Medicament(metaclass=PoolMeta): - __name__ = 'gnuhealth.medicament' - quantity = fields.Function(fields.Float('Quantity'), 'get_quantity') - - def get_quantity(self,name): - return self.name.quantity -""" - class Party(metaclass=PoolMeta): __name__ = 'party.party' - warehouse = fields.Many2One('stock.location', 'Warehouse', + warehouse = fields.Many2One( + 'stock.location', 'Warehouse', domain=[('type', 'in', ['warehouse', 'storage'])], states={ 'invisible': Not(Bool(Eval('is_pharmacy'))), @@ -74,7 +65,8 @@ class Lot(metaclass=PoolMeta): __name__ = 'stock.lot' expiration_date = fields.Date('Expiration Date') - + + class Move(metaclass=PoolMeta): __name__ = 'stock.move' @@ -92,11 +84,13 @@ 'Patient Ambulatory Care' __name__ = 'gnuhealth.patient.ambulatory_care' - care_location = fields.Many2One('stock.location', 'Care Location', + care_location = fields.Many2One( + 'stock.location', 'Care Location', domain=[('type', '=', 'storage')], states={ - 'required': If(Or(Bool(Eval('medicaments')), - Bool(Eval('medical_supplies'))), True, False), + 'required': If( + Or(Bool(Eval('medicaments')), + Bool(Eval('medical_supplies'))), True, False), 'readonly': Eval('state') == 'done', }, depends=['state', 'medicaments']) medicaments = fields.One2Many( @@ -106,7 +100,8 @@ 'gnuhealth.patient.ambulatory_care.medical_supply', 'name', 'Medical Supplies', states=_STATES, depends=_DEPENDS) - moves = fields.One2Many('stock.move', 'origin', 'Stock Moves', + moves = fields.One2Many( + 'stock.move', 'origin', 'Stock Moves', readonly=True) @classmethod @@ -134,7 +129,6 @@ @Workflow.transition('done') def done(cls, ambulatory_cares): pool = Pool() - Patient = pool.get('gnuhealth.patient') HealthProfessional = pool.get('gnuhealth.healthprofessional') lines_to_ship = {} @@ -144,7 +138,6 @@ signing_hp = HealthProfessional.get_health_professional() for ambulatory in ambulatory_cares: - patient = Patient(ambulatory.patient.id) for medicament in ambulatory.medicaments: medicaments_to_ship.append(medicament) @@ -180,8 +173,8 @@ move_info['unit_price'] = \ medicament.medicament.name.list_price if medicament.lot: - if medicament.lot.expiration_date \ - and medicament.lot.expiration_date < Date.today(): + if medicament.lot.expiration_date and \ + medicament.lot.expiration_date < Date.today(): raise UserError('Expired medicaments') move_info['lot'] = medicament.lot.id moves.append(move_info) @@ -197,8 +190,9 @@ ambulatory.patient.name.customer_location.id move_info['unit_price'] = medical_supply.product.list_price if medical_supply.lot: - if medical_supply.lot.expiration_date \ - and medical_supply.lot.expiration_date < Date.today(): + if medical_supply.lot.expiration_date \ + and medical_supply.lot.expiration_date \ + < Date.today(): raise UserError('Expired supplies') move_info['lot'] = medical_supply.lot.id moves.append(move_info) @@ -216,15 +210,19 @@ 'Patient Ambulatory Care Medicament' __name__ = 'gnuhealth.patient.ambulatory_care.medicament' - name = fields.Many2One('gnuhealth.patient.ambulatory_care', + name = fields.Many2One( + 'gnuhealth.patient.ambulatory_care', 'Ambulatory ID') - medicament = fields.Many2One('gnuhealth.medicament', 'Medicament', + medicament = fields.Many2One( + 'gnuhealth.medicament', 'Medicament', required=True) product = fields.Many2One('product.product', 'Product') quantity = fields.Integer('Quantity') - short_comment = fields.Char('Comment', + short_comment = fields.Char( + 'Comment', help='Short comment on the specific drug') - lot = fields.Many2One('stock.lot', 'Lot', depends=['product'], + lot = fields.Many2One( + 'stock.lot', 'Lot', depends=['product'], domain=[('product', '=', Eval('product'))]) @staticmethod @@ -244,14 +242,18 @@ 'Patient Ambulatory Care Medical Supply' __name__ = 'gnuhealth.patient.ambulatory_care.medical_supply' - name = fields.Many2One('gnuhealth.patient.ambulatory_care', + name = fields.Many2One( + 'gnuhealth.patient.ambulatory_care', 'Ambulatory ID') - product = fields.Many2One('product.product', 'Medical Supply', + product = fields.Many2One( + 'product.product', 'Medical Supply', domain=[('is_medical_supply', '=', True)], required=True) quantity = fields.Integer('Quantity') - short_comment = fields.Char('Comment', + short_comment = fields.Char( + 'Comment', help='Short comment on the specific drug') - lot = fields.Many2One('stock.lot', 'Lot', depends=['product'], + lot = fields.Many2One( + 'stock.lot', 'Lot', depends=['product'], domain=[ ('product', '=', Eval('product')), ]) @@ -260,14 +262,17 @@ def default_quantity(): return 1 + class PatientRounding(Workflow, ModelSQL, ModelView): 'Patient Ambulatory Care' __name__ = 'gnuhealth.patient.rounding' - hospitalization_location = fields.Many2One('stock.location', + hospitalization_location = fields.Many2One( + 'stock.location', 'Hospitalization Location', domain=[('type', '=', 'storage')], states={ - 'required': If(Or(Bool(Eval('medicaments')), + 'required': If(Or( + Bool(Eval('medicaments')), Bool(Eval('medical_supplies'))), True, False), 'readonly': Eval('state') == 'done', }, depends=_DEPENDS) @@ -275,20 +280,22 @@ 'gnuhealth.patient.rounding.medicament', 'name', 'Medicaments', states=_STATES, depends=_DEPENDS) medical_supplies = fields.One2Many( - 'gnuhealth.patient.rounding.medical_supply', 'name', 'Medical Supplies', + 'gnuhealth.patient.rounding.medical_supply', + 'name', 'Medical Supplies', states=_STATES, depends=_DEPENDS) - moves = fields.One2Many('stock.move', 'origin', 'Stock Moves', + moves = fields.One2Many( + 'stock.move', 'origin', 'Stock Moves', readonly=True) @classmethod def __setup__(cls): super(PatientRounding, cls).__setup__() cls._transitions |= set(( - ('draft', 'done'), + ('draft', 'done'), )) cls._buttons.update({ 'done': { - 'invisible': ~Eval('state').in_(['draft']), + 'invisible': ~Eval('state').in_(['draft']), }}) @classmethod @@ -303,19 +310,13 @@ @ModelView.button @Workflow.transition('done') def done(cls, roundings): - pool = Pool() - Patient = pool.get('gnuhealth.patient') - HealthProfessional = pool.get('gnuhealth.healthprofessional') - - signing_hp = HealthProfessional.get_health_professional() + signing_hp = get_health_professional() lines_to_ship = {} medicaments_to_ship = [] supplies_to_ship = [] for rounding in roundings: - patient = Patient(rounding.name.patient.id) - for medicament in rounding.medicaments: medicaments_to_ship.append(medicament) @@ -324,7 +325,6 @@ lines_to_ship['medicaments'] = medicaments_to_ship lines_to_ship['supplies'] = supplies_to_ship - cls.create_stock_moves(roundings, lines_to_ship) @@ -349,11 +349,11 @@ move_info['from_location'] = \ rounding.hospitalization_location.id move_info['to_location'] = \ - rounding.name.patient.name.customer_location.id + rounding.name.patient.name.customer_location.id move_info['unit_price'] = medicament.medicament.name.list_price if medicament.lot: - if medicament.lot.expiration_date \ - and medicament.lot.expiration_date < Date.today(): + if medicament.lot.expiration_date \ + and medicament.lot.expiration_date < Date.today(): raise UserError('Expired medicaments') move_info['lot'] = medicament.lot.id moves.append(move_info) @@ -366,11 +366,12 @@ move_info['from_location'] = \ rounding.hospitalization_location.id move_info['to_location'] = \ - rounding.name.patient.name.customer_location.id + rounding.name.patient.name.customer_location.id move_info['unit_price'] = medical_supply.product.list_price if medical_supply.lot: - if medical_supply.lot.expiration_date \ - and medical_supply.lot.expiration_date < Date.today(): + if medical_supply.lot.expiration_date \ + and medical_supply.lot.expiration_date < \ + Date.today(): raise UserError('Expired supplies') move_info['lot'] = medical_supply.lot.id moves.append(move_info) @@ -388,13 +389,16 @@ __name__ = 'gnuhealth.patient.rounding.medicament' name = fields.Many2One('gnuhealth.patient.rounding', 'Ambulatory ID') - medicament = fields.Many2One('gnuhealth.medicament', 'Medicament', + medicament = fields.Many2One( + 'gnuhealth.medicament', 'Medicament', required=True) product = fields.Many2One('product.product', 'Product') quantity = fields.Integer('Quantity') - short_comment = fields.Char('Comment', + short_comment = fields.Char( + 'Comment', help='Short comment on the specific drug') - lot = fields.Many2One('stock.lot', 'Lot', depends=['product'], + lot = fields.Many2One( + 'stock.lot', 'Lot', depends=['product'], domain=[('product', '=', Eval('product'))]) @staticmethod @@ -415,12 +419,15 @@ __name__ = 'gnuhealth.patient.rounding.medical_supply' name = fields.Many2One('gnuhealth.patient.rounding', 'Ambulatory ID') - product = fields.Many2One('product.product', 'Medical Supply', + product = fields.Many2One( + 'product.product', 'Medical Supply', domain=[('is_medical_supply', '=', True)], required=True) quantity = fields.Integer('Quantity') - short_comment = fields.Char('Comment', + short_comment = fields.Char( + 'Comment', help='Short comment on the specific drug') - lot = fields.Many2One('stock.lot', 'Lot', depends=['product'], + lot = fields.Many2One( + 'stock.lot', 'Lot', depends=['product'], domain=[ ('product', '=', Eval('product')), ]) @@ -453,23 +460,27 @@ class PatientVaccination(metaclass=PoolMeta): __name__ = 'gnuhealth.vaccination' moves = fields.One2Many('stock.move', 'origin', 'Moves', readonly=True) - location = fields.Many2One('stock.location', + location = fields.Many2One( + 'stock.location', 'Stock Location', domain=[('type', '=', 'storage')]) product = fields.Many2One('product.product', 'Product') - lot = fields.Many2One('stock.lot', 'Lot', depends=['product'], + lot = fields.Many2One( + 'stock.lot', 'Lot', depends=['product'], domain=[('product', '=', Eval('product'))], help="This field includes the lot number and expiration date") - @fields.depends('lot') def on_change_lot(self): # Check expiration date on the vaccine lot if self.lot: if self.lot.expiration_date < datetime.date(self.date): - self.raise_user_error('expired_vaccine') + raise ExpiredVaccine( + gettext('health_stock.msg_expired_vaccine') + ) return {} + @classmethod def copy(cls, vaccinations, default=None): if default is None: @@ -479,17 +490,9 @@ return super(PatientVaccination, cls).copy( vaccinations, default=default) - @classmethod - def __setup__(cls): - super(PatientVaccination, cls).__setup__() - cls._error_messages.update({ - 'expired_vaccine': 'EXPIRED VACCINE. PLEASE INFORM THE LOCAL ' - 'HEALTH AUTHORITIES AND DO NOT USE IT !!!', - }) - @fields.depends('vaccine') def on_change_vaccine(self): if self.vaccine: self.product = self.vaccine.name.id else: - self.product = None + self.product = None
--- a/tryton/health_stock/tryton.cfg +++ b/tryton/health_stock/tryton.cfg @@ -1,5 +1,5 @@ [tryton] -version=3.8.0 +version=3.9.0 depends: health_nursing stock_lot @@ -7,3 +7,4 @@ health_stock_view.xml wizard/create_prescription_stock_move.xml wizard/create_vaccination_stock_move.xml + data/messages/messages.xml
--- a/tryton/health_stock/wizard/wizard_create_prescription_stock_move.py +++ b/tryton/health_stock/wizard/wizard_create_prescription_stock_move.py @@ -26,8 +26,11 @@ from trytond.model import ModelView from trytond.transaction import Transaction from trytond.pool import Pool +from trytond.i18n import gettext +from ..exceptions import (StockMoveExists, NoPharmacy) -__all__ = ['CreatePrescriptionStockMoveInit','CreatePrescriptionStockMove'] +__all__ = ['CreatePrescriptionStockMoveInit', 'CreatePrescriptionStockMove'] + class CreatePrescriptionStockMoveInit(ModelView): 'Create Prescription Stock Move Init' @@ -38,12 +41,14 @@ 'Create Prescription Stock Move' __name__ = 'gnuhealth.prescription.stock.move.create' - start = StateView('gnuhealth.prescription.stock.move.init', - 'health_stock.view_create_prescription_stock_move', [ + start = StateView( + 'gnuhealth.prescription.stock.move.init', + 'health_stock.view_create_prescription_stock_move', [ Button('Cancel', 'end', 'tryton-cancel'), - Button('Create Stock Move', 'create_stock_move', + Button( + 'Create Stock Move', 'create_stock_move', 'tryton-ok', True), - ]) + ]) create_stock_move = StateTransition() def transition_create_stock_move(self): @@ -57,10 +62,14 @@ for prescription in prescriptions: if prescription.moves: - self.raise_user_error('stock_move_exists') + raise StockMoveExists( + gettext('health_stock.msg_stock_move_exists') + ) if not prescription.pharmacy: - self.raise_user_error('no_pharmacy_selected') + raise NoPharmacy( + gettext('health_stock.msg_no_pharmacy') + ) from_location = prescription.pharmacy.warehouse if from_location.type == 'warehouse': @@ -80,14 +89,3 @@ StockMove.save(moves) StockMove.do(moves) return 'end' - - @classmethod - def __setup__(cls): - super(CreatePrescriptionStockMove, cls).__setup__() - cls._error_messages.update({ - 'stock_move_exists': - 'Stock moves already exists!.', - 'no_pharmacy_selected': - 'You need to select a pharmacy.', - }) -
--- a/tryton/health_stock/wizard/wizard_create_vaccination_stock_move.py +++ b/tryton/health_stock/wizard/wizard_create_vaccination_stock_move.py @@ -25,8 +25,11 @@ from trytond.model import ModelView from trytond.transaction import Transaction from trytond.pool import Pool +from trytond.i18n import gettext +from ..exceptions import (StockMoveExists) -__all__ = ['CreateVaccinationStockMoveInit','CreateVaccinationStockMove'] +__all__ = ['CreateVaccinationStockMoveInit', 'CreateVaccinationStockMove'] + class CreateVaccinationStockMoveInit(ModelView): 'Create Vaccination Stock Move Init' @@ -37,12 +40,12 @@ 'Create Vaccination Stock Move' __name__ = 'gnuhealth.vaccination.stock.move.create' - start = StateView('gnuhealth.vaccination.stock.move.init', - 'health_stock.view_create_vaccination_stock_move', [ + start = StateView( + 'gnuhealth.vaccination.stock.move.init', + 'health_stock.view_create_vaccination_stock_move', [ Button('Cancel', 'end', 'tryton-cancel'), - Button('Create Stock Move', 'create_stock_move', - 'tryton-ok', True), - ]) + Button('Create Stock Move', 'create_stock_move', 'tryton-ok', True) + ]) create_stock_move = StateTransition() def transition_create_stock_move(self): @@ -55,10 +58,12 @@ for vaccination in vaccinations: if vaccination.moves: - self.raise_user_error('stock_move_exists') - + raise StockMoveExists( + gettext('health_stock.msg_stock_move_exists') + ) + lines = [] - + line_data = {} line_data['origin'] = str(vaccination) line_data['from_location'] = \ @@ -74,19 +79,10 @@ vaccination.vaccine.name.default_uom.id line_data['state'] = 'draft' lines.append(line_data) - + moves = StockMove.create(lines) StockMove.assign(moves) StockMove.do(moves) - - + return 'end' - - @classmethod - def __setup__(cls): - super(CreateVaccinationStockMove, cls).__setup__() - cls._error_messages.update({ - 'stock_move_exists': - 'Stock moves already exists!.',}) -
