Error executing template "Designs/Ege/eCom/ProductCatalog/Ege_ProductViewDetail.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_374dfa4e29d5427baf07bc8404c76820.Execute() in E:\Solutions\egecarpets.dk\Files\Templates\Designs\Ege\eCom\ProductCatalog\Ege_ProductViewDetail.cshtml:line 433
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @using Dynamicweb.Rendering 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using EGE.Website.CustomModules 4 @using EGE.Website.CustomModules.Models 5 @using EGE.Website.CustomModules.Extensions 6 @using EGE.Website.CustomModules.Helpers 7 @using System.Web 8 9 @inherits ViewModelTemplate<ProductViewModel> 10 11 @{ 12 var product = Dynamicweb.Ecommerce.Services.Products.GetProductById(Model.Id, Model.VariantId, Model.LanguageId); 13 14 } 15 16 @if (product == null) 17 { 18 <h3>The product is not available in the chosen language, please try another.</h3> 19 } 20 else 21 { 22 bool isOutletSite = PageExtensions.IsOutletArea(Pageview.AreaID); 23 var B2cSiteActive = PageExtensions.IsB2CArea(Pageview.AreaID); 24 //string groupIdQueryParameter = string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["GroupID"]) 25 // ? string.Empty 26 // : "&amp;GroupID=" + Dynamicweb.Context.Current.Request["GroupID"]; 27 var variantCombinations = product.VariantCombinations.Where(x => !x.VariantId.Contains("NA")); 28 29 string productLink = "/Default.aspx?ID=" + Pageview.Page.ID + "&amp;ProductID=" + Model.Id; 30 var prodImage = ProductExtensions.GetProductImagePath(Model.Id, out bool isExternal); 31 var prodTypeName = Model.GetFieldName("ProductEgeType"); 32 var prodTypeValue = Model.GetFieldValue("ProductEgeType"); 33 var prodConceptName = Model.GetFieldName("ProductConcept"); 34 var prodConceptValue = Model.GetFieldValue("ProductConcept"); 35 var prodCollectionName = Model.PrimaryOrDefaultGroup.Name; 36 var prodCollectionLink = string.Empty; 37 var prodB2CCollectionLink = string.Empty; 38 var prodConceptLink = string.Empty; 39 int variantListCounter = 0; 40 var IsBulkCarpets = PageExtensions.IsBulkCarpets(prodTypeValue); 41 42 //EGEDR-769 43 bool isCircleBack = false; 44 string circleBackText = string.Empty; 45 if (Model.ProductCategories.Keys.Any()) 46 { 47 if (Model.ProductCategories.ContainsKey("CarpetCategory")) 48 { 49 isCircleBack = bool.Parse(product.GetCategoryValue("CarpetCategory", "IsCircleBack").ToString()); 50 var circleBackTextObj = product.GetCategoryValue("CarpetCategory", "CircleBackText"); 51 circleBackText = circleBackTextObj != null ? circleBackTextObj.ToString() : null; 52 } 53 54 } 55 56 var CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code; 57 58 if (Model.ProductCategories.Keys.Any()) 59 { 60 if (Model.ProductCategories.ContainsKey("CarpetCategory")) 61 { 62 var fields = Model.ProductCategories["CarpetCategory"]; 63 prodCollectionLink = fields.Fields["CollectionContentPage"].Value as string; 64 prodConceptLink = fields.Fields["ConceptContentPage"].Value as string; 65 prodB2CCollectionLink = fields.Fields["B2CCollectionContentPage"].Value as string; 66 } 67 68 } 69 var images = Model.GetImages(); 70 var sustainabilityChoices = string.Empty; 71 if (Model.ProductCategories.ContainsKey("CarpetCategory")) 72 { 73 var susChoiceList = (Model.ProductCategories["CarpetCategory"].Fields["PdfSustainBlocks"]?.Value as List<FieldOptionValueViewModel>); 74 75 foreach (var choice in susChoiceList) 76 { 77 sustainabilityChoices += choice.Value; 78 } 79 } 80 81 var variantsDivId = "js-product-details__variants"; 82 var prodNumber = ""; 83 var patternNumber = ""; 84 var backingAbbr = ""; 85 86 if (isOutletSite) 87 { 88 @TemplateHelper.RenderPartial("Ecom/Partials/Details_OutletData.cshtml", Model) 89 prodNumber = Model.GetCategoryValueAs<string>("M3ProductNumber", "OutletSpecs"); 90 patternNumber = Model.GetCategoryValueAs<string>("PatternNumber", "OutletSpecs"); 91 backingAbbr = Model.GetFieldValue("ProductBacking").ToString(); 92 } 93 else 94 { 95 @TemplateHelper.RenderPartial("Ecom/Partials/Details_Data.cshtml", Model) 96 } 97 98 var cartOrderLinesFeed = Dynamicweb.Services.Pages.GetPageByNavigationTag(Pageview.AreaID, "CartOrderLinesFeed"); 99 var cartOrderLinesFeedUrl = ""; 100 if (cartOrderLinesFeed != null) 101 { 102 cartOrderLinesFeedUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(cartOrderLinesFeed.ID); 103 } 104 105 var isProductRug = EGE.Website.CustomModules.Extensions.ProductExtensions.IsRug(HttpContext.Current.Request["ProductID"]); 106 var showConfigurator = EGE.Website.CustomModules.Extensions.ProductExtensions.GetProductShowConfigurator(HttpContext.Current.Request["ProductID"]); 107 108 Dynamicweb.Content.PageService pageService = new Dynamicweb.Content.PageService(); 109 Dynamicweb.Content.Page configuratorLoginPage = pageService.GetPageByNavigationTag(Pageview.AreaID, "ConfiguratorLoginPage"); 110 string configuratorLoginPageUrl = configuratorLoginPage != null ? Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(configuratorLoginPage.ID) : null; 111 string productId = HttpContext.Current.Request["ProductID"]; 112 113 string configuratorFullLink = configuratorLoginPageUrl + "?configuratorId=" + productId; 114 115 <section class="product-details" id="js-product-details" data-model-id="@Model.Id" data-model-name="@Model.Name" data-non-variants="@Model.GetRelatedGroupById("RELGRP1").Any()" data-thumb="@ProductExtensions.GetProductImagePath(Model.Id, out isExternal, "XS")"> 116 117 <div class="container"> 118 <div class="product-details__inner"> 119 <div class="product-details__header-holder"> 120 <h1 class="header-in-component header-in-component--product-detail"> 121 @Model.Name 122 </h1> 123 <div class="product-details__header-id"> 124 @if (!isOutletSite) 125 { 126 @Model.Number 127 } 128 else 129 { 130 @:@prodNumber - @patternNumber - @backingAbbr 131 } 132 </div> 133 </div> 134 <div class="product-details__slider-holder"> 135 <div class="slider-with-counter slider-with-counter--main" id="slider-with-counter--wide"> 136 <div class="slider-with-counter__slider-holder"> 137 138 <ul class="slider-with-counter__list slider-with-counter__list--hidden" data-counter-text="@Translate("Product | You are viewing {X} of {Y} images", "You are viewing {X} of {Y} images").Replace("{X}", "{0}").Replace("{Y}", "{0}")"> 139 140 @foreach (var image in images) 141 { 142 var imageIndex = 0; 143 <li class="slider-with-counter__item"> 144 @if (isCircleBack && !B2cSiteActive && image.Url.Contains("/Files/Files/Ecom/Images/Products/")) 145 { 146 <div class="product-details__circle-back-overlay-container"> 147 <div class="product-details__circle-back-overlay"> 148 <div class="product-details__circle-back-overlay--img-container"> 149 <img class="product-details__circle-back-overlay--img" src="@ImageUiFormatHelper.Format("/Files/Files/Images/CircleBack/Ege_Circular_Black.png", 90, 100)" height="90" width="100" /> 150 </div> 151 <span class="product-details__circle-back-overlay--text">@Translate("EgeCircleBack:OverlayText", "Ege CircleBack")</span> 152 </div> 153 </div> 154 } 155 <img class="lazyload a-image lazyload-measure lazyload-bg " src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="@image.AltText" property="contentUrl" data-src="@(image.IsExternal ? image.Url : ImageUiFormatHelper.Format(image.Url, 542, 542))" 156 data-query-obj='{ "mode":"crop" }'> 157 <noscript v-if="false"> 158 <img src="@(image.IsExternal ? image.Url : ImageUiFormatHelper.Format(image.Url, 542, 542))" alt="@image.AltText"> 159 </noscript> 160 161 <button @@click="showOverlay(@imageIndex+1)" class="slider-with-counter__button-lightbox" data-lightbox-image="test-slider.jpg"></button> 162 </li> 163 } 164 </ul> 165 <div class="slider-with-counter__navigation"> 166 <button @@click="slideToPrev(sliderMain)" v-bind:class="{ 'slider-with-counter__button--show': sliderMain.showButtonPrev}" class="slider-with-counter__button slider-with-counter__button--prev"> 167 <svg class="svg-icon slider-with-counter__svg"> 168 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow"></use> 169 </svg> 170 </button> 171 <button @@click="slideToNext(sliderMain)" v-bind:class="{ 'slider-with-counter__button--show': sliderMain.showButtonNext }" class="slider-with-counter__button slider-with-counter__button--next"> 172 <svg class="svg-icon slider-with-counter__svg"> 173 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow"></use> 174 </svg> 175 </button> 176 </div> 177 </div> 178 @if (!isOutletSite && !B2cSiteActive) 179 { 180 <div v-if="sliderMain.currentSlide <= 1"> 181 <span id="ImageDownload" class="product-list-room-shot__item-image-download-product-detail"> 182 <figure class="product-list-room-shot__item-image-download-icon"><svg class="svg-icon product-list-room-shot__item-image-download-icon-arrow"><use xlink:href="/dist/icons/icons.svg#arrow-down-in-circle"></use></svg></figure> 183 <a href="@prodImage" download="@prodImage" class="product-list-room-shot__item-image-download-link">Low res</a> 184 185 @if (ProductExtensions.GetHighResolutionImagePath(Model.Id) != null && !string.IsNullOrEmpty(ProductExtensions.GetHighResolutionImagePath(Model.Id))) 186 { 187 <a href="@ProductExtensions.GetHighResolutionImagePath(Model.Id)" download="@ProductExtensions.GetHighResolutionImagePath(Model.Id)" class="product-list-room-shot__item-image-download-link">High res</a> 188 } 189 </span> 190 </div> 191 192 } 193 <div class="slider-with-counter__counter"> 194 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--plain" v-html="sliderMain.counterTextBefore"></span> 195 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--number" v-html="sliderMain.currentSlide"></span> 196 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--middle" v-html="sliderMain.counterTextMiddle"></span> 197 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--number" v-html="slidesAmount"></span> 198 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--plain" v-html="sliderMain.counterTextAfter"></span> 199 </div> 200 <div class="slider-with-counter__template"> 201 202 <div class="novi-backdrop novi-backdrop--hidden novi-backdrop--slider-with-counter" id="slider-with-counter__overlay"> 203 <div class="novi-overlay"> 204 <div class="novi-overlay__container"> 205 <div class="novi-overlay__content"> 206 <div class="slider-with-counter slider-with-counter--in-overlay slider-with-counter--zoom" id="slider-with-counter--wide"> 207 <div class="slider-with-counter__slider-holder"> 208 <ul class="slider-with-counter__list slider-with-counter__list--hidden slider-with-counter__list--zoom"> 209 @{ 210 int canvasCounter = 0; 211 } 212 @foreach (var image in images) 213 { 214 <li class="slider-with-counter__item"> 215 <img class="lazyload a-image lazyload-measure @(image.IsFirst ? "slider-with-counter__real-image" : "lazyload-bg")" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="@image.AltText" property="contentUrl" data-src="@(image.IsExternal ? image.Url : ImageUiFormatHelper.Format(image.Url, 700, 700))" 216 data-query-obj='{ "mode":"crop" }'> 217 <noscript v-if="false"> 218 <img src="@(image.IsExternal ? image.Url + "?mode=crop" : ImageUiFormatHelper.Format(image.Url, 700, 700))" 219 alt="@image.AltText"> 220 </noscript> 221 <span class="button__wait-animation button__wait-animation--slider-with-counter"> 222 <span></span> 223 <span></span> 224 <span></span> 225 <span></span> 226 </span> 227 228 @if (canvasCounter == 0) 229 { 230 <canvas v-bind:class="{'slider-with-counter__zoom-canvas--loading':zoomElements[@canvasCounter] && zoomElements[@canvasCounter].isLoading}" @@touchend="zoomOnTouchEnd(@canvasCounter,$event)" @@mouseup="zoomOnTouchEnd(@canvasCounter,$event)" @@touchmove="zoomOnTouchMove(@canvasCounter,$event)" @@touchstart="zoomOnTouchStart(@canvasCounter,$event)" @@mousedown="zoomOnTouchStart(@canvasCounter,$event)" @@wheel="zoomOnWheel(@canvasCounter,$event)" @@mousemove="zoomOnTouchMove(@canvasCounter,$event)" @@mouseleave="zoomClear(@canvasCounter)" data-src="@(image.Url + "&mode=crop")" data-no="@canvasCounter" class="slider-with-counter__zoom-canvas"></canvas> 231 <span class="slider-with-counter__zoom-loading" v-if="zoomElements[@canvasCounter] && zoomElements[@canvasCounter].isLoading"> 232 <span class="button__wait-animation button__wait-animation--zoom"> 233 <span></span> 234 <span></span> 235 <span></span> 236 <span></span> 237 </span> 238 <span class="slider-with-counter__zoom-loading-text">@Translate("Product | Zoom | Loading zoomable image", "Loading zoomable image")</span> 239 </span> 240 <div class="slider-with-counter__zoom-container"> 241 <div v-if="zoomElements[@canvasCounter]" class="slider-with-counter__zoom-level-indicator"> 242 <button @@click="zoomOnButton(@canvasCounter,true)" class="increase-decrease__button increase-decrease__button--up slider-with-counter__zoom-level-button slider-with-counter__zoom-level-button--plus"></button> 243 <div class="slider-with-counter__zoom-level-illustration"> 244 <span v-bind:style="'top:'+zoomDotPosition" class="slider-with-counter__zoom-level-illustration-dot"></span> 245 </div> 246 <button @@click="zoomOnButton(@canvasCounter,false)" class="increase-decrease__button increase-decrease__button--down slider-with-counter__zoom-level-button slider-with-counter__zoom-level-button--minus"></button> 247 </div> 248 <span class="slider-with-counter__zoom-indicator" style="background-image: url(@image.Url)"> 249 <span v-if="zoomElements[@canvasCounter]" v-bind:style="{paddingTop: zoomElements[@canvasCounter].thumbnailRatio}" class="slider-with-counter__zoom-indicator-aspect-ratio"></span> 250 <span v-if="zoomElements[@canvasCounter]" v-bind:style="{width:zoomThumbnailSize[@canvasCounter],height:zoomThumbnailSize[@canvasCounter],left:zoomThumbnailPositionComp[@canvasCounter].left,top:zoomThumbnailPositionComp[@canvasCounter].top}" class="slider-with-counter__zoom-indicator-excerpt"><span></span></span> 251 </span> 252 </div> 253 } 254 @{canvasCounter++;} 255 </li> 256 } 257 </ul> 258 <div class="slider-with-counter__navigation"> 259 <button @@click="slideToPrev(sliderInOverlay)" v-bind:class="{ 'slider-with-counter__button--show': sliderInOverlay.showButtonPrev}" class="slider-with-counter__button slider-with-counter__button--prev"> 260 <svg class="svg-icon slider-with-counter__svg"> 261 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow"></use> 262 </svg> 263 </button> 264 <button @@click="slideToNext(sliderInOverlay)" v-bind:class="{ 'slider-with-counter__button--show': sliderInOverlay.showButtonNext }" class="slider-with-counter__button slider-with-counter__button--next"> 265 <svg class="svg-icon slider-with-counter__svg"> 266 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow"></use> 267 </svg> 268 </button> 269 </div> 270 </div> 271 <div class="slider-with-counter__counter"> 272 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--plain" v-html="sliderInOverlay.counterTextBefore"></span> 273 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--number" v-html="sliderInOverlay.currentSlide"></span> 274 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--middle" v-html="sliderInOverlay.counterTextMiddle"></span> 275 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--number" v-html="slidesAmount"></span> 276 <span class="slider-with-counter__counter-part slider-with-counter__counter-part--plain" v-html="sliderInOverlay.counterTextAfter"></span> 277 </div> 278 </div> 279 <div class="novi-overlay__close-area"> 280 <button class="close-button novi-overlay__close-button"> 281 <span class="close-button__icon"> 282 <svg class="svg-icon close-button__svg"> 283 <use xlink:href="@Constants.DistPath/icons/icons.svg#cross"></use> 284 </svg> 285 </span> 286 <span class="close-button__text">@Translate("Product | Image overlay | Close", "Close")</span> 287 </button> 288 </div> 289 </div> 290 </div> 291 </div> 292 293 </div> 294 </div> 295 296 </div> 297 298 </div> 299 300 <div class="product-details__details-holder"> 301 <h2 class="product-text__header">@(B2cSiteActive ? @Translate("Product | B2C Tags", "B2C Tags") : @Translate("Product | Tags", "Tags"))</h2> 302 <ul class="product-details__tag-list"> 303 <li class="product-details__tag-item"> 304 @if (B2cSiteActive) 305 { 306 <span class="product-details__tag-link">@prodTypeName</span> 307 } 308 else 309 { 310 311 <a href="@(Model.GetTypeUrl(prodTypeValue))" class="product-details__tag-link">@prodTypeName</a> 312 } 313 </li> 314 @if (!B2cSiteActive) 315 { 316 <li class="product-details__tag-item"> 317 <a href="@(!string.IsNullOrWhiteSpace(prodConceptLink) ? prodConceptLink : Model.GetProductListUrl() + "?concept=" + prodConceptValue)" class="product-details__tag-link">@prodConceptName</a> 318 </li> 319 } 320 @if (B2cSiteActive) 321 { 322 <li class="product-details__tag-item"> 323 <span class="product-details__tag-link">@prodCollectionName</span> 324 </li> 325 326 } 327 else if (!string.IsNullOrWhiteSpace(prodCollectionLink)) 328 { 329 <li class="product-details__tag-item"> 330 <a href="@prodCollectionLink" class="product-details__tag-link">@prodCollectionName</a> 331 </li> 332 } 333 </ul> 334 335 <div id="@variantsDivId" ref="variantType_@variantListCounter" class="product-details__variants"> 336 @foreach (var designVariantLists in Model.ProduceListsOfDesignVariants()) 337 { 338 var activeProductId = HttpContext.Current.Request["ProductID"]; 339 var hideVariantsClass = "product-details__variant-type--hide"; 340 if (variantListCounter == 0) 341 { 342 hideVariantsClass = ""; 343 } 344 if (variantListCounter > 0) 345 { 346 <button ref="variantTypeButton_@variantListCounter" @@click="toggleVariantType(@variantListCounter)" class="product-text__read-more"><svg class="svg-icon product-text__svg"><use xlink:href="/dist/icons/icons.svg#arrow"></use></svg><span>@Translate(designVariantLists.TranslationKey, designVariantLists.TranslationDefaultValue)</span></button> 347 } 348 <div ref="variantType_@variantListCounter" class="product-details__variant-type @hideVariantsClass"> 349 <h2 class="product-text__header">@Translate(designVariantLists.TranslationKey, designVariantLists.TranslationDefaultValue)</h2> 350 <div class="product-details__variant-type-content"> 351 <div class="product-details__variant-truncate" :style="{'max-height':variantTruncateHeight[@variantListCounter]}"> 352 <ul class="product-details__variant-list"> 353 354 @foreach (var relatedProduct in designVariantLists.RelatedProducts.OrderBy(x => x.Id)) 355 { 356 var imagePath = ProductExtensions.GetProductImagePath(relatedProduct.Id, out bool relatedIsExternal, "XS"); 357 productLink = "/Default.aspx?ID=" + Pageview.Page.ID + "&amp;ProductID=" + relatedProduct.Id; 358 <li class="product-details__variant-item"> 359 <a href="@productLink" class="product-details__variant-link @(activeProductId == relatedProduct.Id ? "product-details__variant-link--active" : "")" title="@relatedProduct.Id"> 360 <figure class="product-details__variant-img"> 361 <img class="lazyload a-image lazyload-measure lazyload-bg " src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="@relatedProduct.Name" property="contentUrl" data-src="@(activeProductId == relatedProduct.Id ? (isExternal ? prodImage : ImageUiFormatHelper.Format(prodImage, 700, 700)) : (relatedIsExternal ? imagePath : ImageUiFormatHelper.Format(imagePath, 700, 700)))" 362 data-query-obj='{ }'> 363 <noscript v-if="false"> 364 <img src="@(activeProductId == relatedProduct.Id ? (isExternal ? prodImage : ImageUiFormatHelper.Format(prodImage, 700, 700)) : (relatedIsExternal ? imagePath : ImageUiFormatHelper.Format(imagePath, 700, 700)))" 365 alt="@relatedProduct.Name"> 366 </noscript> 367 </figure> 368 </a> 369 </li> 370 } 371 <li class="product-details__variant-item product-details__variant-item--adjustment"></li> 372 <li class="product-details__variant-item product-details__variant-item--adjustment"></li> 373 <li class="product-details__variant-item product-details__variant-item--adjustment"></li> 374 <li class="product-details__variant-item product-details__variant-item--adjustment"></li> 375 <li class="product-details__variant-item product-details__variant-item--adjustment"></li> 376 <li class="product-details__variant-item product-details__variant-item--adjustment"></li> 377 <li class="product-details__variant-item product-details__variant-item--adjustment"></li> 378 </ul> 379 </div> 380 </div> 381 <button class="product-details__see-all-variants" :class="{'product-details__see-all-variants--open':variantTypes[@variantListCounter].showAllVariants}" v-if="variantTypes[@variantListCounter] && variantTypes[@variantListCounter].moreVariantsThanOneLine" @@click="hideShowVariants(@variantListCounter)"> 382 <span class="product-details__see-all-variants-text product-details__see-all-variants-text--see-all"> 383 @Translate("Product | See all variants", "See all variants") 384 </span> 385 <span class="product-details__see-all-variants-text product-details__see-all-variants-text--see-less"> 386 @Translate("Product | See less variants", "See less variants") 387 </span> 388 389 <svg class="svg-icon product-details__see-all-variants-svg"> 390 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow-down-in-circle"></use> 391 </svg> 392 </button> 393 </div> 394 variantListCounter++; 395 } 396 </div> 397 @if (isCircleBack && !B2cSiteActive) 398 { 399 <div id="product-details__circle-back" class="product-details__variant-type"> 400 <img src="@ImageUiFormatHelper.Format("/Files/Files/Images/CircleBack/Ege_Circular_Black.png", 50, 55)" height="50" width="55" /> 401 <button ref="circleBackButton" v-show="!toggleCircleBack" @@click="initToggleCircleBack()" class="product-text__read-more"><svg class="svg-icon product-text__svg"><use xlink:href="/dist/icons/icons.svg#arrow"></use></svg><span>@Translate("EgeCircleBack:ReadMoreButtonText", "Ege CircleBack")</span></button> 402 <div v-show="toggleCircleBack" class="product-text__text"> 403 @circleBackText 404 </div> 405 </div> 406 } 407 <div class="product-text" data-button-text-1="@Translate("Read more", "Read more")" data-button-text-2="@Translate("Show less", "Show less")"> 408 <h2 class="product-text__header">@Model.ShortDescription</h2> 409 <div v-bind:style="{ maxHeight: maxHeight + 'px' }" class="product-text__text" v-bind:class="{'product-text__text--truncate':truncateText}"> 410 <div>@Model.LongDescription</div> 411 </div> 412 <button @@click="toggle" v-if="hasOverflow" class="product-text__read-more"> 413 <svg class="svg-icon product-text__svg"> 414 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow"></use> 415 </svg><span v-html="buttonText"></span> 416 </button> 417 </div> 418 419 @if (B2cSiteActive) 420 { 421 422 var B2CFullWidthPrice = string.Empty; 423 var B2CCarvingPrice = string.Empty; 424 var B2CAnyShapePrice = string.Empty; 425 var B2CAnyShapeExtraText = string.Empty; 426 427 if (Model.ProductCategories.Keys.Any()) 428 { 429 if (Model.ProductCategories.ContainsKey("CarpetCategory")) 430 { 431 var fields2 = Model.ProductCategories["CarpetCategory"]; 432 433 B2CFullWidthPrice = product.GetCategoryValue("CarpetCategory", "B2CFullWidthPrice").ToString(); 434 B2CCarvingPrice = product.GetCategoryValue("CarpetCategory", "B2CCarvingPrice").ToString(); 435 B2CAnyShapePrice = product.GetCategoryValue("CarpetCategory", "B2CAnyShapePrice").ToString(); 436 B2CAnyShapeExtraText = fields2.Fields["B2CAnyShapeExtraText"].Value as string; 437 } 438 439 } 440 441 <div class="remnants"> 442 <div class="remnants__header"> 443 <div class="remnants__headline">@Translate("Product details B2C | Remnants | Priser", "Priser")</div> 444 </div> 445 <ul class="remnants__list"> 446 @if (!string.IsNullOrWhiteSpace(B2CFullWidthPrice) && B2CFullWidthPrice != "0") 447 { 448 // adding decimals if not already present 449 var B2CFillWidthPriceFormatted = (B2CFullWidthPrice.Contains(',') ? B2CFullWidthPrice : B2CFullWidthPrice + ",00"); 450 451 <li class="remnants__item"> 452 <div class="remnants__item-inner"> 453 <div class="remnants__info remnants__info--first-column"> 454 <div class="remnants__info-text">@Translate("Product details B2C | Remnants | B2CFullWidthText", "Fuld bredde, pr. m2 inkl. moms")</div> 455 </div> 456 <div class="remnants__price remnants__price--first-column">@CurrencyCode @B2CFillWidthPriceFormatted</div> 457 </div> 458 </li> 459 } 460 @if (!string.IsNullOrWhiteSpace(B2CCarvingPrice) && B2CCarvingPrice != "0") 461 { 462 // adding decimals if not already present 463 var B2CCarvingPriceFormatted = (B2CCarvingPrice.Contains(',') ? B2CCarvingPrice : B2CCarvingPrice + ",00"); 464 465 <li class="remnants__item"> 466 <div class="remnants__item-inner"> 467 <div class="remnants__info remnants__info--first-column"> 468 <div class="remnants__info-text">@Translate("Product details B2C | Remnants | B2CCarvingText", "Udskåret mål, pr. m2 inkl. moms")</div> 469 </div> 470 <div class="remnants__price remnants__price--first-column">@CurrencyCode @B2CCarvingPriceFormatted</div> 471 </div> 472 </li> 473 } 474 @if (!string.IsNullOrWhiteSpace(B2CAnyShapePrice) && B2CAnyShapePrice != "0") 475 { 476 // adding decimals if not already present 477 var B2CAnyShapePriceFormatted = (B2CAnyShapePrice.Contains(',') ? B2CAnyShapePrice : B2CAnyShapePrice + ",00"); 478 479 <li class="remnants__item"> 480 <div class="remnants__item-inner"> 481 <div class="remnants__info remnants__info--first-column"> 482 <div class="remnants__info-text">@B2CAnyShapeExtraText</div> 483 </div> 484 <div class="remnants__price remnants__price--first-column">@CurrencyCode @B2CAnyShapePriceFormatted</div> 485 </div> 486 </li> 487 } 488 </ul> 489 </div> 490 } 491 492 @if (isOutletSite) 493 { 494 var addToBasketString = Translate("Product details | Remnants | Add to basket", "Add to basket"); 495 496 <div id="js-remnants" v-cloak class="remnants" data-text-options-singular="@Translate("Product details | Remnants | option (singular)", "option")" data-text-options-plural="@Translate("Product details | Remnants | options (plural)", "options")" data-text-product-singular="@Translate("Product details | Remnants | fault (singular)", "fault")" data-text-product-plural="@Translate("Product details | Remnants | faults (plural)", "faults")"> 497 <div class="remnants__header"> 498 <div class="remnants__headline">@Translate("Product details | Remnants | Choose carpet remnants", "Choose carpet remnants")</div> 499 <div class="remnants__items-available">{{remnantItems.length}} <span v-html="remnantItems.length === 1 ? textOptionsSingular : textOptionsPlural"></span></div> 500 </div> 501 <ul class="remnants__list" :class="{'remnants__list--show-all':showAll}"> 502 <li class="remnants__item" v-for="remnantItem in remnantItems" :key="remnantItem.VariantId"> 503 <div class="remnants__item-inner"> 504 <div class="remnants__input"> 505 <label :for="'remnant-input-'+remnantItem.VariantId" class="form__checkbox-label"> 506 <input :id="'remnant-input-'+remnantItem.VariantId" :value="remnantItem.VariantId" v-model="chosenRemnants" name="remnants" type="checkbox" class="form__input-checkbox"> 507 <span class="form__checkbox-label-text"></span> 508 </label> 509 </div> 510 <div class="remnants__area">{{remnantItem.AvailableArea}} m<sup>2</sup></div> 511 <div class="remnants__info"> 512 <div class="remnants__info-text">{{remnantItem.RollCorners}} @Translate("Product details | Remnants | corners", "corners"), {{remnantItem.NumberOfFlaws}} <span v-html="remnantItem.NumberOfFlaws === 1 ? textProductSingular : textProductPlural"></span><span class="remnants__waste-carpet" v-if="remnantItem.IsWasteCarpet"> (@Translate("Product details | Remnants | waste carpet", "waste carpet"))</span><span v-if="remnantItem.UnitPrice">, </span><span class="remnants__unit-price" v-if="remnantItem.UnitPrice">{{remnantItem.UnitPrice}} {{remnantItem.CurrencyCode}} @Translate("Product details | Remnants | per m2", "per m2")</span></div> 513 <button class="remnants__preview" @@click="showCarpetProfile(remnantItem.ProductNumber,remnantItem.M3BatchNumber,remnantItem.M3ProductNumber)">@Translate("Product details | Remnants | Outlet | Roll profile", "Roll profile")</button> 514 @if (ProductExtensions.GetOutletPatternPDF(patternNumber) != "") 515 { 516 <a target="_blank" class="remnants__pattern-pdf" href="@ProductExtensions.GetOutletPatternPDF(patternNumber)">@Translate("Product details | Remnants | Outlet | Pattern PDF", "Pattern PDF")</a> 517 } 518 </div> 519 <div class="remnants__price">{{Number(remnantItem.Price).toLocaleString('en-GB') }} {{remnantItem.CurrencyCode}}</div> 520 </div> 521 </li> 522 <div class="remnants__additional-costs-msg" v-if="remnantItems.length > 0">@Translate("Product details | Remnants | Additional costs message", "Delivery costs will be added")</div> 523 </ul> 524 <div class="remnants__footer"> 525 <div class="remnants__show-all-holder"> 526 <button class="remnants__show-all" @@click="doShowAll" :class="{'remnants__show-all--show':showShowAll}">@Translate("Product details | Remnants | Show all", "Show all") ({{remnantItems.length}})</button> 527 </div> 528 <button @@click="addChosenToBasket" type="button" property="url" 529 class="button button--solid button--black button--wait-animation" 530 data-service="@cartOrderLinesFeedUrl" 531 v-bind:class="{'button--error':showErrorOnButton,'button--wait':showWaitAnimation}" 532 data-text="@addToBasketString"> 533 <span class="button__error-message"> 534 @Translate("Product details | Remnants | You haven't selected any products to add to basket", "You haven't selected any products to add to basket") 535 </span> 536 <span class="button__wait-animation"> 537 <span></span> 538 <span></span> 539 <span></span> 540 <span></span> 541 </span> 542 <span class="button__content"> 543 <span class="button__icon"> 544 <svg class="svg-icon button__svg"> 545 <use xlink:href="@Constants.DistPath/icons/icons.svg#samples"></use> 546 </svg> 547 </span> 548 <span class="button__text">@addToBasketString</span> 549 </span> 550 </button> 551 </div> 552 553 <div @@click="closeProfileOverlay" class="novi-backdrop novi-backdrop--hidden novi-backdrop--carpet-profile" :class="{'novi-backdrop--shown':showProfileOverlay}"> 554 <div class="novi-overlay"> 555 <div class="novi-overlay__container"> 556 <div class="novi-overlay__content" @@click="stopProp"> 557 <div class="carpet-profile"> 558 <header class="carpet-profile__header"> 559 <h2 class="subheader-in-component js-alt-color-gold"> 560 @Translate("Product details | Remnants | Error table | header | Error profile", "Error profile") 561 </h2> 562 <p v-if="currentChosenProfileIndex !== null">@Translate("Product details | Remnants | Profile overlay | For product number", "For product number"): <span v-html="remnantProfiles[currentChosenProfileIndex].M3productNumber"></span> @Translate("Product details | Remnants | Profile overlay | Batch number", "Batch number"): <span v-html="remnantProfiles[currentChosenProfileIndex].batchNumber"></span></p> 563 </header> 564 <div class="row"> 565 <div class="col-xs-12"> 566 <img class="carpet-profile__img" id='base64image' v-if="currentChosenProfileIndex !== null" 567 :src="'data:image/jpeg;base64, '+remnantProfiles[this.currentChosenProfileIndex].data.profileBase64" /> 568 <p class="carpet-profile__draw-outline" v-if="currentChosenProfileIndex !== null" v-html="remnantProfiles[this.currentChosenProfileIndex].data.profileText"></p> 569 570 <table class="carpet-profile__fault-list" v-if="currentChosenProfileIndex !== null && remnantProfiles[this.currentChosenProfileIndex].data.faults.length"> 571 <tr class="carpet-profile__fault-list-item carpet-profile__fault-list-item--header"> 572 <th class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--header">@Translate("Product details | Remnants | Error table | Error code", "Error code")</th> 573 <th class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--header">@Translate("Product details | Remnants | Error table | Error rank", "Error rank")</th> 574 <th class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--header">@Translate("Product details | Remnants | Error table | Text", "Text")</th> 575 <th class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--header">@Translate("Product details | Remnants | Error table | Width from", "Width from")</th> 576 <th class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--header">@Translate("Product details | Remnants | Error table | Width to", "Width to")</th> 577 <th class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--header">@Translate("Product details | Remnants | Error table | Length from", "Length from")</th> 578 <th class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--header">@Translate("Product details | Remnants | Error table | Length to", "Length to")</th> 579 </tr> 580 <tr class="carpet-profile__fault-list-item" v-for="fault in remnantProfiles[this.currentChosenProfileIndex].data.faults"> 581 <td data-header="@Translate("Product details | Remnants | Error table | Error code", "Error code")" class="carpet-profile__fault-list-cell" v-html="fault.reasonCode"></td> 582 <td data-header="@Translate("Product details | Remnants | Error table | Error rank", "Error rank")" class="carpet-profile__fault-list-cell" v-html="fault.errorRank"></td> 583 <td data-header="@Translate("Product details | Remnants | Error table | Text", "Text")" class="carpet-profile__fault-list-cell carpet-profile__fault-list-cell--text" v-html="fault.textForReason"></td> 584 <td data-header="@Translate("Product details | Remnants | Error table | Width from", "Width from")" class="carpet-profile__fault-list-cell" v-html="fault.brdStart"></td> 585 <td data-header="@Translate("Product details | Remnants | Error table | Width to", "Width to")" class="carpet-profile__fault-list-cell" v-html="fault.brdEnd"></td> 586 <td data-header="@Translate("Product details | Remnants | Error table | Length from", "Length from")" class="carpet-profile__fault-list-cell" v-html="fault.lgdStart"></td> 587 <td data-header="@Translate("Product details | Remnants | Error table | Length to", "Length to")" class="carpet-profile__fault-list-cell" v-html="fault.lgdEnd"></td> 588 </tr> 589 </table> 590 </div> 591 </div> 592 </div> 593 <div class="novi-overlay__close-area"> 594 <button @@click="closeProfileOverlay" class="close-button novi-overlay__close-button"> 595 <span class="close-button__icon"> 596 <svg class="svg-icon close-button__svg"> 597 <use xlink:href="@Constants.DistPath/icons/icons.svg#cross"></use> 598 </svg> 599 </span> 600 <span class="close-button__text">@Translate("Product | Sample overlay | Close", "Close")</span> 601 </button> 602 </div> 603 </div> 604 </div> 605 </div> 606 </div> 607 </div> 608 } 609 else 610 { 611 <span> 612 <div class="button-double product-details__buttons"> 613 @if (!B2cSiteActive && !string.IsNullOrWhiteSpace(Model.GetCadesignProperties().ToolUrl) && !isProductRug) 614 { 615 string firstBtnText = string.Empty; 616 617 if (Model.GetCadesignProperties().IsTile) 618 { 619 firstBtnText = Translate("Product | Tile", "Create your tile design"); 620 } 621 else if (Model.GetCadesignProperties().Recolour) 622 { 623 firstBtnText = Translate("Product | Customize", "Customize"); 624 } 625 else 626 { 627 firstBtnText = Translate("Product | Visualize", "Visualize"); 628 } 629 <button data-href="@Model.GetCadesignProperties().ToolUrl" @@click="openCustomizeOverlay" class="button button--ghost button--black js-customize-button" data-text="@firstBtnText"> 630 <span class="button__content"> 631 <span class="button__icon"> 632 <svg class="svg-icon button__svg"> 633 <use xlink:href="@Constants.DistPath/icons/icons.svg#magic-wand"></use> 634 </svg> 635 </span> 636 <span class="button__text">@firstBtnText</span> 637 </span> 638 <div class="product-details__hide js-customize-iframe-holder"> 639 <div class="product-details__iframe-holder"> 640 <iframe class="product-details__customize-iframe" frameborder="0"></iframe> 641 <span class="product-details__wait-animation"> 642 <span></span> 643 <span></span> 644 <span></span> 645 <span></span> 646 </span> 647 </div> 648 </div> 649 </button> 650 } 651 else if (isProductRug) 652 { 653 if (showConfigurator) 654 { 655 string firstBtnText = string.Empty; 656 firstBtnText = Translate("Product | Rug configurator", "Configure rug"); 657 <a href="@configuratorFullLink" target="_blank" class="button button--ghost button--black js-customize-button"> 658 <span class="button__content"> 659 <span class="button__icon"> 660 <svg class="svg-icon button__svg"> 661 <use xlink:href="@Constants.DistPath/icons/icons.svg#magic-wand"></use> 662 </svg> 663 </span> 664 <span class="button__text">@firstBtnText</span> 665 </span> 666 <div class="product-details__hide js-customize-iframe-holder"> 667 <div class="product-details__iframe-holder"> 668 <iframe class="product-details__customize-iframe" frameborder="0"></iframe> 669 <span class="product-details__wait-animation"> 670 <span></span> 671 <span></span> 672 <span></span> 673 <span></span> 674 </span> 675 </div> 676 </div> 677 </a> 678 } 679 } 680 681 682 else if (B2cSiteActive && !string.IsNullOrWhiteSpace(Model.GetFieldValue<string>("ProductBacking")) && !string.IsNullOrWhiteSpace(Model.GetFieldValue<string>("ProductSpecificationCode"))) 683 { 684 var prod = Dynamicweb.Ecommerce.Services.Products.GetProductByNumber(Model.GetFieldValue<string>("ProductBacking"), Model.LanguageId); 685 686 <form method="post" action="/api/specifications/getpdf" class="button-double__form"> 687 <input type="hidden" name="backingCode" value="@(Model.GetFieldValue<string>("ProductBacking"))" /> 688 <input type="hidden" name="backingName" value="@(ProductExtensions.GetProductName(product))" /> 689 <input type="hidden" name="qualityName" value="@prodCollectionName" /> 690 <input type="hidden" name="collectionCode" value="@Model.GetFieldValue("ProductCollectionCode")" /> 691 <input type="hidden" name="specificationCode" value="@(Model.GetFieldValue<string>("ProductSpecificationCode"))" /> 692 <input type="hidden" name="nationalityCode" value="@Dynamicweb.Ecommerce.Common.Context.Language.CountryCode" /> 693 <input type="hidden" name="areaId" value="@Pageview.AreaID" /> @* On the B2C site we hardcode the area id to the danish b2b site to pull the sustainability stores from there(these are defined in website settings) *@ 694 <input type="hidden" name="productName" value="@Model.Name" /> 695 <input type="hidden" name="sustainabilityChoice" value="@sustainabilityChoices" /> 696 <button type="submit" property="url" class="button button--ghost button--black" data-text="@Translate("Product details | Specifications | Download full specifications", "Download full specifications")" @@click="downloadFullSpecifications" ref="showFullSpecificationsSubmitButton"> 697 <span class="button__content"> 698 <span class="button__icon"> 699 <svg class="svg-icon button__svg"> 700 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow-down-in-circle"></use> 701 </svg> 702 </span> 703 <span class="button__text"> 704 @Translate("Product details | Specifications | Download full specifications", "Download full specifications") 705 </span> 706 </span> 707 </button> 708 </form> 709 } 710 @if (!B2cSiteActive && (variantCombinations.Any() || Model.GetRelatedGroupById("RELGRP1").Any())) 711 { 712 var nonVariantSamples = Model.GetRelatedGroupById("RELGRP1"); 713 var showSamplesVersion = ""; 714 if (variantCombinations.Any()) 715 { 716 showSamplesVersion = "showSamplesAdvanced"; 717 } 718 else if (nonVariantSamples.Any()) 719 { 720 showSamplesVersion = "showSamplesSimple"; 721 } 722 <button id="js-add-to-samples-button" type="button" class="button button--solid button--black " @@click="@showSamplesVersion" data-text="@Translate("Product | Add to samples", "Add to samples")"> 723 <span class="button__content"> 724 <span class="button__icon"> 725 <svg class="svg-icon button__svg"> 726 <use xlink:href="@Constants.DistPath/icons/icons.svg#samples"></use> 727 </svg> 728 </span> 729 <span class="button__text">@Translate("Product | Add to samples", "Add to samples")</span> 730 </span> 731 </button> 732 } 733 else if (B2cSiteActive) 734 { 735 if (IsBulkCarpets && prodCollectionName != "Geometrica Rugs") 736 { 737 var shapeOverlayBtnText = Translate("Product | See rug in room", "Se tæppet i rum"); 738 var shapeToolUrl = ProductExtensions.CadesignServiceUrl + "/rug-ui.html?prod=" + @Model.Id; 739 <button data-href="@shapeToolUrl" @@click="openCustomizeOverlay" 740 class="button button--solid button--black js-customize-button" 741 data-text="@shapeOverlayBtnText"> 742 <span class="button__content"> 743 <span class="button__icon"> 744 <svg class="svg-icon button__svg"> 745 <use xlink:href="@Constants.DistPath/icons/icons.svg#magic-wand"></use> 746 </svg> 747 </span> 748 <span class="button__text">@shapeOverlayBtnText</span> 749 </span> 750 <div class="product-details__hide js-customize-iframe-holder"> 751 <div class="product-details__iframe-holder"> 752 <iframe class="product-details__customize-iframe" frameborder="0"></iframe> 753 <span class="product-details__wait-animation"> 754 <span></span> 755 <span></span> 756 <span></span> 757 <span></span> 758 </span> 759 </div> 760 </div> 761 </button> 762 } 763 else 764 { 765 <button id="js-product-details__contact-form-link-button" @@click="scrollDown" type="button" class="button button--solid button--black " data-text="@Translate("Product | B2C Kontakt Os Knap", "B2C Kontakt Os Knap")"> 766 <span class="button__content"> 767 <span class="button__icon"> 768 <svg class="svg-icon button__svg"> 769 <use xlink:href="@Constants.DistPath/icons/icons.svg#contact"></use> 770 </svg> 771 </span> 772 <span class="button__text">@Translate("Product | B2C Kontakt Os Knap", "B2C Kontakt Os Knap")</span> 773 </span> 774 </button> 775 } 776 } 777 @if (!B2cSiteActive) 778 { 779 <div class="product-details__contact-form-link"> 780 <span class="product-details__contact-form-link-left">@Translate("Product | Do you need help", "Do you need help?")</span> 781 <span class="product-details__contact-form-link-right"> 782 <button type="button" id="js-product-details__contact-form-link-button" class="product-details__contact-form-link-button" @@click="scrollDown"> 783 @Translate("Product | Contact us", "Contact us") 784 <span class="product-details__contact-form-link-arrow"> 785 <svg class="svg-icon product-details__contact-form-link-arrow-svg"> 786 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow"></use> 787 </svg> 788 </span> 789 </button> 790 </span> 791 </div> 792 } 793 else if (B2cSiteActive && !string.IsNullOrEmpty(prodB2CCollectionLink)) 794 { 795 <div class="product-details__contact-form-link product-details__contact-form-link--b2c"> 796 <a href="@prodB2CCollectionLink" type="button" class="product-details__contact-form-link-button"> 797 @Translate("Product | B2C Se vores Priser", "Se vores priser her!") 798 <span class="product-details__contact-form-link-arrow product-details__contact-form-link-arrow--b2c"> 799 <svg class="svg-icon product-details__contact-form-link-arrow-svg"> 800 <use xlink:href="@Constants.DistPath/icons/icons.svg#arrow"></use> 801 </svg> 802 </span> 803 </a> 804 </div> 805 } 806 </div> 807 </span> 808 <div> 809 @TemplateHelper.RenderPartial("Ecom/Partials/Details_SelectedSamplesOverlay.cshtml") 810 @TemplateHelper.RenderPartial("Ecom/Partials/Details_AddToSamples.cshtml", Model) 811 </div> 812 } 813 </div> 814 </div> 815 816 </div> 817 </section> 818 819 if (isOutletSite) 820 { 821 822 } 823 else if (B2cSiteActive) 824 { 825 @TemplateHelper.RenderPartial("Ecom/Partials/Details_B2CGuidesAndImages.cshtml", Model) 826 } 827 else 828 { 829 @TemplateHelper.RenderPartial("Ecom/Partials/Details_B2BGuidesAndImages.cshtml", Model) 830 @TemplateHelper.RenderPartial("Ecom/Partials/Details_SpecificationsAndHighlights.cshtml", Model) 831 } 832 } 833

Vil du vide mere?

Så lad os kontakte dig

Har du spørgsmål eller forespørgsler om Ege Carpets eller vores tæpper, er du velkommen til at kontakte os.

Indsæt dine kontakt informationer og vi vil kontakte dig - eller du kan finde kontaktoplysningerne på en forhandler.