Ejemplo n.º 1
0
        public XElement GetDocumentOperations(Document document)
        {
            var processTypeAttr = document.Attributes.Children.Where(a => a.DocumentFieldName == DocumentFieldName.Attribute_ProcessType).FirstOrDefault();

            if (processTypeAttr == null)
            {
                return(null);
            }

            var    processObjectAttr = document.Attributes.Children.Where(a => a.DocumentFieldName == DocumentFieldName.Attribute_ProcessObject).FirstOrDefault();
            string processObject     = processObjectAttr.Value.Value;
            var    processStateAttr  = document.Attributes.Children.Where(a => a.DocumentFieldName == DocumentFieldName.Attribute_ProcessState).FirstOrDefault();

            DocumentRelation processMainObjectRelation = null;

            DocumentRelationType?drt = this.GetRelationTypeToMainObject(document);

            if (drt != null)
            {
                processMainObjectRelation = document.Relations.Children.Where(r => r.RelationType == drt.Value).FirstOrDefault();
            }

            XElement process = ConfigurationMapper.Instance.Processes[processTypeAttr.Value.Value];

            string   processState = null;
            Document mainObject   = null;

            if (processStateAttr != null) // jestesmy w glownym obiekcie
            {
                processState = processStateAttr.Value.Value.ToLowerInvariant();
            }
            else //wczytujemy glowny obiekt i z niego odczytujemy stan
            {
                if (processMainObjectRelation == null)
                {
                    //throw new InvalidOperationException("Relation to the main object not found in the given document.");
                    return(null); //zmienione bo w przypadku SERWIS->FVS->WZ to wz nie ma powiazania z serwisem i narazie upraszczamy
                }
                var    moElement  = process.Element("objects").Elements().Where(o => o.Attribute("mainObject") != null && o.Attribute("mainObject").Value.ToUpperInvariant() == "TRUE").First();
                string typeSymbol = moElement.Attribute("typeSymbol").Value;

                DocumentType dt = DictionaryMapper.Instance.GetDocumentType(typeSymbol);

                using (Coordinator c = Coordinator.GetCoordinatorForSpecifiedType(dt.BusinessObjectType, false, false))
                {
                    mainObject = (Document)c.LoadBusinessObject(dt.BusinessObjectType, processMainObjectRelation.RelatedDocument.Id.Value);
                }

                processState = mainObject.Attributes.Children.Where(aa => aa.DocumentFieldName == DocumentFieldName.Attribute_ProcessState).First().Value.Value.ToLowerInvariant();
            }

            //mamy stan procesu, mamy role jaka odgrywa biezacy dokument (processObject), wiec teraz sprawdzamy jakie operacje moze miec

            var operationsResult = from node in process.Element("states").Elements("state")
                                   where node.Attribute("name").Value == processState
                                   from operation in node.Elements()
                                   where operation.Attribute("object").Value == processObject
                                   select operation;

            XElement operations = new XElement("operations");

            operations.Add(operationsResult);

            if (document.DocumentType.DocumentCategory == DocumentCategory.SalesOrder)
            {
                CommercialDocument comDoc = document as CommercialDocument;

                if (comDoc.SalesOrderSettlements == null) //na wszelki wypadek tylko jak w pozniejszym developmencie zdarzy sie inny przypadek
                {
                    SalesOrderSettlements settlements = new SalesOrderSettlements();
                    settlements.LoadSalesOrder(comDoc);

                    XElement prepaidsXml = DependencyContainerManager.Container.Get <DocumentMapper>().GetSalesOrderSettledAmount(comDoc.Id.Value);
                    settlements.LoadPrepaids(prepaidsXml);
                    comDoc.SalesOrderSettlements = settlements;
                }
            }

            this.FilterOperations(document, operations);
            return(operations);
        }
