protected virtual ScanLine FindLine(ScanHeader header, Func <ScanLine, bool> search)
        {
            var existLines = LinesView.SelectMain().Where(t =>
                                                          t.InventoryID == header.InventoryID &&
                                                          t.SiteID == header.SiteID &&
                                                          t.ToSiteID == header.ToSiteID
                                                          //&& t.LocationID == (header.LocationID ?? t.LocationID)
                                                          && t.ReasonCode == (header.ReasonCode ?? t.ReasonCode) &&
                                                          t.UOM == header.UOM &&
                                                          (search == null || search(t)));

            ScanLine existLine = null;

            if (IsLotSerialRequired && SplitsView != null)
            {
                foreach (var line in existLines)
                {
                    LinesView.Current = line;
                    if (SplitsView.SelectMain().Any(t => (t.LotSerialNbr ?? "") == (header.LotSerialNbr ?? "")))
                    {
                        existLine = line;
                        break;
                    }
                }
            }
            else
            {
                existLine = existLines.FirstOrDefault();
            }
            return(existLine);
        }
        protected virtual INCartSplit SyncWithCart(ScanHeader header, decimal?qty)
        {
            INCartSplit cartSplit = CartSplits.Search <INCartSplit.inventoryID, INCartSplit.subItemID, INCartSplit.fromLocationID, INCartSplit.lotSerialNbr>(
                header.InventoryID, header.SubItemID, header.LocationID, string.IsNullOrEmpty(header.LotSerialNbr) ? null : header.LotSerialNbr);

            if (cartSplit == null)
            {
                cartSplit = CartSplits.Insert(new INCartSplit
                {
                    CartID         = header.CartID,
                    InventoryID    = header.InventoryID,
                    SubItemID      = header.SubItemID,
                    LotSerialNbr   = header.LotSerialNbr,
                    ExpireDate     = header.ExpireDate,
                    UOM            = header.UOM,
                    SiteID         = header.SiteID,
                    FromLocationID = header.LocationID,
                    Qty            = qty
                });
            }
            else
            {
                var copy = (INCartSplit)CartSplits.Cache.CreateCopy(cartSplit);
                copy.Qty += qty;
                cartSplit = CartSplits.Update(copy);

                if (cartSplit.Qty == 0)
                {
                    cartSplit = CartSplits.Delete(cartSplit);
                }
            }

            return(cartSplit);
        }
        protected override INRegister SyncWithDocument(ScanHeader header)
        {
            var cache = Base.Caches <INRegister>();

            if (Register == null)
            {
                cache.Insert();
            }

            cache.SetValueExt <INRegister.siteID>(Register, header.SiteID);
            cache.SetValueExt <INRegister.toSiteID>(Register, header.ToSiteID);
            return((INRegister)cache.Update(Register));
        }
        protected virtual bool EnsureSplitsLotSerial(string userLotSerial, ScanHeader header, Action rollbackAction, out WMSFlowStatus flowStatus)
        {
            if (!string.IsNullOrEmpty(userLotSerial) &&
                SplitsView != null &&
                SplitsView.SelectMain().Any(s => s.LotSerialNbr != userLotSerial))
            {
                flowStatus = WMSFlowStatus.Fail(Msg.QtyIssueExceedsQtyOnLot, userLotSerial,
                                                HeaderView.Cache.GetValueExt <ScanHeader.inventoryID>(header));

                rollbackAction();

                SetScanState(MainCycleStartState);

                return(false);
            }
            flowStatus = WMSFlowStatus.Ok;
            return(true);
        }
        protected override void SyncWithDocumentCart(ScanHeader header, ScanLine line, INCartSplit cartSplit, decimal?qty)
        {
            INRegisterCart registerCart = RegisterCart.Current;

            if (registerCart == null)
            {
                registerCart = RegisterCart.Insert();
            }

            RegisterCart.Cache.SetValue <INRegisterCart.docType>(registerCart, Register.DocType);
            RegisterCart.Cache.SetValue <INRegisterCart.refNbr>(registerCart, Register.RefNbr);

            SyncWithDocumentCartLine(header, line, cartSplit, qty);

            if (IsEmptyCart)
            {
                RegisterCart.Delete(registerCart);
            }
        }
        protected virtual void ConfirmCartIn()
        {
            WMSFlowStatus Implementation()
            {
                WMSFlowStatus status;

                if (!ValidateConfirmation(out status))
                {
                    return(status);
                }

                ScanHeader header        = CurrentHeader;
                bool       isSerialItem  = header.LotSerTrack == INLotSerTrack.SerialNumbered;
                var        userLotSerial = header.LotSerialNbr;

                TScanDocument doc       = SyncWithDocument(header);
                ScanLine      existLine = FindFixedLineFromCart(header);

                if (!SyncWithLines(header, header.Qty, ref existLine, out status))
                {
                    return(status);
                }

                INCartSplit cartSplit = SyncWithCart(header, header.Qty);

                SyncWithDocumentCart(header, existLine, cartSplit, header.Qty);

                Report(Msg.InventoryAdded, LinesView.Cache.GetValueExt <ScanLine.inventoryID>(existLine), header.Qty, header.UOM);

                OnCartInConfirmed();

                return(WMSFlowStatus.Ok.WithPostAction(() => SetQtyOverridable(!isSerialItem)));
            }

            using (var ts = new PXTransactionScope())
            {
                var res = ExecuteAndCompleteFlow(Implementation);
                if (res.IsError == false)
                {
                    ts.Complete();
                }
            }
        }
        protected virtual bool EnsureSplitsLocation(int?userLocationID, ScanHeader header, Action rollbackAction, out WMSFlowStatus flowStatus)
        {
            if (IsLocationRequired &&
                SplitsView != null &&
                SplitsView.SelectMain().Any(s => s.LocationID != userLocationID))
            {
                flowStatus = WMSFlowStatus.Fail(Msg.QtyIssueExceedsQtyOnLocation,
                                                HeaderView.Cache.GetValueExt <ScanHeader.locationID>(header),
                                                HeaderView.Cache.GetValueExt <ScanHeader.inventoryID>(header));

                rollbackAction();

                SetScanState(MainCycleStartState);

                return(false);
            }
            flowStatus = WMSFlowStatus.Ok;
            return(true);
        }
        protected virtual void SyncWithDocumentCartLine(ScanHeader header, ScanLine line, INCartSplit cartSplit, decimal?qty)
        {
            bool emptyLine = line.Qty.GetValueOrDefault() == 0;

            INRegisterCartLine docCartLine = RegisterCartLines.Search <INRegisterCartLine.lineNbr>(line.LineNbr);

            if (docCartLine == null)
            {
                if (qty <= 0)
                {
                    throw new PXArgumentException(nameof(qty));
                }
                docCartLine = RegisterCartLines.Insert();
                RegisterCartLines.Cache.SetValue <INRegisterCartLine.cartSplitLineNbr>(docCartLine, cartSplit.SplitLineNbr);
            }
            docCartLine      = (INRegisterCartLine)RegisterCartLines.Cache.CreateCopy(docCartLine);
            docCartLine.Qty += qty;
            RegisterCartLines.Cache.Update(docCartLine);

            if (docCartLine.Qty == 0)
            {
                RegisterCartLines.Delete(docCartLine);
            }
        }
        protected virtual void MoveToCart()
        {
            WMSFlowStatus Implementation()
            {
                WMSFlowStatus status;

                if (!ValidateConfirmation(out status))
                {
                    return(status);
                }

                ScanHeader header       = CurrentHeader;
                bool       isSerialItem = header.LotSerTrack == INLotSerTrack.SerialNumbered;
                decimal?   confirmQty   = header.Qty;

                ScanLine existLine = FindLineFromDocument(header);

                if (existLine == null)
                {
                    return(LineMissingStatus());
                }

                if (!SyncWithLines(CurrentHeader, -confirmQty, ref existLine, out status))
                {
                    return(status);
                }

                HeaderSetter.Set(x => x.LocationID, existLine.LocationID);
                HeaderSetter.Set(x => x.ToLocationID, existLine.LocationID);
                HeaderSetter.Set(x => x.SiteID, existLine.SiteID);
                HeaderSetter.Set(x => x.LotSerialNbr, existLine.LotSerialNbr);
                HeaderSetter.Set(x => x.ReasonCode, existLine.ReasonCode);
                HeaderSetter.Set(x => x.ExpireDate, existLine.ExpireDate);
                HeaderSetter.Set(x => x.SubItemID, existLine.SubItemID);

                //put item to the cart
                existLine = FindFixedLineFromCart(CurrentHeader);
                if (!SyncWithLines(CurrentHeader, confirmQty, ref existLine, out status))
                {
                    return(status);
                }

                INCartSplit cartSplit = SyncWithCart(CurrentHeader, confirmQty);

                SyncWithDocumentCart(CurrentHeader, existLine, cartSplit, confirmQty);

                Report(Msg.InventoryRemoved, LinesView.Cache.GetValueExt <ScanLine.inventoryID>(existLine), confirmQty);

                OnMovedToCart();

                return(WMSFlowStatus.Ok.WithPostAction(() => SetQtyOverridable(!isSerialItem)));
            };
            using (var ts = new PXTransactionScope())
            {
                var res = ExecuteAndCompleteFlow(Implementation);
                if (res.IsError == false)
                {
                    ts.Complete();
                }
            }
        }
