Programmer:Sales Invoice: Difference between revisions
Content deleted Content added
m Protected "Programmer:Sales Invoice" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite) [Delete=Allow only administrators] (indefinite)) |
No edit summary |
||
(13 intermediate revisions by the same user not shown) | |||
Line 1:
==Technical Specification==
# NetTotal must not be negative amount
# Negative Quantity is allowed, if it does not violate the NetTotal rule.
# Changing Unit Price of '''Item Package''' directly will affect the accuracy of Sales Analysis and Profit Margin Report.
#:To change the Price of an Item Package, it is required to change at the detail level.
==Assemblies version 1.8, 1.9==
{{BaseReferenceAC18}}
'''BCE.AutoCount.Invoicing.dll'''
'''BCE.AutoCount.Invoicing.Sales.dll'''
==Sample with data model==
===Create New Sale Invoice===
<syntaxhighlight lang="csharp">
public void NewSaleInvoice(BCE.Data.DBSetting dbSetting, SaleInvoiceSource source)
{
BCE.AutoCount.Invoicing.Sales.Invoice.InvoiceCommand cmd = BCE.AutoCount.Invoicing.Sales.Invoice.InvoiceCommand.Create(dbSetting);
BCE.AutoCount.Invoicing.Sales.Invoice.Invoice doc = cmd.AddNew();
doc.DebtorCode = source.CustomerCode;
doc.DocNo = source.DocumentNo;
doc.DocDate = source.DocumentDate;
doc.Description = source.Description;
doc.CurrencyRate = source.CurrencyRate;
doc.Agent = source.SalesPerson;
//Set to apply rounding method of either by Document or by Each Line,
//this may affect different result in GST Calculation due to decimal point.
doc.RoundingMethod = source.RoundMethod;
//Document Level Inclusive Tax
doc.InclusiveTax = source.Inclusive;
source.Details.ForEach(s => AddSaleInvoiceDetail(s, doc.AddDetail));
try
{
doc.Save();
//log success
//BCE.Application.AppMessage.ShowMessage(string.Format("{0} is created.", doc.DocNo));
}
catch (BCE.Application.AppException ex)
{
//log ex.Message
//BCE.Application.AppMessage.ShowMessage(ex.Message);
}
}
private void AddSaleInvoiceDetail(SaleInvoiceDetail sourceDtl,
Func<BCE.AutoCount.Invoicing.Sales.Invoice.InvoiceDetail> addToDoc)
{
BCE.AutoCount.Invoicing.Sales.Invoice.InvoiceDetail dtl = addToDoc();
dtl.AccNo = sourceDtl.Account;
//When ItemCode is assigned, AccNo will be refreshed based on ItemGroup's SaleAccNo;
//If ItemGroup is not maintained, then default Sale AccNo will be assigned.
dtl.ItemCode = sourceDtl.ItemCode;
dtl.Description = sourceDtl.Description ?? dtl.Description;
if (sourceDtl.Project != null)
dtl.ProjNo = sourceDtl.Project;
if (sourceDtl.Department != null)
dtl.DeptNo = sourceDtl.Department;
if (sourceDtl.Location != null)
dtl.Location = sourceDtl.Location;
dtl.Qty = sourceDtl.Quantity ?? dtl.Qty;
dtl.UOM = sourceDtl.Uom ?? dtl.UOM;
dtl.UnitPrice = sourceDtl.UnitPrice ?? dtl.UnitPrice;
dtl.Discount = sourceDtl.Discount ?? dtl.Discount;
dtl.SubTotal = sourceDtl.Amount ?? dtl.SubTotal;
if (sourceDtl.GSTCode != null)
dtl.TaxType = sourceDtl.GSTCode;
dtl.TaxAdjustment = sourceDtl.GSTAdjustment;
}
</syntaxhighlight>
===Classes of source===
<syntaxhighlight lang="csharp">
public class SaleInvoiceSource
{
public string CustomerCode { get; set; }
public string DocumentNo { get; set; }
public DateTime DocumentDate { get; set; }
public string Description { get; set; }
public decimal CurrencyRate { get; set; } = 1;
public string SalesPerson { get; set; }
public BCE.AutoCount.Document.DocumentRoundingMethod RoundMethod { get; set; } =
BCE.AutoCount.Document.DocumentRoundingMethod.LineByLine_Ver2;
public bool Inclusive { get; set; } = false;
public List<SaleInvoiceDetail> Details { get; set; } = new List<SaleInvoiceDetail>();
}
public class SaleInvoiceDetail
{
public string Account { get; set; }
public string ItemCode { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public string Project { get; set; }
public string Department { get; set; }
public decimal? Quantity { get; set; }
public string Uom { get; set; }
public decimal? UnitPrice { get; set; }
public string Discount { get; set; }
public decimal? Amount { get; set; }
public string GSTCode { get; set; }
public decimal GSTAdjustment { get; set; }
}
</syntaxhighlight>
===Implementation===
[[File:SALEInvoiceGenerate01.PNG|link=]]
<syntaxhighlight lang="csharp">
public void MainEntry(BCE.Data.DBSetting dbSetting)
{
SaleInvoiceSource newDoc = new SaleInvoiceSource()
{
CustomerCode = "300-A001",
Description = "SALES INVOICE GENERATED",
//If let AutoCount auto assign running number, assign "<<New>>" is unnecessary
//DocumentNo = "<<New>>",
DocumentDate = new DateTime(2017, 11, 30),
Inclusive = true
};
//There are many ways which data input can be entered into details, here are some of the common input.
newDoc.Details.Add(new SaleInvoiceDetail() { Description = "Particulars" });
newDoc.Details.Add(new SaleInvoiceDetail(){ ItemCode = "FG00001", Quantity = 1, UnitPrice = 50.20M, GSTCode = "SR-S" });
newDoc.Details.Add(new SaleInvoiceDetail(){ ItemCode = "FG00001", Quantity = 2, UnitPrice = 50.20M, Discount = "5%", GSTCode = "SR-S" });
newDoc.Details.Add(new SaleInvoiceDetail(){ ItemCode = "FG00001", Quantity = 1, GSTCode = "SR-S", Amount = 50.20M });
//Return stock is allowed, if the NetTotal is larger or equal to Zero after deduction.
newDoc.Details.Add(new SaleInvoiceDetail(){ ItemCode = "FG00002", Quantity = -1, GSTCode = "SR-S", Amount = -60.20M });
newDoc.Details.Add(new SaleInvoiceDetail(){ ItemCode = "FG00002", Quantity = -1, UnitPrice = 60.20M, Discount = "5%", GSTCode = "SR-S" });
newDoc.Details.Add(new SaleInvoiceDetail() { Description = "Non-Stock Items" });
//When AccNo & ItemCode both are not defined, system will retrieve from default Sale Account.
//If default Sale Account is not maintained in Tools | Options, system will throw error on saving.
newDoc.Details.Add(new SaleInvoiceDetail(){ Description = "Misc. Charges", GSTCode = "SR-S", Amount = 30 });
newDoc.Details.Add(new SaleInvoiceDetail(){ Account = "500-0000", Description = "Transport", Amount = 50, GSTCode = "SR-S" });
NewSaleInvoice(dbSetting, newDoc);
}
</syntaxhighlight>
{{Note|'''Non-Stock Item''' can either with or without ItemCode, it depends on the setting & preference in customer Account Book.}}
<br/>
==Transfer from Delivery Order with ItemCode and Item Package==
<syntaxhighlight lang="csharp">
public void TransferFromDeliveryOrderWithItemPackage(BCE.Data.DBSetting dbSetting)
{
string docNo = "DO-00001";
BCE.AutoCount.Invoicing.Sales.TransferFrom transferFrom = BCE.AutoCount.Invoicing.Sales.TransferFrom.DeliveryOrder;
BCE.AutoCount.Invoicing.Sales.Invoice.InvoiceCommand cmd =
BCE.AutoCount.Invoicing.Sales.Invoice.InvoiceCommand.Create(dbSetting);
BCE.AutoCount.Invoicing.Sales.Invoice.Invoice doc = cmd.AddNew();
BCE.AutoCount.Invoicing.Sales.Invoice.InvoiceDetail dtl;
//Transfer Item Package
//PackA is Package Code
if (!doc.PartialTransfer(transferFrom, docNo, "PackA", 1))
{
//Log error - failed
}
//Transfer Item Package with DtlKey in DODtl
//When there are 2 or more same Package Code in Delivery Order,
//using DtlKey to ensure a specific Item (Item Package) is transferred
//Without DtlKey, it will go by sequence of the item.
if (!doc.PartialTransfer(transferFrom, docNo, "PackB", 1, 13485))
{
//Log error - failed
}
//Transfer ItemCode from D/O
//FG0001 is the ItemCode
//UNIT is the UOM
//1 is qty to transfer
//0 is FocQty to transfer
if (!doc.PartialTransfer(transferFrom, docNo, "FG0001", "UNIT", 1, 0))
{
//Log error
}
//Transfer ItemCode from D/O with specific DtlKey in DODtl
if (!doc.PartialTransfer(transferFrom, docNo, "FG0002", "UNIT", 1, 0, 13487))
{
//Log error
}
//Add new Item Package in Invoice
dtl = doc.AddPackage("PackC");
dtl.Qty = 2;
//Do not change UnitPrice at Package level, as the UnitPrice of package must be the sum of items' unit price.
//Change unit Price of items in Package
foreach (System.Data.DataRow row in doc.DataTablePackageDetail.Rows)
{
//Write a function to assign price to the ItemCode
//Eg.
//row["UnitPrice"] = GetPackageItemsPrice(row["ItemCode"].ToString());
}
//Add new ItemCode in Invoice
dtl = doc.AddDetail();
dtl.ItemCode = "FG0003";
dtl.UOM = "UNIT";
dtl.Qty = 2;
dtl.UnitPrice = 50.00M;
try
{
doc.Save();
//Success
}
catch (BCE.Application.AppException ex)
{
BCE.Application.AppMessage.ShowErrorMessage(ex.Message);
//Fail
}
}
</syntaxhighlight>
{{SeeAlsoSale}}
{{NavigateDeveloper}}
|