Skip to content

Instantly share code, notes, and snippets.

@GeorgDangl
Last active July 25, 2018 18:48
Show Gist options
  • Save GeorgDangl/1256ef690b018436eabb9319280b92e4 to your computer and use it in GitHub Desktop.
Save GeorgDangl/1256ef690b018436eabb9319280b92e4 to your computer and use it in GitHub Desktop.
Dangl.AVA & Dangl.GAEB Tendering Process
<Item ID="ID_cc1077f7-9618-46be-af53-4b500acfefb6" RNoPart="02" RNoIndex="5">
<Qty>240</Qty>
<QU>m²</QU>
<Description>
<OutlineText>
<OutlTSA>No</OutlTSA>
<OutlTxt>
<TextOutlTxt>
<span>Wand, 20cm, Stahlbeton</span>
</TextOutlTxt>
</OutlTxt>
</OutlineText>
</Description>
</Item>
<Item ID="ID_a71d8ec9-e92c-4fca-b097-511a329fd4ec" RNoPart="02" RNoIndex="5">
<Qty>240</Qty>
<QU>m²</QU>
<Description>
<OutlineText>
<OutlTSA>No</OutlTSA>
<OutlTxt>
<TextOutlTxt>
<span>Concrete Walls</span>
</TextOutlTxt>
</OutlTxt>
</OutlineText>
</Description>
</Item>
<Item ID="ID_a71d8ec9-e92c-4fca-b097-511a329fd4ec" RNoPart="02" RNoIndex="5">
<Qty>240</Qty>
<UP>35.0</UP>
<IT>8400.0</IT>
</Item>
using Dangl.AVA.Contents.ServiceSpecificationContents;
using Dangl.AVA.Extensions;
using System.IO;
using System.Linq;
using System.Reflection;
using Xunit;
namespace Dangl.AVA.Converter.Tests.Utilities.TutorialFiles
{
public class TenderingWorkflow
{
[Fact]
public void ReadOfferRequestThenCalculatePricesThenExportOffer()
{
// First, get the GAEB file as System.IO.Stream.
// It can be anything - directly from a file, from a web request
// or read from your database.
var gaebFileStream = GetGaebFileStream();
// The GAEB file can be any GAEB format - GAEB 90, GAEB 2000 or GAEB XML
var gaebFile = Dangl.GAEB.Reader.GAEBReader.ReadGaeb(gaebFileStream);
// In this case, it's GAEB XML
Assert.Equal(Dangl.GAEB.GaebFileVersion.GaebXml, gaebFile.Version);
// Dangl.AVA.Converter can convert all GAEB formats to Dangl.AVA.Projects
var importedProject = Dangl.AVA.Converter.Converter.ConvertFromGaeb(gaebFile);
// The project can now be edited, for example by setting prices
var projectWithPrices = CalculatePricesForOffer(importedProject);
Assert.Equal(0m, importedProject.ServiceSpecifications[0].TotalPrice);
// projectWithPrices should have a TotalPrice set now
Assert.Equal(57_550m, projectWithPrices.ServiceSpecifications[0].TotalPrice);
// This project can now be converted again to a GAEB Stream
using (var gaebExportStream = ExportProjectAsGaebXmlOffer(projectWithPrices))
{
// Now the Stream can be saved as file,
// returned in a web request,
// stored in the database...
}
}
private Stream GetGaebFileStream()
{
var assembly = typeof(TenderingWorkflow).GetTypeInfo().Assembly;
var resourceName = "Dangl.AVA.Converter.Tests.Utilities.Resources.GAEBXML_EN.X83";
return assembly.GetManifestResourceStream(resourceName);
}
public Project CalculatePricesForOffer(Project sourceProject)
{
// We make a copy of the project so we don't change the input object
var project = sourceProject.Copy(keepId: true);
// First, we set the VAT Tax Rate for the project
project.ServiceSpecifications[0].ProjectTaxRate = .19m; // 19 % tax rate
// GetPositionByItemNumber() is an extension method in Dangl.AVA.Extensions
var sitePreparationPosition = project.GetPositionByItemNumber("01.01.001");
// In the site preparation, we simply set a price without any calculations
// via the SetUnitPrice() extension method
sitePreparationPosition.SetUnitPrice(800m);
// The project defines two price components:
// 1. Material
// 2. Gear, such as tools & machinery
// Additionally, Dangl.AVA allows to set a price-per-hour of manual labour and a time component
// for position prices
// For the walls, we want to do a more detailed price calculation
var concreteWallsPosition = project.GetPositionByItemNumber("02.02.005");
var formulaForMaterial = "0.25\"Wall thickness in meter\" * 80\"EUR/m3\""; // Formulas support comments
var formulaForLabour = "1.20\"Hours per m³\" * 0.25\"Wall thickness in meter\"";
concreteWallsPosition.PriceComponents
.First(comp => comp.Label == "Material") // Select the Price Component for "Material"
.Values.Add(new Calculation { Formula = formulaForMaterial });
concreteWallsPosition
.LabourComponents
.Values.Add(new Calculation { Formula = formulaForLabour });
// Also, we define the cost-per-hour of labour as 50 currency units
project.ServiceSpecifications[0].PriceInformation.HourlyWage = 50m;
// All other positions simply get a price set
project.GetPositionByItemNumber("02.02.001").SetUnitPrice(9);
project.GetPositionByItemNumber("02.02.002").SetUnitPrice(6);
project.GetPositionByItemNumber("02.02.003").SetUnitPrice(12);
project.GetPositionByItemNumber("02.02.004").SetUnitPrice(40);
return project;
}
public Stream ExportProjectAsGaebXmlOffer(Project projectWithPrices)
{
// We want to make sure that for the export:
// 1. The format is GAEB XML
// 2. The export phase is 84 - Offer
var gaebFileOffer = Dangl.AVA.Converter.Converter.ConvertToGaeb(projectWithPrices,
destinationType: DestinationGAEBType.GAEBXML_V3_2,
targetExchangePhase: GAEBTargetExchangePhase.Offer); // Phase "Offer" is GAEB Phase 84
// The GAEB file object is now converted to a Stream
var gaebStream = Dangl.GAEB.Writer.GAEBWriter.GetStream(gaebFileOffer);
return gaebStream;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment