Добавить GuestBill.cs
Пречек без процентов скидок-надбавок. Только название и сумма
This commit is contained in:
674
GuestBill.cs
Normal file
674
GuestBill.cs
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
@using System
|
||||||
|
@using System.Collections.Generic
|
||||||
|
@using System.Globalization
|
||||||
|
@using System.Linq
|
||||||
|
@using Resto.Front.PrintTemplates.Cheques.Razor
|
||||||
|
@using Resto.Front.PrintTemplates.Cheques.Razor.TemplateModels
|
||||||
|
|
||||||
|
@inherits TemplateBase<IBillCheque>
|
||||||
|
@{
|
||||||
|
var order = Model.Order;
|
||||||
|
}
|
||||||
|
|
||||||
|
<doc>
|
||||||
|
@* Header (begin) *@
|
||||||
|
|
||||||
|
@if (Model.AdditionalServiceChequeInfo == null)
|
||||||
|
{
|
||||||
|
if (Model.RepeatBillNumber == 0)
|
||||||
|
{
|
||||||
|
<center>@Resources.BillHeaderTitle</center>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<center>@string.Format(Resources.RepeateBillHeaderTitleFormat, Model.RepeatBillNumber)</center>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<pair left="@string.Format(Resources.BillHeaderSectionPattern, order.Table.Section.Name)" right="@string.Format(Resources.BillHeaderTablePattern, order.Table.Number)" />
|
||||||
|
<pair left="@string.Format(Resources.BillHeaderOrderOpenPattern, FormatLongDateTime(order.OpenTime))" right="@string.Format(Resources.BillHeaderOrderNumberPattern, order.Number)" />
|
||||||
|
|
||||||
|
@if (Model.AdditionalServiceChequeInfo != null)
|
||||||
|
{
|
||||||
|
<left>@string.Format(Resources.AdditionalServiceHeaderOrderItemsAddedPattern, FormatLongDateTime(Model.CommonInfo.CurrentTime))</left>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (!string.IsNullOrWhiteSpace(order.ExternalNumber))
|
||||||
|
{
|
||||||
|
<left>@string.Format(Resources.BillHeaderOrderExternalNumberPattern, order.ExternalNumber)</left>
|
||||||
|
}
|
||||||
|
|
||||||
|
<left>@string.Format(Resources.BillHeaderWaiterPattern, order.Waiter.GetNameOrEmpty())</left>
|
||||||
|
|
||||||
|
@foreach (var clientInfo in
|
||||||
|
from discountItem in order.DiscountItems
|
||||||
|
where discountItem.CardInfo != null
|
||||||
|
select discountItem.CardInfo into cardInfo
|
||||||
|
select string.IsNullOrWhiteSpace(cardInfo.MaskedCard) ? cardInfo.Owner : string.Format("{0} ({1})", cardInfo.Owner, cardInfo.MaskedCard) into clientInfo
|
||||||
|
where !string.IsNullOrWhiteSpace(clientInfo)
|
||||||
|
select clientInfo)
|
||||||
|
{
|
||||||
|
<left>@string.Format(Resources.ClientFormat, clientInfo)</left>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.AdditionalServiceChequeInfo == null)
|
||||||
|
{
|
||||||
|
<whitespace-preserve>@Raw(string.Join(Environment.NewLine, Model.Extensions.AfterHeader))</whitespace-preserve>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Model.AdditionalServiceChequeInfo != null)
|
||||||
|
{
|
||||||
|
if (order.ClientBinding != null && !string.IsNullOrWhiteSpace(order.ClientBinding.CardNumber))
|
||||||
|
{
|
||||||
|
<left>@string.Format(Resources.CardPattern, order.ClientBinding.CardNumber)</left>
|
||||||
|
}
|
||||||
|
<np />
|
||||||
|
<center>@Resources.AdditionalServiceHeaderTitle</center>
|
||||||
|
}
|
||||||
|
@* Header (end) *@
|
||||||
|
|
||||||
|
@* Body (begin) *@
|
||||||
|
<table>
|
||||||
|
<columns>
|
||||||
|
<column />
|
||||||
|
<column align="right" autowidth="" />
|
||||||
|
<column width="2" />
|
||||||
|
<column align="right" autowidth="" />
|
||||||
|
</columns>
|
||||||
|
<cells>
|
||||||
|
@Guests()
|
||||||
|
<linecell />
|
||||||
|
@Summaries()
|
||||||
|
</cells>
|
||||||
|
</table>
|
||||||
|
@* Body (end) *@
|
||||||
|
|
||||||
|
@* Footer (begin) *@
|
||||||
|
<np />
|
||||||
|
@if (Model.AdditionalServiceChequeInfo == null)
|
||||||
|
{
|
||||||
|
<whitespace-preserve>@Raw(string.Join(Environment.NewLine, Model.Extensions.BeforeFooter))</whitespace-preserve>
|
||||||
|
}
|
||||||
|
<center><split><whitespace-preserve>@Model.CommonInfo.CafeSetup.BillFooter</whitespace-preserve></split></center>
|
||||||
|
<np />
|
||||||
|
<np />
|
||||||
|
@if (Model.AdditionalServiceChequeInfo == null)
|
||||||
|
{
|
||||||
|
<whitespace-preserve>@Raw(string.Join(Environment.NewLine, Model.Extensions.AfterFooter))</whitespace-preserve>
|
||||||
|
}
|
||||||
|
<np />
|
||||||
|
@* Footer (end) *@
|
||||||
|
</doc>
|
||||||
|
|
||||||
|
@helper Guests()
|
||||||
|
{
|
||||||
|
var order = Model.Order;
|
||||||
|
Func<IOrderItem, bool> orderItemsFilter;
|
||||||
|
if (Model.AdditionalServiceChequeInfo != null)
|
||||||
|
{
|
||||||
|
orderItemsFilter = orderItem => Model.AdditionalServiceChequeInfo.AddedOrderItems.Contains(orderItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
orderItemsFilter = orderItem => orderItem.DeletionInfo == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var guestsWithItems = Model.Order.Table.Section.DisplayGuests
|
||||||
|
? order.Guests.Select(guest => new
|
||||||
|
{
|
||||||
|
Guest = guest,
|
||||||
|
Items = guest.Items.Where(item => orderItemsFilter(item) && OrderItemsToPrintFilter(item, order.DiscountItems) && OrderItemsPrechequePrintableFilter(item))
|
||||||
|
})
|
||||||
|
.Where(guestWithItems => guestWithItems.Items.Any()).ToList()
|
||||||
|
: EnumerableEx.Return(new
|
||||||
|
{
|
||||||
|
Guest = order.Guests.FirstOrDefault(),
|
||||||
|
Items = order.Guests.SelectMany(g => g.Items.Where(item => orderItemsFilter(item) && OrderItemsToPrintFilter(item, order.DiscountItems) && OrderItemsPrechequePrintableFilter(item)))
|
||||||
|
})
|
||||||
|
.Where(guestWithItems => guestWithItems.Items.Any()).ToList();
|
||||||
|
|
||||||
|
if (!guestsWithItems.Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
<linecell />
|
||||||
|
<ct>@Resources.NameColumnHeader</ct>
|
||||||
|
<ct>@Resources.ProductAmount</ct>
|
||||||
|
<ct />
|
||||||
|
<ct>@Resources.ResultSum</ct>
|
||||||
|
<linecell />
|
||||||
|
|
||||||
|
if (guestsWithItems.Count == 1)
|
||||||
|
{
|
||||||
|
@SingleGuest(guestsWithItems.Single().Items.ToList())
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@OneOfMultipleGuests(guestsWithItems.First().Guest, guestsWithItems.First().Items.ToList())
|
||||||
|
foreach (var guestWithItems in guestsWithItems.Skip(1))
|
||||||
|
{
|
||||||
|
<linecell symbols=" " />
|
||||||
|
@OneOfMultipleGuests(guestWithItems.Guest, guestWithItems.Items.ToList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@helper SingleGuest(IEnumerable<IOrderItem> items)
|
||||||
|
{
|
||||||
|
foreach (var comboGroup in items.OrderBy(i => i.OrderRank).GroupBy(i => i.Combo))
|
||||||
|
{
|
||||||
|
var combo = comboGroup.Key;
|
||||||
|
var isPartOfCombo = combo != null;
|
||||||
|
var additionalSpace = isPartOfCombo ? " " : string.Empty;
|
||||||
|
if (isPartOfCombo)
|
||||||
|
{
|
||||||
|
<ct>@combo.Name</ct>
|
||||||
|
<ct>@FormatAmount(combo.Amount)</ct>
|
||||||
|
<ct />
|
||||||
|
<ct>@FormatMoney(combo.Price * combo.Amount)</ct>
|
||||||
|
}
|
||||||
|
foreach (var orderItemGroup in comboGroup.OrderBy(item => item.OrderRank).GroupBy(_ => _, CreateComparer<IOrderItem>(AreOrderItemsEqual)))
|
||||||
|
{
|
||||||
|
var totalAmount = orderItemGroup.Sum(orderItem => orderItem.Amount);
|
||||||
|
var totalCost = orderItemGroup.Sum(orderItem => orderItem.Cost);
|
||||||
|
|
||||||
|
var productItem = orderItemGroup.Key as IProductItem;
|
||||||
|
if (productItem != null && productItem.CompoundsInfo != null && productItem.CompoundsInfo.IsPrimaryComponent)
|
||||||
|
{
|
||||||
|
<ct><whitespace-preserve>@(additionalSpace + string.Format("{0} {1}", productItem.CompoundsInfo.ModifierSchemaName, productItem.ProductSize == null ? string.Empty : productItem.ProductSize.Name))</whitespace-preserve></ct>
|
||||||
|
<c colspan="3" />
|
||||||
|
|
||||||
|
// для разделенной пиццы комменты печатаем под схемой
|
||||||
|
if (Model.Order.Table.Section.PrintProductItemCommentInCheque && productItem.Comment != null && !productItem.Comment.Deleted)
|
||||||
|
{
|
||||||
|
<c>
|
||||||
|
<table cellspacing="0">
|
||||||
|
<columns>
|
||||||
|
<column width="2" />
|
||||||
|
<column />
|
||||||
|
</columns>
|
||||||
|
<cells>
|
||||||
|
<c />
|
||||||
|
<c><split><whitespace-preserve>@(additionalSpace + productItem.Comment.Text)</whitespace-preserve></split></c>
|
||||||
|
</cells>
|
||||||
|
</table>
|
||||||
|
</c>
|
||||||
|
<c colspan="3" />
|
||||||
|
}
|
||||||
|
|
||||||
|
// у пиццы не может быть удаленных модификаторов, поэтому берем весь список
|
||||||
|
foreach (var orderEntry in productItem.ModifierEntries.Where(orderEntry => ModifiersFilter(orderEntry, productItem, true)))
|
||||||
|
{
|
||||||
|
var productName = orderEntry.ProductCustomName ?? orderEntry.Product.Name;
|
||||||
|
<ct><whitespace-preserve>@(additionalSpace + " " + productName)</whitespace-preserve></ct>
|
||||||
|
|
||||||
|
if (orderEntry.Amount != 1m)
|
||||||
|
{
|
||||||
|
<ct>@FormatAmount(orderEntry.Amount)</ct>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<ct />
|
||||||
|
}
|
||||||
|
<ct />
|
||||||
|
|
||||||
|
if (orderEntry.Cost != 0m)
|
||||||
|
{
|
||||||
|
<ct>@FormatMoney(orderEntry.Cost)</ct>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<ct />
|
||||||
|
}
|
||||||
|
|
||||||
|
@PrintOrderEntryAllergens(orderEntry)
|
||||||
|
@CategorizedDiscountsForOrderEntryGroup(new[] { orderEntry }, isPartOfCombo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productItem != null && productItem.CompoundsInfo != null)
|
||||||
|
{
|
||||||
|
<ct><whitespace-preserve>@(additionalSpace + " 1/2 " + GetOrderEntryNameWithProductSize(productItem))</whitespace-preserve></ct>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<ct><whitespace-preserve>@(additionalSpace + GetOrderEntryNameWithProductSize(orderItemGroup.Key))</whitespace-preserve></ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
<ct>@FormatAmount(totalAmount)</ct>
|
||||||
|
if (!isPartOfCombo)
|
||||||
|
{
|
||||||
|
<ct />
|
||||||
|
<ct>@FormatMoney(totalCost)</ct>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<c colspan="2" />
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productItem != null)
|
||||||
|
{
|
||||||
|
@PrintOrderEntryAllergens(productItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
@CategorizedDiscountsForOrderEntryGroup(orderItemGroup.ToList<IOrderEntry>(), isPartOfCombo)
|
||||||
|
|
||||||
|
// здесь комменты для обычных блюд и целых пицц
|
||||||
|
if (Model.Order.Table.Section.PrintProductItemCommentInCheque && productItem != null && productItem.Comment != null && !productItem.Comment.Deleted && productItem.CompoundsInfo == null)
|
||||||
|
{
|
||||||
|
<c>
|
||||||
|
<table cellspacing="0">
|
||||||
|
<columns>
|
||||||
|
<column width="2" />
|
||||||
|
<column />
|
||||||
|
</columns>
|
||||||
|
<cells>
|
||||||
|
<c />
|
||||||
|
<c><split><whitespace-preserve>@(additionalSpace + productItem.Comment.Text)</whitespace-preserve></split></c>
|
||||||
|
</cells>
|
||||||
|
</table>
|
||||||
|
</c>
|
||||||
|
<c colspan="3" />
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var orderEntry in orderItemGroup.Key.GetNotDeletedChildren().Where(orderEntry => ModifiersFilter(orderEntry, orderItemGroup.Key)).ToList())
|
||||||
|
{
|
||||||
|
var productName = orderEntry.ProductCustomName ?? orderEntry.Product.Name;
|
||||||
|
<ct><whitespace-preserve>@(additionalSpace + " " + productName)</whitespace-preserve></ct>
|
||||||
|
|
||||||
|
if (orderEntry.Amount != 1m)
|
||||||
|
{
|
||||||
|
<ct>@FormatAmount(orderEntry.Amount)</ct>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<ct />
|
||||||
|
}
|
||||||
|
<ct />
|
||||||
|
|
||||||
|
if (orderEntry.Cost != 0m)
|
||||||
|
{
|
||||||
|
<ct>@FormatMoney(orderEntry.Cost)</ct>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<ct />
|
||||||
|
}
|
||||||
|
|
||||||
|
@PrintOrderEntryAllergens(orderEntry)
|
||||||
|
@CategorizedDiscountsForOrderEntryGroup(new[] { orderEntry }, isPartOfCombo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@helper CategorizedDiscountsForOrderEntryGroup(ICollection<IOrderEntry> entries, bool isPartOfCombo)
|
||||||
|
{
|
||||||
|
var orderEntry = entries.First();
|
||||||
|
var additionalSpace = isPartOfCombo ? " " : string.Empty;
|
||||||
|
if (orderEntry.Cost != 0m)
|
||||||
|
{
|
||||||
|
var categorizedDiscounts = from discountItem in Model.Order.DiscountItems
|
||||||
|
where discountItem.IsCategorized && discountItem.PrintDetailedInPrecheque
|
||||||
|
let discountSum = entries.Sum(entry => discountItem.GetDiscountSumFor(entry))
|
||||||
|
where discountSum != 0m
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
IsDiscount = discountSum > 0m,
|
||||||
|
Sum = Math.Abs(discountSum),
|
||||||
|
Percent = Math.Abs(CalculatePercent(entries.Sum(entry => entry.Cost), discountSum)),
|
||||||
|
Name = discountItem.Type.PrintableName,
|
||||||
|
discountItem.Type.DiscountBySum
|
||||||
|
} into discount
|
||||||
|
orderby discount.IsDiscount descending
|
||||||
|
select discount;
|
||||||
|
|
||||||
|
foreach (var categorizedDiscount in categorizedDiscounts)
|
||||||
|
{
|
||||||
|
<c colspan="3">
|
||||||
|
<whitespace-preserve>@(additionalSpace + GetFormattedDiscountDescriptionForOrderItem(categorizedDiscount.IsDiscount, categorizedDiscount.Name, categorizedDiscount.DiscountBySum, categorizedDiscount.Percent))</whitespace-preserve>
|
||||||
|
</c>
|
||||||
|
<ct>@GetFormattedDiscountSum(categorizedDiscount.IsDiscount, categorizedDiscount.Sum)</ct>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@helper OneOfMultipleGuests(IGuest guest, ICollection<IOrderItem> items)
|
||||||
|
{
|
||||||
|
<c colspan="0">@guest.Name</c>
|
||||||
|
@SingleGuest(items)
|
||||||
|
<c colspan="3" />
|
||||||
|
<c><line /></c>
|
||||||
|
|
||||||
|
var includedEntries = items.SelectMany(item => item.ExpandIncludedEntries()).ToList();
|
||||||
|
var total = includedEntries.Sum(orderEntry => orderEntry.Cost);
|
||||||
|
var totalWithoutCategorizedDiscounts = total - (from orderEntry in includedEntries
|
||||||
|
from discountItem in Model.Order.DiscountItems
|
||||||
|
where discountItem.IsCategorized
|
||||||
|
select discountItem.GetDiscountSumFor(orderEntry)).Sum();
|
||||||
|
|
||||||
|
var totalWithoutDiscounts = totalWithoutCategorizedDiscounts - (from orderEntry in includedEntries
|
||||||
|
from discountItem in Model.Order.DiscountItems
|
||||||
|
where !discountItem.IsCategorized
|
||||||
|
select discountItem.GetDiscountSumFor(orderEntry)).Sum();
|
||||||
|
|
||||||
|
if (totalWithoutCategorizedDiscounts != totalWithoutDiscounts)
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.BillFooterTotalPlain</c>
|
||||||
|
<ct>@FormatMoney(totalWithoutCategorizedDiscounts)</ct>
|
||||||
|
|
||||||
|
var nonCategorizedDiscounts = from discountItem in Model.Order.DiscountItems
|
||||||
|
where !discountItem.IsCategorized
|
||||||
|
let discountSum = includedEntries.Sum(orderEntry => discountItem.GetDiscountSumFor(orderEntry))
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
IsDiscount = discountSum > 0m,
|
||||||
|
Sum = Math.Abs(discountSum),
|
||||||
|
Percent = Math.Abs(CalculatePercent(includedEntries.Sum(entry => entry.Cost), discountSum)),
|
||||||
|
Name = discountItem.Type.PrintableName,
|
||||||
|
discountItem.Type.DiscountBySum
|
||||||
|
} into discount
|
||||||
|
orderby discount.IsDiscount descending
|
||||||
|
select discount;
|
||||||
|
|
||||||
|
foreach (var nonCategorizedDiscount in nonCategorizedDiscounts)
|
||||||
|
{
|
||||||
|
<c colspan="3">
|
||||||
|
@(nonCategorizedDiscount.DiscountBySum
|
||||||
|
? GetFormattedDiscountDescriptionShort(nonCategorizedDiscount.IsDiscount, nonCategorizedDiscount.Name)
|
||||||
|
: GetFormattedDiscountDescriptionDetailed(nonCategorizedDiscount.IsDiscount, nonCategorizedDiscount.Name, nonCategorizedDiscount.Percent))
|
||||||
|
</c>
|
||||||
|
<ct>@GetFormattedDiscountSum(nonCategorizedDiscount.IsDiscount, nonCategorizedDiscount.Sum)</ct>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<c colspan="3">@string.Format(Model.AdditionalServiceChequeInfo == null ? Resources.BillFooterTotalGuestPattern : Resources.AdditionalServiceFooterTotalGuestPattern, guest.Name)</c>
|
||||||
|
<ct>@FormatMoney(totalWithoutDiscounts)</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
@helper Summaries()
|
||||||
|
{
|
||||||
|
var order = Model.Order;
|
||||||
|
var fullSum = order.GetFullSum() - order.DiscountItems.Where(di => !di.Type.PrintProductItemInPrecheque).Sum(di => di.GetDiscountSum());
|
||||||
|
var categorizedDiscountItems = new List<IDiscountItem>();
|
||||||
|
var nonCategorizedDiscountItems = new List<IDiscountItem>();
|
||||||
|
|
||||||
|
foreach (var discountItem in order.DiscountItems.Where(di => di.Type.PrintProductItemInPrecheque && di.DiscountSums.Count > 0))
|
||||||
|
{
|
||||||
|
if (discountItem.IsCategorized)
|
||||||
|
{
|
||||||
|
categorizedDiscountItems.Add(discountItem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nonCategorizedDiscountItems.Add(discountItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var subTotal = fullSum - categorizedDiscountItems.Sum(di => di.GetDiscountSum());
|
||||||
|
var totalWithoutDiscounts = subTotal - nonCategorizedDiscountItems.Sum(di => di.GetDiscountSum());
|
||||||
|
var prepay = order.PrePayments.Sum(prepayItem => prepayItem.Sum);
|
||||||
|
var total = Math.Max(totalWithoutDiscounts + order.GetVatSumExcludedFromPrice() - prepay, 0m);
|
||||||
|
|
||||||
|
if (Model.DiscountMarketingCampaigns != null)
|
||||||
|
{
|
||||||
|
total -= Model.DiscountMarketingCampaigns.TotalDiscount;
|
||||||
|
totalWithoutDiscounts -= Model.DiscountMarketingCampaigns.TotalDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
var vatSumsByVat = (Model.AdditionalServiceChequeInfo == null
|
||||||
|
? order.GetIncludedEntries()
|
||||||
|
: Model.AdditionalServiceChequeInfo.AddedOrderItems.SelectMany(item => item.ExpandIncludedEntries()))
|
||||||
|
.Where(orderEntry => !orderEntry.VatIncludedInPrice)
|
||||||
|
.GroupBy(orderEntry => orderEntry.Vat)
|
||||||
|
.Where(group => group.Key != 0m)
|
||||||
|
.Select(group => new { Vat = group.Key, Sum = group.Sum(orderEntry => orderEntry.ExcludedVat) })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var vatSum = vatSumsByVat.Sum(vatWithSum => vatWithSum.Sum);
|
||||||
|
|
||||||
|
if ((prepay != 0m || fullSum != total) && Model.AdditionalServiceChequeInfo == null)
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.BillFooterFullSum</c>
|
||||||
|
<ct>@FormatMoney(fullSum)</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
@PrintOrderDiscounts(categorizedDiscountItems, fullSum)
|
||||||
|
|
||||||
|
if (categorizedDiscountItems.Any())
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.BillFooterTotalPlain</c>
|
||||||
|
<ct>@FormatMoney(subTotal)</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
@PrintOrderDiscounts(nonCategorizedDiscountItems, fullSum)
|
||||||
|
|
||||||
|
if (Model.DiscountMarketingCampaigns != null)
|
||||||
|
{
|
||||||
|
foreach (var discountMarketingCampaign in Model.DiscountMarketingCampaigns.Campaigns)
|
||||||
|
{
|
||||||
|
<c colspan="3">@discountMarketingCampaign.Name</c>
|
||||||
|
<ct>@("-" + FormatMoney(discountMarketingCampaign.TotalDiscount))</ct>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prepay != 0m && (categorizedDiscountItems.Any() || nonCategorizedDiscountItems.Any()))
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.BillFooterTotalWithoutDiscounts</c>
|
||||||
|
<ct>@FormatMoney(totalWithoutDiscounts)</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vatSum != 0m)
|
||||||
|
{
|
||||||
|
foreach (var vatWithSum in vatSumsByVat)
|
||||||
|
{
|
||||||
|
<c colspan="3">@string.Format(Resources.VatFormat, vatWithSum.Vat)</c>
|
||||||
|
<ct>@string.Format(FormatMoney(vatWithSum.Sum))</ct>
|
||||||
|
}
|
||||||
|
if (vatSumsByVat.Count > 1)
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.VatSum</c>
|
||||||
|
<ct>@FormatMoney(vatSum)</ct>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Model.AdditionalServiceChequeInfo != null)
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.AdditionalServiceAddedFooterTotalUpper</c>
|
||||||
|
<ct>@FormatMoney(Model.AdditionalServiceChequeInfo.AddedOrderItems.SelectMany(item => item.ExpandIncludedEntries()).Sum(orderEntry => orderEntry.Cost) + vatSum)</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prepay != 0m)
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.Prepay</c>
|
||||||
|
<ct>@FormatMoney(prepay)</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
<c colspan="3">@(Model.AdditionalServiceChequeInfo == null ? Resources.BillFooterTotal : Resources.AdditionalServiceFooterTotalUpper)</c>
|
||||||
|
<ct>@FormatMoney(total)</ct>
|
||||||
|
foreach (var rate in order.FixedCurrencyRates)
|
||||||
|
{
|
||||||
|
var currencyIsoName = rate.Key.IsoName;
|
||||||
|
var defaultCurrencyIsoName = Model.CommonInfo.CafeSetup.CurrencyIsoName;
|
||||||
|
<c colspan="2">
|
||||||
|
<right>
|
||||||
|
@string.Format(Resources.CurrencyRateFormat, currencyIsoName, rate.Value.ToString("f4", CultureInfo.CurrentCulture), defaultCurrencyIsoName)
|
||||||
|
</right>
|
||||||
|
</c>
|
||||||
|
<ct />
|
||||||
|
<ct>@string.Format(Resources.CurrencyFormat, currencyIsoName, FormatMoney(GetSumInAdditionalCurrency(rate.Key, rate.Value, total), currencyIsoName))</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Model.AdditionalServiceChequeInfo != null && order.ClientBinding != null && order.ClientBinding.PaymentLimit.HasValue)
|
||||||
|
{
|
||||||
|
<c colspan="3">@Resources.AdditionalServiceLimit</c>
|
||||||
|
<ct>@FormatMoney(order.ClientBinding.PaymentLimit.Value - total)</ct>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Model.DiscountMarketingCampaigns != null)
|
||||||
|
{
|
||||||
|
foreach (var discountMarketingCampaign in Model.DiscountMarketingCampaigns.Campaigns.Where(campaign => !string.IsNullOrWhiteSpace(campaign.BillComment)))
|
||||||
|
{
|
||||||
|
<c colspan="4">@discountMarketingCampaign.BillComment</c>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@helper PrintOrderDiscounts(IEnumerable<IDiscountItem> discountItems, decimal fullSum)
|
||||||
|
{
|
||||||
|
foreach (var discountItem in discountItems.OrderByDescending(discountItem => discountItem.IsDiscount()))
|
||||||
|
{
|
||||||
|
<c colspan="3">
|
||||||
|
@GetFormattedDiscountDescriptionShort(discountItem.IsDiscount(), discountItem.Type.PrintableName)
|
||||||
|
</c>
|
||||||
|
<ct>@GetFormattedDiscountSum(discountItem.IsDiscount(), Math.Abs(discountItem.GetDiscountSum()))</ct>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@helper PrintOrderEntryAllergens(IOrderEntry orderEntry)
|
||||||
|
{
|
||||||
|
var totalAllergens = orderEntry.Allergens.ToArray();
|
||||||
|
if (totalAllergens.Any())
|
||||||
|
{
|
||||||
|
<c colspan="0">@( string.Format(Resources.AllergenGroupsFormat, string.Join(", ", totalAllergens)) )</c>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@functions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Отфильтровывает флаерные блюда, для которых нет настройки "Печать в пречеке блюд по флаеру"
|
||||||
|
/// </summary>
|
||||||
|
private static bool OrderItemsToPrintFilter(IOrderItem orderItem, IEnumerable<IDiscountItem> discountItems)
|
||||||
|
{
|
||||||
|
return !(orderItem is IProductItem) || discountItems
|
||||||
|
.Where(discountItem => discountItem.DiscountSums.ContainsKey(orderItem))
|
||||||
|
.All(discountItem => discountItem.Type.PrintProductItemInPrecheque);
|
||||||
|
}
|
||||||
|
private static bool OrderItemsPrechequePrintableFilter(IOrderItem orderItem)
|
||||||
|
{
|
||||||
|
if (orderItem.Cost != 0m)
|
||||||
|
return true;
|
||||||
|
return orderItem.Product.PrechequePrintable;
|
||||||
|
}
|
||||||
|
private bool AreOrderItemsEqual(IOrderItem x, IOrderItem y)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(x, y))
|
||||||
|
return true;
|
||||||
|
if (x == null)
|
||||||
|
return y == null;
|
||||||
|
if (y == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var xProductItem = x as IProductItem;
|
||||||
|
var yProductItem = y as IProductItem;
|
||||||
|
|
||||||
|
if (xProductItem == null || yProductItem == null || !ProductItemCanBeMerged(xProductItem) || !ProductItemCanBeMerged(yProductItem))
|
||||||
|
return false;
|
||||||
|
if (xProductItem.Product.Name != yProductItem.Product.Name)
|
||||||
|
return false;
|
||||||
|
if (xProductItem.ProductCustomName != yProductItem.ProductCustomName)
|
||||||
|
return false;
|
||||||
|
if (xProductItem.ProductSize == null ^ yProductItem.ProductSize == null)
|
||||||
|
return false;
|
||||||
|
if (xProductItem.ProductSize != null && yProductItem.ProductSize != null && xProductItem.ProductSize.Name != yProductItem.ProductSize.Name)
|
||||||
|
return false;
|
||||||
|
if (xProductItem.Price != yProductItem.Price)
|
||||||
|
return false;
|
||||||
|
if (xProductItem.Price == 0m)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var categorizedDiscounts = Model.Order.DiscountItems
|
||||||
|
.Where(discountItem => discountItem.IsCategorized && discountItem.PrintDetailedInPrecheque && discountItem.DiscountSums.Count > 0)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var xCategorizedDiscountItems = categorizedDiscounts.Where(discountItem => discountItem.DiscountSums.ContainsKey(x));
|
||||||
|
var yCategorizedDiscountItems = categorizedDiscounts.Where(discountItem => discountItem.DiscountSums.ContainsKey(y));
|
||||||
|
|
||||||
|
return new HashSet<IDiscountItem>(xCategorizedDiscountItems).SetEquals(yCategorizedDiscountItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProductItemCanBeMerged(IProductItem productItem)
|
||||||
|
{
|
||||||
|
return productItem.CompoundsInfo == null &&
|
||||||
|
productItem.Amount - Math.Truncate(productItem.Amount) == 0m &&
|
||||||
|
productItem.GetNotDeletedChildren().Where(orderEntry => ModifiersFilter(orderEntry, productItem)).IsEmpty() &&
|
||||||
|
(productItem.Comment == null || productItem.Comment.Deleted || !Model.Order.Table.Section.PrintProductItemCommentInCheque);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CommonModifiersFilter(bool isCommonModifier, IProductItem parent, bool onlyCommonModifiers)
|
||||||
|
{
|
||||||
|
if (parent.CompoundsInfo != null && parent.CompoundsInfo.IsPrimaryComponent)
|
||||||
|
{
|
||||||
|
if (onlyCommonModifiers && !isCommonModifier)
|
||||||
|
return false;
|
||||||
|
if (!onlyCommonModifiers && isCommonModifier)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ModifiersFilter(IOrderEntry orderEntry, IOrderItem parent, bool onlyCommonModifiers = false)
|
||||||
|
{
|
||||||
|
var parentProductItem = parent as IProductItem;
|
||||||
|
if (parentProductItem != null && !CommonModifiersFilter(((IModifierEntry)orderEntry).IsCommonModifier, parentProductItem, onlyCommonModifiers))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (orderEntry.Cost > 0m)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!orderEntry.Product.PrechequePrintable)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var modifierEntry = orderEntry as IModifierEntry;
|
||||||
|
if (modifierEntry == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (modifierEntry.ChildModifier == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!modifierEntry.ChildModifier.HideIfDefaultAmount)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var amountPerItem = modifierEntry.ChildModifier.AmountIndependentOfParentAmount
|
||||||
|
? modifierEntry.Amount
|
||||||
|
: modifierEntry.Amount / GetParentAmount(parent, onlyCommonModifiers);
|
||||||
|
|
||||||
|
return amountPerItem != modifierEntry.ChildModifier.DefaultAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFormattedDiscountDescriptionForOrderItem(bool isDiscount, string discountName, bool discountBySum, decimal absolutePercent)
|
||||||
|
{
|
||||||
|
return string.Format(" {0}", discountName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFormattedDiscountDescriptionShort(bool isDiscount, string discountName)
|
||||||
|
{
|
||||||
|
return string.Format(discountName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFormattedDiscountDescriptionDetailed(bool isDiscount, string discountName, decimal absolutePercent)
|
||||||
|
{
|
||||||
|
return string.Format(discountName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFormattedDiscountSum(bool isDiscount, decimal absoluteSum)
|
||||||
|
{
|
||||||
|
return (isDiscount ? "-" : "+") + FormatMoney(absoluteSum);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetOrderEntryNameWithProductSize(IOrderEntry orderEntry)
|
||||||
|
{
|
||||||
|
var productName = orderEntry.ProductCustomName ?? orderEntry.Product.Name;
|
||||||
|
var productItem = orderEntry as IProductItem;
|
||||||
|
return (productItem == null || productItem.ProductSize == null || productItem.CompoundsInfo != null)
|
||||||
|
? productName
|
||||||
|
: string.Format(Resources.ProductNameWithSizeFormat, productName, productItem.ProductSize.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static decimal GetParentAmount(IOrderItem parent, bool onlyCommonModifiers)
|
||||||
|
{
|
||||||
|
return onlyCommonModifiers ? parent.Amount * 2 : parent.Amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user