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; } }
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> /// 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; } }