Refactor: Instead of a concept of Price/FullPrice, happy hour is now a checkbox in the product.

This needed major refactor in all parts dealing with product or inventory.
This commit is contained in:
tanshu 2016-04-11 12:31:52 +05:30
parent 69cb7d8bce
commit 20eac3c216
35 changed files with 861 additions and 435 deletions

@ -0,0 +1,26 @@
declare @id uniqueidentifier
declare @name nvarchar(255)
declare @units nvarchar(255)
declare @price decimal(19,5)
declare @org uniqueidentifier
declare @c int
DECLARE db_cursor CURSOR FOR
select ProductID, Name, Units, price from products where name like 'H h %' and hashappyhour = 1
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @id, @name, @units, @price
WHILE @@FETCH_STATUS = 0
BEGIN
select @c = count(*) from products where 'H H ' + name = @name and units = @units
if @c = 1
BEGIN
select @org = productid from products where 'H H ' + name = @name and units = @units
update inventories set productid = @org, ishappyhour = 1 where productid = @id
delete from products where productid = @id
update products set hashappyhour = 1 where productid = @org
END
FETCH NEXT FROM db_cursor INTO @id, @name, @units, @price
END
CLOSE db_cursor
DEALLOCATE db_cursor

@ -0,0 +1,195 @@
BEGIN TRANSACTION
GO
ALTER TABLE dbo.Inventories DROP CONSTRAINT FK8C0CFB221DECC269
GO
ALTER TABLE dbo.Inventories DROP CONSTRAINT FK8C0CFB22EB4DE5BC
GO
ALTER TABLE dbo.Inventories DROP CONSTRAINT FK8C0CFB223F88CAB6
GO
ALTER TABLE dbo.Inventories DROP CONSTRAINT FK8C0CFB22DB70F42
GO
CREATE TABLE dbo.Tmp_Inventories
(
InventoryID uniqueidentifier NOT NULL,
KotID uniqueidentifier NOT NULL,
ProductID uniqueidentifier NOT NULL,
SortOrder int NOT NULL,
Quantity decimal(19, 5) NOT NULL,
Price decimal(19, 5) NOT NULL,
IsHappyHour bit NOT NULL,
ServiceCharge decimal(19, 5) NOT NULL,
IsScTaxable bit NOT NULL,
ServiceTaxRate decimal(19, 5) NOT NULL,
VatRate decimal(19, 5) NOT NULL,
ServiceTaxID uniqueidentifier NOT NULL,
VatID uniqueidentifier NOT NULL,
Discount decimal(19, 5) NOT NULL,
Amount AS (Quantity * CASE WHEN IsHappyHour = 1 THEN 0 ELSE Price END * (1 - Discount) * CASE WHEN IsScTaxable = 1 THEN (1 + ServiceCharge) * (1 + ServiceTaxRate + VatRate) ELSE (1 + ServiceCharge + ServiceTaxRate + VatRate) END)
) ON [PRIMARY]
GO
IF EXISTS(SELECT * FROM dbo.Inventories)
EXEC('INSERT INTO dbo.Tmp_Inventories (InventoryID, KotID, ProductID, SortOrder, Quantity, Price, IsHappyHour, ServiceCharge, IsScTaxable, ServiceTaxRate, VatRate, ServiceTaxID, VatID, Discount)
SELECT InventoryID, KotID, ProductID, SortOrder, Quantity, CASE WHEN Price = 0 THEN FullPrice ELSE Price END, CASE WHEN Price = 0 THEN 1 ELSE 0 END, ServiceCharge, IsScTaxable, ServiceTaxRate, VatRate, ServiceTaxID, VatID, Discount FROM dbo.Inventories WITH (HOLDLOCK TABLOCKX)')
GO
ALTER TABLE dbo.InventoryModifiers DROP CONSTRAINT FK80820FB4BA29671A
GO
DROP TABLE dbo.Inventories
GO
EXECUTE sp_rename N'dbo.Tmp_Inventories', N'Inventories', 'OBJECT'
GO
ALTER TABLE dbo.Inventories ADD CONSTRAINT
PK__Inventories__0DAF0CB0 PRIMARY KEY CLUSTERED
(
InventoryID
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Inventories ADD CONSTRAINT
FK8C0CFB22DB70F42 FOREIGN KEY
(
KotID
) REFERENCES dbo.Kots
(
KotID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Inventories ADD CONSTRAINT
FK8C0CFB223F88CAB6 FOREIGN KEY
(
ProductID
) REFERENCES dbo.Products
(
ProductID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Inventories ADD CONSTRAINT
FK8C0CFB221DECC269 FOREIGN KEY
(
ServiceTaxID
) REFERENCES dbo.Taxes
(
TaxID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Inventories ADD CONSTRAINT
FK8C0CFB22EB4DE5BC FOREIGN KEY
(
VatID
) REFERENCES dbo.Taxes
(
TaxID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.InventoryModifiers ADD CONSTRAINT
FK80820FB4BA29671A FOREIGN KEY
(
InventoryID
) REFERENCES dbo.Inventories
(
InventoryID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Products DROP CONSTRAINT FK4065562AEB4DE5BC
GO
ALTER TABLE dbo.Products DROP CONSTRAINT FK4065562A1DECC269
GO
ALTER TABLE dbo.Products DROP CONSTRAINT FK4065562A95976D16
GO
CREATE TABLE dbo.Tmp_Products (
ProductID uniqueidentifier NOT NULL,
Code int NULL,
Name nvarchar(255) NOT NULL,
Units nvarchar(255) NOT NULL,
ProductGroupID uniqueidentifier NULL,
VatID uniqueidentifier NULL,
ServiceTaxID uniqueidentifier NULL,
ServiceCharge decimal(19, 5) NOT NULL,
IsScTaxable bit NOT NULL,
Price decimal(19, 5) NOT NULL,
HasHappyHour bit NOT NULL,
IsActive bit NOT NULL,
IsNotAvailable bit NOT NULL,
SortOrder int NOT NULL,
Quantity decimal(19, 5) NOT NULL
) ON [PRIMARY]
GO
IF EXISTS(SELECT * FROM dbo.Products)
EXEC('INSERT INTO dbo.Tmp_Products (ProductID, Code, Name, Units, ProductGroupID, VatID, ServiceTaxID, ServiceCharge, IsScTaxable, Price, HasHappyHour, IsActive, IsNotAvailable, SortOrder, Quantity)
SELECT ProductID, Code, Name, Units, ProductGroupID, VatID, ServiceTaxID, ServiceCharge, IsScTaxable, Price, CASE WHEN Price = 0 AND FullPrice != 0 THEN 1 ELSE 0 END, IsActive, IsNotAvailable, SortOrder, Quantity FROM dbo.Products WITH (HOLDLOCK TABLOCKX)')
GO
ALTER TABLE dbo.Inventories DROP CONSTRAINT FK8C0CFB223F88CAB6
GO
DROP TABLE dbo.Products
GO
EXECUTE sp_rename N'dbo.Tmp_Products', N'Products', 'OBJECT'
GO
ALTER TABLE dbo.Products ADD CONSTRAINT
PK__Products__164452B1 PRIMARY KEY CLUSTERED
(
ProductID
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Products ADD CONSTRAINT
UQ__Products__173876EA UNIQUE NONCLUSTERED
(
Name,
Units
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Products ADD CONSTRAINT
FK4065562A95976D16 FOREIGN KEY
(
ProductGroupID
) REFERENCES dbo.ProductGroups
(
ProductGroupID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Products ADD CONSTRAINT
FK4065562AEB4DE5BC FOREIGN KEY
(
VatID
) REFERENCES dbo.Taxes
(
TaxID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Products ADD CONSTRAINT
FK4065562A1DECC269 FOREIGN KEY
(
ServiceTaxID
) REFERENCES dbo.Taxes
(
TaxID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Inventories ADD CONSTRAINT
FK8C0CFB223F88CAB6 FOREIGN KEY
(
ProductID
) REFERENCES dbo.Products
(
ProductID
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
COMMIT

@ -15,7 +15,7 @@ namespace Tanshu.Accounts.Contracts
{
if (inventory != null)
{
var output = string.Format("{0} @ Rs. {1:#.##}", inventory.Product.FullName, inventory.Price);
var output = string.Format("{0} @ Rs. {1:#.##}", inventory.EffectiveName, inventory.Price);
if (inventory.Discount != 0)
output += string.Format(" - {0:#.##%}", inventory.Discount);
foreach (var item in inventory.InventoryModifier)
@ -36,12 +36,12 @@ namespace Tanshu.Accounts.Contracts
{
inventory = inv;
}
public BillItemValue(Product product)
public BillItemValue(Product product, bool isHappyHour)
{
inventory = new Inventory()
{
Product = product,
FullPrice = product.FullPrice,
IsHappyHour = isHappyHour,
Price = product.Price,
IsScTaxable = product.IsScTaxable,
Quantity = 1,

@ -4,7 +4,8 @@ namespace Tanshu.Accounts.Contracts
{
public enum BillItemType
{
Product,
RegularProduct,
HappyHourProduct,
Kot
}
public class BillItemKey
@ -18,15 +19,15 @@ namespace Tanshu.Accounts.Contracts
public BillItemKey(Guid kotID)
: this(Guid.Empty, kotID, BillItemType.Kot)
{ }
public BillItemKey(Guid productID, Guid kotID)
: this(productID, kotID, BillItemType.Product)
public BillItemKey(Guid productID, Guid kotID, bool IsHappyHour)
: this(productID, kotID, IsHappyHour? BillItemType.HappyHourProduct : BillItemType.RegularProduct)
{ }
private Guid _productID;
public Guid ProductID
{
get { return BillItemType == BillItemType.Product ? _productID : Guid.Empty; }
private set { _productID = BillItemType == BillItemType.Product ? value : Guid.Empty; }
get { return BillItemType != BillItemType.Kot ? _productID : Guid.Empty; }
private set { _productID = BillItemType != BillItemType.Kot ? value : Guid.Empty; }
}
public Guid KotID { get; private set; }
@ -35,7 +36,7 @@ namespace Tanshu.Accounts.Contracts
public override int GetHashCode()
{
return BillItemType.GetHashCode() ^ KotID.GetHashCode() ^ ProductID.GetHashCode();
return BillItemType.GetHashCode() ^ KotID.GetHashCode() ^ ProductID.GetHashCode() ^ BillItemType.GetHashCode();
}
public static bool operator ==(BillItemKey a, BillItemKey b)
{
@ -50,7 +51,7 @@ namespace Tanshu.Accounts.Contracts
if (a.BillItemType != b.BillItemType)
return false;
return a.KotID == b.KotID && a.BillItemType == b.BillItemType && a.ProductID == b.ProductID;
return a.KotID == b.KotID && a.BillItemType == b.BillItemType && a.ProductID == b.ProductID && a.BillItemType == b.BillItemType;
}
public static bool operator !=(BillItemKey a, BillItemKey b)
{

@ -19,10 +19,22 @@ namespace Tanshu.Accounts.Contracts
public class SalesAnalysisDetail
{
public virtual string Product { get; set; }
public virtual decimal Sale { get; set; }
public virtual decimal NC { get; set; }
public virtual decimal Staff { get; set; }
private string _name;
public Guid ProductID { get; set; }
public string Name
{
get
{
return IsHappyHour ? "H H " + _name : _name;
}
set
{
_name = value;
}
}
public bool IsHappyHour { get; set; }
public decimal Sale { get; set; }
public decimal NC { get; set; }
}
public class BillDetail
{

@ -20,7 +20,7 @@ namespace Tanshu.Accounts.Entities
public virtual Product Product { get; set; }
public virtual decimal Quantity { get; set; }
public virtual decimal Price { get; set; }
public virtual decimal FullPrice { get; set; }
public virtual bool IsHappyHour { get; set; }
public virtual decimal ServiceCharge { get; set; }
public virtual bool IsScTaxable { get; set; }
public virtual decimal ServiceTaxRate { get; set; }
@ -31,13 +31,29 @@ namespace Tanshu.Accounts.Entities
public virtual IList<InventoryModifier> InventoryModifier { get; set; }
public virtual string EffectiveName
{
get
{
return IsHappyHour ? string.Format("H H {0}", Product.FullName) : Product.FullName;
}
set { }
}
public virtual decimal EffectivePrice
{
get
{
return IsHappyHour ? 0 : Price;
}
set { }
}
public virtual decimal Amount
{
get
{
if (IsScTaxable)
return Quantity * Price * (1 - Discount) * (1 + ServiceCharge) * (1 + ServiceTaxRate + VatRate);
return Quantity * Price * (1 - Discount) * (1 + ServiceCharge + ServiceTaxRate + VatRate);
return Quantity * EffectivePrice * (1 - Discount) * (1 + ServiceCharge) * (1 + ServiceTaxRate + VatRate);
return Quantity * EffectivePrice * (1 - Discount) * (1 + ServiceCharge + ServiceTaxRate + VatRate);
}
set { }
}
@ -47,8 +63,8 @@ namespace Tanshu.Accounts.Entities
get
{
if (IsScTaxable)
return Quantity * Price * (1 - Discount) * (1 + ServiceCharge) * ServiceTaxRate;
return Quantity * Price * (1 - Discount) * ServiceTaxRate;
return Quantity * EffectivePrice * (1 - Discount) * (1 + ServiceCharge) * ServiceTaxRate;
return Quantity * EffectivePrice * (1 - Discount) * ServiceTaxRate;
}
}
@ -57,8 +73,8 @@ namespace Tanshu.Accounts.Entities
get
{
if (IsScTaxable)
return Quantity * Price * (1 - Discount) * (1 + ServiceCharge) * VatRate;
return Quantity * Price * (1 - Discount) * VatRate;
return Quantity * EffectivePrice * (1 - Discount) * (1 + ServiceCharge) * VatRate;
return Quantity * EffectivePrice * (1 - Discount) * VatRate;
}
}
@ -66,7 +82,7 @@ namespace Tanshu.Accounts.Entities
{
get
{
return Quantity * Price * (1 - Discount) * ServiceCharge;
return Quantity * EffectivePrice * (1 - Discount) * ServiceCharge;
}
}
@ -74,7 +90,7 @@ namespace Tanshu.Accounts.Entities
{
get
{
return Quantity * Price * Discount;
return Quantity * EffectivePrice * Discount;
}
}
@ -82,7 +98,7 @@ namespace Tanshu.Accounts.Entities
{
get
{
return Quantity * Price * (1 - Discount);
return Quantity * EffectivePrice * (1 - Discount);
}
}
}
@ -97,15 +113,19 @@ namespace Tanshu.Accounts.Entities
Property(x => x.SortOrder, map => map.NotNullable(true));
Property(x => x.Quantity, map => map.NotNullable(true));
Property(x => x.Price, map => map.NotNullable(true));
Property(x => x.FullPrice, map => map.NotNullable(true));
Property(x => x.IsHappyHour, map => map.NotNullable(true));
Property(x => x.ServiceTaxRate, map => map.NotNullable(true));
Property(x => x.VatRate, map => map.NotNullable(true));
Property(x => x.Discount, map => map.NotNullable(true));
Property(x => x.ServiceCharge, map => map.NotNullable(true));
Property(x => x.IsScTaxable, map => map.NotNullable(true));
Property(x => x.EffectivePrice, map =>
{
map.Formula("CASE WHEN IsHappyHour = 1 THEN 0 ELSE Price END");
});
Property(x => x.Amount, map =>
{
map.Formula("CASE WHEN IsScTaxable = 1 THEN Quantity * Price * (1 - Discount) * (1 + ServiceCharge) * (1 + ServiceTaxRate + VatRate) ELSE Quantity * Price * (1 - Discount) * (1 + ServiceCharge + ServiceTaxRate + VatRate) END");
map.Formula("Quantity * CASE WHEN IsHappyHour = 1 THEN 0 ELSE Price END * (1 - Discount) * CASE WHEN IsScTaxable = 1 THEN (1 + ServiceCharge) * (1 + ServiceTaxRate + VatRate) ELSE (1 + ServiceCharge + ServiceTaxRate + VatRate) END");
});
ManyToOne(x => x.ServiceTax, map =>

@ -17,7 +17,7 @@ namespace Tanshu.Accounts.Entities
public virtual decimal ServiceCharge { get; set; }
public virtual bool IsScTaxable { get; set; }
public virtual decimal Price { get; set; }
public virtual decimal FullPrice { get; set; }
public virtual bool HasHappyHour { get; set; }
public virtual bool IsActive { get; set; }
public virtual bool IsNotAvailable { get; set; }
public virtual int SortOrder { get; set; }
@ -30,6 +30,7 @@ namespace Tanshu.Accounts.Entities
{
return Units == string.Empty ? Name : string.Format("{0} ({1})", Name, Units);
}
set { }
}
}
public class ProductMap : ClassMapping<Product>
@ -46,12 +47,16 @@ namespace Tanshu.Accounts.Entities
Property(x => x.ServiceCharge, map => map.NotNullable(true));
Property(x => x.IsScTaxable, map => map.NotNullable(true));
Property(x => x.Price, map => map.NotNullable(true));
Property(x => x.FullPrice, map => map.NotNullable(true));
Property(x => x.HasHappyHour, map => map.NotNullable(true));
Property(x => x.IsActive, map => map.NotNullable(true));
Property(x => x.IsNotAvailable, map => map.NotNullable(true));
Property(x => x.SortOrder, map => map.NotNullable(true));
Property(x => x.Quantity, map => map.NotNullable(true));
Property(x => x.FullName, map =>
{
map.Formula("CASE WHEN Units = '' THEN Name ELSE Name + ' (' + Units + ')' END");
});
ManyToOne(x => x.ProductGroup, map => { map.Column("ProductGroupID"); map.Cascade(Cascade.None); });
ManyToOne(x => x.ServiceTax, map => { map.Column("ServiceTaxID"); map.Cascade(Cascade.None); });
ManyToOne(x => x.Vat, map => { map.Column("VatID"); map.Cascade(Cascade.None); });

@ -101,13 +101,13 @@ namespace Tanshu.Accounts.Helpers
control = new Button()
{
Name = string.Format("p{0}", i),
Text = item.FullName,
Text = (item.HasHappyHour ? "H H " : "") + item.FullName,
Width = size.X,
Height = size.Y,
Tag = item,
};
control.Click += new EventHandler(bcDelegate);
if (item.Price == 0)
if (item.HasHappyHour)
control.BackColor = Color.Yellow;
if (item.IsNotAvailable)
control.BackColor = Color.Red;

@ -1,118 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using Tanshu.Accounts.Contracts;
using Tanshu.Data;
using Tanshu.Accounts.Entities.Auth;
namespace Tanshu.Accounts.Helpers
{
public class SelectUser : Tanshu.Data.BaseSelector<User>
{
public event UserEventHandler UserEvent;
public SelectUser(GetData<User> getData, bool autoClose) : base (getData, true, "Select a User")
{
var filters = new List<string> {"Name"};
SetFilterColumns(filters);
grid.Columns["UserID"].Visible = false;
}
protected override void FilterChanged(Dictionary<string, string> filter)
{
//data = originalData.Where(d => d.Name.ToLower().Contains(filter["Name"].ToLower())).ToList();
data = getData(filter);
bindingSource.DataSource = data;
}
protected override void UpdateDisplay(User item)
{
DisplayLabel = item == null ? "" : string.Format("User Name: {0}", item.Name);
}
protected override User HandleKeydown(object sender, ExtendedKeyEventArgs e)
{
var user = bindingSource.Current as User;
if (UserEvent == null)
{
e.Handled = false;
return user;
}
if ((e.KeyCode != Keys.F1) && (e.KeyCode != Keys.F2))
{
e.Handled = false;
return user;
}
if ((user == null) && (e.KeyCode == Keys.F2))
{
e.Handled = false;
return user;
}
if (e.KeyCode == Keys.F1)
user = new User();
var userEventArgs = new UserEventArgs(user);
user = UserEvent(sender, userEventArgs);
e.Handled = userEventArgs.Handled;
return user;
}
#region Designer Code
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
}
#endregion
#endregion
}
public delegate User UserEventHandler(object sender, UserEventArgs e);
public class UserEventArgs : EventArgs
{
public UserEventArgs(User user)
{
User = user;
Handled = false;
}
public User User
{
get;
private set;
}
public bool Handled
{
get;
set;
}
}
}

@ -1,76 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using Tanshu.Data;
namespace Tanshu.Accounts.Helpers
{
public class SelectVoidReason : Tanshu.Data.BaseSelector<StringType>
{
public SelectVoidReason(GetData<StringType> getData, bool autoClose)
: base(getData, autoClose, "Reason for Voiding Bill")
{
List<string> filters = new List<string>();
filters.Add("Name");
SetFilterColumns(filters);
}
protected override void FilterChanged(Dictionary<string, string> filter)
{
//data = originalData.Where(d => d.Description.ToLower().Contains(filter["Name"].ToLower())).ToList();
data = getData(filter);
bindingSource.DataSource = data;
}
protected override void UpdateDisplay(StringType item)
{
if (item == null)
DisplayLabel = "";
else
DisplayLabel = string.Format("Reason for Voiding: {0}", item);
}
protected override StringType HandleKeydown(object sender, ExtendedKeyEventArgs e)
{
e.Handled = false;
return null;
}
#region Designer Code
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
}
#endregion
#endregion
}
}

@ -66,9 +66,6 @@
<Compile Include="CustomStructs.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="SelectVoidReason.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

@ -27,7 +27,7 @@ namespace Tanshu.Accounts.PointOfSale
public void AddProduct(Product product)
{
var newKey = new BillItemKey(product.ProductID, Guid.Empty);
var newKey = new BillItemKey(product.ProductID, Guid.Empty, product.HasHappyHour);
if (_bill.ContainsKey(newKey))
{
@ -35,8 +35,8 @@ namespace Tanshu.Accounts.PointOfSale
}
else
{
var billItemValue = new BillItemValue(product);
var old = _bill.FirstOrDefault(x => x.Key.BillItemType == BillItemType.Product && x.Key.ProductID == newKey.ProductID);
var billItemValue = new BillItemValue(product, product.HasHappyHour);
var old = _bill.FirstOrDefault(x => x.Key.BillItemType == (product.HasHappyHour ? BillItemType.HappyHourProduct : BillItemType.RegularProduct) && x.Key.ProductID == newKey.ProductID);
if (old.Key != null)
{
billItemValue.inventory.Discount = old.Value.inventory.Discount;
@ -70,7 +70,7 @@ namespace Tanshu.Accounts.PointOfSale
if (discount > 1 || discount < 0)
return;
foreach (var item in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && outList.Contains(x.Value.inventory.Product.ProductGroup.GroupType)))
foreach (var item in _bill.Where(x => x.Key.BillItemType != BillItemType.Kot && outList.Contains(x.Value.inventory.Product.ProductGroup.GroupType)))
{
var product = item.Value.inventory.Product;
var maxDiscount = product.ProductGroup.DiscountLimit;
@ -99,6 +99,8 @@ namespace Tanshu.Accounts.PointOfSale
}
public void SetPrice(BillItemValue item)
{
if (item.inventory.IsHappyHour)
return;
if (!Session.IsAllowed("Change Rate"))
return;
var price = item.inventory.Price;
@ -106,7 +108,7 @@ namespace Tanshu.Accounts.PointOfSale
return;
if (price == 0 && !Session.IsAllowed("NC Product"))
throw new PermissionException("NC of Product is not Allowed");
foreach (var sub in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.ProductID == item.inventory.Product.ProductID))
foreach (var sub in _bill.Where(x => x.Key.BillItemType != BillItemType.Kot && x.Key.ProductID == item.inventory.Product.ProductID))
sub.Value.inventory.Price = price;
}
public void ShowCustomers()
@ -138,7 +140,6 @@ namespace Tanshu.Accounts.PointOfSale
}
private void LoadBill(Guid voucherID)
{
ClearBill();
using (var bi = new VoucherBI())
{
_voucher = bi.Get(x => x.VoucherID == voucherID);
@ -345,7 +346,7 @@ namespace Tanshu.Accounts.PointOfSale
public bool SaveAndPrintKot()
{
#region Check if Allowed
if (!Session.IsAllowed("Print Kot") || _bill.Count(x => x.Key.BillItemType == BillItemType.Product) == 0)
if (!Session.IsAllowed("Print Kot") || _bill.Count(x => x.Key.BillItemType != BillItemType.Kot) == 0)
return false;
bool isPrinted = false, isVoid = false;
if (_voucher.VoucherID != Guid.Empty)
@ -383,7 +384,7 @@ namespace Tanshu.Accounts.PointOfSale
public bool SaveAndPrintBill()
{
#region Check if Allowed
if (!Session.IsAllowed("Print Bill") || _bill.Count(x => x.Key.BillItemType == BillItemType.Product) == 0)
if (!Session.IsAllowed("Print Bill") || _bill.Count(x => x.Key.BillItemType != BillItemType.Kot) == 0)
return false;
bool isPrinted = false, isVoid = false;
if (_voucher.VoucherID != Guid.Empty)
@ -464,8 +465,8 @@ namespace Tanshu.Accounts.PointOfSale
if (splitList == null || splitList.Count == 0)
return;
var listFirst = _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != Guid.Empty && splitList.Contains(x.Value.inventory.Product.ProductGroup.GroupType));
var listSecond = _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != Guid.Empty && !splitList.Contains(x.Value.inventory.Product.ProductGroup.GroupType));
var listFirst = _bill.Where(x => x.Key.BillItemType != BillItemType.Kot && x.Key.KotID != Guid.Empty && splitList.Contains(x.Value.inventory.Product.ProductGroup.GroupType));
var listSecond = _bill.Where(x => x.Key.BillItemType != BillItemType.Kot && x.Key.KotID != Guid.Empty && !splitList.Contains(x.Value.inventory.Product.ProductGroup.GroupType));
if (listFirst.Count() == 0 || listSecond.Count() == 0)
return; // all or none items selected to be moved
@ -527,43 +528,41 @@ namespace Tanshu.Accounts.PointOfSale
if (MessageBox.Show("Are you sure you want to void this bill?", "Void Bill", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) != DialogResult.Yes)
return false;
#endregion
var reasons = new string[] {
"Discount",
"Printing Fault",
"Item Changed",
"Quantity Reduced",
"Costing Bill for Party",
"Cashier Mistake",
"Management Freesale",
"Other"
};
var voidReason = new SelectVoidReason(GetVoidReason, true);
voidReason.ShowDialog();
if (voidReason.SelectedItem != null)
using (var voidReason = new VoidReasonListForm(reasons))
{
MessageBox.Show("Please Select a reason if you want to void the bill", "Bill NOT Voided", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
return false;
}
using (var bi = new VoucherBI())
{
bi.VoidBill(_voucher.VoucherID, voidReason.SelectedItem.Description);
if (!_editVoucherID.HasValue)
bi.UpdateTable(x => x.FoodTableID == _voucher.Table.FoodTableID && x.VoucherID == _voucher.VoucherID, null, null);
bi.SaveChanges();
voidReason.ShowDialog();
if (voidReason.SelectedItem == null)
{
MessageBox.Show("Please Select a reason if you want to void the bill", "Bill NOT Voided", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
return false;
}
using (var bi = new VoucherBI())
{
bi.VoidBill(_voucher.VoucherID, voidReason.SelectedItem);
if (!_editVoucherID.HasValue)
bi.UpdateTable(x => x.FoodTableID == _voucher.Table.FoodTableID && x.VoucherID == _voucher.VoucherID, null, null);
bi.SaveChanges();
}
}
ClearBill();
return true;
}
private static List<StringType> GetVoidReason(Dictionary<string, string> filter)
{
var list = new List<StringType>
{
new StringType("Discount"),
new StringType("Printing Fault"),
new StringType("Item Changed"),
new StringType("Quantity Reduced"),
new StringType("Costing Bill for Party"),
new StringType("Cashier Mistake"),
new StringType("Management Freesale"),
new StringType("Other")
};
return list.Where(i => i.Description.ToLower().Contains(filter["Name"].ToLower().Trim())).ToList();
}
private void SaveReprintOrDiscountBill(decimal oldAmount)
{
var amountChanged = oldAmount != _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != Guid.Empty).Sum(x => x.Value.inventory.Net);
var itemsChanged = _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID == Guid.Empty).Count() != 0;
var amountChanged = oldAmount != _bill.Where(x => x.Key.BillItemType != BillItemType.Kot && x.Key.KotID != Guid.Empty).Sum(x => x.Value.inventory.Net);
var itemsChanged = _bill.Where(x => x.Key.BillItemType != BillItemType.Kot && x.Key.KotID == Guid.Empty).Count() != 0;
if (amountChanged || itemsChanged) // Discount or Products changed
{
@ -577,7 +576,7 @@ namespace Tanshu.Accounts.PointOfSale
VoucherType = _voucher.VoucherType
};
var kotNew = GetKot(_bill.Where(x => x.Key.BillItemType == BillItemType.Product));
var kotNew = GetKot(_bill.Where(x => x.Key.BillItemType != BillItemType.Kot));
if (kotNew != null)
newVoucher.Kots.Add(kotNew);
#endregion
@ -605,7 +604,7 @@ namespace Tanshu.Accounts.PointOfSale
_voucher.Printed = finalBill;
_voucher.Void = false;
_voucher.Narration = "";
var kot = GetKot(_bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID == Guid.Empty && x.Value.inventory.Quantity != 0));
var kot = GetKot(_bill.Where(x => x.Key.KotID == Guid.Empty));
if (kot == null)
return null;
_voucher.Kots.Add(kot);
@ -630,15 +629,15 @@ namespace Tanshu.Accounts.PointOfSale
voucher.Customer = _voucher.Customer;
voucher.Printed = finalBill;
voucher.VoucherType = _voucher.VoucherType;
foreach (var item in _bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID != Guid.Empty))
foreach (var item in _bill.Where(x => x.Key.BillItemType != BillItemType.Kot && x.Key.KotID != Guid.Empty))
{
var i = voucher.Kots.Single(x => x.KotID == item.Key.KotID).Inventories.Single(x => x.Product.ProductID == item.Key.ProductID);
var i = voucher.Kots.Single(x => x.KotID == item.Key.KotID).Inventories.Single(x => x.Product.ProductID == item.Key.ProductID && x.IsHappyHour == item.Value.inventory.IsHappyHour);
i.Discount = item.Value.inventory.Discount;
i.Price = item.Value.inventory.Price;
}
if (!_voucher.Printed)
{
var kot = GetKot(_bill.Where(x => x.Key.BillItemType == BillItemType.Product && x.Key.KotID == Guid.Empty && x.Value.inventory.Quantity != 0));
var kot = GetKot(_bill.Where(x => x.Key.KotID == Guid.Empty));
if (kot != null)
voucher.Kots.Add(kot);
}
@ -658,7 +657,13 @@ namespace Tanshu.Accounts.PointOfSale
var kot = new Kot();
foreach (var item in list)
{
var oldInv = kot.Inventories.SingleOrDefault(x => x.Product.ProductID == item.Key.ProductID);
if (item.Key.BillItemType == BillItemType.Kot)
continue;
if (item.Value.inventory.Quantity == 0)
continue;
var happyHour = item.Key.BillItemType == BillItemType.HappyHourProduct;
var productID = item.Key.ProductID;
var oldInv = kot.Inventories.SingleOrDefault(x => x.Product.ProductID == productID && x.IsHappyHour == happyHour);
if (oldInv != null)
{
oldInv.Quantity += item.Value.inventory.Quantity;
@ -672,7 +677,7 @@ namespace Tanshu.Accounts.PointOfSale
Product = item.Value.inventory.Product,
Quantity = item.Value.inventory.Quantity,
Price = item.Value.inventory.Price,
FullPrice = item.Value.inventory.FullPrice,
IsHappyHour = item.Value.inventory.IsHappyHour,
Discount = item.Value.inventory.Discount,
ServiceCharge = item.Value.inventory.ServiceCharge,
IsScTaxable = item.Value.inventory.IsScTaxable,

@ -11,6 +11,7 @@ namespace Tanshu.Accounts.PointOfSale
public delegate void ItemChangedHandler();
public void Load(Voucher voucher)
{
this.Clear();
foreach (var kot in voucher.Kots)
{
var kotKey = new BillItemKey(kot.KotID);
@ -18,12 +19,13 @@ namespace Tanshu.Accounts.PointOfSale
this.Add(kotKey, kotItem);
foreach (var inv in kot.Inventories)
{
var key = new BillItemKey(inv.Product.ProductID, kot.KotID);
var key = new BillItemKey(inv.Product.ProductID, kot.KotID, inv.IsHappyHour);
var item = new BillItemValue(inv);
this.Add(key, item);
}
}
}
public decimal Tax
{
get
@ -35,7 +37,7 @@ namespace Tanshu.Accounts.PointOfSale
{
get
{
return this.Where(x => x.Key.BillItemType != BillItemType.Kot).Sum(i => i.Value.inventory.DiscountAmount);
return this.Where(x=>x.Key.BillItemType != BillItemType.Kot).Sum(i => i.Value.inventory.DiscountAmount);
}
}
public decimal ServiceCharge

@ -37,7 +37,6 @@
this.Label2 = new System.Windows.Forms.Label();
this.txtUnits = new System.Windows.Forms.TextBox();
this.txtName = new System.Windows.Forms.TextBox();
this.txtPrice = new System.Windows.Forms.TextBox();
this.cmbVat = new System.Windows.Forms.ComboBox();
this.bsVat = new System.Windows.Forms.BindingSource(this.components);
this.chkIsActive = new System.Windows.Forms.CheckBox();
@ -51,8 +50,8 @@
this.chkIsScTaxable = new System.Windows.Forms.CheckBox();
this.chkIsNotAvailable = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.txtFullPrice = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.txtPrice = new System.Windows.Forms.TextBox();
this.chkHasHappyHour = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.bsProductGroups)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.bsServiceTax)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.bsVat)).BeginInit();
@ -118,15 +117,6 @@
this.txtName.Size = new System.Drawing.Size(189, 20);
this.txtName.TabIndex = 0;
//
// txtPrice
//
this.txtPrice.AccessibleName = "";
this.txtPrice.Location = new System.Drawing.Point(112, 64);
this.txtPrice.Name = "txtPrice";
this.txtPrice.Size = new System.Drawing.Size(104, 20);
this.txtPrice.TabIndex = 3;
this.txtPrice.Text = "0";
//
// cmbVat
//
this.cmbVat.DataSource = this.bsVat;
@ -249,23 +239,24 @@
this.label1.TabIndex = 18;
this.label1.Text = "VAT";
//
// txtFullPrice
// txtPrice
//
this.txtFullPrice.AccessibleName = "";
this.txtFullPrice.Location = new System.Drawing.Point(112, 38);
this.txtFullPrice.Name = "txtFullPrice";
this.txtFullPrice.Size = new System.Drawing.Size(104, 20);
this.txtFullPrice.TabIndex = 2;
this.txtFullPrice.Text = "0";
this.txtPrice.AccessibleName = "";
this.txtPrice.Location = new System.Drawing.Point(112, 38);
this.txtPrice.Name = "txtPrice";
this.txtPrice.Size = new System.Drawing.Size(189, 20);
this.txtPrice.TabIndex = 2;
this.txtPrice.Text = "0";
//
// label3
// chkHasHappyHour
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(15, 67);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(91, 13);
this.label3.TabIndex = 16;
this.label3.Text = "Happy Hour Price";
this.chkHasHappyHour.AutoSize = true;
this.chkHasHappyHour.Location = new System.Drawing.Point(307, 40);
this.chkHasHappyHour.Name = "chkHasHappyHour";
this.chkHasHappyHour.Size = new System.Drawing.Size(105, 17);
this.chkHasHappyHour.TabIndex = 21;
this.chkHasHappyHour.Text = "Has Happy Hour";
this.chkHasHappyHour.UseVisualStyleBackColor = true;
//
// ProductForm
//
@ -273,8 +264,8 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(415, 285);
this.Controls.Add(this.txtFullPrice);
this.Controls.Add(this.label3);
this.Controls.Add(this.chkHasHappyHour);
this.Controls.Add(this.txtPrice);
this.Controls.Add(this.label1);
this.Controls.Add(this.chkIsNotAvailable);
this.Controls.Add(this.chkIsScTaxable);
@ -287,7 +278,6 @@
this.Controls.Add(this.chkIsActive);
this.Controls.Add(this.txtServiceCharge);
this.Controls.Add(this.Label7);
this.Controls.Add(this.txtPrice);
this.Controls.Add(this.lblServiceCharge);
this.Controls.Add(this.cmbVat);
this.Controls.Add(this.txtUnits);
@ -318,7 +308,6 @@
internal System.Windows.Forms.Label Label2;
internal System.Windows.Forms.TextBox txtUnits;
internal System.Windows.Forms.TextBox txtName;
internal System.Windows.Forms.TextBox txtPrice;
internal System.Windows.Forms.ComboBox cmbVat;
private System.Windows.Forms.CheckBox chkIsActive;
internal System.Windows.Forms.TextBox txtServiceCharge;
@ -332,7 +321,7 @@
private System.Windows.Forms.BindingSource bsVat;
private System.Windows.Forms.CheckBox chkIsNotAvailable;
internal System.Windows.Forms.Label label1;
internal System.Windows.Forms.TextBox txtFullPrice;
internal System.Windows.Forms.Label label3;
internal System.Windows.Forms.TextBox txtPrice;
private System.Windows.Forms.CheckBox chkHasHappyHour;
}
}

@ -29,7 +29,7 @@ namespace Tanshu.Accounts.PointOfSale
txtName.Text = product.Name;
txtUnits.Text = product.Units;
txtPrice.Text = product.Price.ToString("#.##");
txtFullPrice.Text = product.FullPrice.ToString("#.##");
chkHasHappyHour.Checked = product.HasHappyHour;
cmbVat.SelectedValue = product.Vat.TaxID;
cmbServiceTax.SelectedValue = product.ServiceTax.TaxID;
txtServiceCharge.Text = product.ServiceCharge.ToString("#.##");
@ -95,24 +95,6 @@ namespace Tanshu.Accounts.PointOfSale
else
product.Price = decimal.Parse(txtPrice.Text.Trim());
if (string.IsNullOrEmpty(txtFullPrice.Text.Trim()))
txtFullPrice.Text = "0";
if (!Regex.IsMatch(txtFullPrice.Text, @"^\d*([.]\d{1,5})?$"))
{
MessageBox.Show("Full Price is not valid, it must be a decimal >= 0");
txtFullPrice.Focus();
return;
}
else
product.FullPrice = decimal.Parse(txtFullPrice.Text.Trim());
if (product.FullPrice < product.Price)
{
MessageBox.Show("Full Price cannot be less than the actual price.");
txtFullPrice.Focus();
return;
}
// Tax
if (cmbVat.SelectedItem == null)
{

@ -126,6 +126,9 @@
<metadata name="bsVat.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>382, 17</value>
</metadata>
<metadata name="bsVat.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>382, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>102</value>
</metadata>

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Tanshu.Accounts.Repository;
using Tanshu.Accounts.Contracts;
@ -12,6 +13,7 @@ namespace Tanshu.Accounts.PointOfSale
public FrmSaleDetail()
{
InitializeComponent();
dgvSale.AutoGenerateColumns = false;
}
private void dtpStart_ValueChanged(object sender, EventArgs e)
@ -23,16 +25,18 @@ namespace Tanshu.Accounts.PointOfSale
{
if (DateTime.Today.Subtract(dtpStart.Value.Date).Days > 5 && !Session.IsAllowed("Accounts Audit"))
return;
_list = new ReportsBI().GetSaleDetail(dtpStart.Value, dtpFinish.Value);
dgvSale.AutoGenerateColumns = true;
var bi = new ReportsBI();
_list = bi.SaleQuantity(dtpStart.Value, dtpFinish.Value);
foreach (var item in bi.NcQuantity(dtpStart.Value, dtpFinish.Value))
{
var old = _list.FirstOrDefault(x => x.ProductID == item.ProductID);
if (old != null)
old.NC = item.NC;
else
_list.Add(new SalesAnalysisDetail() { Name = item.Name, ProductID = item.ProductID, NC = item.NC });
}
dgvSale.DataSource = _list;
dgvSale.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dgvSale.Columns[1].DefaultCellStyle.Format = "#,##0.00;(#,##0.00);0";
dgvSale.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
dgvSale.Columns[2].DefaultCellStyle.Format = "#,##0.00;(#,##0.00);0";
dgvSale.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
dgvSale.Columns[3].DefaultCellStyle.Format = "#,##0.00;(#,##0.00);0";
dgvSale.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
}
private void dtpFinish_ValueChanged(object sender, EventArgs e)
@ -65,10 +69,11 @@ namespace Tanshu.Accounts.PointOfSale
{
if (_list == null)
return;
var data = string.Format("{0}\t{1}\t{2}\t{3}\n", "Product", "Sale", "NC", "Staff");
var data = string.Format("{0}\t{1}\t{2}\t{3}\n", "ProductID", "Product", "Sale", "NC");
foreach (var item in _list)
{
data += string.Format("{0}\t{1}\t{2}\t{3}\n", item.Product, item.Sale, item.NC, item.Staff);
data += string.Format("{0}\t{1}\t{2}\t{3}\n", item.ProductID, item.Name, item.Sale, item.NC);
}
Clipboard.SetText(data, TextDataFormat.Text);
}

@ -28,6 +28,8 @@
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
this.dgvSale = new System.Windows.Forms.DataGridView();
this.dtpFinish = new System.Windows.Forms.DateTimePicker();
this.dtpStart = new System.Windows.Forms.DateTimePicker();
@ -35,6 +37,9 @@
this.btnPrint = new System.Windows.Forms.Button();
this.btnExport = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.NameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Sale = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.NC = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dgvSale)).BeginInit();
this.SuspendLayout();
//
@ -46,7 +51,12 @@
this.dgvSale.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dgvSale.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
this.dgvSale.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvSale.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.NameColumn,
this.Sale,
this.NC});
this.dgvSale.Location = new System.Drawing.Point(12, 41);
this.dgvSale.MultiSelect = false;
this.dgvSale.Name = "dgvSale";
@ -120,6 +130,34 @@
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// NameColumn
//
this.NameColumn.DataPropertyName = "Name";
this.NameColumn.HeaderText = "Name";
this.NameColumn.Name = "NameColumn";
this.NameColumn.ReadOnly = true;
this.NameColumn.Width = 60;
//
// Sale
//
this.Sale.DataPropertyName = "Sale";
dataGridViewCellStyle1.Format = "#,##0.00;(#,##0.00);0";
this.Sale.DefaultCellStyle = dataGridViewCellStyle1;
this.Sale.HeaderText = "Sale";
this.Sale.Name = "Sale";
this.Sale.ReadOnly = true;
this.Sale.Width = 53;
//
// NC
//
this.NC.DataPropertyName = "NC";
dataGridViewCellStyle2.Format = "#,##0.00;(#,##0.00);0";
this.NC.DefaultCellStyle = dataGridViewCellStyle2;
this.NC.HeaderText = "NC";
this.NC.Name = "NC";
this.NC.ReadOnly = true;
this.NC.Width = 47;
//
// FrmSaleDetail
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -152,5 +190,8 @@
private System.Windows.Forms.Button btnPrint;
private System.Windows.Forms.Button btnExport;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.DataGridViewTextBoxColumn NameColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn Sale;
private System.Windows.Forms.DataGridViewTextBoxColumn NC;
}
}

@ -117,4 +117,13 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="NameColumn.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Sale.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="NC.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

@ -30,6 +30,7 @@
{
this.flpModifier = new System.Windows.Forms.FlowLayoutPanel();
this.btnClose = new System.Windows.Forms.Button();
this.flpModifier.SuspendLayout();
this.SuspendLayout();
//
// flpModifier
@ -61,11 +62,13 @@
this.ControlBox = false;
this.Controls.Add(this.btnClose);
this.Controls.Add(this.flpModifier);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.MaximizeBox = false;
this.Name = "ModifierForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Modifier";
this.Load += new System.EventHandler(this.ModifierForm_Load);
this.flpModifier.ResumeLayout(false);
this.ResumeLayout(false);
}

@ -28,11 +28,14 @@ namespace Tanshu.Accounts.PointOfSale
private void button_Click(object sender, EventArgs e)
{
CheckBox button = sender as CheckBox;
if (button == null)
return;
if (button.CheckState == CheckState.Checked)
selection.Add(new InventoryModifier() { Modifier = (Modifier)button.Tag });
else
selection.Remove(selection.First(x => x.Modifier.ModifierID == ((Modifier)button.Tag).ModifierID));
}
private void ModifierForm_Load(object sender, EventArgs e)
{
var size = new Point(75, 75);
@ -70,6 +73,5 @@ namespace Tanshu.Accounts.PointOfSale
{
this.Close();
}
}
}

@ -218,7 +218,7 @@ namespace Tanshu.Accounts.PointOfSale.Sales
//
// quantityColumn
//
this.quantityColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.quantityColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.quantityColumn.DataPropertyName = "Quantity";
dgvCellStyleQuantity.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleRight;
dgvCellStyleQuantity.Format = "N2";
@ -344,7 +344,7 @@ namespace Tanshu.Accounts.PointOfSale.Sales
this.btnPrice.Name = "btnPrice";
this.btnPrice.Size = new System.Drawing.Size(75, 75);
this.btnPrice.TabIndex = 146;
this.btnPrice.Text = "btnPrice";
this.btnPrice.Text = "Price";
this.btnPrice.UseVisualStyleBackColor = true;
this.btnPrice.Click += new System.EventHandler(this.btnPrice_Click);
//

@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@ -355,7 +356,7 @@ namespace Tanshu.Accounts.PointOfSale.Sales
return;
_controller.AddProduct(item);
bindingSource.DataSource = _controller._bill.ToList();
bindingSource.CurrencyManager.Position = _controller._bill.IndexOfKey(new BillItemKey(item.ProductID, Guid.Empty));
bindingSource.CurrencyManager.Position = _controller._bill.IndexOfKey(new BillItemKey(item.ProductID, Guid.Empty, item.HasHappyHour));
var showModifier = false;
using (var bi = new ProductGroupModifierBI())

@ -123,6 +123,12 @@
<metadata name="bindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="Display.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="bindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>81</value>
</metadata>

@ -0,0 +1,119 @@
namespace Tanshu.Accounts.PointOfSale
{
partial class VoidReasonListForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.btnExit = new System.Windows.Forms.Button();
this.dgvVoidReasons = new System.Windows.Forms.DataGridView();
this.bsList = new System.Windows.Forms.BindingSource(this.components);
this.info = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dgvVoidReasons)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.bsList)).BeginInit();
this.SuspendLayout();
//
// btnExit
//
this.btnExit.AccessibleName = "Done";
this.btnExit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnExit.Location = new System.Drawing.Point(575, 255);
this.btnExit.Name = "btnExit";
this.btnExit.Size = new System.Drawing.Size(75, 75);
this.btnExit.TabIndex = 61;
this.btnExit.Text = "E&xit";
this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
//
// dgvVoidReasons
//
this.dgvVoidReasons.AllowUserToAddRows = false;
this.dgvVoidReasons.AllowUserToDeleteRows = false;
this.dgvVoidReasons.AllowUserToResizeRows = false;
this.dgvVoidReasons.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dgvVoidReasons.AutoGenerateColumns = false;
this.dgvVoidReasons.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
this.dgvVoidReasons.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvVoidReasons.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.info});
this.dgvVoidReasons.DataSource = this.bsList;
this.dgvVoidReasons.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this.dgvVoidReasons.Location = new System.Drawing.Point(12, 12);
this.dgvVoidReasons.MultiSelect = false;
this.dgvVoidReasons.Name = "dgvVoidReasons";
this.dgvVoidReasons.ReadOnly = true;
this.dgvVoidReasons.RowHeadersVisible = false;
this.dgvVoidReasons.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
this.dgvVoidReasons.RowTemplate.Height = 24;
this.dgvVoidReasons.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dgvVoidReasons.Size = new System.Drawing.Size(638, 237);
this.dgvVoidReasons.TabIndex = 74;
this.dgvVoidReasons.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvVoidReasons_CellDoubleClick);
this.dgvVoidReasons.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.dgvVoidReasons_CellFormatting);
//
// bsList
//
this.bsList.DataSource = typeof(string);
//
// info
//
this.info.HeaderText = "Info";
this.info.Name = "info";
this.info.ReadOnly = true;
this.info.Width = 50;
//
// VoidReasonListForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(662, 342);
this.Controls.Add(this.dgvVoidReasons);
this.Controls.Add(this.btnExit);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "VoidReasonListForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Customers";
this.Load += new System.EventHandler(this.VoidReasonListForm_Load);
((System.ComponentModel.ISupportInitialize)(this.dgvVoidReasons)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.bsList)).EndInit();
this.ResumeLayout(false);
}
#endregion
internal System.Windows.Forms.Button btnExit;
private System.Windows.Forms.DataGridView dgvVoidReasons;
private System.Windows.Forms.BindingSource bsList;
private System.Windows.Forms.DataGridViewTextBoxColumn Password;
private System.Windows.Forms.DataGridViewTextBoxColumn CustomerGroups;
private System.Windows.Forms.DataGridViewTextBoxColumn nameDataGridViewTextBoxColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn info;
}
}

