private void UpdateStock(ProductStock ps, Node storedNode, string comment)
        {
            if (!string.IsNullOrEmpty(ps.Bin.BinCode))
            {
                try { ps.Bin = Factory.DaoBin().Select(ps.Bin).First(); }
                catch (Exception ex)
                { //El bin no Existe
                    //Console.WriteLine(ps.Product.ProductCode + " => " + ps.Bin.BinCode);
                    Console.WriteLine(ex.Message);
                    //Console.ReadKey();
                    Status active = Factory.DaoStatus().Select(new Status {
                        StatusID = EntityStatus.Active
                    }).First();
                    ps.Bin.CreatedBy    = WmsSetupValues.SystemUser;
                    ps.Bin.CreationDate = DateTime.Now;
                    ps.Bin.IsFromErp    = true;
                    ps.Bin.Status       = active;
                    ps.Bin.Rank         = 0;
                    Console.WriteLine("Creating Bin: " + ps.Bin.BinCode);
                    ps.Bin = Factory.DaoBin().Save(ps.Bin);
                }
            }
            else
            {
                ps.Bin = WType.GetBin(new Bin {
                    BinCode = DefaultBin.MAIN, Location = ps.Bin.Location
                });
            }

            //Procesando el Stock.
            DocumentLine line = new DocumentLine
            {
                Product   = ps.Product,
                Quantity  = ps.Stock,
                Unit      = ps.Product.BaseUnit,
                CreatedBy = WmsSetupValues.SystemUser
            };

            (new TransactionMngr()).IncreaseQtyIntoBin(line, storedNode, ps.Bin, comment, true, DateTime.Now, null, null);
        }
        //Process the lines to Print - OBSOLETE
        public String GetReplacedTemplate(IList <DocumentBalance> printList, LabelTemplate template, string printLot, UserByRol userByRol)
        {
            Factory.IsTransactional = true;

            string result = "";
            Node   node   = WType.GetNode(new Node {
                NodeID = NodeType.PreLabeled
            });
            Bin bin = WType.GetBin(new Bin {
                BinCode = DefaultBin.MAIN, Location = userByRol.Location
            });



            try
            {
                foreach (DocumentBalance printLine in printList)
                {
                    result += ProcessPrintingLine(printLine, template, printLot, node, bin, userByRol);

                    if (template.PrintEmptyLabel == true)
                    {
                        result += template.Empty;
                    }
                }

                Factory.Commit();
            }
            catch (Exception ex)
            {
                Factory.Rollback();
                ExceptionMngr.WriteEvent("GetReplacedTemplate:", ListValues.EventType.Fatal, ex, null, ListValues.ErrorCategory.ErpConnection);
                throw new Exception(WriteLog.GetTechMessage(ex));
            }

            return(result);
        }
        //
        /// <summary>
        ///Receive Returns, primero recibe normal la cantidad total y luego saca de ese label todo lo que o sea onHand.
        /// Deja el mismo receiving document para poder crear el documento a postear en el ERP.
        /// </summary>
        /// <param name="document"></param>
        /// <param name="retProduct"></param>
        /// <param name="sysUser"></param>
        /// <param name="retTotalQty"></param>
        /// <returns></returns>
        public bool ReceiveReturn(Document document, IList <ProductStock> retProduct,
                                  SysUser sysUser, double retTotalQty, Node recNode)
        {
            Factory.IsTransactional = true;

            try
            {
                DocumentLine line = new DocumentLine
                {
                    Document     = document,
                    Product      = retProduct.First().Product, //View.ComboProduct.SelectedItem,
                    Unit         = retProduct.First().Unit,
                    Quantity     = retTotalQty,
                    QtyPending   = retTotalQty,
                    QtyAllocated = 1,
                    CreatedBy    = sysUser.UserName
                };

                //RETURN
                Bin binDest = WType.GetBin(new Bin {
                    BinCode = DefaultBin.RETURN, Location = retProduct.First().Bin.Location
                });
                //retProduct.Where(f => f.Bin.BinCode == DefaultBin.RETURN).Select(f => f.Bin).First();

                ReceiveProduct(line, new Unit(), binDest, recNode);

                //Mueve las cantidades diferentes del Bin Return a el Bin Correcto.
                Label label = Factory.DaoLabel().Select(new Label {
                    ReceivingDocument = document,
                    Product           = retProduct.First().Product,
                    Status            = new Status {
                        StatusID = EntityStatus.Active
                    }, Node = recNode
                }).First();
                DocumentLine tmpLine = null;

                foreach (ProductStock ps in retProduct.Where(f => f.Bin.BinCode != DefaultBin.RETURN))
                {
                    tmpLine = new DocumentLine {
                        Quantity = ps.Stock, Document = document,
                        Product  = ps.Product, CreatedBy = sysUser.UserName, Unit = ps.Unit
                    };

                    //Disminuye el Label Original
                    DecreaseQtyFromLabel(label, tmpLine, "Decreased in return " + document.DocNumber, false, recNode, false);
                    label.StartQty = label.CurrQty;

                    //Crea un Lable Nuevo en el bin de destino.
                    IncreaseQtyIntoBin(tmpLine, recNode, ps.Bin, "Decreased in return " + document.DocNumber + ", Bin: " + ps.Bin.BinCode, true, DateTime.Now, null, label);
                }

                //Reversado el Node trace del label original al la cantidad final.
                try {
                    NodeTrace ndtrace = Factory.DaoNodeTrace().Select(new NodeTrace {
                        Label = label, Document = document
                    }).First();

                    if (label.CurrQty == 0)
                    {//Lo elimina porque la QTY es cero.
                        Factory.DaoNodeTrace().Delete(ndtrace);
                        Factory.DaoLabel().Delete(label);
                    }
                    else
                    {
                        ndtrace.Quantity = label.CurrQty;
                        Factory.DaoNodeTrace().Update(ndtrace);
                        Factory.DaoLabel().Update(label);
                    }
                }
                catch { }



                return(true);
            }
            catch (Exception ex)
            {
                Factory.Rollback();
                ExceptionMngr.WriteEvent("ReceiveReturn:", ListValues.EventType.Fatal, ex, null, ListValues.ErrorCategory.Business);
                throw new Exception(WriteLog.GetTechMessage(ex));
            }
        }
        //This method revisa si el recibo pertenece a aun procesos de cross dock
        //y Anula el docuemnto de crossdock y sus lineas, y Unpick las cantidades
        //piqueadas para los documentos de ventas
        private void ReverseCrossDockProcess(Document receipt)
        {
            if (receipt.CrossDocking != true)
            {
                return;
            }

            try
            {
                Factory.IsTransactional = true;

                Status cancelled = WType.GetStatus(new Status {
                    StatusID = DocStatus.Cancelled
                });

                TaskDocumentRelation taskRel = new TaskDocumentRelation
                {
                    IncludedDoc = receipt,
                    TaskDoc     = new Document {
                        DocType = new DocumentType {
                            DocTypeID = SDocType.CrossDock
                        }
                    }
                };


                IList <TaskDocumentRelation> listTask = Factory.DaoTaskDocumentRelation().Select(taskRel)
                                                        .Where(f => f.TaskDoc.DocStatus.StatusID != DocStatus.Cancelled).ToList();

                //Cuando no tiene docuemnto asociado
                if (listTask == null || listTask.Count == 0)
                {
                    return;
                }

                //Si tiene docuemnto asociado continua.
                //1. Cancela el documento cross dock y sus lineas.
                Document crossDockDocument = listTask[0].TaskDoc;
                crossDockDocument.DocStatus = cancelled;
                WType.GetStatus(new Status {
                    StatusID = DocStatus.Cancelled
                });
                crossDockDocument.Comment   += "\nDocument cancelled due the reversion of receipt " + receipt.DocNumber;
                crossDockDocument.ModifiedBy = receipt.ModifiedBy;
                crossDockDocument.ModDate    = DateTime.Now;

                foreach (DocumentLine line in crossDockDocument.DocumentLines)
                {
                    line.LineStatus = cancelled;
                    Factory.DaoDocumentLine().Update(line);
                }

                //Actualizando el documento
                Factory.DaoDocument().Update(crossDockDocument);

                //Reversando las cantidades piqeuadas para suplir los documentos de ventas.
                //Obtiene las cantidades que fueron piquedas por cada liena de cada documento de vantas

                //Node traces que fueron afectados con ese recibo.
                NodeTrace sourceTrace = new NodeTrace
                {
                    Node = new Node {
                        NodeID = NodeType.Picked
                    },
                    Status = new Status {
                        StatusID = EntityStatus.Active
                    },
                    Comment = receipt.CustPONumber
                };

                IList <NodeTrace> nodes = Factory.DaoNodeTrace().Select(sourceTrace);

                Node labelNode = Factory.DaoNode().Select(new Node {
                    NodeID = NodeType.Stored
                }).First();

                //revesar todo lo piqueado a main
                Bin bin = WType.GetBin(new Bin {
                    Location = receipt.Location, BinCode = DefaultBin.PUTAWAY
                });

                Status status = Factory.DaoStatus().Select(new Status {
                    StatusID = EntityStatus.Active
                }).First();

                ReverseNodeTrace(nodes, receipt.ModifiedBy, labelNode, bin, status);

                Factory.Commit();
            }
            catch (Exception ex)
            {
                Factory.Rollback();

                ExceptionMngr.WriteEvent("ReverseCrossDockProcess:Doc#" + receipt.DocNumber, ListValues.EventType.Fatal, ex, null, ListValues.ErrorCategory.Business);
                throw;
            }
        }