Beispiel #10
0
        protected virtual bool SyncWithLines(ScanHeader header, decimal?qty, ref ScanLine line, out WMSFlowStatus flowStatus)
        {
            var      linesCache     = LinesView.Cache;
            Action   rollbackAction = null;
            ScanLine existLine      = line;

            if (existLine != null)
            {
                decimal?newQty = existLine.Qty + qty;

                var backup = linesCache.CreateCopy(existLine) as ScanLine;
                if (newQty == 0)
                {
                    //remove
                    linesCache.SetValueExt <ScanLine.qty>(existLine, newQty);
                    existLine      = (ScanLine)linesCache.Delete(existLine);
                    rollbackAction = () =>
                    {
                        linesCache.Insert(backup);
                    };
                }
                else
                {
                    if (CurrentHeader.LotSerTrack == INLotSerTrack.SerialNumbered && newQty != 1)
                    {
                        flowStatus = WMSFlowStatus.Fail(Msg.SerialItemNotComplexQty);
                        return(false);
                    }

                    linesCache.SetValueExt <ScanLine.qty>(existLine, newQty);
                    linesCache.SetValueExt <ScanLine.lotSerialNbr>(existLine, null);
                    existLine = (ScanLine)linesCache.Update(existLine);

                    linesCache.SetValueExt <INTran.lotSerialNbr>(existLine, header.LotSerialNbr);
                    existLine = (ScanLine)linesCache.Update(existLine);

                    rollbackAction = () =>
                    {
                        linesCache.Delete(existLine);
                        linesCache.Insert(backup);
                    };
                }
            }
            else
            {
                if (qty < 0)
                {
                    flowStatus = LineMissingStatus();
                    return(false);
                }
                existLine = (ScanLine)linesCache.Insert();
                linesCache.SetValueExt <ScanLine.inventoryID>(existLine, header.InventoryID);
                linesCache.SetValueExt <ScanLine.siteID>(existLine, header.SiteID);
                linesCache.SetValueExt <ScanLine.toSiteID>(existLine, header.ToSiteID);
                linesCache.SetValueExt <ScanLine.locationID>(existLine, header.LocationID);
                linesCache.SetValueExt <ScanLine.toLocationID>(existLine, header.ToLocationID);
                linesCache.SetValueExt <ScanLine.uOM>(existLine, header.UOM);
                linesCache.SetValueExt <ScanLine.reasonCode>(existLine, header.ReasonCode);
                existLine = (ScanLine)linesCache.Update(existLine);

                linesCache.SetValueExt <INTran.qty>(existLine, qty);
                existLine = (ScanLine)linesCache.Update(existLine);

                linesCache.SetValueExt <INTran.lotSerialNbr>(existLine, header.LotSerialNbr);
                existLine = (ScanLine)linesCache.Update(existLine);

                rollbackAction = () => linesCache.Delete(existLine);
            }

            if (!VerifyConfirmedLine(header, existLine, rollbackAction, out flowStatus))
            {
                return(false);
            }

            flowStatus = WMSFlowStatus.Ok;
            line       = existLine;
            return(true);
        }
