public void signOrder(String orderId, String providerDuz, String locationIen, String eSig) { if (String.IsNullOrEmpty(orderId) || String.IsNullOrEmpty(providerDuz) || String.IsNullOrEmpty(locationIen) || String.IsNullOrEmpty(eSig)) { throw new ArgumentException("Must supply all arguments!"); } VistaOrdersDao orderDao = new VistaOrdersDao(this.cxn); Order order = orderDao.getOrder(orderId); if (order == null) { throw new ArgumentException("Invalid order IEN"); } VistaUserDao userDao = new VistaUserDao(cxn); bool providerHasProvider = userDao.hasPermission(providerDuz, new SecurityKey("", "PROVIDER")); if (!providerHasProvider) { throw new MdoException("Provider DUZ specified does not have PROVIDER key"); } if (!userDao.isValidEsig(eSig)) { throw new MdoException("Invalid signature code"); } // NOTE:: these are the SAME business rules as found in discontinueAndSign above - must change them BOTH PLACES if they need updated!!! String userId = cxn.Uid; bool userHasProvider = String.Equals(userId, providerDuz) ? providerHasProvider : userDao.hasPermission(userId, new SecurityKey("", "PROVIDER")); bool userHasOremas = userDao.hasPermission(userId, new SecurityKey("", "OREMAS")); // need this for some decisions so fetch even if user holds superceding PROVIDER key bool usingWrittenOnChart = false; bool okToDcAndSign = false; //using this to simplify logic and skip checks // allow this to be configurable bool okToCancelOrderFromOtherProvider = false; Boolean.TryParse(ConfigurationManager.AppSettings["AllowOrderDcFromOtherProvider"], out okToCancelOrderFromOtherProvider); String originalOrderProvider = order.Provider.Uid; if (String.Equals(originalOrderProvider, userId)) { okToDcAndSign = true; } if (!okToDcAndSign) { if (!String.Equals(originalOrderProvider, userId) && userHasProvider) { if (okToCancelOrderFromOtherProvider) { okToDcAndSign = true; } else { throw new ArgumentException("Providers may not sign another provider's order."); } } } if (!okToDcAndSign) { if (!userHasProvider) { if (!userHasOremas) { throw new UnauthorizedAccessException("User does not have appropriate keys for sign"); } } } if (!okToDcAndSign) { if (!userHasProvider && userHasOremas) { okToDcAndSign = usingWrittenOnChart = true; } } orderDao.lockOrder(orderId); orderDao.signOrder(orderId, providerDuz, locationIen, eSig, true, usingWrittenOnChart); orderDao.unlockOrder(orderId); }
public bool isValidEsig(string esig) { return(vistaDao.isValidEsig(esig)); }
public Order discontinueAndSignOrder(String patientId, string orderIen, string providerDuz, String locationIen, string reasonIen, String eSig) { if (String.IsNullOrEmpty(orderIen)) { throw new ArgumentException("No order ID"); } if (String.IsNullOrEmpty(providerDuz)) { throw new ArgumentException("No user ID"); } if (String.IsNullOrEmpty(locationIen)) { throw new ArgumentException("No location ID"); } if (String.IsNullOrEmpty(reasonIen)) { throw new ArgumentException("No reason ID"); } if (String.IsNullOrEmpty(eSig)) { throw new ArgumentException("No electronic signature code"); } String userId = cxn.Uid; VistaUserDao userDao = new VistaUserDao(cxn); bool providerHasProvider = userDao.hasPermission(providerDuz, new SecurityKey("", "PROVIDER")); if (!providerHasProvider) { throw new ArgumentException("The account with the DUZ specified does not hold the PROVIDER key"); } if (!userDao.isValidEsig(eSig)) { throw new MdoException("Invalid signature code"); } VistaOrdersDao orderDao = new VistaOrdersDao(cxn); Order order = orderDao.getOrder(orderIen); if (order == null) { throw new MdoException("No such order"); } if (String.Equals(order.Status, "DISCONTINUED", StringComparison.CurrentCultureIgnoreCase)) { throw new ArgumentException("Order is already discontinued"); } bool userHasProvider = String.Equals(userId, providerDuz) ? providerHasProvider : userDao.hasPermission(userId, new SecurityKey("", "PROVIDER")); bool userHasOremas = userDao.hasPermission(userId, new SecurityKey("", "OREMAS")); // need this for some decisions so fetch even if user holds superceding PROVIDER key bool usingWrittenOnChart = false; bool okToDcAndSign = false; //using this to simplify logic and skip checks // allow this to be configurable bool okToCancelOrderFromOtherProvider = false; Boolean.TryParse(ConfigurationManager.AppSettings["AllowOrderDcFromOtherProvider"], out okToCancelOrderFromOtherProvider); String originalOrderProvider = order.Provider.Uid; //.Provider.Id; if (String.Equals(originalOrderProvider, userId)) { okToDcAndSign = true; } if (!okToDcAndSign) { if (!String.Equals(originalOrderProvider, userId) && userHasProvider) { if (okToCancelOrderFromOtherProvider) { okToDcAndSign = true; } else { throw new ArgumentException("Providers may not sign discontinue order request for another provider's order. Use discontinue order without signature"); } } } if (!okToDcAndSign) { if (!userHasProvider && !userHasOremas) { throw new UnauthorizedAccessException("User does not have appropriate keys for cancel and sign"); } } if (!okToDcAndSign) { if (!userHasProvider && userHasOremas) { okToDcAndSign = usingWrittenOnChart = true; } } string msg = orderDao.validateOrderActionNature(order.Id, "DC", providerDuz, ""); // TBD - orderIen -> order.Id?? if (msg != "OK") { throw new MdoException(msg); } msg = orderDao.getComplexOrderMsg(order.Id); // TBD - orderIen -> order.Id?? if (msg != "") { throw new MdoException(msg); } if (!orderDao.lockOrdersForPatient(patientId)) { throw new MdoException("Unable to lock orders for patient"); } msg = orderDao.lockOrder(order.Id); if (msg != "OK") { orderDao.unlockOrdersForPatient(); throw new MdoException(msg); } Order canceledOrder = cancelOrder(order.Id, providerDuz, locationIen, reasonIen); orderDao.signOrder(patientId, canceledOrder.Id, providerDuz, locationIen, eSig, true, usingWrittenOnChart); orderDao.unlockOrder(canceledOrder.Id); orderDao.unlockOrdersForPatient(patientId); return(canceledOrder); }