using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.ApplicationBlocks.Data;

using HISClinic.DataModel;
using HISClinic.DataServices.Database;

namespace HISClinic.DataServices
{
	/// <summary>
	/// PrescriptionMapper 的摘要说明。
	/// </summary>
	public class PrescriptionMapper
	{			
        private const string PARAM_RxID="@RxID";
		private const string PARAM_PatientID="@PatientID";
		private const string PARAM_PatientName="@PatientName";
		private const string PARAM_FirstVisit="@FirstVisit";
		private const string PARAM_DepartmentID="@DepartmentID";
		private const string PARAM_DepartmentName="@DepartmentName";
		private const string PARAM_PrescriberID="@PrescriberID";
		private const string PARAM_PrescriberName="@PrescriberName";
		private const string PARAM_Diagnosis1ID="@Diagnosis1ID";
		private const string PARAM_Diagnosis1Name="@Diagnosis1Name";
		private const string PARAM_Diagnosis2ID="@Diagnosis2ID";
		private const string PARAM_Diagnosis2Name="@Diagnosis2Name";
		private const string PARAM_Status="@Status";

		private const string PARAM_LineNumber="@LineNumber";
		private const string PARAM_OriginalLineNumber="@OriginalLineNumber";
		private const string PARAM_NewLineNumber="@NewLineNumber";
		private const string PARAM_MedicineID="@MedicineID";
		private const string PARAM_MedicineName="@MedicineName";
		private const string PARAM_MedicineSpec="@MedicineSpec";
		private const string PARAM_DailyTimes="@DailyTimes";
		private const string PARAM_DosageEverytime="@DosageEverytime";
		private const string PARAM_UnitName="@UnitName";
		private const string PARAM_CommomUsage="@CommomUsage";
		private const string PARAM_Quantity="@Quantity";
		private const string PARAM_UnitPrice="@UnitPrice";

		public PrescriptionMapper()
		{
			//
			// TODO: 在此处添加构造函数逻辑
			//
		}

		public bool SavePrescription(PrescriptionsEx prescriptionsEx,long RegistrationID)
		{
			PrescriptionsEx DeletedPrescriptions=(PrescriptionsEx)prescriptionsEx.GetChanges(DataRowState.Deleted);
			PrescriptionsEx ModifiedPrescriptions=(PrescriptionsEx)prescriptionsEx.GetChanges(DataRowState.Modified);
			PrescriptionsEx AddedPrescriptions=(PrescriptionsEx)prescriptionsEx.GetChanges(DataRowState.Added);

			using(SqlConnection conn=HISDBConfig.GetConnection())
			{
				if(conn.State == ConnectionState.Closed)
				{
					conn.Open();
				}
				SqlTransaction tran=conn.BeginTransaction();

				try
				{


					if(DeletedPrescriptions!=null)
					{
					
					}

					if(ModifiedPrescriptions !=null )
					{

					}

					if(AddedPrescriptions !=null )
					{
						InsertPrescriptions(AddedPrescriptions,tran);
						if(RegistrationID>0)
						{
							if(!(new RegistrationMapper()).UseRegistration(RegistrationID,tran))
							{
								throw(new ApplicationException("设置挂号信息失败。"));
							}
						}
					}

					tran.Commit();	
					return true;
				}
				catch(Exception ex)
				{
					tran.Rollback();
					throw(ex);
				}
			}
		}


