Example #1
0
 ///<summary>(HQ Only) When we create, modify, or delete a non-sales tax adjustment that is attached to a procedure, we may also need to update
 ///sales tax for that procedure. Takes a non-sales tax adjustment and checks if the procedure already has a sales tax adjustment. If one already
 ///exists, calculate the new tax after the change to the passed in adjustment, and update the sales tax accordingly. If not, calculate and
 ///create a sales tax adjustment only if the procedure is taxable.</summary>
 public static void CreateOrUpdateSalesTaxIfNeeded(Adjustment modifiedAdj)
 {
     if (AvaTax.IsEnabled() && modifiedAdj.ProcNum > 0 && modifiedAdj.AdjType != AvaTax.SalesTaxAdjType && modifiedAdj.AdjType != AvaTax.SalesTaxReturnAdjType)
     {
         Adjustment taxAdjForProc = GetSalesTaxForProc(modifiedAdj.ProcNum);
         if (taxAdjForProc != null)
         {
             Procedure proc = Procedures.GetOneProc(modifiedAdj.ProcNum, false);
             CreateOrUpdateSalesTaxIfNeeded(proc, taxAdjForProc);
         }
     }
 }
Example #2
0
        ///<summary>Sums all adjustments for a proc then returns that sum. Pass false to canIncludeTax in order to exclude sales tax from the end amount.
        ///</summary>
        public static double GetTotForProc(long procNum, bool canIncludeTax = true)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetDouble(MethodBase.GetCurrentMethod(), procNum, canIncludeTax));
            }
            string command = "SELECT SUM(AdjAmt) FROM adjustment"
                             + " WHERE ProcNum=" + POut.Long(procNum);

            if (AvaTax.IsEnabled() && !canIncludeTax)
            {
                command += " AND AdjType NOT IN (" + string.Join(",", POut.Long(AvaTax.SalesTaxAdjType), POut.Long(AvaTax.SalesTaxReturnAdjType)) + ")";
            }
            return(PIn.Double(Db.GetScalar(command)));
        }
Example #3
0
 public static bool DoCreateReturnAdjustment(Procedure procedure, Adjustment lockedAdj, Adjustment returnAdj)
 {
     try {
         double  procTotal = procedure.ProcFeeTotal + Adjustments.GetTotForProc(procedure.ProcNum, canIncludeTax: false);
         decimal taxEstNew = AvaTax.GetEstimate(procedure.CodeNum, procedure.PatNum, procTotal, hasExceptions: true);
         returnAdj.AdjAmt = (Adjustments.GetTotTaxForProc(procedure) - (double)taxEstNew) * (-1);
         if (returnAdj.AdjAmt == 0)
         {
             return(false);                    //no error and we would be refunding $0 to the customer, so no need to create a return adjustment
         }
     }
     catch (Exception e) {
         returnAdj.AdjNote = AvaTax.AddNote(returnAdj.AdjNote, "An error occurred processing the transaction: " + e.Message + " See local logs for more details.");
     }
     return(true);
 }
Example #4
0
        ///<summary></summary>
        public static double GetTotTaxForProc(Procedure proc)
        {
            if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
            {
                return(Meth.GetDouble(MethodBase.GetCurrentMethod(), proc));
            }
            if (!AvaTax.DoSendProcToAvalara(proc))
            {
                return(0);
            }
            string command = "SELECT SUM(AdjAmt) FROM adjustment"
                             + " WHERE ProcNum=" + POut.Long(proc.ProcNum)
                             + " AND AdjType IN (" + string.Join(",", POut.Long(AvaTax.SalesTaxAdjType), POut.Long(AvaTax.SalesTaxReturnAdjType)) + ")";

            return(PIn.Double(Db.GetScalar(command)));
        }
Example #5
0
        public static void CreateSalesTaxRefundIfNeeded(Procedure procedure, Adjustment adjustmentExistingLocked)
        {
            Adjustment adjustmentSalesTaxReturn = new Adjustment();

            adjustmentSalesTaxReturn.DateEntry = DateTime.Today;
            adjustmentSalesTaxReturn.AdjDate   = DateTime.Today;
            adjustmentSalesTaxReturn.ProcDate  = procedure.ProcDate;
            adjustmentSalesTaxReturn.ProvNum   = procedure.ProvNum;
            adjustmentSalesTaxReturn.PatNum    = procedure.PatNum;
            adjustmentSalesTaxReturn.AdjType   = AvaTax.SalesTaxReturnAdjType;
            adjustmentSalesTaxReturn.ClinicNum = procedure.ClinicNum;
            adjustmentSalesTaxReturn.ProcNum   = procedure.ProcNum;
            if (AvaTax.DoCreateReturnAdjustment(procedure, adjustmentExistingLocked, adjustmentSalesTaxReturn))
            {
                Insert(adjustmentSalesTaxReturn);
                TsiTransLogs.CheckAndInsertLogsIfAdjTypeExcluded(adjustmentSalesTaxReturn);
            }
        }
