AR Deposit - Create New or Update with Refund & Forfeit v2

From AutoCount Resource Center

Rules in AR Deposit Refund & Forfeit

  1. One AR Deposit allows only one Refund, and one Payment Voucher is created.
  2. One AR Deposit allows only one Forfeit
  3. Refund created in AR Deposit will auto create GL Cash Book Payment Voucher under GL | Cash Book Entry.

References of AutoCount Accounting version 2.0

AutoCount.Accounting.dll
AutoCount.Accounting.UI.dll
AutoCount.dll
AutoCount.MainEntry.dll
AutoCount.UI.dll
AutoCount.ARAP.dll


Sample with data model

Add New or Edit Existing AR Deposit with Deposit Refund and Forfeit

public string AddUpdateDepositWithRefundForfeit(ARDepositSource source, AutoCount.Authentication.UserSession userSession)
{
    AutoCount.ARAP.ARDeposit.ARDepositCommand cmd =
        AutoCount.ARAP.ARDeposit.ARDepositCommand.Create(userSession, userSession.DBSetting);
    AutoCount.ARAP.ARDeposit.ARDeposit doc = null;

    //Only possible to edit a document when document number is provided,
    //and exist in the record
    if (source.DocumentNo != null)
    {
        doc = cmd.Edit(source.DocumentNo);
    }

    if (doc == null)
    {
        //Add New ARDeposit
        doc = cmd.AddNew();
    }
    else
    {
        //Edit existing ARDeposit
        doc.ClearDetails();
        doc.ClearRefundDetails();
    }

    return UpdateARDeposit(doc, source, userSession);
}

Update AR Deposit with Refund and Forfeit

private string UpdateARDeposit(AutoCount.ARAP.ARDeposit.ARDeposit doc, ARDepositSource source, AutoCount.Authentication.UserSession userSession)
{
    string retDocNo = null;
    if (IsValidDepositMethod(source.DepositMethod, userSession))
    {
        if (doc.DepositPaymentMethod != source.DepositMethod)
            doc.DepositPaymentMethod = source.DepositMethod;
    }
    else
    {
        //AutoCount.AppMessage.ShowErrorMessage(string.Format("Invalid Deposit Payment Method of \"{0}\"", source.DepositMethod));
        //log error on Deposit Payment Method error
        return retDocNo;
    }

    if (doc.DocNo != source.DocumentNo)
        doc.DocNo = source.DocumentNo ?? doc.DocNo;
    if (doc.DocDate != source.DocumentDate)
        doc.DocDate = source.DocumentDate;

    doc.Description = source.Description ?? doc.Description;
    doc.CurrencyCode = source.CurrencyCode ?? doc.CurrencyCode;
    doc.DebtorCode = source.CustomerAccount;
    doc.DebtorName = source.CustomerName;
    doc.Attention = source.Attention;
    doc.Phone1 = source.Phone;
    doc.Fax1 = source.Fax;
    doc.ProjNo = source.Project;
    doc.DeptNo = source.Department;
    //Deposit Payment Detail
    source.PaymentDetail.ForEach(s => AddARDepositDetail(s, doc.AddDetail));

    //Remove all refund(s), if any
    for (int i = 0; i < doc.RefundCount; i++)
    {
        doc.DeleteRefundDetail(i);
    }

    //Single Refund
    //Though AC2.0 supports more than one Refund in single Deposit
    if (source.Refund != null)
    {
        AutoCount.ARAP.ARDeposit.ARDepositRefund refund = doc.AddRefund();

        if (!string.IsNullOrEmpty(source.Refund.DocumentNo))
            refund.DocNo = source.Refund.DocumentNo;

        refund.DocDate = source.Refund.RefundDate;
        refund.Description = source.Refund.Description;
        source.Refund.RefundDetail.ForEach(s => AddARRefundDetail(s, doc.AddRefundDetail));
    }
    else
    {
    }

    //Forfeit
    //Remove all forfeit(s), if any
    for (int i=0; i < doc.GetValidForfeitRows().Length; i++)
    {
        doc.DeleteForfeit(i);
    }

    if (source.Forfeit != null)
    {
        AutoCount.ARAP.ARDeposit.ARDepositForfeit forfeit = doc.AddForfeit();
        forfeit.DocDate = source.Forfeit.ForfeitDate;
        forfeit.ForFeitedAccNo = source.Forfeit.ForfeitAccNo;
        forfeit.ForfeitedAmount = source.Forfeit.ForfeitAmount;
        forfeit.Description = source.Forfeit.Description;
    }
    else
    {
    }
            
    try
    {
        doc.Save();
        retDocNo = doc.DocNo;
        //AutoCount.AppMessage.ShowMessage(string.Format("{0} is Created/Updated.", doc.DocNo));
        //Log Success created
    }
    catch (AutoCount.AppException ex)
    {
        AutoCount.AppMessage.ShowErrorMessage(ex.Message);
        //Log Error saving
    }

    //Return null if document is not created or updated.
    //If successfully saved, Document number is returned.
    return retDocNo;
}

