//Obtienene el listado de labels d eun BIN especifico. private IList <Label> GetPackageLabels(Label labelPattern, DocumentLine searchLine) { //Cuenta el producto necesario a mover al nuevo Bin, si no alcanza tira exception Label searchLabel = new Label(); searchLabel.LabelType = WType.GetLabelType(new DocumentType { DocTypeID = LabelType.ProductLabel }); searchLabel.Product = searchLine.Product; searchLabel.FatherLabel = labelPattern; //searchLabel.Status = WType.GetStatus(new Status { StatusID = EntityStatus.Active }); //searchLabel.Node = labelPattern.Node; //searchLabel.Bin = labelPattern.Bin; //Llamar los labels a afectar return(Factory.DaoLabel().Select(searchLabel).OrderBy(f => f.ReceivingDate).ToList <Label>()); }
public Label CreateUniqueTrackLabel(Product product, string labelCode, Label destLabel, string user) { //Chequear que no exista un labelcode igual para el mismo producto. En estado Activo. if (labelCode != WmsSetupValues.AutoSerialNumber) { if (Factory.DaoLabel().Select(new Label { LabelCode = labelCode.Trim(), Product = product, Node = new Node { NodeID = NodeType.Stored }, Status = new Status { StatusID = EntityStatus.Active } }).Count() > 0) { throw new Exception("Track# [" + labelCode + "] already exists."); } } Factory.IsTransactional = true; //BIN Label uniqueLabel = new Label { }; uniqueLabel.StartQty = 1; uniqueLabel.CurrQty = 1; uniqueLabel.LabelID = 0; uniqueLabel.LabelCode = labelCode == WmsSetupValues.AutoSerialNumber ? Guid.NewGuid().ToString() : labelCode.Trim(); uniqueLabel.LabelType = WType.GetLabelType(new DocumentType { DocTypeID = LabelType.UniqueTrackLabel }); uniqueLabel.Bin = destLabel.Bin; uniqueLabel.Printed = true; uniqueLabel.Unit = product.BaseUnit; //Garantiza que el unique sea de unidad basica. uniqueLabel.CreatedBy = user; uniqueLabel.CreationDate = DateTime.Now; uniqueLabel.Notes = "Adjusmet Inventory Serial"; uniqueLabel.Node = new Node { NodeID = NodeType.Stored }; uniqueLabel.Product = product; uniqueLabel.Status = new Status { StatusID = EntityStatus.Active }; if (destLabel.LabelType.DocTypeID == LabelType.ProductLabel) { uniqueLabel.FatherLabel = destLabel; } uniqueLabel = Factory.DaoLabel().Save(uniqueLabel); if (labelCode == WmsSetupValues.AutoSerialNumber) { uniqueLabel.LabelCode = '1' + uniqueLabel.LabelID.ToString().PadLeft(WmsSetupValues.LabelLength - 1, '0'); Factory.DaoLabel().Update(uniqueLabel); } Factory.Commit(); return(uniqueLabel); }
public Label CreateUniqueTrackLabel(Label fatherLabel, string labelCode) { //Chequear que no exista un labelcode igual para el mismo producto. En estado Activo. if (labelCode != WmsSetupValues.AutoSerialNumber) { if (Factory.DaoLabel().Select(new Label { LabelCode = labelCode.Trim(), Product = fatherLabel.Product, Node = new Node { NodeID = NodeType.Stored }, Status = new Status { StatusID = EntityStatus.Active } }).Count() > 0) { throw new Exception("Track# [" + labelCode + "] already exists."); } } Factory.IsTransactional = true; //Crea un label a partir de otro, poniendol eun labelcode diferente Label tmpFather = Factory.DaoLabel().Select(new Label { LabelID = fatherLabel.LabelID }).First(); //Si es una label pre impreso se pasa a stored por que e sun INitial Inventory Label. if (tmpFather.Node.NodeID == NodeType.PreLabeled) { tmpFather.Node = new Node { NodeID = NodeType.Stored } } ; Label uniqueLabel = fatherLabel; uniqueLabel.StartQty = 1; uniqueLabel.CurrQty = 1; uniqueLabel.LabelID = 0; uniqueLabel.LabelCode = labelCode == WmsSetupValues.AutoSerialNumber ? Guid.NewGuid().ToString() : labelCode.Trim(); uniqueLabel.LabelType = WType.GetLabelType(new DocumentType { DocTypeID = LabelType.UniqueTrackLabel }); uniqueLabel.Bin = fatherLabel.Bin; uniqueLabel.Printed = true; uniqueLabel.Unit = uniqueLabel.Product.BaseUnit; //Garantiza que el unique sea de unidad basica. uniqueLabel = Factory.DaoLabel().Save(uniqueLabel); if (labelCode == WmsSetupValues.AutoSerialNumber) { uniqueLabel.LabelCode = '1' + uniqueLabel.LabelID.ToString().PadLeft(WmsSetupValues.LabelLength - 1, '0'); Factory.DaoLabel().Update(uniqueLabel); } if (tmpFather.Unit.BaseAmount > 1) { tmpFather.StartQty = tmpFather.StartQty * tmpFather.Unit.BaseAmount; tmpFather.CurrQty = tmpFather.CurrQty * tmpFather.Unit.BaseAmount; tmpFather.Unit = tmpFather.Product.BaseUnit; } if (tmpFather.CurrQty > 0) { tmpFather.CurrQty--; } Factory.DaoLabel().Update(tmpFather); uniqueLabel.FatherLabel = tmpFather; Factory.DaoLabel().Update(uniqueLabel); Factory.Commit(); return(uniqueLabel); }
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)); } }
/// <summary> /// Recolecta= producto, sin etiqueta (recibo manual) toma de los labels virtuales para cada unidad basica de producto /// </summary> /// <param name="line"></param> /// <param name="sourceLocation"></param> /// <param name="node"></param> /// <param name="packageLabel"></param> /// <param name="picker"></param> public void PickProduct(DocumentLine line, Label sourceLocation, Node destNode, Label packageLabel, SysUser picker, Bin destBin) { Factory.IsTransactional = true; Node storedNode = WType.GetNode(new Node { NodeID = NodeType.Stored }); Status status = WType.GetStatus(new Status { StatusID = EntityStatus.Active }); Status locked = WType.GetStatus(new Status { StatusID = EntityStatus.Locked }); DocumentType labelType = WType.GetLabelType(new DocumentType { DocTypeID = LabelType.ProductLabel }); if (destBin == null) { destBin = Rules.GetBinForNode(destNode, sourceLocation.Bin.Location); } try { //Valida si el docuemnto no es nulo Rules.ValidateDocument(line.Document, true); Rules.ValidateBinStatus(sourceLocation.Bin, true); //Validar si las locations son iguales Rules.ValidatePickLocation(line.Document.Location, sourceLocation.Bin.Location, true); if (sourceLocation.LabelType.DocTypeID == LabelType.ProductLabel) { //Valida que este activo Rules.ValidateActiveStatus(sourceLocation.Status, true); //Validar que no este vod Rules.ValidateVoided(sourceLocation.Node, 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.Quantity, CreatedBy = picker.UserName }; Rules.ValidateProductInDocument(docLine, true); //Valida si hay saldo pendiente por procesar Rules.ValidateBalanceQuantityInDocument(docLine, destNode, true, false); } //Evaluacion de tipo de source, Bin or Label DateTime recDate = DateTime.Now; if (Rules.ValidateIsBinLabel(sourceLocation, false)) { IList <Label> tranLabel = DecreaseQtyFromBin(sourceLocation, line, "Picking Source Product", true, storedNode); try { recDate = (DateTime)tranLabel.Where(f => f.ReceivingDate != null).OrderBy(f => f.ReceivingDate).First().ReceivingDate; } catch { recDate = DateTime.Now; } } //SI el ajustes es sobre un Label else if (Rules.ValidateIsProductLabel(sourceLocation, false)) { DecreaseQtyFromLabel(sourceLocation, line, "Picking Source Product", true, storedNode, true); try { recDate = (sourceLocation.ReceivingDate == null) ? DateTime.Now : (DateTime)sourceLocation.ReceivingDate; } catch { recDate = DateTime.Now; } } //Creando el package para ingresar la mercancia. if (packageLabel != null) { line.Document.Location = sourceLocation.Bin.Location; //Revalidando que el location sea correcto try { packageLabel = GetPackageLabel(packageLabel, line.Document, picker).PackLabel; } catch (Exception ex) { Factory.Rollback(); throw new Exception("Package label could not be created.\n" + ex.Message); } } //Increasing the Record of Product on Dest Bin. Label pickedLabel = IncreaseQtyIntoBin(line, destNode, destBin, "Picking Dest Product", true, recDate, null, sourceLocation); pickedLabel.FatherLabel = packageLabel; pickedLabel.Status = locked; pickedLabel.ShippingDocument = line.Document; Factory.DaoLabel().Update(pickedLabel); Factory.Commit(); } catch (Exception ex) { Factory.Rollback(); ExceptionMngr.WriteEvent("PickProduct:", ListValues.EventType.Fatal, ex, null, ListValues.ErrorCategory.Business); throw new Exception(WriteLog.GetTechMessage(ex)); } }
/// <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; } }