Convert Basket to Order

Convert Basket to Order 

public class ExtendedOrdersApi : OrdersApi
    {
        public override IOrderLine ConvertToOrderLine(IBasketLine basketLine)
        {
            var line =  base.ConvertToOrderLine(basketLine);
 
            /// Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.            
            ((OrderLine)line).RangeValueList = ((BasketLine)basketLine).RangeValueList;
            return line;
        }
        
    }


public class ExtendedOrderCheckoutProcess : OrderCheckoutProcess
protected override IList<IOrderLine> ConvertBasketLinesToOrderLines(IList<IBasketLine> basketLines)
        {
            var result =base.ConvertBasketLinesToOrderLines(basketLines);            
 
            return result;
        }







steps Sana

 when add item to basket 

call /en-us/basket/addproductline

basket control > addproductline

ExtendedBasketApi > AddProductLines()
call CreateBasketLine


Then Go to basket Page

call calculate basket

ExtendedOrderProvider > CreateBasketRequest


 when click Proced to checkout

call calculate basket


when submit click

order provide >

convert basket to order









input field with default validation

use same id for  input field 

Holz pitch project. 3.3 issue.

https://sanacommerce.visualstudio.com/Sana%20Projects/_workitems/edit/93818/

Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.

Page :- _RangeValues




<input id="RangeValueList[@i]"

and span 

data-valmsg-for="RangeValueList[@i]"


<div class="rangeValueitem form-row">
        <label for="@rangeValue.Id">@rangeValue.Name</label>
        <div class="tbx">
            <input id="RangeValueList[@i]" required
                   name="RangeValueList[@i]"
                   type="text"
                   class="valid" aria-invalid="false"
                   min="@rangeValue.MinimumValue"
                   max="@rangeValue.MaximumValue" step="@rangeValue.Step">
        </div>
        <span data-valmsg-for="RangeValueList[@i]" data-valmsg-replace="true"></span>
        @*This hidden field used to get Range values 'Name' list to match with the Range values's 'Value' pass by 'RangeValueList'*@
        <input id="@fieldName" name="RangeValueListNames[@i]" type="hidden" value="@rangeValue.Id">
    </div>

 

step use to get decimal points 

https://stackoverflow.com/questions/34057595/allow-2-decimal-places-in-input-type-number/34057860

max="@rangeValue.MaximumValue" step="@rangeValue.Step">











When click Submit button , How to pass values from view to model.

 How to pass value which can not 



 <div class="rangeValueitem">

        <label for="@rangeValue.Id">@rangeValue.Name</label>

        <div class="tbx">

            <input id="@rangeValue.Id" required name="RangeValueList[@i]" type="text" value="@rangeValue.MinimumValue" class="valid" aria-invalid="false" min="@rangeValue.MinimumValue" max="@rangeValue.MaximumValue">

        </div>

        <span class="field-validation-valid" data-valmsg-for="@rangeValue.Id" data-valmsg-replace="true">pp</span>


        <input id="@fieldName" name="RangeValueListNames[@i]" type="hidden" value="@rangeValue.Id">

    </div>