@ -0,0 +1,60 @@
using System;
using System.Linq;
using System.Windows.Forms;
using Tanshu.Accounts.Entities;
using Tanshu.Accounts.Repository;
using System.Collections.Generic;
using Tanshu.Accounts.Entities.Auth;
using Tanshu.Accounts.Contracts;
namespace Tanshu.Accounts.PointOfSale
{
public partial class VoidReasonListForm : Form
{
private string[] _list;
public VoidReasonListForm(string[] list)
{
_list = list;
InitializeComponent();
}
private void VoidReasonListForm_Load(object sender, EventArgs e)
{
bsList.DataSource = _list;
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
public string SelectedItem
{
get
{
if (bsList.Position >= 0)
{
var item = _list[bsList.Position];
if (item != null)
return item;
}
return null;
}
}
private void dgvVoidReasons_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
this.Close();
}
private void dgvVoidReasons_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
var data = dgvVoidReasons.Rows[e.RowIndex].DataBoundItem as string;
if (e.ColumnIndex == dgvVoidReasons.Columns["Info"].Index)
{
e.Value = data;
}
}
}
}

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="info.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="bsList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

@ -194,6 +194,12 @@
<Compile Include="Masters\ReorderTableForm.Designer.cs">
<DependentUpon>ReorderTableForm.cs</DependentUpon>
</Compile>
<Compile Include="Sales\VoidReasonListForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Sales\VoidReasonListForm.Designer.cs">
<DependentUpon>VoidReasonListForm.cs</DependentUpon>
</Compile>
<Compile Include="Sales\CustomerListForm.cs">
<SubType>Form</SubType>
</Compile>
@ -377,6 +383,10 @@
<EmbeddedResource Include="Masters\ReorderTableForm.resx">
<DependentUpon>ReorderTableForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Sales\VoidReasonListForm.resx">
<DependentUpon>VoidReasonListForm.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Sales\CustomerListForm.resx">
<DependentUpon>CustomerListForm.cs</DependentUpon>
<SubType>Designer</SubType>