Beispiel #5
0
        public void PickCrossDockProduct(Document purchase, IList <DocumentBalance> crossDockBalance, SysUser picker)
        {
            Factory.IsTransactional = true;

            Node storedNode = WType.GetNode(new Node {
                NodeID = NodeType.Stored
            });
            Node node = WType.GetNode(new Node {
                NodeID = NodeType.Picked
            });
            Status status = WType.GetStatus(new Status {
                StatusID = EntityStatus.Active
            });
            DocumentType labelType = WType.GetLabelType(new DocumentType {
                DocTypeID = LabelType.ProductLabel
            });

            Bin pickingBin = WType.GetBin(new Bin {
                Location = purchase.Location, BinCode = DefaultBin.PICKING
            });

            Dictionary <Document, Label> packageLabel = new Dictionary <Document, Label>();
            Status locked = WType.GetStatus(new Status {
                StatusID = EntityStatus.Locked
            });


            try
            {
                //Solo toma las lineas de sales y deja quietas las del docuemnto de purchasing
                foreach (DocumentBalance line in crossDockBalance.Where(f => f.Document.DocType.DocClass.DocClassID == SDocClass.Shipping))
                {
                    //Valida si el documento no es nulo
                    Rules.ValidateDocument(line.Document, true);


                    if (line.Document.DocType.DocTypeID != SDocType.PickTicket)
                    {
                        //Valida si el producto esta en ese documento
                        DocumentLine docLine = new DocumentLine
                        {
                            Document   = line.Document,
                            Product    = line.Product,
                            LineStatus = new Status {
                                StatusID = DocStatus.New
                            },
                            Unit     = line.Unit,
                            Quantity = line.QtyProcessed //Quatity processed que es la que hace el cruce con el CrossDock
                        };

                        Rules.ValidateProductInDocument(docLine, true);

                        //Valida si hay saldo pendiente por procesar
                        try { Rules.ValidateBalanceQuantityInDocument(docLine, node, true, true); }
                        catch { continue; }
                    }

                    //Toma el producto del nodetrace
                    //Obtiene los labels que va a mover
                    NodeTrace sourceTrace = new NodeTrace
                    {
                        Document = purchase,
                        //Dec 7/09 no se puede forzar a que sea la misma unidad del balance //Unit = line.Unit,
                        Label = new Label {
                            Product = line.Product, Node = storedNode, Status = status
                        },
                        Status = status,
                        Node   = storedNode
                    };

                    //Obtiene las transacciones del node trace para ese documento especifico de Purchase.
                    IList <Label> labelList = Factory.DaoNodeTrace().Select(sourceTrace).Select(f => f.Label)
                                              //.Take(int.Parse(line.QtyProcessed.ToString()))
                                              .ToList();


                    if (labelList.Sum(f => f.CurrQty * f.Unit.BaseAmount) < line.QtyProcessed * line.Unit.BaseAmount)
                    {
                        Factory.Rollback();
                        throw new Exception("No quantity available in the purchase document " + purchase.DocNumber
                                            + " for product " + line.Product.FullDesc + ".\nQty Available: " + labelList.Sum(f => f.CurrQty * f.Unit.BaseAmount).ToString()
                                            + " Qty Requested: " + (line.QtyProcessed * line.Unit.BaseAmount).ToString() + " in Doc# " + line.Document.DocNumber);
                    }


                    //Package Label para el Despacho
                    if (!packageLabel.ContainsKey(line.Document))
                    {
                        packageLabel.Add(line.Document, GetPackageLabel(new Label {
                            LabelID = -1
                        }, line.Document, picker).PackLabel);
                    }


                    //Debe piquear la cantidad necesaria para suplir el SO con los labels
                    //recibidos.

                    double crQtyBal = line.QtyProcessed * line.Unit.BaseAmount; //LLevada  a la unidad basica

                    foreach (Label curLabel in labelList)
                    {
                        if (crQtyBal <= 0)
                        {
                            break;
                        }

                        //Si el Qty del label menor que lo pendiente mando todo el label
                        if (curLabel.CurrQty * curLabel.Unit.BaseAmount <= crQtyBal)
                        {
                            //Si el destino es logitico lo hace su padre, si no es producto suelto en BIN
                            curLabel.ModifiedBy = purchase.ModifiedBy;
                            curLabel.Node       = node;
                            curLabel.LastBin    = curLabel.Bin;
                            curLabel.Bin        = pickingBin;
                            curLabel.ModDate    = DateTime.Now;

                            curLabel.FatherLabel = null;
                            curLabel.FatherLabel = packageLabel[line.Document];
                            curLabel.Status      = locked;

                            SaveNodeTrace(new NodeTrace
                            {
                                Node      = node,
                                Label     = curLabel,
                                Quantity  = curLabel.CurrQty,
                                Bin       = pickingBin,
                                IsDebit   = false,
                                CreatedBy = purchase.ModifiedBy,
                                Document  = line.Document,
                                // 07 Marzo 2009
                                // En el comenttario se pone el # del PO de cross dock,
                                // este dato sirve en caso de reversion del crossdock process
                                Comment = purchase.DocNumber
                            });


                            curLabel.ShippingDocument = line.Document;
                            Factory.DaoLabel().Update(curLabel);
                            crQtyBal -= curLabel.CurrQty * curLabel.Unit.BaseAmount;
                        }

                        //Si no: disminuyo el Qty del label y hago un Increase
                        else
                        {
                            //Si el destino es logitico lo hace su padre, si no es producto suelto en BIN
                            curLabel.ModifiedBy = purchase.ModifiedBy;
                            curLabel.ModDate    = DateTime.Now;
                            curLabel.CurrQty   -= crQtyBal;
                            Factory.DaoLabel().Update(curLabel);

                            //Increase The Pick Node

                            Node pickNode = WType.GetNode(new Node {
                                NodeID = NodeType.Picked
                            });

                            DocumentLine crdLine = new DocumentLine {
                                Document  = line.Document,
                                Product   = line.Product,
                                Quantity  = crQtyBal,
                                CreatedBy = purchase.ModifiedBy
                            };

                            Label pickedLabel = IncreaseQtyIntoBin(crdLine, pickNode, Rules.GetBinForNode(pickNode, purchase.Location),
                                                                   "Picking Dest", true, DateTime.Now, null, curLabel);

                            pickedLabel.FatherLabel      = packageLabel[line.Document];
                            pickedLabel.Status           = locked;
                            pickedLabel.ShippingDocument = line.Document;

                            Factory.DaoLabel().Update(pickedLabel);

                            //Factory.Commit();
                        }
                    }



                    /*
                     * //Acutualiza la ubicacion Nuevo Bin
                     * foreach (Label curLabel in labelList)
                     * {
                     *  //Si el destino es logitico lo hace su padre, si no es producto suelto en BIN
                     *  curLabel.ModifiedBy = purchase.ModifiedBy;
                     *  curLabel.Node = node;
                     *  curLabel.LastBin = curLabel.Bin;
                     *  curLabel.Bin = pickingBin;
                     *
                     *  SaveNodeTrace(new NodeTrace
                     *  {
                     *      Node = node,
                     *      Label = curLabel,
                     *      Quantity = curLabel.CurrQty,
                     *      Bin = pickingBin,
                     *      IsDebit = false,
                     *      CreatedBy = purchase.ModifiedBy,
                     *      Document = line.Document,
                     *      // 07 Marzo 2009
                     *      // En el comenttario se pone el # del PO de cross dock,
                     *      // este dato sirve en caso de reversion del crossdock process
                     *      Comment = purchase.DocNumber
                     *  });
                     *
                     *  curLabel.FatherLabel = null;
                     *  Factory.DaoLabel().Update(curLabel);
                     * }
                     */
                }

                Factory.Commit();


                //Actualiza el estado de los documentos de shiiping a CrossDock
                foreach (Document doc in crossDockBalance.Where(f => f.Document.DocType.DocClass.DocClassID == SDocClass.Shipping).Select(f => f.Document).Distinct())
                {
                    doc.CrossDocking = true;
                    Factory.DaoDocument().Update(doc);
                }

                Factory.Commit();
            }
            catch (Exception ex)
            {
                Factory.Rollback();
                ExceptionMngr.WriteEvent("PickCrossDockProduct:", ListValues.EventType.Fatal, ex, null, ListValues.ErrorCategory.Business);
                throw new Exception(WriteLog.GetTechMessage(ex));
            }
        }
