> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onelox.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Integrate your weclapp ERP system

export const Groups = {
  essentials: {
    label: "Essentials"
  },
  products: {
    label: "Product related features"
  },
  delivery_notes: {
    label: "Delivery Note related features"
  },
  inventory: {
    label: "Inventory related features"
  },
  shipments: {
    label: "Shipment related features"
  },
  warehouses: {
    label: "Warehouse related features"
  },
  additional: {
    label: "Integration specific features"
  }
};

export const Features = {
  essentials: {
    ProductData: {
      id: "essentials.product_data",
      label: "Basic Product data (i.e. name, SKU)",
      categoryLabel: "Essentials"
    },
    DeliveryNotes: {
      id: "essentials.delivery_notes",
      label: "Delivery Notes",
      categoryLabel: "Essentials"
    },
    Shipments: {
      id: "essentials.shipments",
      label: "Shipments",
      categoryLabel: "Essentials"
    },
    Inventory: {
      id: "essentials.inventory",
      label: "Inventory",
      categoryLabel: "Essentials"
    }
  },
  products: {
    PartsLists: {
      id: "products.parts_lists",
      label: "Parts Lists",
      categoryLabel: "Product related features"
    },
    Filtering: {
      id: "products.filtering",
      label: "Filtering",
      categoryLabel: "Product related features"
    }
  },
  delivery_notes: {
    Filtering: {
      id: "delivery_notes.filtering",
      label: "Delivery Note filtering",
      categoryLabel: "Delivery Note related features"
    },
    Documents: {
      id: "delivery_notes.documents",
      label: "Delivery Note Documents",
      categoryLabel: "Delivery Note related features"
    }
  },
  shipments: {
    Batches: {
      id: "shipments.batches",
      label: "Batch data for shipped items",
      categoryLabel: "Shipping related features"
    },
    SellByDates: {
      id: "shipments.sell_by_dates",
      label: "Sell by date data for shipped items",
      categoryLabel: "Shipping related features"
    },
    PartialShipments: {
      id: "shipments.partial_shipments",
      label: "Partial and multiple Shipments",
      categoryLabel: "Shipping related features"
    }
  },
  inventory: {
    Types: {
      id: "inventory.types",
      label: "Inventory types",
      categoryLabel: "Inventory related features"
    },
    Shelves: {
      id: "inventory.shelves",
      label: "Inventory shelves",
      categoryLabel: "Inventory related features"
    },
    Batches: {
      id: "inventory.batches",
      label: "Inventory batches",
      categoryLabel: "Inventory related features"
    },
    SellByDates: {
      id: "inventory.sell_by_dates",
      label: "Inventory sell by dates",
      categoryLabel: "Inventory related features"
    },
    Warehouses: {
      id: "inventory.warehouses",
      label: "Inventory warehouses",
      categoryLabel: "Inventory related features"
    }
  },
  warehouses: {
    Warehouses: {
      id: "warehouses.multiple_warehouses",
      label: "Multiple warehouses",
      categoryLabel: "Warehouse related features"
    },
    Routing: {
      id: "warehouses.native_routing",
      label: "Native routing",
      categoryLabel: "Warehouse related features"
    }
  }
};

export const FeatureList = ({features = [], additionalFeatures = [], type = 'data_source'}) => {
  let featuresByCategory = {};
  const categories = type === 'data_source' ? Features : FulfillerFeatures;
  const groups = type === 'data_source' ? Groups : FulfillerGroups;
  for (let featureCategory in categories) {
    let categoryFeatures = categories[featureCategory], integrationFeatures = featuresByCategory[groups[featureCategory].label] || [];
    for (let availableFeature in categoryFeatures) {
      let featureDefinition = categoryFeatures[availableFeature], integrationFeatureSupport = {
        label: featureDefinition.label,
        supported: false,
        comment: null
      };
      features.forEach(feature => {
        if (feature.id === featureDefinition.id) {
          integrationFeatureSupport.supported = feature.supported === undefined ? true : feature.supported;
          integrationFeatureSupport.comment = feature.comment || null;
        }
      });
      integrationFeatures.push(integrationFeatureSupport);
    }
    featuresByCategory[groups[featureCategory].label] = integrationFeatures;
  }
  if (additionalFeatures.length) {
    featuresByCategory[groups.additional.label] = additionalFeatures;
  }
  return FeatureTable.render(featuresByCategory);
};

export const FeatureTable = {
  renderTableHeader(heading) {
    return <tr>
                <th>{heading}</th>
            </tr>;
  },
  renderTableRow(featureDefinition) {
    return <tr>
            <td>{featureDefinition.label}</td>
            <td><strong>{featureDefinition.supported ? 'x' : '-'}</strong></td>
            <td>{featureDefinition.comment}</td>
        </tr>;
  },
  render(featuresByCategory) {
    let rows = [];
    for (let category in featuresByCategory) {
      rows.push(this.renderTableHeader(category));
      featuresByCategory[category].forEach(feature => {
        rows.push(this.renderTableRow(feature));
      });
    }
    return <div>
            <h2>Feature list</h2>
            <table>
                <thead>
                <tr>
                    <th>Feature</th>
                    <th>Supported</th>
                    <th>Additional information</th>
                </tr>
                </thead>
                <tbody>
                {rows}
                </tbody>
            </table>
        </div>;
  }
};

<FeatureList
  features={[
{
    id: Features.essentials.ProductData.id
},
{
    id: Features.essentials.DeliveryNotes.id
},
{
    id: Features.essentials.Shipments.id
},
{
    id: Features.essentials.Inventory.id
},
{
    id: Features.delivery_notes.Filtering.id,
    comment: "Delivery Notes are filterable by warehouse"
},
{
    id: Features.products.PartsLists.id,
    comment: "Parts lists configured in ONELOX will be resolved from a basic weclapp item, if enabled. Once enabled, parts lists must NOT be resolved in weclapp"
},
{
    id: Features.products.Filtering.id,
    comment: "Products can be filtered via custom field to configure inclusion"
},
{
    id: Features.inventory.Batches.id
},
{
    id: Features.inventory.Warehouses.id
},
{
    id: Features.shipments.PartialShipments.id,
    comment: "weclapp does not natively support multiple Shipments per Delivery Note. ONELOX utilizes custom fields to add multiple tracking codes and URLs"
},
{
    id: Features.shipments.Batches.id
},
{
    id: Features.warehouses.Warehouses.id
},
{
    id: Features.warehouses.Routing.id,
    comment: "weclapp warehouse IDs may be mapped to a ONELOX warehouse by using external references"
}
]}
  additionalFeatures={[
{
    label: "Position filtering",
    supported: true,
    comment: "Delivery note positions may be filtered via an additional custom field to configure exclusion"
}
]}
/>