@ -28,7 +28,7 @@ namespace Tanshu.Accounts.Print
billText += DrawLine;
foreach (var item in billItems)
{
billText += string.Format("\n\r{0,6:#,##0.00} x {1,-33}", item.Quantity, Name(item.Product));
billText += string.Format("\n\r{0,6:#,##0.00} x {1,-33}", item.Quantity, item.EffectiveName);
foreach (var mod in item.InventoryModifier)
billText += string.Format("\n\r --- {0,-32}", mod.Modifier.Name);
}
@ -41,13 +41,6 @@ namespace Tanshu.Accounts.Print
return billText;
}
private static string Name(Product product)
{
return string.IsNullOrEmpty(product.Units)
? product.Name
: string.Format("{0} ({1})", product.Name, product.Units);
}
private static string FormatText(string inputString, int width, Align alignment)
{
if (inputString.Length > width)
@ -205,7 +198,7 @@ namespace Tanshu.Accounts.Print
printText += DrawLine;
foreach (var item in list)
{
printText += string.Format("\n\r{0,-22} {1,9:#,##0.00} {2,9:#,##0.00} {3,9:#,##0.00}", item.Product, item.Sale, item.NC, item.Staff);
printText += string.Format("\n\r{0,-22} {1,9:#,##0.00} {2,9:#,##0.00}", item.Name, item.Sale, item.NC);
}
printText += DrawEqual;
return PrintRaw(Cache.BasePrinter, printText, "Sale Detail " + user);

@ -20,6 +20,7 @@ namespace Tanshu.Accounts.Print
foreach (var item in voucher.Kots.SelectMany(kot => kot.Inventories))
{
int hash = item.Product.ProductID.GetHashCode();
hash = hash ^ item.IsHappyHour.GetHashCode();
foreach (var mod in item.InventoryModifier.Where(x => x.Modifier.ShowInBill))
{
hash = hash ^ mod.Modifier.ModifierID.GetHashCode();
@ -35,19 +36,19 @@ namespace Tanshu.Accounts.Print
billText += Products(voucher, list.Values.ToList());
decimal amount;
amount = list.Values.Sum(item => item.Quantity * item.FullPrice);
amount = list.Values.Sum(item => item.Quantity * item.Price);
if (amount != 0)
billText += "\n\r" + FormatText("Total : ", 33, Align.Right) + FormatBillNum(amount, 9);
amount = list.Values.Sum(item => item.Quantity * (item.FullPrice - item.Price));
amount = list.Values.Where(x=>x.IsHappyHour == true).Sum(item => item.Quantity * item.Price);
if (amount != 0)
billText += "\n\r" + FormatText("Happy Hour Discount : ", 33, Align.Right) + FormatBillNum(amount, 9);
amount = list.Values.Sum(item => item.Quantity * item.Price * item.Discount);
amount = list.Values.Sum(item => item.Quantity * item.EffectivePrice * item.Discount);
if (amount != 0)
billText += "\n\r" + FormatText("Discount : ", 33, Align.Right) + FormatBillNum(amount, 9);
amount = list.Values.Sum(item => item.Quantity * item.Price * (1 - item.Discount));
amount = list.Values.Sum(item => item.Quantity * item.EffectivePrice * (1 - item.Discount));
if (amount != 0)
{
billText += "\n\r" + FormatText(" : ", 33, Align.Right) + "---------";
@ -55,7 +56,7 @@ namespace Tanshu.Accounts.Print
}
amount = list.Values.Sum(item => item.Quantity * item.Price * (1 - item.Discount) * item.ServiceCharge);
amount = list.Values.Sum(item => item.Quantity * item.EffectivePrice * (1 - item.Discount) * item.ServiceCharge);
if (amount != 0)
billText += "\n\r" + FormatText("Service Charge : ", 33, Align.Right) + FormatBillNum(amount, 9);
@ -64,7 +65,7 @@ namespace Tanshu.Accounts.Print
select new
{
Tax = vat.Key,
Amount = vat.Sum(x => x.Quantity * x.Price * (1 - x.Discount) * (1 + x.ServiceCharge) * x.VatRate)
Amount = vat.Sum(x => x.VatAmount)
};
foreach (var item in vatList)
if (item.Amount != 0)
@ -75,7 +76,7 @@ namespace Tanshu.Accounts.Print
select new
{
Tax = serviceTax.Key,
Amount = serviceTax.Sum(x => x.Quantity * x.Price * (1 - x.Discount) * (1 + x.ServiceCharge) * x.ServiceTaxRate)
Amount = serviceTax.Sum(x => x.ServiceTaxAmount)
};
foreach (var item in stList)
if (item.Amount != 0)
@ -137,9 +138,9 @@ namespace Tanshu.Accounts.Print
foreach (var item in list.Where(item => item.Quantity != 0))
{
billText += "\n\r" + FormatBillNum(item.Quantity, 5) + " ";
billText += FormatText(Name(item.Product), 22, Align.Left) + " ";
billText += FormatBillNum(item.FullPrice, 6) + " ";
billText += FormatBillNum(item.FullPrice * item.Quantity, 6);
billText += FormatText(item.EffectiveName, 22, Align.Left) + " ";
billText += FormatBillNum(item.Price, 6) + " ";
billText += FormatBillNum(item.Price * item.Quantity, 6);
foreach (var mod in item.InventoryModifier.Where(x => x.Modifier.ShowInBill))
{
billText += "\n\r -- " + FormatText(mod.Modifier.Name, 38, Align.Left);

@ -77,6 +77,33 @@ namespace Tanshu.Accounts.Repository
}
_productGroups = list;
}
foreach (var item in _productGroups)
{
for (var i = item.Products.Count - 1; i >= 0; i--)
{
if (item.Products[i].HasHappyHour)
{
var product = item.Products[i];
product.HasHappyHour = false;
item.Products.Insert(i + 1, new Product() {
ProductID = product.ProductID,
Name = product.FullName,
Units = product.Units,
ProductGroup = product.ProductGroup,
Vat = product.Vat,
ServiceTax = product.ServiceTax,
ServiceCharge = product.ServiceCharge,
IsScTaxable = product.IsScTaxable,
Price = product.Price,
HasHappyHour = true,
IsActive = product.IsActive,
IsNotAvailable = product.IsNotAvailable,
SortOrder = product.SortOrder,
Quantity = product.Quantity
});
}
}
}
}
return _productGroups;
}

@ -29,7 +29,6 @@ namespace Tanshu.Accounts.Repository
#endregion
protected readonly ISession _session;
private IDictionary<SettleOption, IList<Voucher>> vList = new Dictionary<SettleOption, IList<Voucher>>();
public CheckoutBI(Guid cashier, DateTime startDate, DateTime finishDate)
{
_session = SessionManager.Session;

@ -636,9 +636,10 @@ where v.Date >= :startDate and v.Date <= :finishDate and i.VatRate = :vat and v.
{
get
{
var effectivePrice = IsHappyHour ? 0 : Price;
if (IsScTaxable)
return Quantity * Price * (1 - Discount) * (1 + ServiceCharge);
return Quantity * Price * (1 - Discount);
return Quantity * effectivePrice * (1 - Discount) * (1 + ServiceCharge);
return Quantity * effectivePrice * (1 - Discount);
}
}
}

@ -12,7 +12,7 @@ namespace Tanshu.Accounts.Repository
{
public class ReportsBI
{
public IList<SalesAnalysisDetail> GetSaleDetail(DateTime startDate, DateTime finishDate)
public IList<SalesAnalysisDetail> SaleQuantity(DateTime startDate, DateTime finishDate)
{
startDate = startDate.Date.AddHours(6);
finishDate = finishDate.Date.AddDays(1).AddHours(5);
@ -21,9 +21,8 @@ namespace Tanshu.Accounts.Repository
using (var session = SessionManager.Session)
{
#region Sale
var query = @"
select concat(p.Name, ' ', p.Units) as Product, Sum(i.Quantity) as Amount
const string query = @"
select p.ProductID, p.FullName, i.IsHappyHour, Sum(i.Quantity)
from Voucher v
inner join v.Kots k
inner join k.Inventories i
@ -31,75 +30,56 @@ inner join i.Product p
inner join p.ProductGroup pg
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false
and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v
and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amount and vs.Settled != :roundoff and vs.Settled != :staff)
group by concat(p.Name, ' ', p.Units), p.ProductGroup, pg.GroupType
order by pg.GroupType, p.ProductGroup, concat(p.Name, ' ', p.Units)
and vs.Settled in (:cash, :creditCard, :billToCompany, :staff))
group by p.ProductID, p.FullName, i.IsHappyHour, p.ProductGroup, pg.GroupType
order by pg.GroupType, p.ProductGroup, p.FullName, i.IsHappyHour
";
var list = session
.CreateQuery(query)
.SetParameter("startDate", startDate)
.SetParameter("finishDate", finishDate)
.SetParameter("cash", SettleOption.Cash)
.SetParameter("creditCard", SettleOption.CreditCard)
.SetParameter("billToCompany", SettleOption.BillToCompany)
.SetParameter("staff", SettleOption.Staff)
.List<object[]>();
var outList = new List<SalesAnalysisDetail>();
foreach (var item in list)
outList.Add(new SalesAnalysisDetail() { ProductID = (Guid)item[0], Name = (string)item[1], IsHappyHour = (bool)item[2], Sale = (decimal)item[3] });
return outList;
}
}
public IList<SalesAnalysisDetail> NcQuantity(DateTime startDate, DateTime finishDate)
{
startDate = startDate.Date.AddHours(6);
finishDate = finishDate.Date.AddDays(1).AddHours(5);
if (finishDate <= startDate)
return new List<SalesAnalysisDetail>();
using (var session = SessionManager.Session)
{
const string query = @"
select p.ProductID, p.FullName, i.IsHappyHour, Sum(i.Quantity)
from Voucher v
inner join v.Kots k
inner join k.Inventories i
inner join i.Product p
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false
and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled = :noCharge)
group by p.ProductID, p.FullName, i.IsHappyHour
";
var list = session
.CreateQuery(query)
.SetParameter("startDate", startDate)
.SetParameter("finishDate", finishDate)
.SetParameter("noCharge", SettleOption.NoCharge)
.SetParameter("unsettled", SettleOption.Unsettled)
.SetParameter("amount", SettleOption.Amount)
.SetParameter("roundoff", SettleOption.RoundOff)
.SetParameter("staff", SettleOption.Staff)
.List<object[]>();
var outList = new OrderedDictionary<string, SalesAnalysisDetail>();
.List<object[]>(); var outList = new List<SalesAnalysisDetail>();
foreach (var item in list)
outList.Add((string)item[0], new SalesAnalysisDetail() { Product = (string)item[0], Sale = (decimal)item[1] });
#endregion
#region NC
query = @"
select concat(p.Name, ' ', p.Units) as Product, Sum(i.Quantity) as Amount
from Voucher v
inner join v.Kots k
inner join k.Inventories i
inner join i.Product p
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false
and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled = :noCharge)
group by concat(p.Name, ' ', p.Units), p.ProductGroup
order by p.ProductGroup, concat(p.Name, ' ', p.Units)
";
list = session
.CreateQuery(query)
.SetParameter("startDate", startDate)
.SetParameter("finishDate", finishDate)
.SetParameter("noCharge", SettleOption.NoCharge)
.List<object[]>();
foreach (var item in list)
if (outList.ContainsKey((string)item[0]))
outList[(string)item[0]].NC = (decimal)item[1];
else
outList.Add((string)item[0], new SalesAnalysisDetail() { Product = (string)item[0], NC = (decimal)item[1] });
#endregion
#region Staff
query = @"
select concat(p.Name, ' ', p.Units) as Product, Sum(i.Quantity) as Amount
from Voucher v
inner join v.Kots k
inner join k.Inventories i
inner join i.Product p
where v.Date >= :startDate and v.Date <= :finishDate and v.Void = false
and exists (select Voucher from VoucherSettlement vs where vs.Voucher = v and vs.Settled = :staff)
group by concat(p.Name, ' ', p.Units), p.ProductGroup
order by p.ProductGroup, concat(p.Name, ' ', p.Units)
";
list = session
.CreateQuery(query)
.SetParameter("startDate", startDate)
.SetParameter("finishDate", finishDate)
.SetParameter("staff", SettleOption.Staff)
.List<object[]>();
foreach (var item in list)
if (outList.ContainsKey((string)item[0]))
outList[(string)item[0]].Staff = (decimal)item[1];
else
outList.Add((string)item[0], new SalesAnalysisDetail() { Product = (string)item[0], Staff = (decimal)item[1] });
#endregion
return outList.Values.ToList();
outList.Add(new SalesAnalysisDetail() { ProductID = (Guid)item[0], Name = (string)item[1], IsHappyHour = (bool)item[2], NC = (decimal)item[3] });
return outList;
}
}
public IList<BillDetail> GetBillDetails(DateTime startDate, DateTime finishDate)
{
startDate = startDate.Date.AddHours(6);
@ -157,7 +137,7 @@ order by p.ProductGroup, concat(p.Name, ' ', p.Units)
using (var session = SessionManager.Session)
{
const string query = @"
select pg.GroupType, sum(i.Quantity * i.Price * i.Discount)
select pg.GroupType, sum(i.Quantity * i.EffectivePrice * i.Discount)
from Inventory i
inner join i.Kot k
inner join k.Voucher v

@ -22,7 +22,7 @@ namespace Tanshu.Accounts.Repository
public IList<SalesAnalysis> GetSale(DateTime startDate, DateTime finishDate)
{
const string query = @"
select g.GroupType as GroupType, Sum(i.Quantity * i.Price * (1 - i.Discount)) as Amount
select g.GroupType as GroupType, Sum(i.Quantity * i.EffectivePrice * (1 - i.Discount)) as Amount
from Voucher v
inner join v.Kots k
inner join k.Inventories i
@ -82,7 +82,7 @@ order by s.Settled
public SalesAnalysis GetServiceCharge(DateTime startDate, DateTime finishDate)
{
var query = @"
select coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * i.ServiceCharge), 0)
select coalesce(Sum(i.Quantity * i.EffectivePrice * (1 - i.Discount) * i.ServiceCharge), 0)
from Voucher v
inner join v.Kots k
inner join k.Inventories i
@ -108,8 +108,8 @@ and vs.Settled != :noCharge and vs.Settled != :unsettled and vs.Settled != :amou
{
var outList = new List<TaxAnalysis>();
var query = @"
select i.ServiceTaxRate, coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.ServiceTaxRate), 0),
coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), 0)
select i.ServiceTaxRate, coalesce(Sum(i.Quantity * i.EffectivePrice * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.ServiceTaxRate), 0),
coalesce(Sum(i.Quantity * i.EffectivePrice * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), 0)
from Voucher v
inner join v.Kots k
inner join k.Inventories i
@ -135,8 +135,8 @@ group by i.ServiceTaxRate";
{
var outList = new List<TaxAnalysis>();
var query = @"
select va.Name, i.VatRate, coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.VatRate), 0),
coalesce(Sum(i.Quantity * i.Price * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), 0)
select va.Name, i.VatRate, coalesce(Sum(i.Quantity * i.EffectivePrice * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end) * i.VatRate), 0),
coalesce(Sum(i.Quantity * i.EffectivePrice * (1 - i.Discount) * (1 + case when i.IsScTaxable then i.ServiceCharge else 0 end)), 0)
from Voucher v
inner join v.Kots k
inner join k.Inventories i