Beispiel #6
0
        /// <summary>
        /// Crea a new label package for a specific document, this package will contain product picked for the order.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="picker"></param>
        /// <returns></returns>
        public DocumentPackage CreateNewPackage(Document document, SysUser picker, bool isOpen,
                                                DocumentPackage parent, string packageType)
        {
            Factory.IsTransactional = true;

            Node node = WType.GetNode(new Node {
                NodeID = NodeType.Picked
            });
            Status status = WType.GetStatus(new Status {
                StatusID = EntityStatus.Active
            });
            DocumentType labelType = WType.GetLabelType(new DocumentType {
                DocTypeID = LabelType.CustomerLabel
            });
            Unit logisticUnit = WType.GetUnit(new Unit {
                Company = document.Company, Name = WmsSetupValues.CustomUnit
            });
            Bin destLocation = WType.GetBin(new Bin {
                Location = document.Location, BinCode = DefaultBin.PICKING
            });

            int sequence = Factory.DaoDocumentPackage().Select(new DocumentPackage
            {
                Document = document,
                //PostingDocument = new Document {DocID = -1 }
            }).Count + 1;

            //Generate new logistig labels located in MAIN
            //Labels shouldbe activated the next transaction
            try
            {
                //Funcion para obtener siguiente Label
                //DocumentTypeSequence initSequence = GetNextDocSequence(document.Company, labelType);

                Label packLabel = new Label();
                packLabel.Node             = node;
                packLabel.Bin              = destLocation;
                packLabel.CreatedBy        = picker.UserName;
                packLabel.Status           = status;
                packLabel.LabelType        = labelType;
                packLabel.CreationDate     = DateTime.Now;
                packLabel.Printed          = false;
                packLabel.Unit             = logisticUnit;
                packLabel.IsLogistic       = true;
                packLabel.LabelCode        = ""; // initSequence.NumSequence.ToString() + GetRandomHex(picker.UserName, initSequence.NumSequence);
                packLabel.Notes            = "Package label for Document # " + document.DocNumber;
                packLabel.ShippingDocument = document;

                //Added on 14/ENE/09
                if (parent != null && parent.PackLabel != null && parent.PackLabel.LabelID != 0)
                {
                    try { packLabel.FatherLabel = parent.PackLabel; }
                    catch { }
                }



                //Creado el document Package Asociado al Label
                DocumentPackage docPack = new DocumentPackage
                {
                    Document     = document,
                    CreatedBy    = picker.UserName,
                    CreationDate = DateTime.Now,
                    IsClosed     = !isOpen,
                    PackLabel    = packLabel,
                    Picker       = picker,
                    StartTime    = DateTime.Now,
                    EndTime      = DateTime.Now,
                    Sequence     = (short)sequence,
                    Dimension    = "",
                    ShipToName   = document.Customer.Name,
                    //Added on 14/ENE/09
                    ParentPackage = (parent != null && parent.PackID != 0) ? parent : null,
                    PackageType   = packageType
                };

                //Address Line for package 16/oct/09

                DocumentAddress ShipTo_address = null;
                try
                {
                    ShipTo_address = Factory.DaoDocumentAddress().Select(
                        new DocumentAddress
                    {
                        Document    = document,
                        AddressType = AddressType.Shipping
                    })
                                     .Where(f => f.DocumentLine == null).First();

                    docPack.AddressLine1 = ShipTo_address.AddressLine1 + " " + ShipTo_address.AddressLine2;
                    docPack.AddressLine2 = ShipTo_address.City + ", " + ShipTo_address.State + " " + ShipTo_address.ZipCode;
                    docPack.AddressLine3 = ShipTo_address.Country;
                }
                catch { }

                packLabel.DocumentPackages = new List <DocumentPackage> {
                    docPack
                };
                packLabel           = Factory.DaoLabel().Save(packLabel);
                packLabel.LabelCode = packLabel.LabelID.ToString();

                //Registra el movimiento del nodo

                SaveNodeTrace(
                    new NodeTrace
                {
                    Node      = node,
                    Document  = document,
                    Label     = packLabel,
                    Quantity  = packLabel.CurrQty,
                    IsDebit   = false,
                    CreatedBy = picker.UserName
                }
                    );

                //initSequence.NumSequence;
                //Factory.DaoDocumentTypeSequence().Update(initSequence);
                Factory.Commit();


                //actualizando el documento
                try
                {
                    if (string.IsNullOrEmpty(document.UserDef3))
                    {
                        //document.UserDef3 = picker.UserName;
                        Factory.DaoDocument().Update(document);
                    }
                }
                catch { }

                return(docPack);
            }
            catch { throw; }
        }