		/// <summary>
		/// 保存增加的处方记录
		/// </summary>
		/// <param name="prescriptionsEx"></param>
		/// <param name="conn"></param>
		/// <param name="tran"></param>
		private void InsertPrescriptions(PrescriptionsEx prescriptionsEx,SqlTransaction tran)
		{
			long RxID=0;
			PrescriptionsEx.t_PrescriptionMasterRow prescriptionMasterRow=null;
			for(int i=0;i<prescriptionsEx.t_PrescriptionMaster.Count;i++)
			{
				prescriptionMasterRow=(PrescriptionsEx.t_PrescriptionMasterRow)prescriptionsEx.t_PrescriptionMaster.Rows[i];
				RxID=InsertPrescriptionMaster(prescriptionMasterRow,tran);	
				
			    DataRow[] dataRow=prescriptionsEx.t_PrescriptionDetail.Select(PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_RxID +"="+prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_RxID].ToString());
				if(dataRow !=null)
				{
					for(int k=0;k<dataRow.Length;k++)
					{
						dataRow[k][PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_RxID]=RxID;
					}
				}
			}	            
			UpdatePrescriptionDetail(prescriptionsEx.t_PrescriptionDetail,tran);
		}

		#region 保存增加的一条处方主表的记录
		/// <summary>
		/// 保存增加的一条处方主表的记录
		/// </summary>
		/// <param name="prescriptionMasterRow"></param>
		/// <param name="tran"></param>
		/// <returns></returns>
		private long InsertPrescriptionMaster(PrescriptionsEx.t_PrescriptionMasterRow prescriptionMasterRow,SqlTransaction tran)
		{

			SqlParameter paramRxID=new SqlParameter();
			paramRxID.ParameterName=PARAM_RxID;			
			paramRxID.SourceColumn=PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_RxID;
			paramRxID.Direction=ParameterDirection.Output;		
			paramRxID.SqlDbType=SqlDbType.BigInt;
			paramRxID.DbType=DbType.Int64;
			paramRxID.Size=0;
  
			SqlParameter[] parameters={
										  paramRxID,										  
										  new SqlParameter(PARAM_PatientID,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PatientID]),
										  new SqlParameter(PARAM_PatientName,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PatientName]),
										  new SqlParameter(PARAM_FirstVisit,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_FirstVisit]),
										  new SqlParameter(PARAM_DepartmentID,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_DepartmentID]),
										  new SqlParameter(PARAM_DepartmentName,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_DepartmentName]),
										  new SqlParameter(PARAM_PrescriberID,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PrescriberID]),
										  new SqlParameter(PARAM_PrescriberName,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PrescriberName]),
										  new SqlParameter(PARAM_Diagnosis1ID,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis1ID]),
										  new SqlParameter(PARAM_Diagnosis1Name,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis1Name]),										  
										  new SqlParameter(PARAM_Diagnosis2ID,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis2ID]),
										  new SqlParameter(PARAM_Diagnosis2Name,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis2Name]),
										  new SqlParameter(PARAM_Status,prescriptionMasterRow[PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Status])
									  };

			SqlCommand comm=new SqlCommand();
			comm.CommandText="ut_PrescriptionMasterInsert";
			comm.Connection=tran.Connection;
			comm.Transaction=tran;
			comm.CommandType=CommandType.StoredProcedure;

			foreach(SqlParameter p in parameters)
			{
				comm.Parameters.Add(p);
			}

			comm.ExecuteNonQuery();
			
			if(paramRxID.Value !=null )
			{
				return Convert.ToInt64(paramRxID.Value);
			}
			return 0;
		}

		#endregion

		private void UpdatePrescriptionDetail(PrescriptionsEx.t_PrescriptionDetailDataTable prescriptionDetail,SqlTransaction tran)
		{
			SqlDataAdapter da=new SqlDataAdapter();	
		
			da.InsertCommand=GetPrescriptionDetailInsertCommand(tran);
			da.UpdateCommand=GetPrescriptionDetailUpdateCommand(tran);
			da.DeleteCommand=GetPrescriptionDetailDeleteCommand(tran);            
			da.Update(prescriptionDetail);		
		}		

		#region 产生在PrescriptionMaster表更新记录的命令
		/// <summary>
		/// 产生在PrescriptionMaster表更新记录的命令
		/// </summary>
		/// <param name="sqlConnection"></param>
		/// <param name="sqlTransaction"></param>
		/// <returns></returns>
		private SqlCommand GetPrescriptionMasterUpdateCommand(SqlTransaction tran)
		{
			SqlCommand comm=new SqlCommand();
			comm.Connection=tran.Connection;
			comm.Transaction=tran;

			comm.CommandType=CommandType.StoredProcedure;
			comm.CommandText="ut_PrescriptionMasterUpdate";

			comm.Parameters.Add(new SqlParameter(PARAM_RxID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_RxID));
			comm.Parameters.Add(new SqlParameter(PARAM_PatientID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PatientID));
			comm.Parameters.Add(new SqlParameter(PARAM_PatientName,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PatientName));
			comm.Parameters.Add(new SqlParameter(PARAM_FirstVisit,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_FirstVisit));
			comm.Parameters.Add(new SqlParameter(PARAM_DepartmentID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_DepartmentID));
			comm.Parameters.Add(new SqlParameter(PARAM_DepartmentName,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_DepartmentName));
			comm.Parameters.Add(new SqlParameter(PARAM_PrescriberID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PrescriberID));
			comm.Parameters.Add(new SqlParameter(PARAM_PrescriberName,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PrescriberName));
			comm.Parameters.Add(new SqlParameter(PARAM_Diagnosis1ID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis1ID));
			comm.Parameters.Add(new SqlParameter(PARAM_PatientID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis1Name));
			comm.Parameters.Add(new SqlParameter(PARAM_Diagnosis1Name,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_PatientID));
			comm.Parameters.Add(new SqlParameter(PARAM_Diagnosis2ID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis2ID));
			comm.Parameters.Add(new SqlParameter(PARAM_Diagnosis2Name,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_Diagnosis2Name));			

			return comm;
		}

		#endregion

		#region 产生在PrescriptionMaster表删除记录的命令
		/// <summary>
		/// 产生在PrescriptionMaster表删除记录的命令
		/// </summary>
		/// <param name="sqlConnection"></param>
		/// <param name="sqlTransaction"></param>
		/// <returns></returns>
		private SqlCommand GetPrescriptionMasterDeleteCommand(SqlTransaction tran)
		{
			SqlCommand comm=new SqlCommand();
			comm.Connection=tran.Connection;
			comm.Transaction=tran;

			comm.CommandType=CommandType.StoredProcedure;
			comm.CommandText="ut_PrescriptionMasterDelete";

			comm.Parameters.Add(new SqlParameter(PARAM_RxID,PrescriptionsEx.t_PrescriptionMasterDataTableEx.FIELD_RxID));

			return comm;
		}

		#endregion

		#region 产生在PrescriptionDetail表增加记录的命令
		/// <summary>
		/// 产生在PrescriptionDetail表增加记录的命令
		/// </summary>
		/// <param name="sqlConnection"></param>
		/// <param name="sqlTransaction"></param>
		/// <returns></returns>
		private SqlCommand GetPrescriptionDetailInsertCommand(SqlTransaction tran)
		{
			SqlCommand comm=new SqlCommand();
			comm.Connection=tran.Connection;
			comm.Transaction=tran;
			comm.CommandType=CommandType.StoredProcedure;
			comm.CommandText="ut_PrescriptionDetailInsert";

			comm.Parameters.Add(new SqlParameter(PARAM_RxID,SqlDbType.BigInt,0,PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_RxID));
			comm.Parameters.Add(new SqlParameter(PARAM_LineNumber,SqlDbType.SmallInt,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_LineNumber));
			comm.Parameters.Add(new SqlParameter(PARAM_MedicineID,SqlDbType.Int,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_MedicineID));
			comm.Parameters.Add(new SqlParameter(PARAM_MedicineName,SqlDbType.VarChar,50, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_MedicineName));
			comm.Parameters.Add(new SqlParameter(PARAM_MedicineSpec,SqlDbType.VarChar,50, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_MedicineSpec));
			comm.Parameters.Add(new SqlParameter(PARAM_DailyTimes,SqlDbType.TinyInt,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_DailyTimes));
			comm.Parameters.Add(new SqlParameter(PARAM_DosageEverytime,SqlDbType.Int,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_DosageEverytime));
			comm.Parameters.Add(new SqlParameter(PARAM_CommomUsage,SqlDbType.VarChar,50, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_CommomUsage));
			comm.Parameters.Add(new SqlParameter(PARAM_UnitName,SqlDbType.VarChar,10, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_UnitName));
			comm.Parameters.Add(new SqlParameter(PARAM_UnitPrice,SqlDbType.Money,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_UnitPrice));
			comm.Parameters.Add(new SqlParameter(PARAM_Quantity,SqlDbType.Int,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_Quantity));
			return comm;
		}
		#endregion

		#region 产生在PrescriptionDetail表更新记录的命令
		/// <summary>
		///  产生在PrescriptionDetail表更新记录的命令
		/// </summary>
		/// <param name="sqlConnection"></param>
		/// <param name="sqlTransaction"></param>
		/// <returns></returns>
		private SqlCommand GetPrescriptionDetailUpdateCommand(SqlTransaction tran)
		{
			SqlCommand comm=new SqlCommand();
			comm.Connection=tran.Connection;
			comm.Transaction=tran;

			comm.CommandType=CommandType.StoredProcedure;
			comm.CommandText="ut_PrescriptionDetailUpdate";

			SqlParameter paramNewLineNumber=new SqlParameter();
			paramNewLineNumber.ParameterName=PARAM_NewLineNumber;
			paramNewLineNumber.SourceColumn=PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_LineNumber;
			paramNewLineNumber.SourceVersion=DataRowVersion.Current;
			paramNewLineNumber.Direction=ParameterDirection.Input;
			paramNewLineNumber.SqlDbType=SqlDbType.SmallInt;
			paramNewLineNumber.DbType=DbType.Int16;

			SqlParameter paramOriginalLineNumber=new SqlParameter();
			paramOriginalLineNumber.ParameterName=PARAM_OriginalLineNumber;
			paramOriginalLineNumber.SourceColumn=PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_LineNumber;
			paramOriginalLineNumber.SourceVersion=DataRowVersion.Original;
			paramOriginalLineNumber.Direction=ParameterDirection.Input;
			paramOriginalLineNumber.SqlDbType=SqlDbType.SmallInt;
			paramOriginalLineNumber.DbType=DbType.Int16;

			comm.Parameters.Add(new SqlParameter(PARAM_RxID,SqlDbType.BigInt,0,PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_RxID));
			comm.Parameters.Add(paramNewLineNumber);
			comm.Parameters.Add(paramOriginalLineNumber);	
			comm.Parameters.Add(new SqlParameter(PARAM_MedicineID,SqlDbType.Int,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_MedicineID));
			comm.Parameters.Add(new SqlParameter(PARAM_MedicineName,SqlDbType.VarChar,50, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_MedicineName));
			comm.Parameters.Add(new SqlParameter(PARAM_MedicineSpec,SqlDbType.VarChar,50, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_MedicineSpec));
			comm.Parameters.Add(new SqlParameter(PARAM_DailyTimes,SqlDbType.TinyInt,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_DailyTimes));
			comm.Parameters.Add(new SqlParameter(PARAM_DosageEverytime,SqlDbType.Int,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_DosageEverytime));
			comm.Parameters.Add(new SqlParameter(PARAM_CommomUsage,SqlDbType.VarChar,50, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_CommomUsage));
			comm.Parameters.Add(new SqlParameter(PARAM_UnitName,SqlDbType.VarChar,10, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_UnitName));
			comm.Parameters.Add(new SqlParameter(PARAM_UnitPrice,SqlDbType.Money,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_UnitPrice));
			comm.Parameters.Add(new SqlParameter(PARAM_Quantity,SqlDbType.Int,0, PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_Quantity));


			return comm;
		}
		#endregion

		#region 产生在PrescriptionDetail表删除记录的命令
		/// <summary>
		///  产生在PrescriptionDetail表删除记录的命令
		/// </summary>
		/// <param name="sqlConnection"></param>
		/// <param name="sqlTransaction"></param>
		/// <returns></returns>
		private SqlCommand GetPrescriptionDetailDeleteCommand(SqlTransaction tran)
		{
			SqlCommand comm=new SqlCommand();
			comm.Connection=tran.Connection;
			comm.Transaction=tran;

			comm.CommandType=CommandType.StoredProcedure;
			comm.CommandText="ut_PrescriptionDetailDelete";

			SqlParameter paramOriginalLineNumber=new SqlParameter();
			paramOriginalLineNumber.ParameterName=PARAM_NewLineNumber;
			paramOriginalLineNumber.SourceColumn=PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_LineNumber;
			paramOriginalLineNumber.SourceVersion=DataRowVersion.Original;
			paramOriginalLineNumber.Direction=ParameterDirection.Input;
			paramOriginalLineNumber.SqlDbType=SqlDbType.SmallInt;
			paramOriginalLineNumber.DbType=DbType.Int16;

			comm.Parameters.Add(new SqlParameter(PARAM_RxID,SqlDbType.BigInt,0,PrescriptionsEx.t_PrescriptionDetailDataTableEx.FIELD_RxID));
			comm.Parameters.Add(paramOriginalLineNumber);

			return comm;
		}
		#endregion

		/// <summary>
		/// 根据PatientID查找未付款的处方
		/// </summary>
		/// <param name="PatientID"></param>
		public PrescriptionsEx FindUnpaidPrescriptions(int PatientID)
		{
			SqlParameter[] parameters={new SqlParameter(PARAM_PatientID,PatientID)};

			PrescriptionsEx prescriptionsEx=new PrescriptionsEx();
			using(SqlConnection conn=HISDBConfig.GetNewConection())
			{
				SqlHelper.FillDataset(conn,"ut_FindPrescriptionByPatientID",prescriptionsEx,new string[] {PrescriptionsEx.t_PrescriptionMasterDataTableEx.TableName_PrescriptionMaster,PrescriptionsEx.t_PrescriptionDetailDataTableEx.TableName_PrescriptionDetail},parameters);
			}
			return prescriptionsEx;
		}

		/// <summary>
		/// 将相应的处方标志为已经收费
		/// </summary>
		/// <param name="prescriptionMasterRows"></param>
		/// <param name="BillOfRxID"></param>
		/// <param name="tran"></param>
		/// <returns></returns>
		internal bool BillPrescriptions(PrescriptionsEx.t_PrescriptionMasterRow[] prescriptionMasterRows,long BillOfRxID,SqlTransaction tran)
		{
			string SQL=" Update {0} SET BillOfRxID={1},Status={2} Where RxID IN({3}) AND Status={4}";

			string RxIDs="";
			foreach(PrescriptionsEx.t_PrescriptionMasterRow row in prescriptionMasterRows)
			{
				RxIDs+=","+row.RxID.ToString();
			}
			RxIDs=RxIDs.Substring(1,RxIDs.Length-1);

			SQL=String.Format(SQL,PrescriptionsEx.t_PrescriptionMasterDataTableEx.TableName_PrescriptionMaster,
					BillOfRxID.ToString(),((int)PrescriptionsEx.PrescriptionStatus.Billed).ToString(),RxIDs,
					((int)PrescriptionsEx.PrescriptionStatus.Maked).ToString());

			int Result=0;
			SqlCommand comm=new SqlCommand();
			comm.CommandText=SQL;
			comm.Connection=tran.Connection;
			comm.Transaction=tran;
			comm.CommandType=CommandType.Text;	            

			Result=comm.ExecuteNonQuery();

			return Result==prescriptionMasterRows.Length;
		}
	}
}
