Hi,
Below is my Repository code.
namespace iwms.Transactions.Repositories
{
using Serenity;
using Serenity.Data;
using Serenity.Services;
using System;
using System.Data;
using MyRow = Entities.WorkOrderRow;
public class WorkOrderRepository
{
private static MyRow.RowFields fld { get { return MyRow.Fields; } }
public SaveResponse Create(IUnitOfWork uow, SaveRequest<MyRow> request)
{
return new MySaveHandler().Process(uow, request, SaveRequestType.Create);
}
public SaveResponse Update(IUnitOfWork uow, SaveRequest<MyRow> request)
{
return new MySaveHandler().Process(uow, request, SaveRequestType.Update);
}
public DeleteResponse Delete(IUnitOfWork uow, DeleteRequest request)
{
return new MyDeleteHandler().Process(uow, request);
}
public RetrieveResponse<MyRow> Retrieve(IDbConnection connection, RetrieveRequest request)
{
return new MyRetrieveHandler().Process(connection, request);
}
public ListResponse<MyRow> List(IDbConnection connection, ListRequest request)
{
return new MyListHandler().Process(connection, request);
}
private class MySaveHandler : SaveRequestHandler<MyRow>
{
protected override void AfterSave()
{
base.AfterSave();
if (Row.Items != null)
{
var mc = Entities.WorkOrderDetailRow.Fields;
var oldList = IsCreate ? null : Connection.List<Entities.WorkOrderDetailRow>(mc.WorkOrderId == this.Row.WorkOrderId.Value);
new Common.DetailListSaveHandler<Entities.WorkOrderDetailRow>(oldList, Row.Items, x => x.WorkOrderId = Row.WorkOrderId.Value).Process(this.UnitOfWork);
foreach (var item in Row.Items)
{
updateInventory(item);
}
}
}
private void updateInventory(Entities.WorkOrderDetailRow item)
{
var inv = Entities.InventoryRow.Fields;
Int32 tTypeId = getTransactionTypeId("WorkOrders");
var invRow = Connection.TryFirst<Entities.InventoryRow>(q => q
.Select(inv.StockOnHand)
.Select(inv.StockIn)
.Where(
inv.ItemId == item.ItemId.Value &
inv.StoreId == item.StoreId.Value)
//inv.TransactionTypeId == tTypeId)
.OrderBy(inv.InventoryDate, desc: true));
if (invRow != null)
{
if(item.Quantity.Value <= invRow.StockOnHand)
{
invRow.StoreId = item.StoreId.Value;
invRow.ItemId = item.ItemId.Value;
invRow.StockOnHand = invRow.StockOnHand - item.Quantity.Value;
invRow.StockIn = item.Quantity.Value;
invRow.StockOut = 0;
invRow.InventoryDate = DateTime.Now.Date;
invRow.TransactionTypeId = tTypeId;
}
else
{
}
}
Connection.Insert(invRow);
}
private Int32 getTransactionTypeId(String tTypeName)
{
var tType = MasterData.Entities.TransactionTypeRow.Fields;
var transactionTypeRow = Connection.TryFirst<MasterData.Entities.TransactionTypeRow>(t => t
.Select(tType.TransactionTypeId)
.Where(tType.TransactionTypeName == tTypeName));
Int32 tTypeId = 0;
if (transactionTypeRow != null)
{
tTypeId = transactionTypeRow.TransactionTypeId.Value;
}
return tTypeId;
}
}
private class MyDeleteHandler : DeleteRequestHandler<MyRow> { }
private class MyRetrieveHandler : RetrieveRequestHandler<MyRow>
{
protected override void OnReturn()
{
base.OnReturn();
var mc = Entities.ReturningItemRow.Fields;
Row.Items = Connection.List<Entities.ReturningItemRow>(q => q
.SelectTableFields()
.Select(mc.ItemId)
.Select(mc.ItemItemNo)
.Select(mc.ItemItemName)
.Select(mc.StoreId)
.Select(mc.StoreStoreName)
.Select(mc.Quantity)
.Where(mc.ReturnId == Row.ReturnId.Value));
}
}
private class MyListHandler : ListRequestHandler<MyRow> { }
}
}
Inside the updateInventory(), at the else block, I want to be able to show an alert box on the interface informing the user that Quantity of items are greater than the stock in the store. Can anyone guide me on the right code snippet from both server and client side to solve this?
if (invRow != null)
{
if(item.Quantity.Value <= invRow.StockOnHand)
{
invRow.StoreId = item.StoreId.Value;
invRow.ItemId = item.ItemId.Value;
invRow.StockOnHand = invRow.StockOnHand - item.Quantity.Value;
invRow.StockIn = item.Quantity.Value;
invRow.StockOut = 0;
invRow.InventoryDate = DateTime.Now.Date;
invRow.TransactionTypeId = tTypeId;
}
else
{
}
}
on the client side (typically in the validateEntity(row, id)) :
if ( ...) {
Q.alert('Application Date already listed !');
return false;
}
You could throw an exception on server side
Dialogs are a bit better:
Q.confirm(' Remove Record ?', () => {
TduObrasService.Delete({
EntityId: item.CduId,
}, response => {
this.refresh();
});
});
@brunobola. One quick question. I I have to fields. One is Quantity and the other is Stock On Hand. When I enter the quantity on the form, I want to be able to retrieve the StockOnHand in the database and compare to the Quantity value. If Quantity value is greater than the stock on hand, I want to show a message to the user that quantity should be less or equal to the Stock On Hnad.
This is a master-detail scenario and this particular logic is occuring in memory at the detail form dialog. I want to carry out this logic inside the ValidateEntity method. Below is the Typescript file.
///
namespace iwms.Transactions {
@Serenity.Decorators.registerEditor()
export class WorkOrderDetailEditor
extends Common.GridEditorBase
protected getColumnsKey() { return "Transactions.WorkOrderDetail"; }
protected getDialogType() { return WorkOrderDetailEditDialog; }
protected getLocalTextPrefix() { return WorkOrderDetailRow.localTextPrefix; }
constructor(container: JQuery) {
super(container);
}
protected getAddButtonCaption() {
return "Add Item";
}
protected validateEntity(row: WorkOrderDetailRow, id: number) {
if (!super.validateEntity(row, id))
return false;
row.ItemItemNo = MasterData.ItemRow.getLookup().itemById[row.ItemId].ItemNo;
row.ItemItemName = MasterData.ItemRow.getLookup().itemById[row.ItemId].ItemName;
row.StoreStoreName = MasterData.StoreRow.getLookup().itemById[row.StoreId].StoreName;
//InventoryService.Retrieve()
return true;
}
}
}
@gfo2007 see https://github.com/volkanceylan/Serenity/issues/381
@brunobola the answer is pretty verbose and confusing. I have created method in my endpoint as below.
namespace iwms.Transactions.Endpoints
{
using iwms.Transactions.Entities;
using Serenity;
using Serenity.Data;
using Serenity.Services;
using System.Data;
using System.Web.Mvc;
using MyRepository = Repositories.WorkOrderDetailRepository;
using MyRow = Entities.WorkOrderDetailRow;
[RoutePrefix("Services/Transactions/WorkOrderDetail"), Route("{action}")]
[ConnectionKey(typeof(MyRow)), ServiceAuthorize(typeof(MyRow))]
public class WorkOrderDetailController : ServiceEndpoint
{
[HttpPost, AuthorizeCreate(typeof(MyRow))]
public SaveResponse Create(IUnitOfWork uow, SaveRequest<MyRow> request)
{
return new MyRepository().Create(uow, request);
}
[HttpPost, AuthorizeUpdate(typeof(MyRow))]
public SaveResponse Update(IUnitOfWork uow, SaveRequest<MyRow> request)
{
return new MyRepository().Update(uow, request);
}
[HttpPost, AuthorizeDelete(typeof(MyRow))]
public DeleteResponse Delete(IUnitOfWork uow, DeleteRequest request)
{
return new MyRepository().Delete(uow, request);
}
[HttpPost]
public RetrieveResponse<MyRow> Retrieve(IDbConnection connection, RetrieveRequest request)
{
return new MyRepository().Retrieve(connection, request);
}
[HttpPost]
public ListResponse<MyRow> List(IDbConnection connection, ListRequest request)
{
return new MyRepository().List(connection, request);
}
public int RetrieveStock(IDbConnection connection, ListRequest request)
{
var stockOnHand = 0;
var invRow = connection.TryFirst<Entities.InventoryRow>(q => q
.Select(InventoryRow.Fields.StockOnHand)
.Where(
InventoryRow.Fields.ItemId == WorkOrderDetailRow.Fields.ItemId &
InventoryRow.Fields.StoreId == WorkOrderDetailRow.Fields.StoreId)
//inv.TransactionTypeId == tTypeId)
.OrderBy(InventoryRow.Fields.InventoryDate, desc: true));
if(invRow != null)
{
stockOnHand = invRow.StockOnHand.Value;
}
return stockOnHand;
}
}
}
I want to call this service on the client side and get the Id in the return object. Could you please show me how to do this successfully?
How do you call RetrieveStock?
MyRowService.RetrieveStock(
{ MyId: this.get_entityId(),}, response => { Q.notifySuccess("Success! ", '', null) });
@Zahar661 RetrieveStock returns an integer value (StockOnHand) which I need at the client side for some logic. So I want to be able to get that value.
The response is showing a notification of success, blank or null. How do I pass the return object to a variable and use it in the client side. Pardon my ignorance. I am very new to javascript and typescript.
MyService.MyAction({.....}, response => {
Q.notifyInfo('Rezultat: ' + (response.Rezult|| 0));
});
Look for GetNextNumberResponse class in GetNextNumberRequest.cs which is installed with the Serene template
Thanks everyone for your contribution and help. After sitting on it through the weekend, I have what I needed picking bits and pieces of clues from your suggestions.