Add Deposit Payment Detail

private void AddARDepositDetail(ARDepositDetailSource source, Func<AutoCount.ARAP.ARDeposit.ARDepositDetail> addDepositDetail)
{
    AutoCount.ARAP.ARDeposit.ARDepositDetail dtl = addDepositDetail();
    dtl.PaymentMethod = source.PaymentMethod;
    dtl.ChequeNo = source.ChequeNo;
    dtl.PaymentAmt = source.DepositAmount;
    dtl.BankCharge = source.BankCharge;
    dtl.BankChargeTaxType = source.BankChargeTaxCode;
    dtl.BankChargeTaxRefNo = source.BankChargeBillNoForGst;
    dtl.PaymentBy = source.PaymentBy;

    //Returned Cheque
    if (source.ReturnChequeDate.HasValue)
    {
        dtl.IsRCHQ = true;
        dtl.RCHQDate = source.ReturnChequeDate.Value;
    }
    else
    {
        dtl.IsRCHQ = false;
    }
}

Add Deposit Refund Payment Detail

private void AddARRefundDetail(ARDepositDetailSource source, Func<AutoCount.ARAP.ARDeposit.ARDepositRefundDetail> addRefundDetail)
{
    AutoCount.ARAP.ARDeposit.ARDepositRefundDetail dtl = addRefundDetail();
    dtl.PaymentMethod = source.PaymentMethod;
    dtl.ChequeNo = source.ChequeNo;
    dtl.PaymentAmount = source.DepositAmount;
    dtl.BankCharge = source.BankCharge;
    dtl.BankChargeTaxType = source.BankChargeTaxCode;
    dtl.BankChargeTaxRefNo = source.BankChargeBillNoForGst;
    dtl.PaymentBy = source.PaymentBy;

    //Returned Cheque
    if (source.ReturnChequeDate.HasValue)
    {
        dtl.IsReturnedCheque = true;
        dtl.ReturnedChequeDate = source.ReturnChequeDate.Value;
    }
    else
    {
        dtl.IsReturnedCheque = false;
    }
}

Check Deposit Payment Method Validity

private bool IsValidDepositMethod(string depositMethod, AutoCount.Authentication.UserSession userSession)
{
    return GetDepositPaymentMethod(userSession).AsEnumerable()
        .Count(r => r.Field<string>("PaymentMethod") == depositMethod) > 0;
}

private DataTable GetDepositPaymentMethod(AutoCount.Authentication.UserSession userSession)
{
    AutoCount.XtraUtils.LookupEditBuilder.DepositPaymentMethodLookupEditBuilder depositBuilder =
        new AutoCount.XtraUtils.LookupEditBuilder.DepositPaymentMethodLookupEditBuilder();

    //The return table contains of 3 columns: (1) PaymentMethod, (2) BankAccount, (3) CurrencyCode
    return depositBuilder.BuildDataTable(userSession);
}

Classes of Deposit source

public class ARDepositSource
{
    public string DocumentNo { get; set; }
    public DateTime DocumentDate { get; set; } = DateTime.Today.Date;
    public string Description { get; set; }
    public string DepositMethod { get; set; }

    //Currency Code that is used to pay the deposit
    public string CurrencyCode { get; set; }
    public string CustomerAccount { get; set; }
    public string CustomerName { get; set; }
    public string Attention { get; set; }
    public string Phone { get; set; }
    public string Fax { get; set; }
    public string Project { get; set; }
    public string Department { get; set; }

    //IsSecurityDeposit is to decide whether this deposit is subject to GST
    //true: not subject to GST until this deposit is convert to payment or payment of a sale
    //false: subject to GST and is considered as "Advance Payment"
    public bool IsSecurityDeposit { get; set; }

    public ARDepositRefundSource Refund { get; set; }
    public ARDepositForfeitSource Forfeit { get; set; }

    public List<ARDepositDetailSource> PaymentDetail = new List<ARDepositDetailSource>();
}
public class ARDepositDetailSource
{
    public string PaymentMethod { get; set; }
    public string ChequeNo { get; set; }
    public decimal DepositAmount { get; set; }
    public decimal BankCharge { get; set; }
    public string BankChargeTaxCode { get; set; }
    public string BankChargeBillNoForGst { get; set; }
    public string PaymentBy { get; set; }