Beispiel #11
0
 protected virtual bool VerifyConfirmedLine(ScanHeader header, ScanLine line, Action rollbackAction, out WMSFlowStatus flowStatus)
 => EnsureSplitsLotSerial(header.LotSerialNbr, header, rollbackAction, out flowStatus) &&
 (header.Remove == true || EnsureSplitsLocation(header.LocationID, header, rollbackAction, out flowStatus));
Beispiel #12
0
 protected virtual ScanLine FindLineFromDocument(ScanHeader header)
 => FindLine(header, line =>
             line.LocationID == header.LocationID &&
             line.ToLocationID == header.ToLocationID &&
             GetCartQty(line) == null);
Beispiel #13
0
 protected virtual ScanLine FindAnyLineFromCart(ScanHeader header)
 => FindLine(header,
             line => GetCartQty(line) != null);
Beispiel #14
0
 protected abstract TScanDocument SyncWithDocument(ScanHeader header);
Beispiel #15
0
 protected virtual void SyncWithDocumentCart(ScanHeader header, ScanLine line, INCartSplit cartSplit, decimal?qty)
 => SyncWithDocumentCart(HeaderView.Cache.GetMain(header) as TWMSHeader, LinesView.Cache.GetMain(line) as TScanLine, cartSplit, qty);