Ejemplo n.º 2
0
        public static void GeneratePrepaymentDocument(XElement source, CommercialDocument destination)
        {
            /*
             *      <source type="salesOrder">
             *        <salesOrderId>{documentId}</salesOrderId>
             *        <processObject>prepaidInvoice</processObject>
             *        <closeOrder>false</closeOrder>
             *      </source>
             */
            DocumentMapper mapper = DependencyContainerManager.Container.Get <DocumentMapper>();

            bool closeOrder = false;

            if (source.Element("closeOrder") != null && source.Element("closeOrder").Value.ToUpperInvariant() == "TRUE")
            {
                closeOrder = true;
            }

            CommercialDocument salesOrder = (CommercialDocument)mapper.LoadBusinessObject(BusinessObjectType.CommercialDocument, new Guid(source.Element("salesOrderId").Value));


            SalesOrderFactory.CheckIfSalesOrderHasWarehouseDocumentsWithInvoices(salesOrder, closeOrder);

            SalesOrderSettlements salesOrderSettlements = new SalesOrderSettlements();

            salesOrderSettlements.LoadSalesOrder(salesOrder);
            XElement settledAmount = mapper.GetSalesOrderSettledAmount(salesOrder.Id.Value);

            salesOrderSettlements.LoadPrepaids(settledAmount);
            destination.SalesOrderSettlements = salesOrderSettlements;

            string processType   = salesOrder.Attributes[DocumentFieldName.Attribute_ProcessType].Value.Value;
            string processObject = source.Element("processObject").Value;
            bool   isSimulated   = processObject == "simulatedInvoice";
            bool   hasProtocole  = source.Element("protocole") != null && source.Element("protocole").Value == "true";

            ProcessManager.Instance.AppendProcessAttributes(destination, processType, processObject, null, null);
            DuplicableAttributeFactory.DuplicateAttributes(salesOrder, destination);

            if (isSimulated && hasProtocole)
            {
                destination.Attributes.GetOrCreateNew(DocumentFieldName.Attribute_IsSimulateSettlementInvoiceWithProtocole).Value.Value = "1";
            }

            //sprawdzamy czy dokumenty zrodlowe maja zgodne sposoby liczenia

            if (salesOrder.CalculationType != destination.CalculationType && destination.DocumentType.CommercialDocumentOptions.AllowCalculationTypeChange)
            {
                destination.CalculationType = salesOrder.CalculationType;
            }

            if (salesOrder.Contractor != null)
            {
                destination.Contractor = (Contractor)salesOrder.Contractor;
            }

            if (salesOrder.ContractorAddressId != null)
            {
                destination.ContractorAddressId = salesOrder.ContractorAddressId;
            }

            int prepaidDocuments = 0;

            prepaidDocuments = salesOrder.Relations.Where(r => r.RelationType == DocumentRelationType.SalesOrderToInvoice).Count();

            destination.Tag = prepaidDocuments.ToString(CultureInfo.InvariantCulture);

            /* teraz wybieramy odpowiednia sciezke algorytmu. mamy takie mozliwosc:
             * 1) wystawiamy zaliczke
             *    - w takiej sytuacji wybieramy id towaru zaliczkowego dla kazdej ze stawek vat i wpisujemy tam wartosci nierozliczone
             * 2) wystawiamy fakture rozliczajaca (closeOrder == true) podczas gdy mamy zaliczki (prepaidDocuments > 0)
             *    - kopiujemy wszystkie pozycje z ZS 1:1, a tabele vat pomniejszamy o sume zaliczek
             * 3) wystawiamy fakture rozliczajaca (closeOrder == true) i nie mamy dokumentow zaliczkowych (prepaidDocuments == 0)
             *    - w takim przypadku zamowienie sprzedazowe traktujemy jako proforme, kopiujemy wszystkie pozycje i tabele vat bez zmian i tyle
             */


            //wstawiamy odpowiedni towar na zaliczke + ustawiamy odpowiednai wartosc
            int stage = 0;

            if (closeOrder)
            {
                stage = 0;
            }
            else if (prepaidDocuments == 0)
            {
                stage = 1;
            }
            else if (prepaidDocuments == 1)
            {
                stage = 2;
            }
            else if (prepaidDocuments == 2)
            {
                stage = 3;
            }
            else if (prepaidDocuments >= 3)
            {
                stage = 4;
            }

            List <Guid> items = new List <Guid>(2);

            ICollection <SalesOrderSettlement> unsettledValues = salesOrderSettlements.GetUnsettledValues();

            foreach (var v in salesOrder.VatTableEntries.GetVatRates())
            {
                items.Add(ProcessManager.Instance.GetPrepaidItemId(salesOrder, stage, v));
            }

            XDocument xml = DependencyContainerManager.Container.Get <ItemMapper>().GetItemsDetailsForDocument(false, null, null, items);

            if (closeOrder)
            {
                SalesOrderFactory.CopyLinesFromSalesOrder(salesOrder, destination, false, true, false, true);
                destination.Calculate();

                //Ostatnia rata pchamy do atrybutu zeby wydruk fiskalny wiedzial co ma wydrukowac
                if (destination.CalculationType == CalculationType.Gross && !isSimulated)
                {
                    XElement fiscalLines = new XElement("fiscalLines");

                    foreach (var v in unsettledValues)
                    {
                        XElement itemXml    = xml.Root.Elements().Where(i => i.Attribute("id").Value == ProcessManager.Instance.GetPrepaidItemId(salesOrder, stage, v.VatRateId).ToUpperString()).First();
                        XElement fiscalLine = new XElement("fiscalLine");
                        fiscalLine.Add(new XElement("itemName", itemXml.Attribute("name").Value));
                        fiscalLine.Add(new XElement("quantity", "1"));
                        fiscalLine.Add(new XElement("vatRateId", itemXml.Attribute("vatRateId").Value));
                        fiscalLine.Add(new XElement("grossPrice", v.GrossValue.ToString(CultureInfo.InvariantCulture)));
                        fiscalLine.Add(new XElement("grossValue", v.GrossValue.ToString(CultureInfo.InvariantCulture)));
                        fiscalLine.Add(new XElement("unitId", itemXml.Attribute("unitId").Value));
                        fiscalLines.Add(fiscalLine);
                    }

                    var attribute = destination.Attributes.CreateNew(DocumentFieldName.Attribute_FiscalPrepayment);
                    attribute.Value = fiscalLines;
                }

                if (prepaidDocuments > 0)                 // *2)
                {
                    decimal maxDifference = ProcessManager.Instance.GetMaxSettlementDifference(salesOrder);

                    foreach (var v in salesOrderSettlements.Prepaids)
                    {
                        if (v.NetValue > 0 || v.GrossValue > 0 || v.VatValue > 0)
                        {
                            var vt        = destination.VatTableEntries.Where(t => t.VatRateId == v.VatRateId).FirstOrDefault();
                            var prepaidVt = destination.VatTableEntries.CreateNewAfter(vt, v.VatRateId);
                            prepaidVt.VatRateId  = v.VatRateId;
                            prepaidVt.NetValue   = -v.NetValue;
                            prepaidVt.GrossValue = -v.GrossValue;
                            prepaidVt.VatValue   = -v.VatValue;

                            decimal vtNetValue   = 0;
                            decimal vtGrossValue = 0;
                            decimal vtVatValue   = 0;
                            if (vt != null)
                            {
                                vtNetValue   = vt.NetValue;
                                vtGrossValue = vt.GrossValue;
                                vtVatValue   = vt.VatValue;
                            }

                            decimal grossBalance = vtGrossValue + prepaidVt.GrossValue;
                            decimal netBalance   = vtNetValue + prepaidVt.NetValue;
                            decimal vatBalance   = vtVatValue + prepaidVt.VatValue;

                            SalesOrderBalanceValidator validator =
                                new SalesOrderBalanceValidator(maxDifference, grossBalance, netBalance, vatBalance);

                            if (validator.IsIllegalOverPayment)
                            {
                                throw new ClientException(ClientExceptionId.SalesOrderSettlementOverpaidError, null, "value:" + (-grossBalance).ToString(CultureInfo.InvariantCulture).Replace('.', ',')); //nadpłata powyżej granicy błędu
                            }
                            else if (validator.IsAcceptableOverPayment)                                                                                                                                    //czyli mamy nadplate w granicy bledu
                            {
                                prepaidVt.NetValue   = -vtNetValue;
                                prepaidVt.GrossValue = -vtGrossValue;
                                prepaidVt.VatValue   = -vtVatValue;
                            }
                        }
                    }
                }
                else
                {
                    throw new ClientException(ClientExceptionId.UnableToCreateSettlementDocument3);
                }

                decimal netValue   = 0;
                decimal grossValue = 0;
                decimal vatValue   = 0;

                foreach (var vt in destination.VatTableEntries)
                {
                    netValue   += vt.NetValue;
                    grossValue += vt.GrossValue;
                    vatValue   += vt.VatValue;
                }

                destination.NetValue   = netValue;
                destination.GrossValue = grossValue;
                destination.VatValue   = vatValue;

                destination.DisableLinesChange = DisableDocumentChangeReason.LINES_SETTLEMENT_INVOICE;

                if (!isSimulated)
                {
                    var attr = destination.Attributes.CreateNew(DocumentFieldName.Attribute_IsSettlementDocument);
                    attr.Value.Value = "1";
                }
            }
            else             //1) wystawiamy zaliczke
            {
                foreach (XElement itemXml in xml.Root.Elements("item"))
                {
                    CommercialDocumentLine line = destination.Lines.CreateNew();
                    line.ItemId = new Guid(itemXml.Attribute("id").Value);
                    Guid vatRateId = new Guid(itemXml.Attribute("vatRateId").Value);

                    if (itemXml.Attribute("code") != null)
                    {
                        line.ItemCode = itemXml.Attribute("code").Value;
                    }

                    line.UnitId      = new Guid(itemXml.Attribute("unitId").Value);
                    line.VatRateId   = vatRateId;
                    line.ItemVersion = new Guid(itemXml.Attribute("version").Value);
                    line.Quantity    = 1;
                    line.ItemName    = itemXml.Attribute("name").Value;
                }

                destination.Calculate();
            }
        }