diff --git a/CHANGELOG.md b/CHANGELOG.md index 06cb0912cad..5c3bc419e7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,33 +2,59 @@ All notable changes for each version of this project will be documented in this file. + ## 20.1.0 + ### New Features -- `IgxCarousel` - - Added `select` method overload accepting index. - ```ts - this.carousel.select(2, Direction.NEXT); - ``` + - `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid` + - Introduced a new cell merging feature that allows you to configure and merge cells in a column based on same data or other custom condition, into a single cell. + + It can be enabled on the individual columns: + + ```html + + ``` + The merging can be configured on the grid level to apply either: + - `onSort` - only when the column is sorted. + - `always` - always, regardless of data operations. + + ```html + + + ``` + + The default `cellMergeMode` is `onSort`. + + The functionality can be modified by setting a custom `mergeStrategy` on the grid, in case some other merge conditions or logic is needed for a custom scenario. + + It's possible also to set a `mergeComparer` on the individual columns, in case some custom handling is needed for a particular data field. + - Added ability to pin individual columns to a specific side (start or end of the grid), so that you can now have pinning from both sides. This can be done either declaratively by setting the `pinningPosition` property on the column: - ```html - - - ``` + ```html + + + ``` - ```ts - public pinningPosition = ColumnPinningPosition.End; - ``` + ```ts + public pinningPosition = ColumnPinningPosition.End; + ``` - Or with the API, via optional parameter: + Or with the API, via optional parameter: - ```ts + ```ts grid.pinColumn('Col1', 0, ColumnPinningPosition.End); grid.pinColumn('Col2', 0, ColumnPinningPosition.Start); - ``` + ``` - If property `pinningPosition` is not set on a column, the column will default to the position specified on the grid's `pinning` options for `columns`. + If property `pinningPosition` is not set on a column, the column will default to the position specified on the grid's `pinning` options for `columns`. + +- `IgxCarousel` + - Added `select` method overload accepting index. + ```ts + this.carousel.select(2, Direction.NEXT); + ``` - `IgxDateRangePicker` - Now has a complete set of properties to customize the calendar: @@ -75,10 +101,10 @@ All notable changes for each version of this project will be documented in this - `IgxTooltip` - The tooltip now remains open while interacting with it. + - `IgxTooltipTarget` - Introduced several new properties to enhance customization of tooltip content and behavior. Those include `positionSettings`, `hasArrow`, `sticky`, `closeButtonTemplate`. For detailed usage and examples, please refer to the Tooltip [README](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/directives/tooltip/README.md). - ### General - `IgxDropDown` now exposes a `role` input property, allowing users to customize the role attribute based on the use case. The default is `listbox`. @@ -187,24 +213,24 @@ All notable changes for each version of this project will be documented in this - Added the `canCommit`, `commit` and `discard` public methods that allows the user to save/discard the current state of the expression tree. - Added option to template the search value input: ``` - @if (selectedField?.field === 'Id' && selectedCondition === 'equals'){ - } @else { + } @else { } - + ``` - - **Behavioral Changes** + - **Behavioral Changes** - Expression enters edit mode on single click, `Enter` or `Space`. - Selecting conditions inside the `IgxQueryBuilderComponent` is no longer supported. Grouping/ungrouping expressions is now achieved via the newly exposed Drag & Drop functionality. - Deleting multiple expressions through the context menu is no longer supported. - `IgxQueryBuilderHeaderComponent` - - **Behavioral Change** + - **Behavioral Change** - Legend is no longer shown. - If the `title` input property is not set, by default it would be empty string. - **Deprecation** @@ -286,9 +312,9 @@ All notable changes for each version of this project will be documented in this ### Themes - **Breaking Change** `Palettes` - - All palette colors have been migrated to the [CSS relative colors syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors). This means that color consumed as CSS variables no longer need to be wrapped in an `hsl` function. + - All palette colors have been migrated to the [CSS relative colors syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors). This means that color consumed as CSS variables no longer need to be wrapped in an `hsl` function. - Example: + Example: ```css /* 18.1.x and before: */ background: hsl(var(--ig-primary-600)); @@ -299,7 +325,7 @@ All notable changes for each version of this project will be documented in this This change also opens up the door for declaring the base (500) variants of each color in CSS from any color, including other CSS variables, whereas before the Sass `palette` function was needed to generate color shades from a base color. - Example: + Example: ```scss /* 18.1.x and before: */ $my-palette: palette($primary: #09f, ...); @@ -339,7 +365,7 @@ For Firefox users, we provide limited scrollbar styling options through the foll - `animationType` input property is now of type `CarouselAnimationType`. `HorizontalAnimationType` can also be used, however, to accommodate the new vertical mode, which supports vertical slide animations, it is recommended to use `CarouselAnimationType`. - **Behavioral Changes** - the `keyboardSupport` input property now defaults to `false`. - - **Deprecation** - the `keyboardSupport` input property has been deprecated and will be removed in a future version. Keyboard navigation with `ArrowLeft`, `ArrowRight`, `Home`, and `End` keys will be supported when focusing the indicators' container via ` Tab`/`Shift+Tab`. + - **Deprecation** - the `keyboardSupport` input property has been deprecated and will be removed in a future version. Keyboard navigation with `ArrowLeft`, `ArrowRight`, `Home`, and `End` keys will be supported when focusing the indicators' container via ` Tab`/`Shift+Tab`. - `IgxCombo`: - **Breaking Change** The deprecated `filterable` property is replaced with `disableFiltering`. diff --git a/projects/igniteui-angular-elements/src/analyzer/elements.config.ts b/projects/igniteui-angular-elements/src/analyzer/elements.config.ts index 32ad4ac6042..f17b7ad8fb8 100644 --- a/projects/igniteui-angular-elements/src/analyzer/elements.config.ts +++ b/projects/igniteui-angular-elements/src/analyzer/elements.config.ts @@ -95,6 +95,7 @@ export var registerConfig = [ ], numericProps: ["rowEnd", "colEnd", "rowStart", "colStart"], boolProps: [ + "merge", "sortable", "selectable", "groupable", @@ -158,6 +159,7 @@ export var registerConfig = [ "expanded", "searchable", "hidden", + "merge", "sortable", "groupable", "editable", @@ -213,6 +215,7 @@ export var registerConfig = [ "collapsible", "expanded", "searchable", + "merge", "sortable", "groupable", "editable", diff --git a/projects/igniteui-angular-elements/src/public_api.ts b/projects/igniteui-angular-elements/src/public_api.ts index d8081637986..aa796e8c5b2 100644 --- a/projects/igniteui-angular-elements/src/public_api.ts +++ b/projects/igniteui-angular-elements/src/public_api.ts @@ -12,7 +12,7 @@ import { IgxPivotDateDimension } from 'projects/igniteui-angular/src/lib/grids/p import { PivotDimensionType } from 'projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.interface'; import { IgxDateSummaryOperand, IgxNumberSummaryOperand, IgxSummaryOperand, IgxTimeSummaryOperand } from 'projects/igniteui-angular/src/lib/grids/summaries/grid-summary'; import { HorizontalAlignment, VerticalAlignment } from 'projects/igniteui-angular/src/lib/services/overlay/utilities'; - +import { ByLevelTreeGridMergeStrategy } from 'projects/igniteui-angular/src/lib/data-operations/merge-strategy'; /** Export Public API, TODO: reorganize, Generate all w/ renames? */ export { @@ -35,6 +35,7 @@ export { NoopSortingStrategy as IgcNoopSortingStrategy, NoopFilteringStrategy as IgcNoopFilteringStrategy, + ByLevelTreeGridMergeStrategy as IgcByLevelTreeGridMergeStrategy, // Pivot API IgxPivotDateDimension as IgcPivotDateDimension, diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index f446ffbe128..91b864e6c87 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -272,6 +272,14 @@ @extend %igx-grid__tr--pinned !optional; } + @include e(tr, $m: merged) { + @extend %igx-grid__tr--merged !optional; + } + + @include e(tr, $m: merged-top) { + @extend %igx-grid__tr--merged-top !optional; + } + @include e(tr, $m: pinned-top) { @extend %igx-grid__tr--pinned-top !optional; } @@ -296,6 +304,22 @@ @extend %igx-grid__td--edited !optional; } + @include e(td, $m: merged) { + @extend %igx-grid__td--merged !optional; + } + + @include e(td, $mods: (merged-selected, merged-hovered)) { + @extend %igx-grid__td--merged-selected-hovered !optional; + } + + @include e(td, $m: merged-selected) { + @extend %igx-grid__td--merged-selected !optional; + } + + @include e(td, $m: merged-hovered) { + @extend %igx-grid__td--merged-hovered !optional; + } + @include e(td, $m: editing) { @extend %igx-grid__td--editing !optional; } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index cc5ce39d8af..ffa36f14e90 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -622,6 +622,7 @@ %grid-row--mrl { %igx-grid__hierarchical-expander--header, + %igx-grid__hierarchical-expander, %igx-grid__header-indentation, %igx-grid__row-indentation, %grid__cbx-selection { @@ -754,6 +755,7 @@ } %grid__cbx-selection, + %igx-grid__hierarchical-expander, %igx-grid__row-indentation, %igx-grid__drag-indicator { border-bottom: rem(1px) solid var-get($theme, 'row-border-color'); @@ -1338,6 +1340,35 @@ } } + %igx-grid__tr--merged { + border-block-end: 0; + } + + %igx-grid__tr--merged-top { + position: absolute; + width: 100%; + } + + %igx-grid__td--merged { + z-index: 1; + grid-row: 1 / -1; + } + + %igx-grid__td--merged-selected { + color: var-get($theme, 'row-selected-text-color'); + background: var-get($theme, 'row-selected-background') !important; + } + + %igx-grid__td--merged-hovered { + background: var-get($theme, 'row-hover-background') !important; + color: var-get($theme, 'row-hover-text-color'); + } + + %igx-grid__td--merged-selected-hovered { + background: var-get($theme, 'row-selected-hover-background') !important; + color: var-get($theme, 'row-selected-hover-text-color'); + } + %igx-grid__tr--deleted { %grid-cell-text { font-style: italic; diff --git a/projects/igniteui-angular/src/lib/core/utils.ts b/projects/igniteui-angular/src/lib/core/utils.ts index 749b85832e5..6b0b7b7acbd 100644 --- a/projects/igniteui-angular/src/lib/core/utils.ts +++ b/projects/igniteui-angular/src/lib/core/utils.ts @@ -33,6 +33,17 @@ export function cloneArray(array: T[], deep = false): T[] { return deep ? (array ?? []).map(cloneValue) : (array ?? []).slice(); } +/** + * @hidden + */ +export function areEqualArrays(arr1: T[], arr2: T[]): boolean { + if (arr1.length !== arr2.length) return false; + for (let i = 0; i < arr1.length; i++) { + if (arr1[i] !== arr2[i]) return false; + } + return true; +} + /** * Doesn't clone leaf items * diff --git a/projects/igniteui-angular/src/lib/data-operations/data-util.ts b/projects/igniteui-angular/src/lib/data-operations/data-util.ts index ac609764713..adb59f9a2ed 100644 --- a/projects/igniteui-angular/src/lib/data-operations/data-util.ts +++ b/projects/igniteui-angular/src/lib/data-operations/data-util.ts @@ -8,7 +8,7 @@ import { IGroupingState } from './groupby-state.interface'; import { mergeObjects } from '../core/utils'; import { Transaction, TransactionType, HierarchicalTransaction } from '../services/transaction/transaction'; import { getHierarchy, isHierarchyMatch } from './operations'; -import { GridType } from '../grids/common/grid.interface'; +import { ColumnType, GridType } from '../grids/common/grid.interface'; import { ITreeGridRecord } from '../grids/tree-grid/tree-grid.interfaces'; import { ISortingExpression } from './sorting-strategy'; import { @@ -20,6 +20,7 @@ import { } from '../grids/common/strategy'; import { DefaultDataCloneStrategy, IDataCloneStrategy } from '../data-operations/data-clone-strategy'; import { IGroupingExpression } from './grouping-expression.interface'; +import { DefaultMergeStrategy, IGridMergeStrategy } from './merge-strategy'; /** * @hidden @@ -115,6 +116,25 @@ export class DataUtil { return grouping.groupBy(data, state, grid, groupsRecords, fullResult); } + public static merge(data: T[], columns: ColumnType[], strategy: IGridMergeStrategy = new DefaultMergeStrategy(), activeRowIndexes = [], grid: GridType = null, + ): any[] { + let result = []; + for (const col of columns) { + const isDate = col?.dataType === 'date' || col?.dataType === 'dateTime'; + const isTime = col?.dataType === 'time' || col?.dataType === 'dateTime'; + strategy.merge( + data, + col.field, + col.mergingComparer, + result, + activeRowIndexes, + isDate, + isTime, + grid); + } + return result; + } + public static page(data: T[], state: IPagingState, dataLength?: number): T[] { if (!state) { return data; diff --git a/projects/igniteui-angular/src/lib/data-operations/merge-strategy.ts b/projects/igniteui-angular/src/lib/data-operations/merge-strategy.ts new file mode 100644 index 00000000000..3768b84c458 --- /dev/null +++ b/projects/igniteui-angular/src/lib/data-operations/merge-strategy.ts @@ -0,0 +1,185 @@ +import { columnFieldPath, parseDate, resolveNestedPath } from '../core/utils'; +import { GridType } from '../grids/common/grid.interface'; + + + + +export interface IMergeByResult { + rowSpan: number; + root?: any; +} + +/** + * Merge strategy interface. + */ +export interface IGridMergeStrategy { + /* blazorSuppress */ + /** + * Function that processes merging of the whole data per merged field. + * Returns collection where object has reference to the original record and map of the cell merge metadata per field. + */ + merge: ( + /* The original data to merge. */ + data: any[], + /* The field in the data to merge. */ + field: string, + /* Custom comparer function to use for field. */ + comparer: (prevRecord: any, currentRecord: any, field: string) => boolean, + /* Existing merge result to which to add the field specific metadata for merging. */ + result: any[], + /* The active row indexes, where merging should break the sequence. */ + activeRowIndexes: number[], + /* (Optional) Indicates if the field is of type Date. */ + isDate?: boolean, + /* (Optional) Indicates if the field is of type Time. */ + isTime?: boolean, + /* (Optional) Reference to the grid */ + grid?: GridType + ) => any[]; + /** + * Function that compares values for merging. Returns true if same, false if different. + */ + comparer: (prevRecord: any, record: any, field: string) => boolean; +} + +export class DefaultMergeStrategy implements IGridMergeStrategy { + protected static _instance: DefaultMergeStrategy = null; + + public static instance(): DefaultMergeStrategy { + return this._instance || (this._instance = new this()); + } + + /* blazorSuppress */ + public merge( + data: any[], + field: string, + comparer: (prevRecord: any, record: any, field: string, isDate?: boolean, isTime?: boolean) => boolean = this.comparer, + result: any[], + activeRowIndexes: number[], + isDate = false, + isTime = false, + grid?: GridType + ) { + let prev = null; + let index = 0; + for (const rec of data) { + + const recData = result[index]; + // if this is active row or some special record type - add and skip merging + if (activeRowIndexes.indexOf(index) != -1 || (grid && grid.isDetailRecord(rec) || grid.isGroupByRecord(rec) || grid.isChildGridRecord(rec))) { + if (!recData) { + result.push(rec); + } + prev = null; + index++; + continue; + } + let recToUpdateData = recData ?? { recordRef: grid.isGhostRecord(rec) ? rec.recordRef : rec, cellMergeMeta: new Map(), ghostRecord: rec.ghostRecord }; + recToUpdateData.cellMergeMeta.set(field, { rowSpan: 1 }); + if (prev && comparer.call(this, prev.recordRef, recToUpdateData.recordRef, field, isDate, isTime) && prev.ghostRecord === recToUpdateData.ghostRecord) { + const root = prev.cellMergeMeta.get(field)?.root ?? prev; + root.cellMergeMeta.get(field).rowSpan += 1; + recToUpdateData.cellMergeMeta.get(field).root = root; + } + prev = recToUpdateData; + if (!recData) { + result.push(recToUpdateData); + } + index++; + } + return result; + } + + /* blazorSuppress */ + public comparer(prevRecord: any, record: any, field: string, isDate = false, isTime = false): boolean { + const a = this.getFieldValue(prevRecord,field, isDate, isTime); + const b = this.getFieldValue(record,field, isDate, isTime); + const an = (a === null || a === undefined); + const bn = (b === null || b === undefined); + if (an) { + if (bn) { + return true; + } + return false; + } else if (bn) { + return false; + } + return a === b; + } + + /** + * Retrieves the value of the specified field from the given object, considering date and time data types. + * `key`: The key of the field to retrieve. + * `isDate`: (Optional) Indicates if the field is of type Date. + * `isTime`: (Optional) Indicates if the field is of type Time. + * Returns the value of the specified field in the data object. + * @internal + */ + protected getFieldValue(obj: T, key: string, isDate = false, isTime = false) { + let resolvedValue = resolveNestedPath(obj, columnFieldPath(key)); + if (isDate || isTime) { + resolvedValue = this.getDateValue(resolvedValue, isDate, isTime); + } + return resolvedValue; + } + + /** + * @internal + */ + protected getDateValue(obj: T, isDate = false, isTime = false) { + let date = obj instanceof Date ? obj : parseDate(obj); + let resolvedValue; + if (isDate && isTime) { + // date + time + resolvedValue = date.getTime(); + } else if (date && isDate && !isTime) { + // date, but no time + resolvedValue = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0).getTime(); + } else if (date && isTime && !isDate) { + // just time + resolvedValue = new Date().setHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); + } + return resolvedValue; + } +} + + +export class DefaultTreeGridMergeStrategy extends DefaultMergeStrategy { + /* blazorSuppress */ + public override comparer(prevRecord: any, record: any, field: string, isDate = false, isTime = false): boolean { + const a = this.getFieldValue( prevRecord.data, field, isDate, isTime); + const b = this.getFieldValue(record.data,field, isDate, isTime); + const an = (a === null || a === undefined); + const bn = (b === null || b === undefined); + if (an) { + if (bn) { + return true; + } + return false; + } else if (bn) { + return false; + } + return a === b; + } +} + +export class ByLevelTreeGridMergeStrategy extends DefaultMergeStrategy { + /* blazorSuppress */ + public override comparer(prevRecord: any, record: any, field: string, isDate = false, isTime = false): boolean { + const a = this.getFieldValue( prevRecord.data, field, isDate, isTime); + const b = this.getFieldValue(record.data,field, isDate, isTime); + const levelA = prevRecord.level; + const levelB = record.level; + const an = (a === null || a === undefined); + const bn = (b === null || b === undefined); + if (an) { + if (bn) { + return true; + } + return false; + } else if (bn) { + return false; + } + return a === b && levelA === levelB; + } +} diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.html b/projects/igniteui-angular/src/lib/grids/cell.component.html index 61fa42a6393..4bbce226c42 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/cell.component.html @@ -57,6 +57,8 @@ } + + @if (column.dataType !== 'boolean' || (column.dataType === 'boolean' && this.formatter)) {
{ + if (this.isPlaceholder) { + return this.emptyCellTemplate; + } if (this.editMode && this.formGroup) { const inlineEditorTemplate = this.column.inlineEditorTemplate; return inlineEditorTemplate ? inlineEditorTemplate : this.inlineEditorTemplate; @@ -717,6 +732,9 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT @ViewChild('defaultCell', { read: TemplateRef, static: true }) protected defaultCellTemplate: TemplateRef; + @ViewChild('emptyCell', { read: TemplateRef, static: true }) + protected emptyCellTemplate: TemplateRef; + @ViewChild('defaultPinnedIndicator', { read: TemplateRef, static: true }) protected defaultPinnedIndicator: TemplateRef; @@ -1016,6 +1034,19 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT * @internal */ public pointerdown = (event: PointerEvent) => { + + if (this.isMerged) { + // need an approximation of where in the cell the user clicked to get actual index to be activated. + const scrollOffset = this.grid.verticalScrollContainer.scrollPosition + (event.y - this.grid.tbody.nativeElement.getBoundingClientRect().y); + const targetRowIndex = this.grid.verticalScrollContainer.getIndexAtScroll(scrollOffset); + if (targetRowIndex != this.rowIndex) { + const row = this.grid.rowList.toArray().find(x => x.index === targetRowIndex); + const actualTarget = row.cells.find(x => x.column === this.column); + actualTarget.pointerdown(event); + return; + } + } + if (this.cellSelectionMode !== GridSelectionMode.multiple) { this.activate(event); return; diff --git a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts index 30c7ab57c89..db3e0569c2f 100644 --- a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts +++ b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts @@ -107,6 +107,31 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return this._field; } + /** + * Sets/gets whether to merge cells in this column. + * ```html + * + * ``` + * + */ + @Input() + public get merge() { + return this._merge; + } + + public set merge(value) { + if (this.grid.hasColumnLayouts) { + console.warn('Merging is not supported with multi-row layouts.'); + return; + } + if (value !== this._merge) { + this._merge = value; + if (this.grid) { + this.grid.resetColumnCollections(); + this.grid.notifyChanges(); + } + } + } /** * @hidden @internal @@ -1224,6 +1249,30 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy this._sortStrategy = classRef; } + /* blazorSuppress */ + /** + * Gets the function that compares values for merging. + * ```typescript + * let mergingComparer = this.column.mergingComparer' + * ``` + */ + @Input() + public get mergingComparer(): (prevRecord: any, record: any, field: string) => boolean { + return this._mergingComparer; + } + + /* blazorSuppress */ + /** + * Sets a custom function to compare values for merging. + * ```typescript + * this.column.mergingComparer = (prevRecord: any, record: any, field: string) => { return prevRecord[field] === record[field]; } + * ``` + */ + public set mergingComparer(funcRef: (prevRecord: any, record: any, field: string) => boolean) { + this._mergingComparer = funcRef; + } + + /* blazorSuppress */ /** * Gets the function that compares values for grouping. @@ -1864,6 +1913,8 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @hidden */ protected _groupingComparer: (a: any, b: any, currRec?: any, groupRec?: any) => number; + + protected _mergingComparer: (prevRecord: any, record: any, field: string) => boolean; /** * @hidden */ @@ -1900,6 +1951,10 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @hidden */ protected _groupable = false; + /** + * @hidden + */ + protected _merge = false; /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/grids/common/enums.ts b/projects/igniteui-angular/src/lib/grids/common/enums.ts index 88d277ccd39..fd19aa101ca 100644 --- a/projects/igniteui-angular/src/lib/grids/common/enums.ts +++ b/projects/igniteui-angular/src/lib/grids/common/enums.ts @@ -73,6 +73,19 @@ export const GridSelectionMode = { } as const; export type GridSelectionMode = (typeof GridSelectionMode)[keyof typeof GridSelectionMode]; + +/** + * Enumeration representing different cell merging modes for the grid elements. + * - 'never': Never merge cells. + * - 'always': Always merge adjacent cells based on merge strategy. + * - 'onSort': Only merge cells in column that are sorted. + */ +export const GridCellMergeMode = { + always: 'always', + onSort: 'onSort' +} as const; +export type GridCellMergeMode = (typeof GridCellMergeMode)[keyof typeof GridCellMergeMode]; + /** Enumeration representing different column display order options. */ export const ColumnDisplayOrder = { Alphabetical: 'Alphabetical', diff --git a/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts b/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts index dca83e871c2..fda967afb6c 100644 --- a/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts +++ b/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts @@ -1,4 +1,4 @@ -import { ColumnPinningPosition, FilterMode, GridPagingMode, GridSelectionMode, GridSummaryCalculationMode, GridSummaryPosition, GridValidationTrigger, RowPinningPosition, Size } from './enums'; +import { ColumnPinningPosition, FilterMode, GridCellMergeMode, GridPagingMode, GridSelectionMode, GridSummaryCalculationMode, GridSummaryPosition, GridValidationTrigger, RowPinningPosition, Size } from './enums'; import { ISearchInfo, IGridCellEventArgs, IRowSelectionEventArgs, IColumnSelectionEventArgs, IPinColumnCancellableEventArgs, IColumnVisibilityChangedEventArgs, IColumnVisibilityChangingEventArgs, @@ -38,6 +38,7 @@ import { IDimensionsChange, IPivotConfiguration, IPivotDimension, IPivotKeys, IP import { IDataCloneStrategy } from '../../data-operations/data-clone-strategy'; import { FormControl, FormGroup, ValidationErrors } from '@angular/forms'; import { IgxGridValidationService } from '../grid/grid-validation.service'; +import { IGridMergeStrategy } from '../../data-operations/merge-strategy'; export const IGX_GRID_BASE = /*@__PURE__*/new InjectionToken('IgxGridBaseToken'); export const IGX_GRID_SERVICE_BASE = /*@__PURE__*/new InjectionToken('IgxGridServiceBaseToken'); @@ -379,6 +380,7 @@ export interface ColumnType extends FieldType { /** @hidden @internal */ headerCell: any; validators: any[]; + mergingComparer: (prevRecord: any, record: any, field: string) => boolean; /** * The template reference for the custom header of the column @@ -497,6 +499,7 @@ export interface ColumnType extends FieldType { pinned: boolean; /** Indicates if the column is currently expanded or collapsed. If the value is true, the column is expanded */ expanded: boolean; + merge: boolean; /** Indicates if the column is currently selected. If the value is true, the column is selected */ selected: boolean; /** Indicates if the column can be selected. If the value is true, the column can be selected */ @@ -734,6 +737,8 @@ export interface GridServiceType { export interface GridType extends IGridDataBindable { /** Represents the locale of the grid: `USD`, `EUR`, `GBP`, `CNY`, `JPY`, etc. */ locale: string; + cellMergeMode: GridCellMergeMode; + mergeStrategy: IGridMergeStrategy; resourceStrings: IGridResourceStrings; /* blazorSuppress */ /** Represents the native HTML element itself */ @@ -754,6 +759,8 @@ export interface GridType extends IGridDataBindable { pipeTrigger: number; summaryPipeTrigger: number; /** @hidden @internal */ + columnsToMerge: ColumnType[], + /** @hidden @internal */ groupablePipeTrigger: number; filteringPipeTrigger: number; /** @hidden @internal */ @@ -767,6 +774,8 @@ export interface GridType extends IGridDataBindable { isColumnWidthSum: boolean; /** @hidden @internal */ minColumnWidth: number; + /** @hidden @internal */ + hoverIndex?: number; /** Strategy, used for cloning the provided data. The type has one method, that takes any type of data */ dataCloneStrategy: IDataCloneStrategy; @@ -1228,6 +1237,7 @@ export interface GridType extends IGridDataBindable { getEmptyRecordObjectFor(inRow: RowType): any; isSummaryRow(rec: any): boolean; isRecordPinned(rec: any): boolean; + isRecordMerged(rec: any): boolean; getInitialPinnedIndex(rec: any): number; isRecordPinnedByViewIndex(rowIndex: number): boolean; isColumnGrouped(fieldName: string): boolean; diff --git a/projects/igniteui-angular/src/lib/grids/common/pipes.ts b/projects/igniteui-angular/src/lib/grids/common/pipes.ts index 818a0ea3854..23bc4d4a9b0 100644 --- a/projects/igniteui-angular/src/lib/grids/common/pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/common/pipes.ts @@ -115,6 +115,7 @@ export class IgxGridRowClassesPipe implements PipeTransform { dragging: boolean, index: number, mrl: boolean, + merged: boolean, filteredOut: boolean, _rowData: any, _: number @@ -126,7 +127,8 @@ export class IgxGridRowClassesPipe implements PipeTransform { [dirty, 'igx-grid__tr--edited'], [deleted, 'igx-grid__tr--deleted'], [dragging, 'igx-grid__tr--drag'], - [mrl, 'igx-grid__tr--mrl'], + [mrl || merged, 'igx-grid__tr--mrl'], + [merged, 'igx-grid__tr--merged'], // Tree grid only [filteredOut, 'igx-grid__tr--filtered'] ]; diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 3cccc7505e2..80883a9302a 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -33,12 +33,12 @@ import { ViewContainerRef, DOCUMENT } from '@angular/core'; -import { columnFieldPath, formatDate, resizeObservable } from '../core/utils'; +import { areEqualArrays, columnFieldPath, formatDate, resizeObservable } from '../core/utils'; import { IgcTrialWatermark } from 'igniteui-trial-watermark'; import { Subject, pipe, fromEvent, animationFrameScheduler, merge } from 'rxjs'; import { takeUntil, first, filter, throttleTime, map, shareReplay, takeWhile } from 'rxjs/operators'; import { cloneArray, mergeObjects, compareMaps, resolveNestedPath, isObject, PlatformUtil } from '../core/utils'; -import { GridColumnDataType } from '../data-operations/data-util'; +import { DataUtil, GridColumnDataType } from '../data-operations/data-util'; import { FilteringLogic } from '../data-operations/filtering-expression.interface'; import { IGroupByRecord } from '../data-operations/groupby-record.interface'; import { IForOfDataChangeEventArgs, IgxGridForOfDirective } from '../directives/for-of/for_of.directive'; @@ -93,7 +93,8 @@ import { RowPinningPosition, GridPagingMode, GridValidationTrigger, - Size + Size, + GridCellMergeMode } from './common/enums'; import { IGridCellEventArgs, @@ -184,6 +185,7 @@ import { IgxGridValidationService } from './grid/grid-validation.service'; import { getCurrentResourceStrings } from '../core/i18n/resources'; import { isTree, recreateTree, recreateTreeFromFields } from '../data-operations/expressions-tree-util'; import { getUUID } from './common/random'; +import { DefaultMergeStrategy, IGridMergeStrategy } from '../data-operations/merge-strategy'; interface IMatchInfoCache { row: any; @@ -2502,6 +2504,23 @@ export abstract class IgxGridBaseDirective implements GridType, this._sortingStrategy = value; } + + /** + * Gets/Sets the merge strategy of the grid. + * + * @example + * ```html + * + * ``` + */ + @Input() + public get mergeStrategy() { + return this._mergeStrategy; + } + public set mergeStrategy(value) { + this._mergeStrategy = value; + } + /** * Gets/Sets the sorting options - single or multiple sorting. * Accepts an `ISortingOptions` object with any of the `mode` properties. @@ -2798,6 +2817,9 @@ export abstract class IgxGridBaseDirective implements GridType, public set sortingExpressions(value: ISortingExpression[]) { this._sortingExpressions = cloneArray(value); this.sortingExpressionsChange.emit(this._sortingExpressions); + if (this.cellMergeMode === GridCellMergeMode.onSort) { + this.resetColumnCollections(); + } this.notifyChanges(); } @@ -2905,10 +2927,29 @@ export abstract class IgxGridBaseDirective implements GridType, this._cellSelectionMode = selectionMode; // if (this.gridAPI.grid) { this.selectionService.clear(true); + this._activeRowIndexes = null; this.notifyChanges(); // } } + /** + * Gets/Sets cell merge mode. + * + */ + @WatchChanges() + @Input() + public get cellMergeMode() { + return this._cellMergeMode; + } + + public set cellMergeMode(value: GridCellMergeMode) { + if (value !== this._cellMergeMode) { + this._cellMergeMode = value; + this.resetColumnCollections(); + this.notifyChanges(); + } + } + /** * Gets/Sets row selection mode * @@ -3075,6 +3116,11 @@ export abstract class IgxGridBaseDirective implements GridType, */ public groupablePipeTrigger = 0; + /** + * @hidden @internal + */ + public hoverIndex: number; + /** * @hidden @internal */ @@ -3157,6 +3203,10 @@ export abstract class IgxGridBaseDirective implements GridType, protected _columnPinning = false; protected _pinnedRecordIDs = []; + /** + * @hidden + */ + protected _mergeStrategy: IGridMergeStrategy = new DefaultMergeStrategy(); /** * @hidden @@ -3212,6 +3262,8 @@ export abstract class IgxGridBaseDirective implements GridType, private _currentRowState: any; private _filteredSortedData = null; private _filteredData = null; + private _mergedDataInView = null; + private _activeRowIndexes = null; private _customDragIndicatorIconTemplate: TemplateRef; private _excelStyleHeaderIconTemplate: TemplateRef; @@ -3313,6 +3365,8 @@ export abstract class IgxGridBaseDirective implements GridType, private _gridSize: Size = Size.Large; private _defaultRowHeight = 50; private _rowCount: number; + private _cellMergeMode: GridCellMergeMode = GridCellMergeMode.onSort; + private _columnsToMerge: IgxColumnComponent[] = []; /** * @hidden @internal @@ -3551,6 +3605,14 @@ export abstract class IgxGridBaseDirective implements GridType, return false; } + /** + * @hidden + * @internal + */ + public isChildGridRecord(_rec) { + return false; + } + /** * @hidden @internal */ @@ -3646,6 +3708,23 @@ export abstract class IgxGridBaseDirective implements GridType, return this.getInitialPinnedIndex(rec) !== -1; } + /** + * @hidden + * @internal + */ + public isRecordMerged(rec) { + return rec?.cellMergeMeta; + } + + protected getMergeCellOffset(rowData) { + const index = rowData.dataIndex; + let offset = this.verticalScrollContainer.scrollPosition - this.verticalScrollContainer.getScrollForIndex(index); + if (this.hasPinnedRecords && this.isRowPinningToTop) { + offset -= this.pinnedRowHeight; + } + return -offset; + } + /** * @hidden * @internal @@ -3800,6 +3879,7 @@ export abstract class IgxGridBaseDirective implements GridType, $event.containerSize = this.calcHeight; } this.evaluateLoadingState(); + this.updateMergedData(); }); this.verticalScrollContainer.scrollbarVisibilityChanged.pipe(filter(() => !this._init), destructor).subscribe(() => { @@ -3822,6 +3902,10 @@ export abstract class IgxGridBaseDirective implements GridType, this.notifyChanges(true); }); + this.verticalScrollContainer.chunkPreload.pipe(filter(() => !this._init), destructor).subscribe(() => { + this.updateMergedData(); + }); + // notifier for column autosize requests this._autoSizeColumnsNotify.pipe( throttleTime(0, this.platform.isBrowser ? animationFrameScheduler : undefined, { leading: false, trailing: true }), @@ -3831,6 +3915,24 @@ export abstract class IgxGridBaseDirective implements GridType, this.autoSizeColumnsInView(); this._firstAutoResize = false; }); + + this.activeNodeChange.pipe( + throttleTime(0, this.platform.isBrowser ? animationFrameScheduler : undefined, { leading: false, trailing: true }), + destructor + ).subscribe(() => { + this._activeRowIndexes = null; + if (this.hasCellsToMerge) { + this.refreshSearch(); + this.notifyChanges(); + } + }); + + this.selectionService.selectedRangeChange.pipe(filter(() => !this._init), destructor).subscribe(() => { + this._activeRowIndexes = null; + if (this.hasCellsToMerge) { + this.refreshSearch(); + } + }); } /** @@ -3895,6 +3997,38 @@ export abstract class IgxGridBaseDirective implements GridType, } } + /** + * @hidden + * @internal + */ + public get columnsToMerge() : ColumnType[] { + if (this._columnsToMerge.length) { + return this._columnsToMerge; + } + const cols = this.visibleColumns.filter( + x => x.merge && (this.cellMergeMode ==='always' || + (this.cellMergeMode === 'onSort' && !!this.sortingExpressions.find( y => y.fieldName === x.field))) + ); + this._columnsToMerge = cols; + return this._columnsToMerge; + } + + protected allowResetOfColumnsToMerge() { + const cols = this.visibleColumns.filter( + x => x.merge && (this.cellMergeMode ==='always' || + (this.cellMergeMode === 'onSort' && !!this.sortingExpressions.find( y => y.fieldName === x.field))) + ); + if (areEqualArrays(cols, this._columnsToMerge)) { + return false; + } else { + return true + } + } + + protected get mergedDataInView() { + return this._mergedDataInView; + } + /** * @hidden * @internal @@ -3906,6 +4040,9 @@ export abstract class IgxGridBaseDirective implements GridType, this._visibleColumns.length = 0; this._pinnedVisible.length = 0; this._unpinnedVisible.length = 0; + if (this.allowResetOfColumnsToMerge()) { + this._columnsToMerge.length = 0; + } } /** @@ -3963,6 +4100,22 @@ export abstract class IgxGridBaseDirective implements GridType, } } + + protected get activeRowIndexes(): number[] { + if (this._activeRowIndexes) { + return this._activeRowIndexes; + } else { + const activeRow = this.navigation.activeNode?.row; + const selectedCellIndexes = (this.selectionService.selection?.keys() as any)?.toArray(); + this._activeRowIndexes = [activeRow, ...selectedCellIndexes]; + return this._activeRowIndexes; + } + } + + protected get hasCellsToMerge() { + return this.columnsToMerge.length > 0; + } + /** * @hidden @internal */ @@ -4006,6 +4159,7 @@ export abstract class IgxGridBaseDirective implements GridType, .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.selectionService.clear(true); + this._activeRowIndexes = null; this.crudService.endEdit(false); this.pipeTrigger++; this.navigateTo(0); @@ -4016,6 +4170,7 @@ export abstract class IgxGridBaseDirective implements GridType, .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.selectionService.clear(true); + this._activeRowIndexes = null; this.page = 0; this.crudService.endEdit(false); this.notifyChanges(); @@ -5802,6 +5957,7 @@ export abstract class IgxGridBaseDirective implements GridType, */ public clearCellSelection(): void { this.selectionService.clear(true); + this._activeRowIndexes = null; this.notifyChanges(); } @@ -7580,15 +7736,21 @@ export abstract class IgxGridBaseDirective implements GridType, this.page = page; } } - + let targetRowIndex = (typeof (row) === 'number' ? row : this.unpinnedDataView.indexOf(row)); + const virtRec = this.verticalScrollContainer.igxForOf[targetRowIndex]; + const col = typeof (column) === 'number' ? this.visibleColumns[column] : column; + const rowSpan = this.isRecordMerged(virtRec) ? virtRec?.cellMergeMeta.get(col)?.rowSpan : 1; + if (rowSpan > 1) { + targetRowIndex += Math.floor(rowSpan/2); + } if (delayScrolling) { this.verticalScrollContainer.dataChanged.pipe(first(), takeUntil(this.destroy$)).subscribe(() => { this.scrollDirective(this.verticalScrollContainer, - typeof (row) === 'number' ? row : this.unpinnedDataView.indexOf(row)); + targetRowIndex); }); } else { this.scrollDirective(this.verticalScrollContainer, - typeof (row) === 'number' ? row : this.unpinnedDataView.indexOf(row)); + targetRowIndex); } this.scrollToHorizontally(column); @@ -7930,25 +8092,34 @@ export abstract class IgxGridBaseDirective implements GridType, const caseSensitive = this._lastSearchInfo.caseSensitive; const exactMatch = this._lastSearchInfo.exactMatch; const searchText = caseSensitive ? this._lastSearchInfo.searchText : this._lastSearchInfo.searchText.toLowerCase(); - const data = this.filteredSortedData; + let data = this.filteredSortedData; + if (this.hasCellsToMerge) { + let indexes = this.activeRowIndexes; + if (this.page > 0) { + indexes = indexes.map(x => this.perPage * this.page + x ); + } + + data = DataUtil.merge(cloneArray(this.filteredSortedData), this.columnsToMerge, this.mergeStrategy, indexes, this); + } const columnItems = this.visibleColumns.filter((c) => !c.columnGroup).sort((c1, c2) => c1.visibleIndex - c2.visibleIndex); const columnsPathParts = columnItems.map(col => columnFieldPath(col.field)); data.forEach((dataRow, rowIndex) => { + const currentRowData = this.isRecordMerged(dataRow) ? dataRow.recordRef : dataRow; columnItems.forEach((c, cid) => { const pipeArgs = this.getColumnByName(c.field).pipeArgs; - const value = c.formatter ? c.formatter(resolveNestedPath(dataRow, columnsPathParts[cid]), dataRow) : - c.dataType === 'number' ? formatNumber(resolveNestedPath(dataRow, columnsPathParts[cid]) as number, this.locale, pipeArgs.digitsInfo) : + const value = c.formatter ? c.formatter(resolveNestedPath(currentRowData, columnsPathParts[cid]), currentRowData) : + c.dataType === 'number' ? formatNumber(resolveNestedPath(currentRowData, columnsPathParts[cid]) as number, this.locale, pipeArgs.digitsInfo) : c.dataType === 'date' - ? formatDate(resolveNestedPath(dataRow, columnsPathParts[cid]) as string, pipeArgs.format, this.locale, pipeArgs.timezone) - : resolveNestedPath(dataRow, columnsPathParts[cid]); + ? formatDate(resolveNestedPath(currentRowData, columnsPathParts[cid]) as string, pipeArgs.format, this.locale, pipeArgs.timezone) + : resolveNestedPath(currentRowData, columnsPathParts[cid]); if (value !== undefined && value !== null && c.searchable) { let searchValue = caseSensitive ? String(value) : String(value).toLowerCase(); - + const isMergePlaceHolder = this.isRecordMerged(dataRow) ? !!dataRow?.cellMergeMeta.get(c.field)?.root : false; if (exactMatch) { - if (searchValue === searchText) { + if (searchValue === searchText && !isMergePlaceHolder) { const mic: IMatchInfoCache = { - row: dataRow, + row: currentRowData, column: c.field, index: 0, metadata: new Map([['pinned', this.isRecordPinnedByIndex(rowIndex)]]) @@ -7960,9 +8131,9 @@ export abstract class IgxGridBaseDirective implements GridType, let occurrenceIndex = 0; let searchIndex = searchValue.indexOf(searchText); - while (searchIndex !== -1) { + while (searchIndex !== -1 && !isMergePlaceHolder) { const mic: IMatchInfoCache = { - row: dataRow, + row: currentRowData, column: c.field, index: occurrenceIndex++, metadata: new Map([['pinned', this.isRecordPinnedByIndex(rowIndex)]]) @@ -8062,6 +8233,7 @@ export abstract class IgxGridBaseDirective implements GridType, private clearActiveNode() { this.navigation.lastActiveNode = this.navigation.activeNode; this.navigation.activeNode = {} as IActiveNode; + this._activeRowIndexes = null; this.notifyChanges(); } @@ -8083,4 +8255,24 @@ export abstract class IgxGridBaseDirective implements GridType, } this._rowCount += 1; // include header row } + + private updateMergedData(){ + // recalc merged data + if (this.columnsToMerge.length > 0) { + const startIndex = this.verticalScrollContainer.state.startIndex; + const prevDataView = this.verticalScrollContainer.igxForOf?.slice(0, startIndex); + const data = []; + for (let index = 0; index < startIndex; index++) { + const rec = prevDataView[index]; + if (rec.cellMergeMeta && + // index + maxRowSpan is within view + startIndex < (index + Math.max(...rec.cellMergeMeta.values().toArray().map(x => x.rowSpan)))) { + const visibleIndex = this.isRowPinningToTop ? index + this.pinnedRecordsCount : index; + data.push({record: rec, index: visibleIndex, dataIndex: index }); + } + } + this._mergedDataInView = data; + this.notifyChanges(); + } + } } diff --git a/projects/igniteui-angular/src/lib/grids/grid/cell-merge.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/cell-merge.spec.ts new file mode 100644 index 00000000000..4bcf4a4ef54 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/grid/cell-merge.spec.ts @@ -0,0 +1,1052 @@ +import { Component, TemplateRef, ViewChild } from '@angular/core'; +import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { ByLevelTreeGridMergeStrategy, DefaultMergeStrategy, DefaultSortingStrategy, GridCellMergeMode, GridColumnDataType, GridType, IgxColumnComponent, IgxGridComponent, IgxHierarchicalGridComponent, IgxPaginatorComponent, IgxStringFilteringOperand, SortingDirection } from 'igniteui-angular'; +import { DataParent } from '../../test-utils/sample-test-data.spec'; +import { GridFunctions, GridSelectionFunctions } from '../../test-utils/grid-functions.spec'; +import { By } from '@angular/platform-browser'; +import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec'; +import { hasClass } from '../../test-utils/helper-utils.spec'; +import { ColumnLayoutTestComponent } from './grid.multi-row-layout.spec'; +import { IgxHierarchicalGridTestBaseComponent } from '../hierarchical-grid/hierarchical-grid.spec'; +import { IgxHierarchicalRowComponent } from '../hierarchical-grid/hierarchical-row.component'; +import { IgxTreeGridSelectionComponent } from '../../test-utils/tree-grid-components.spec'; + +describe('IgxGrid - Cell merging #grid', () => { + let fix; + let grid: IgxGridComponent; + const MERGE_CELL_CSS_CLASS = '.igx-grid__td--merged'; + const CELL_CSS_CLASS = '.igx-grid__td'; + const CSS_CLASS_GRID_ROW = '.igx-grid__tr'; + const HIGHLIGHT_ACTIVE_CSS_CLASS = '.igx-highlight__active'; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [ + NoopAnimationsModule, DefaultCellMergeGridComponent, ColumnLayoutTestComponent, + IgxHierarchicalGridTestBaseComponent, IgxTreeGridSelectionComponent + ] + }).compileComponents(); + })); + + + + describe('Basic', () => { + + beforeEach(() => { + fix = TestBed.createComponent(DefaultCellMergeGridComponent); + fix.detectChanges(); + grid = fix.componentInstance.grid; + }); + + describe('Configuration', () => { + + it('should allow enabling/disabling merging per column.', () => { + + const col = grid.getColumnByName('ProductName'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 2 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + + // disable merge + col.merge = false; + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 1 }, + { value: 'NetAdvantage', span: 1 } + ]); + }); + + it('should always merge columns if mergeMode is always.', () => { + const col = grid.getColumnByName('Released'); + col.merge = true; + fix.detectChanges(); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: true, span: 9 } + ]); + }); + + it('should merge only sorted columns if mergeMode is onSort.', () => { + grid.cellMergeMode = 'onSort'; + fix.detectChanges(); + const col = grid.getColumnByName('ProductName'); + //nothing is merged initially + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 1 }, + { value: 'NetAdvantage', span: 1 } + ]); + + grid.sort({ fieldName: 'ProductName', dir: SortingDirection.Desc, ignoreCase: false }); + fix.detectChanges(); + + // merge only after sorted + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'NetAdvantage', span: 2 }, + { value: 'Ignite UI for JavaScript', span: 3 }, + { value: 'Ignite UI for Angular', span: 3 }, + { value: null, span: 1 } + ]); + }); + + it('should allow setting a custom merge strategy via mergeStrategy on grid.', () => { + grid.mergeStrategy = new NoopMergeStrategy(); + fix.detectChanges(); + const col = grid.getColumnByName('ProductName'); + // this strategy does no merging + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 1 }, + { value: 'NetAdvantage', span: 1 } + ]); + }); + + it('should allow setting a custom comparer for merging on particular column via mergingComparer.', () => { + const col = grid.getColumnByName('ProductName'); + // all are same and should merge + col.mergingComparer = (prev: any, rec: any, field: string) => { + return true; + }; + grid.pipeTrigger += 1; + fix.detectChanges(); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 9 } + ]); + }); + + it('should merge date column correctly.', () => { + const col = grid.getColumnByName('ReleaseDate'); + + grid.sort({ fieldName: 'ReleaseDate', dir: SortingDirection.Desc, ignoreCase: false }); + fix.detectChanges(); + + // merge date column + col.merge = true; + fix.detectChanges(); + + const today: Date = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 0, 0, 0); + const nextDay = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate() + 1, 0, 0, 0); + const prevDay = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate() - 1, 0, 0, 0); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: nextDay, span: 2 }, + { value: today, span: 2 }, + { value: prevDay, span: 3 }, + { value: null, span: 2 } + ]); + }); + }); + + describe('UI', () => { + it('should properly align merged cells with their spanned rows.', () => { + const mergedCell = fix.debugElement.queryAll(By.css(MERGE_CELL_CSS_CLASS))[0].nativeNode; + const endRow = fix.debugElement.queryAll(By.css(CSS_CLASS_GRID_ROW))[2].nativeNode; + expect(mergedCell.getBoundingClientRect().bottom).toBe(endRow.getBoundingClientRect().bottom); + }); + + it('should mark merged cell as hovered when hovering any row that intersects that cell.', () => { + const secondRow = fix.debugElement.queryAll(By.css(CSS_CLASS_GRID_ROW))[2]; + UIInteractions.hoverElement(secondRow.nativeNode); + fix.detectChanges(); + // hover 2nd row that intersects the merged cell in row 1 + const mergedCell = fix.debugElement.queryAll(By.css(MERGE_CELL_CSS_CLASS))[0].nativeNode; + // merged cell should be marked as hovered + hasClass(mergedCell, 'igx-grid__td--merged-hovered', true); + }); + + it('should set correct size to merged cell that spans multiple rows that have different sizes.', () => { + const col = grid.getColumnByName('ID'); + col.bodyTemplate = fix.componentInstance.customTemplate; + fix.detectChanges(); + grid.verticalScrollContainer.recalcUpdateSizes(); + grid.dataRowList.toArray().forEach(x => x.cdr.detectChanges()); + const mergedCell = fix.debugElement.queryAll(By.css(MERGE_CELL_CSS_CLASS))[0].nativeNode; + // one row is 100px, other is 200, 2px border + expect(mergedCell.getBoundingClientRect().height).toBe(100 + 200 + 2); + }); + }); + }); + + describe('Integration', () => { + beforeEach(() => { + fix = TestBed.createComponent(IntegrationCellMergeGridComponent); + fix.detectChanges(); + grid = fix.componentInstance.grid; + }); + + describe('Virtualization', () => { + beforeEach(() => { + fix.componentInstance.width = '400px'; + fix.componentInstance.height = '300px'; + fix.detectChanges(); + }); + it('should retain rows with merged cells that span multiple rows in DOM as long as merged cell is still in view.', async() => { + // initial row list is same as the virtualization chunk + expect(grid.rowList.length).toBe(grid.virtualizationState.chunkSize); + + grid.navigateTo(grid.virtualizationState.chunkSize - 1, 0); + await wait(100); + fix.detectChanges(); + + //virtualization starts from 1 + expect(grid.virtualizationState.startIndex).toBe(1); + + // check row is chunkSize + 1 extra row at the top + expect(grid.rowList.length).toBe(grid.virtualizationState.chunkSize + 1); + // first row at top is index 0 + expect(grid.rowList.first.index).toBe(0); + // and has offset to position correctly the merged cell + expect(grid.rowList.first.nativeElement.offsetTop).toBeLessThan(-50); + }); + + it('should remove row from DOM when merged cell is no longer in view.', async() => { + // scroll so that first row with merged cell is not in view + grid.navigateTo(grid.virtualizationState.chunkSize, 0); + await wait(100); + fix.detectChanges(); + + //virtualization starts from 2 + expect(grid.virtualizationState.startIndex).toBe(2); + + // no merge cells from previous chunks + expect(grid.rowList.length).toBe(grid.virtualizationState.chunkSize); + // first row is from the virtualization + expect(grid.rowList.first.index).toBe(grid.virtualizationState.startIndex); + }); + + it('horizontal virtualization should not be affected by vertically merged cells.', async() => { + let mergedCell = grid.rowList.first.cells.find(x => x.column.field === 'ProductName'); + expect(mergedCell.value).toBe('Ignite UI for JavaScript'); + expect(mergedCell.nativeElement.parentElement.style.gridTemplateRows).toBe("50px 50px"); + + // scroll horizontally + grid.navigateTo(0, 4); + await wait(100); + fix.detectChanges(); + + // not in DOM + mergedCell = grid.rowList.first.cells.find(x => x.column.field === 'ProductName'); + expect(mergedCell).toBeUndefined(); + + // scroll back + grid.navigateTo(0, 0); + await wait(100); + fix.detectChanges(); + + mergedCell = grid.rowList.first.cells.find(x => x.column.field === 'ProductName'); + expect(mergedCell.value).toBe('Ignite UI for JavaScript'); + expect(mergedCell.nativeElement.parentElement.style.gridTemplateRows).toBe("50px 50px"); + }); + }); + + describe('Group By', () => { + it('cells should merge only within their respective groups.', () => { + grid.groupBy({ + fieldName: 'ProductName', dir: SortingDirection.Desc, + ignoreCase: false, strategy: DefaultSortingStrategy.instance() + }); + fix.detectChanges(); + + const col = grid.getColumnByName('ProductName'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'NetAdvantage', span: 2 }, + { value: 'Ignite UI for JavaScript', span: 3 }, + { value: 'Ignite UI for Angular', span: 3 }, + { value: null, span: 1 } + ]); + + grid.groupBy({ + fieldName: 'ReleaseDate', dir: SortingDirection.Desc, + ignoreCase: false, strategy: DefaultSortingStrategy.instance() + }); + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'NetAdvantage', span: 1 }, + { value: 'NetAdvantage', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 } + ]); + + }); + + }); + + describe('Master-Detail', () => { + + it('should interrupt merge sequence if a master-detail row is expanded.', () => { + grid.detailTemplate = fix.componentInstance.detailTemplate; + fix.detectChanges(); + + const col = grid.getColumnByName('ProductName'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 2 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + + GridFunctions.toggleMasterRow(fix, grid.rowList.first); + fix.detectChanges(); + + // should slit first merge group in 2 + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + }); + + + }); + + describe('Paging', () => { + it('should merge cells only on current page of data.', () => { + fix.componentInstance.paging = true; + fix.detectChanges(); + grid.triggerPipes(); + fix.detectChanges(); + + const col = grid.getColumnByName('ProductName'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 2 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 } + ]); + + grid.page = 2; + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for Angular', span: 1 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + }); + }); + + describe('Column Pinning', () => { + it('should merge cells in pinned columns.', () => { + const col = grid.getColumnByName('ProductName'); + col.pinned = true; + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 2 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + + const mergedCell = grid.rowList.first.cells.find(x => x.column.field === 'ProductName'); + expect(mergedCell.value).toBe('Ignite UI for JavaScript'); + expect(mergedCell.nativeElement.parentElement.style.gridTemplateRows).toBe("50px 50px"); + }); + }); + + describe('Row Pinning', () => { + it('should merge adjacent pinned rows in pinned row area.', () => { + const row1 = grid.rowList.toArray()[0]; + const row2 = grid.rowList.toArray()[1]; + const col = grid.getColumnByName('ProductName'); + row1.pin(); + row2.pin(); + fix.detectChanges(); + + expect(grid.pinnedRows.length).toBe(2); + const pinnedRow = grid.pinnedRows[0]; + expect(pinnedRow.metaData.cellMergeMeta.get(col.field)?.rowSpan).toBe(2); + const mergedPinnedCell = pinnedRow.cells.find(x => x.column.field === 'ProductName'); + expect(mergedPinnedCell.value).toBe('Ignite UI for JavaScript'); + expect(mergedPinnedCell.nativeElement.parentElement.style.gridTemplateRows).toBe("50px 50px"); + }); + + it('should merge adjacent ghost rows in unpinned area.', () => { + const row1 = grid.rowList.toArray()[0]; + const row2 = grid.rowList.toArray()[1]; + const col = grid.getColumnByName('ProductName'); + row1.pin(); + row2.pin(); + fix.detectChanges(); + + const ghostRows = grid.rowList.filter(x => x.disabled); + expect(ghostRows.length).toBe(2); + const ghostRow = ghostRows[0]; + expect(ghostRow.metaData.cellMergeMeta.get(col.field)?.rowSpan).toBe(2); + const mergedPinnedCell = ghostRow.cells.find(x => x.column.field === 'ProductName'); + expect(mergedPinnedCell.value).toBe('Ignite UI for JavaScript'); + expect(mergedPinnedCell.nativeElement.parentElement.style.gridTemplateRows).toBe("50px 50px"); + }); + + it('should not merge ghost and data rows together.', () => { + const col = grid.getColumnByName('ProductName'); + const row1 = grid.rowList.toArray()[0]; + row1.pin(); + fix.detectChanges(); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + }); + }); + + describe('Activation', () => { + + it('should interrupt merge sequence so that active row has no merging.', async() => { + const col = grid.getColumnByName('ProductName'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 2 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + + const row1 = grid.rowList.toArray()[0]; + + UIInteractions.simulateClickAndSelectEvent(row1.cells.toArray()[1].nativeElement); + await wait(1); + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + }); + + }); + + describe('Updating', () => { + + beforeEach(() => { + grid.primaryKey = 'ID'; + grid.columns.forEach(x => x.editable = true); + fix.detectChanges(); + }); + + it('should edit the individual row values for the active row.', async() => { + const col = grid.getColumnByName('ProductName'); + grid.rowEditable = true; + fix.detectChanges(); + + const row = grid.gridAPI.get_row_by_index(0); + const cell = grid.gridAPI.get_cell_by_index(0, 'ProductName'); + UIInteractions.simulateDoubleClickAndSelectEvent(cell.nativeElement); + await wait(1); + fix.detectChanges(); + expect(row.inEditMode).toBe(true); + + // row in edit is not merged anymore + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + + // enter new val + const cellInput = grid.gridAPI.get_cell_by_index(0, 'ProductName').nativeElement.querySelector('[igxinput]'); + UIInteractions.setInputElementValue(cellInput, "NewValue"); + fix.detectChanges(); + + // Done button click + const doneButtonElement = GridFunctions.getRowEditingDoneButton(fix); + doneButtonElement.click(); + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'NewValue', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + }); + + it('should edit the individual cell value for the active row.', () => { + const col = grid.getColumnByName('ProductName'); + let cell = grid.gridAPI.get_cell_by_index(0, 'ProductName'); + + UIInteractions.simulateDoubleClickAndSelectEvent(cell.nativeElement); + fix.detectChanges(); + + cell = grid.gridAPI.get_cell_by_index(0, 'ProductName'); + expect(cell.editMode).toBe(true); + + // enter new val + const cellInput = grid.gridAPI.get_cell_by_index(0, 'ProductName').nativeElement.querySelector('[igxinput]'); + UIInteractions.setInputElementValue(cellInput, "NewValue"); + fix.detectChanges(); + + UIInteractions.triggerEventHandlerKeyDown('enter', GridFunctions.getGridContent(fix)); + fix.detectChanges(); + + // row with edit cell is not merged anymore + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'NewValue', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + }); + }); + + describe('Row Selection', () => { + + it('should mark all merged cells that intersect with a selected row as selected.', () => { + grid.rowSelection = 'multiple'; + fix.detectChanges(); + + const secondRow = grid.rowList.toArray()[1]; + GridSelectionFunctions.clickRowCheckbox(secondRow); + fix.detectChanges(); + + expect(secondRow.selected).toBe(true); + + const mergedIntersectedCell = grid.gridAPI.get_cell_by_index(0, 'ProductName'); + // check cell has selected style + hasClass(mergedIntersectedCell.nativeElement,'igx-grid__td--merged-selected', true); + }); + + }); + + describe('Cell Selection', () => { + it('should interrupt merge sequence so that selected cell has no merging.', () => { + const col = grid.getColumnByName('ProductName'); + grid.cellSelection = 'multiple'; + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 2 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 2 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + + const startCell = grid.gridAPI.get_cell_by_index(4, 'ProductName'); + const endCell = grid.gridAPI.get_cell_by_index(0, 'ID'); + + GridSelectionFunctions.selectCellsRangeNoWait(fix, startCell, endCell); + fix.detectChanges(); + + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for JavaScript', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: 'Ignite UI for Angular', span: 1 }, + { value: null, span: 1 }, + { value: 'NetAdvantage', span: 2 } + ]); + + // check api + expect(grid.getSelectedData().length).toBe(5); + expect(grid.getSelectedData()).toEqual(grid.data.slice(0, 5).map(x => { + return { 'ID': x.ID, 'ProductName': x. ProductName}; + })); + }); + }); + + describe('Column selection', () => { + it('should mark merged cells in selected column as selected.', () => { + grid.columnSelection = 'multiple'; + fix.detectChanges(); + const col = grid.getColumnByName('ProductName'); + col.selected = true; + fix.detectChanges(); + + const mergedCells = fix.debugElement.queryAll(By.css(MERGE_CELL_CSS_CLASS)); + mergedCells.forEach(element => { + hasClass(element.nativeNode, 'igx-grid__td--column-selected', true); + }); + }); + + it('selected data API should return all associated data fields as selected.', () => { + grid.columnSelection = 'multiple'; + fix.detectChanges(); + const col = grid.getColumnByName('ProductName'); + col.selected = true; + fix.detectChanges(); + + expect(grid.getSelectedColumnsData()).toEqual(grid.data.map(x => { + return {'ProductName': x. ProductName}; + })); + }); + }); + + describe('Filtering', () => { + + it('should merge cells in filtered data.', () => { + grid.filter('ProductName', 'Net', IgxStringFilteringOperand.instance().condition('startsWith'), true); + fix.detectChanges(); + const col = grid.getColumnByName('ProductName'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'NetAdvantage', span: 2 } + ]); + }); + + }); + + describe('Searching', () => { + + it('findNext \ findPrev should count merged cells as 1 result and navigate once through them.', () => { + const cell0 = grid.gridAPI.get_cell_by_index(0, 'ProductName').nativeElement; + const cell3 = grid.gridAPI.get_cell_by_index(3, 'ProductName').nativeElement; + const fixNativeElem = fix.debugElement.nativeElement; + + let matches = grid.findNext('JavaScript'); + fix.detectChanges(); + + expect(matches).toBe(2); + + let activeHighlight = fixNativeElem.querySelectorAll(HIGHLIGHT_ACTIVE_CSS_CLASS); + expect(activeHighlight[0].closest("igx-grid-cell")).toBe(cell0); + + matches = grid.findNext('JavaScript'); + fix.detectChanges(); + + activeHighlight = fixNativeElem.querySelectorAll(HIGHLIGHT_ACTIVE_CSS_CLASS); + expect(activeHighlight[0].closest("igx-grid-cell")).toBe(cell3); + + matches = grid.findPrev('JavaScript'); + fix.detectChanges(); + + activeHighlight = fixNativeElem.querySelectorAll(HIGHLIGHT_ACTIVE_CSS_CLASS); + expect(activeHighlight[0].closest("igx-grid-cell")).toBe(cell0); + }); + + it('should update matches if a cell becomes unmerged.', async() => { + let matches = grid.findNext('JavaScript'); + fix.detectChanges(); + + expect(matches).toBe(2); + + UIInteractions.simulateClickAndSelectEvent(grid.gridAPI.get_cell_by_index(0, 'ProductName').nativeElement); + await wait(1); + fix.detectChanges(); + + matches = grid.findNext('JavaScript'); + fix.detectChanges(); + expect(matches).toBe(3); + }); + + }); + + describe('Multi-row layout', () => { + it('should throw warning and disallow merging with mrl.', () => { + jasmine.getEnv().allowRespy(true); + fix = TestBed.createComponent(ColumnLayoutTestComponent); + fix.detectChanges(); + grid = fix.componentInstance.grid; + spyOn(console, 'warn'); + grid.columns[1].merge = true; + fix.detectChanges(); + + expect(console.warn).toHaveBeenCalledWith('Merging is not supported with multi-row layouts.'); + expect(console.warn).toHaveBeenCalledTimes(1); + jasmine.getEnv().allowRespy(false); + }); + + }); + + describe('HierarchicalGrid', () => { + + beforeEach(() => { + fix = TestBed.createComponent(IgxHierarchicalGridTestBaseComponent); + fix.componentInstance.data = [ + { + ID: 1, ChildLevels: 1, ProductName: 'Product A' , Col1: 1, + childData: [ + { + ID: 1, ChildLevels: 2, ProductName: 'Product A' , Col1: 1, + }, + { + ID: 2, ChildLevels: 2, ProductName: 'Product A' , Col1: 1, + }, + { + ID: 3, ChildLevels: 2, ProductName: 'Product B' , Col1: 1, + }, + { + ID: 4, ChildLevels: 2, ProductName: 'Product A' , Col1: 1, + } + ] + }, + { + ID: 2, ChildLevels: 1, ProductName: 'Product A' , Col1: 1, childData: [ + { + ID: 1, ChildLevels: 2, ProductName: 'Product A' , Col1: 1, + }, + { + ID: 2, ChildLevels: 2, ProductName: 'Product A' , Col1: 1, + }, + { + ID: 3, ChildLevels: 2, ProductName: 'Product A' , Col1: 1, + }, + { + ID: 4, ChildLevels: 2, ProductName: 'Product A' , Col1: 1, + } + ] + }, + { + ID: 3, ChildLevels: 1, ProductName: 'Product B' , Col1: 1 + }, + { + ID: 4, ChildLevels: 1, ProductName: 'Product B' , Col1: 1 + }, + { + ID: 5, ChildLevels: 1, ProductName: 'Product C' , Col1: 1 + }, + { + ID: 6, ChildLevels: 1, ProductName: 'Product B' , Col1: 1 + } + ]; + fix.detectChanges(); + grid = fix.componentInstance.hgrid; + // enable merging + grid.cellMergeMode = 'always'; + const col = grid.getColumnByName('ProductName'); + col.merge = true; + fix.detectChanges(); + }); + + it('should allow configuring and merging cells on each level of hierarchy.', () => { + + const col = grid.getColumnByName('ProductName'); + // root grid should be merged + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Product A', span: 2 }, + { value: 'Product B', span: 2 }, + { value: 'Product C', span: 1 }, + { value: 'Product B', span: 1 } + ]); + + const ri = fix.componentInstance.rowIsland; + ri.cellMergeMode = 'always'; + ri.getColumnByName('ProductName').merge = true; + fix.detectChanges(); + + // toggle row + const firstRow = grid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent; + firstRow.toggle(); + fix.detectChanges(); + + const childGrid = grid.gridAPI.getChildGrids(false)[0] as IgxHierarchicalGridComponent; + expect(childGrid).toBeDefined(); + + // merging enabled + GridFunctions.verifyColumnMergedState(childGrid, childGrid.getColumnByName('ProductName'), [ + { value: 'Product A', span: 2 }, + { value: 'Product B', span: 1 }, + { value: 'Product A', span: 1 } + ]); + }); + + it('should merge cells within their respective grids only.', () => { + const ri = fix.componentInstance.rowIsland; + ri.cellMergeMode = 'always'; + ri.getColumnByName('ProductName').merge = true; + fix.detectChanges(); + + // toggle row 1 + const firstRow = grid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent; + firstRow.toggle(); + fix.detectChanges(); + + // toggle row 2 + const secondRow = grid.gridAPI.get_row_by_index(2) as IgxHierarchicalRowComponent; + secondRow.toggle(); + fix.detectChanges(); + + const childGrid1 = grid.gridAPI.getChildGrids(false)[0] as IgxHierarchicalGridComponent; + expect(childGrid1).toBeDefined(); + + GridFunctions.verifyColumnMergedState(childGrid1, childGrid1.getColumnByName('ProductName'), [ + { value: 'Product A', span: 2 }, + { value: 'Product B', span: 1 }, + { value: 'Product A', span: 1 } + ]); + + const childGrid2 = grid.gridAPI.getChildGrids(false)[1] as IgxHierarchicalGridComponent; + expect(childGrid2).toBeDefined(); + + GridFunctions.verifyColumnMergedState(childGrid2, childGrid2.getColumnByName('ProductName'), [ + { value: 'Product A', span: 4 } + ]); + }); + + it('should interrupt merge sequence if row is expanded and a child grid is shown between same value cells.', () => { + const col = grid.getColumnByName('ProductName'); + // root grid should be merged + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Product A', span: 2 }, + { value: 'Product B', span: 2 }, + { value: 'Product C', span: 1 }, + { value: 'Product B', span: 1 } + ]); + + // toggle row 1 + const firstRow = grid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent; + firstRow.toggle(); + fix.detectChanges(); + + // first merge sequence interrupted due to expanded row + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: 'Product A', span: 1 }, + { value: 'Product A', span: 1 }, + { value: 'Product B', span: 2 }, + { value: 'Product C', span: 1 }, + { value: 'Product B', span: 1 } + ]); + }); + + }); + + describe('TreeGrid', () => { + + beforeEach(() => { + fix = TestBed.createComponent(IgxTreeGridSelectionComponent); + fix.detectChanges(); + grid = fix.componentInstance.treeGrid; + // enable merging + grid.cellMergeMode = 'always'; + const col = grid.getColumnByName('OnPTO'); + col.merge = true; + fix.detectChanges(); + }); + + it('should merge all cells with same values, even if on different levels by default.', () => { + const col = grid.getColumnByName('OnPTO'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: false, span: 2 }, + { value: true, span: 1 }, + { value: false, span: 1 }, + { value: true, span: 1 }, + { value: false, span: 2 }, + { value: true, span: 1 }, + { value: false, span: 3 }, + { value: true, span: 1 } + ]); + }); + + it('should allow setting the ByLevelTreeGridMergeStrategy as the mergeStrategy to merge only data on the same hierarchy level.', () => { + grid.mergeStrategy = new ByLevelTreeGridMergeStrategy(); + fix.detectChanges(); + grid.triggerPipes(); + fix.detectChanges(); + const col = grid.getColumnByName('OnPTO'); + GridFunctions.verifyColumnMergedState(grid, col, [ + { value: false, span: 1 }, + { value: false, span: 1 }, + { value: true, span: 1 }, + { value: false, span: 1 }, + { value: true, span: 1 }, + { value: false, span: 1 }, + { value: false, span: 1 }, + { value: true, span: 1 }, + { value: false, span: 1 }, + { value: false, span: 1 }, + { value: false, span: 1 }, + { value: true, span: 1 } + ]); + }); + }); + }); +}); + +@Component({ + template: ` + + @for(col of cols; track col) { + + } + + + + + `, + imports: [IgxGridComponent, IgxColumnComponent] +}) +export class DefaultCellMergeGridComponent extends DataParent { + public mergeMode: GridCellMergeMode = GridCellMergeMode.always; + @ViewChild('grid', { read: IgxGridComponent, static: true }) + public grid: IgxGridComponent; + + @ViewChild('customTemplate', { read: TemplateRef, static: true }) + public customTemplate: TemplateRef; + + public cols = [ + { field: 'ID', merge: false }, + { field: 'ProductName', dataType: GridColumnDataType.String, merge: true }, + { field: 'Downloads', dataType: GridColumnDataType.Number, merge: false }, + { field: 'Released', dataType: GridColumnDataType.Boolean, merge: false }, + { field: 'ReleaseDate', dataType: GridColumnDataType.Date, merge: false } + ]; + + public override data = [ + { + Downloads: 254, + ID: 1, + ProductName: 'Ignite UI for JavaScript', + ReleaseDate: this.today, + Released: true + }, + { + Downloads: 1000, + ID: 2, + ProductName: 'Ignite UI for JavaScript', + ReleaseDate: this.nextDay, + Released: true + }, + { + Downloads: 20, + ID: 3, + ProductName: 'Ignite UI for Angular', + ReleaseDate: null, + Released: true + }, + { + Downloads: null, + ID: 4, + ProductName: 'Ignite UI for JavaScript', + ReleaseDate: this.prevDay, + Released: true + }, + { + Downloads: 100, + ID: 5, + ProductName: 'Ignite UI for Angular', + ReleaseDate: null, + Released: true + }, + { + Downloads: 1000, + ID: 6, + ProductName: 'Ignite UI for Angular', + ReleaseDate: this.nextDay, + Released: true + }, + { + Downloads: 0, + ID: 7, + ProductName: null, + ReleaseDate: this.prevDay, + Released: true + }, + { + Downloads: 1000, + ID: 8, + ProductName: 'NetAdvantage', + ReleaseDate: this.today, + Released: true + }, + { + Downloads: 1000, + ID: 9, + ProductName: 'NetAdvantage', + ReleaseDate: this.prevDay, + Released: true + } + ]; + +} + +@Component({ + template: ` + + @for(col of cols; track col) { + + } + @if (paging) { + + } + + + + + `, + imports: [IgxGridComponent, IgxColumnComponent, IgxPaginatorComponent] +}) +export class IntegrationCellMergeGridComponent extends DefaultCellMergeGridComponent { + public height = '100%'; + public width = '100%'; + public paging = false; + + @ViewChild('detailTemplate', { read: TemplateRef, static: true }) + public detailTemplate: TemplateRef; +} + +class NoopMergeStrategy extends DefaultMergeStrategy { + public override merge( + data: any[], + field: string, + comparer: (prevRecord: any, record: any, field: string) => boolean = this.comparer, + result: any[], + activeRowIndexes: number[], + isDate?: boolean, + isTime?: boolean, + grid?: GridType + ) { + return data; + } +} diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html index f0eecaecd20..825d6951afb 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html @@ -27,15 +27,52 @@ @if (!grid.hasColumnLayouts) { @if (pinnedStartColumns.length > 0) { @for (col of pinnedStartColumns | igxNotGrouped; track trackPinnedColumn(col)) { - + @if (this.hasMergedCells) { +
+ +
+ } + @else { + + } } } - + @if (this.hasMergedCells) { +
+ +
+ } + @else { + + } +
@if (pinnedEndColumns.length > 0) { @for (col of pinnedEndColumns | igxNotGrouped; track trackPinnedColumn(col)) { - + @if (this.hasMergedCells) { +
+ +
+ } + @else { + + } } } } @@ -95,6 +132,11 @@ @@ -185,7 +232,7 @@ [lastSearchInfo]="grid.lastSearchInfo" [active]="isCellActive(col.visibleIndex)" [cellSelectionMode]="grid.cellSelection" - [displayPinnedChip]="shouldDisplayPinnedChip(col.visibleIndex)" + [displayPinnedChip]="shouldDisplayPinnedChip(col)" #cell> @@ -217,7 +264,7 @@ [lastSearchInfo]="grid.lastSearchInfo" [active]="isCellActive(col.visibleIndex)" [cellSelectionMode]="grid.cellSelection" - [displayPinnedChip]="shouldDisplayPinnedChip(col.visibleIndex)" + [displayPinnedChip]="shouldDisplayPinnedChip(col)" #cell> diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html index 611c4035eef..9631c1bd71a 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html @@ -47,6 +47,20 @@ } + + @if (mergedDataInView && mergedDataInView.length > 0) { +
+ @for (rowData of mergedDataInView; track rowData.record;) { + + + } +
+ } + @if (data | gridTransaction:id:pipeTrigger @@ -54,7 +68,8 @@ | gridAddRow:true:pipeTrigger | gridRowPinning:id:true:pipeTrigger | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true - | gridSort:sortingExpressions:groupingExpressions:sortStrategy:id:pipeTrigger:true; as pinnedData) { + | gridSort:sortingExpressions:groupingExpressions:sortStrategy:id:pipeTrigger:true + | gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:true:pipeTrigger; as pinnedData) { @if (pinnedData.length > 0) {
- @for (rowData of pinnedData; track rowData; let rowIndex = $index) { + @for (rowData of pinnedData; track (rowData.recordRef || rowData); let rowIndex = $index) { } @@ -80,7 +95,8 @@ | gridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:showSummaryOnCollapse:pipeTrigger:summaryPipeTrigger | gridDetails:hasDetails:expansionStates:pipeTrigger | gridAddRow:false:pipeTrigger - | gridRowPinning:id:false:pipeTrigger" + | gridRowPinning:id:false:pipeTrigger + | gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:false:pipeTrigger" let-rowIndex="index" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]="verticalScroll" [igxForContainerSize]="calcHeight" [igxForItemSize]="hasColumnLayouts ? rowHeight * multiRowLayoutRowSize + 1 : renderedRowHeight" @@ -96,15 +112,15 @@ - - + - - + diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts index ddf918f42b7..247975c757f 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts @@ -34,7 +34,7 @@ import { IGridGroupingStrategy } from '../common/strategy'; import { IgxGridValidationService } from './grid-validation.service'; import { IgxGridDetailsPipe } from './grid.details.pipe'; import { IgxGridSummaryPipe } from './grid.summary.pipe'; -import { IgxGridGroupingPipe, IgxGridPagingPipe, IgxGridSortingPipe, IgxGridFilteringPipe } from './grid.pipes'; +import { IgxGridGroupingPipe, IgxGridPagingPipe, IgxGridSortingPipe, IgxGridFilteringPipe, IgxGridCellMergePipe } from './grid.pipes'; import { IgxSummaryDataPipe } from '../summaries/grid-root-summary.pipe'; import { IgxGridTransactionPipe, IgxHasVisibleColumnsPipe, IgxGridRowPinningPipe, IgxGridAddRowPipe, IgxGridRowClassesPipe, IgxGridRowStylesPipe, IgxStringReplacePipe } from '../common/pipes'; import { IgxGridColumnResizerComponent } from '../resizing/resizer.component'; @@ -54,6 +54,7 @@ import { IgxGridBodyDirective } from '../grid.common'; import { IgxGridHeaderRowComponent } from '../headers/grid-header-row.component'; import { IgxGridGroupByAreaComponent } from '../grouping/grid-group-by-area.component'; import { Observable, Subject } from 'rxjs'; +import { IgxScrollInertiaDirective } from '../../directives/scroll-inertia/scroll_inertia.directive'; let NEXT_ID = 0; @@ -151,7 +152,9 @@ export interface IGroupingDoneEventArgs extends IBaseEventArgs { IgxGridFilteringPipe, IgxGridSummaryPipe, IgxGridDetailsPipe, - IgxStringReplacePipe + IgxStringReplacePipe, + IgxGridCellMergePipe, + IgxScrollInertiaDirective ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) @@ -388,7 +391,6 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType, private _groupByRowSelectorTemplate: TemplateRef; private _detailTemplate; - /** * Gets/Sets the array of data that populates the component. * @@ -948,13 +950,14 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType, } } return { - $implicit: this.isGhostRecord(rowData) ? rowData.recordRef : rowData, + $implicit: this.isGhostRecord(rowData) || this.isRecordMerged(rowData) ? rowData.recordRef : rowData, index: this.getDataViewIndex(rowIndex, pinned), templateID: { type: this.isGroupByRecord(rowData) ? 'groupRow' : this.isSummaryRow(rowData) ? 'summaryRow' : 'dataRow', id: null }, - disabled: this.isGhostRecord(rowData) + disabled: this.isGhostRecord(rowData), + metaData: this.isRecordMerged(rowData) ? rowData : null }; } @@ -1344,7 +1347,7 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType, this._gridAPI.sort_groupBy_multiple(this._groupingExpressions); } - private _setupNavigationService() { + protected _setupNavigationService() { if (this.hasColumnLayouts) { this.navigation = new IgxGridMRLNavigationService(this.platform); this.navigation.grid = this; diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts index 4f5a4238eb4..dedd1a26cc3 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts @@ -5,10 +5,12 @@ import { IGroupByExpandState } from '../../data-operations/groupby-expand-state. import { IGroupByResult } from '../../data-operations/grouping-result.interface'; import { IFilteringExpressionsTree, FilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; import { IGroupingExpression } from '../../data-operations/grouping-expression.interface'; -import { GridType, IGX_GRID_BASE } from '../common/grid.interface'; +import { ColumnType, GridType, IGX_GRID_BASE } from '../common/grid.interface'; import { FilterUtil, IFilteringStrategy } from '../../data-operations/filtering-strategy'; import { ISortingExpression } from '../../data-operations/sorting-strategy'; import { IGridSortingStrategy, IGridGroupingStrategy } from '../common/strategy'; +import { GridCellMergeMode, RowPinningPosition } from '../common/enums'; +import { IGridMergeStrategy } from '../../data-operations/merge-strategy'; /** * @hidden @@ -76,6 +78,26 @@ export class IgxGridGroupingPipe implements PipeTransform { } } +@Pipe({ + name: 'gridCellMerge', + standalone: true +}) +export class IgxGridCellMergePipe implements PipeTransform { + + constructor(@Inject(IGX_GRID_BASE) private grid: GridType) { } + + public transform(collection: any, colsToMerge: ColumnType[], mergeMode: GridCellMergeMode, mergeStrategy: IGridMergeStrategy, activeRowIndexes: number[], pinned: boolean, _pipeTrigger: number) { + if (colsToMerge.length === 0) { + return collection; + } + if (this.grid.hasPinnedRecords && !pinned && this.grid.pinning.rows !== RowPinningPosition.Bottom) { + activeRowIndexes = activeRowIndexes.map(x => x - this.grid.pinnedRecordsCount); + } + const result = DataUtil.merge(cloneArray(collection), colsToMerge, mergeStrategy, activeRowIndexes, this.grid); + return result; + } +} + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index b59998440a4..276e89cb377 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -31,6 +31,18 @@ [igxColumnMovingDrop]="headerContainer" [attr.droppable]="true" id="left" class="igx-grid__scroll-on-drag-pinned" [style.left.px]="pinnedStartWidth"> } + @if (mergedDataInView && mergedDataInView.length > 0) { +
+ @for (rowData of mergedDataInView; track rowData.record;) { + + + } +
+ } @if (data | gridTransaction:id:pipeTrigger @@ -38,13 +50,14 @@ | gridAddRow:true:pipeTrigger | gridRowPinning:id:true:pipeTrigger | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true - | gridSort:sortingExpressions:[]:sortStrategy:id:pipeTrigger:true; as pinnedData + | gridSort:sortingExpressions:[]:sortStrategy:id:pipeTrigger:true + | gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:true:pipeTrigger; as pinnedData ) { @if (pinnedData.length > 0) {
- @for (rowData of pinnedData; track rowData; let rowIndex = $index) { + @for (rowData of pinnedData; track (rowData.recordRef || rowData); let rowIndex = $index) { } @@ -62,7 +75,8 @@ | gridHierarchicalPaging:!!paginator:page:perPage:id:pipeTrigger | gridHierarchical:expansionStates:id:primaryKey:childLayoutKeys:pipeTrigger | gridAddRow:false:pipeTrigger - | gridRowPinning:id:false:pipeTrigger" + | gridRowPinning:id:false:pipeTrigger + | gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:false:pipeTrigger" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]="verticalScroll" [igxForContainerSize]="calcHeight" [igxForItemSize]="renderedRowHeight" [igxForTrackBy]="trackChanges" #verticalScrollContainer (chunkPreload)="dataLoading($event)" (dataChanging)="dataRebinding($event)" (dataChanged)="dataRebound($event)"> @@ -73,16 +87,16 @@ - - + - - + diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index 2ce0f166cb2..988fa60ec80 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -50,7 +50,7 @@ import { IgxGridValidationService } from '../grid/grid-validation.service'; import { IgxGridHierarchicalPipe, IgxGridHierarchicalPagingPipe } from './hierarchical-grid.pipes'; import { IgxSummaryDataPipe } from '../summaries/grid-root-summary.pipe'; import { IgxGridTransactionPipe, IgxHasVisibleColumnsPipe, IgxGridRowPinningPipe, IgxGridAddRowPipe, IgxGridRowClassesPipe, IgxGridRowStylesPipe, IgxStringReplacePipe } from '../common/pipes'; -import { IgxGridSortingPipe, IgxGridFilteringPipe } from '../grid/grid.pipes'; +import { IgxGridSortingPipe, IgxGridFilteringPipe, IgxGridCellMergePipe } from '../grid/grid.pipes'; import { IgxGridColumnResizerComponent } from '../resizing/resizer.component'; import { IgxRowEditTabStopDirective } from '../grid.rowEdit.directive'; import { IgxIconComponent } from '../../icon/icon.component'; @@ -68,6 +68,7 @@ import { IgxGridHeaderRowComponent } from '../headers/grid-header-row.component' import { IgxActionStripToken } from '../../action-strip/token'; import { flatten } from '../../core/utils'; import { IFilteringExpressionsTree } from '../../data-operations/filtering-expressions-tree'; +import { IgxScrollInertiaDirective } from '../../directives/scroll-inertia/scroll_inertia.directive'; let NEXT_ID = 0; @@ -350,7 +351,9 @@ export class IgxChildGridRowComponent implements AfterViewInit, OnInit { IgxSummaryDataPipe, IgxGridHierarchicalPipe, IgxGridHierarchicalPagingPipe, - IgxStringReplacePipe + IgxStringReplacePipe, + IgxGridCellMergePipe, + IgxScrollInertiaDirective ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) @@ -942,7 +945,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public isChildGridRecord(record: any): boolean { + public override isChildGridRecord(record: any): boolean { // Can be null when there is defined layout but no child data was found return record?.childGridsData !== undefined; } @@ -986,13 +989,14 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti } } else { return { - $implicit: this.isGhostRecord(rowData) ? rowData.recordRef : rowData, + $implicit: this.isGhostRecord(rowData) || this.isRecordMerged(rowData) ? rowData.recordRef : rowData, templateID: { type: 'dataRow', id: null }, index: this.getDataViewIndex(rowIndex, pinned), - disabled: this.isGhostRecord(rowData) + disabled: this.isGhostRecord(rowData), + metaData: this.isRecordMerged(rowData) ? rowData : null }; } } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html index 131773bd307..eb204fb12ef 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html @@ -54,32 +54,19 @@ } - - + @if (this.hasMergedCells) { +
+ +
+ } + @else { + + }
@if (pinnedEndColumns.length > 0) { @@ -127,8 +114,42 @@ [cellValidationErrorTemplate]="col.errorTemplate" [lastSearchInfo]="grid.lastSearchInfo" [cellSelectionMode]="grid.cellSelection" - [displayPinnedChip]="shouldDisplayPinnedChip(col.visibleIndex)"> + [displayPinnedChip]="shouldDisplayPinnedChip(col)"> } + + + + + diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html index 6f71cf31802..558cf1c4721 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html @@ -52,7 +52,7 @@ diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-row.component.html b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-row.component.html index 39d6a48bd63..a6a93da2e92 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-row.component.html @@ -16,7 +16,7 @@ [style.flex-basis]="col.resolvedWidth" [width]="col.getCellWidth()" [visibleColumnIndex]="col.visibleIndex" [value]="pivotAggregationData[col.field] | dataMapper:col.field:grid.pipeTrigger:pivotAggregationData[col.field]:col.hasNestedPath" [cellTemplate]="col.bodyTemplate" [lastSearchInfo]="grid.lastSearchInfo" - [cellSelectionMode]="grid.cellSelection" [displayPinnedChip]="shouldDisplayPinnedChip(col.visibleIndex)" + [cellSelectionMode]="grid.cellSelection" [displayPinnedChip]="shouldDisplayPinnedChip(col)" (pointerdown)="grid.navigation.focusOutRowHeader($event)"> diff --git a/projects/igniteui-angular/src/lib/grids/row.directive.ts b/projects/igniteui-angular/src/lib/grids/row.directive.ts index 922e0b14b90..f895f59545a 100644 --- a/projects/igniteui-angular/src/lib/grids/row.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/row.directive.ts @@ -45,6 +45,12 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { @HostBinding('attr.role') public role = 'row'; + /** + * @hidden + */ + @Input() + public metaData: any; + /** * The data passed to the row component. * @@ -117,6 +123,10 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { return this.grid.isRecordPinned(this.data); } + public get hasMergedCells(): boolean { + return this.grid.columnsToMerge.length > 0; + } + /** * Gets the expanded state of the row. * ```typescript @@ -401,6 +411,14 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { */ @HostListener('click', ['$event']) public onClick(event: MouseEvent) { + if (this.hasMergedCells && this.metaData?.cellMergeMeta) { + const targetRowIndex = this.grid.navigation.activeNode.row; + if (targetRowIndex != this.index) { + const row = this.grid.rowList.toArray().find(x => x.index === targetRowIndex); + row.onClick(event); + return; + } + } this.grid.rowClick.emit({ row: this, event @@ -445,6 +463,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { if (this.grid.actionStrip) { this.grid.actionStrip.show(this); } + this.grid.hoverIndex = this.index; } /** @@ -456,6 +475,7 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { if (this.grid.actionStrip && this.grid.actionStrip.hideOnRowLeave) { this.grid.actionStrip.hide(); } + this.grid.hoverIndex = null; } /** @@ -526,6 +546,12 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { public isCellActive(visibleColumnIndex) { const node = this.grid.navigation.activeNode; + const field = this.grid.visibleColumns[visibleColumnIndex]?.field; + const rowSpan = this.metaData?.cellMergeMeta?.get(field)?.rowSpan; + if (rowSpan > 1) { + return node ? (node.row >= this.index && node.row < this.index + rowSpan) + && node.column === visibleColumnIndex : false; + } return node ? node.row === this.index && node.column === visibleColumnIndex : false; } @@ -574,8 +600,8 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { /** * @hidden */ - public shouldDisplayPinnedChip(visibleColumnIndex: number): boolean { - return this.pinned && this.disabled && visibleColumnIndex === 0; + public shouldDisplayPinnedChip(col: ColumnType): boolean { + return this.pinned && this.disabled && col.visibleIndex === 0 && !this.metaData?.cellMergeMeta?.get(col.field)?.root; } /** @@ -606,6 +632,65 @@ export class IgxRowDirective implements DoCheck, AfterViewInit, OnDestroy { this.addAnimationEnd.emit(this); } + protected getMergeCellSpan(col: ColumnType) { + const rowCount = this.metaData.cellMergeMeta.get(col.field).rowSpan; + let sizeSpans = ""; + const isPinned = this.pinned && !this.disabled; + const indexInData = this.grid.isRowPinningToTop && !isPinned ? this.index - this.grid.pinnedRecordsCount : this.index; + for (let index = indexInData; index < indexInData + rowCount; index++) { + const size = this.grid.verticalScrollContainer.getSizeAt(index); + sizeSpans += size + 'px '; + } + return `${sizeSpans}`; + } + + protected isSelectionRoot(col: ColumnType) { + const mergeMeta = this.metaData?.cellMergeMeta; + const rowCount = mergeMeta?.get(col.field)?.rowSpan; + if (mergeMeta && rowCount > 1) { + const isPinned = this.pinned && !this.disabled; + const indexInData = this.grid.isRowPinningToTop && !isPinned ? this.index - this.grid.pinnedRecordsCount : this.index; + const range = isPinned ? this.grid.pinnedDataView.slice(indexInData, indexInData + rowCount) : this.grid.verticalScrollContainer.igxForOf.slice(indexInData, indexInData + rowCount); + const inRange = range.filter(x => this.selectionService.isRowSelected(this.extractRecordKey(x))).length > 0; + return inRange; + } + return false; + } + + protected isHoveredRoot(col: ColumnType) { + const mergeMeta = this.metaData?.cellMergeMeta; + const rowCount = mergeMeta?.get(col.field)?.rowSpan; + if (mergeMeta && rowCount > 1 && this.grid.hoverIndex !== null && this.grid.hoverIndex !== undefined) { + const indexInData = this.index; + const hoveredIndex = this.grid.hoverIndex; + return indexInData <= hoveredIndex && indexInData + rowCount > hoveredIndex; + } + return false; + } + + protected extractRecordKey(rec: any) { + let recData = rec; + if (this.grid.isRecordMerged(recData)) { + recData = rec.recordRef; + } + + if(this.grid.isTreeRow && this.grid.isTreeRow(recData)){ + recData = recData.data; + } + return this.grid.primaryKey ? recData[this.grid.primaryKey] : recData; + } + + protected getRowHeight() { + const isPinned = this.pinned && !this.disabled; + const indexInData = this.grid.isRowPinningToTop && !isPinned ? this.index - this.grid.pinnedRecordsCount : this.index; + if ((this.grid as any)._cdrRequests) { + // recalc size if repaint is requested. + this.grid.verticalScrollContainer.recalcUpdateSizes(); + } + const size = this.grid.verticalScrollContainer.getSizeAt(indexInData) - 1; + return size || this.grid.rowHeight; + } + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts b/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts index e97cc8a0f2a..0610c491e63 100644 --- a/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts +++ b/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts @@ -35,6 +35,11 @@ export class IgxGridSelectionService { */ public selectedRowsChange = new Subject(); + /** + * @hidden @internal + */ + public selectedRangeChange = new Subject>>(); + /** * Toggled when a pointerdown event is triggered inside the grid body (cells). * When `false` the drag select behavior is disabled. @@ -355,6 +360,8 @@ export class IgxGridSelectionService { } } } + + this.selectedRangeChange.next(collection); } public dragSelect(node: ISelectionNode, state: SelectionState): void { diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html index f1143950558..b526f039ca9 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-row.component.html @@ -23,66 +23,19 @@ } - - - - - - - - - + @if (this.hasMergedCells) { +
+ +
+ } + @else { + + }
@if (pinnedEndColumns.length > 0) { @@ -106,69 +59,95 @@ @for (col of columns | igxNotGrouped; track trackPinnedColumn(col)) { - - - - - - - - - + @if (this.hasMergedCells) { +
+ +
+ } + @else { + + } }
+ + + + + + + + + + diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html index c68e5c6d5cb..33c79416332 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html @@ -30,6 +30,20 @@ [igxColumnMovingDrop]="headerContainer" [attr.droppable]="true" id="left" class="igx-grid__scroll-on-drag-pinned" [style.left.px]="pinnedStartWidth"> } + + @if (mergedDataInView && mergedDataInView.length > 0) { +
+ @for (rowData of mergedDataInView; track rowData.record;) { + + + } +
+ } + @if (data | treeGridTransaction:pipeTrigger @@ -38,7 +52,8 @@ | treeGridAddRow:true:pipeTrigger | gridRowPinning:id:true:pipeTrigger | treeGridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:pipeTrigger:filteringPipeTrigger:true - | treeGridSorting:sortingExpressions:treeGroupArea?.expressions:sortStrategy:pipeTrigger:true; as pinnedData + | treeGridSorting:sortingExpressions:treeGroupArea?.expressions:sortStrategy:pipeTrigger:true + | gridCellMerge:columnsToMerge:cellMergeMode:mergeStrategy:activeRowIndexes:true:pipeTrigger; as pinnedData ) { @if (pinnedData.length > 0) {
@@ -76,15 +92,15 @@ - - + - - + diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts index 30f413e00e4..4820bca8339 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts @@ -82,6 +82,9 @@ import { IgxGridDragSelectDirective } from '../selection/drag-select.directive'; import { IgxGridBodyDirective } from '../grid.common'; import { IgxGridHeaderRowComponent } from '../headers/grid-header-row.component'; import { IgxTextHighlightService } from '../../directives/text-highlight/text-highlight.service'; +import { IgxGridCellMergePipe } from '../grid/grid.pipes'; +import { DefaultTreeGridMergeStrategy, IGridMergeStrategy } from '../../data-operations/merge-strategy'; +import { IgxScrollInertiaDirective } from '../../directives/scroll-inertia/scroll_inertia.directive'; let NEXT_ID = 0; @@ -168,7 +171,9 @@ let NEXT_ID = 0; IgxTreeGridSummaryPipe, IgxTreeGridNormalizeRecordsPipe, IgxTreeGridAddRowPipe, - IgxStringReplacePipe + IgxStringReplacePipe, + IgxGridCellMergePipe, + IgxScrollInertiaDirective ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) @@ -348,6 +353,7 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy protected override _filterStrategy = new TreeGridFilteringStrategy(); protected override _transactions: HierarchicalTransactionService; + protected override _mergeStrategy: IGridMergeStrategy = new DefaultTreeGridMergeStrategy(); private _data; private _rowLoadingIndicatorTemplate: TemplateRef; private _expansionDepth = Infinity; @@ -699,13 +705,14 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy */ public getContext(rowData: any, rowIndex: number, pinned?: boolean): any { return { - $implicit: this.isGhostRecord(rowData) ? rowData.recordRef : rowData, + $implicit: this.isGhostRecord(rowData) || this.isRecordMerged(rowData) ? rowData.recordRef : rowData, index: this.getDataViewIndex(rowIndex, pinned), templateID: { type: this.isSummaryRow(rowData) ? 'summaryRow' : 'dataRow', id: null }, - disabled: this.isGhostRecord(rowData) ? rowData.recordRef.isFilteredOutParent === undefined : false + disabled: this.isGhostRecord(rowData) ? rowData.recordRef.isFilteredOutParent === undefined : false, + metaData: this.isRecordMerged(rowData) ? rowData : null }; } diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts index 8a1e2af8635..38f0578a17e 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts @@ -773,7 +773,7 @@ describe('IgxQueryBuilder', () => { // Verify value input placeholder const input = QueryBuilderFunctions.getQueryBuilderValueInput(fix).querySelector('input'); // Verify value input placeholder - expect(input.placeholder).toEqual('Select date'); + expect(input.placeholder).toEqual(queryBuilder.resourceStrings.igx_query_builder_date_placeholder); QueryBuilderFunctions.verifyEditModeExpressionInputStates(fix, true, true, false, true); // Third input should be disabled for unary operators. // Commit the populated expression. diff --git a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts index 24d751b251e..0083516d4e1 100644 --- a/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/simple-combo/simple-combo.component.spec.ts @@ -532,6 +532,7 @@ describe('IgxSimpleCombo', () => { }); it('should delete the selection on destroy', () => { + jasmine.getEnv().allowRespy(true); const selectionService = new IgxSelectionAPIService(); const comboClearSpy = spyOn(mockComboService, 'clear'); const selectionDeleteSpy = spyOn(selectionService, 'delete'); @@ -548,6 +549,7 @@ describe('IgxSimpleCombo', () => { combo.ngOnDestroy(); expect(comboClearSpy).toHaveBeenCalled(); expect(selectionDeleteSpy).toHaveBeenCalled(); + jasmine.getEnv().allowRespy(false); }); }); diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts index 8fe08283d36..aec6b388b6c 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts @@ -19,7 +19,7 @@ import { IgxGridCellComponent } from '../grids/cell.component'; import { IgxPivotRowComponent } from '../grids/pivot-grid/pivot-row.component'; import { SortingDirection } from '../data-operations/sorting-strategy'; import { IgxRowDirective } from '../grids/row.directive'; -import { CellType, GridType, RowType } from '../grids/common/grid.interface'; +import { CellType, ColumnType, GridType, RowType } from '../grids/common/grid.interface'; import { IgxTreeNodeComponent } from '../tree/tree-node/tree-node.component'; import { IgxColumnComponent } from '../grids/columns/column.component'; import { IgxPivotGridComponent } from '../grids/pivot-grid/pivot-grid.component'; @@ -104,6 +104,21 @@ export const SAFE_DISPOSE_COMP_ID = 'root'; export class GridFunctions { + public static verifyColumnMergedState(grid: GridType, col: ColumnType, state: any[]) { + const dataRows = grid.dataRowList.toArray(); + let totalSpan = 0; + for (let index = 0; index < dataRows.length - 1; index++) { + const row = dataRows[index]; + const cellValue = row.cells.toArray().find(x => x.column === col).value; + const rowSpan = row.metaData?.cellMergeMeta.get(col.field)?.rowSpan || 1; + const currState = state[index - totalSpan]; + expect(cellValue).toEqual(currState.value); + expect(rowSpan).toEqual(currState.span); + totalSpan += (rowSpan - 1); + index += (rowSpan - 1); + } + } + public static getRows(fix): DebugElement[] { const rows: DebugElement[] = fix.debugElement.queryAll(By.css(ROW_CSS_CLASS)); rows.shift(); diff --git a/projects/igniteui-angular/src/lib/test-utils/ui-interactions.spec.ts b/projects/igniteui-angular/src/lib/test-utils/ui-interactions.spec.ts index 0b72f5a3c7b..eb470e8137f 100644 --- a/projects/igniteui-angular/src/lib/test-utils/ui-interactions.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/ui-interactions.spec.ts @@ -345,6 +345,7 @@ export class UIInteractions { cancelable: true, pointerId: 1, buttons: 1, + clientY: element.getBoundingClientRect().y, button: eventName === 'pointerenter' ? -1 : 0, shiftKey, ctrlKey diff --git a/projects/igniteui-angular/src/public_api.ts b/projects/igniteui-angular/src/public_api.ts index 0e844761ba2..d4a70104a95 100644 --- a/projects/igniteui-angular/src/public_api.ts +++ b/projects/igniteui-angular/src/public_api.ts @@ -52,6 +52,7 @@ export * from './lib/data-operations/filtering-expressions-tree'; export * from './lib/data-operations/filtering-condition'; export * from './lib/data-operations/filtering-state.interface'; export * from './lib/data-operations/filtering-strategy'; +export * from './lib/data-operations/merge-strategy'; export { ExpressionsTreeUtil } from './lib/data-operations/expressions-tree-util'; export * from './lib/data-operations/groupby-expand-state.interface'; export * from './lib/data-operations/groupby-record.interface'; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index c4637552c6b..c3d2d4d104b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -211,6 +211,11 @@ export class AppComponent implements OnInit { icon: 'view_column', name: 'Grid Cell Editing' }, + { + link: '/gridCellMerging', + icon: 'view_column', + name: 'Grid Cell Merging' + }, { link: '/gridClipboard', icon: 'insert_comment', diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 992516f1574..5234d396dc1 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -51,6 +51,7 @@ import { TimePickerSampleComponent } from './time-picker/time-picker.sample'; import { ToastShowcaseSampleComponent } from './toast-showcase/toast-showcase.sample'; import { VirtualForSampleComponent } from './virtual-for-directive/virtual-for.sample'; import { GridCellEditingComponent } from './grid-cellEditing/grid-cellEditing.component'; +import { GridCellMergingComponent } from './grid-cellMerging/grid-cellMerging.component'; import { GridSampleComponent } from './grid/grid.sample'; import { GridColumnMovingSampleComponent } from './grid-column-moving/grid-column-moving.sample'; import { GridColumnSelectionSampleComponent } from './grid-column-selection/grid-column-selection.sample'; @@ -419,6 +420,10 @@ export const appRoutes: Routes = [ path: 'gridCellEditing', component: GridCellEditingComponent }, + { + path: 'gridCellMerging', + component: GridCellMergingComponent + }, { path: 'gridConditionalCellStyling', component: GridCellStylingSampleComponent diff --git a/src/app/grid-cellMerging/grid-cellMerging.component.html b/src/app/grid-cellMerging/grid-cellMerging.component.html new file mode 100644 index 00000000000..73233eb9c1c --- /dev/null +++ b/src/app/grid-cellMerging/grid-cellMerging.component.html @@ -0,0 +1,122 @@ +

Grid with cell merge

+ +
+ + + @if (searchText.length === 0) { + search + } + @if (searchText.length > 0) { + clear + } + + + + + @if (searchText.length > 0) { + + @if (grid.lastSearchInfo) { +
+ @if (grid.lastSearchInfo.matchInfoCache.length > 0) { + + {{ grid.lastSearchInfo.activeMatchIndex + 1 }} of {{ grid.lastSearchInfo.matchInfoCache.length }} + results + + } + @if (grid.lastSearchInfo.matchInfoCache.length === 0) { + + No results + + } +
+ } +
+ + +
+
+ } +
+
+ + + + Value: {{val}},Index: {{cell.row.index}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Hierarchical grid with cell merge

+ + + + + + + + + + + + + + + + + + + + + + + + + +

Tree grid with cell merge

+ + + + + + + + diff --git a/src/app/grid-cellMerging/grid-cellMerging.component.scss b/src/app/grid-cellMerging/grid-cellMerging.component.scss new file mode 100644 index 00000000000..9f4f5d20867 --- /dev/null +++ b/src/app/grid-cellMerging/grid-cellMerging.component.scss @@ -0,0 +1,22 @@ +.sample-actions { + display: flex; + flex-wrap: wrap; + margin: 1rem 0; + gap: 0.5rem; +} + +.density-chooser { + margin-bottom: 1rem; + + igx-buttongroup { + display: block; + width: 500px; + } +} + +.grid-size { + --ig-size: var(--ig-size-small); +} +.searchInput{ + width: 800px; +} diff --git a/src/app/grid-cellMerging/grid-cellMerging.component.ts b/src/app/grid-cellMerging/grid-cellMerging.component.ts new file mode 100644 index 00000000000..3374c5e606f --- /dev/null +++ b/src/app/grid-cellMerging/grid-cellMerging.component.ts @@ -0,0 +1,92 @@ +import { Component, HostBinding, ViewChild } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { + DefaultTreeGridMergeStrategy, + IgxActionStripComponent, + IgxButtonDirective, + IgxCellTemplateDirective, + IgxColumnComponent, + IgxGridComponent, + IgxGridPinningActionsComponent, + IgxGridToolbarActionsComponent, + IgxGridToolbarComponent, + IgxGridToolbarExporterComponent, + IgxGridToolbarHidingComponent, + IgxGridToolbarPinningComponent, + IgxHierarchicalGridComponent, + IgxIconComponent, + IgxInputDirective, + IgxInputGroupComponent, + IgxPaginatorComponent, + IgxPrefixDirective, + IgxRowIslandComponent, + IgxSuffixDirective, + IgxTreeGridComponent +} from 'igniteui-angular'; +import { HIERARCHICAL_DATA } from '../shared/hierarchicalData'; + +import { data, dataWithoutPK } from '../shared/data'; +import { HIERARCHICAL_SAMPLE_DATA } from '../shared/sample-data'; +import { ByLevelTreeGridMergeStrategy } from 'igniteui-angular'; +import { INVOICE_DATA } from '../shared/invoiceData'; + +@Component({ + selector: 'app-grid-cellMerging', + templateUrl: 'grid-cellMerging.component.html', + styleUrl: 'grid-cellMerging.component.scss', + imports: [ + FormsModule, + IgxColumnComponent, + IgxGridComponent, + IgxPaginatorComponent, + IgxActionStripComponent, + IgxGridPinningActionsComponent, + IgxGridToolbarComponent, + IgxGridToolbarActionsComponent, + IgxGridToolbarPinningComponent, + IgxGridToolbarHidingComponent, + IgxHierarchicalGridComponent, + IgxRowIslandComponent, + IgxTreeGridComponent, + IgxInputGroupComponent, + IgxPrefixDirective, + IgxSuffixDirective, + IgxIconComponent, + IgxInputDirective, + IgxCellTemplateDirective + ] +}) +export class GridCellMergingComponent { + public hierarchicalData = HIERARCHICAL_DATA.concat(HIERARCHICAL_DATA).concat(HIERARCHICAL_DATA); + public treeData = HIERARCHICAL_SAMPLE_DATA; + public treeGridMergeStrategy = new ByLevelTreeGridMergeStrategy(); + public alignBottom = { alignItems: "flex-end", paddingBottom: "12px"}; + public alignTop= { alignItems: "flex-start", paddingTop: "12px" }; + public searchText: string =''; + @ViewChild('grid1', { static: true }) public grid: IgxGridComponent; + public data = INVOICE_DATA; + + public toggleStrategy() { + if (this.treeGridMergeStrategy instanceof ByLevelTreeGridMergeStrategy) { + this.treeGridMergeStrategy = new DefaultTreeGridMergeStrategy(); + } else { + this.treeGridMergeStrategy = new ByLevelTreeGridMergeStrategy(); + } + } + + public searchKeyDown(ev) { + if (ev.key === 'Enter' || ev.key === 'ArrowDown' || ev.key === 'ArrowRight') { + ev.preventDefault(); + this.grid.findNext(this.searchText, true, false); + } else if (ev.key === 'ArrowUp' || ev.key === 'ArrowLeft') { + ev.preventDefault(); + this.grid.findPrev(this.searchText, true, false); + } + } + + public clearSearch() { + this.searchText = ''; + this.grid.clearSearch(); + } +} + diff --git a/src/app/shared/invoiceData.ts b/src/app/shared/invoiceData.ts new file mode 100644 index 00000000000..051444c0009 --- /dev/null +++ b/src/app/shared/invoiceData.ts @@ -0,0 +1,8081 @@ +/* eslint-disable */ + +export interface Invoice { + ID: number; + ShipAddress: string; + ShipCity: string; + ShipCountry: string; + ShipName: string; + ShipRegion: string; + ShipPostalCode: string; + CustomerID: string; + CustomerName: string; + Address: string; + City: string; + Region: string; + PostalCode: string; + Country: string; + Salesperson: string; + OrderID: number; + OrderDate: Date; + ShipperName: string; + ProductID: number; + ProductName: string; + UnitPrice: number; + Quantity: number; + Discontinued: boolean; + ExtendedPrice: number; + Freight: number; +} + +export const INVOICE_DATA = [{ + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipCountry: "Germany", + ShipName: "Alfred's Futterkiste", + ShipRegion: null, + ShipPostalCode: "12209", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10692, + OrderDate: new Date("11/23/2016"), + ShipperName: "United Package", + ProductID: 63, + ProductName: "Vegie-spread", + UnitPrice: 43.9000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 878.0000, + Freight: 61.0200 +}, { + ShipName: "Alfred's Futterkiste", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10702, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 3, + ProductName: "Aniseed Syrup", + UnitPrice: 10.0000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 60.0000, + Freight: 23.9400 +}, { + ShipName: "Alfred's Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10702, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 76, + ProductName: "Lakkalik\u00f6\u00f6ri", + UnitPrice: 18.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 270.0000, + Freight: 23.9400 +}, { + ShipName: "Alfred's Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 10835, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 59, + ProductName: "Raclette Courdavault", + UnitPrice: 55.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 825.0000, + Freight: 69.5300 +}, { + ShipName: "Alfred's Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 10952, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 28, + ProductName: "R\u00f6ssle Sauerkraut", + UnitPrice: 45.6000, + Quantity: 2, + Discontinued: true, + ExtendedPrice: 91.2000, + Freight: 40.4200 +}, { + ShipName: "Alfred's Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Janet Leverling", + OrderID: 11011, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 71, + ProductName: "Flotemysost", + UnitPrice: 21.5000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 430.0000, + Freight: 1.2100 +}, { + ShipName: "Alfred's Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 10952, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 6, + ProductName: "Grandma's Boysenberry Spread", + UnitPrice: 25.0000, + Quantity: 16, + Discontinued: true, + ExtendedPrice: 380.0000, + Freight: 40.4200 +}, { + ShipName: "Alfred's Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Janet Leverling", + OrderID: 11011, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 58, + ProductName: "Escargots de Bourgogne", + UnitPrice: 13.2500, + Quantity: 40, + Discontinued: true, + ExtendedPrice: 503.5000, + Freight: 1.2100 +}, { + ShipName: "Alfred's Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 10835, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 77, + ProductName: "Original Frankfurter gr\u00fcne So\u00dfe", + UnitPrice: 13.0000, + Quantity: 2, + Discontinued: true, + ExtendedPrice: 20.8000, + Freight: 69.5300 +}, { + ShipName: "Alfreds Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10643, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 28, + ProductName: "R\u00f6ssle Sauerkraut", + UnitPrice: 45.6000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 513.0000, + Freight: 29.4600 +}, { + ShipName: "Alfreds Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10643, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 39, + ProductName: "Chartreuse verte", + UnitPrice: 18.0000, + Quantity: 21, + Discontinued: true, + ExtendedPrice: 283.5000, + Freight: 29.4600 +}, { + ShipName: "Alfreds Futterkiste", + ShipAddress: "Obere Str. 57", + ShipCity: "Berlin", + ShipRegion: null, + ShipPostalCode: "12209", + ShipCountry: "Germany", + CustomerID: "ALFKI", + CustomerName: "Alfreds Futterkiste", + Address: "Obere Str. 57", + City: "Berlin", + Region: null, + PostalCode: "12209", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10643, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 46, + ProductName: "Spegesild", + UnitPrice: 12.0000, + Quantity: 2, + Discontinued: true, + ExtendedPrice: 18.0000, + Freight: 29.4600 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Robert King", + OrderID: 10308, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 69, + ProductName: "Gudbrandsdalsost", + UnitPrice: 28.8000, + Quantity: 1, + Discontinued: false, + ExtendedPrice: 28.8000, + Freight: 1.6100 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Robert King", + OrderID: 10308, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 70, + ProductName: "Outback Lager", + UnitPrice: 12.0000, + Quantity: 5, + Discontinued: false, + ExtendedPrice: 60.0000, + Freight: 1.6100 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10625, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 14, + ProductName: "Tofu", + UnitPrice: 23.2500, + Quantity: 3, + Discontinued: false, + ExtendedPrice: 69.7500, + Freight: 43.9000 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10625, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 42, + ProductName: "Singaporean Hokkien Fried Mee", + UnitPrice: 14.0000, + Quantity: 5, + Discontinued: false, + ExtendedPrice: 70.0000, + Freight: 43.9000 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10625, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 34.0000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 340.0000, + Freight: 43.9000 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10759, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 32, + ProductName: "Mascarpone Fabioli", + UnitPrice: 32.0000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 320.0000, + Freight: 11.9900 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10926, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 21.0000, + Quantity: 2, + Discontinued: false, + ExtendedPrice: 42.0000, + Freight: 39.9200 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10926, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 6.0000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 60.0000, + Freight: 39.9200 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10926, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 19, + ProductName: "Teatime Chocolate Biscuits", + UnitPrice: 9.2000, + Quantity: 7, + Discontinued: false, + ExtendedPrice: 64.4000, + Freight: 39.9200 +}, { + ShipName: "Ana Trujillo Emparedados y helados", + ShipAddress: "Avda. de la Constituci\u00f3n 2222", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05021", + ShipCountry: "Mexico", + CustomerID: "ANATR", + CustomerName: "Ana Trujillo Emparedados y helados", + Address: "Avda. de la Constituci\u00f3n 2222", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05021", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10926, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 72, + ProductName: "Mozzarella di Giovanni", + UnitPrice: 34.8000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 348.0000, + Freight: 39.9200 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10365, + OrderDate: new Date("11/23/2016"), + ShipperName: "United Package", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 16.8000, + Quantity: 24, + Discontinued: false, + ExtendedPrice: 403.2000, + Freight: 22.0000 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Robert King", + OrderID: 10573, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 17, + ProductName: "Alice Mutton", + UnitPrice: 39.0000, + Quantity: 18, + Discontinued: false, + ExtendedPrice: 702.0000, + Freight: 84.8400 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Robert King", + OrderID: 10573, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 34, + ProductName: "Sasquatch Ale", + UnitPrice: 14.0000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 560.0000, + Freight: 84.8400 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Robert King", + OrderID: 10573, + OrderDate: new Date("11/23/2016"), + ShipperName: "Federal Shipping", + ProductID: 53, + ProductName: "Perth Pasties", + UnitPrice: 32.8000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 820.0000, + Freight: 84.8400 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10682, + OrderDate: new Date("11/23/2016"), + ShipperName: "United Package", + ProductID: 33, + ProductName: "Geitost", + UnitPrice: 2.5000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 75.0000, + Freight: 36.1300 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10682, + OrderDate: new Date("11/23/2016"), + ShipperName: "United Package", + ProductID: 66, + ProductName: "Louisiana Hot Spiced Okra", + UnitPrice: 17.0000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 68.0000, + Freight: 36.1300 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10682, + OrderDate: new Date("11/23/2016"), + ShipperName: "United Package", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 7.7500, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 232.5000, + Freight: 36.1300 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10856, + OrderDate: new Date("11/23/2016"), + ShipperName: "United Package", + ProductID: 2, + ProductName: "Chang", + UnitPrice: 19.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 380.0000, + Freight: 58.4300 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Janet Leverling", + OrderID: 10856, + OrderDate: new Date("11/23/2016"), + ShipperName: "United Package", + ProductID: 42, + ProductName: "Singaporean Hokkien Fried Mee", + UnitPrice: 14.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 280.0000, + Freight: 58.4300 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10535, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 21.0000, + Quantity: 50, + Discontinued: true, + ExtendedPrice: 945.0000, + Freight: 15.6400 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10535, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 18.4000, + Quantity: 10, + Discontinued: true, + ExtendedPrice: 165.6000, + Freight: 15.6400 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10535, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 57, + ProductName: "Ravioli Angelo", + UnitPrice: 19.5000, + Quantity: 5, + Discontinued: true, + ExtendedPrice: 87.7500, + Freight: 15.6400 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10535, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 59, + ProductName: "Raclette Courdavault", + UnitPrice: 55.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 742.5000, + Freight: 15.6400 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Robert King", + OrderID: 10507, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 43, + ProductName: "Ipoh Coffee", + UnitPrice: 46.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 586.5000, + Freight: 47.4500 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Robert King", + OrderID: 10507, + OrderDate: new Date("11/23/2016"), + ShipperName: "Speedy Express", + ProductID: 48, + ProductName: "Chocolade", + UnitPrice: 12.7500, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 162.5600, + Freight: 47.4500 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Nancy Davolio", + OrderID: 10677, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 26, + ProductName: "Gumb\u00e4r Gummib\u00e4rchen", + UnitPrice: 31.2300, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 796.3700, + Freight: 4.0300 +}, { + ShipName: "Antonio Moreno Taquer\u00eda", + ShipAddress: "Mataderos 2312", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05023", + ShipCountry: "Mexico", + CustomerID: "ANTON", + CustomerName: "Antonio Moreno Taquer\u00eda", + Address: "Mataderos 2312", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05023", + Country: "Mexico", + Salesperson: "Nancy Davolio", + OrderID: 10677, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 33, + ProductName: "Geitost", + UnitPrice: 2.5000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 17.0000, + Freight: 4.0300 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Michael Suyama", + OrderID: 10355, + OrderDate: new Date("10/4/2017"), + ShipperName: "Speedy Express", + ProductID: 24, + ProductName: "Guaran\u00e1 Fant\u00e1stica", + UnitPrice: 3.6000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 90.0000, + Freight: 41.9500 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Michael Suyama", + OrderID: 10355, + OrderDate: new Date("10/4/2017"), + ShipperName: "Speedy Express", + ProductID: 57, + ProductName: "Ravioli Angelo", + UnitPrice: 15.6000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 390.0000, + Freight: 41.9500 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10383, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 4.8000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 96.0000, + Freight: 34.2400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10383, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 50, + ProductName: "Valkoinen suklaa", + UnitPrice: 13.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 195.0000, + Freight: 34.2400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10383, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 30.4000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 608.0000, + Freight: 34.2400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10558, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 47, + ProductName: "Zaanse koeken", + UnitPrice: 9.5000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 237.5000, + Freight: 72.9700 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10558, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 51, + ProductName: "Manjimup Dried Apples", + UnitPrice: 53.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 1060.0000, + Freight: 72.9700 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10558, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 52, + ProductName: "Filo Mix", + UnitPrice: 7.0000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 210.0000, + Freight: 72.9700 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10558, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 53, + ProductName: "Perth Pasties", + UnitPrice: 32.8000, + Quantity: 18, + Discontinued: false, + ExtendedPrice: 590.4000, + Freight: 72.9700 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10558, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 73, + ProductName: "R\u00f6d Kaviar", + UnitPrice: 15.0000, + Quantity: 3, + Discontinued: false, + ExtendedPrice: 45.0000, + Freight: 72.9700 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10707, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 55, + ProductName: "P\u00e2t\u00e9 chinois", + UnitPrice: 24.0000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 504.0000, + Freight: 21.7400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10707, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 57, + ProductName: "Ravioli Angelo", + UnitPrice: 19.5000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 780.0000, + Freight: 21.7400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10768, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 22, + ProductName: "Gustaf's Kn\u00e4ckebr\u00f6d", + UnitPrice: 21.0000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 84.0000, + Freight: 146.3200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10768, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 31, + ProductName: "Gorgonzola Telino", + UnitPrice: 12.5000, + Quantity: 50, + Discontinued: true, + ExtendedPrice: 625.0000, + Freight: 146.3200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10768, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 34.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 510.0000, + Freight: 146.3200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10768, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 71, + ProductName: "Flotemysost", + UnitPrice: 21.5000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 258.0000, + Freight: 146.3200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10793, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 41, + ProductName: "Jack's New England Clam Chowder", + UnitPrice: 9.6500, + Quantity: 14, + Discontinued: false, + ExtendedPrice: 135.1000, + Freight: 4.5200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10793, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 52, + ProductName: "Filo Mix", + UnitPrice: 7.0000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 56.0000, + Freight: 4.5200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10864, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 35, + ProductName: "Steeleye Stout", + UnitPrice: 18.0000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 72.0000, + Freight: 3.0400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10864, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 67, + ProductName: "Laughing Lumberjack Lager", + UnitPrice: 14.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 210.0000, + Freight: 3.0400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10920, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 50, + ProductName: "Valkoinen suklaa", + UnitPrice: 16.2500, + Quantity: 24, + Discontinued: false, + ExtendedPrice: 390.0000, + Freight: 29.6100 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Anne Dodsworth", + OrderID: 11016, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 31, + ProductName: "Gorgonzola Telino", + UnitPrice: 12.5000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 187.5000, + Freight: 33.8000 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Anne Dodsworth", + OrderID: 11016, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 36, + ProductName: "Inlagd Sill", + UnitPrice: 19.0000, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 304.0000, + Freight: 33.8000 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10743, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 46, + ProductName: "Spegesild", + UnitPrice: 12.0000, + Quantity: 28, + Discontinued: false, + ExtendedPrice: 319.2000, + Freight: 23.7200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Anne Dodsworth", + OrderID: 10953, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 20, + ProductName: "Sir Rodney's Marmalade", + UnitPrice: 81.0000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 3847.5000, + Freight: 23.7200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Anne Dodsworth", + OrderID: 10953, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 31, + ProductName: "Gorgonzola Telino", + UnitPrice: 12.5000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 593.7500, + Freight: 23.7200 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10453, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 48, + ProductName: "Chocolade", + UnitPrice: 10.2000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 137.7000, + Freight: 25.3600 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10453, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 70, + ProductName: "Outback Lager", + UnitPrice: 12.0000, + Quantity: 25, + Discontinued: true, + ExtendedPrice: 270.0000, + Freight: 25.3600 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10707, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 70, + ProductName: "Outback Lager", + UnitPrice: 15.0000, + Quantity: 28, + Discontinued: false, + ExtendedPrice: 357.0000, + Freight: 21.7400 +}, { + ShipName: "Around the Horn", + ShipAddress: "Brook Farm Stratford St. Mary", + ShipCity: "Colchester", + ShipRegion: "Essex", + ShipPostalCode: "CO7 6JX", + ShipCountry: "UK", + CustomerID: "AROUT", + CustomerName: "Around the Horn", + Address: "120 Hanover Sq.", + City: "London", + Region: null, + PostalCode: "WA1 1DP", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10741, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 2, + ProductName: "Chang", + UnitPrice: 19.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 228.0000, + Freight: 10.9600 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Laura Callahan", + OrderID: 10278, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 44, + ProductName: "Gula Malacca", + UnitPrice: 15.5000, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 248.0000, + Freight: 92.6900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Laura Callahan", + OrderID: 10278, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 59, + ProductName: "Raclette Courdavault", + UnitPrice: 44.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 660.0000, + Freight: 92.6900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Laura Callahan", + OrderID: 10278, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 63, + ProductName: "Vegie-spread", + UnitPrice: 35.1000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 280.8000, + Freight: 92.6900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Laura Callahan", + OrderID: 10278, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 73, + ProductName: "R\u00f6d Kaviar", + UnitPrice: 12.0000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 300.0000, + Freight: 92.6900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Andrew Fuller", + OrderID: 10280, + OrderDate: new Date("10/4/2017"), + ShipperName: "Speedy Express", + ProductID: 24, + ProductName: "Guaran\u00e1 Fant\u00e1stica", + UnitPrice: 3.6000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 43.2000, + Freight: 8.9800 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Andrew Fuller", + OrderID: 10280, + OrderDate: new Date("10/4/2017"), + ShipperName: "Speedy Express", + ProductID: 55, + ProductName: "P\u00e2t\u00e9 chinois", + UnitPrice: 19.2000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 384.0000, + Freight: 8.9800 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Andrew Fuller", + OrderID: 10280, + OrderDate: new Date("10/4/2017"), + ShipperName: "Speedy Express", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 6.2000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 186.0000, + Freight: 8.9800 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10384, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 20, + ProductName: "Sir Rodney's Marmalade", + UnitPrice: 64.8000, + Quantity: 28, + Discontinued: false, + ExtendedPrice: 1814.4000, + Freight: 168.6400 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10384, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 27.2000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 408.0000, + Freight: 168.6400 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10444, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 17, + ProductName: "Alice Mutton", + UnitPrice: 31.2000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 312.0000, + Freight: 3.5000 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10444, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 26, + ProductName: "Gumb\u00e4r Gummib\u00e4rchen", + UnitPrice: 24.9000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 373.5000, + Freight: 3.5000 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10444, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 35, + ProductName: "Steeleye Stout", + UnitPrice: 14.4000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 115.2000, + Freight: 3.5000 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10444, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 41, + ProductName: "Jack's New England Clam Chowder", + UnitPrice: 7.7000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 231.0000, + Freight: 3.5000 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10524, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 54, + ProductName: "Tourti\u00e8re", + UnitPrice: 7.4500, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 111.7500, + Freight: 244.7900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10572, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 18.4000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 920.0000, + Freight: 116.4300 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10626, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 53, + ProductName: "Perth Pasties", + UnitPrice: 32.8000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 393.6000, + Freight: 138.6900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10626, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 34.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 680.0000, + Freight: 138.6900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10626, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 71, + ProductName: "Flotemysost", + UnitPrice: 21.5000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 430.0000, + Freight: 138.6900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Anne Dodsworth", + OrderID: 10672, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 71, + ProductName: "Flotemysost", + UnitPrice: 21.5000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 258.0000, + Freight: 95.7500 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10733, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 14, + ProductName: "Tofu", + UnitPrice: 23.2500, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 372.0000, + Freight: 110.1100 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10733, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 28, + ProductName: "R\u00f6ssle Sauerkraut", + UnitPrice: 45.6000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 912.0000, + Freight: 110.1100 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10733, + OrderDate: new Date("10/4/2017"), + ShipperName: "Federal Shipping", + ProductID: 52, + ProductName: "Filo Mix", + UnitPrice: 7.0000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 175.0000, + Freight: 110.1100 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10778, + OrderDate: new Date("10/4/2017"), + ShipperName: "Speedy Express", + ProductID: 41, + ProductName: "Jack's New England Clam Chowder", + UnitPrice: 9.6500, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 96.5000, + Freight: 6.7900 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Anne Dodsworth", + OrderID: 10837, + OrderDate: new Date("10/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 6.0000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 36.0000, + Freight: 13.3200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Anne Dodsworth", + OrderID: 10837, + OrderDate: new Date("10/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 18.4000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 460.0000, + Freight: 13.3200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Laura Callahan", + OrderID: 10857, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 3, + ProductName: "Aniseed Syrup", + UnitPrice: 10.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 300.0000, + Freight: 188.8500 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Margaret Peacock", + OrderID: 10875, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 19, + ProductName: "Teatime Chocolate Biscuits", + UnitPrice: 9.2000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 230.0000, + Freight: 32.3700 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Margaret Peacock", + OrderID: 10875, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 49, + ProductName: "Maxilaku", + UnitPrice: 20.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 300.0000, + Freight: 32.3700 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10924, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 7.7500, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 46.5000, + Freight: 151.5200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10572, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 16, + ProductName: "Pavlova", + UnitPrice: 17.4500, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 188.4600, + Freight: 116.4300 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10572, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 32, + ProductName: "Mascarpone Fabioli", + UnitPrice: 32.0000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 288.0000, + Freight: 116.4300 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10572, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 7.7500, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 104.6200, + Freight: 116.4300 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Steven Buchanan", + OrderID: 10654, + OrderDate: new Date("10/4/2018"), + ShipperName: "Speedy Express", + ProductID: 4, + ProductName: "Chef Anton's Cajun Seasoning", + UnitPrice: 22.0000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 237.6000, + Freight: 55.2600 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Steven Buchanan", + OrderID: 10654, + OrderDate: new Date("10/4/2018"), + ShipperName: "Speedy Express", + ProductID: 39, + ProductName: "Chartreuse verte", + UnitPrice: 18.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 324.0000, + Freight: 55.2600 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Steven Buchanan", + OrderID: 10654, + OrderDate: new Date("10/4/2018"), + ShipperName: "Speedy Express", + ProductID: 54, + ProductName: "Tourti\u00e8re", + UnitPrice: 7.4500, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 40.2300, + Freight: 55.2600 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Anne Dodsworth", + OrderID: 10672, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 38, + ProductName: "C\u00f4te de Blaye", + UnitPrice: 263.5000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 3557.2500, + Freight: 95.7500 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Margaret Peacock", + OrderID: 10875, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 47, + ProductName: "Zaanse koeken", + UnitPrice: 9.5000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 179.5500, + Freight: 32.3700 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10924, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 10, + ProductName: "Ikura", + UnitPrice: 31.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 558.0000, + Freight: 151.5200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Janet Leverling", + OrderID: 10924, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 28, + ProductName: "R\u00f6ssle Sauerkraut", + UnitPrice: 45.6000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 1231.2000, + Freight: 151.5200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Nancy Davolio", + OrderID: 10689, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 1, + ProductName: "Chai", + UnitPrice: 18.0000, + Quantity: 35, + Discontinued: true, + ExtendedPrice: 472.5000, + Freight: 13.4200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Anne Dodsworth", + OrderID: 10837, + OrderDate: new Date("10/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 47, + ProductName: "Zaanse koeken", + UnitPrice: 9.5000, + Quantity: 40, + Discontinued: true, + ExtendedPrice: 285.0000, + Freight: 13.3200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Anne Dodsworth", + OrderID: 10837, + OrderDate: new Date("10/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 76, + ProductName: "Lakkalik\u00f6\u00f6ri", + UnitPrice: 18.0000, + Quantity: 21, + Discontinued: true, + ExtendedPrice: 283.5000, + Freight: 13.3200 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Laura Callahan", + OrderID: 10857, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 26, + ProductName: "Gumb\u00e4r Gummib\u00e4rchen", + UnitPrice: 31.2300, + Quantity: 35, + Discontinued: true, + ExtendedPrice: 819.7900, + Freight: 188.8500 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Laura Callahan", + OrderID: 10857, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 29, + ProductName: "Th\u00fcringer Rostbratwurst", + UnitPrice: 123.7900, + Quantity: 10, + Discontinued: true, + ExtendedPrice: 928.4300, + Freight: 188.8500 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Steven Buchanan", + OrderID: 10866, + OrderDate: new Date("10/4/2018"), + ShipperName: "Speedy Express", + ProductID: 2, + ProductName: "Chang", + UnitPrice: 19.0000, + Quantity: 21, + Discontinued: true, + ExtendedPrice: 299.2500, + Freight: 109.1100 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Steven Buchanan", + OrderID: 10866, + OrderDate: new Date("10/4/2018"), + ShipperName: "Speedy Express", + ProductID: 24, + ProductName: "Guaran\u00e1 Fant\u00e1stica", + UnitPrice: 4.5000, + Quantity: 6, + Discontinued: true, + ExtendedPrice: 20.2500, + Freight: 109.1100 +}, { + ShipName: "Berglunds snabbk\u00f6p", + ShipAddress: "Berguvsv\u00e4gen 8", + ShipCity: "Lule\u00e5", + ShipRegion: null, + ShipPostalCode: "S-958 22", + ShipCountry: "Sweden", + CustomerID: "BERGS", + CustomerName: "Berglunds snabbk\u00f6p", + Address: "Berguvsv\u00e4gen 8", + City: "Lule\u00e5", + Region: null, + PostalCode: "S-958 22", + Country: "Sweden", + Salesperson: "Steven Buchanan", + OrderID: 10866, + OrderDate: new Date("10/4/2018"), + ShipperName: "Speedy Express", + ProductID: 30, + ProductName: "Nord-Ost Matjeshering", + UnitPrice: 25.8900, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 776.7000, + Freight: 109.1100 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Anne Dodsworth", + OrderID: 10501, + OrderDate: new Date("10/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 54, + ProductName: "Tourti\u00e8re", + UnitPrice: 7.4500, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 149.0000, + Freight: 8.8500 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10509, + OrderDate: new Date("10/4/2018"), + ShipperName: "Speedy Express", + ProductID: 28, + ProductName: "R\u00f6ssle Sauerkraut", + UnitPrice: 45.6000, + Quantity: 3, + Discontinued: false, + ExtendedPrice: 136.8000, + Freight: 0.1500 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Janet Leverling", + OrderID: 10582, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 57, + ProductName: "Ravioli Angelo", + UnitPrice: 19.5000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 78.0000, + Freight: 27.7100 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Janet Leverling", + OrderID: 10582, + OrderDate: new Date("10/4/2018"), + ShipperName: "United Package", + ProductID: 76, + ProductName: "Lakkalik\u00f6\u00f6ri", + UnitPrice: 18.0000, + Quantity: 14, + Discontinued: false, + ExtendedPrice: 252.0000, + Freight: 27.7100 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10614, + OrderDate: new Date("10/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 21.0000, + Quantity: 14, + Discontinued: false, + ExtendedPrice: 294.0000, + Freight: 1.9300 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10614, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 10.0000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 80.0000, + Freight: 1.9300 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10614, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 39, + ProductName: "Chartreuse verte", + UnitPrice: 18.0000, + Quantity: 5, + Discontinued: false, + ExtendedPrice: 90.0000, + Freight: 1.9300 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Anne Dodsworth", + OrderID: 10853, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 18, + ProductName: "Carnarvon Tigers", + UnitPrice: 62.5000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 625.0000, + Freight: 53.8300 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10956, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 10.0000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 120.0000, + Freight: 44.6500 +}, { + ShipName: "Blauer See Delikatessen", + ShipAddress: "Forsterstr. 57", + ShipCity: "Mannheim", + ShipRegion: null, + ShipPostalCode: "68306", + ShipCountry: "Germany", + CustomerID: "BLAUS", + CustomerName: "Blauer See Delikatessen", + Address: "Forsterstr. 57", + City: "Mannheim", + Region: null, + PostalCode: "68306", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10956, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 47, + ProductName: "Zaanse koeken", + UnitPrice: 9.5000, + Quantity: 14, + Discontinued: false, + ExtendedPrice: 133.0000, + Freight: 44.6500 +}, { + ShipName: "B\u00f3lido Comidas preparadas", + ShipAddress: "C/ Araquil, 67", + ShipCity: "Madrid", + ShipRegion: null, + ShipPostalCode: "28023", + ShipCountry: "Spain", + CustomerID: "BOLID", + CustomerName: "B\u00f3lido Comidas preparadas", + Address: "C/ Araquil, 67", + City: "Madrid", + Region: null, + PostalCode: "28023", + Country: "Spain", + Salesperson: "Margaret Peacock", + OrderID: 10326, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 6.2000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 310.0000, + Freight: 77.9200 +}, { + ShipName: "B\u00f3lido Comidas preparadas", + ShipAddress: "C/ Araquil, 67", + ShipCity: "Madrid", + ShipRegion: null, + ShipPostalCode: "28023", + ShipCountry: "Spain", + CustomerID: "BOLID", + CustomerName: "B\u00f3lido Comidas preparadas", + Address: "C/ Araquil, 67", + City: "Madrid", + Region: null, + PostalCode: "28023", + Country: "Spain", + Salesperson: "Anne Dodsworth", + OrderID: 10970, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 52, + ProductName: "Filo Mix", + UnitPrice: 7.0000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 224.0000, + Freight: 16.1600 +}, { + ShipName: "B\u00f3lido Comidas preparadas", + ShipAddress: "C/ Araquil, 67", + ShipCity: "Madrid", + ShipRegion: null, + ShipPostalCode: "28023", + ShipCountry: "Spain", + CustomerID: "BOLID", + CustomerName: "B\u00f3lido Comidas preparadas", + Address: "C/ Araquil, 67", + City: "Madrid", + Region: null, + PostalCode: "28023", + Country: "Spain", + Salesperson: "Margaret Peacock", + OrderID: 10801, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 17, + ProductName: "Alice Mutton", + UnitPrice: 39.0000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 1170.0000, + Freight: 97.0900 +}, { + ShipName: "B\u00f3lido Comidas preparadas", + ShipAddress: "C/ Araquil, 67", + ShipCity: "Madrid", + ShipRegion: null, + ShipPostalCode: "28023", + ShipCountry: "Spain", + CustomerID: "BOLID", + CustomerName: "B\u00f3lido Comidas preparadas", + Address: "C/ Araquil, 67", + City: "Madrid", + Region: null, + PostalCode: "28023", + Country: "Spain", + Salesperson: "Margaret Peacock", + OrderID: 10801, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 29, + ProductName: "Th\u00fcringer Rostbratwurst", + UnitPrice: 123.7900, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 1856.8500, + Freight: 97.0900 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Anne Dodsworth", + OrderID: 10331, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 54, + ProductName: "Tourti\u00e8re", + UnitPrice: 5.9000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 88.5000, + Freight: 10.1900 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Janet Leverling", + OrderID: 10362, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 25, + ProductName: "NuNuCa Nu\u00df-Nougat-Creme", + UnitPrice: 11.2000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 560.0000, + Freight: 96.0400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Janet Leverling", + OrderID: 10362, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 51, + ProductName: "Manjimup Dried Apples", + UnitPrice: 42.4000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 848.0000, + Freight: 96.0400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Janet Leverling", + OrderID: 10362, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 54, + ProductName: "Tourti\u00e8re", + UnitPrice: 5.9000, + Quantity: 24, + Discontinued: false, + ExtendedPrice: 141.6000, + Freight: 96.0400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10470, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 18, + ProductName: "Carnarvon Tigers", + UnitPrice: 50.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 1500.0000, + Freight: 64.5600 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10470, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 23, + ProductName: "Tunnbr\u00f6d", + UnitPrice: 7.2000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 108.0000, + Freight: 64.5600 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10470, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 64, + ProductName: "Wimmers gute Semmelkn\u00f6del", + UnitPrice: 26.6000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 212.8000, + Freight: 64.5600 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10525, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 36, + ProductName: "Inlagd Sill", + UnitPrice: 19.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 570.0000, + Freight: 11.0600 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Janet Leverling", + OrderID: 10715, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 10, + ProductName: "Ikura", + UnitPrice: 31.0000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 651.0000, + Freight: 63.2000 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Janet Leverling", + OrderID: 10715, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 71, + ProductName: "Flotemysost", + UnitPrice: 21.5000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 645.0000, + Freight: 63.2000 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Janet Leverling", + OrderID: 10732, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 76, + ProductName: "Lakkalik\u00f6\u00f6ri", + UnitPrice: 18.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 360.0000, + Freight: 16.9700 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10827, + OrderDate: new Date("10/4/2017"), + ShipperName: "United Package", + ProductID: 10, + ProductName: "Ikura", + UnitPrice: 31.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 465.0000, + Freight: 63.5400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10827, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 39, + ProductName: "Chartreuse verte", + UnitPrice: 18.0000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 378.0000, + Freight: 63.5400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Robert King", + OrderID: 10876, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 46, + ProductName: "Spegesild", + UnitPrice: 12.0000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 252.0000, + Freight: 60.4200 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Robert King", + OrderID: 10876, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 64, + ProductName: "Wimmers gute Semmelkn\u00f6del", + UnitPrice: 33.2500, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 665.0000, + Freight: 60.4200 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Laura Callahan", + OrderID: 10932, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 72, + ProductName: "Mozzarella di Giovanni", + UnitPrice: 34.8000, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 556.8000, + Freight: 134.6400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Laura Callahan", + OrderID: 10940, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 6.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 120.0000, + Freight: 19.7700 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10340, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 18, + ProductName: "Carnarvon Tigers", + UnitPrice: 50.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 950.0000, + Freight: 166.3100 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10340, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 41, + ProductName: "Jack's New England Clam Chowder", + UnitPrice: 7.7000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 87.7800, + Freight: 166.3100 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10340, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 43, + ProductName: "Ipoh Coffee", + UnitPrice: 36.8000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 1398.4000, + Freight: 166.3100 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Andrew Fuller", + OrderID: 10663, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 18.4000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 524.4000, + Freight: 113.1500 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Andrew Fuller", + OrderID: 10663, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 42, + ProductName: "Singaporean Hokkien Fried Mee", + UnitPrice: 14.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 399.0000, + Freight: 113.1500 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Andrew Fuller", + OrderID: 10663, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 51, + ProductName: "Manjimup Dried Apples", + UnitPrice: 53.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 1007.0000, + Freight: 113.1500 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Steven Buchanan", + OrderID: 10730, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 16, + ProductName: "Pavlova", + UnitPrice: 17.4500, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 248.6600, + Freight: 20.1200 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Steven Buchanan", + OrderID: 10730, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 31, + ProductName: "Gorgonzola Telino", + UnitPrice: 12.5000, + Quantity: 3, + Discontinued: false, + ExtendedPrice: 35.6200, + Freight: 20.1200 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Steven Buchanan", + OrderID: 10730, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 65, + ProductName: "Louisiana Fiery Hot Pepper Sauce", + UnitPrice: 21.0500, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 199.9700, + Freight: 20.1200 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Anne Dodsworth", + OrderID: 10871, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 6, + ProductName: "Grandma's Boysenberry Spread", + UnitPrice: 25.0000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 1187.5000, + Freight: 112.2700 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Anne Dodsworth", + OrderID: 10871, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 16, + ProductName: "Pavlova", + UnitPrice: 17.4500, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 198.9300, + Freight: 112.2700 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Anne Dodsworth", + OrderID: 10871, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 17, + ProductName: "Alice Mutton", + UnitPrice: 39.0000, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 592.8000, + Freight: 112.2700 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10525, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 18.4000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 248.4000, + Freight: 11.0600 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Laura Callahan", + OrderID: 10932, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 16, + ProductName: "Pavlova", + UnitPrice: 17.4500, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 471.1500, + Freight: 134.6400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Laura Callahan", + OrderID: 10932, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 62, + ProductName: "Tarte au sucre", + UnitPrice: 49.3000, + Quantity: 14, + Discontinued: true, + ExtendedPrice: 621.1800, + Freight: 134.6400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Laura Callahan", + OrderID: 10932, + OrderDate: new Date("10/4/2016"), + ShipperName: "Speedy Express", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 7.7500, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 139.5000, + Freight: 134.6400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10511, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 4, + ProductName: "Chef Anton's Cajun Seasoning", + UnitPrice: 22.0000, + Quantity: 50, + Discontinued: true, + ExtendedPrice: 935.0000, + Freight: 350.6400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10511, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 7, + ProductName: "Uncle Bob's Organic Dried Pears", + UnitPrice: 30.0000, + Quantity: 50, + Discontinued: true, + ExtendedPrice: 1275.0000, + Freight: 350.6400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10511, + OrderDate: new Date("10/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 8, + ProductName: "Northwoods Cranberry Sauce", + UnitPrice: 40.0000, + Quantity: 10, + Discontinued: true, + ExtendedPrice: 340.0000, + Freight: 350.6400 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10755, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 47, + ProductName: "Zaanse koeken", + UnitPrice: 9.5000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 213.7500, + Freight: 16.7100 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10755, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 38.0000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 855.0000, + Freight: 16.7100 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10755, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 57, + ProductName: "Ravioli Angelo", + UnitPrice: 19.5000, + Quantity: 14, + Discontinued: true, + ExtendedPrice: 204.7500, + Freight: 16.7100 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 10755, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 69, + ProductName: "Gudbrandsdalsost", + UnitPrice: 36.0000, + Quantity: 25, + Discontinued: true, + ExtendedPrice: 675.0000, + Freight: 16.7100 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 11076, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 6, + ProductName: "Grandma's Boysenberry Spread", + UnitPrice: 25.0000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 375.0000, + Freight: 38.2800 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 11076, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 14, + ProductName: "Tofu", + UnitPrice: 23.2500, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 348.7500, + Freight: 38.2800 +}, { + ShipName: "Bon app'", + ShipAddress: "12, rue des Bouchers", + ShipCity: "Marseille", + ShipRegion: null, + ShipPostalCode: "13008", + ShipCountry: "France", + CustomerID: "BONAP", + CustomerName: "Bon app'", + Address: "12, rue des Bouchers", + City: "Marseille", + Region: null, + PostalCode: "13008", + Country: "France", + Salesperson: "Margaret Peacock", + OrderID: 11076, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 19, + ProductName: "Teatime Chocolate Biscuits", + UnitPrice: 9.2000, + Quantity: 10, + Discontinued: true, + ExtendedPrice: 69.0000, + Freight: 38.2800 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Toronto Blvd.", + ShipCity: "Toronto", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Toronto Blvd.", + City: "Toronto", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Margaret Peacock", + OrderID: 10389, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 10, + ProductName: "Ikura", + UnitPrice: 24.8000, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 396.8000, + Freight: 47.4200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Toronto Blvd.", + ShipCity: "Toronto", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Toronto Blvd.", + City: "Toronto", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Margaret Peacock", + OrderID: 10389, + OrderDate: new Date("10/4/2016"), + ShipperName: "United Package", + ProductID: 55, + ProductName: "P\u00e2t\u00e9 chinois", + UnitPrice: 19.2000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 288.0000, + Freight: 47.4200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Margaret Peacock", + OrderID: 10389, + OrderDate: new Date("9/4/2018"), + ShipperName: "United Package", + ProductID: 62, + ProductName: "Tarte au sucre", + UnitPrice: 39.4000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 788.0000, + Freight: 47.4200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Margaret Peacock", + OrderID: 10389, + OrderDate: new Date("9/4/2018"), + ShipperName: "United Package", + ProductID: 70, + ProductName: "Outback Lager", + UnitPrice: 12.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 360.0000, + Freight: 47.4200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Janet Leverling", + OrderID: 10410, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 33, + ProductName: "Geitost", + UnitPrice: 2.0000, + Quantity: 49, + Discontinued: false, + ExtendedPrice: 98.0000, + Freight: 2.4000 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Toronto Blvd.", + ShipCity: "Toronto", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Toronto Blvd.", + City: "Toronto", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Janet Leverling", + OrderID: 10410, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 59, + ProductName: "Raclette Courdavault", + UnitPrice: 44.0000, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 704.0000, + Freight: 2.4000 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Janet Leverling", + OrderID: 10742, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 3, + ProductName: "Aniseed Syrup", + UnitPrice: 10.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 200.0000, + Freight: 243.7300 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Janet Leverling", + OrderID: 10742, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 34.0000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 1700.0000, + Freight: 243.7300 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Janet Leverling", + OrderID: 10742, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 72, + ProductName: "Mozzarella di Giovanni", + UnitPrice: 34.8000, + Quantity: 35, + Discontinued: false, + ExtendedPrice: 1218.0000, + Freight: 243.7300 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Toronto Blvd.", + ShipCity: "Toronto", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Toronto Blvd.", + City: "Toronto", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Michael Suyama", + OrderID: 10944, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 38.0000, + Quantity: 18, + Discontinued: false, + ExtendedPrice: 684.0000, + Freight: 52.9200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Toronto Blvd.", + ShipCity: "Toronto", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Toronto Blvd.", + City: "Toronto", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Andrew Fuller", + OrderID: 10949, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 6, + ProductName: "Grandma's Boysenberry Spread", + UnitPrice: 25.0000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 300.0000, + Freight: 74.4400 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Andrew Fuller", + OrderID: 10949, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 10, + ProductName: "Ikura", + UnitPrice: 31.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 930.0000, + Freight: 74.4400 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Andrew Fuller", + OrderID: 10949, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 17, + ProductName: "Alice Mutton", + UnitPrice: 39.0000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 234.0000, + Freight: 74.4400 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Andrew Fuller", + OrderID: 10949, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 62, + ProductName: "Tarte au sucre", + UnitPrice: 49.3000, + Quantity: 60, + Discontinued: false, + ExtendedPrice: 2958.0000, + Freight: 74.4400 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Nancy Davolio", + OrderID: 10975, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 8, + ProductName: "Northwoods Cranberry Sauce", + UnitPrice: 40.0000, + Quantity: 16, + Discontinued: false, + ExtendedPrice: 640.0000, + Freight: 32.2700 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Nancy Davolio", + OrderID: 10975, + OrderDate: new Date("9/4/2018"), + ShipperName: "Federal Shipping", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 7.7500, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 77.5000, + Freight: 32.2700 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Toronto Blvd.", + ShipCity: "Toronto", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Toronto Blvd.", + City: "Toronto", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Anne Dodsworth", + OrderID: 10411, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 41, + ProductName: "Jack's New England Clam Chowder", + UnitPrice: 7.7000, + Quantity: 25, + Discontinued: true, + ExtendedPrice: 154.0000, + Freight: 23.6500 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Anne Dodsworth", + OrderID: 10411, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 44, + ProductName: "Gula Malacca", + UnitPrice: 15.5000, + Quantity: 40, + Discontinued: true, + ExtendedPrice: 496.0000, + Freight: 23.6500 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Anne Dodsworth", + OrderID: 10411, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 59, + ProductName: "Raclette Courdavault", + UnitPrice: 44.0000, + Quantity: 9, + Discontinued: true, + ExtendedPrice: 316.8000, + Freight: 23.6500 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Margaret Peacock", + OrderID: 10431, + OrderDate: new Date("5/12/2017"), + ShipperName: "United Package", + ProductID: 17, + ProductName: "Alice Mutton", + UnitPrice: 31.2000, + Quantity: 50, + Discontinued: true, + ExtendedPrice: 1170.0000, + Freight: 44.1700 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Margaret Peacock", + OrderID: 10431, + OrderDate: new Date("5/12/2017"), + ShipperName: "United Package", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 14.7000, + Quantity: 50, + Discontinued: true, + ExtendedPrice: 551.2500, + Freight: 44.1700 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Margaret Peacock", + OrderID: 10431, + OrderDate: new Date("5/12/2017"), + ShipperName: "United Package", + ProductID: 47, + ProductName: "Zaanse koeken", + UnitPrice: 7.6000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 171.0000, + Freight: 44.1700 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Janet Leverling", + OrderID: 10918, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 1, + ProductName: "Chai", + UnitPrice: 18.0000, + Quantity: 60, + Discontinued: true, + ExtendedPrice: 810.0000, + Freight: 48.8300 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Janet Leverling", + OrderID: 10918, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 34.0000, + Quantity: 25, + Discontinued: true, + ExtendedPrice: 637.5000, + Freight: 48.8300 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Michael Suyama", + OrderID: 10944, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 21.0000, + Quantity: 5, + Discontinued: true, + ExtendedPrice: 78.7500, + Freight: 52.9200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Michael Suyama", + OrderID: 10944, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 44, + ProductName: "Gula Malacca", + UnitPrice: 19.4500, + Quantity: 18, + Discontinued: true, + ExtendedPrice: 262.5800, + Freight: 52.9200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Nancy Davolio", + OrderID: 11027, + OrderDate: new Date("5/12/2017"), + ShipperName: "Speedy Express", + ProductID: 24, + ProductName: "Guaran\u00e1 Fant\u00e1stica", + UnitPrice: 4.5000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 101.2500, + Freight: 52.5200 +}, { + ShipName: "Bottom-Dollar Markets", + ShipAddress: "23 Tsawassen Blvd.", + ShipCity: "Tsawassen", + ShipRegion: "BC", + ShipPostalCode: "T2F 8M4", + ShipCountry: "Canada", + CustomerID: "BOTTM", + CustomerName: "Bottom-Dollar Markets", + Address: "23 Tsawassen Blvd.", + City: "Tsawassen", + Region: "BC", + PostalCode: "T2F 8M4", + Country: "Canada", + Salesperson: "Nancy Davolio", + OrderID: 11027, + OrderDate: new Date("5/12/2017"), + ShipperName: "Speedy Express", + ProductID: 62, + ProductName: "Tarte au sucre", + UnitPrice: 49.3000, + Quantity: 21, + Discontinued: true, + ExtendedPrice: 776.4800, + Freight: 52.5200 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Robert King", + OrderID: 10289, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 3, + ProductName: "Aniseed Syrup", + UnitPrice: 8.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 240.0000, + Freight: 22.7700 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Robert King", + OrderID: 10289, + OrderDate: new Date("5/12/2017"), + ShipperName: "Federal Shipping", + ProductID: 64, + ProductName: "Wimmers gute Semmelkn\u00f6del", + UnitPrice: 26.6000, + Quantity: 9, + Discontinued: false, + ExtendedPrice: 239.4000, + Freight: 22.7700 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Andrew Fuller", + OrderID: 10471, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 7, + ProductName: "Uncle Bob's Organic Dried Pears", + UnitPrice: 24.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 720.0000, + Freight: 45.5900 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Andrew Fuller", + OrderID: 10471, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 30.4000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 608.0000, + Freight: 45.5900 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10484, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 8.0000, + Quantity: 14, + Discontinued: false, + ExtendedPrice: 112.0000, + Freight: 6.8800 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10484, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 14.7000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 147.0000, + Freight: 6.8800 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10484, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 51, + ProductName: "Manjimup Dried Apples", + UnitPrice: 42.4000, + Quantity: 3, + Discontinued: false, + ExtendedPrice: 127.2000, + Freight: 6.8800 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Anne Dodsworth", + OrderID: 10538, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 70, + ProductName: "Outback Lager", + UnitPrice: 15.0000, + Quantity: 7, + Discontinued: false, + ExtendedPrice: 105.0000, + Freight: 4.8700 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Anne Dodsworth", + OrderID: 10538, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 72, + ProductName: "Mozzarella di Giovanni", + UnitPrice: 34.8000, + Quantity: 1, + Discontinued: false, + ExtendedPrice: 34.8000, + Freight: 4.8700 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Michael Suyama", + OrderID: 10539, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 6.0000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 48.0000, + Freight: 12.3600 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Michael Suyama", + OrderID: 10539, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 10.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 150.0000, + Freight: 12.3600 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Michael Suyama", + OrderID: 10539, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 33, + ProductName: "Geitost", + UnitPrice: 2.5000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 37.5000, + Freight: 12.3600 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Michael Suyama", + OrderID: 10539, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 49, + ProductName: "Maxilaku", + UnitPrice: 20.0000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 120.0000, + Freight: 12.3600 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Janet Leverling", + OrderID: 10947, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 59, + ProductName: "Raclette Courdavault", + UnitPrice: 55.0000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 220.0000, + Freight: 3.2600 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 11023, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 7, + ProductName: "Uncle Bob's Organic Dried Pears", + UnitPrice: 30.0000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 120.0000, + Freight: 123.8300 +}, { + ShipName: "B's Beverages", + ShipAddress: "Fauntleroy Circus", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "EC2 5NT", + ShipCountry: "UK", + CustomerID: "BSBEV", + CustomerName: "B's Beverages", + Address: "Fauntleroy Circus", + City: "London", + Region: null, + PostalCode: "EC2 5NT", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 11023, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 43, + ProductName: "Ipoh Coffee", + UnitPrice: 46.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 1380.0000, + Freight: 123.8300 +}, { + ShipName: "Cactus Comidas para llevar", + ShipAddress: "Cerrito 333", + ShipCity: "Buenos Aires", + ShipRegion: null, + ShipPostalCode: "1010", + ShipCountry: "Argentina", + CustomerID: "CACTU", + CustomerName: "Cactus Comidas para llevar", + Address: "Cerrito 333", + City: "Buenos Aires", + Region: null, + PostalCode: "1010", + Country: "Argentina", + Salesperson: "Laura Callahan", + OrderID: 10521, + OrderDate: new Date("4/14/2017"), + ShipperName: "United Package", + ProductID: 68, + ProductName: "Scottish Longbreads", + UnitPrice: 12.5000, + Quantity: 6, + Discontinued: true, + ExtendedPrice: 75.0000, + Freight: 17.2200 +}, { + ShipName: "Cactus Comidas para llevar", + ShipAddress: "Cerrito 333", + ShipCity: "Buenos Aires", + ShipRegion: null, + ShipPostalCode: "1010", + ShipCountry: "Argentina", + CustomerID: "CACTU", + CustomerName: "Cactus Comidas para llevar", + Address: "Cerrito 333", + City: "Buenos Aires", + Region: null, + PostalCode: "1010", + Country: "Argentina", + Salesperson: "Laura Callahan", + OrderID: 11054, + OrderDate: new Date("4/14/2017"), + ShipperName: "Speedy Express", + ProductID: 33, + ProductName: "Geitost", + UnitPrice: 2.5000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 25.0000, + Freight: 0.3300 +}, { + ShipName: "Cactus Comidas para llevar", + ShipAddress: "Cerrito 333", + ShipCity: "Buenos Aires", + ShipRegion: null, + ShipPostalCode: "1010", + ShipCountry: "Argentina", + CustomerID: "CACTU", + CustomerName: "Cactus Comidas para llevar", + Address: "Cerrito 333", + City: "Buenos Aires", + Region: null, + PostalCode: "1010", + Country: "Argentina", + Salesperson: "Laura Callahan", + OrderID: 11054, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 67, + ProductName: "Laughing Lumberjack Lager", + UnitPrice: 14.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 280.0000, + Freight: 0.3300 +}, { + ShipName: "Centro comercial Moctezuma", + ShipAddress: "Sierras de Granada 9993", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05022", + ShipCountry: "Mexico", + CustomerID: "CENTC", + CustomerName: "Centro comercial Moctezuma", + Address: "Sierras de Granada 9993", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05022", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10259, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 8.0000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 80.0000, + Freight: 3.2500 +}, { + ShipName: "Centro comercial Moctezuma", + ShipAddress: "Sierras de Granada 9993", + ShipCity: "M\u00e9xico D.F.", + ShipRegion: null, + ShipPostalCode: "05022", + ShipCountry: "Mexico", + CustomerID: "CENTC", + CustomerName: "Centro comercial Moctezuma", + Address: "Sierras de Granada 9993", + City: "M\u00e9xico D.F.", + Region: null, + PostalCode: "05022", + Country: "Mexico", + Salesperson: "Margaret Peacock", + OrderID: 10259, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 37, + ProductName: "Gravad lax", + UnitPrice: 20.8000, + Quantity: 1, + Discontinued: false, + ExtendedPrice: 20.8000, + Freight: 3.2500 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Steven Buchanan", + OrderID: 10254, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 74, + ProductName: "Longlife Tofu", + UnitPrice: 8.0000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 168.0000, + Freight: 22.9800 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Michael Suyama", + OrderID: 10370, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 64, + ProductName: "Wimmers gute Semmelkn\u00f6del", + UnitPrice: 26.6000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 798.0000, + Freight: 1.1700 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Michael Suyama", + OrderID: 10519, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 38.0000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 1520.0000, + Freight: 91.7600 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Nancy Davolio", + OrderID: 10746, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 6.0000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 36.0000, + Freight: 31.4300 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Nancy Davolio", + OrderID: 10746, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 42, + ProductName: "Singaporean Hokkien Fried Mee", + UnitPrice: 14.0000, + Quantity: 28, + Discontinued: false, + ExtendedPrice: 392.0000, + Freight: 31.4300 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Nancy Davolio", + OrderID: 10746, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 62, + ProductName: "Tarte au sucre", + UnitPrice: 49.3000, + Quantity: 9, + Discontinued: false, + ExtendedPrice: 443.7000, + Freight: 31.4300 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Nancy Davolio", + OrderID: 10746, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 69, + ProductName: "Gudbrandsdalsost", + UnitPrice: 36.0000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 1440.0000, + Freight: 31.4300 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Margaret Peacock", + OrderID: 10966, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 37, + ProductName: "Gravad lax", + UnitPrice: 26.0000, + Quantity: 8, + Discontinued: false, + ExtendedPrice: 208.0000, + Freight: 27.1900 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Margaret Peacock", + OrderID: 11029, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 38.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 760.0000, + Freight: 47.8400 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Margaret Peacock", + OrderID: 11029, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 63, + ProductName: "Vegie-spread", + UnitPrice: 43.9000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 526.8000, + Freight: 47.8400 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Janet Leverling", + OrderID: 11041, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 63, + ProductName: "Vegie-spread", + UnitPrice: 43.9000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 1317.0000, + Freight: 48.2200 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Michael Suyama", + OrderID: 10519, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 10, + ProductName: "Ikura", + UnitPrice: 31.0000, + Quantity: 16, + Discontinued: true, + ExtendedPrice: 471.2000, + Freight: 91.7600 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Michael Suyama", + OrderID: 10519, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 34.0000, + Quantity: 10, + Discontinued: true, + ExtendedPrice: 323.0000, + Freight: 91.7600 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Robert King", + OrderID: 10731, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 10.0000, + Quantity: 40, + Discontinued: true, + ExtendedPrice: 380.0000, + Freight: 96.6500 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Robert King", + OrderID: 10731, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 51, + ProductName: "Manjimup Dried Apples", + UnitPrice: 53.0000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 1510.5000, + Freight: 96.6500 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Steven Buchanan", + OrderID: 10254, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 24, + ProductName: "Guaran\u00e1 Fant\u00e1stica", + UnitPrice: 3.6000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 45.9000, + Freight: 22.9800 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Steven Buchanan", + OrderID: 10254, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 55, + ProductName: "P\u00e2t\u00e9 chinois", + UnitPrice: 19.2000, + Quantity: 21, + Discontinued: true, + ExtendedPrice: 342.7200, + Freight: 22.9800 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Michael Suyama", + OrderID: 10370, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 1, + ProductName: "Chai", + UnitPrice: 14.4000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 183.6000, + Freight: 1.1700 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Michael Suyama", + OrderID: 10370, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 74, + ProductName: "Longlife Tofu", + UnitPrice: 8.0000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 136.0000, + Freight: 1.1700 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Margaret Peacock", + OrderID: 10966, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 38.0000, + Quantity: 12, + Discontinued: true, + ExtendedPrice: 387.6000, + Freight: 27.1900 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Margaret Peacock", + OrderID: 10966, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 62, + ProductName: "Tarte au sucre", + UnitPrice: 49.3000, + Quantity: 12, + Discontinued: true, + ExtendedPrice: 502.8600, + Freight: 27.1900 +}, { + ShipName: "Chop-suey Chinese", + ShipAddress: "Hauptstr. 31", + ShipCity: "Bern", + ShipRegion: null, + ShipPostalCode: "3012", + ShipCountry: "Switzerland", + CustomerID: "CHOPS", + CustomerName: "Chop-suey Chinese", + Address: "Hauptstr. 29", + City: "Bern", + Region: null, + PostalCode: "3012", + Country: "Switzerland", + Salesperson: "Janet Leverling", + OrderID: 11041, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 2, + ProductName: "Chang", + UnitPrice: 19.0000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 456.0000, + Freight: 48.2200 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Rio de Janeiro", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Rio de Janeiro", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Laura Callahan", + OrderID: 10290, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 5, + ProductName: "Chef Anton's Gumbo Mix", + UnitPrice: 17.0000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 340.0000, + Freight: 79.7000 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Sao Paulo", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Sao Paulo", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Laura Callahan", + OrderID: 10290, + OrderDate: new Date("2/15/2017"), + ShipperName: "Speedy Express", + ProductID: 29, + ProductName: "Th\u00fcringer Rostbratwurst", + UnitPrice: 99.0000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 1485.0000, + Freight: 79.7000 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Rio de Janeiro", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Rio de Janeiro", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Laura Callahan", + OrderID: 10290, + OrderDate: new Date("4/14/2017"), + ShipperName: "Speedy Express", + ProductID: 49, + ProductName: "Maxilaku", + UnitPrice: 16.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 240.0000, + Freight: 79.7000 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Sao Paulo", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Sao Paulo", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Laura Callahan", + OrderID: 10290, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 77, + ProductName: "Original Frankfurter gr\u00fcne So\u00dfe", + UnitPrice: 10.4000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 104.0000, + Freight: 79.7000 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Sao Paulo", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Sao Paulo", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Margaret Peacock", + OrderID: 10466, + OrderDate: new Date("5/4/2017"), + ShipperName: "Speedy Express", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 16.8000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 168.0000, + Freight: 11.9300 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Sao Paulo", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Sao Paulo", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Margaret Peacock", + OrderID: 10466, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 46, + ProductName: "Spegesild", + UnitPrice: 9.6000, + Quantity: 5, + Discontinued: false, + ExtendedPrice: 48.0000, + Freight: 11.9300 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Rio de Janeiro", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Rio de Janeiro", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Margaret Peacock", + OrderID: 10494, + OrderDate: new Date("4/1/2017"), + ShipperName: "United Package", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 30.4000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 912.0000, + Freight: 65.9900 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Rio de Janeiro", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Rio de Janeiro", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Nancy Davolio", + OrderID: 10969, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 46, + ProductName: "Spegesild", + UnitPrice: 12.0000, + Quantity: 9, + Discontinued: false, + ExtendedPrice: 108.0000, + Freight: 0.2100 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Sao Paulo", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Sao Paulo", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Andrew Fuller", + OrderID: 11042, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 44, + ProductName: "Gula Malacca", + UnitPrice: 19.4500, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 291.7500, + Freight: 29.9900 +}, { + ShipName: "Com\u00e9rcio Mineiro", + ShipAddress: "Av. dos Lus\u00edadas, 23", + ShipCity: "Sao Paulo", + ShipRegion: "SP", + ShipPostalCode: "05432-043", + ShipCountry: "Brazil", + CustomerID: "COMMI", + CustomerName: "Com\u00e9rcio Mineiro", + Address: "Av. dos Lus\u00edadas, 23", + City: "Sao Paulo", + Region: "SP", + PostalCode: "05432-043", + Country: "Brazil", + Salesperson: "Andrew Fuller", + OrderID: 11042, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 61, + ProductName: "Sirop d'\u00e9rable", + UnitPrice: 28.5000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 114.0000, + Freight: 29.9900 +}, { + ShipName: "Consolidated Holdings", + ShipAddress: "Berkeley Gardens 12 Brewery", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX1 6LT", + ShipCountry: "UK", + CustomerID: "CONSH", + CustomerName: "Consolidated Holdings", + Address: "Berkeley Gardens 12 Brewery", + City: "London", + Region: null, + PostalCode: "WX1 6LT", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10435, + OrderDate: new Date("4/16/2016"), + ShipperName: "United Package", + ProductID: 2, + ProductName: "Chang", + UnitPrice: 15.2000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 152.0000, + Freight: 9.2100 +}, { + ShipName: "Consolidated Holdings", + ShipAddress: "Berkeley Gardens 12 Brewery", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX1 6LT", + ShipCountry: "UK", + CustomerID: "CONSH", + CustomerName: "Consolidated Holdings", + Address: "Berkeley Gardens 12 Brewery", + City: "London", + Region: null, + PostalCode: "WX1 6LT", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10435, + OrderDate: new Date("5/12/2016"), + ShipperName: "United Package", + ProductID: 22, + ProductName: "Gustaf's Kn\u00e4ckebr\u00f6d", + UnitPrice: 16.8000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 201.6000, + Freight: 9.2100 +}, { + ShipName: "Consolidated Holdings", + ShipAddress: "Berkeley Gardens 12 Brewery", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX1 6LT", + ShipCountry: "UK", + CustomerID: "CONSH", + CustomerName: "Consolidated Holdings", + Address: "Berkeley Gardens 12 Brewery", + City: "London", + Region: null, + PostalCode: "WX1 6LT", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10435, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 72, + ProductName: "Mozzarella di Giovanni", + UnitPrice: 27.8000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 278.0000, + Freight: 9.2100 +}, { + ShipName: "Consolidated Holdings", + ShipAddress: "Berkeley Gardens 12 Brewery", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX1 6LT", + ShipCountry: "UK", + CustomerID: "CONSH", + CustomerName: "Consolidated Holdings", + Address: "Berkeley Gardens 12 Brewery", + City: "London", + Region: null, + PostalCode: "WX1 6LT", + Country: "UK", + Salesperson: "Andrew Fuller", + OrderID: 10462, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 4.8000, + Quantity: 1, + Discontinued: false, + ExtendedPrice: 4.8000, + Freight: 6.1700 +}, { + ShipName: "Consolidated Holdings", + ShipAddress: "Berkeley Gardens 12 Brewery", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX1 6LT", + ShipCountry: "UK", + CustomerID: "CONSH", + CustomerName: "Consolidated Holdings", + Address: "Berkeley Gardens 12 Brewery", + City: "London", + Region: null, + PostalCode: "WX1 6LT", + Country: "UK", + Salesperson: "Andrew Fuller", + OrderID: 10462, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 23, + ProductName: "Tunnbr\u00f6d", + UnitPrice: 7.2000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 151.2000, + Freight: 6.1700 +}, { + ShipName: "Consolidated Holdings", + ShipAddress: "Berkeley Gardens 12 Brewery", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX1 6LT", + ShipCountry: "UK", + CustomerID: "CONSH", + CustomerName: "Consolidated Holdings", + Address: "Berkeley Gardens 12 Brewery", + City: "London", + Region: null, + PostalCode: "WX1 6LT", + Country: "UK", + Salesperson: "Robert King", + OrderID: 10848, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 5, + ProductName: "Chef Anton's Gumbo Mix", + UnitPrice: 21.3500, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 640.5000, + Freight: 38.2400 +}, { + ShipName: "Consolidated Holdings", + ShipAddress: "Berkeley Gardens 12 Brewery", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX1 6LT", + ShipCountry: "UK", + CustomerID: "CONSH", + CustomerName: "Consolidated Holdings", + Address: "Berkeley Gardens 12 Brewery", + City: "London", + Region: null, + PostalCode: "WX1 6LT", + Country: "UK", + Salesperson: "Robert King", + OrderID: 10848, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 9, + ProductName: "Mishi Kobe Niku", + UnitPrice: 97.0000, + Quantity: 3, + Discontinued: false, + ExtendedPrice: 291.0000, + Freight: 38.2400 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10301, + OrderDate: new Date("4/14/2017"), + ShipperName: "United Package", + ProductID: 40, + ProductName: "Boston Crab Meat", + UnitPrice: 14.7000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 147.0000, + Freight: 45.0800 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10301, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 56, + ProductName: "Gnocchi di nonna Alice", + UnitPrice: 30.4000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 608.0000, + Freight: 45.0800 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Andrew Fuller", + OrderID: 10312, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 28, + ProductName: "R\u00f6ssle Sauerkraut", + UnitPrice: 36.4000, + Quantity: 4, + Discontinued: false, + ExtendedPrice: 145.6000, + Freight: 40.2600 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Andrew Fuller", + OrderID: 10312, + OrderDate: new Date("4/14/2018"), + ShipperName: "United Package", + ProductID: 43, + ProductName: "Ipoh Coffee", + UnitPrice: 36.8000, + Quantity: 24, + Discontinued: false, + ExtendedPrice: 883.2000, + Freight: 40.2600 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Andrew Fuller", + OrderID: 10312, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 53, + ProductName: "Perth Pasties", + UnitPrice: 26.2000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 524.0000, + Freight: 40.2600 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Andrew Fuller", + OrderID: 10312, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 6.2000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 62.0000, + Freight: 40.2600 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10348, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 23, + ProductName: "Tunnbr\u00f6d", + UnitPrice: 7.2000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 180.0000, + Freight: 0.7800 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10356, + OrderDate: new Date("4/14/2018"), + ShipperName: "United Package", + ProductID: 31, + ProductName: "Gorgonzola Telino", + UnitPrice: 10.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 300.0000, + Freight: 36.7100 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10356, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 55, + ProductName: "P\u00e2t\u00e9 chinois", + UnitPrice: 19.2000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 230.4000, + Freight: 36.7100 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Michael Suyama", + OrderID: 10356, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 69, + ProductName: "Gudbrandsdalsost", + UnitPrice: 28.8000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 576.0000, + Freight: 36.7100 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10632, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 2, + ProductName: "Chang", + UnitPrice: 19.0000, + Quantity: 30, + Discontinued: true, + ExtendedPrice: 541.5000, + Freight: 41.3800 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10632, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 33, + ProductName: "Geitost", + UnitPrice: 2.5000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 47.5000, + Freight: 41.3800 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 11046, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 12, + ProductName: "Queso Manchego La Pastora", + UnitPrice: 38.0000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 722.0000, + Freight: 71.6400 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 11046, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 32, + ProductName: "Mascarpone Fabioli", + UnitPrice: 32.0000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 456.0000, + Freight: 71.6400 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 11046, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 35, + ProductName: "Steeleye Stout", + UnitPrice: 18.0000, + Quantity: 18, + Discontinued: true, + ExtendedPrice: 307.8000, + Freight: 71.6400 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 10668, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 31, + ProductName: "Gorgonzola Telino", + UnitPrice: 12.5000, + Quantity: 8, + Discontinued: true, + ExtendedPrice: 90.0000, + Freight: 47.2200 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 10668, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 55, + ProductName: "P\u00e2t\u00e9 chinois", + UnitPrice: 24.0000, + Quantity: 4, + Discontinued: true, + ExtendedPrice: 86.4000, + Freight: 47.2200 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 10668, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 64, + ProductName: "Wimmers gute Semmelkn\u00f6del", + UnitPrice: 33.2500, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 448.8700, + Freight: 47.2200 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10348, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 1, + ProductName: "Chai", + UnitPrice: 14.4000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 183.6000, + Freight: 0.7800 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Robert King", + OrderID: 10513, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 10.0000, + Quantity: 40, + Discontinued: true, + ExtendedPrice: 320.0000, + Freight: 105.6500 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Robert King", + OrderID: 10513, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 32, + ProductName: "Mascarpone Fabioli", + UnitPrice: 32.0000, + Quantity: 50, + Discontinued: true, + ExtendedPrice: 1280.0000, + Freight: 105.6500 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Robert King", + OrderID: 10513, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 61, + ProductName: "Sirop d'\u00e9rable", + UnitPrice: 28.5000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 342.0000, + Freight: 105.6500 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10640, + OrderDate: new Date("4/14/2017"), + ShipperName: "Speedy Express", + ProductID: 69, + ProductName: "Gudbrandsdalsost", + UnitPrice: 36.0000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 540.0000, + Freight: 23.5500 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10640, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 70, + ProductName: "Outback Lager", + UnitPrice: 15.0000, + Quantity: 15, + Discontinued: true, + ExtendedPrice: 168.7500, + Freight: 23.5500 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10651, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 19, + ProductName: "Teatime Chocolate Biscuits", + UnitPrice: 9.2000, + Quantity: 12, + Discontinued: true, + ExtendedPrice: 82.8000, + Freight: 20.6000 +}, { + ShipName: "Die Wandernde Kuh", + ShipAddress: "Adenauerallee 900", + ShipCity: "Stuttgart", + ShipRegion: null, + ShipPostalCode: "70563", + ShipCountry: "Germany", + CustomerID: "WANDK", + CustomerName: "Die Wandernde Kuh", + Address: "Adenauerallee 900", + City: "Stuttgart", + Region: null, + PostalCode: "70563", + Country: "Germany", + Salesperson: "Laura Callahan", + OrderID: 10651, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 22, + ProductName: "Gustaf's Kn\u00e4ckebr\u00f6d", + UnitPrice: 21.0000, + Quantity: 20, + Discontinued: true, + ExtendedPrice: 315.0000, + Freight: 20.6000 +}, { + ShipName: "Drachenblut Delikatessen", + ShipAddress: "Walserweg 21", + ShipCity: "Aachen", + ShipRegion: null, + ShipPostalCode: "52066", + ShipCountry: "Germany", + CustomerID: "DRACD", + CustomerName: "Drachenblut Delikatessen", + Address: "Walserweg 21", + City: "Aachen", + Region: null, + PostalCode: "52066", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10363, + OrderDate: new Date("4/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 31, + ProductName: "Gorgonzola Telino", + UnitPrice: 10.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 200.0000, + Freight: 30.5400 +}, { + ShipName: "Drachenblut Delikatessen", + ShipAddress: "Walserweg 21", + ShipCity: "Aachen", + ShipRegion: null, + ShipPostalCode: "52066", + ShipCountry: "Germany", + CustomerID: "DRACD", + CustomerName: "Drachenblut Delikatessen", + Address: "Walserweg 21", + City: "Aachen", + Region: null, + PostalCode: "52066", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10363, + OrderDate: new Date("12/4/2016"), + ShipperName: "Federal Shipping", + ProductID: 75, + ProductName: "Rh\u00f6nbr\u00e4u Klosterbier", + UnitPrice: 6.2000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 74.4000, + Freight: 30.5400 +}, { + ShipName: "Drachenblut Delikatessen", + ShipAddress: "Walserweg 21", + ShipCity: "Aachen", + ShipRegion: null, + ShipPostalCode: "52066", + ShipCountry: "Germany", + CustomerID: "DRACD", + CustomerName: "Drachenblut Delikatessen", + Address: "Walserweg 21", + City: "Aachen", + Region: null, + PostalCode: "52066", + Country: "Germany", + Salesperson: "Margaret Peacock", + OrderID: 10363, + OrderDate: new Date("2/8/2016"), + ShipperName: "Federal Shipping", + ProductID: 76, + ProductName: "Lakkalik\u00f6\u00f6ri", + UnitPrice: 14.4000, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 172.8000, + Freight: 30.5400 +}, { + ShipName: "Drachenblut Delikatessen", + ShipAddress: "Walserweg 21", + ShipCity: "Aachen", + ShipRegion: null, + ShipPostalCode: "52066", + ShipCountry: "Germany", + CustomerID: "DRACD", + CustomerName: "Drachenblut Delikatessen", + Address: "Walserweg 21", + City: "Aachen", + Region: null, + PostalCode: "52066", + Country: "Germany", + Salesperson: "Janet Leverling", + OrderID: 10391, + OrderDate: new Date("4/14/2017"), + ShipperName: "Federal Shipping", + ProductID: 13, + ProductName: "Konbu", + UnitPrice: 4.8000, + Quantity: 18, + Discontinued: false, + ExtendedPrice: 86.4000, + Freight: 5.4500 +}, { + ShipName: "Drachenblut Delikatessen", + ShipAddress: "Walserweg 21", + ShipCity: "Aachen", + ShipRegion: null, + ShipPostalCode: "52066", + ShipCountry: "Germany", + CustomerID: "DRACD", + CustomerName: "Drachenblut Delikatessen", + Address: "Walserweg 21", + City: "Aachen", + Region: null, + PostalCode: "52066", + Country: "Germany", + Salesperson: "Robert King", + OrderID: 10797, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 21.0000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 420.0000, + Freight: 33.3500 +}, { + ShipName: "Drachenblut Delikatessen", + ShipAddress: "Walserweg 21", + ShipCity: "Aachen", + ShipRegion: null, + ShipPostalCode: "52066", + ShipCountry: "Germany", + CustomerID: "DRACD", + CustomerName: "Drachenblut Delikatessen", + Address: "Walserweg 21", + City: "Aachen", + Region: null, + PostalCode: "52066", + Country: "Germany", + Salesperson: "Nancy Davolio", + OrderID: 11067, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 41, + ProductName: "Jack's New England Clam Chowder", + UnitPrice: 9.6500, + Quantity: 9, + Discontinued: false, + ExtendedPrice: 86.8500, + Freight: 7.9800 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10311, + OrderDate: new Date("8/14/2016"), + ShipperName: "Federal Shipping", + ProductID: 42, + ProductName: "Singaporean Hokkien Fried Mee", + UnitPrice: 11.2000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 67.2000, + Freight: 24.6900 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Nancy Davolio", + OrderID: 10311, + OrderDate: new Date("4/14/2017"), + ShipperName: "Federal Shipping", + ProductID: 69, + ProductName: "Gudbrandsdalsost", + UnitPrice: 28.8000, + Quantity: 7, + Discontinued: false, + ExtendedPrice: 201.6000, + Freight: 24.6900 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Robert King", + OrderID: 10609, + OrderDate: new Date("6/14/2016"), + ShipperName: "United Package", + ProductID: 1, + ProductName: "Chai", + UnitPrice: 18.0000, + Quantity: 3, + Discontinued: false, + ExtendedPrice: 54.0000, + Freight: 1.8500 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Robert King", + OrderID: 10609, + OrderDate: new Date("4/14/2015"), + ShipperName: "United Package", + ProductID: 10, + ProductName: "Ikura", + UnitPrice: 31.0000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 310.0000, + Freight: 1.8500 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Robert King", + OrderID: 10609, + OrderDate: new Date("4/14/2016"), + ShipperName: "United Package", + ProductID: 21, + ProductName: "Sir Rodney's Scones", + UnitPrice: 10.0000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 60.0000, + Freight: 1.8500 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Andrew Fuller", + OrderID: 10683, + OrderDate: new Date("4/14/2017"), + ShipperName: "Speedy Express", + ProductID: 52, + ProductName: "Filo Mix", + UnitPrice: 7.0000, + Quantity: 9, + Discontinued: false, + ExtendedPrice: 63.0000, + Freight: 4.4000 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Robert King", + OrderID: 10890, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 17, + ProductName: "Alice Mutton", + UnitPrice: 39.0000, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 585.0000, + Freight: 32.7600 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Robert King", + OrderID: 10890, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 34, + ProductName: "Sasquatch Ale", + UnitPrice: 14.0000, + Quantity: 10, + Discontinued: false, + ExtendedPrice: 140.0000, + Freight: 32.7600 +}, { + ShipName: "Du monde entier", + ShipAddress: "67, rue des Cinquante Otages", + ShipCity: "Nantes", + ShipRegion: null, + ShipPostalCode: "44000", + ShipCountry: "France", + CustomerID: "DUMON", + CustomerName: "Du monde entier", + Address: "67, rue des Cinquante Otages", + City: "Nantes", + Region: null, + PostalCode: "44000", + Country: "France", + Salesperson: "Robert King", + OrderID: 10890, + OrderDate: new Date("2/14/2016"), + ShipperName: "Speedy Express", + ProductID: 41, + ProductName: "Jack's New England Clam Chowder", + UnitPrice: 9.6500, + Quantity: 14, + Discontinued: false, + ExtendedPrice: 135.1000, + Freight: 32.7600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10364, + OrderDate: new Date("4/14/2017"), + ShipperName: "Speedy Express", + ProductID: 69, + ProductName: "Gudbrandsdalsost", + UnitPrice: 28.8000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 864.0000, + Freight: 71.9700 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10364, + OrderDate: new Date("4/4/2016"), + ShipperName: "Speedy Express", + ProductID: 71, + ProductName: "Flotemysost", + UnitPrice: 17.2000, + Quantity: 5, + Discontinued: false, + ExtendedPrice: 86.0000, + Freight: 71.9700 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10400, + OrderDate: new Date("3/12/2016"), + ShipperName: "Federal Shipping", + ProductID: 29, + ProductName: "Th\u00fcringer Rostbratwurst", + UnitPrice: 99.0000, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 2079.0000, + Freight: 83.9300 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10400, + OrderDate: new Date("4/14/2017"), + ShipperName: "Federal Shipping", + ProductID: 35, + ProductName: "Steeleye Stout", + UnitPrice: 14.4000, + Quantity: 35, + Discontinued: false, + ExtendedPrice: 504.0000, + Freight: 83.9300 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Nancy Davolio", + OrderID: 10400, + OrderDate: new Date("1/1/2017"), + ShipperName: "Federal Shipping", + ProductID: 49, + ProductName: "Maxilaku", + UnitPrice: 16.0000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 480.0000, + Freight: 83.9300 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Robert King", + OrderID: 10532, + OrderDate: new Date("4/22/2017"), + ShipperName: "Federal Shipping", + ProductID: 30, + ProductName: "Nord-Ost Matjeshering", + UnitPrice: 25.8900, + Quantity: 15, + Discontinued: false, + ExtendedPrice: 388.3500, + Freight: 74.4600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Robert King", + OrderID: 10532, + OrderDate: new Date("9/25/2017"), + ShipperName: "Federal Shipping", + ProductID: 66, + ProductName: "Louisiana Hot Spiced Okra", + UnitPrice: 17.0000, + Quantity: 24, + Discontinued: false, + ExtendedPrice: 408.0000, + Freight: 74.4600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10726, + OrderDate: new Date("4/24/2015"), + ShipperName: "Speedy Express", + ProductID: 4, + ProductName: "Chef Anton's Cajun Seasoning", + UnitPrice: 22.0000, + Quantity: 25, + Discontinued: false, + ExtendedPrice: 550.0000, + Freight: 16.5600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 10726, + OrderDate: new Date("3/11/2017"), + ShipperName: "Speedy Express", + ProductID: 11, + ProductName: "Queso Cabrales", + UnitPrice: 21.0000, + Quantity: 5, + Discontinued: false, + ExtendedPrice: 105.0000, + Freight: 16.5600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10987, + OrderDate: new Date("4/14/2016"), + ShipperName: "Speedy Express", + ProductID: 7, + ProductName: "Uncle Bob's Organic Dried Pears", + UnitPrice: 30.0000, + Quantity: 60, + Discontinued: false, + ExtendedPrice: 1800.0000, + Freight: 185.4800 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10987, + OrderDate: new Date("1/24/2017"), + ShipperName: "Speedy Express", + ProductID: 43, + ProductName: "Ipoh Coffee", + UnitPrice: 46.0000, + Quantity: 6, + Discontinued: false, + ExtendedPrice: 276.0000, + Freight: 185.4800 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 10987, + OrderDate: new Date("3/31/2017"), + ShipperName: "Speedy Express", + ProductID: 72, + ProductName: "Mozzarella di Giovanni", + UnitPrice: 34.8000, + Quantity: 20, + Discontinued: false, + ExtendedPrice: 696.0000, + Freight: 185.4800 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 11024, + OrderDate: new Date("4/15/2018"), + ShipperName: "Speedy Express", + ProductID: 26, + ProductName: "Gumb\u00e4r Gummib\u00e4rchen", + UnitPrice: 31.2300, + Quantity: 12, + Discontinued: false, + ExtendedPrice: 374.7600, + Freight: 74.3600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 11024, + OrderDate: new Date("5/17/2017"), + ShipperName: "Speedy Express", + ProductID: 33, + ProductName: "Geitost", + UnitPrice: 2.5000, + Quantity: 30, + Discontinued: false, + ExtendedPrice: 75.0000, + Freight: 74.3600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 11024, + OrderDate: new Date("4/24/2016"), + ShipperName: "Speedy Express", + ProductID: 65, + ProductName: "Louisiana Fiery Hot Pepper Sauce", + UnitPrice: 21.0500, + Quantity: 21, + Discontinued: false, + ExtendedPrice: 442.0500, + Freight: 74.3600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Margaret Peacock", + OrderID: 11024, + OrderDate: new Date("6/24/2017"), + ShipperName: "Speedy Express", + ProductID: 71, + ProductName: "Flotemysost", + UnitPrice: 21.5000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 1075.0000, + Freight: 74.3600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 11056, + OrderDate: new Date("4/24/2017"), + ShipperName: "United Package", + ProductID: 7, + ProductName: "Uncle Bob's Organic Dried Pears", + UnitPrice: 30.0000, + Quantity: 40, + Discontinued: false, + ExtendedPrice: 1200.0000, + Freight: 278.9600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 11056, + OrderDate: new Date("3/24/2018"), + ShipperName: "United Package", + ProductID: 55, + ProductName: "P\u00e2t\u00e9 chinois", + UnitPrice: 24.0000, + Quantity: 35, + Discontinued: false, + ExtendedPrice: 840.0000, + Freight: 278.9600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Laura Callahan", + OrderID: 11056, + OrderDate: new Date("4/28/2018"), + ShipperName: "United Package", + ProductID: 60, + ProductName: "Camembert Pierrot", + UnitPrice: 34.0000, + Quantity: 50, + Discontinued: false, + ExtendedPrice: 1700.0000, + Freight: 278.9600 +}, { + ShipName: "Eastern Connection", + ShipAddress: "35 King George", + ShipCity: "London", + ShipRegion: null, + ShipPostalCode: "WX3 6FW", + ShipCountry: "UK", + CustomerID: "EASTC", + CustomerName: "Eastern Connection", + Address: "35 King George", + City: "London", + Region: null, + PostalCode: "WX3 6FW", + Country: "UK", + Salesperson: "Robert King", + OrderID: 11047, + OrderDate: new Date("4/24/2017"), + ShipperName: "Federal Shipping", + ProductID: 1, + ProductName: "Chai", + UnitPrice: 18.0000, + Quantity: 25, + Discontinued: true, + ExtendedPrice: 337.5000, + Freight: 46.6200 +}]; +/* tslint:enable */