Example #6
0
 ///<summary>(HQ Only) Automatically creates or updates a sales tax adjustment for the passted in procedure. If an adjustment is passed in, we go
 ///ahead and update that adjustment, otherwise we check if there is already a sales tax adjustment for the given procedure and if not, we create
 ///a new one. Pass in false to doCalcTax if we have already called the AvaTax API to get the tax estimate recently to avoid redundant calls
 ///(currently only pre-payments uses this flag).
 ///isRepeatCharge indicates if the adjustment is being inserted by the repeat charge tool, currently only used to supress error messages
 ///in the Avatax API.</summary>
 public static void CreateOrUpdateSalesTaxIfNeeded(Procedure procedure, Adjustment salesTaxAdj = null, bool doCalcTax = true, bool isRepeatCharge = false)
 {
     if (!AvaTax.DoSendProcToAvalara(procedure, isRepeatCharge))             //tests isHQ
     {
         return;
     }
     //Check for middle tier as crud is called below
     if (RemotingClient.RemotingRole == RemotingRole.ClientWeb)
     {
         Meth.GetVoid(MethodBase.GetCurrentMethod(), procedure, salesTaxAdj, doCalcTax, isRepeatCharge);
         return;
     }
     if (salesTaxAdj == null)
     {
         salesTaxAdj = Adjustments.GetSalesTaxForProc(procedure.ProcNum);
     }
     //If we didn't find any existing adjustments to modify, create an adjustment instead
     if (salesTaxAdj == null)
     {
         salesTaxAdj           = new Adjustment();
         salesTaxAdj.DateEntry = DateTime.Today;
         salesTaxAdj.AdjDate   = procedure.ProcDate;
         salesTaxAdj.ProcDate  = procedure.ProcDate;
         salesTaxAdj.ProvNum   = procedure.ProvNum;
         salesTaxAdj.PatNum    = procedure.PatNum;
         salesTaxAdj.AdjType   = AvaTax.SalesTaxAdjType;
         salesTaxAdj.ClinicNum = procedure.ClinicNum;
         salesTaxAdj.ProcNum   = procedure.ProcNum;
     }
     //if the sales tax adjustment is locked, create a sales tax refund adjustment instead
     if (procedure.ProcDate <= AvaTax.TaxLockDate)
     {
         CreateSalesTaxRefundIfNeeded(procedure, salesTaxAdj);
         return;
     }
     if (!doCalcTax)              //Should only ever happen for pre-payments, where we've already called the api to get the tax amount
     {
         salesTaxAdj.AdjAmt = procedure.TaxAmt;
         Insert(salesTaxAdj);
     }
     else if (AvaTax.DidUpdateAdjustment(procedure, salesTaxAdj))
     {
         string note = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ": Tax amount changed from $" + procedure.TaxAmt.ToString("f2") + " to $" + salesTaxAdj.AdjAmt.ToString("f2");
         if (!(procedure.TaxAmt - salesTaxAdj.AdjAmt).IsZero())
         {
             procedure.TaxAmt = salesTaxAdj.AdjAmt;
             Crud.ProcedureCrud.Update(procedure);
         }
         if (salesTaxAdj.AdjNum == 0)
         {
             //The only way to get salesTaxAdj.AdjAmt=0 when AvaTax.DidUpdateAdjustment() returns true is if there was an error.
             if (isRepeatCharge && salesTaxAdj.AdjAmt == 0)                   //this is an error; we would normally not save a new adjustment with amt $0
             {
                 throw new ODException("Encountered an error communicating with AvaTax.  Skip for repeating charges only.  " + salesTaxAdj.AdjNote);
             }
             Insert(salesTaxAdj); //This could be an error or a new adjustment/repeating charge, either way we want to insert
         }
         else                     //updating an existing adjustment. We don't need to check isRepeatCharge because of
         {
             if (!string.IsNullOrWhiteSpace(salesTaxAdj.AdjNote))
             {
                 salesTaxAdj.AdjNote += Environment.NewLine;
             }
             salesTaxAdj.AdjNote += note;                   //If we are updating this adjustment, leave a note indicating what changed
             Update(salesTaxAdj);
         }
     }
     TsiTransLogs.CheckAndInsertLogsIfAdjTypeExcluded(salesTaxAdj);
 }