@*Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.*@
@model ProductViewModel
@{ 
    var variants = Model.Product.Variants;
    var rangeValueList = ((Product)Model.Product).RangeValueList;
} 
@{
    if (rangeValueList.Count > 0//set list.count > 0 
    {
        var rangeValueListSort = rangeValueList.OrderBy(x => x.SortNumber).ToList();
        int i = 0;
 
        foreach (var rangeValue in rangeValueListSort) 
        {
            string fieldName = rangeValue.Id + "_" + rangeValue.Name;
 
            <div class="rangeValueitem form-row">
                <div class="control">
                    <div class="label">
                        <label for="@rangeValue.Id">@rangeValue.Name</label>
                    </div>
                    <div class="field">
                        <div class="tbx">
                            <input id="RangeValueList[@i]" required
                                   name="RangeValueList[@i]"
                                   type="text"
                                   class="valid" aria-invalid="false"
                                   min="@rangeValue.MinimumValue"
                                   max="@rangeValue.MaximumValue"> 
                        </div>
                        <span data-valmsg-for="RangeValueList[@i]" data-valmsg-replace="true"></span>
                    </div> 
                </div>
 
                @*This hidden field used to get Range values 'Name' list to match with the Range values's 'Value' pass by 'RangeValueList'*@
                <input id="@fieldName" name="RangeValueListNames[@i]" type="hidden" value="@rangeValue.Id"> 
            </div>
            i++;
        }
    }

When click Submit button , How to pass Range values

create range value list as above  Html,


When Click submit button it will call Basket controlr >  AddProductLine(ProductLine line)

Then ExtendeProductLine class and add as folowing 

public class ExtendedProductLine : ProductLine
    {
        /// Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.
        /// <summary>
        /// Gets or sets the Range Value List.
        /// </summary>
        public List<string> RangeValueList { getset; }
 
        /// Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.
        /// <summary>
        /// Get the sorted Range Value name list.
        /// </summary>
        public List<string> RangeValueListNames { getset; }
        
    }


use Kinseys_935 project also need to check .




Sort/Filter field translation

 


search the code 

var titleKey = "General_Product_" + field.Name;
       var orderedTitleKey = titleKey + (ascending ? "_Asc" : "_Desc");
       var fieldTitle = Sana.SimpleText(titleKey, field.Title.Or(field.Name)).Decode();

run the project and add necessary Filterfields > 

Sana Admin > ERP interaction > Filterfields section add fields. 

Add fields to Sort fields and Enable > product index need to run

debug the code and get the names

ar titleKey = "General_Product_" + field.Name;
       var orderedTitleKey = titleKey + (ascending ? "_Asc" : "_Desc");
       var fieldTitle = Sana.SimpleText(titleKey, field.Title.Or(field.Name)).Decode();



parse xml / Fill Properties /Read xml

 Fill Properties /Read xml 

Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.

ExtendedOrderXmlParser

public override IBasketLine ParseBasketLine(XElement element)
{
    var result = ParseEntity<IBasketLine>(element, (fields, basketLine) =>
    {
        FillSalesLineProperties(fields, basketLine);
 
 
        var rangeValueList = ParseRangeValueLineList(element.Element("RangeValues")) as List<RangeValue>; ;
        ((BasketLine)basketLine).RangeValueList = rangeValueList;
 
 
        basketLine.AvailableSalesAgreementLines = ParseAvailableSalesAgreementLines(element);
        if (basketLine.IsSupplementary)
        {
            basketLine.StoredProductTitle = basketLine.ProductTitle;
            basketLine.StoredVariantTitle = basketLine.Title;
        }
    });
    if (result != null)
        RenameFields(result.Fields, "UnitOfMeasureDescription_""UOMDescription_");
 
    return result;
}
 
protected virtual IList<RangeValue> ParseRangeValueLineList(XElement rangeValueElement)
{
    return ParseList<RangeValue>(rangeValueElement, "RangeValue", ParseRangeValueLine);
}
 
protected virtual RangeValue ParseRangeValueLine(XElement element)
{
    return ParseEntity<RangeValue>(element, (fields, result) =>
    {
        result.Id = fields.ReadString("Id");
        result.Name = fields.ReadString("Name");
        result.Value = fields.ReadDecimal("Value").GetValueOrDefault();
        result.SortNumber = fields.ReadInt("SortNumber").GetValueOrDefault();
    });
}


Ticket 96724: [Kavo] 3.16 SEARCH – OEM# AND COMPETITOR# FIELDS

sample Respons from Get Product for OEMReferanceNo (String List)
<field name="ConfiguratorModel" value="" />
      <field name="ModifiedDate" value="21-01-21 10:17:00" />
      <Attachments></Attachments>
      <RelatedProducts></RelatedProducts>
      <OemReferenceNumbers>
        <ReferenceNumber>1741084A00</ReferenceNumber>
        <ReferenceNumber>1741084A11</ReferenceNumber>
        <ReferenceNumber>2101000Q0E</ReferenceNumber>
        <ReferenceNumber>2101000QAE</ReferenceNumber>
        <ReferenceNumber>2101000QAS</ReferenceNumber>
        <ReferenceNumber>21010BN700</ReferenceNumber>
        <ReferenceNumber>7701473327</ReferenceNumber>
        <ReferenceNumber>7701475995</ReferenceNumber>
        <ReferenceNumber>7701476496</ReferenceNumber>
        <ReferenceNumber>7701774435</ReferenceNumber>
        <ReferenceNumber>8200035221</ReferenceNumber>
        <ReferenceNumber>8200438425</ReferenceNumber>
        <ReferenceNumber>7701478031</ReferenceNumber>
        <ReferenceNumber>21310010190</ReferenceNumber>
      </OemReferenceNumbers>
    </Product>
  </Result>

How to parse XML List of String

public override IProduct ParseProduct(XElement element)
        {
            var product = base.ParseProduct(element);

            //Competitors
            ((Product)product).Competitors = ParseCompetitors(element.Element("Competitors"));

 
            //OemReferenceNumbers
            ((Product)product).OemReferenceNumbers = ParseOemReferenceNumbers(element.Element("OemReferenceNumbers"));
            
            return product;
        } 


protected virtual List<string> ParseOemReferenceNumbers(XElement element)
        {
            var oemReferenceNumbers = new List<string>();
            if (element == null)
                return oemReferenceNumbers;
            
            foreach (var child in element.Elements())
            { 
                oemReferenceNumbers.Add(child.Value);
            }  
            return oemReferenceNumbers;
        }


sample Respons from Get Product for Competotors (object)
<field name="Barcodes" value="" />
      <field name="ConfiguratorModel" value="" />
      <field name="ModifiedDate" value="21-01-21 12:18:00" />
      <Attachments></Attachments>
      <RelatedProducts></RelatedProducts>
      <Competitors>
        <Competitor id="182" name="Ashika" reference="95-03-393" />
        <Competitor id="227" name="Girling" reference="1207105" />
        <Competitor id="49" name="Japanparts" reference="FR-320" />
        <Competitor id="230" name="Japko" reference="95393" />
        <Competitor id="23" name="Nipparts" reference="J2503019" />
        <Competitor id="136" name="NPS" reference="M250A24" />
        <Competitor id="129" name="TRW" reference="PNK105" />
        <Competitor id="1579" name="Seiken" reference="110-20472" />
      </Competitors> </Product>

protected virtual List<CompetitorParseCompetitors(XElement element)
        {
            var competitors = new List<Competitor>();
            if (element == null)
                return competitors;
            
            foreach (var child in element.Elements())
            {                
                var competitor = ParseCompetitor(child);
                if (!competitors.Any(item => item.Equals(competitor)))
                    competitors.Add(competitor);
            }
            return competitors;
        }


/// Ticket 96724: [Kavo] 3.16 SEARCH – OEM# AND COMPETITOR# FIELDS 
        /// <summary>
        /// Parse the competitor.
        /// </summary>
        /// <param name="element">The XML element.</param>
        /// <returns></returns>
        protected virtual Competitor ParseCompetitor(XElement element)
        {
            var competitor = ObjectFactory.Create<Competitor>();
            competitor.Id = element.Attribute("id")?.Value;
            competitor.Name = element.Attribute("name")?.Value;
            competitor.Reference = element.Attribute("reference")?.Value;
            return competitor;
        }


// Top media 

<Response>
  <Version>9.3.5.1</Version>
  <Result>
    <ProductType>
      <field name = "Code" value="Laptop" />
      <field name = "Name" value="Laptop" />
    </ProductType>
    <ProductType>
      <field name = "Code" value="Mobile" />
      <field name = "Name" value="Mobile" />
    </ProductType> 
    <TotalTimeElapsed>1.473</TotalTimeElapsed>
  </Result>
</Response>


public class ExtendedCommonProvider
/// Ticket 100006: [Topmedia] 3.1. Search – Product Finder        
        public virtual IList<IProductType> GetProductTypes()
        {
            var request = new List<XElement>(); 
            var result = ExecuteRequest("GetProductTypes", request); 
             var productTypes = result.Elements("ProductType").Select(e => ((ExtendedCommonXmlParser)Parser).ParseProductType(e)).ToList();
             
            foreach (var item in productTypes)
            {
                item.WebsiteId = Context.WebsiteId;
            }
            return productTypes;
        }
public class ExtendedCommonXmlParser : CommonXmlParser
   {
       /// Ticket 100006: [Topmedia] 3.1. Search – Product Finder      
       public virtual IProductType ParseProductType(XElement element)
       {
           return ParseEntity<IProductType>(element, (fields, result) =>
           {
               result.Code = fields.ReadString("Code");
               result.Name = fields.ReadString("Name");
           });                      
 
       } 
   }