    //If this cheque is returned/bounced cheque
    //Set the returned/bounced date. Otherwise it is null
    public DateTime? ReturnChequeDate { get; set; }
}

Deposit Refund Source

public class ARDepositRefundSource
{
    public string DocumentNo { get; set; }
    public string Description { get; set; }
    public DateTime RefundDate { get; set; }
    public List<ARDepositRefundDetailSource> PaymentDetail { get; set; } = new List<ARDepositRefundDetailSource>();
}

public class ARDepositRefundDetailSource : ARDepositDetailSource
{ }

Deposit Forfeit source

public class ARDepositForfeitSource
{
    public string ForfeitAccNo { get; set; }
    public decimal ForfeitAmount { get; set; }
    public DateTime ForfeitDate { get; set; }
}

Implementation

public void MainEntry(AutoCount.Authentication.UserSession userSession)
{
    string docNo = "";
    //Example of First Deposit with Refund and with New Document Number
    ARDepositSource newDoc = new ARDepositSource()
    {
        //DEPOSIT RECEIVED must be a Payment Method created for Deposit Account
        DepositMethod = "DEPOSIT RECEIVED",
        Description = "DEPOSIT",
        DocumentDate = new DateTime(2017, 11, 25)
    };

    newDoc.PaymentDetail.Add(new ARDepositDetailSource()
    {
        PaymentMethod = "BANK",
        ChequeNo = "CHQ00021",
        PaymentBy = "CHEQUE",
        DepositAmount = 500
    });

    newDoc.Refund = new ARDepositRefundSource()
    {
        Description = "Refund of Deposit",
        RefundDate = new DateTime(2017, 11, 26)
    };

    newDoc.Refund.PaymentDetail.Add(new ARDepositRefundDetailSource()
    {
        //Return to customer
        PaymentMethod = "BANK",
        ChequeNo = "C00101",
        PaymentBy = "Bank Transfer",
        DepositAmount = 200
    });

    docNo = AddUpdateDepositWithRefundForfeit(newDoc, userSession);

    //Add Forfeit amount to 1st Deposit with Refund
    newDoc = new ARDepositSource()
    {
        //DEPOSIT RECEIVED must be a Payment Method created for Deposit Account
        DepositMethod = "DEPOSIT RECEIVED",
        Description = "DEPOSIT",
        //Assign an existing document number to "DocumentNo" will edit & update this deposit.
        DocumentNo = docNo,
        DocumentDate = new DateTime(2017, 11, 25)
    };

    newDoc.PaymentDetail.Add(new ARDepositDetailSource()
    {
        PaymentMethod = "BANK",
        ChequeNo = "CHQ00021",
        PaymentBy = "CHEQUE",
        DepositAmount = 500
    });

    newDoc.Refund = new ARDepositRefundSource()
    {
        Description = "Refund of Deposit",
        RefundDate = new DateTime(2017, 11, 26)
    };

    newDoc.Refund.PaymentDetail.Add(new ARDepositRefundDetailSource()
    {
        //Return to customer
        PaymentMethod = "BANK",
        ChequeNo = "C00101",
        PaymentBy = "Bank Transfer",
        DepositAmount = 250
    });
    //Forfeit
    newDoc.Forfeit = new ARDepositForfeitSource()
    {
        //Forfeit AccNo can be maintained in Tools | Option
        //G/L | Default Accounts
        //If Default Account is maintained, ForfeitAccNo can be null
        ForfeitAccNo = "550-0000",
        ForfeitAmount = 100,
        ForfeitDate = new DateTime(2017, 12, 2)
    };

    AddUpdateDepositWithRefundForfeit(newDoc, userSession);
}


See Also

AutoCount Accounting Account API
AR AP
Transactions Version Transactions Version
AR Debtor (Customer) 1.8, 1.9
2.0
AP Creditor (Supplier) 1.8, 1.9
2.0
AR Invoice 1.8, 1.9
2.0
AP Invoice 1.8, 1.9
2.0
AR Received Payment 1.8, 1.9
2.0
AP Payment 1.8, 1.9
2.0
AR Debit Note 1.8, 1.9
2.0
AP Debit Note 1.8, 1.9
2.0
AR Credit Note 1.8, 1.9
2.0
AP Credit Note 1.8, 1.9
2.0
AR Refund 1.8, 1.9
2.0
AP Refund 1.8, 1.9
2.0
AR Deposit 1.8, 1.9
2.0
AP Deposit 1.8, 1.9
2.0
AR Deposit - Create New or Update
with Refund & Forfeit
1.8, 1.9
2.0
A/R and A/P Contra Entry 1.8, 1.9
2.0

Go to menu

Go to top
Resources For AutoCount Software Developers